diff --git a/include/client.h b/include/client.h index 81cb5c6e..9d47edaf 100644 --- a/include/client.h +++ b/include/client.h @@ -97,4 +97,10 @@ void client_unmap(xcb_connection_t *conn, Client *client); */ void client_map(xcb_connection_t *conn, Client *client); +/** + * Pretty-prints the client’s information into the logfile. + * + */ +void client_log(Client *client); + #endif diff --git a/include/xinerama.h b/include/xinerama.h index d4e7bb56..135ab1ab 100644 --- a/include/xinerama.h +++ b/include/xinerama.h @@ -57,6 +57,6 @@ i3Screen *get_screen_containing(int x, int y); * This function always returns a screen. * */ -i3Screen *get_screen_most(direction_t direction); +i3Screen *get_screen_most(direction_t direction, i3Screen *current); #endif diff --git a/src/client.c b/src/client.c index a4269805..12125d8b 100644 --- a/src/client.c +++ b/src/client.c @@ -314,3 +314,11 @@ void client_map(xcb_connection_t *conn, Client *client) { xcb_map_window(conn, client->frame); } + +/* + * Pretty-prints the client’s information into the logfile. + * + */ +void client_log(Client *client) { + LOG("Window: frame 0x%08x, child 0x%08x\n", client->frame, client->child); +} diff --git a/src/commands.c b/src/commands.c index 6472d860..afb16704 100644 --- a/src/commands.c +++ b/src/commands.c @@ -104,12 +104,12 @@ static void focus_thing(xcb_connection_t *conn, direction_t direction, thing_t t LOG("Target screen NULL\n"); /* Wrap around if the target screen is out of bounds */ if (direction == D_RIGHT) - target = get_screen_most(D_LEFT); + target = get_screen_most(D_LEFT, cs); else if (direction == D_LEFT) - target = get_screen_most(D_RIGHT); + target = get_screen_most(D_RIGHT, cs); else if (direction == D_UP) - target = get_screen_most(D_DOWN); - else target = get_screen_most(D_UP); + target = get_screen_most(D_DOWN, cs); + else target = get_screen_most(D_UP, cs); } LOG("Switching to ws %d\n", target->current_workspace + 1); @@ -146,7 +146,7 @@ static void focus_thing(xcb_connection_t *conn, direction_t direction, thing_t t if ((screen = get_screen_containing(container->x, destination_y)) == NULL) { LOG("Wrapping screen around vertically\n"); /* No screen found? Then wrap */ - screen = get_screen_most((direction == D_UP ? D_DOWN : D_UP)); + screen = get_screen_most((direction == D_UP ? D_DOWN : D_UP), container->workspace->screen); } t_ws = &(workspaces[screen->current_workspace]); new_row = (direction == D_UP ? (t_ws->rows - 1) : 0); @@ -188,7 +188,7 @@ static void focus_thing(xcb_connection_t *conn, direction_t direction, thing_t t int destination_x = (direction == D_LEFT ? (container->x - 1) : (container->x + container->width + 1)); if ((screen = get_screen_containing(destination_x, container->y)) == NULL) { LOG("Wrapping screen around horizontally\n"); - screen = get_screen_most((direction == D_LEFT ? D_RIGHT : D_LEFT)); + screen = get_screen_most((direction == D_LEFT ? D_RIGHT : D_LEFT), container->workspace->screen); } t_ws = &(workspaces[screen->current_workspace]); new_col = (direction == D_LEFT ? (t_ws->cols - 1) : 0); diff --git a/src/handlers.c b/src/handlers.c index 0f450c70..1e10705a 100644 --- a/src/handlers.c +++ b/src/handlers.c @@ -248,7 +248,10 @@ int handle_enter_notify(void *ignored, xcb_connection_t *conn, xcb_enter_notify_ * */ int handle_motion_notify(void *ignored, xcb_connection_t *conn, xcb_motion_notify_event_t *event) { - LOG("pointer motion notify, getting screen at %d x %d\n", event->root_x, event->root_y); + /* Skip events where the pointer was over a child window, we are only + * interested in events on the root window. */ + if (event->child != 0) + return 1; check_crossing_screen_boundary(event->root_x, event->root_y); @@ -261,20 +264,17 @@ int handle_motion_notify(void *ignored, xcb_connection_t *conn, xcb_motion_notif * */ int handle_mapping_notify(void *ignored, xcb_connection_t *conn, xcb_mapping_notify_event_t *event) { - LOG("\n\nmapping notify\n\n"); - if (event->request != XCB_MAPPING_KEYBOARD && event->request != XCB_MAPPING_MODIFIER) return 0; + LOG("Received mapping_notify for keyboard or modifier mapping, re-grabbing keys\n"); xcb_refresh_keyboard_mapping(keysyms, event); xcb_get_numlock_mask(conn); ungrab_all_keys(conn); - LOG("Re-grabbing...\n"); grab_all_keys(conn); - LOG("Done\n"); return 0; } @@ -366,8 +366,7 @@ static bool button_press_bar(xcb_connection_t *conn, xcb_button_press_event_t *e } int handle_button_press(void *ignored, xcb_connection_t *conn, xcb_button_press_event_t *event) { - LOG("button press!\n"); - LOG("state = %d\n", event->state); + LOG("Button %d pressed\n", event->state); /* This was either a focus for a client’s parent (= titlebar)… */ Client *client = table_get(&by_child, event->event); bool border_click = false; @@ -523,13 +522,11 @@ int handle_map_request(void *prophs, xcb_connection_t *conn, xcb_map_request_eve * */ int handle_configure_request(void *prophs, xcb_connection_t *conn, xcb_configure_request_event_t *event) { - LOG("configure-request, serial %d\n", event->sequence); - LOG("event->window = %08x\n", event->window); - LOG("application wants to be at %dx%d with %dx%d\n", event->x, event->y, event->width, event->height); + LOG("window 0x%08x wants to be at %dx%d with %dx%d\n", + event->window, event->x, event->y, event->width, event->height); Client *client = table_get(&by_child, event->window); if (client == NULL) { - LOG("This client is not mapped, so we don't care and just tell the client that he will get its size\n"); uint32_t mask = 0; uint32_t values[7]; int c = 0; @@ -611,8 +608,6 @@ int handle_configure_request(void *prophs, xcb_connection_t *conn, xcb_configure int handle_configure_event(void *prophs, xcb_connection_t *conn, xcb_configure_notify_event_t *event) { xcb_window_t root = xcb_setup_roots_iterator(xcb_get_setup(conn)).data->root; - LOG("handle_configure_event for window %08x\n", event->window); - LOG("event->type = %d, \n", event->response_type); LOG("event->x = %d, ->y = %d, ->width = %d, ->height = %d\n", event->x, event->y, event->width, event->height); /* We ignore this sequence twice because events for child and frame should be ignored */ @@ -723,11 +718,8 @@ int handle_unmap_notify_event(void *data, xcb_connection_t *conn, xcb_unmap_noti break; } - if (workspace_empty) { - LOG("setting ws to NULL for workspace %d (%p)\n", client->workspace->num, - client->workspace); + if (workspace_empty) client->workspace->screen = NULL; - } FREE(client->window_class); FREE(client->name); @@ -748,7 +740,6 @@ int handle_unmap_notify_event(void *data, xcb_connection_t *conn, xcb_unmap_noti */ int handle_windowname_change(void *data, xcb_connection_t *conn, uint8_t state, xcb_window_t window, xcb_atom_t atom, xcb_get_property_reply_t *prop) { - LOG("window's name changed.\n"); if (prop == NULL || xcb_get_property_value_length(prop) == 0) { LOG("_NET_WM_NAME not specified, not changing\n"); return 1; @@ -763,7 +754,7 @@ int handle_windowname_change(void *data, xcb_connection_t *conn, uint8_t state, asprintf(&new_name, "%.*s", xcb_get_property_value_length(prop), (char*)xcb_get_property_value(prop)); /* Convert it to UCS-2 here for not having to convert it later every time we want to pass it to X */ char *ucs2_name = convert_utf8_to_ucs2(new_name, &new_len); - LOG("Name should change to \"%s\"\n", new_name); + LOG("_NET_WM_NAME changed to \"%s\"\n", new_name); free(new_name); /* Check if they are the same and don’t update if so. @@ -773,7 +764,6 @@ int handle_windowname_change(void *data, xcb_connection_t *conn, uint8_t state, if ((new_len == client->name_len) && (client->name != NULL) && (memcmp(client->name, ucs2_name, new_len * 2) == 0)) { - LOG("Name did not change, not updating\n"); free(ucs2_name); return 1; } @@ -810,7 +800,6 @@ int handle_windowname_change(void *data, xcb_connection_t *conn, uint8_t state, */ int handle_windowname_change_legacy(void *data, xcb_connection_t *conn, uint8_t state, xcb_window_t window, xcb_atom_t atom, xcb_get_property_reply_t *prop) { - LOG("window's name changed (legacy).\n"); if (prop == NULL || xcb_get_property_value_length(prop) == 0) { LOG("prop == NULL\n"); return 1; @@ -819,10 +808,9 @@ int handle_windowname_change_legacy(void *data, xcb_connection_t *conn, uint8_t if (client == NULL) return 1; - if (client->uses_net_wm_name) { - LOG("This client is capable of _NET_WM_NAME, ignoring legacy name\n"); + /* Client capable of _NET_WM_NAME, ignore legacy name changes */ + if (client->uses_net_wm_name) return 1; - } /* Save the old pointer to make the update atomic */ char *new_name; @@ -832,18 +820,17 @@ int handle_windowname_change_legacy(void *data, xcb_connection_t *conn, uint8_t return 1; } /* Convert it to UCS-2 here for not having to convert it later every time we want to pass it to X */ - LOG("Name should change to \"%s\"\n", new_name); + LOG("WM_NAME changed to \"%s\"\n", new_name); /* Check if they are the same and don’t update if so. */ if (client->name != NULL && strlen(new_name) == strlen(client->name) && strcmp(client->name, new_name) == 0) { - LOG("Name did not change, not updating\n"); free(new_name); return 1; } - LOG("Using legacy window title. Note that in order to get Unicode window titles in i3," + LOG("Using legacy window title. Note that in order to get Unicode window titles in i3, " "the application has to set _NET_WM_NAME which is in UTF-8 encoding.\n"); char *old_name = client->name; @@ -871,7 +858,6 @@ int handle_windowname_change_legacy(void *data, xcb_connection_t *conn, uint8_t */ int handle_windowclass_change(void *data, xcb_connection_t *conn, uint8_t state, xcb_window_t window, xcb_atom_t atom, xcb_get_property_reply_t *prop) { - LOG("window class changed\n"); if (prop == NULL || xcb_get_property_value_length(prop) == 0) { LOG("prop == NULL\n"); return 1; @@ -886,7 +872,7 @@ int handle_windowclass_change(void *data, xcb_connection_t *conn, uint8_t state, return 1; } - LOG("changed to %s\n", new_class); + LOG("WM_CLASS changed to %s\n", new_class); char *old_class = client->window_class; client->window_class = new_class; FREE(old_class); @@ -935,11 +921,8 @@ int handle_expose_event(void *data, xcb_connection_t *conn, xcb_expose_event_t * return 1; } - LOG("got client %s\n", client->name); - if (client->dock) { - LOG("this is a dock\n"); + if (client->dock) return 1; - } if (client->container == NULL || client->container->mode != MODE_STACK) decorate_window(conn, client, client->frame, client->titlegc, 0); @@ -976,14 +959,10 @@ int handle_expose_event(void *data, xcb_connection_t *conn, xcb_expose_event_t * * */ int handle_client_message(void *data, xcb_connection_t *conn, xcb_client_message_event_t *event) { - LOG("client_message\n"); - if (event->type == atoms[_NET_WM_STATE]) { if (event->format != 32 || event->data.data32[1] != atoms[_NET_WM_STATE_FULLSCREEN]) return 0; - LOG("fullscreen\n"); - Client *client = table_get(&by_child, event->window); if (client == NULL) return 0; @@ -1027,7 +1006,8 @@ int handle_normal_hints(void *data, xcb_connection_t *conn, uint8_t state, xcb_w return 1; } xcb_size_hints_t size_hints; - LOG("client is %08x / child %08x\n", client->frame, client->child); + + client_log(client); /* If the hints were already in this event, use them, if not, request them */ if (reply != NULL) @@ -1056,8 +1036,6 @@ int handle_normal_hints(void *data, xcb_connection_t *conn, uint8_t state, xcb_w return 1; } - LOG("window is %08x / %s\n", client->child, client->name); - int base_width = 0, base_height = 0; /* base_width/height are the desired size of the window. @@ -1112,7 +1090,6 @@ int handle_normal_hints(void *data, xcb_connection_t *conn, uint8_t state, xcb_w */ int handle_transient_for(void *data, xcb_connection_t *conn, uint8_t state, xcb_window_t window, xcb_atom_t name, xcb_get_property_reply_t *reply) { - LOG("Transient hint!\n"); Client *client = table_get(&by_child, window); if (client == NULL) { LOG("No such client\n"); @@ -1122,16 +1099,12 @@ int handle_transient_for(void *data, xcb_connection_t *conn, uint8_t state, xcb_ xcb_window_t transient_for; if (reply != NULL) { - if (!xcb_get_wm_transient_for_from_reply(&transient_for, reply)) { - LOG("Not transient for any window\n"); + if (!xcb_get_wm_transient_for_from_reply(&transient_for, reply)) return 1; - } } else { if (!xcb_get_wm_transient_for_reply(conn, xcb_get_wm_transient_for_unchecked(conn, window), - &transient_for, NULL)) { - LOG("Not transient for any window\n"); + &transient_for, NULL)) return 1; - } } if (client->floating == FLOATING_AUTO_OFF) { @@ -1149,7 +1122,6 @@ int handle_transient_for(void *data, xcb_connection_t *conn, uint8_t state, xcb_ */ int handle_clientleader_change(void *data, xcb_connection_t *conn, uint8_t state, xcb_window_t window, xcb_atom_t name, xcb_get_property_reply_t *prop) { - LOG("client leader changed\n"); if (prop == NULL) { prop = xcb_get_property_reply(conn, xcb_get_property_unchecked(conn, false, window, WM_CLIENT_LEADER, WINDOW, 0, 32), NULL); @@ -1163,7 +1135,7 @@ int handle_clientleader_change(void *data, xcb_connection_t *conn, uint8_t state if (leader == NULL) return 1; - LOG("changed to %08x\n", *leader); + LOG("Client leader changed to %08x\n", *leader); client->leader = *leader; diff --git a/src/layout.c b/src/layout.c index d40cf431..d628ef8f 100644 --- a/src/layout.c +++ b/src/layout.c @@ -448,7 +448,6 @@ static void render_bars(xcb_connection_t *conn, Workspace *r_ws, int width, int } static void render_internal_bar(xcb_connection_t *conn, Workspace *r_ws, int width, int height) { - LOG("Rendering internal bar\n"); i3Font *font = load_font(conn, config.font); i3Screen *screen = r_ws->screen; enum { SET_NORMAL = 0, SET_FOCUSED = 1 }; @@ -491,8 +490,6 @@ static void render_internal_bar(xcb_connection_t *conn, Workspace *r_ws, int wid (xcb_char2b_t*)ws->name); drawn += ws->text_width + 12; } - - LOG("done rendering internal\n"); } /* @@ -505,8 +502,6 @@ void ignore_enter_notify_forall(xcb_connection_t *conn, Workspace *workspace, bo Client *client; uint32_t values[1]; - LOG("Ignore enter_notify = %d\n", ignore_enter_notify); - FOR_TABLE(workspace) CIRCLEQ_FOREACH(client, &(workspace->table[cols][rows]->clients), clients) { /* Change event mask for the decorations */ diff --git a/src/xinerama.c b/src/xinerama.c index 3bf988e7..59e7e225 100644 --- a/src/xinerama.c +++ b/src/xinerama.c @@ -92,7 +92,7 @@ i3Screen *get_screen_containing(int x, int y) { * This function always returns a screen. * */ -i3Screen *get_screen_most(direction_t direction) { +i3Screen *get_screen_most(direction_t direction, i3Screen *current) { i3Screen *screen, *candidate = NULL; int position = 0; TAILQ_FOREACH(screen, virtual_screens, screens) { @@ -104,6 +104,14 @@ i3Screen *get_screen_most(direction_t direction) { } \ break; + if (((direction == D_UP) || (direction == D_DOWN)) && + (current->rect.x != screen->rect.x)) + continue; + + if (((direction == D_LEFT) || (direction == D_RIGHT)) && + (current->rect.y != screen->rect.y)) + continue; + switch (direction) { case D_UP: WIN(screen->rect.y, <= position);