]> git.sur5r.net Git - i3/i3/blobdiff - src/commands.c
Fix unaligned memory access on sparc (Thanks David Coppa)
[i3/i3] / src / commands.c
index 6276ac199b3ee60a70173b7427b05fb61b8e8a53..18181a61de61d20c7811e250a4861bdb2ae4960c 100644 (file)
@@ -73,8 +73,8 @@ static void jump_to_mark(xcb_connection_t *conn, const char *mark) {
                         if (current->mark == NULL || strcmp(current->mark, mark) != 0)
                                 continue;
 
-                        workspace_show(conn, current->workspace->num + 1);
                         set_focus(conn, current, true);
+                        workspace_show(conn, current->workspace->num + 1);
                         return;
                 }
 
@@ -593,11 +593,16 @@ static void move_floating_window_to_workspace(xcb_connection_t *conn, Client *cl
                 uint32_t relative_x = client->rect.x - old_ws->rect.x,
                          relative_y = client->rect.y - old_ws->rect.y;
                 DLOG("rel_x = %d, rel_y = %d\n", relative_x, relative_y);
-                client->rect.x = t_ws->rect.x + relative_x;
-                client->rect.y = t_ws->rect.y + relative_y;
-                DLOG("after x = %d, y = %d\n", client->rect.x, client->rect.y);
-                reposition_client(conn, client);
-                xcb_flush(conn);
+                if (client->fullscreen) {
+                        client_enter_fullscreen(conn, client, false);
+                        memcpy(&(client->rect), &(t_ws->rect), sizeof(Rect));
+                } else {
+                        client->rect.x = t_ws->rect.x + relative_x;
+                        client->rect.y = t_ws->rect.y + relative_y;
+                        DLOG("after x = %d, y = %d\n", client->rect.x, client->rect.y);
+                        reposition_client(conn, client);
+                        xcb_flush(conn);
+                }
         }
 
         /* Configure the window above all tiling windows (or below a fullscreen
@@ -620,8 +625,10 @@ static void move_floating_window_to_workspace(xcb_connection_t *conn, Client *cl
 
         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);
+        }
 }
 
 /*
@@ -696,6 +703,41 @@ static void move_current_window_to_workspace(xcb_connection_t *conn, int workspa
         }
 }
 
+/*
+ * Brings the given window class / title to the current workspace.
+ *
+ */
+static void bring_window_here(xcb_connection_t *conn, const char *arguments) {
+       char *classtitle;
+       Client *client;
+
+       /* The first character is a quote, this was checked before */
+       classtitle = sstrdup(arguments+1);
+       /* The last character is a quote, we just set it to NULL */
+       classtitle[strlen(classtitle)-1] = '\0';
+
+       if ((client = get_matching_client(conn, classtitle, NULL)) == NULL) {
+               free(classtitle);
+               ELOG("No matching client found.\n");
+               return;
+       }
+
+       /* This is the workspace num that we are on */
+       int current_workspace_num = c_ws->output->current_workspace->num + 1;
+       /* This is the workspace num that the client is on */
+       int clients_workspace_num = client->workspace->num + 1;
+
+       free(classtitle);
+       workspace_show(conn, clients_workspace_num);
+       set_focus(conn, client, true);
+       if (client_is_floating(client))
+               move_floating_window_to_workspace(conn, client, current_workspace_num);
+       else move_current_window_to_workspace(conn, current_workspace_num);
+       workspace_show(conn, current_workspace_num);
+       set_focus(conn, client, true);
+
+}
+
 /*
  * Jumps to the given window class / title.
  * Title is matched using strstr, that is, matches if it appears anywhere
@@ -719,6 +761,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);
 }
 
@@ -858,6 +901,33 @@ static void next_previous_workspace(xcb_connection_t *conn, int direction) {
         }
 }
 
+static void parse_move_command(xcb_connection_t *conn, Client *last_focused, const char *command) {
+        if (!client_is_floating(last_focused)) {
+                LOG("You can only move floating clients with the \"move\" command\n");
+                return;
+        }
+
+        DLOG("Moving a floating client\n");
+        if (STARTS_WITH(command, "left")) {
+                command += strlen("left");
+                last_focused->rect.x -= atoi(command);
+        } else if (STARTS_WITH(command, "right")) {
+                command += strlen("right");
+                last_focused->rect.x += atoi(command);
+        } else if (STARTS_WITH(command, "top")) {
+                command += strlen("top");
+                last_focused->rect.y -= atoi(command);
+        } else if (STARTS_WITH(command, "bottom")) {
+                command += strlen("bottom");
+                last_focused->rect.y += atoi(command);
+        } else {
+                ELOG("Syntax: move <left|right|top|bottom> <pixels>\n");
+                return;
+        }
+        /* resize_client flushes */
+        resize_client(conn, last_focused);
+}
+
 static void parse_resize_command(xcb_connection_t *conn, Client *last_focused, const char *command) {
         int first, second;
         resize_orientation_t orientation = O_VERTICAL;
@@ -868,15 +938,15 @@ static void parse_resize_command(xcb_connection_t *conn, Client *last_focused, c
                 DLOG("Resizing a floating client\n");
                 if (STARTS_WITH(command, "left")) {
                         command += strlen("left");
-                        last_focused->rect.width += atoi(command);
-                        last_focused->rect.x -= atoi(command);
+                        last_focused->rect.width -= atoi(command);
+                        last_focused->rect.x += atoi(command);
                 } else if (STARTS_WITH(command, "right")) {
                         command += strlen("right");
                         last_focused->rect.width += atoi(command);
                 } else if (STARTS_WITH(command, "top")) {
                         command += strlen("top");
-                        last_focused->rect.height += atoi(command);
-                        last_focused->rect.y -= atoi(command);
+                        last_focused->rect.height -= atoi(command);
+                        last_focused->rect.y += atoi(command);
                 } else if (STARTS_WITH(command, "bottom")) {
                         command += strlen("bottom");
                         last_focused->rect.height += atoi(command);
@@ -1022,6 +1092,14 @@ void parse_command(xcb_connection_t *conn, const char *command) {
                 return;
         }
 
+        if (STARTS_WITH(command, "move ")) {
+                if (last_focused == NULL)
+                        return;
+                const char *rest = command + strlen("move ");
+                parse_move_command(conn, last_focused, rest);
+                return;
+        }
+
         if (STARTS_WITH(command, "mode ")) {
                 const char *rest = command + strlen("mode ");
                 switch_mode(conn, rest);
@@ -1039,6 +1117,9 @@ void parse_command(xcb_connection_t *conn, const char *command) {
         /* 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;
         }
 
@@ -1058,6 +1139,13 @@ void parse_command(xcb_connection_t *conn, const char *command) {
                 return;
         }
 
+        if (STARTS_WITH(command, "bring ")) {
+                const char *arguments = command + strlen("bring ");
+                if (arguments[0] == '"')
+                        bring_window_here(conn, arguments);
+                return;
+        }
+
         /* Is it a jump to a specified workspace, row, col? */
         if (STARTS_WITH(command, "jump ")) {
                 const char *arguments = command + strlen("jump ");
@@ -1165,6 +1253,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);