[gtk+/wip/statusicon] GtkApplication: Add a status-menu to as an exported object



commit 747a31cd70639691e167b9c9a1a2e19023acf36c
Author: Matthias Clasen <mclasen redhat com>
Date:   Wed May 24 22:21:57 2017 -0400

    GtkApplication: Add a status-menu to as an exported object
    
    This can be used together with the StatusIcon property to
    implement status icons.

 gtk/gtkapplication-dbus.c   |   11 +++++++++
 gtk/gtkapplication-x11.c    |    1 +
 gtk/gtkapplication.c        |   48 +++++++++++++++++++++++++++++++++++++++++++
 gtk/gtkapplication.h        |    7 ++++++
 gtk/gtkapplicationimpl.c    |    8 +++++++
 gtk/gtkapplicationprivate.h |   13 +++++++++++
 6 files changed, 88 insertions(+), 0 deletions(-)
---
diff --git a/gtk/gtkapplication-dbus.c b/gtk/gtkapplication-dbus.c
index 3ad964e..7219281 100644
--- a/gtk/gtkapplication-dbus.c
+++ b/gtk/gtkapplication-dbus.c
@@ -443,6 +443,15 @@ gtk_application_impl_dbus_set_menubar (GtkApplicationImpl *impl,
   gtk_application_impl_dbus_publish_menu (dbus, "menubar", menubar, &dbus->menubar_id, &dbus->menubar_path);
 }
 
+static void
+gtk_application_impl_dbus_set_status_menu (GtkApplicationImpl *impl,
+                                           GMenuModel         *menu)
+{
+  GtkApplicationImplDBus *dbus = (GtkApplicationImplDBus *) impl;
+
+  gtk_application_impl_dbus_publish_menu (dbus, "statusmenu", menu, &dbus->status_menu_id, 
&dbus->status_menu_path);
+}
+
 static GVariant *
 gtk_application_impl_dbus_real_get_window_system_id (GtkApplicationImplDBus *dbus,
                                                      GtkWindow              *window)
@@ -693,6 +702,7 @@ gtk_application_impl_dbus_finalize (GObject *object)
   g_slist_free_full (dbus->inhibit_handles, inhibit_handle_free);
   g_free (dbus->app_menu_path);
   g_free (dbus->menubar_path);
+  g_free (dbus->status_menu_path);
   g_clear_object (&dbus->sm_proxy);
 
   G_OBJECT_CLASS (gtk_application_impl_dbus_parent_class)->finalize (object);
@@ -713,6 +723,7 @@ gtk_application_impl_dbus_class_init (GtkApplicationImplDBusClass *class)
   impl_class->active_window_changed = gtk_application_impl_dbus_active_window_changed;
   impl_class->set_app_menu = gtk_application_impl_dbus_set_app_menu;
   impl_class->set_menubar = gtk_application_impl_dbus_set_menubar;
+  impl_class->set_status_menu = gtk_application_impl_dbus_set_status_menu;
   impl_class->inhibit = gtk_application_impl_dbus_inhibit;
   impl_class->uninhibit = gtk_application_impl_dbus_uninhibit;
   impl_class->is_inhibited = gtk_application_impl_dbus_is_inhibited;
diff --git a/gtk/gtkapplication-x11.c b/gtk/gtkapplication-x11.c
index 8c52be8..adf814f 100644
--- a/gtk/gtkapplication-x11.c
+++ b/gtk/gtkapplication-x11.c
@@ -55,6 +55,7 @@ gtk_application_impl_x11_handle_window_realize (GtkApplicationImpl *impl,
   gdk_x11_window_set_utf8_property (gdk_window, "_GTK_WINDOW_OBJECT_PATH", window_path);
   gdk_x11_window_set_utf8_property (gdk_window, "_GTK_APP_MENU_OBJECT_PATH", dbus->app_menu_path);
   gdk_x11_window_set_utf8_property (gdk_window, "_GTK_MENUBAR_OBJECT_PATH", dbus->menubar_path);
+  gdk_x11_window_set_utf8_property (gdk_window, "_GTK_STATUS_MENU_OBJECT_PATH", dbus->status_menu_path);
 
   g_free (window_path);
 }
diff --git a/gtk/gtkapplication.c b/gtk/gtkapplication.c
index ff70808..511b3ae 100644
--- a/gtk/gtkapplication.c
+++ b/gtk/gtkapplication.c
@@ -140,6 +140,7 @@ enum {
   PROP_APP_MENU,
   PROP_MENUBAR,
   PROP_ACTIVE_WINDOW,
+  PROP_STATUS_MENU,
   NUM_PROPERTIES
 };
 
@@ -160,6 +161,8 @@ struct _GtkApplicationPrivate
   GtkActionMuxer  *muxer;
   GtkBuilder      *menus_builder;
   gchar           *help_overlay_path;
+
+  GMenuModel      *status_menu;
 };
 
 G_DEFINE_TYPE_WITH_PRIVATE (GtkApplication, gtk_application, G_TYPE_APPLICATION)
@@ -258,6 +261,9 @@ gtk_application_load_resources (GtkApplication *application)
         menu = gtk_builder_get_object (application->priv->menus_builder, "menubar");
         if (menu != NULL && G_IS_MENU_MODEL (menu))
           gtk_application_set_menubar (application, G_MENU_MODEL (menu));
+        menu = gtk_builder_get_object (application->priv->menus_builder, "status-menu");
+        if (menu != NULL && G_IS_MENU_MODEL (menu))
+          gtk_application_set_status_menu (application, G_MENU_MODEL (menu));
       }
   }
 
@@ -531,6 +537,10 @@ gtk_application_get_property (GObject    *object,
       g_value_set_object (value, gtk_application_get_active_window (application));
       break;
 
+    case PROP_STATUS_MENU:
+      g_value_set_object (value, gtk_application_get_status_menu (application));
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -559,6 +569,10 @@ gtk_application_set_property (GObject      *object,
       gtk_application_set_menubar (application, g_value_get_object (value));
       break;
 
+    case PROP_STATUS_MENU:
+      gtk_application_set_status_menu (application, g_value_get_object (value));
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -575,6 +589,7 @@ gtk_application_finalize (GObject *object)
   g_clear_object (&application->priv->menubar);
   g_clear_object (&application->priv->muxer);
   g_clear_object (&application->priv->accels);
+  g_clear_object (&application->priv->status_menu);
 
   g_free (application->priv->help_overlay_path);
 
@@ -671,6 +686,13 @@ gtk_application_class_init (GtkApplicationClass *class)
                          GTK_TYPE_WINDOW,
                          G_PARAM_READABLE|G_PARAM_STATIC_STRINGS);
 
+  gtk_application_props[PROP_STATUS_MENU] =
+    g_param_spec_object ("status-menu",
+                         P_("Status menu"),
+                         P_("The GMenuModel for the status menu"),
+                         G_TYPE_MENU_MODEL,
+                         G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS);
+
   g_object_class_install_properties (object_class, NUM_PROPERTIES, gtk_application_props);
 }
 
@@ -1377,3 +1399,29 @@ gtk_application_get_menu_by_id (GtkApplication *application,
 
   return G_MENU (object);
 }
+
+void
+gtk_application_set_status_menu (GtkApplication *application,
+                                 GMenuModel     *menu)
+{
+  g_return_if_fail (GTK_IS_APPLICATION (application));
+  g_return_if_fail (g_application_get_is_registered (G_APPLICATION (application)));
+  g_return_if_fail (!g_application_get_is_remote (G_APPLICATION (application)));
+  g_return_if_fail (menu == NULL || G_IS_MENU_MODEL (menu));
+
+  if (g_set_object (&application->priv->status_menu, menu))
+    {
+      gtk_application_impl_set_status_menu (application->priv->impl, menu);
+
+      g_object_notify_by_pspec (G_OBJECT (application), gtk_application_props[PROP_STATUS_MENU]);
+    }
+}
+
+GMenuModel *
+gtk_application_get_status_menu (GtkApplication *application)
+{
+  g_return_val_if_fail (GTK_IS_APPLICATION (application), NULL);
+
+  return application->priv->status_menu;
+}
+
diff --git a/gtk/gtkapplication.h b/gtk/gtkapplication.h
index 3b7cb1a..b8c7573 100644
--- a/gtk/gtkapplication.h
+++ b/gtk/gtkapplication.h
@@ -151,6 +151,13 @@ GDK_AVAILABLE_IN_3_14
 GMenu *          gtk_application_get_menu_by_id                  (GtkApplication       *application,
                                                                   const gchar          *id);
 
