From 4a585748a475b23f55aa6b62cd1029453f15fb86 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Ingo=20B=C3=BCrk?= Date: Sun, 3 May 2015 00:19:26 +0200 Subject: [PATCH] Implemented new command 'move [window|container] [to] position mouse|cursor|pointer fixes #1696 --- include/commands.h | 6 ++++++ include/floating.h | 6 ++++++ parser-specs/commands.spec | 3 +++ src/commands.c | 24 ++++++++++++++++++++++++ src/floating.c | 32 ++++++++++++++++++++++++++++++++ 5 files changed, 71 insertions(+) diff --git a/include/commands.h b/include/commands.h index bbcd7f6f..afb3c32a 100644 --- a/include/commands.h +++ b/include/commands.h @@ -258,6 +258,12 @@ void cmd_move_window_to_position(I3_CMD, char *method, char *x, char *y); */ void cmd_move_window_to_center(I3_CMD, char *method); +/** + * Implementation of 'move [window|container] [to] position mouse' + * + */ +void cmd_move_window_to_mouse(I3_CMD); + /** * Implementation of 'move scratchpad'. * diff --git a/include/floating.h b/include/floating.h index 5e7b8e31..78e75be8 100644 --- a/include/floating.h +++ b/include/floating.h @@ -70,6 +70,12 @@ bool floating_maybe_reassign_ws(Con *con); */ void floating_center(Con *con, Rect rect); +/** + * Moves the given floating con to the current pointer position. + * + */ +void floating_move_to_pointer(Con *con); + #if 0 /** * Removes the floating client from its workspace and attaches it to the new diff --git a/parser-specs/commands.spec b/parser-specs/commands.spec index 1cd8d2f6..8d497cd1 100644 --- a/parser-specs/commands.spec +++ b/parser-specs/commands.spec @@ -271,6 +271,7 @@ state RENAME_WORKSPACE_NEW_NAME: # move workspace to [output] # move scratchpad # move [window|container] [to] [absolute] position [ [ [px] [px]] | center ] +# move [window|container] [to] position mouse|cursor|pointer state MOVE: 'window' -> @@ -342,6 +343,8 @@ state MOVE_TO_ABSOLUTE_POSITION: state MOVE_TO_POSITION: 'center' -> call cmd_move_window_to_center($method) + 'mouse', 'cursor', 'pointer' + -> call cmd_move_window_to_mouse() coord_x = word -> MOVE_TO_POSITION_X diff --git a/src/commands.c b/src/commands.c index 3263dd03..1f5c8f44 100644 --- a/src/commands.c +++ b/src/commands.c @@ -1833,6 +1833,30 @@ void cmd_move_window_to_center(I3_CMD, char *method) { ysuccess(true); } +/* + * Implementation of 'move [window|container] [to] position mouse' + * + */ +void cmd_move_window_to_mouse(I3_CMD) { + HANDLE_EMPTY_MATCH; + + owindow *current; + TAILQ_FOREACH(current, &owindows, owindows) { + Con *floating_con = con_inside_floating(current->con); + if (floating_con == NULL) { + DLOG("con %p / %s is not floating, cannot move it to the mouse position.\n", + current->con, current->con->name); + continue; + } + + DLOG("moving floating container %p / %s to cursor position\n", floating_con, floating_con->name); + floating_move_to_pointer(floating_con); + } + + cmd_output->needs_tree_render = true; + ysuccess(true); +} + /* * Implementation of 'move scratchpad'. * diff --git a/src/floating.c b/src/floating.c index f5641fff..d44334fe 100644 --- a/src/floating.c +++ b/src/floating.c @@ -426,6 +426,38 @@ void floating_center(Con *con, Rect rect) { con->rect.y = rect.y + (rect.height / 2) - (con->rect.height / 2); } +/* + * Moves the given floating con to the current pointer position. + * + */ +void floating_move_to_pointer(Con *con) { + assert(con->type == CT_FLOATING_CON); + + xcb_query_pointer_reply_t *reply = xcb_query_pointer_reply(conn, xcb_query_pointer(conn, root), NULL); + if (reply == NULL) { + ELOG("could not query pointer position, not moving this container\n"); + return; + } + + Output *output = get_output_containing(reply->root_x, reply->root_y); + + /* Determine where to put the window. */ + int32_t x = reply->root_x - con->rect.width / 2; + int32_t y = reply->root_y - con->rect.height / 2; + FREE(reply); + + /* Correct target coordinates to be in-bounds. */ + x = MAX(x, (int32_t)output->rect.x); + y = MAX(y, (int32_t)output->rect.y); + if (x + con->rect.width > output->rect.x + output->rect.width) + x = output->rect.x + output->rect.width - con->rect.width; + if (y + con->rect.height > output->rect.y + output->rect.height) + y = output->rect.y + output->rect.height - con->rect.height; + + /* Update container's coordinates to position it correctly. */ + floating_reposition(con, (Rect){x, y, con->rect.width, con->rect.height}); +} + DRAGGING_CB(drag_window_callback) { const struct xcb_button_press_event_t *event = extra; -- 2.39.2