diff --git a/bspc.c b/bspc.c index 410f9e7..f4e3f31 100644 --- a/bspc.c +++ b/bspc.c @@ -10,16 +10,16 @@ int main(int argc, char *argv[]) { int sock_fd, nbr, i; struct sockaddr_un sock_address; - char *sock_path; + char *socket_path; char msg[BUFSIZ]; char rsp[BUFSIZ]; if (argc < 2) return -1; - sock_path = getenv(SOCK_PATH); + socket_path = getenv(SOCKET_ENV_VAR); - if (sock_path == NULL) + if (socket_path == NULL) return -1; msg[0] = '\0'; @@ -31,7 +31,7 @@ int main(int argc, char *argv[]) } sock_address.sun_family = AF_UNIX; - strcpy(sock_address.sun_path, sock_path); + strcpy(sock_address.sun_path, socket_path); sock_fd = socket(AF_UNIX, SOCK_STREAM, 0); connect(sock_fd, (struct sockaddr *) &sock_address, sizeof(sock_address)); diff --git a/bspwm.c b/bspwm.c index 6751edd..3f80d8f 100644 --- a/bspwm.c +++ b/bspwm.c @@ -29,13 +29,14 @@ void quit(void) running = false; } -int register_events(void) +void register_events(void) { uint32_t values[] = {XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY}; xcb_generic_error_t *err = xcb_request_check(dpy, xcb_change_window_attributes_checked(dpy, screen->root, XCB_CW_EVENT_MASK, values)); - if (err != NULL) - return 1; - return 0; + if (err != NULL) { + xcb_disconnect(dpy); + die("another WM is already running\n"); + } } void setup(void) @@ -47,6 +48,7 @@ void setup(void) screen_width = screen->width_in_pixels; screen_height = screen->height_in_pixels; + root_depth = screen->root_depth; xcb_atom_t net_atoms[] = {ewmh->_NET_SUPPORTED, ewmh->_NET_WM_STATE_FULLSCREEN, ewmh->_NET_WM_STATE, ewmh->_NET_ACTIVE_WINDOW}; @@ -67,9 +69,9 @@ void setup(void) int main(void) { fd_set descriptors; + char *socket_path; int sock_fd, ret_fd, dpy_fd, sel, nbr; struct sockaddr_un sock_address; - char *sock_path; char msg[BUFSIZ], rsp[BUFSIZ]; xcb_generic_event_t *event; @@ -82,22 +84,20 @@ int main(void) die("error: cannot open display\n"); setup(); - - if (register_events() == 1) { - xcb_disconnect(dpy); - die("another WM is already running\n"); - } + register_events(); dpy_fd = xcb_get_file_descriptor(dpy); - sock_path = getenv(SOCK_PATH); + socket_path = getenv(SOCKET_ENV_VAR); - if (sock_path == NULL) - die("BSPWM_SOCKET environment variable is not set\n"); + if (socket_path == NULL) { + xcb_disconnect(dpy); + die("the socket path environment variable is not defined\n"); + } sock_address.sun_family = AF_UNIX; - strcpy(sock_address.sun_path, sock_path); - unlink(sock_path); + strcpy(sock_address.sun_path, socket_path); + unlink(socket_path); sock_fd = socket(AF_UNIX, SOCK_STREAM, 0); diff --git a/bspwm.h b/bspwm.h index f981f4b..b5a2977 100644 --- a/bspwm.h +++ b/bspwm.h @@ -9,6 +9,8 @@ unsigned int num_clients; uint32_t num_desktops; xcb_screen_t *screen; xcb_rectangle_t root_rect; +uint8_t root_depth; + split_mode_t split_mode; direction_t split_dir; desktop_t *desk; @@ -16,9 +18,10 @@ desktop_t *last_desk; desktop_t *desk_head; desktop_t *desk_tail; rule_t *rule_head; + bool running; -int register_events(void); +void register_events(void); void handle_zombie(int); void setup(void); void quit(void); diff --git a/common.h b/common.h index d700b74..ca962cc 100644 --- a/common.h +++ b/common.h @@ -1,7 +1,7 @@ #ifndef _COMMON_H #define _COMMON_H -#define SOCK_PATH "BSPWM_SOCKET" +#define SOCKET_ENV_VAR "BSPWM_SOCKET" #define EMPTY_RESPONSE "" #define TOKEN_SEP " " diff --git a/events.c b/events.c index 12e7005..6cd50ee 100644 --- a/events.c +++ b/events.c @@ -24,7 +24,7 @@ void handle_event(xcb_generic_event_t *evt) destroy_notify(evt); break; case XCB_UNMAP_NOTIFY: - unmap_notify(evt); + /* unmap_notify(evt); */ break; case XCB_CLIENT_MESSAGE: client_message(evt); @@ -65,10 +65,10 @@ void map_request(xcb_generic_event_t *evt) xcb_get_geometry_reply_t *geom = xcb_get_geometry_reply(dpy, xcb_get_geometry(dpy, win), NULL); if (geom) { - c->rectangle = (xcb_rectangle_t) {geom->x, geom->y, geom->width, geom->height}; + c->floating_rectangle = (xcb_rectangle_t) {geom->x, geom->y, geom->width, geom->height}; free(geom); } else { - c->rectangle = (xcb_rectangle_t) {0, 0, 320, 240}; + c->floating_rectangle = (xcb_rectangle_t) {0, 0, 320, 240}; } bool floating = false, transient = false, fullscreen = false, takes_focus = true; @@ -130,28 +130,28 @@ void configure_request(xcb_generic_event_t *evt) mask |= XCB_CONFIG_WINDOW_X; values[i++] = e->x; if (is_managed) - loc.node->client->rectangle.x = e->x; + loc.node->client->floating_rectangle.x = e->x; } if (e->value_mask & XCB_CONFIG_WINDOW_Y) { mask |= XCB_CONFIG_WINDOW_Y; values[i++] = e->y; if (is_managed) - loc.node->client->rectangle.y = e->y; + loc.node->client->floating_rectangle.y = e->y; } if (e->value_mask & XCB_CONFIG_WINDOW_WIDTH) { mask |= XCB_CONFIG_WINDOW_WIDTH; values[i++] = e->width; if (is_managed) - loc.node->client->rectangle.width = e->width; + loc.node->client->floating_rectangle.width = e->width; } if (e->value_mask & XCB_CONFIG_WINDOW_HEIGHT) { mask |= XCB_CONFIG_WINDOW_HEIGHT; values[i++] = e->height; if (is_managed) - loc.node->client->rectangle.height = e->height; + loc.node->client->floating_rectangle.height = e->height; } if (!is_managed && e->value_mask & XCB_CONFIG_WINDOW_BORDER_WIDTH) { @@ -193,11 +193,12 @@ void unmap_notify(xcb_generic_event_t *evt) { xcb_unmap_notify_event_t *e = (xcb_unmap_notify_event_t *) evt; - PRINTF("unmap notify %X\n", e->window); + PRINTF("unmap notify %X %u\n", e->window, e->from_configure); window_location_t loc; if (locate_window(e->window, &loc)) { if (loc.node->client->visible) { + PRINTF("remove node in unmap notify %X\n", e->window); remove_node(loc.desktop, loc.node); apply_layout(loc.desktop, loc.desktop->root, root_rect); } @@ -209,7 +210,7 @@ void property_notify(xcb_generic_event_t *evt) xcb_property_notify_event_t *e = (xcb_property_notify_event_t *) evt; xcb_icccm_wm_hints_t hints; - PRINTF("property notify %X\n", e->window); + /* PRINTF("property notify %X\n", e->window); */ if (e->atom != XCB_ATOM_WM_HINTS) return; diff --git a/messages.c b/messages.c index 7bf293f..bcfb321 100644 --- a/messages.c +++ b/messages.c @@ -129,6 +129,8 @@ void process_message(char *msg, char *rsp) } } } else if (strcmp(cmd, "cycle") == 0) { + if (desk->focus != NULL && desk->focus->client->fullscreen) + return; char *dir = strtok(NULL, TOKEN_SEP); if (dir != NULL) { cycle_dir_t d; @@ -167,6 +169,8 @@ void process_message(char *msg, char *rsp) } return; } else if (strcmp(cmd, "focus") == 0) { + if (desk->focus != NULL && desk->focus->client->fullscreen) + return; char *dir = strtok(NULL, TOKEN_SEP); if (dir != NULL) { direction_t d; diff --git a/tree.c b/tree.c index d0128da..2ebd1df 100644 --- a/tree.c +++ b/tree.c @@ -179,7 +179,7 @@ void dump_tree(desktop_t *d, node_t *n, char *rsp, int depth) if (is_leaf(n)) /* sprintf(line, "0x%X [%i %i %u %u]", n->client->window, n->rectangle.x, n->rectangle.y, n->rectangle.width, n->rectangle.height); */ - /* sprintf(line, "C %X [%i %i %u %u] (%s%s) [%i %i %u %u]", n->client->window, n->rectangle.x, n->rectangle.y, n->rectangle.width, n->rectangle.height, (n->client->floating ? "f" : "-"), (n->client->transient ? "t" : "-"), n->client->rectangle.x, n->client->rectangle.y, n->client->rectangle.width, n->client->rectangle.height); */ + /* sprintf(line, "C %X [%i %i %u %u] (%s%s) [%i %i %u %u]", n->client->window, n->rectangle.x, n->rectangle.y, n->rectangle.width, n->rectangle.height, (n->client->floating ? "f" : "-"), (n->client->transient ? "t" : "-"), n->client->floating_rectangle.x, n->client->floating_rectangle.y, n->client->floating_rectangle.width, n->client->floating_rectangle.height); */ sprintf(line, "C %X %s%s%s%s%s%s", n->client->window, (n->client->floating ? "f" : "-"), (n->client->transient ? "t" : "-"), (n->client->fullscreen ? "F" : "-"), (n->client->urgent ? "u" : "-"), (n->client->locked ? "l" : "-"), (n->client->visible ? "v" : "-")); else /* sprintf(line, "%s %.2f [%i %i %u %u]", (n->split_type == TYPE_HORIZONTAL ? "H" : "V"), n->split_ratio, n->rectangle.x, n->rectangle.y, n->rectangle.width, n->rectangle.height); */ @@ -245,8 +245,9 @@ void apply_layout(desktop_t *d, node_t *n, xcb_rectangle_t rect) int bleed = window_gap + 2 * border_width; r.width = (bleed < r.width ? r.width - bleed : 1); r.height = (bleed < r.height ? r.height - bleed : 1); + n->client->tiled_rectangle = r; } else { - r = n->client->rectangle; + r = n->client->floating_rectangle; } window_move_resize(n->client->window, r.x, r.y, r.width, r.height); @@ -257,7 +258,6 @@ void apply_layout(desktop_t *d, node_t *n, xcb_rectangle_t rect) window_raise(n->client->window); } else { - xcb_rectangle_t first_rect; xcb_rectangle_t second_rect; @@ -376,9 +376,6 @@ void focus_node(desktop_t *d, node_t *n, bool is_mapped) if (n == NULL) return; - if (desk->focus != NULL && desk->focus->client->fullscreen) - return; - PRINTF("focus node %X\n", n->client->window); split_mode = MODE_AUTOMATIC; @@ -543,7 +540,7 @@ void select_desktop(desktop_t *d) if (d == NULL || d == desk) return; - PRINTF("select desktop %s\n", desk->name); + PRINTF("select desktop %s\n", d->name); node_t *n = first_extrema(d->root); diff --git a/types.h b/types.h index d214a23..c5bb679 100644 --- a/types.h +++ b/types.h @@ -65,7 +65,8 @@ typedef struct { bool locked; /* protects window from being closed */ bool urgent; bool visible; - xcb_rectangle_t rectangle; + xcb_rectangle_t floating_rectangle; + xcb_rectangle_t tiled_rectangle; } client_t; typedef struct node_t node_t; diff --git a/window.c b/window.c index fb4127b..6862ba8 100644 --- a/window.c +++ b/window.c @@ -47,16 +47,21 @@ void window_draw_border(node_t *n, bool focused) return; xcb_window_t win = n->client->window; - xcb_get_geometry_reply_t *geom = xcb_get_geometry_reply(dpy, xcb_get_geometry(dpy, win), NULL); + /* xcb_get_geometry_reply_t *geom = xcb_get_geometry_reply(dpy, xcb_get_geometry(dpy, win), NULL); */ - if (geom == NULL) - return; + /* if (geom == NULL) */ + /* return; */ - uint16_t width = geom->width; - uint16_t height = geom->height; - uint8_t depth = geom->depth; + /* uint16_t width = geom->width; */ + /* uint16_t height = geom->height; */ + /* uint8_t depth = geom->depth; */ - free(geom); + /* free(geom); */ + + xcb_rectangle_t actual_rectangle = (is_tiled(n->client) ? n->client->tiled_rectangle : n->client->floating_rectangle); + + uint16_t width = actual_rectangle.width; + uint16_t height = actual_rectangle.height; uint16_t full_width = width + 2 * border_width; uint16_t full_height = height + 2 * border_width; @@ -82,7 +87,7 @@ void window_draw_border(node_t *n, bool focused) xcb_rectangle_t *presel_rectangles; xcb_pixmap_t pix = xcb_generate_id(dpy); - xcb_create_pixmap(dpy, depth, pix, win, full_width, full_height); + xcb_create_pixmap(dpy, root_depth, pix, win, full_width, full_height); xcb_gcontext_t gc = xcb_generate_id(dpy); xcb_create_gc(dpy, gc, pix, 0, NULL); @@ -178,14 +183,14 @@ void toggle_fullscreen(client_t *c) c->fullscreen = false; xcb_atom_t values[] = {XCB_NONE}; xcb_ewmh_set_wm_state(ewmh, c->window, LENGTH(values), values); - xcb_rectangle_t rect = c->rectangle; + xcb_rectangle_t rect = c->floating_rectangle; window_border_width(c->window, border_width); window_move_resize(c->window, rect.x, rect.y, rect.width, rect.height); } else { c->fullscreen = true; xcb_get_geometry_reply_t *geom = xcb_get_geometry_reply(dpy, xcb_get_geometry(dpy, c->window), NULL); if (geom != NULL) { - c->rectangle = (xcb_rectangle_t) {geom->x, geom->y, geom->width, geom->height}; + c->floating_rectangle = (xcb_rectangle_t) {geom->x, geom->y, geom->width, geom->height}; free(geom); } xcb_atom_t values[] = {ewmh->_NET_WM_STATE_FULLSCREEN};