+GDK_AVAILABLE_IN_3_92
+void             gtk_application_set_status_menu                 (GtkApplication       *application,
+                                                                  GMenuModel           *menu);
+
+GDK_AVAILABLE_IN_3_92
+GMenuModel *     gtk_application_get_status_menu                 (GtkApplication       *application);
+
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkApplication, g_object_unref)
 
 G_END_DECLS
diff --git a/gtk/gtkapplicationimpl.c b/gtk/gtkapplicationimpl.c
index 946284b..b428019 100644
--- a/gtk/gtkapplicationimpl.c
+++ b/gtk/gtkapplicationimpl.c
@@ -61,6 +61,7 @@ gtk_application_impl_class_init (GtkApplicationImplClass *class)
   class->uninhibit = (gpointer) do_nothing;
   class->is_inhibited = (gpointer) do_nothing;
   class->prefers_app_menu = (gpointer) return_false;
+  class->set_status_menu = (gpointer) do_nothing;
 }
 
 void
@@ -161,6 +162,13 @@ gtk_application_impl_prefers_app_menu (GtkApplicationImpl *impl)
   return GTK_APPLICATION_IMPL_GET_CLASS (impl)->prefers_app_menu (impl);
 }
 
+void
+gtk_application_impl_set_status_menu (GtkApplicationImpl *impl,
+                                      GMenuModel         *menu)
+{
+  GTK_APPLICATION_IMPL_GET_CLASS (impl)->set_status_menu (impl, menu);
+}
+
 GtkApplicationImpl *
 gtk_application_impl_new (GtkApplication *application,
                           GdkDisplay     *display)
diff --git a/gtk/gtkapplicationprivate.h b/gtk/gtkapplicationprivate.h
index 59eff02..d7fcee3 100644
--- a/gtk/gtkapplicationprivate.h
+++ b/gtk/gtkapplicationprivate.h
@@ -98,6 +98,10 @@ typedef struct
 
   gboolean    (* prefers_app_menu)          (GtkApplicationImpl          *impl);
 
+  void        (* set_status_icon)           (GtkApplicationImpl          *impl,
+                                             GIcon                       *icon);
+  void        (* set_status_menu)           (GtkApplicationImpl          *impl,
+                                             GMenuModel                  *menu);
 
 } GtkApplicationImplClass;
 
@@ -125,6 +129,9 @@ typedef struct
   gchar           *menubar_path;
   guint            menubar_id;
 
+  gchar           *status_menu_path;
+  guint            status_menu_id;
+
   /* Session management... */
   GDBusProxy      *sm_proxy;
   GDBusProxy      *client_proxy;
@@ -188,6 +195,12 @@ gboolean                gtk_application_impl_prefers_app_menu           (GtkAppl
 void                    gtk_application_impl_quartz_setup_menu          (GMenuModel                  *model,
                                                                          GtkActionMuxer              *muxer);
 
+void                    gtk_application_impl_set_status_icon            (GtkApplicationImpl          *impl,
+                                                                         GIcon                       *icon);
+
+void                    gtk_application_impl_set_status_menu            (GtkApplicationImpl          *impl,
+                                                                         GMenuModel                  *menu);
+
 G_END_DECLS
 
 #endif /* __GTK_APPLICATION_PRIVATE_H__ */


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