[gnome-panel/wip/muktupavels/logout-applet] action-button: turn logout object into applet



commit 28e056f937a7b8ed8c42602d26a71c703449b0a3
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Thu Apr 16 20:59:16 2020 +0300

    action-button: turn logout object into applet

 gnome-panel/libpanel-util/panel-session-manager.c  |  41 ----
 gnome-panel/libpanel-util/panel-session-manager.h  |   9 -
 gnome-panel/panel-action-button.c                  |  25 ---
 gnome-panel/panel-enums.h                          |   1 -
 gnome-panel/panel-icon-names.h                     |   1 -
 gnome-panel/panel-object-loader.c                  |   3 +-
 modules/action-button/Makefile.am                  |  11 +
 modules/action-button/gp-action-button-module.c    |  13 ++
 modules/action-button/gp-logout-applet.c           | 228 +++++++++++++++++++++
 modules/action-button/gp-logout-applet.h           |  34 +++
 modules/action-button/org.gnome.SessionManager.xml |  13 ++
 modules/menu/gp-lock-logout.c                      |   9 +-
 po/POTFILES.in                                     |   1 +
 13 files changed, 309 insertions(+), 80 deletions(-)
---
diff --git a/gnome-panel/libpanel-util/panel-session-manager.c 
b/gnome-panel/libpanel-util/panel-session-manager.c
index 0e7949460..6cf840144 100644
--- a/gnome-panel/libpanel-util/panel-session-manager.c
+++ b/gnome-panel/libpanel-util/panel-session-manager.c
@@ -61,47 +61,6 @@ panel_session_manager_init (PanelSessionManager *manager)
        }
 }
 
-static void
-logout_ready_callback (GObject      *source_object,
-                       GAsyncResult *res,
-                       gpointer      user_data)
-{
-       PanelSessionManager *manager = (PanelSessionManager *) user_data;
-       GError *error = NULL;
-       GVariant *ret;
-
-       ret = g_dbus_proxy_call_finish (manager->priv->session_proxy, res, &error);
-       if (ret) {
-               g_variant_unref (ret);
-       }
-
-       if (error) {
-               g_warning ("Could not ask session manager to log out: %s", error->message);
-               g_error_free (error);
-       }
-}
-
-void
-panel_session_manager_request_logout (PanelSessionManager           *manager,
-                                     PanelSessionManagerLogoutType  mode)
-{
-       g_return_if_fail (PANEL_IS_SESSION_MANAGER (manager));
-
-       if (!manager->priv->session_proxy) {
-               g_warning ("Session manager service not available.");
-               return;
-       }
-
-       g_dbus_proxy_call (manager->priv->session_proxy,
-                          "Logout",
-                          g_variant_new ("(u)", mode),
-                          G_DBUS_CALL_FLAGS_NONE,
-                          -1,
-                          NULL,
-                          (GAsyncReadyCallback) logout_ready_callback,
-                          manager);
-}
-
 static void
 shutdown_ready_callback (GObject      *source_object,
                          GAsyncResult *res,
diff --git a/gnome-panel/libpanel-util/panel-session-manager.h 
b/gnome-panel/libpanel-util/panel-session-manager.h
index 0dcf83d0a..65a4e6770 100644
--- a/gnome-panel/libpanel-util/panel-session-manager.h
+++ b/gnome-panel/libpanel-util/panel-session-manager.h
@@ -38,13 +38,6 @@ typedef struct _PanelSessionManager          PanelSessionManager;
 typedef struct _PanelSessionManagerClass       PanelSessionManagerClass;
 typedef struct _PanelSessionManagerPrivate     PanelSessionManagerPrivate;
 
-/* Keep in sync with the values defined in gnome-session/session.h */
-typedef enum {
-        PANEL_SESSION_MANAGER_LOGOUT_MODE_NORMAL = 0,
-        PANEL_SESSION_MANAGER_LOGOUT_MODE_NO_CONFIRMATION,
-        PANEL_SESSION_MANAGER_LOGOUT_MODE_FORCE
-} PanelSessionManagerLogoutType;
-
 struct _PanelSessionManager {
        GObject parent;
 
@@ -60,8 +53,6 @@ GType panel_session_manager_get_type (void);
 
 PanelSessionManager *panel_session_manager_get (void);
 
-void panel_session_manager_request_logout   (PanelSessionManager           *session,
-                                            PanelSessionManagerLogoutType  mode);
 void panel_session_manager_request_shutdown (PanelSessionManager *session);
 void panel_session_manager_request_reboot   (PanelSessionManager *session);
 
diff --git a/gnome-panel/panel-action-button.c b/gnome-panel/panel-action-button.c
index 8844e6962..bfeaf9c78 100644
--- a/gnome-panel/panel-action-button.c
+++ b/gnome-panel/panel-action-button.c
@@ -65,7 +65,6 @@ typedef struct {
 
 static PanelEnumStringPair panel_action_type_map [] = {
        { PANEL_ACTION_NONE,           "none"           },
-       { PANEL_ACTION_LOGOUT,         "logout"         },
        { PANEL_ACTION_RUN,            "run"            },
        { PANEL_ACTION_FORCE_QUIT,     "force-quit"     },
        { PANEL_ACTION_HIBERNATE,      "hibernate"      },
@@ -105,18 +104,6 @@ panel_enum_to_string (gint enum_value)
        return NULL;
 }
 
-/* Log Out
- */
-static void
-panel_action_logout (GtkWidget *widget)
-{
-       /* FIXME: we need to use widget to get the screen for the
-        * confirmation dialog, see
-        * http://bugzilla.gnome.org/show_bug.cgi?id=536914 */
-       panel_session_manager_request_logout (panel_session_manager_get (),
-                                             PANEL_SESSION_MANAGER_LOGOUT_MODE_NORMAL);
-}
-
 static void
 panel_action_hibernate (GtkWidget *widget)
 {
@@ -250,18 +237,6 @@ static PanelAction actions [] = {
                NULL, NULL, NULL, NULL,
                NULL, NULL
        },
-       {
-               PANEL_ACTION_LOGOUT,
-               PANEL_ICON_LOGOUT,
-               /* when changing one of those two strings, don't forget to
-                * update the ones in panel-menu-items.c (look for
-                * "1" (msgctxt: "panel:showusername")) */
-               N_("Log Out"),
-               N_("Log out of this session to log in as a different user"),
-               "ACTION:logout:NEW",
-               panel_action_logout,
-               panel_lockdown_get_disable_log_out_s
-       },
        {
                PANEL_ACTION_RUN,
                PANEL_ICON_RUN,
diff --git a/gnome-panel/panel-enums.h b/gnome-panel/panel-enums.h
index 83a4f181c..b0bef1864 100644
--- a/gnome-panel/panel-enums.h
+++ b/gnome-panel/panel-enums.h
@@ -38,7 +38,6 @@ typedef enum {
 
 typedef enum {
         PANEL_ACTION_NONE = 0,
-        PANEL_ACTION_LOGOUT,
         PANEL_ACTION_RUN,
        PANEL_ACTION_FORCE_QUIT,
        PANEL_ACTION_HIBERNATE,
diff --git a/gnome-panel/panel-icon-names.h b/gnome-panel/panel-icon-names.h
index fa895ae51..de26633bd 100644
--- a/gnome-panel/panel-icon-names.h
+++ b/gnome-panel/panel-icon-names.h
@@ -17,7 +17,6 @@
 #define PANEL_ICON_HOME                        "user-home"
 #define PANEL_ICON_HIBERNATE           "gnome-panel-hibernate"
 #define PANEL_ICON_LAUNCHER            "gnome-panel-launcher"
-#define PANEL_ICON_LOGOUT              "system-log-out"
 #define PANEL_ICON_NETWORK             "network-workgroup"
 #define PANEL_ICON_PANEL               "gnome-panel"
 #define PANEL_ICON_REBOOT              "view-refresh"
diff --git a/gnome-panel/panel-object-loader.c b/gnome-panel/panel-object-loader.c
index 8c8ccae06..067705bad 100644
--- a/gnome-panel/panel-object-loader.c
+++ b/gnome-panel/panel-object-loader.c
@@ -424,7 +424,8 @@ panel_object_iid_to_type (const char       *iid,
                         if (d[0] == '\0')
                                 return FALSE;
 
-                        if (g_strcmp0 (d, "lock") == 0) {
+                        if (g_strcmp0 (d, "lock") == 0 ||
+                            g_strcmp0 (d, "logout") == 0) {
                                 *type = PANEL_OBJECT_APPLET;
                                 return TRUE;
                         }
diff --git a/modules/action-button/Makefile.am b/modules/action-button/Makefile.am
index 873ad4f14..c510b20b3 100644
--- a/modules/action-button/Makefile.am
+++ b/modules/action-button/Makefile.am
@@ -26,6 +26,8 @@ org_gnome_gnome_panel_action_button_la_SOURCES = \
        gp-action-button-module.c \
        gp-lock-screen-applet.c \
        gp-lock-screen-applet.h \
+       gp-logout-applet.c \
+       gp-logout-applet.h \
        $(BUILT_SOURCES) \
        $(NULL)
 
@@ -67,16 +69,25 @@ gpab-screensaver-gen.c: org.gnome.ScreenSaver.xml
                --generate-c-code gpab-screensaver-gen \
                $(srcdir)/org.gnome.ScreenSaver.xml
 
+gpab-session-manager-gen.h:
+gpab-session-manager-gen.c: org.gnome.SessionManager.xml
+       $(AM_V_GEN) $(GDBUS_CODEGEN) --c-namespace Gpab \
+               --generate-c-code gpab-session-manager-gen \
+               $(srcdir)/org.gnome.SessionManager.xml
+
 BUILT_SOURCES = \
        action-button-resources.c \
        action-button-resources.h \
        gpab-screensaver-gen.c \
        gpab-screensaver-gen.h \
+       gpab-session-manager-gen.c \
+       gpab-session-manager-gen.h \
        $(NULL)
 
 EXTRA_DIST = \
        action-button.gresource.xml \
        org.gnome.ScreenSaver.xml \
+       org.gnome.SessionManager.xml \
        $(ui_FILES) \
        $(NULL)
 
diff --git a/modules/action-button/gp-action-button-module.c b/modules/action-button/gp-action-button-module.c
index 377f4b7de..f8cda4019 100644
--- a/modules/action-button/gp-action-button-module.c
+++ b/modules/action-button/gp-action-button-module.c
@@ -21,6 +21,7 @@
 #include <libgnome-panel/gp-module.h>
 
 #include "gp-lock-screen-applet.h"
+#include "gp-logout-applet.h"
 
 static GpAppletInfo *
 action_button_get_applet_info (const char *id)
@@ -43,6 +44,15 @@ action_button_get_applet_info (const char *id)
 
       is_disabled_func = gp_lock_screen_applet_is_disabled;
     }
+  else if (g_strcmp0 (id, "logout") == 0)
+    {
+      type_func = gp_logout_applet_get_type;
+      name = _("Log Out");
+      description = _("Log out of this session to log in as a different user");
+      icon = "system-log-out";
+
+      is_disabled_func = gp_logout_applet_is_disabled;
+    }
   else
     {
       g_assert_not_reached ();
@@ -62,6 +72,8 @@ action_button_get_applet_id_from_iid (const char *iid)
 {
   if (g_strcmp0 (iid, "PanelInternalFactory::ActionButton:lock") == 0)
     return "lock-screen";
+  else if (g_strcmp0 (iid, "PanelInternalFactory::ActionButton:logout") == 0)
+    return "logout";
 
   return NULL;
 }
@@ -80,6 +92,7 @@ gp_module_load (GpModule *module)
 
   gp_module_set_applet_ids (module,
                             "lock-screen",
+                            "logout",
                             NULL);
 
   gp_module_set_get_applet_info (module, action_button_get_applet_info);
diff --git a/modules/action-button/gp-logout-applet.c b/modules/action-button/gp-logout-applet.c
new file mode 100644
index 000000000..a26fcb74e
--- /dev/null
+++ b/modules/action-button/gp-logout-applet.c
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2020 Alberts Muktupāvels
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+#include "gp-logout-applet.h"
+
+#include <glib/gi18n-lib.h>
+
+#include "gpab-session-manager-gen.h"
+
+struct _GpLogoutApplet
+{
+  GpActionButtonApplet   parent;
+
+  GpabSessionManagerGen *session_manager;
+};
+
+G_DEFINE_TYPE (GpLogoutApplet, gp_logout_applet, GP_TYPE_ACTION_BUTTON_APPLET)
+
+static void
+lockdown_changed (GpLogoutApplet *self)
+{
+  GpLockdownFlags lockdowns;
+  gboolean applet_sensitive;
+
+  lockdowns = gp_applet_get_lockdowns (GP_APPLET (self));
+
+  applet_sensitive = TRUE;
+
+  if ((lockdowns & GP_LOCKDOWN_FLAGS_APPLET) == GP_LOCKDOWN_FLAGS_APPLET ||
+      (lockdowns & GP_LOCKDOWN_FLAGS_LOG_OUT) == GP_LOCKDOWN_FLAGS_LOG_OUT)
+    applet_sensitive = FALSE;
+
+  gtk_widget_set_sensitive (GTK_WIDGET (self), applet_sensitive);
+}
+
+static void
+lockdowns_cb (GpApplet       *applet,
+              GParamSpec     *pspec,
+              GpLogoutApplet *self)
+{
+  lockdown_changed (self);
+}
+
+static void
+setup_applet (GpLogoutApplet *self)
+{
+  const char *text;
+  AtkObject *atk;
+
+  gp_action_button_applet_set_icon_name (GP_ACTION_BUTTON_APPLET (self),
+                                         "system-log-out");
+
+  text = _("Log out of this session to log in as a different user");
+
+  atk = gtk_widget_get_accessible (GTK_WIDGET (self));
+  atk_object_set_name (atk, text);
+  atk_object_set_description (atk, text);
+
+  gtk_widget_set_tooltip_text (GTK_WIDGET (self), text);
+
+  g_object_bind_property (self,
+                          "enable-tooltips",
+                          self,
+                          "has-tooltip",
+                          G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
+
+  lockdown_changed (self);
+}
+
+static void
+session_manager_ready_cb (GObject      *source,
+                          GAsyncResult *res,
+                          gpointer      user_data)
+{
+  GError *error;
+  GpabSessionManagerGen *session_manager;
+  GpLogoutApplet *self;
+
+  error = NULL;
+  session_manager = gpab_session_manager_gen_proxy_new_for_bus_finish (res,
+                                                                       &error);
+
+  if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+    {
+      g_error_free (error);
+      return;
+    }
+
+  self = GP_LOGOUT_APPLET (user_data);
+  self->session_manager = session_manager;
+
+  if (error)
+    {
+      g_warning ("%s", error->message);
+      g_error_free (error);
+
+      return;
+    }
+}
+
+static void
+gp_logout_applet_constructed (GObject *object)
+{
+  G_OBJECT_CLASS (gp_logout_applet_parent_class)->constructed (object);
+  setup_applet (GP_LOGOUT_APPLET (object));
+}
+
+static void
+gp_logout_applet_dispose (GObject *object)
+{
+  GpLogoutApplet *self;
+
+  self = GP_LOGOUT_APPLET (object);
+
+  g_clear_object (&self->session_manager);
+
+  G_OBJECT_CLASS (gp_logout_applet_parent_class)->dispose (object);
+}
+
+static void
+logout_cb (GObject      *source,
+           GAsyncResult *res,
+           gpointer      user_data)
+{
+  GError *error;
+
+  error = NULL;
+  gpab_session_manager_gen_call_logout_finish (GPAB_SESSION_MANAGER_GEN (source),
+                                               res,
+                                               &error);
+
+  if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+    {
+      g_error_free (error);
+      return;
+    }
+
+  if (error)
+    {
+      g_warning ("Could not ask session manager to log out: %s",
+                 error->message);
+
+      g_error_free (error);
+      return;
+    }
+}
+
+static void
+gp_logout_applet_clicked (GpActionButtonApplet *applet)
+{
+  GpLogoutApplet *self;
+
+  self = GP_LOGOUT_APPLET (applet);
+
+  if (!self->session_manager)
+    {
+      g_warning ("Screensaver service not available.");
+      return;
+    }
+
+  gpab_session_manager_gen_call_logout (self->session_manager,
+                                        0 /* normal */,
+                                        NULL,
+                                        logout_cb,
+                                        self);
+}
+
+static void
+gp_logout_applet_class_init (GpLogoutAppletClass *self_class)
+{
+  GObjectClass *object_class;
+  GpActionButtonAppletClass *action_button_applet_class;
+
+  object_class = G_OBJECT_CLASS (self_class);
+  action_button_applet_class = GP_ACTION_BUTTON_APPLET_CLASS (self_class);
+
+  object_class->constructed = gp_logout_applet_constructed;
+  object_class->dispose = gp_logout_applet_dispose;
+
+  action_button_applet_class->clicked = gp_logout_applet_clicked;
+}
+
+static void
+gp_logout_applet_init (GpLogoutApplet *self)
+{
+  gpab_session_manager_gen_proxy_new_for_bus (G_BUS_TYPE_SESSION,
+                                              G_DBUS_PROXY_FLAGS_NONE,
+                                              "org.gnome.SessionManager",
+                                              "/org/gnome/SessionManager",
+                                              NULL,
+                                              session_manager_ready_cb,
+                                              self);
+
+  g_signal_connect (self,
+                    "notify::lockdowns",
+                    G_CALLBACK (lockdowns_cb),
+                    self);
+}
+
+gboolean
+gp_logout_applet_is_disabled (GpLockdownFlags   flags,
+                              char            **reason)
+{
+  if ((flags & GP_LOCKDOWN_FLAGS_LOG_OUT) != GP_LOCKDOWN_FLAGS_LOG_OUT)
+    return FALSE;
+
+  if (reason != NULL)
+    *reason = g_strdup (_("Disabled because “disable-log-out” setting in "
+                          "“org.gnome.desktop.lockdown” GSettings schema is "
+                          "set to true."));
+
+  return FALSE;
+}
diff --git a/modules/action-button/gp-logout-applet.h b/modules/action-button/gp-logout-applet.h
new file mode 100644
index 000000000..d01018796
--- /dev/null
+++ b/modules/action-button/gp-logout-applet.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2020 Alberts Muktupāvels
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GP_LOGOUT_APPLET_H
+#define GP_LOGOUT_APPLET_H
+
+#include "gp-action-button-applet.h"
+
+G_BEGIN_DECLS
+
+#define GP_TYPE_LOGOUT_APPLET (gp_logout_applet_get_type ())
+G_DECLARE_FINAL_TYPE (GpLogoutApplet, gp_logout_applet,
+                      GP, LOGOUT_APPLET, GpActionButtonApplet)
+
+gboolean gp_logout_applet_is_disabled (GpLockdownFlags   flags,
+                                       char            **reason);
+
+G_END_DECLS
+
+#endif
diff --git a/modules/action-button/org.gnome.SessionManager.xml 
b/modules/action-button/org.gnome.SessionManager.xml
new file mode 100644
index 000000000..e4c8ba0a1
--- /dev/null
+++ b/modules/action-button/org.gnome.SessionManager.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd";>
+<node>
+  <interface name="org.gnome.SessionManager">
+    <annotation name="org.gtk.GDBus.C.Name" value="SessionManagerGen" />
+
+    <method name="Logout">
+      <arg name="mode" type="u" direction="in" />
+    </method>
+
+  </interface>
+</node>
diff --git a/modules/menu/gp-lock-logout.c b/modules/menu/gp-lock-logout.c
index f73c67b73..c034b2875 100644
--- a/modules/menu/gp-lock-logout.c
+++ b/modules/menu/gp-lock-logout.c
@@ -1011,12 +1011,17 @@ gp_lock_logout_append_to_menu (GpLockLogout *lock_logout,
     {
       label = _("Log Out");
       tooltip = _("Log out of this session to log in as a different user");
-      drag_id = "ACTION:logout:NEW";
+      drag_id = "org.gnome.gnome-panel.action-button::logout";
 
       logout = create_menu_item (lock_logout,
                                  "system-log-out",
                                  label, tooltip,
-                                 drag_id);
+                                 NULL);
+
+      setup_drag_source (lock_logout,
+                         logout,
+                         "system-log-out",
+                         drag_id);
 
       g_signal_connect (logout, "activate",
                         G_CALLBACK (logout_activate_cb),
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 5abfb1410..1445f865b 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -34,6 +34,7 @@ libgnome-panel/gp-module.c
 modules/action-button/gp-action-button-module.c
 modules/action-button/gp-lock-screen-applet.c
 modules/action-button/gp-lock-screen-menu.ui
+modules/action-button/gp-logout-applet.c
 modules/clock/calendar-client.c
 modules/clock/calendar-window.c
 modules/clock/clock-applet.c


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]