]> git.sur5r.net Git - i3/i3/commitdiff
Bugfix: Track the user’s pointer over the root window and update current workspace...
authorMichael Stapelberg <michael@stapelberg.de>
Wed, 5 Aug 2009 22:59:48 +0000 (00:59 +0200)
committerMichael Stapelberg <michael@stapelberg.de>
Wed, 5 Aug 2009 22:59:48 +0000 (00:59 +0200)
When not having any windows on the first workspace, switching to the
second workspace using your mouse was not registered by i3.

include/handlers.h
src/handlers.c
src/mainx.c

index 83b70894b5df483ed60e44b78d63b76b36cdd51d..5b776de78b0768fc68db9c2f533710ee6a909362 100644 (file)
@@ -35,6 +35,15 @@ int handle_key_press(void *ignored, xcb_connection_t *conn,
 int handle_enter_notify(void *ignored, xcb_connection_t *conn,
                         xcb_enter_notify_event_t *event);
 
+/**
+ * When the user moves the mouse but does not change the active window
+ * (e.g. when having no windows opened but moving mouse on the root screen
+ * and crossing virtual screen boundaries), this callback gets called.
+ *
+ */
+int handle_motion_notify(void *ignored, xcb_connection_t *conn,
+                         xcb_motion_notify_event_t *event);
+
 /**
  * Checks if the button press was on a stack window, handles focus setting and
  * returns true if so, or false otherwise.
index 9a402629f2dd175883f651f9c69e0a538536317b..ffbde9fabb37f8fecfdb5f54b91fe27f81751694 100644 (file)
@@ -140,6 +140,29 @@ int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press_event_
         return 1;
 }
 
+/*
+ * Called with coordinates of an enter_notify event or motion_notify event
+ * to check if the user crossed virtual screen boundaries and adjust the
+ * current workspace, if so.
+ *
+ */
+static void check_crossing_screen_boundary(uint32_t x, uint32_t y) {
+        i3Screen *screen;
+
+        if ((screen = get_screen_containing(x, y)) == NULL) {
+                LOG("ERROR: No such screen\n");
+                return;
+        }
+        if (screen == c_ws->screen)
+                return;
+
+        c_ws->current_row = current_row;
+        c_ws->current_col = current_col;
+        c_ws = &workspaces[screen->current_workspace];
+        current_row = c_ws->current_row;
+        current_col = c_ws->current_col;
+        LOG("We're now on virtual screen number %d\n", screen->num);
+}
 
 /*
  * When the user moves the mouse pointer onto a window, this callback gets called.
@@ -176,17 +199,7 @@ int handle_enter_notify(void *ignored, xcb_connection_t *conn, xcb_enter_notify_
         /* If not, then the user moved his cursor to the root window. In that case, we adjust c_ws */
         if (client == NULL) {
                 LOG("Getting screen at %d x %d\n", event->root_x, event->root_y);
-                i3Screen *screen = get_screen_containing(event->root_x, event->root_y);
-                if (screen == NULL) {
-                        LOG("ERROR: No such screen\n");
-                        return 0;
-                }
-                c_ws->current_row = current_row;
-                c_ws->current_col = current_col;
-                c_ws = &workspaces[screen->current_workspace];
-                current_row = c_ws->current_row;
-                current_col = c_ws->current_col;
-                LOG("We're now on virtual screen number %d\n", screen->num);
+                check_crossing_screen_boundary(event->root_x, event->root_y);
                 return 1;
         }
 
@@ -212,6 +225,20 @@ int handle_enter_notify(void *ignored, xcb_connection_t *conn, xcb_enter_notify_
         return 1;
 }
 
+/*
+ * When the user moves the mouse but does not change the active window
+ * (e.g. when having no windows opened but moving mouse on the root screen
+ * and crossing virtual screen boundaries), this callback gets called.
+ *
+ */
+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);
+
+        check_crossing_screen_boundary(event->root_x, event->root_y);
+
+        return 1;
+}
+
 /*
  * Checks if the button press was on a stack window, handles focus setting and returns true
  * if so, or false otherwise.
index 27e026b57ec3881b2d3bcba92d06a617993fe40f..a26a957f90789f11ec7525516238ff1ca8ab4de2 100644 (file)
@@ -257,6 +257,10 @@ int main(int argc, char *argv[], char *env[]) {
         /* Configure request = window tried to change size on its own */
         xcb_event_set_configure_request_handler(&evenths, handle_configure_request, NULL);
 
+        /* Motion notify = user moved his cursor (over the root window and may
+         * cross virtual screen boundaries doing that) */
+        xcb_event_set_motion_notify_handler(&evenths, handle_motion_notify, NULL);
+
         /* Client message are sent to the root window. The only interesting client message
            for us is _NET_WM_STATE, we honour _NET_WM_STATE_FULLSCREEN */
         xcb_event_set_client_message_handler(&evenths, handle_client_message, NULL);
@@ -277,6 +281,7 @@ int main(int argc, char *argv[], char *env[]) {
                               XCB_EVENT_MASK_STRUCTURE_NOTIFY |         /* when the user adds a screen (e.g. video
                                                                            projector), the root window gets a
                                                                            ConfigureNotify */
+                              XCB_EVENT_MASK_POINTER_MOTION |
                               XCB_EVENT_MASK_PROPERTY_CHANGE |
                               XCB_EVENT_MASK_ENTER_WINDOW };
         xcb_change_window_attributes(conn, root, mask, values);