[gnome-flashback] system-indicators: add SiDesktopMenuItem



commit 689e2964452e799d81ef7b71f136396b453b37e0
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Fri Dec 27 15:16:26 2019 +0200

    system-indicators: add SiDesktopMenuItem
    
    And use it to create menu items that are used to launch desktop files.

 po/POTFILES.in                           |   1 +
 system-indicators/Makefile.am            |   2 +
 system-indicators/si-bluetooth.c         | 107 +++-------------
 system-indicators/si-desktop-menu-item.c | 205 +++++++++++++++++++++++++++++++
 system-indicators/si-desktop-menu-item.h |  34 +++++
 system-indicators/si-input-source.c      |   7 ++
 system-indicators/si-power.c             |  53 +-------
 7 files changed, 270 insertions(+), 139 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 4a706bb..1891937 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -43,6 +43,7 @@ gnome-flashback/libsound-applet/gvc-channel-bar.c
 gnome-flashback/libsound-applet/gvc-stream-status-icon.c
 gvc/gvc/gvc-mixer-control.c
 system-indicators/si-bluetooth.c
+system-indicators/si-desktop-menu-item.c
 system-indicators/si-input-source.c
 system-indicators/si-module.c
 system-indicators/si-power.c
diff --git a/system-indicators/Makefile.am b/system-indicators/Makefile.am
index 8207589..65b816c 100644
--- a/system-indicators/Makefile.am
+++ b/system-indicators/Makefile.am
@@ -23,6 +23,8 @@ system_indicators_la_SOURCES = \
        si-applet.h \
        si-bluetooth.c \
        si-bluetooth.h \
+       si-desktop-menu-item.c \
+       si-desktop-menu-item.h \
        si-indicator.c \
        si-indicator.h \
        si-input-source.c \
diff --git a/system-indicators/si-bluetooth.c b/system-indicators/si-bluetooth.c
index 069afc3..ba60603 100644
--- a/system-indicators/si-bluetooth.c
+++ b/system-indicators/si-bluetooth.c
@@ -19,10 +19,10 @@
 #include "si-bluetooth.h"
 
 #include <bluetooth-client.h>
-#include <gio/gdesktopappinfo.h>
 #include <glib/gi18n.h>
 
 #include "dbus/gf-sd-rfkill-gen.h"
