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.
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.
/* 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;
}
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.
/* 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);
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);