mirror of https://github.com/GNOME/gimp.git
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.
This commit is contained in:
parent
577e01d48a
commit
3ced1e18f4
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue