*
*/
#include "all.h"
+#include "yajl_utils.h"
+
+#include <yajl/yajl_gen.h>
/* Stores a copy of the name of the last used workspace for the workspace
* back-and-forth switching. */
ws->fullscreen_mode = CF_OUTPUT;
+ ws->workspace_layout = config.default_layout;
_workspace_apply_default_orientation(ws);
return ws;
FREE(con->urgency_timer);
}
+/*
+ * For the "focus" event we send, along the usual "change" field, also the
+ * current and previous workspace, in "current" and "old" respectively.
+ */
+static void ipc_send_workspace_focus_event(Con *current, Con *old) {
+ setlocale(LC_NUMERIC, "C");
+ yajl_gen gen = ygenalloc();
+
+ y(map_open);
+
+ ystr("change");
+ ystr("focus");
+
+ ystr("current");
+ dump_node(gen, current, false);
+
+ ystr("old");
+ if (old == NULL)
+ y(null);
+ else
+ dump_node(gen, old, false);
+
+ y(map_close);
+
+ const unsigned char *payload;
+ ylength length;
+ y(get_buf, &payload, &length);
+
+ ipc_send_event("workspace", I3_IPC_EVENT_WORKSPACE, (const char *)payload);
+ y(free);
+ setlocale(LC_NUMERIC, "");
+}
+
static void _workspace_show(Con *workspace) {
Con *current, *old = NULL;
/* 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);
- if (current)
- previous_workspace_name = sstrdup(current->name);
+ * the corresponding workspace is cleaned up.
+ * NOTE: Internal cons such as __i3_scratch (when a scratchpad window is
+ * focused) are skipped, see bug #868. */
+ if (current && !con_is_internal(current)) {
+ FREE(previous_workspace_name);
+ if (current) {
+ previous_workspace_name = sstrdup(current->name);
+ DLOG("Setting previous_workspace_name = %s\n", previous_workspace_name);
+ }
+ }
workspace_reassign_sticky(workspace);
- LOG("switching to %p\n", workspace);
+ DLOG("switching to %p / %s\n", workspace, workspace->name);
Con *next = con_descend_focused(workspace);
/* Memorize current output */
} else
con_focus(next);
+ ipc_send_workspace_focus_event(workspace, old);
+
+ DLOG("old = %p / %s\n", old, (old ? old->name : "(null)"));
/* Close old workspace if necessary. This must be done *after* doing
* urgency handling, because tree_close() will do a con_focus() on the next
* client, which will clear the urgency flag too early. Also, there is no
/* Update the EWMH hints */
ewmh_update_current_desktop();
-
- ipc_send_event("workspace", I3_IPC_EVENT_WORKSPACE, "{\"change\":\"focus\"}");
}
/*
/* 1: create a new split container */
Con *split = con_new(NULL, NULL);
split->parent = ws;
- split->split = true;
/* 2: copy layout from workspace */
split->layout = ws->layout;
/* 1: create a new split container */
Con *new = con_new(NULL, NULL);
new->parent = ws;
- new->split = true;
/* 2: set the requested layout on the split con */
new->layout = ws->workspace_layout;
return new;
}
+
+/**
+ * Creates a new container and re-parents all of children from the given
+ * workspace into it.
+ *
+ * The container inherits the layout from the workspace.
+ */
+Con *workspace_encapsulate(Con *ws) {
+ if (TAILQ_EMPTY(&(ws->nodes_head))) {
+ ELOG("Workspace %p / %s has no children to encapsulate\n", ws, ws->name);
+ return NULL;
+ }
+
+ Con *new = con_new(NULL, NULL);
+ new->parent = ws;
+ new->layout = ws->layout;
+
+ DLOG("Moving children of workspace %p / %s into container %p\n",
+ ws, ws->name, new);
+
+ Con *child;
+ while (!TAILQ_EMPTY(&(ws->nodes_head))) {
+ child = TAILQ_FIRST(&(ws->nodes_head));
+ con_detach(child);
+ con_attach(child, new, true);
+ }
+
+ con_attach(new, ws, true);
+
+ return new;
+}