Commit 373b7a30 authored by Christian Hergert's avatar Christian Hergert
Browse files

util: ensure IdeWidgetContextHandler is emitted only once per change

It was possible previously that we could notify multiple times for the same
IdeContext. This stashes a pointer (only for comparison) in quark data like
we do with our handler. It then only notifies when that has changed.

Additionally, we move to using the Quark API instead of the string-based
parent 288227fd
......@@ -21,25 +21,48 @@
#include "application/ide-application.h"
#include "util/ide-gtk.h"
static GQuark quark_handler;
static GQuark quark_where_context_was;
static void
ide_widget_notify_context (GtkWidget *toplevel,
GParamSpec *pspec,
GtkWidget *widget)
IdeWidgetContextHandler handler;
g_autoptr(IdeContext) context = NULL;
IdeContext *old_context;
IdeContext *context;
g_assert (GTK_IS_WIDGET (toplevel));
g_assert (GTK_IS_WIDGET (widget));
handler = g_object_get_qdata (G_OBJECT (widget), quark_handler);
old_context = g_object_get_qdata (G_OBJECT (widget), quark_where_context_was);
handler = g_object_get_data (G_OBJECT (widget), "IDE_CONTEXT_HANDLER");
if (handler == NULL)
g_object_get (toplevel,
"context", &context,
context = ide_widget_get_context (toplevel);
if (context == old_context)
g_object_set_qdata (G_OBJECT (widget), quark_where_context_was, context);
handler (widget, context);
static gboolean
has_context_property (GtkWidget *widget)
GParamSpec *pspec;
g_assert (GTK_IS_WIDGET (widget));
pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (widget), "context");
return pspec != NULL && g_type_is_a (pspec->value_type, IDE_TYPE_CONTEXT);
static void
ide_widget_hierarchy_changed (GtkWidget *widget,
GtkWidget *previous_toplevel,
......@@ -56,7 +79,7 @@ ide_widget_hierarchy_changed (GtkWidget *widget,
toplevel = gtk_widget_get_toplevel (widget);
if (GTK_IS_WINDOW (toplevel))
if (GTK_IS_WINDOW (toplevel) && has_context_property (toplevel))
g_signal_connect_object (toplevel,
......@@ -82,14 +105,22 @@ ide_widget_set_context_handler (gpointer widget,
g_return_if_fail (GTK_IS_WIDGET (widget));
g_object_set_data (G_OBJECT (widget), "IDE_CONTEXT_HANDLER", handler);
/* Ensure we have our quarks for quick key lookup */
if G_UNLIKELY (quark_handler == 0)
quark_handler = g_quark_from_static_string ("IDE_CONTEXT_HANDLER");
if G_UNLIKELY (quark_where_context_was == 0)
quark_where_context_was = g_quark_from_static_string ("IDE_CONTEXT");
g_object_set_qdata (G_OBJECT (widget), quark_handler, handler);
g_signal_connect (widget,
G_CALLBACK (ide_widget_hierarchy_changed),
if ((toplevel = gtk_widget_get_toplevel (widget)))
toplevel = gtk_widget_get_toplevel (widget);
if (GTK_IS_WINDOW (toplevel))
ide_widget_hierarchy_changed (widget, NULL, NULL);
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment