[gimp] app: fix GimpDeviceManager to not add the same display twice
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: fix GimpDeviceManager to not add the same display twice
- Date: Thu, 10 May 2018 12:24:24 +0000 (UTC)
commit 3ced1e18f44ed8a60f98743204fc94149e200659
Author: Michael Natterer <mitch gimp org>
Date: Thu May 10 14:18:59 2018 +0200
app: fix GimpDeviceManager to not add the same display twice
Displays can be opened multiple times, which caused the device manager
to try to add their devices multiple times (which gets prevented with
warnings), and then remove the devices prematurely when the
multiple-opened display gets closed the first time (which is even
worse).
Add a simple hash that keeps track of how often displays are open, and
only add/remove their devices on first open and last close.
This actually happened with gtk-inspector on the gtk3-port branch, but
there is no reason this can't also happen in stable.
app/widgets/gimpdevicemanager.c | 48 +++++++++++++++++++++++++++++++++-----
app/widgets/gimpdevicemanager.h | 7 ++++-
2 files changed, 46 insertions(+), 9 deletions(-)
---
diff --git a/app/widgets/gimpdevicemanager.c b/app/widgets/gimpdevicemanager.c
index b952bae..4598bae 100644
--- a/app/widgets/gimpdevicemanager.c
+++ b/app/widgets/gimpdevicemanager.c
@@ -44,18 +44,15 @@ enum
};
-typedef struct _GimpDeviceManagerPrivate GimpDeviceManagerPrivate;
struct _GimpDeviceManagerPrivate
{
Gimp *gimp;
+ GHashTable *displays;
GimpDeviceInfo *current_device;
};
-#define GET_PRIVATE(manager) \
- G_TYPE_INSTANCE_GET_PRIVATE (manager, \
- GIMP_TYPE_DEVICE_MANAGER, \
- GimpDeviceManagerPrivate)
+#define GET_PRIVATE(obj) (((GimpDeviceManager *) (obj))->priv)
static void gimp_device_manager_constructed (GObject *object);
@@ -126,6 +123,12 @@ gimp_device_manager_class_init (GimpDeviceManagerClass *klass)
static void
gimp_device_manager_init (GimpDeviceManager *manager)
{
+ manager->priv = G_TYPE_INSTANCE_GET_PRIVATE (manager,
+ GIMP_TYPE_DEVICE_MANAGER,
+ GimpDeviceManagerPrivate);
+
+ manager->priv->displays = g_hash_table_new (g_direct_hash,
+ g_direct_equal);
}
static void
@@ -183,6 +186,10 @@ gimp_device_manager_dispose (GObject *object)
static void
gimp_device_manager_finalize (GObject *object)
{
+ GimpDeviceManagerPrivate *private = GET_PRIVATE (object);
+
+ g_clear_pointer (&private->displays, g_hash_table_unref);
+
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -297,7 +304,19 @@ gimp_device_manager_display_opened (GdkDisplayManager *disp_manager,
GdkDisplay *gdk_display,
GimpDeviceManager *manager)
{
- GList *list;
+ GimpDeviceManagerPrivate *private = GET_PRIVATE (manager);
+ GList *list;
+ gint count;
+
+ count = GPOINTER_TO_INT (g_hash_table_lookup (private->displays,
+ gdk_display));
+
+ g_hash_table_insert (private->displays, gdk_display,
+ GINT_TO_POINTER (count + 1));
+
+ /* don't add the same display twice */
+ if (count > 0)
+ return;
/* create device info structures for present devices */
for (list = gdk_display_list_devices (gdk_display); list; list = list->next)
@@ -317,7 +336,22 @@ gimp_device_manager_display_closed (GdkDisplay *gdk_display,
gboolean is_error,
GimpDeviceManager *manager)
{
- GList *list;
+ GimpDeviceManagerPrivate *private = GET_PRIVATE (manager);
+ GList *list;
+ gint count;
+
+ count = GPOINTER_TO_INT (g_hash_table_lookup (private->displays,
+ gdk_display));
+
+ /* don't remove the same display twice */
+ if (count > 1)
+ {
+ g_hash_table_insert (private->displays, gdk_display,
+ GINT_TO_POINTER (count - 1));
+ return;
+ }
+
+ g_hash_table_remove (private->displays, gdk_display);
for (list = gdk_display_list_devices (gdk_display); list; list = list->next)
{
diff --git a/app/widgets/gimpdevicemanager.h b/app/widgets/gimpdevicemanager.h
index 8bd723a..b07eaa8 100644
--- a/app/widgets/gimpdevicemanager.h
+++ b/app/widgets/gimpdevicemanager.h
@@ -36,11 +36,14 @@ G_BEGIN_DECLS
#define GIMP_DEVICE_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_DEVICE_MANAGER,
GimpDeviceManagerClass))
-typedef struct _GimpDeviceManagerClass GimpDeviceManagerClass;
+typedef struct _GimpDeviceManagerPrivate GimpDeviceManagerPrivate;
+typedef struct _GimpDeviceManagerClass GimpDeviceManagerClass;
struct _GimpDeviceManager
{
- GimpList parent_instance;
+ GimpList parent_instance;
+
+ GimpDeviceManagerPrivate *priv;
};
struct _GimpDeviceManagerClass
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]