Also note that your output names are not descriptive (like +HDMI1+) when using
Xinerama, instead they are counted up, starting at 0: +xinerama-0+, +xinerama-1+, …
+=== Automatic back-and-forth when switching to the current workspace
+
+This configuration directive enables automatic +workspace back_and_forth+ (see
+<<back_and_forth>>) when switching to the workspace that is currently focused.
+
+For instance: Assume you are on workspace "1: www" and switch to "2: IM" using
+mod+2 because somebody sent you a message. You don’t need to remember where you
+came from now, you can just press mod+2 again to switch back to "1: www".
+
+*Syntax*:
+--------------------------------------
+workspace_auto_back_and_forth <yes|no>
+--------------------------------------
+
+*Example*:
+---------------------------------
+workspace_auto_back_and_forth yes
+---------------------------------
+
== List of commands
Commands are what you bind to specific keypresses. You can also issue commands
combination. Similarily, you can use +move workspace next+ and +move workspace
prev+ to move a container to the next/previous workspace.
+[[back_and_forth]]
+To switch back to the previously focused workspace, use +workspace
+back_and_forth+.
+
To move a container to another xrandr output such as +LVDS1+ or +VGA1+, you can
use the +move output+ command followed by the name of the target output. You
may also use +left+, +right+, +up+, +down+ instead of the xrandr output name to
bindsym mod+Shift+1 move workspace 1
bindsym mod+Shift+2 move workspace 2
...
+
+# switch between the current and the previously focused one
+bindsym mod+b workspace back_and_forth
-------------------------
==== Named workspaces
* is fetched once and never updated. */
bool force_xinerama;
+ /** Automatic workspace back and forth switching. If this is set, a
+ * switch to the currently active workspace will switch to the
+ * previously focused one instead, making it possible to fast toggle
+ * between two workspaces. */
+ bool workspace_auto_back_and_forth;
+
/** The default border style for new windows. */
border_style_t default_border;
*/
Con* workspace_prev();
+/**
+ * Focuses the previously focused workspace.
+ *
+ */
+void workspace_back_and_forth();
+
+
#if 0
/**
* Assigns the given workspace to the given screen by correctly updating its
focus_follows_mouse { return TOKFOCUSFOLLOWSMOUSE; }
force_focus_wrapping { return TOK_FORCE_FOCUS_WRAPPING; }
force_xinerama { return TOK_FORCE_XINERAMA; }
+workspace_auto_back_and_forth { return TOK_WORKSPACE_AUTO_BAF; }
workspace_bar { return TOKWORKSPACEBAR; }
popup_during_fullscreen { return TOK_POPUP_DURING_FULLSCREEN; }
ignore { return TOK_IGNORE; }
%token TOKFOCUSFOLLOWSMOUSE "focus_follows_mouse"
%token TOK_FORCE_FOCUS_WRAPPING "force_focus_wrapping"
%token TOK_FORCE_XINERAMA "force_xinerama"
+%token TOK_WORKSPACE_AUTO_BAF "workspace_auto_back_and_forth"
%token TOKWORKSPACEBAR "workspace_bar"
%token TOK_DEFAULT "default"
%token TOK_STACKING "stacking"
| focus_follows_mouse
| force_focus_wrapping
| force_xinerama
+ | workspace_back_and_forth
| workspace_bar
| workspace
| assign
}
;
+workspace_back_and_forth:
+ TOK_WORKSPACE_AUTO_BAF bool
+ {
+ DLOG("automatic workspace back-and-forth = %d\n", $2);
+ config.workspace_auto_back_and_forth = $2;
+ }
+ ;
+
workspace_bar:
TOKWORKSPACEBAR bool
{
cmdyycolumn = 1;
}
- /* the next/prev tokens are here to recognize them *before* handling
- * strings ('workspace' command) */
+ /* the next/prev/back_and_forth tokens are here to recognize them *before*
+ * handling strings ('workspace' command) */
next { return TOK_NEXT; }
prev { return TOK_PREV; }
+back_and_forth { return TOK_BACK_AND_FORTH; }
<WANT_STRING>\"[^\"]+\" {
BEGIN(INITIAL);
%token TOK_OR "or"
%token TOK_PPT "ppt"
%token TOK_NOP "nop"
+%token TOK_BACK_AND_FORTH "back_and_forth"
%token TOK_CLASS "class"
%token TOK_INSTANCE "instance"
workspace_show(workspace_prev());
tree_render();
}
+ | TOK_WORKSPACE TOK_BACK_AND_FORTH
+ {
+ workspace_back_and_forth();
+ tree_render();
+ }
| TOK_WORKSPACE STR
{
printf("should switch to workspace %s\n", $2);
+
+ Con *ws = con_get_workspace(focused);
+
+ /* Check if the command wants to switch to the current workspace */
+ if (strcmp(ws->name, $2) == 0) {
+ printf("This workspace is already focused.\n");
+ if (config.workspace_auto_back_and_forth) {
+ workspace_back_and_forth();
+ free($2);
+ tree_render();
+ }
+ break;
+ }
+
workspace_show_by_name($2);
free($2);
* vim:ts=4:sw=4:expandtab
*
* i3 - an improved dynamic tiling window manager
- * © 2009-2010 Michael Stapelberg and contributors (see also: LICENSE)
+ * © 2009-2011 Michael Stapelberg and contributors (see also: LICENSE)
*
* workspace.c: Functions for modifying workspaces
*
*/
#include "all.h"
+/* Stores a copy of the name of the last used workspace for the workspace
+ * back-and-forth switching. */
+static char *previous_workspace_name = NULL;
+
/*
* Returns a pointer to the workspace with the given number (starting at 0),
* creating the workspace if necessary (by allocating the necessary amount of
/* enable fullscreen for the target workspace. If it happens to be the
* same one we are currently on anyways, we can stop here. */
workspace->fullscreen_mode = CF_OUTPUT;
- if (workspace == con_get_workspace(focused)) {
+ current = con_get_workspace(focused);
+ if (workspace == current) {
DLOG("Not switching, already there.\n");
return;
}
+ /* Remember currently focused workspace for switching back to it later with
+ * the 'workspace back_and_forth' command.
+ * NOTE: We have to duplicate the name as the original will be freed when
+ * the corresponding workspace is cleaned up. */
+
+ FREE(previous_workspace_name);
+ previous_workspace_name = sstrdup(current->name);
+
workspace_reassign_sticky(workspace);
LOG("switching to %p\n", workspace);
return prev;
}
+/*
+ * Focuses the previously focused workspace.
+ *
+ */
+void workspace_back_and_forth() {
+ if (!previous_workspace_name) {
+ DLOG("No previous workspace name set. Not switching.");
+ return;
+ }
+
+ workspace_show_by_name(previous_workspace_name);
+}
+
static bool get_urgency_flag(Con *con) {
Con *child;
TAILQ_FOREACH(child, &(con->nodes_head), nodes)