]> git.sur5r.net Git - i3/i3/blobdiff - src/commands.c
implement 'move' command in the new parser
[i3/i3] / src / commands.c
index 184394b40323e747421206df634d4e903e1119f1..2d8155f276a162494db56b6ce416566875b2861a 100644 (file)
@@ -33,6 +33,7 @@
 #include "log.h"
 #include "sighandler.h"
 #include "manage.h"
+#include "ipc.h"
 
 bool focus_window_in_container(xcb_connection_t *conn, Container *container, direction_t direction) {
         /* If this container is empty, we’re done */
@@ -185,9 +186,26 @@ static void focus_thing(xcb_connection_t *conn, direction_t direction, thing_t t
                                         continue;
 
                                 new_col = cols;
+                                DLOG("Fixed it to new col %d\n", new_col);
+                                break;
+                        }
+                }
+
+                if (t_ws->table[new_col][new_row]->currently_focused == NULL) {
+                        DLOG("Cell still empty, checking for full cols above spanned width...\n");
+                        DLOG("new_col = %d\n", new_col);
+                        DLOG("colspan = %d\n", container->colspan);
+                        for (int cols = new_col;
+                             cols < container->col + container->colspan;
+                             cols += t_ws->table[cols][new_row]->colspan) {
+                                DLOG("candidate: new_row = %d, cols = %d\n", new_row, cols);
+                                if (t_ws->table[cols][new_row]->currently_focused == NULL)
+                                        continue;
+
+                                new_col = cols;
+                                DLOG("Fixed it to new col %d\n", new_col);
                                 break;
                         }
-                        DLOG("Fixed it to new col %d\n", new_col);
                 }
         } else if (direction == D_LEFT || direction == D_RIGHT) {
                 if (direction == D_RIGHT && cell_exists(t_ws, current_col+1, current_row))
@@ -227,10 +245,28 @@ static void focus_thing(xcb_connection_t *conn, direction_t direction, thing_t t
                                         continue;
 
                                 new_row = rows;
+                                DLOG("Fixed it to new row %d\n", new_row);
+                                break;
+                        }
+                }
+
+                if (t_ws->table[new_col][new_row]->currently_focused == NULL) {
+                        DLOG("Cell still empty, checking for full cols near full spanned height...\n");
+                        DLOG("new_row = %d\n", new_row);
+                        DLOG("rowspan = %d\n", container->rowspan);
+                        for (int rows = new_row;
+                             rows < container->row + container->rowspan;
+                             rows += t_ws->table[new_col][rows]->rowspan) {
+                                DLOG("candidate: new_col = %d, rows = %d\n", new_col, rows);
+                                if (t_ws->table[new_col][rows]->currently_focused == NULL)
+                                        continue;
+
+                                new_row = rows;
+                                DLOG("Fixed it to new col %d\n", new_row);
                                 break;
                         }
-                        DLOG("Fixed it to new row %d\n", new_row);
                 }
+
         } else {
                 ELOG("direction unhandled\n");
                 return;
@@ -564,12 +600,30 @@ static void move_floating_window_to_workspace(xcb_connection_t *conn, Client *cl
                 xcb_flush(conn);
         }
 
+        /* Configure the window above all tiling windows (or below a fullscreen
+         * window, if any) */
+        if (t_ws->fullscreen_client != NULL) {
+                uint32_t values[] = { t_ws->fullscreen_client->frame, XCB_STACK_MODE_BELOW };
+                xcb_configure_window(conn, client->frame, XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE, values);
+        } else {
+                Client *last_tiling;
+                SLIST_FOREACH(last_tiling, &(t_ws->focus_stack), focus_clients)
+                        if (!client_is_floating(last_tiling))
+                                break;
+                if (last_tiling != SLIST_END(&(t_ws->focus_stack))) {
+                        uint32_t values[] = { last_tiling->frame, XCB_STACK_MODE_ABOVE };
+                        xcb_configure_window(conn, client->frame, XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE, values);
+                }
+        }
+
         DLOG("done\n");
 
         render_layout(conn);
 
-        if (workspace_is_visible(t_ws))
+        if (workspace_is_visible(t_ws)) {
+                client_warp_pointer_into(conn, client);
                 set_focus(conn, client, true);
+        }
 }
 
 /*
@@ -629,7 +683,7 @@ static void move_current_window_to_workspace(xcb_connection_t *conn, int workspa
         } else {
                 if (current_client->fullscreen) {
                         DLOG("Calling client_enter_fullscreen again\n");
-                        client_enter_fullscreen(conn, current_client);
+                        client_enter_fullscreen(conn, current_client, false);
                 }
         }
 
@@ -667,6 +721,7 @@ static void jump_to_window(xcb_connection_t *conn, const char *arguments) {
         }
 
         free(classtitle);
+        workspace_show(conn, client->workspace->num + 1);
         set_focus(conn, client, true);
 }
 
@@ -980,12 +1035,16 @@ void parse_command(xcb_connection_t *conn, const char *command) {
         if (STARTS_WITH(command, "exit")) {
                 LOG("User issued exit-command, exiting without error.\n");
                 restore_geometry(global_conn);
+                ipc_shutdown();
                 exit(EXIT_SUCCESS);
         }
 
         /* Is it a <reload>? */
         if (STARTS_WITH(command, "reload")) {
                 load_configuration(conn, NULL, true);
+                render_layout(conn);
+                /* Send an IPC event just in case the ws names have changed */
+                ipc_send_event("workspace", I3_IPC_EVENT_WORKSPACE, "{\"change\":\"reload\"}");
                 return;
         }
 
@@ -1021,11 +1080,14 @@ void parse_command(xcb_connection_t *conn, const char *command) {
                 return;
         }
 
-        /* Is it 'f' for fullscreen? */
+        /* Is it 'f' for fullscreen, or 'fg' for fullscreen_global? */
         if (command[0] == 'f') {
                 if (last_focused == NULL)
                         return;
-                client_toggle_fullscreen(conn, last_focused);
+                if (command[1] == 'g')
+                        client_toggle_fullscreen_global(conn, last_focused);
+                else
+                        client_toggle_fullscreen(conn, last_focused);
                 return;
         }
 
@@ -1109,6 +1171,9 @@ void parse_command(xcb_connection_t *conn, const char *command) {
 
                 Workspace *ws = last_focused->workspace;
 
+                if (last_focused->fullscreen)
+                        client_leave_fullscreen(conn, last_focused);
+
                 toggle_floating_mode(conn, last_focused, false);
                 /* delete all empty columns/rows */
                 cleanup_table(conn, ws);