From c16fa45bfe3b68bbfe8b4ffc8851d37eb1985f9f Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 24 Oct 2014 15:55:31 -0400 Subject: [PATCH] inspector: Use a separate display connection This helps isolate the inspector from some of the changes that it can trigger. To specify a different display, set GTK_INSPECTOR_DISPLAY to the name of the display to use for the inspector window. If no display is specified, GTK+ will use a separate connection to the default display. --- gtk/inspector/general.c | 2 +- gtk/inspector/inspect-button.c | 39 +++++++++++++++++++++++++--------- gtk/inspector/object-tree.c | 4 ++++ gtk/inspector/visual.c | 4 ++-- gtk/inspector/window.c | 37 +++++++++++++++++++++++++++++++- gtk/inspector/window.h | 1 + 6 files changed, 73 insertions(+), 14 deletions(-) diff --git a/gtk/inspector/general.c b/gtk/inspector/general.c index 57c6e4c8d4..8e30189b36 100644 --- a/gtk/inspector/general.c +++ b/gtk/inspector/general.c @@ -70,7 +70,7 @@ init_version (GtkInspectorGeneral *gen) const gchar *backend; GdkDisplay *display; - display = gtk_widget_get_display (GTK_WIDGET (gen)); + display = gdk_display_get_default (); #ifdef GDK_WINDOWING_X11 if (GDK_IS_X11_DISPLAY (display)) diff --git a/gtk/inspector/inspect-button.c b/gtk/inspector/inspect-button.c index 86c6240f1c..4d9403776f 100644 --- a/gtk/inspector/inspect-button.c +++ b/gtk/inspector/inspect-button.c @@ -29,6 +29,7 @@ #include "gtkstack.h" #include "gtkmain.h" +#include "gtkinvisible.h" typedef struct { @@ -312,21 +313,39 @@ gtk_inspector_on_inspect (GtkWidget *button, GdkDisplay *display; GdkDevice *device; GdkCursor *cursor; + GdkGrabStatus status; - g_signal_connect (button, "event", - G_CALLBACK (property_query_event), iw); + if (!iw->invisible) + { + iw->invisible = gtk_invisible_new_for_screen (gdk_screen_get_default ()); + gtk_widget_add_events (iw->invisible, + GDK_POINTER_MOTION_MASK | + GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK | + GDK_KEY_PRESS_MASK | + GDK_KEY_RELEASE_MASK); + gtk_widget_realize (iw->invisible); + gtk_widget_show (iw->invisible); + } - display = gtk_widget_get_display (button); + display = gdk_display_get_default (); cursor = gdk_cursor_new_for_display (display, GDK_CROSSHAIR); device = gdk_device_manager_get_client_pointer (gdk_display_get_device_manager (display)); - gdk_device_grab (device, - gtk_widget_get_window (GTK_WIDGET (button)), - GDK_OWNERSHIP_NONE, TRUE, - GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK, - cursor, GDK_CURRENT_TIME); + status = gdk_device_grab (device, + gtk_widget_get_window (iw->invisible), + GDK_OWNERSHIP_NONE, TRUE, + GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK, + cursor, GDK_CURRENT_TIME); g_object_unref (cursor); - gtk_grab_add (GTK_WIDGET (button)); + if (status != GDK_GRAB_SUCCESS) + { + g_warning ("grab failed (%d) :-(\n", status); + return; + } + g_signal_connect (iw->invisible, "event", G_CALLBACK (property_query_event), iw); + + gtk_grab_add (GTK_WIDGET (iw->invisible)); gdk_window_lower (gtk_widget_get_window (GTK_WIDGET (iw))); } @@ -419,7 +438,7 @@ gtk_inspector_window_select_widget_under_pointer (GtkInspectorWindow *iw) GdkDevice *device; GtkWidget *widget; - display = gtk_widget_get_display (GTK_WIDGET (iw)); + display = gdk_display_get_default (); dm = gdk_display_get_device_manager (display); device = gdk_device_manager_get_client_pointer (dm); diff --git a/gtk/inspector/object-tree.c b/gtk/inspector/object-tree.c index a88847c43e..aaa3674ed8 100644 --- a/gtk/inspector/object-tree.c +++ b/gtk/inspector/object-tree.c @@ -526,6 +526,7 @@ gtk_inspector_object_tree_scan (GtkInspectorObjectTree *wt, { GtkWidget *inspector_win; GList *toplevels, *l; + GdkScreen *screen; gtk_tree_store_clear (wt->priv->model); g_hash_table_remove_all (wt->priv->iters); @@ -536,12 +537,15 @@ gtk_inspector_object_tree_scan (GtkInspectorObjectTree *wt, if (window) gtk_inspector_object_tree_append_object (wt, G_OBJECT (window), NULL, NULL); + screen = gdk_screen_get_default (); + inspector_win = gtk_widget_get_toplevel (GTK_WIDGET (wt)); toplevels = gtk_window_list_toplevels (); for (l = toplevels; l; l = l->next) { if (GTK_IS_WINDOW (l->data) && gtk_window_get_window_type (l->data) == GTK_WINDOW_TOPLEVEL && + gtk_widget_get_screen (l->data) == screen && l->data != window && l->data != inspector_win) gtk_inspector_object_tree_append_object (wt, G_OBJECT (l->data), NULL, NULL); diff --git a/gtk/inspector/visual.c b/gtk/inspector/visual.c index 9e97501bad..15b881c133 100644 --- a/gtk/inspector/visual.c +++ b/gtk/inspector/visual.c @@ -361,7 +361,7 @@ scale_changed (GtkAdjustment *adjustment, GtkInspectorVisual *vis) gint scale; scale = gtk_adjustment_get_value (adjustment); - display = gtk_widget_get_display (GTK_WIDGET (vis)); + display = gdk_display_get_default (); gdk_x11_display_set_window_scale (display, scale); } #endif @@ -372,7 +372,7 @@ init_scale (GtkInspectorVisual *vis) #if defined (GDK_WINDOWING_X11) && defined (HAVE_CAIRO_SURFACE_SET_DEVICE_SCALE) GdkScreen *screen; - screen = gtk_widget_get_screen (GTK_WIDGET (vis)); + screen = gdk_screen_get_default (); if (GDK_IS_X11_SCREEN (screen)) { gdouble scale; diff --git a/gtk/inspector/window.c b/gtk/inspector/window.c index 0b307fa8ed..f196e97602 100644 --- a/gtk/inspector/window.c +++ b/gtk/inspector/window.c @@ -175,10 +175,45 @@ gtk_inspector_window_class_init (GtkInspectorWindowClass *klass) gtk_widget_class_bind_template_callback (widget_class, close_details); } +static GdkScreen * +get_inspector_screen (void) +{ + static GdkDisplay *display = NULL; + + if (display == NULL) + { + const gchar *name; + + name = g_getenv ("GTK_INSPECTOR_DISPLAY"); + display = gdk_display_open (name); + + if (display) + g_debug ("Using display %s for GtkInspector", name); + else + g_message ("Failed to open display %s", name); + } + + if (!display) + { + display = gdk_display_open (NULL); + if (display) + g_debug ("Using default display for GtkInspector"); + else + g_message ("Failed to separate connection to default display"); + } + + if (!display) + display = gdk_display_get_default (); + + return gdk_display_get_default_screen (display); +} + GtkWidget * gtk_inspector_window_new (void) { - return GTK_WIDGET (g_object_new (GTK_TYPE_INSPECTOR_WINDOW, NULL)); + return GTK_WIDGET (g_object_new (GTK_TYPE_INSPECTOR_WINDOW, + "screen", get_inspector_screen (), + NULL)); } // vim: set et sw=2 ts=2: diff --git a/gtk/inspector/window.h b/gtk/inspector/window.h index ff9fe5847b..b973d84017 100644 --- a/gtk/inspector/window.h +++ b/gtk/inspector/window.h @@ -63,6 +63,7 @@ typedef struct GtkWidget *misc_info; GtkWidget *gestures; + GtkWidget *invisible; GtkWidget *selected_widget; GtkWidget *flash_widget;