]> git.sur5r.net Git - i3/i3/commitdiff
Implement a command to travel the focusstack. This can be used like a jumpback.
authorMichael Stapelberg <michael+x200@stapelberg.de>
Tue, 5 May 2009 15:25:56 +0000 (17:25 +0200)
committerMichael Stapelberg <michael+x200@stapelberg.de>
Tue, 5 May 2009 15:25:56 +0000 (17:25 +0200)
However, it is a bit more flexible obviously. You can specify the
offset of the window you want to go to, to implement workflows like
the following:
 * Jump to mutt
 * Jump to irssi
 * Jump back ("focus 2" would be the command)

CMDMODE
src/commands.c
src/handlers.c

diff --git a/CMDMODE b/CMDMODE
index 0231c7051b0e34f4e3f73431539b5aa872180c5e..7428729a9bded1e26d06e641e8bb66af56276ce3 100644 (file)
--- a/CMDMODE
+++ b/CMDMODE
@@ -1,40 +1,41 @@
-left := <h> | <cursor-left>
-right := <l> | <cursor-right>
-up := <j> | <cursor-up>
-down := <k> | <cursor-down>
-
-where := <left|right|up|down> | <tag>
-move := <m>
-snap := <s>
-
-Eingabe ist entweder
-
-cmd := [ <times> ] [ <move> | <snap> ] <where>
-
-oder
+---------------------
+- Command mode
+---------------------
 
-with := <w> { [ <times> ] <where> }+ <space> <cmd>
+This is the grammar for the command mode (your configuration file uses these commands, too).
 
-oder
-
-jump := [ "<window class>[/<window title>]" | <workspace> [ <column> <row> ] ]
-
-oder
+left  := <h> | <cursor-left>
+right := <l> | <cursor-right>
+up    := <j> | <cursor-up>
+down  := <k> | <cursor-down>
 
+where := <left|right|up|down> | <tag>
+move  := <m>
+snap  := <s>
+
+cmd     := [ <times> ] [ <move> | <snap> ] <where>
+with    := <w> { [ <times> ] <where> }+ <space> <cmd>
+jump    := [ "<window class>[/<window title>]" | <workspace> [ <column> <row> ] ]
+focus   := focus [ <times> ]
+(travels the focus stack backwards the given amount of times (by default 1), so
+ it selects the window which had the focus before you focused the current one when
+ specifying "focus 1")
 special := [ exec <path> | kill | exit | restart ]
 
-an jeder Stelle kann mit escape abgebrochen werden
+input := [ <cmd> | <with> | <jump> | <focus> | <special> ]
+
+you can cancel command mode by pressing escape anytime.
 
-Beispiele:
+Some examples:
 
-Fenster links neben dem aktuellen auswählen:
+Select the window on the left:
 h
 
-Fenster zwei links neben dem aktuellen auswählen:
+Select the window two places on the left:
 2h
 
-Fenster nach rechts verschieben:
+Move window to the right:
 ml
 
-Fenster und Fenster untendrunter nach rechts verschieben:
+Move window and window on the bottom to the right:
 wk ml
index 111dce5561488eb426426d6c4c63caf16d9fb9df..c0f5ffdd562042d7aab1388d656e9a2a161daf52 100644 (file)
@@ -648,10 +648,11 @@ static void jump_to_window(xcb_connection_t *conn, const char *arguments) {
 
                         CIRCLEQ_FOREACH(client, &(con->clients), clients) {
                                 LOG("Checking client with class=%s, name=%s\n", client->window_class, client->name);
-                                if (client_matches_class_name(client, to_class, to_title, to_title_ucs, to_title_ucs_len)) {
-                                        set_focus(conn, client);
-                                        goto done;
-                                }
+                                if (!client_matches_class_name(client, to_class, to_title, to_title_ucs, to_title_ucs_len))
+                                        continue;
+
+                                set_focus(conn, client, true);
+                                goto done;
                         }
                 }
         }
@@ -695,7 +696,37 @@ static void jump_to_container(xcb_connection_t *conn, const char *arguments) {
 
         LOG("Jumping to col %d, row %d\n", col, row);
         if (c_ws->table[col][row]->currently_focused != NULL)
-                set_focus(conn, c_ws->table[col][row]->currently_focused);
+                set_focus(conn, c_ws->table[col][row]->currently_focused, true);
+}
+
+/*
+ * Travels the focus stack by the given number of times (or once, if no argument
+ * was specified). That is, selects the window you were in before you focused
+ * the current window.
+ *
+ */
+static void travel_focus_stack(xcb_connection_t *conn, const char *arguments) {
+        /* Start count at -1 to always skip the first element */
+        int times, count = -1;
+        Client *current;
+
+        if (sscanf(arguments, "%u", &times) != 1) {
+                LOG("No or invalid argument given (\"%s\"), using default of 1 times\n", arguments);
+                times = 1;
+        }
+
+        Workspace *ws = CUR_CELL->workspace;
+
+        SLIST_FOREACH(current, &(ws->focus_stack), focus_clients) {
+                if (++count < times) {
+                        LOG("Skipping\n");
+                        continue;
+                }
+
+                LOG("Focussing\n");
+                set_focus(conn, current, true);
+                break;
+        }
 }
 
 /*
@@ -739,7 +770,7 @@ void parse_command(xcb_connection_t *conn, const char *command) {
                 return;
         }
 
-        /* Is it a jump to a specified workspae,row,col? */
+        /* Is it a jump to a specified workspae, row, col? */
         if (STARTS_WITH(command, "jump ")) {
                 const char *arguments = command + strlen("jump ");
                 if (arguments[0] == '"')
@@ -748,6 +779,13 @@ void parse_command(xcb_connection_t *conn, const char *command) {
                 return;
         }
 
+        /* Should we travel the focus stack? */
+        if (STARTS_WITH(command, "focus")) {
+                const char *arguments = command + strlen("focus");
+                travel_focus_stack(conn, arguments);
+                return;
+        }
+
         /* Is it 'f' for fullscreen? */
         if (command[0] == 'f') {
                 if (CUR_CELL->currently_focused == NULL)
index 0525e8cdde4d804c87d562d9666b64352dad0772..4aa3e8f561057a7147765b902a4ea321ec59aec4 100644 (file)
@@ -837,7 +837,7 @@ int handle_windowclass_change(void *data, xcb_connection_t *conn, uint8_t state,
                 LOG("prop == NULL\n");
                 return 1;
         }
-        Client *client = table_get(byChild, window);
+        Client *client = table_get(&by_child, window);
         if (client == NULL)
                 return 1;
         char *new_class;