diff --git a/include/x.h b/include/x.h index df4ee276..29a8bec2 100644 --- a/include/x.h +++ b/include/x.h @@ -104,4 +104,11 @@ void x_set_name(Con *con, const char *name); */ void x_set_i3_atoms(); +/** + * Set warp_to coordinates. This will trigger on the next call to + * x_push_changes(). + * + */ +void x_set_warp_to(Rect *rect); + #endif diff --git a/src/con.c b/src/con.c index 5c5099c4..bf94d460 100644 --- a/src/con.c +++ b/src/con.c @@ -591,6 +591,13 @@ void con_move_to_workspace(Con *con, Con *workspace) { if (source_output != dest_output && workspace_is_visible(workspace)) { workspace_show(workspace->name); + + /* Unset warp_to if target con is floating. Otherwise, set warp_to to + * current target container. */ + if (con->type == CT_FLOATING_CON) + x_set_warp_to(NULL); + else + x_set_warp_to(&(con->rect)); } DLOG("Re-attaching container to %p / %s\n", next, next->name); diff --git a/src/tree.c b/src/tree.c index 55bf27d8..240c22a6 100644 --- a/src/tree.c +++ b/src/tree.c @@ -414,8 +414,10 @@ static bool _tree_next(Con *con, char way, orientation_t orientation, bool wrap) workspace_show(workspace->name); Con *focus = con_descend_direction(workspace, direction); - if (focus) + if (focus) { con_focus(focus); + x_set_warp_to(&(focus->rect)); + } return true; } diff --git a/src/workspace.c b/src/workspace.c index 5dd25357..cf1b4070 100644 --- a/src/workspace.c +++ b/src/workspace.c @@ -227,7 +227,7 @@ void workspace_show(const char *num) { /* Set mouse pointer */ Con *new_output = con_get_output(focused); if (old_output != new_output) { - xcb_warp_pointer_rect(conn, &next->rect); + x_set_warp_to(&next->rect); } /* Update the EWMH hints */ diff --git a/src/x.c b/src/x.c index 6235cfbc..30e6a1c4 100644 --- a/src/x.c +++ b/src/x.c @@ -12,6 +12,9 @@ xcb_window_t focused_id = XCB_NONE; static xcb_window_t *btt_stack; static int btt_stack_num; +/* Stores coordinates to warp mouse pointer to if set */ +static Rect *warp_to; + /* * Describes the X11 state we may modify (map state, position, window stack). * There is one entry per container. The state represents the current situation @@ -862,6 +865,11 @@ void x_push_changes(Con *con) { focused_id = root; } + if (warp_to) { + xcb_warp_pointer_rect(conn, warp_to); + warp_to = NULL; + } + xcb_flush(conn); DLOG("\n\n ENDING CHANGES\n\n"); @@ -937,3 +945,13 @@ void x_set_i3_atoms() { xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A_I3_CONFIG_PATH, A_UTF8_STRING, 8, strlen(current_configpath), current_configpath); } + +/* + * Set warp_to coordinates. This will trigger on the next call to + * x_push_changes(). + * + */ +void x_set_warp_to(Rect *rect) +{ + warp_to = rect; +} diff --git a/src/xcb.c b/src/xcb.c index a70f27fa..b11b0ca6 100644 --- a/src/xcb.c +++ b/src/xcb.c @@ -367,7 +367,9 @@ bool xcb_reply_contains_atom(xcb_get_property_reply_t *prop, xcb_atom_t atom) { * */ void xcb_warp_pointer_rect(xcb_connection_t *conn, Rect *rect) { - xcb_warp_pointer(conn, XCB_NONE, root, 0, 0, 0, 0, - rect->x + (rect->width / 2), - rect->y + (rect->height / 2)); + int mid_x = rect->x + (rect->width / 2); + int mid_y = rect->y + (rect->height / 2); + + LOG("warp pointer to: %d %d\n", mid_x, mid_y); + xcb_warp_pointer(conn, XCB_NONE, root, 0, 0, 0, 0, mid_x, mid_y); }