]> git.sur5r.net Git - i3/i3/commitdiff
Bugfix: Fix screen wrapping, cleanup some log messages
authorMichael Stapelberg <michael@stapelberg.de>
Tue, 11 Aug 2009 13:02:30 +0000 (15:02 +0200)
committerMichael Stapelberg <michael@stapelberg.de>
Tue, 11 Aug 2009 13:02:30 +0000 (15:02 +0200)
Before this fix, you could go upwards and select the screen which
was at the rightmost because it also was the one topmost (if all
screen’s top position is equal).

include/client.h
include/xinerama.h
src/client.c
src/commands.c
src/handlers.c
src/layout.c
src/xinerama.c

index 81cb5c6e4991eee79663eaddea1ba2a82db9e0f2..9d47edafceef5f4132d52da2d4592257d14a48d6 100644 (file)
@@ -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
index d4e7bb56902c2dca5a2984eebe1babd93c682d8c..135ab1ab25e4c69d4d76f37c576bd10556eb7a10 100644 (file)
@@ -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
index a42698055c63f1849b6965abf4fe942183dbd957..12125d8b52d410caa77e0324607ca7732a456945 100644 (file)
@@ -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);
+}
index 6472d8604101e4d6e898fd2a0ddf733645998ab0..afb1670499a0aa1888dbdb91fb628aea76af131e 100644 (file)
@@ -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);
index 0f450c70ee37d0b2306cd1d59b00256e66a8e728..1e10705afc6ba0afef3c94ff4ccaba0cf1d2684d 100644 (file)
@@ -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;
 
index d40cf431a834d4b2df95775a7ee97242bb442aa4..d628ef8faee113b237ca03f4b3a81becdca5d8ff 100644 (file)
@@ -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 */
index 3bf988e74ff18d94f6ab5e0be021da08993287bd..59e7e225aae8696cba1f6d4103a8d3e455126461 100644 (file)
@@ -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);