[Xfce4-commits] <xfwm4:master> Properly implement session handling.

Nick Schermer noreply at xfce.org
Fri Nov 26 15:44:01 CET 2010


Updating branch refs/heads/master
         to e08b248a5cec4ecf161a9a37642650ee48d3423b (commit)
       from 243195d115491e9ebf7864cc98274929f6c112fe (commit)

commit e08b248a5cec4ecf161a9a37642650ee48d3423b
Author: Nick Schermer <nick at xfce.org>
Date:   Fri Nov 26 15:33:07 2010 +0100

    Properly implement session handling.
    
    It turned out the session client was never properly
    hooked up in xfwm4, so a bunch of changes were needed for
    that:
    
    - Use GOptionContext, so we can use xfce_sm_client_get_option_group
      for properly initializing the session options. Also added the
      other options that were manually parsed by Xfwm4 for a nice
      --help output.
    - Connect save-state-extended signal so Xfwm4 saves the window
      position again.
    - Use xfce_sm_client_get_state_file for the state file location,
      basically the same as the Xfwm4 implementation.
    - Do no change the restart style during quit.
    - Change priority to XFCE_SM_CLIENT_PRIORITY_WM.
    
    All in all this should restore the window positioning during login
    and fix the bunch of xfwm4 processes when saving the session.

 src/Makefile.am |    3 +-
 src/main.c      |  149 ++++++++++++++++++++++++++++---------------------------
 src/session.c   |  103 +++++++++++++++++---------------------
 src/session.h   |    8 +--
 4 files changed, 126 insertions(+), 137 deletions(-)

diff --git a/src/Makefile.am b/src/Makefile.am
index c13a2b9..9cf486c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -93,7 +93,8 @@ xfwm4_CFLAGS =								\
 	-DPACKAGE_LOCALE_DIR=\"$(localedir)\"				\
 	-DDATADIR=\"$(datadir)\"					\
 	-DLIBDIR=\"$(libdir)\"						\
-	-DPACKAGE_DATADIR=\"$(pkgdatadir)\"
+	-DPACKAGE_DATADIR=\"$(pkgdatadir)\"				\
+	-DG_LOG_DOMAIN=\"xfwm4\"
 
 xfwm4_LDADD =								\
 	$(GTK_LIBS) 							\
diff --git a/src/main.c b/src/main.c
index 15f0947..d97df06 100644
--- a/src/main.c
+++ b/src/main.c
@@ -32,6 +32,7 @@
 #include <gdk/gdkx.h>
 #include <gtk/gtk.h>
 #include <libxfce4util/libxfce4util.h>
+#include <libxfce4ui/libxfce4ui.h>
 
 #include <sys/stat.h>
 #include <sys/time.h>
@@ -91,6 +92,7 @@ static char revision[]="@(#)$ " PACKAGE " version " VERSION " revision " REVISIO
 #endif
 
 static DisplayInfo *main_display_info = NULL;
+static gint compositor = COMPOSITOR_MODE_MANUAL;
 
 static void
 cleanUp (void)
@@ -260,16 +262,6 @@ ensure_basedir_spec (void)
 }
 
 static void