+#include "si-desktop-menu-item.h"
 
 struct _SiBluetooth
 {
@@ -75,30 +75,6 @@ turn_off_cb (GtkMenuItem *item,
   gf_sd_rfkill_gen_set_bluetooth_airplane_mode (self->rfkill, TRUE);
 }
 
-static void
-send_files_cb (GtkMenuItem *item,
-               gpointer     user_data)
-{
-  GDesktopAppInfo *info;
-  GError *error;
-
-  info = g_desktop_app_info_new ("bluetooth-sendto.desktop");
-
-  if (info == NULL)
-    return;
-
-  error = NULL;
-  g_app_info_launch (G_APP_INFO (info), NULL, NULL, &error);
-
-  if (error != NULL)
-    {
-      g_warning ("Failed to start Bluetooth Transfer - %s", error->message);
-      g_error_free (error);
-    }
-
-  g_clear_object (&info);
-}
-
 static void
 append_main_items (SiBluetooth *self)
 {
@@ -112,11 +88,11 @@ append_main_items (SiBluetooth *self)
 
       g_signal_connect (item, "activate", G_CALLBACK (turn_off_cb), self);
 
-      item = gtk_menu_item_new_with_label (_("Send Files"));
+      item = si_desktop_menu_item_new (_("Send Files"),
+                                       "bluetooth-sendto.desktop");
+
       gtk_menu_shell_append (GTK_MENU_SHELL (self->menu), item);
       gtk_widget_show (item);
-
-      g_signal_connect (item, "activate", G_CALLBACK (send_files_cb), NULL);
     }
   else
     {
@@ -196,37 +172,6 @@ connect_cb (GtkMenuItem *item,
                                     self);
 }
 
-static void
-activate_settings_cb (GtkMenuItem *item,
-                      const char  *desktop_id)
-{
-  GDesktopAppInfo *info;
-  GError *error;
-
-  info = g_desktop_app_info_new (desktop_id);
-
-  if (info == NULL)
-    return;
-
-  error = NULL;
-  g_app_info_launch (G_APP_INFO (info), NULL, NULL, &error);
-
-  if (error != NULL)
-    {
-      g_warning ("%s", error->message);
-      g_error_free (error);
-    }
-
-  g_clear_object (&info);
-}
-
-static void
-free_desktop_id (gpointer  data,
-                 GClosure *closure)
-{
-  g_free (data);
-}
-
 static void
 append_devices (SiBluetooth *self,
                 GtkTreeIter *adapter,
@@ -308,44 +253,29 @@ append_devices (SiBluetooth *self,
       switch (type)
         {
           case BLUETOOTH_TYPE_KEYBOARD:
-            item = gtk_menu_item_new_with_label (_("Keyboard Settings"));
+            item = si_desktop_menu_item_new (_("Keyboard Settings"),
+                                             "gnome-keyboard-panel.desktop");
+
             gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
             gtk_widget_show (item);
-
-            g_signal_connect_data (item,
-                                   "activate",
-                                   G_CALLBACK (activate_settings_cb),
-                                   g_strdup ("gnome-kayboard-panel.desktop"),
-                                   free_desktop_id,
-                                   0);
             break;
 
           case BLUETOOTH_TYPE_MOUSE:
-            item = gtk_menu_item_new_with_label (_("Mouse & Touchpad Settings"));
+            item = si_desktop_menu_item_new (_("Mouse & Touchpad Settings"),
+                                             "gnome-mouse-panel.desktop");
+
             gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
             gtk_widget_show (item);
-
-            g_signal_connect_data (item,
-                                   "activate",
-                                   G_CALLBACK (activate_settings_cb),
-                                   g_strdup ("gnome-mouse-panel.desktop"),
-                                   free_desktop_id,
-                                   0);
             break;
 
           case BLUETOOTH_TYPE_HEADSET:
           case BLUETOOTH_TYPE_HEADPHONES:
           case BLUETOOTH_TYPE_OTHER_AUDIO:
-            item = gtk_menu_item_new_with_label (_("Sound Settings"));
+            item = si_desktop_menu_item_new (_("Sound Settings"),
+                                             "gnome-sound-panel.desktop");
+
             gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
             gtk_widget_show (item);
-
-            g_signal_connect_data (item,
-                                   "activate",
-                                   G_CALLBACK (activate_settings_cb),
-                                   g_strdup ("gnome-sound-panel.desktop"),
-                                   free_desktop_id,
-                                   0);
             break;
 
           case BLUETOOTH_TYPE_ANY:
@@ -395,16 +325,11 @@ update_indicator_menu (SiBluetooth *self,
   gtk_menu_shell_append (GTK_MENU_SHELL (self->menu), separator);
   gtk_widget_show (separator);
 
-  item = gtk_menu_item_new_with_label (_("Bluetooth Settings"));
+  item = si_desktop_menu_item_new (_("Bluetooth Settings"),
+                                   "gnome-bluetooth-panel.desktop");
+
   gtk_menu_shell_append (GTK_MENU_SHELL (self->menu), item);
   gtk_widget_show (item);
-
-  g_signal_connect_data (item,
-                         "activate",
-                         G_CALLBACK (activate_settings_cb),
-                         g_strdup ("gnome-bluetooth-panel.desktop"),
-                         free_desktop_id,
-                         0);
 }
 
 static void
diff --git a/system-indicators/si-desktop-menu-item.c b/system-indicators/si-desktop-menu-item.c
new file mode 100644
index 0000000..851e193
--- /dev/null
+++ b/system-indicators/si-desktop-menu-item.c
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2019 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 3 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 "si-desktop-menu-item.h"
+
+#include <glib/gi18n.h>
+#include <gio/gdesktopappinfo.h>
+
+struct _SiDesktopMenuItem
+{
+  GtkMenuItem      parent;
+
+  char            *desktop_id;
+  GDesktopAppInfo *app_info;
+};
+
+enum
+{
+  PROP_0,
+
+  PROP_DESKTOP_ID,
+
+  LAST_PROP
+};
+
+static GParamSpec *item_properties[LAST_PROP] = { NULL };
+
+G_DEFINE_TYPE (SiDesktopMenuItem, si_desktop_menu_item, GTK_TYPE_MENU_ITEM)
+
+static void
+response_cb (GtkDialog         *dialog,
+             gint               response_id,
+             SiDesktopMenuItem *self)
+{
+  gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+static void
+show_error_message (SiDesktopMenuItem *self,
+                    const char        *message)
+{
+  GtkWidget *dialog;
+
+  dialog = gtk_message_dialog_new (NULL,
+                                   GTK_DIALOG_USE_HEADER_BAR,
+                                   GTK_MESSAGE_ERROR,
+                                   GTK_BUTTONS_CLOSE,
+                                   "%s",
+                                   message);
+
+  g_signal_connect (dialog, "response", G_CALLBACK (response_cb), self);
+  gtk_widget_show (dialog);
+}
+
+static void
+activate_cb (SiDesktopMenuItem *self,
+             gpointer           user_data)
+{
+  char *message;
+  GError *error;
+  const char *label;
+
+  if (self->app_info == NULL)
+    {
+      message = g_strdup_printf (_("Desktop file “%s” is missing!"),
+                                 self->desktop_id);
+
+      show_error_message (self, message);
+      g_free (message);
+      return;
+    }
+
+  error = NULL;
+  g_app_info_launch (G_APP_INFO (self->app_info), NULL, NULL, &error);
+
+  if (error == NULL)
+    return;
+
+  label = gtk_menu_item_get_label (GTK_MENU_ITEM (self));
+  message = g_strdup_printf (_("Failed to start “%s”: %s"), label, error->message);
+  g_error_free (error);
+
+  show_error_message (self, message);
+  g_free (message);
+}
+
+static void
+si_desktop_menu_item_constructed (GObject *object)
+{
+  SiDesktopMenuItem *self;
+
+  self = SI_DESKTOP_MENU_ITEM (object);
+
+  G_OBJECT_CLASS (si_desktop_menu_item_parent_class)->constructed (object);
+
+  self->app_info = g_desktop_app_info_new (self->desktop_id);
+}
+
+static void
+si_desktop_menu_item_dispose (GObject *object)
+{
+  SiDesktopMenuItem *self;
+
+  self = SI_DESKTOP_MENU_ITEM (object);
+
+  g_clear_object (&self->app_info);
+
+  G_OBJECT_CLASS (si_desktop_menu_item_parent_class)->dispose (object);
+}
+
+static void
+si_desktop_menu_item_finalize (GObject *object)
+{
+  SiDesktopMenuItem *self;
+
+  self = SI_DESKTOP_MENU_ITEM (object);
+
+  g_clear_pointer (&self->desktop_id, g_free);
+
+  G_OBJECT_CLASS (si_desktop_menu_item_parent_class)->finalize (object);
+}
+
+static void
+si_desktop_menu_item_set_property (GObject      *object,
+                                   guint         property_id,
+                                   const GValue *value,
+                                   GParamSpec   *pspec)
+{
+  SiDesktopMenuItem *self;
+
+  self = SI_DESKTOP_MENU_ITEM (object);
+
+  switch (property_id)
+    {
+      case PROP_DESKTOP_ID:
+        g_assert (self->desktop_id == NULL);
+        self->desktop_id = g_value_dup_string (value);
+        break;
+
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+        break;
+    }
+}
+
+static void
+install_properties (GObjectClass *object_class)
+{
+  item_properties[PROP_DESKTOP_ID] =
+    g_param_spec_string ("desktop-id",
+                         "desktop-id",
+                         "desktop-id",
+                         NULL,
+                         G_PARAM_CONSTRUCT_ONLY |
+                         G_PARAM_WRITABLE |
+                         G_PARAM_STATIC_STRINGS);
+
+  g_object_class_install_properties (object_class, LAST_PROP, item_properties);
+}
+
+static void
+si_desktop_menu_item_class_init (SiDesktopMenuItemClass *self_class)
+{
+  GObjectClass *object_class;
+
+  object_class = G_OBJECT_CLASS (self_class);
+
+  object_class->constructed = si_desktop_menu_item_constructed;
+  object_class->dispose = si_desktop_menu_item_dispose;
+  object_class->finalize = si_desktop_menu_item_finalize;
+  object_class->set_property = si_desktop_menu_item_set_property;
+
+  install_properties (object_class);
+}
+
+static void
+si_desktop_menu_item_init (SiDesktopMenuItem *self)
+{
+  g_signal_connect (self, "activate", G_CALLBACK (activate_cb), NULL);
+}
+
+GtkWidget *
+si_desktop_menu_item_new (const char *label,
+                          const char *desktop_id)
+{
+  return g_object_new (SI_TYPE_DESKTOP_MENU_ITEM,
+                       "desktop-id", desktop_id,
+                       "label", label,
+                       NULL);
+}
diff --git a/system-indicators/si-desktop-menu-item.h b/system-indicators/si-desktop-menu-item.h
new file mode 100644
index 0000000..dd344aa
--- /dev/null
+++ b/system-indicators/si-desktop-menu-item.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2019 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 3 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 SI_DESKTOP_MENU_ITEM_H
+#define SI_DESKTOP_MENU_ITEM_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define SI_TYPE_DESKTOP_MENU_ITEM (si_desktop_menu_item_get_type ())
+G_DECLARE_FINAL_TYPE (SiDesktopMenuItem, si_desktop_menu_item,
+                      SI, DESKTOP_MENU_ITEM, GtkMenuItem)
+
+GtkWidget *si_desktop_menu_item_new (const char *label,
+                                     const char *desktop_id);
+
+G_END_DECLS
+
+#endif
diff --git a/system-indicators/si-input-source.c b/system-indicators/si-input-source.c
index a433adb..b564ff7 100644
--- a/system-indicators/si-input-source.c
+++ b/system-indicators/si-input-source.c
@@ -24,6 +24,7 @@
 #include <utime.h>
 
 #include "dbus/gf-input-sources-gen.h"
+#include "si-desktop-menu-item.h"
 
 struct _SiInputSource
 {
@@ -854,6 +855,12 @@ append_show_layout_item (SiInputSource *self,
 
   g_signal_connect (item, "activate", G_CALLBACK (show_layout_cb), self);
 
+  item = si_desktop_menu_item_new (_("Region & Language Settings"),
+                                   "gnome-region-panel.desktop");
+
+  gtk_menu_shell_append (GTK_MENU_SHELL (self->menu), item);
+  gtk_widget_show (item);
+
   if (layout != NULL && *layout != '\0')
     {
       char *description;
diff --git a/system-indicators/si-power.c b/system-indicators/si-power.c
index 8dcd3b0..67c7355 100644
--- a/system-indicators/si-power.c
+++ b/system-indicators/si-power.c
@@ -19,11 +19,11 @@
 #include "si-power.h"
 
 #include <glib/gi18n.h>
-#include <gio/gdesktopappinfo.h>
 #include <libupower-glib/upower.h>
 #include <math.h>
 
 #include "dbus/gf-upower-device-gen.h"
+#include "si-desktop-menu-item.h"
 
 struct _SiPower
 {
@@ -40,37 +40,6 @@ struct _SiPower
 
 G_DEFINE_TYPE (SiPower, si_power, SI_TYPE_INDICATOR)
 
-static void
-activate_desktop_cb (GtkMenuItem *item,
-                     const char  *desktop_id)
-{
-  GDesktopAppInfo *info;
-  GError *error;
-
-  info = g_desktop_app_info_new (desktop_id);
-
-  if (info == NULL)
-    return;
-
-  error = NULL;
-  g_app_info_launch (G_APP_INFO (info), NULL, NULL, &error);
-
-  if (error != NULL)
-    {
-      g_warning ("%s", error->message);
-      g_error_free (error);
-    }
-
-  g_clear_object (&info);
-}
-
-static void
-free_desktop_id (gpointer  data,
-                 GClosure *closure)
-{
-  g_free (data);
-}
-
 static void
 remove_item_cb (GtkWidget *widget,
                 gpointer   data)
@@ -159,33 +128,21 @@ update_indicator_menu (SiPower *self)
   label = g_strdup_printf ("%s: %s", type_text, state_text);
   g_free (state_text);
 
-  item = gtk_menu_item_new_with_label (label);
+  item = si_desktop_menu_item_new (label, "org.gnome.PowerStats.desktop");
   g_free (label);
 
   gtk_menu_shell_append (GTK_MENU_SHELL (self->menu), item);
   gtk_widget_show (item);
 
-  g_signal_connect_data (item,
-                         "activate",
-                         G_CALLBACK (activate_desktop_cb),
-                         g_strdup ("org.gnome.PowerStats.desktop"),
-                         free_desktop_id,
-                         0);
-
   separator = gtk_separator_menu_item_new ();
   gtk_menu_shell_append (GTK_MENU_SHELL (self->menu), separator);
   gtk_widget_show (separator);
 
-  item = gtk_menu_item_new_with_label (_("Power Settings"));
+  item = si_desktop_menu_item_new (_("Power Settings"),
+                                   "gnome-power-panel.desktop");
+
   gtk_menu_shell_append (GTK_MENU_SHELL (self->menu), item);
   gtk_widget_show (item);
-
-  g_signal_connect_data (item,
-                         "activate",
-                         G_CALLBACK (activate_desktop_cb),
-                         g_strdup ("gnome-power-panel.desktop"),
-                         free_desktop_id,
-                         0);
 }
 
 static void


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