Skip to content

Instantly share code, notes, and snippets.

@mseiwald
Created May 11, 2013 11:10
Show Gist options
  • Save mseiwald/5559666 to your computer and use it in GitHub Desktop.
Save mseiwald/5559666 to your computer and use it in GitHub Desktop.
diff --git a/include/commands.h b/include/commands.h
index a517d83..6894afb 100644
--- a/include/commands.h
+++ b/include/commands.h
@@ -103,6 +103,8 @@ void cmd_workspace_number(I3_CMD, char *which);
*/
void cmd_workspace_back_and_forth(I3_CMD);
+void cmd_focus_back_and_forth(I3_CMD);
+
/**
* Implementation of 'workspace <name>'
*
diff --git a/include/tree.h b/include/tree.h
index 2799afe..d649346 100644
--- a/include/tree.h
+++ b/include/tree.h
@@ -14,6 +14,9 @@ extern Con *croot;
/* TODO: i am not sure yet how much access to the focused container should
* be permitted to source files */
extern Con *focused;
+/* Stores last focused Con for back-and-forth switching between windows. */
+extern Con *last_focused;
+extern char *last_focused_ws_name;
TAILQ_HEAD(all_cons_head, Con);
extern struct all_cons_head all_cons;
@@ -70,6 +73,12 @@ void tree_close_con(kill_window_t kill_window);
*/
void tree_next(char way, orientation_t orientation);
+/*
+ * Focuses the previously focused window.
+ *
+ */
+void focus_back_and_forth(void);
+
/**
* Closes the given container including all children.
* Returns true if the container was killed or false if just WM_DELETE was sent
diff --git a/parser-specs/commands.spec b/parser-specs/commands.spec
index a4a01a8..b7fdc2d 100644
--- a/parser-specs/commands.spec
+++ b/parser-specs/commands.spec
@@ -123,6 +123,8 @@ state FOCUS:
-> call cmd_focus_direction($direction)
'output'
-> FOCUS_OUTPUT
+ 'back_and_forth'
+ -> call cmd_focus_back_and_forth()
window_mode = 'tiling', 'floating', 'mode_toggle'
-> call cmd_focus_window_mode($window_mode)
level = 'parent', 'child'
diff --git a/src/commands.c b/src/commands.c
index 538e2db..1a5f703 100644
--- a/src/commands.c
+++ b/src/commands.c
@@ -1345,6 +1345,18 @@ void cmd_focus_direction(I3_CMD, char *direction) {
}
/*
+ * Implementation of 'focus back_and_forth'.
+ *
+ */
+void cmd_focus_back_and_forth(I3_CMD) {
+ focus_back_and_forth();
+
+ cmd_output->needs_tree_render = true;
+ // XXX: default reply for now, make this a better reply
+ ysuccess(true);
+}
+
+/*
* Implementation of 'focus tiling|floating|mode_toggle'.
*
*/
diff --git a/src/con.c b/src/con.c
index 1050513..e18f0de 100644
--- a/src/con.c
+++ b/src/con.c
@@ -195,13 +195,7 @@ void con_detach(Con *con) {
}
}
-/*
- * Sets input focus to the given container. Will be updated in X11 in the next
- * run of x_push_changes().
- *
- */
-void con_focus(Con *con) {
- assert(con != NULL);
+void _con_focus(Con *con) {
DLOG("con_focus = %p\n", con);
/* 1: set focused-pointer to the new con */
@@ -209,7 +203,7 @@ void con_focus(Con *con) {
TAILQ_REMOVE(&(con->parent->focus_head), con, focused);
TAILQ_INSERT_HEAD(&(con->parent->focus_head), con, focused);
if (con->parent->parent != NULL)
- con_focus(con->parent);
+ _con_focus(con->parent);
focused = con;
/* We can't blindly reset non-leaf containers since they might have
@@ -225,6 +219,19 @@ void con_focus(Con *con) {
}
/*
+ * Sets input focus to the given container. Will be updated in X11 in the next
+ * run of x_push_changes().
+ *
+ */
+ void con_focus(Con *con){
+ assert(con != NULL);
+ last_focused = focused;
+ if(con_get_workspace(focused))
+ last_focused_ws_name = con_get_workspace(focused)->name;
+ _con_focus(con);
+}
+
+/*
* Returns true when this node is a leaf node (has no children)
*
*/
diff --git a/src/main.c b/src/main.c
index db3aca4..2796119 100644
--- a/src/main.c
+++ b/src/main.c
@@ -35,6 +35,8 @@ static int xkb_event_base;
int xkb_current_group;
extern Con *focused;
+extern Con *last_focused;
+extern char *last_focused_ws_name;
char **start_argv;
diff --git a/src/tree.c b/src/tree.c
index 32bec96..7e95952 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -13,6 +13,9 @@
struct Con *croot;
struct Con *focused;
+/* Stores last focused Con for back-and-forth switching between windows. */
+struct Con *last_focused;
+char *last_focused_ws_name;
struct all_cons_head all_cons = TAILQ_HEAD_INITIALIZER(all_cons);
@@ -664,6 +667,20 @@ void tree_next(char way, orientation_t orientation) {
}
/*
+ * Focuses the previously focused window.
+ *
+ */
+void focus_back_and_forth(void){
+ if (!last_focused) {
+ DLOG("No previous window set. Not switching.");
+ return;
+ }
+ if(strcmp(con_get_workspace(focused)->name, last_focused_ws_name) == 0)
+ con_focus(con_descend_focused(last_focused));
+}
+
+
+/*
* tree_flatten() removes pairs of redundant split containers, e.g.:
* [workspace, horizontal]
* [v-split] [child3]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment