]> git.sur5r.net Git - i3/i3/commitdiff
Implement moving windows to other workspaces
authorMichael Stapelberg <michael+x200@stapelberg.de>
Wed, 4 Mar 2009 07:59:03 +0000 (08:59 +0100)
committerMichael Stapelberg <michael+x200@stapelberg.de>
Wed, 4 Mar 2009 07:59:03 +0000 (08:59 +0100)
include/data.h
man/i3.man
src/commands.c
src/table.c

index 3c308c6b46837c1dccad051825c0c96095c47bbb..9b82a85950082235b6fb531055f658f3d5e748f6 100644 (file)
@@ -121,6 +121,9 @@ struct Stack_Window {
  *
  */
 struct Workspace {
+        /* Number of this workspace, starting from 0 */
+        int num;
+
         /* x, y, width, height */
         Rect rect;
 
index 552a395912ac74410882944e02a02bb37a45ada5..fc62ef37b98fae35e9e44b5b3de13288afc5e884 100644 (file)
@@ -147,6 +147,11 @@ bind Mod1+Shift+46 mk
 bind Mod1+Shift+47 ml
 # Workspaces
 bind Mod1+10 1
+bind Mod1+11 2
+...
+# Move to Workspace
+bind Mod1+Shift+10 1
+bind Mod1+Shift+11 2
 ...
 -------------------------------------------------------------
 
index bc5800d401e63c8e3472b5e51bae0034562a5d89..4fb6e702f2702f03ecaf26449aac9b71c7eae06c 100644 (file)
@@ -140,6 +140,7 @@ static void move_current_window(xcb_connection_t *connection, direction_t direct
 
         switch (direction) {
                 case D_LEFT:
+                        /* TODO: If we’re at the left-most position, move the rest of the table right */
                         if (current_col == 0)
                                 return;
 
@@ -252,6 +253,60 @@ static void snap_current_container(xcb_connection_t *connection, direction_t dir
         render_layout(connection);
 }
 
+/*
+ * Moves the currently selected window to the given workspace
+ *
+ */
+static void move_current_window_to_workspace(xcb_connection_t *connection, int workspace) {
+        printf("Moving current window to workspace %d\n", workspace);
+
+        Container *container = CUR_CELL;
+
+        assert(container != NULL);
+
+        /* t_ws (to workspace) is just a container pointer to the workspace we’re switching to */
+        Workspace *t_ws = &(workspaces[workspace-1]);
+
+        Client *current_client = container->currently_focused;
+        if (current_client == NULL) {
+                printf("No currently focused client in current container.\n");
+                return;
+        }
+        Client *to_focus = CIRCLEQ_NEXT_OR_NULL(&(container->clients), current_client, clients);
+        if (to_focus == NULL)
+                to_focus = CIRCLEQ_PREV_OR_NULL(&(container->clients), current_client, clients);
+
+        if (t_ws->screen == NULL) {
+                printf("initializing new workspace, setting num to %d\n", workspace-1);
+                t_ws->screen = container->workspace->screen;
+                /* Copy the dimensions from the virtual screen */
+               memcpy(&(t_ws->rect), &(container->workspace->screen->rect), sizeof(Rect));
+        }
+
+        Container *to_container = t_ws->table[t_ws->current_col][t_ws->current_row];
+
+        assert(to_container != NULL);
+
+        CIRCLEQ_REMOVE(&(container->clients), current_client, clients);
+        CIRCLEQ_INSERT_TAIL(&(to_container->clients), current_client, clients);
+        printf("Moved.\n");
+
+        current_client->container = to_container;
+        container->currently_focused = to_focus;
+        to_container->currently_focused = current_client;
+
+        /* If we’re moving it to an invisible screen, we need to unmap it */
+        if (to_container->workspace->screen->current_workspace != to_container->workspace->num) {
+                printf("This workspace is not visible, unmapping\n");
+                xcb_unmap_window(connection, current_client->frame);
+        }
+
+        /* delete all empty columns/rows */
+        cleanup_table(connection, container->workspace);
+
+        render_layout(connection);
+}
+
 static void show_workspace(xcb_connection_t *conn, int workspace) {
         Client *client;
         xcb_window_t root = xcb_setup_roots_iterator(xcb_get_setup(conn)).data->root;
@@ -274,7 +329,7 @@ static void show_workspace(xcb_connection_t *conn, int workspace) {
 
         if (c_ws->screen != t_ws->screen) {
                 /* We need to switch to the other screen first */
-                printf("Just moving over to other screen.\n");
+                printf("moving over to other screen.\n");
                 c_ws = &(workspaces[t_ws->screen->current_workspace]);
                 current_col = c_ws->current_col;
                 current_row = c_ws->current_row;
@@ -381,11 +436,10 @@ void parse_command(xcb_connection_t *conn, const char *command) {
         }
 
         /* It's a normal <cmd> */
-        int times;
         char *rest = NULL;
         enum { ACTION_FOCUS, ACTION_MOVE, ACTION_SNAP } action = ACTION_FOCUS;
         direction_t direction;
-        times = strtol(command, &rest, 10);
+        int times = strtol(command, &rest, 10);
         if (rest == NULL) {
                 printf("Invalid command (\"%s\")\n", command);
                 return;
@@ -402,6 +456,18 @@ void parse_command(xcb_connection_t *conn, const char *command) {
                 rest++;
         }
 
+        int workspace = strtol(rest, &rest, 10);
+
+        if (rest == NULL) {
+                printf("Invalid command (\"%s\")\n", command);
+                return;
+        }
+
+        if (*rest == '\0') {
+                move_current_window_to_workspace(conn, workspace);
+                return;
+        }
+
         /* Now perform action to <where> */
         while (*rest != '\0') {
                 if (*rest == 'h')
index be6b8fe1b9503ac382ada489927d99d03922d9f9..adec640dc06373ac4d1fb32c0db313929f967d43 100644 (file)
@@ -40,6 +40,7 @@ void init_table() {
 
         for (int i = 0; i < 10; i++) {
                 workspaces[i].screen = NULL;
+                workspaces[i].num = i;
                 SLIST_INIT(&(workspaces[i].dock_clients));
                 expand_table_cols(&(workspaces[i]));
                 expand_table_rows(&(workspaces[i]));