Bugfix: Track the user’s pointer over the root window and update current workspace (Thanks xeen)
When not having any windows on the first workspace, switching to the second workspace using your mouse was not registered by i3.
This commit is contained in:
parent
20875494ee
commit
3bd724f08d
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue