From 747a31cd70639691e167b9c9a1a2e19023acf36c Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 24 May 2017 22:21:57 -0400 Subject: 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(+) diff --git a/gtk/gtkapplication-dbus.c b/gtk/gtkapplication-dbus.c index 3ad964ee57..721928123a 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 8c52be8490..adf814f593 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 ff70808584..511b3ae8f3 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 3b7cb1a3ee..b8c757337f 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 946284b19a..b42801967d 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 59eff0266e..d7fcee344f 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__ */ -- cgit v1.2.1