]> git.sur5r.net Git - i3/i3/commitdiff
Implemented new command 'move [window|container] [to] position mouse|cursor|pointer
authorIngo Bürk <ingo.buerk@tngtech.com>
Sat, 2 May 2015 22:19:26 +0000 (00:19 +0200)
committerIngo Bürk <ingo.buerk@tngtech.com>
Tue, 12 May 2015 21:46:06 +0000 (17:46 -0400)
fixes #1696

include/commands.h
include/floating.h
parser-specs/commands.spec
src/commands.c
src/floating.c

index bbcd7f6f5bb91dcbda16494c92b8aa9ae7880f65..afb3c32abb605fd04a4c95ece8f18def5f04f273 100644 (file)
@@ -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'.
  *
index 5e7b8e31361f5873347ed98a1109ecbb960a305d..78e75be8fd35d9589dea7ac873131a8fdaf4cac9 100644 (file)
@@ -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
index 1cd8d2f6789686dda558edb5f102e4ff3140bffd..8d497cd140d4eeb3a335b66c36bb4c0e7208dcc4 100644 (file)
@@ -271,6 +271,7 @@ state RENAME_WORKSPACE_NEW_NAME:
 # move workspace to [output] <str>
 # move scratchpad
 # move [window|container] [to] [absolute] position [ [<pixels> [px] <pixels> [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
 
index 3263dd0394b0d73216151f454e31bbb214f6bb22..1f5c8f44ebecfe074ac0e389081992bb1ab8a2e2 100644 (file)
@@ -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'.
  *
index f5641fffa3b81941e2da4ce5e043f8529ba535e8..d44334fe5b6ccdefc43a7c2ddcd5cb930474eb52 100644 (file)
@@ -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;