-print_usage (void)
-{
-    g_print ("%s [--sm-client-id=ID] [--display=DISPLAY] "
-#ifdef HAVE_COMPOSITOR
-             "[--compositor=off|on|auto] "
-#endif
-             "[--daemon] [--replace] [--version|-V] [--help|-H]\n", PACKAGE);
-}
-
-static void
 print_version (void)
 {
     g_print ("\tThis is %s version %s (revision %s) for Xfce %s\n",
@@ -362,41 +354,40 @@ get_default_compositor (DisplayInfo *display_info)
 #endif /* HAVE_COMPOSITOR */
 
 #ifdef HAVE_COMPOSITOR
-static gint
-parse_compositor (const gchar *s)
+static gboolean
+compositor_callback (const gchar  *name,
+                     const gchar  *value,
+                     gpointer      user_data,
+                     GError      **error)
 {
-    gchar *rvalue;
-    gint retval;
+    gboolean succeed = TRUE;
 
-    retval = COMPOSITOR_MODE_MANUAL;
-    rvalue = strrchr (s, '=');
-    if (rvalue)
+    g_return_val_if_fail (value != NULL, FALSE);
+
+    if (strcmp (value, "off") == 0)
     {
-        rvalue++;
-        if (!strcmp (rvalue, "off"))
-        {
-            retval = COMPOSITOR_MODE_OFF;
-        }
-        else if (!strcmp (rvalue, "auto"))
-        {
-            retval = COMPOSITOR_MODE_AUTO;
-        }
-        else if (!strcmp (rvalue, "on"))
-        {
-            retval = COMPOSITOR_MODE_MANUAL;
-        }
-        else
-        {
-            g_warning ("Unrecognized compositor option \"%s\"", rvalue);
-        }
+        compositor = COMPOSITOR_MODE_OFF;
+    }
+    else if (strcmp (value, "auto") == 0)
+    {
+        compositor = COMPOSITOR_MODE_AUTO;
+    }
+    else if (strcmp (value, "on") == 0)
+    {
+        compositor = COMPOSITOR_MODE_MANUAL;
+    }
+    else
+    {
+        g_set_error (error, 0, 0, "Unrecognized compositor option \"%s\"", value);
+        succeed = FALSE;
     }
 
-    return retval;
+    return succeed;
 }
 #endif /* HAVE_COMPOSITOR */
 
 static int
-initialize (int argc, char **argv, gint compositor_mode, gboolean replace_wm)
+initialize (gint compositor_mode, gboolean replace_wm)
 {
     struct sigaction act;
     long ws;
@@ -404,10 +395,6 @@ initialize (int argc, char **argv, gint compositor_mode, gboolean replace_wm)
 
     TRACE ("entering initialize");
 
-    xfce_textdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8");
-
-    gtk_init (&argc, &argv);
-
     DBG ("xfwm4 starting, using GTK+-%d.%d.%d", gtk_major_version,
          gtk_minor_version, gtk_micro_version);
 
@@ -526,52 +513,66 @@ initialize (int argc, char **argv, gint compositor_mode, gboolean replace_wm)
     main_display_info->xfilter = eventFilterInit ((gpointer) main_display_info);
     eventFilterPush (main_display_info->xfilter, xfwm4_event_filter, (gpointer) main_display_info);
 
-    return sessionStart (argc, argv, main_display_info);
+    return sessionStart (main_display_info);
 }
 
 int
 main (int argc, char **argv)
 {
-    gboolean daemon_mode;
-    gboolean replace_wm;
-    gint compositor;
+    gboolean daemon_mode = FALSE;
+    gboolean version = FALSE;
+    gboolean replace_wm = FALSE;
     int status;
-    int i;
+    GOptionContext *context;
+    GError *error = NULL;
+#ifndef HAVE_COMPOSITOR
+    gchar *compositor_foo = NULL;
+#endif
+    GOptionEntry option_entries[] =
+    {
+#ifdef HAVE_DAEMON
+        { "daemon", '\0', 0, G_OPTION_ARG_NONE, &daemon_mode, N_("Fork to the background"), NULL },
+#else
+        { "daemon", '\0', 0, G_OPTION_ARG_NONE, &daemon_mode, N_("Fork to the background (not supported)"), NULL },
+#endif
+#ifdef HAVE_COMPOSITOR
+        { "compositor", '\0', 0, G_OPTION_ARG_CALLBACK, compositor_callback, N_("Set the compositor mode"), "on|off|auto" },
+#else
+        { "compositor", '\0', 0, G_OPTION_ARG_STRING, &compositor_foo, N_("Set the compositor mode (not supported)"), "on|off|auto" },
+#endif
+        { "replace", '\0', 0, G_OPTION_ARG_NONE, &replace_wm, N_("Replace the existing window manager"), NULL },
+        { "version", 'V', 0, G_OPTION_ARG_NONE, &version, N_("Print version information and exit"), NULL },
+        { NULL }
+    };
 
     DBG ("xfwm4 starting");
 
-    daemon_mode = FALSE;
-    replace_wm = FALSE;
-    compositor = -1;
-    for (i = 1; i < argc; i++)
+    xfce_textdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8");
+
+    context = g_option_context_new (_("[ARGUMENTS...]"));
+    g_option_context_add_main_entries (context, option_entries, GETTEXT_PACKAGE);
+    g_option_context_add_group (context, gtk_get_option_group (FALSE));
+    g_option_context_add_group (context, xfce_sm_client_get_option_group (argc, argv));
+    if (!g_option_context_parse (context, &argc, &argv, &error))
     {
-        if (!strcmp (argv[i], "--daemon"))
-        {
-            daemon_mode = TRUE;
-        }
-#ifdef HAVE_COMPOSITOR
-        else if (!strncmp (argv[i], "--compositor=", strlen ("--compositor=")))
-        {
-            compositor = parse_compositor (argv[i]);
-        }
-#endif /* HAVE_COMPOSITOR */
-        else if (!strcmp (argv[i], "--replace"))
-        {
-            replace_wm = TRUE;
-        }
-        else if (!strcmp (argv[i], "--version") || !strcmp (argv[i], "-V"))
-        {
-            print_version ();
-            exit (0);
-        }
-        else if (!strcmp (argv[i], "--help") || !strcmp (argv[i], "-H"))
-        {
-            print_usage ();
-            exit (0);
-        }
+          g_print ("%s: %s.\n", PACKAGE_NAME, error->message);
+          g_print (_("Type \"%s --help\" for usage."), G_LOG_DOMAIN);
+          g_print ("\n");
+          g_error_free (error);
+
+          return EXIT_FAILURE;
+    }
+    g_option_context_free (context);
+
+    gtk_init (&argc, &argv);
+
+    if (G_UNLIKELY (version))
+    {
+         print_version ();
+         return EXIT_SUCCESS;
     }
 
-    status = initialize (argc, argv, compositor, replace_wm);
+    status = initialize (compositor, replace_wm);
     /*
        status  < 0   =>   Error, cancel execution
        status == 0   =>   Run w/out session manager
diff --git a/src/session.c b/src/session.c
index 41a2719..257f89f 100644
--- a/src/session.c
+++ b/src/session.c
@@ -366,7 +366,7 @@ sessionSaveScreen (ScreenInfo *screen_info, FILE *f)
 }
 
 gboolean
-sessionSaveWindowStates (DisplayInfo *display_info, gchar * filename)
+sessionSaveWindowStates (DisplayInfo *display_info, const gchar * filename)
 {
     FILE *f;
     GSList *screens;
@@ -388,7 +388,7 @@ sessionSaveWindowStates (DisplayInfo *display_info, gchar * filename)
 }
 
 gboolean
-sessionLoadWindowStates (gchar * filename)
+sessionLoadWindowStates (const gchar * filename)
 {
     FILE *f;
     gchar s[4096], s1[4096];
@@ -705,95 +705,84 @@ sessionMatchWinToSM (Client * c)
     return FALSE;
 }
 
-static char *
-sessionBuildFilename(XfceSMClient *client_session)
-{
-    gchar *filename, *path, *file;
-    GError *error;
-
-    path = xfce_resource_save_location (XFCE_RESOURCE_CACHE, "sessions", FALSE);
-
-    error = NULL;
-    if (!xfce_mkdirhier(path, 0700, &error))
-    {
-        g_warning("Unable to create session dir %s: %s", path, error->message);
-        g_error_free (error);
-        g_free (path);
-        return NULL;
-    }
-
-    file = g_strdup_printf("xfwm4-%s", xfce_sm_client_get_client_id(client_session));
-    filename = g_build_filename (path, file, NULL);
-    g_free (file);
-    g_free (path);
-
-    return filename;
-}
-
 static void
 sessionLoad (DisplayInfo *display_info)
 {
-    XfceSMClient *session;
-    gchar *filename;
+    const gchar *filename;
 
-    session = display_info->session;
-    filename = sessionBuildFilename(session);
+    filename = xfce_sm_client_get_state_file (display_info->session);
+    DBG ("Restoring session from \"%s\"", filename);
     if (filename)
     {
         sessionLoadWindowStates (filename);
-        g_free (filename);
     }
 }
 
-/*
 static void
-sessionSavePhase2 (gpointer data)
+sessionSavePhase2 (XfceSMClient *session,
+                   DisplayInfo *display_info)
 {
-    DisplayInfo *display_info;
-    XfceSMClient *session;
-    gchar *filename;
+    const gchar *filename;
+
+    g_return_if_fail (XFCE_IS_SM_CLIENT (session));
+    g_return_if_fail (session == display_info->session);
 
-    display_info = (DisplayInfo *) data;
-    session = display_info->session;
-    filename = sessionBuildFilename(session);
+    filename = xfce_sm_client_get_state_file (display_info->session);
+    DBG ("Saving session to \"%s\"", filename);
     if (filename)
     {
         sessionSaveWindowStates (display_info, filename);
-        g_free (filename);
     }
 }
 
 static void
-sessionDie (gpointer data)
+sessionDie (XfceSMClient *session,
+            DisplayInfo *display_info)
 {
-    DisplayInfo *display_info;
+    g_return_if_fail (XFCE_IS_SM_CLIENT (session));
+    g_return_if_fail (session == display_info->session);
 
-    display_info = (DisplayInfo *) data;
-    xfce_sm_client_set_restart_style(display_info->session, XFCE_SM_CLIENT_RESTART_NORMAL);
-    display_info->quit = TRUE;
+    /*
+     * Do not change the session restart style to NORMAL here, else
+     * xfwm4 will never be restarted the next time we login. just
+     * gracefully quit the application.
+     */
+    DBG ("Session clients asked to quit");
     gtk_main_quit ();
 }
-*/
 
 int
-sessionStart (int argc, char **argv, DisplayInfo *display_info)
+sessionStart (DisplayInfo *display_info)
 {
     XfceSMClient *session;
+    GError *error = NULL;
 
-    display_info->session = xfce_sm_client_get_with_argv (argc, argv,
-                                                XFCE_SM_CLIENT_RESTART_IMMEDIATELY, 20);
-    session = display_info->session;
-    /*
-    session->data = (gpointer) display_info;
-    session->save_phase_2 = sessionSavePhase2;
-    session->die = sessionDie;
-    */
+    DBG ("Starting session client");
+
+    session = xfce_sm_client_get ();
+    xfce_sm_client_set_restart_style (session, XFCE_SM_CLIENT_RESTART_IMMEDIATELY);
+    xfce_sm_client_set_priority (session, XFCE_SM_CLIENT_PRIORITY_WM);
 
-    if (xfce_sm_client_connect(session, NULL))
+    if (xfce_sm_client_connect(session, &error))
     {
+        display_info->session = session;
+
         sessionLoad (display_info);
+
+        /* save-state-extended is special for window managers to store
+         * the window positions of all the clients */
+        g_signal_connect (G_OBJECT (session), "save-state-extended",
+                          G_CALLBACK (sessionSavePhase2), display_info);
+        g_signal_connect (G_OBJECT (session), "quit",
+                          G_CALLBACK (sessionDie), display_info);
+
         return 1;
     }
+    else
+    {
+        g_warning ("Failed to connect to session manager: %s", error->message);
+        g_error_free (error);
+    }
 
     return 0;
 }
diff --git a/src/session.h b/src/session.h
index 598cdbf..7dc8ede 100644
--- a/src/session.h
+++ b/src/session.h
@@ -36,12 +36,12 @@
  *  Save window states to file which name is given in argument.
  */
 gboolean                sessionSaveWindowStates                 (DisplayInfo *,
-                                                                 gchar *);
+                                                                 const gchar *);
 
 /*
  *  Load window states to file which name is given in argument.
  */
-gboolean                sessionLoadWindowStates                 (gchar *);
+gboolean                sessionLoadWindowStates                 (const gchar *);
 
 /*
  * Free allocated structure. Should be called before xfwm4 dies
@@ -58,8 +58,6 @@ gboolean                sessionMatchWinToSM                     (Client *);
  * Initiate session, connect to session manager and
  * load saved states if the connection succeeds.
  */
-int                     sessionStart                            (int,
-                                                                 char **,
-                                                                 DisplayInfo *);
+int                     sessionStart                            (DisplayInfo *);
 
 #endif /* INC_CLIENT_H */



More information about the Xfce4-commits mailing list