[gtk+] modelmenu: listen for toplevel changes on the attach widget
- From: Cosimo Cecchi <cosimoc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] modelmenu: listen for toplevel changes on the attach widget
- Date: Fri, 6 Jul 2012 15:14:44 +0000 (UTC)
commit 5dbf3a576aab1bd33e6e08121690afefad19e50f
Author: Cosimo Cecchi <cosimoc gnome org>
Date: Thu Jul 5 10:49:39 2012 -0400
modelmenu: listen for toplevel changes on the attach widget
Right now, when we create a GtkModelMenu for a GMenuModel, we listen to
changes to the menu's attach-widget to detect when a toplevel
GtkApplicationWindow becomes available to fetch actions from it.
This unfortunately breaks this simple code:
GtkWidget *application_window = gtk_application_window_new();
GtkWidget *menu_button = gtk_menu_button_new();
GMenuModel *menu_model = get_menu_model();
gtk_menu_button_set_menu_model(menu_button, menu_model);
gtk_container_add(GTK_CONTAINER(application_window), menu_button);
Since GtkMenuButton creates a GtkModelMenu and sets itself as its attach
widget before it's added to a hierarchy containing a
GtkApplicationWindow.
Fix the bug by simply listening for changes in the window hierarchy, and
creating the menu model when the attach widget is added to an
application window.
https://bugzilla.gnome.org/show_bug.cgi?id=679454
gtk/gtkmodelmenu.c | 60 ++++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 49 insertions(+), 11 deletions(-)
---
diff --git a/gtk/gtkmodelmenu.c b/gtk/gtkmodelmenu.c
index 1f12595..9dd9aa5 100644
--- a/gtk/gtkmodelmenu.c
+++ b/gtk/gtkmodelmenu.c
@@ -29,6 +29,8 @@
#include "gtkmodelmenuitem.h"
#include "gtkapplicationprivate.h"
+#define MODEL_MENU_WIDGET_DATA "gtk-model-menu-widget-data"
+
typedef struct {
GActionObservable *actions;
GMenuModel *model;
@@ -276,24 +278,60 @@ gtk_model_menu_create_menu (GMenuModel *model,
}
static void
-notify_attach (GtkMenu *menu,
- GParamSpec *pspec,
- gpointer data)
+gtk_model_menu_connect_app_window (GtkMenu *menu,
+ GtkApplicationWindow *window)
{
- GtkWidget *widget;
- GtkWidget *toplevel;
GActionObservable *actions;
GtkAccelGroup *accels;
- widget = gtk_menu_get_attach_widget (menu);
- toplevel = gtk_widget_get_toplevel (widget);
+ actions = gtk_application_window_get_observable (window);
+ accels = gtk_application_window_get_accel_group (window);
+
+ gtk_menu_set_accel_group (menu, accels);
+ gtk_model_menu_populate (GTK_MENU_SHELL (menu), actions, accels);
+}
+
+static void
+attach_widget_hierarchy_changed (GtkWidget *attach_widget,
+ GtkWidget *previous_toplevel,
+ gpointer user_data)
+{
+ GtkWidget *toplevel;
+ GtkMenu *menu = user_data;
+
+ toplevel = gtk_widget_get_toplevel (attach_widget);
if (GTK_IS_APPLICATION_WINDOW (toplevel))
+ gtk_model_menu_connect_app_window (menu, GTK_APPLICATION_WINDOW (toplevel));
+}
+
+static void
+notify_attach (GtkMenu *menu,
+ GParamSpec *pspec,
+ gpointer data)
+{
+ GtkWidget *attach_widget, *toplevel;
+
+ attach_widget = g_object_get_data (G_OBJECT (menu), MODEL_MENU_WIDGET_DATA);
+ if (attach_widget != NULL)
{
- actions = gtk_application_window_get_observable (GTK_APPLICATION_WINDOW (toplevel));
- accels = gtk_application_window_get_accel_group (GTK_APPLICATION_WINDOW (toplevel));
+ g_signal_handlers_disconnect_by_func (attach_widget, attach_widget_hierarchy_changed, menu);
+ g_object_set_data (G_OBJECT (menu), MODEL_MENU_WIDGET_DATA, NULL);
+ }
+
+ attach_widget = gtk_menu_get_attach_widget (menu);
+ if (!attach_widget)
+ return;
- gtk_menu_set_accel_group (menu, accels);
- gtk_model_menu_populate (GTK_MENU_SHELL (menu), actions, accels);
+ toplevel = gtk_widget_get_toplevel (attach_widget);
+ if (GTK_IS_APPLICATION_WINDOW (toplevel))
+ {
+ gtk_model_menu_connect_app_window (menu, GTK_APPLICATION_WINDOW (toplevel));
+ }
+ else
+ {
+ g_object_set_data (G_OBJECT (menu), MODEL_MENU_WIDGET_DATA, attach_widget);
+ g_signal_connect_object (attach_widget, "hierarchy-changed",
+ G_CALLBACK (attach_widget_hierarchy_changed), menu, 0);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]