From: Michael Stapelberg Date: Tue, 5 May 2009 15:25:56 +0000 (+0200) Subject: Implement a command to travel the focusstack. This can be used like a jumpback. X-Git-Tag: 3.b~122 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=3a2b546c9ee0cbce0343b09c9acb85064c29aabf;p=i3%2Fi3 Implement a command to travel the focusstack. This can be used like a jumpback. 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) --- diff --git a/CMDMODE b/CMDMODE index 0231c705..7428729a 100644 --- a/CMDMODE +++ b/CMDMODE @@ -1,40 +1,41 @@ -left := | -right := | -up := | -down := | - -where := | -move := -snap := - -Eingabe ist entweder - -cmd := [ ] [ | ] - -oder +--------------------- +- Command mode +--------------------- -with := { [ ] }+ +This is the grammar for the command mode (your configuration file uses these commands, too). -oder - -jump := [ "[/]" | [ ] ] - -oder +left := | +right := | +up := | +down := | +where := | +move := +snap := + +cmd := [ ] [ | ] +with := { [ ] }+ +jump := [ "[/]" | [ ] ] +focus := focus [ ] +(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 | kill | exit | restart ] -an jeder Stelle kann mit escape abgebrochen werden +input := [ | | | | ] + +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 diff --git a/src/commands.c b/src/commands.c index 111dce55..c0f5ffdd 100644 --- a/src/commands.c +++ b/src/commands.c @@ -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", ×) != 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) diff --git a/src/handlers.c b/src/handlers.c index 0525e8cd..4aa3e8f5 100644 --- a/src/handlers.c +++ b/src/handlers.c @@ -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;