GList *session_saved_state = NULL;
gint session_desktop = -1;
+gint session_num_desktops = 0;
+gboolean session_desktop_layout_present = FALSE;
+ObDesktopLayout session_desktop_layout;
+GSList *session_desktop_names = NULL;
#ifndef USE_SM
void session_startup(gint argc, gchar **argv) {}
#include "debug.h"
#include "openbox.h"
#include "client.h"
-#include "prop.h"
#include "focus.h"
-#include "screen.h"
#include "gettext.h"
-#include "parser/parse.h"
+#include "obt/parse.h"
#include <time.h>
#include <errno.h>
static ObSMSaveData *sm_save_get_data()
{
ObSMSaveData *savedata = g_new0(ObSMSaveData, 1);
+ /* save the active desktop and client.
+ we don't bother to preemptively save the other desktop state like
+ number and names of desktops, cuz those shouldn't be changing during
+ the save.. */
savedata->focus_client = focus_client;
savedata->desktop = screen_desktop;
return savedata;
static void sm_shutdown_cancelled(SmcConn conn, SmPointer data)
{
- ob_debug_type(OB_DEBUG_SM, "Shutdown cancelled\n");
+ ob_debug_type(OB_DEBUG_SM, "Shutdown cancelled\n");
}
static gboolean session_save_to_file(const ObSMSaveData *savedata)
fprintf(f, "<desktop>%d</desktop>\n", savedata->desktop);
+ fprintf(f, "<numdesktops>%d</numdesktops>\n", screen_num_desktops);
+
+ fprintf(f, "<desktoplayout>\n");
+ fprintf(f, " <orientation>%d</orientation>\n",
+ screen_desktop_layout.orientation);
+ fprintf(f, " <startcorner>%d</startcorner>\n",
+ screen_desktop_layout.start_corner);
+ fprintf(f, " <columns>%d</columns>\n",
+ screen_desktop_layout.columns);
+ fprintf(f, " <rows>%d</rows>\n",
+ screen_desktop_layout.rows);
+ fprintf(f, "</desktoplayout>\n");
+
+ if (screen_desktop_names) {
+ gint i;
+
+ fprintf(f, "<desktopnames>\n");
+ for (i = 0; screen_desktop_names[i]; ++i)
+ fprintf(f, " <name>%s</name>\n", screen_desktop_names[i]);
+ fprintf(f, "</desktopnames>\n");
+ }
+
/* they are ordered top to bottom in stacking order */
for (it = stacking_list; it; it = g_list_next(it)) {
gint prex, prey, prew, preh;
ob_debug_type(OB_DEBUG_SM, " client name: %s \n", c->name);
ob_debug_type(OB_DEBUG_SM, " client class: %s \n", c->class);
ob_debug_type(OB_DEBUG_SM, " client role: %s \n", c->role);
- ob_debug_type(OB_DEBUG_SM, " client type: %s \n", c->type);
+ ob_debug_type(OB_DEBUG_SM, " client type: %d \n", c->type);
ob_debug_type(OB_DEBUG_SM, " client command: %s \n",
c->wm_command ? c->wm_command : "(null)");
ob_debug_type(OB_DEBUG_SM, " state id: %s \n", s->id);
ob_debug_type(OB_DEBUG_SM, " state name: %s \n", s->name);
ob_debug_type(OB_DEBUG_SM, " state class: %s \n", s->class);
ob_debug_type(OB_DEBUG_SM, " state role: %s \n", s->role);
- ob_debug_type(OB_DEBUG_SM, " state type: %s \n", s->type);
+ ob_debug_type(OB_DEBUG_SM, " state type: %d \n", s->type);
ob_debug_type(OB_DEBUG_SM, " state command: %s \n",
s->command ? s->command : "(null)");
static void session_load_file(const gchar *path)
{
- xmlDocPtr doc;
- xmlNodePtr node, n;
+ ObtParseInst *i;
+ xmlNodePtr node, n, m;
+ GList *it, *inext;
+
+ i = obt_parse_instance_new();
- if (!parse_load(path, "openbox_session", &doc, &node))
+ if (!obt_parse_load_file(i, path, "openbox_session")) {
+ obt_parse_instance_unref(i);
return;
+ }
+ node = obt_parse_root(i);
+
+ if ((n = obt_parse_find_node(node->children, "desktop")))
+ session_desktop = obt_parse_node_int(n);
+
+ if ((n = obt_parse_find_node(node->children, "numdesktops")))
+ session_num_desktops = obt_parse_node_int(n);
+
+ if ((n = obt_parse_find_node(node->children, "desktoplayout"))) {
+ /* make sure they are all there for it to be valid */
+ if ((m = obt_parse_find_node(n->children, "orientation")))
+ session_desktop_layout.orientation = obt_parse_node_int(m);
+ if (m && (m = obt_parse_find_node(n->children, "startcorner")))
+ session_desktop_layout.start_corner = obt_parse_node_int(m);
+ if (m && (m = obt_parse_find_node(n->children, "columns")))
+ session_desktop_layout.columns = obt_parse_node_int(m);
+ if (m && (m = obt_parse_find_node(n->children, "rows")))
+ session_desktop_layout.rows = obt_parse_node_int(m);
+ session_desktop_layout_present = m != NULL;
+ }
- if ((n = parse_find_node("desktop", node->children)))
- session_desktop = parse_int(doc, n);
+ if ((n = obt_parse_find_node(node->children, "desktopnames"))) {
+ for (m = obt_parse_find_node(n->children, "name"); m;
+ m = obt_parse_find_node(m->next, "name"))
+ {
+ session_desktop_names = g_slist_append(session_desktop_names,
+ obt_parse_node_string(m));
+ }
+ }
- for (node = parse_find_node("window", node->children); node != NULL;
- node = parse_find_node("window", node->next))
+ for (node = obt_parse_find_node(node->children, "window"); node != NULL;
+ node = obt_parse_find_node(node->next, "window"))
{
ObSessionState *state;
state = g_new0(ObSessionState, 1);
- if (!parse_attr_string("id", node, &state->id))
- if (!parse_attr_string("command", node, &state->command))
+ if (!obt_parse_attr_string(node, "id", &state->id))
+ if (!obt_parse_attr_string(node, "command", &state->command))
goto session_load_bail;
- if (!(n = parse_find_node("name", node->children)))
+ if (!(n = obt_parse_find_node(node->children, "name")))
goto session_load_bail;
- state->name = parse_string(doc, n);
- if (!(n = parse_find_node("class", node->children)))
+ state->name = obt_parse_node_string(n);
+ if (!(n = obt_parse_find_node(node->children, "class")))
goto session_load_bail;
- state->class = parse_string(doc, n);
- if (!(n = parse_find_node("role", node->children)))
+ state->class = obt_parse_node_string(n);
+ if (!(n = obt_parse_find_node(node->children, "role")))
goto session_load_bail;
- state->role = parse_string(doc, n);
- if (!(n = parse_find_node("windowtype", node->children)))
+ state->role = obt_parse_node_string(n);
+ if (!(n = obt_parse_find_node(node->children, "windowtype")))
goto session_load_bail;
- state->type = parse_int(doc, n);
- if (!(n = parse_find_node("desktop", node->children)))
+ state->type = obt_parse_node_int(n);
+ if (!(n = obt_parse_find_node(node->children, "desktop")))
goto session_load_bail;
- state->desktop = parse_int(doc, n);
- if (!(n = parse_find_node("x", node->children)))
+ state->desktop = obt_parse_node_int(n);
+ if (!(n = obt_parse_find_node(node->children, "x")))
goto session_load_bail;
- state->x = parse_int(doc, n);
- if (!(n = parse_find_node("y", node->children)))
+ state->x = obt_parse_node_int(n);
+ if (!(n = obt_parse_find_node(node->children, "y")))
goto session_load_bail;
- state->y = parse_int(doc, n);
- if (!(n = parse_find_node("width", node->children)))
+ state->y = obt_parse_node_int(n);
+ if (!(n = obt_parse_find_node(node->children, "width")))
goto session_load_bail;
- state->w = parse_int(doc, n);
- if (!(n = parse_find_node("height", node->children)))
+ state->w = obt_parse_node_int(n);
+ if (!(n = obt_parse_find_node(node->children, "height")))
goto session_load_bail;
- state->h = parse_int(doc, n);
+ state->h = obt_parse_node_int(n);
state->shaded =
- parse_find_node("shaded", node->children) != NULL;
+ obt_parse_find_node(node->children, "shaded") != NULL;
state->iconic =
- parse_find_node("iconic", node->children) != NULL;
+ obt_parse_find_node(node->children, "iconic") != NULL;
state->skip_pager =
- parse_find_node("skip_pager", node->children) != NULL;
+ obt_parse_find_node(node->children, "skip_pager") != NULL;
state->skip_taskbar =
- parse_find_node("skip_taskbar", node->children) != NULL;
+ obt_parse_find_node(node->children, "skip_taskbar") != NULL;
state->fullscreen =
- parse_find_node("fullscreen", node->children) != NULL;
+ obt_parse_find_node(node->children, "fullscreen") != NULL;
state->above =
- parse_find_node("above", node->children) != NULL;
+ obt_parse_find_node(node->children, "above") != NULL;
state->below =
- parse_find_node("below", node->children) != NULL;
+ obt_parse_find_node(node->children, "below") != NULL;
state->max_horz =
- parse_find_node("max_horz", node->children) != NULL;
+ obt_parse_find_node(node->children, "max_horz") != NULL;
state->max_vert =
- parse_find_node("max_vert", node->children) != NULL;
+ obt_parse_find_node(node->children, "max_vert") != NULL;
state->undecorated =
- parse_find_node("undecorated", node->children) != NULL;
+ obt_parse_find_node(node->children, "undecorated") != NULL;
state->focused =
- parse_find_node("focused", node->children) != NULL;
-
+ obt_parse_find_node(node->children, "focused") != NULL;
+
/* save this. they are in the file in stacking order, so preserve
that order here */
session_saved_state = g_list_append(session_saved_state, state);
session_state_free(state);
}
- xmlFreeDoc(doc);
+ /* Remove any duplicates. This means that if two windows (or more) are
+ saved with the same session state, we won't restore a session for any
+ of them because we don't know what window to put what on. AHEM FIREFOX.
+
+ This is going to be an O(2^n) kind of operation unfortunately.
+ */
+ for (it = session_saved_state; it; it = inext) {
+ GList *jt, *jnext;
+ gboolean founddup = FALSE;
+ ObSessionState *s1 = it->data;
+
+ inext = g_list_next(it);
+
+ for (jt = g_list_next(it); jt; jt = jnext) {
+ ObSessionState *s2 = jt->data;
+ gboolean match;
+
+ jnext = g_list_next(jt);
+
+ if (s1->id && s2->id)
+ match = strcmp(s1->id, s2->id) == 0;
+ else if (s1->command && s2->command)
+ match = strcmp(s1->command, s2->command) == 0;
+ else
+ match = FALSE;
+
+ if (match &&
+ !strcmp(s1->name, s2->name) &&
+ !strcmp(s1->class, s2->class) &&
+ !strcmp(s1->role, s2->role))
+ {
+ session_state_free(s2);
+ session_saved_state =
+ g_list_delete_link(session_saved_state, jt);
+ founddup = TRUE;
+ }
+ }
+
+ if (founddup) {
+ session_state_free(s1);
+ session_saved_state = g_list_delete_link(session_saved_state, it);
+ }
+ }
+
+ obt_parse_instance_unref(i);
}
#endif