summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsrc/run-metacity.sh2
-rw-r--r--src/session.c64
-rw-r--r--src/session.h33
-rw-r--r--src/window.c84
4 files changed, 166 insertions, 17 deletions
diff --git a/src/run-metacity.sh b/src/run-metacity.sh
index a1aa050..0919c94 100755
--- a/src/run-metacity.sh
+++ b/src/run-metacity.sh
@@ -40,5 +40,5 @@ if test -z "$ONLY_WM"; then
fi
if test -z "$ONLY_SETUP"; then
- METACITY_UISLAVE_DIR=./uislave METACITY_DISPLAY=:1 exec unst libtool --mode=execute $DEBUG ./metacity $OPTIONS
+ METACITY_DISPLAY=:1 exec unst libtool --mode=execute $DEBUG ./metacity $OPTIONS
fi
diff --git a/src/session.c b/src/session.c
index bb9b726..980a8b6 100644
--- a/src/session.c
+++ b/src/session.c
@@ -448,7 +448,7 @@ set_clone_restart_commands (void)
char *session_file;
session_file = g_strconcat (g_get_home_dir (),
- ".metacity/sessions/",
+ "/.metacity/sessions/",
client_id,
NULL);
@@ -701,7 +701,7 @@ save_state (void)
int n;
n = meta_workspace_screen_index (w->data);
fprintf (outfile,
- "<workspace index=\"%d\"/>\n", n);
+ " <workspace index=\"%d\"/>\n", n);
w = w->next;
}
@@ -796,8 +796,8 @@ load_state (const char *previous_id)
char *session_file;
session_file = g_strconcat (g_get_home_dir (),
- ".metacity/sessions/",
- client_id,
+ "/.metacity/sessions/",
+ previous_id,
NULL);
error = NULL;
@@ -845,7 +845,7 @@ load_state (const char *previous_id)
g_free (text);
}
-
+/* FIXME this isn't very robust against bogus session files */
static void
start_element_handler (GMarkupParseContext *context,
const gchar *element_name,
@@ -858,7 +858,11 @@ start_element_handler (GMarkupParseContext *context,
pd = user_data;
- if (strcmp (element_name, "window") == 0)
+ if (strcmp (element_name, "metacity_session") == 0)
+ {
+ /* do nothing */
+ }
+ else if (strcmp (element_name, "window") == 0)
{
int i;
@@ -1051,8 +1055,7 @@ get_possible_matches (MetaWindow *window)
info = tmp->data;
- if (both_null_or_matching (info->id,
- window->sm_client_id) &&
+ if (both_null_or_matching (info->id, window->sm_client_id) &&
both_null_or_matching (info->res_class, window->res_class) &&
both_null_or_matching (info->res_name, window->res_name) &&
both_null_or_matching (info->role, window->role))
@@ -1065,7 +1068,37 @@ get_possible_matches (MetaWindow *window)
retval = g_slist_prepend (retval, info);
}
-
+ else
+ {
+ if (meta_is_verbose ())
+ {
+ if (!both_null_or_matching (info->id, window->sm_client_id))
+ meta_verbose ("Window %s has SM client ID %s, saved state has %s, no match\n",
+ window->desc,
+ window->sm_client_id ? window->sm_client_id : "(none)",
+ info->id ? info->id : "(none)");
+ else if (!both_null_or_matching (info->res_class, window->res_class))
+ meta_verbose ("Window %s has class %s doesn't match saved class %s, no match\n",
+ window->desc,
+ window->res_class ? window->res_class : "(none)",
+ info->res_class ? info->res_class : "(none)");
+
+ else if (!both_null_or_matching (info->res_name, window->res_name))
+ meta_verbose ("Window %s has name %s doesn't match saved name %s, no match\n",
+ window->desc,
+ window->res_name ? window->res_name : "(none)",
+ info->res_name ? info->res_name : "(none)");
+ else if (!both_null_or_matching (info->role, window->role))
+ meta_verbose ("Window %s has role %s doesn't match saved role %s, no match\n",
+ window->desc,
+ window->role ? window->role : "(none)",
+ info->role ? info->role : "(none)");
+ else
+ meta_verbose ("???? should not happen - window %s doesn't match saved state %s for no good reason\n",
+ window->desc, info->id);
+ }
+ }
+
tmp = tmp->next;
}
@@ -1129,14 +1162,21 @@ meta_window_lookup_saved_state (MetaWindow *window)
* situations other than on session restore.
*/
if (window->sm_client_id == NULL)
- return NULL;
+ {
+ meta_verbose ("Window %s is not session managed, not checking for saved state\n", window->desc);
+ return NULL;
+ }
possibles = get_possible_matches (window);
if (possibles == NULL)
- return NULL;
+ {
+ meta_verbose ("Window %s has no possible matches in the list of saved window states\n",
+ window->desc);
+ return NULL;
+ }
- info = find_best_match (possibles, window);
+ info = find_best_match (possibles, window);
g_slist_free (possibles);
diff --git a/src/session.h b/src/session.h
index 3ec3ecc..7250a5a 100644
--- a/src/session.h
+++ b/src/session.h
@@ -28,14 +28,39 @@ typedef struct _MetaWindowSessionInfo MetaWindowSessionInfo;
struct _MetaWindowSessionInfo
{
- int workspace;
+ /* Fields we use to match against */
+ char *id;
+ char *res_class;
+ char *res_name;
+ char *title;
+ char *role;
+ MetaWindowType type;
+
+ /* Information we restore */
+
+ GSList *workspace_indices;
+
+ /* width/height should be multiplied by resize inc and
+ * added to base size; position should be interpreted in
+ * light of gravity. This preserves semantics of the
+ * window size/pos, even if fonts/themes change, etc.
+ */
+ int gravity;
+ MetaRectangle rect;
+ guint on_all_workspaces : 1;
+
+ guint geometry_set : 1;
+ guint on_all_workspaces_set : 1;
};
-void meta_window_lookup_saved_state (MetaWindow *window,
- MetaWindowSessionInfo *info);
+/* If lookup_saved_state returns something, it should be used,
+ * and then released when you're done with it.
+ */
+const MetaWindowSessionInfo* meta_window_lookup_saved_state (MetaWindow *window);
+void meta_window_release_saved_state (const MetaWindowSessionInfo *info);
-void meta_session_init (const char *previous_id);
+void meta_session_init (const char *previous_id);
#endif
diff --git a/src/window.c b/src/window.c
index 37cfda0..35649db 100644
--- a/src/window.c
+++ b/src/window.c
@@ -28,6 +28,7 @@
#include "keybindings.h"
#include "ui.h"
#include "place.h"
+#include "session.h"
#include <X11/Xatom.h>
@@ -86,6 +87,10 @@ static gboolean get_cardinal (MetaDisplay *display,
void meta_window_unqueue_calc_showing (MetaWindow *window);
+static void meta_window_apply_session_info (MetaWindow *window,
+ const MetaWindowSessionInfo *info);
+
+
MetaWindow*
meta_window_new (MetaDisplay *display, Window xwindow,
gboolean must_be_viewable)
@@ -451,6 +456,19 @@ meta_window_new (MetaDisplay *display, Window xwindow,
meta_stack_add (window->screen->stack,
window);
+ /* Now try applying saved stuff from the session */
+ {
+ const MetaWindowSessionInfo *info;
+
+ info = meta_window_lookup_saved_state (window);
+
+ if (info)
+ {
+ meta_window_apply_session_info (window, info);
+ meta_window_release_saved_state (info);
+ }
+ }
+
/* Sync stack changes */
meta_stack_thaw (window->screen->stack);
@@ -461,6 +479,72 @@ meta_window_new (MetaDisplay *display, Window xwindow,
return window;
}
+/* This function should only be called from the end of meta_window_new () */
+static void
+meta_window_apply_session_info (MetaWindow *window,
+ const MetaWindowSessionInfo *info)
+{
+ if (info->on_all_workspaces_set)
+ {
+ window->on_all_workspaces = info->on_all_workspaces;
+ meta_verbose ("Restoring sticky state %d for window %s\n",
+ window->on_all_workspaces, window->desc);
+ }
+
+ if (info->workspace_indices)
+ {
+ GSList *tmp;
+ GSList *spaces;
+
+ spaces = NULL;
+
+ tmp = info->workspace_indices;
+ while (tmp != NULL)
+ {
+ MetaWorkspace *space;
+
+ space =
+ meta_display_get_workspace_by_screen_index (window->display,
+ window->screen,
+ GPOINTER_TO_INT (tmp->data));
+
+ if (space)
+ spaces = g_slist_prepend (spaces, space);
+
+ tmp = tmp->next;
+ }
+
+ if (spaces)
+ {
+ /* This briefly breaks the invariant that we are supposed
+ * to always be on some workspace. But we paranoically
+ * ensured that one of the workspaces from the session was
+ * indeed valid, so we know we'll go right back to one.
+ */
+ while (window->workspaces)
+ meta_workspace_remove_window (window->workspaces->next->data, window);
+
+ tmp = spaces;
+ while (tmp != NULL)
+ {
+ MetaWorkspace *space;
+
+ space = tmp->data;
+
+ meta_workspace_add_window (space, window);
+
+ meta_verbose ("Restoring saved window %s to workspace %d\n",
+ window->desc,
+ meta_workspace_screen_index (space));
+
+ tmp = tmp->next;
+ }
+
+ g_slist_free (spaces);
+ }
+ }
+}
+
void
meta_window_free (MetaWindow *window)
{