[gnome-builder] util: ensure IdeWidgetContextHandler is emitted only once per change
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] util: ensure IdeWidgetContextHandler is emitted only once per change
- Date: Tue, 9 Jan 2018 23:42:17 +0000 (UTC)
commit 373b7a305b354be07bebc6737e6c32a4919b1c1b
Author: Christian Hergert <chergert redhat com>
Date: Tue Jan 9 15:39:40 2018 -0800
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
API.
src/libide/util/ide-gtk.c | 47 +++++++++++++++++++++++++++++++++++++-------
1 files changed, 39 insertions(+), 8 deletions(-)
---
diff --git a/src/libide/util/ide-gtk.c b/src/libide/util/ide-gtk.c
index f004cb6..0f0c349 100644
--- a/src/libide/util/ide-gtk.c
+++ b/src/libide/util/ide-gtk.c
@@ -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)
return;
- g_object_get (toplevel,
- "context", &context,
- NULL);
+ context = ide_widget_get_context (toplevel);
+
+ if (context == old_context)
+ return;
+
+ 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,
"notify::context",
@@ -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,
"hierarchy-changed",
G_CALLBACK (ide_widget_hierarchy_changed),
NULL);
- 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);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]