summaryrefslogtreecommitdiff
path: root/gdk
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2009-12-08 12:19:00 +0100
committerAlexander Larsson <alexl@redhat.com>2009-12-08 12:22:59 +0100
commit159214173d2ec626dd0390a5fd0e5beaa6404f6e (patch)
treec23030c76d4c58e3118345044c52c025d25a5c67 /gdk
parentae2a33be2f6dd83bc8fb12fe42f6f2a094c72570 (diff)
downloadgtk+-159214173d2ec626dd0390a5fd0e5beaa6404f6e.tar.gz
Handle input extension events when making a window native
It may happen when turning a client side window into a native window that the window, or some of its children with the same native parent have extension events enabled, and thus have an input window enabled for the native parent which needs to change as the window is made native. We fix this by temporarily disabling extension events on all the affected windows while we create the native window, and then reenable them afterwards. This fixes: https://bugzilla.redhat.com/show_bug.cgi?id=544624
Diffstat (limited to 'gdk')
-rw-r--r--gdk/gdkwindow.c71
1 files changed, 71 insertions, 0 deletions
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index f05fdb2b32..b8055e9ee0 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -1731,6 +1731,67 @@ gdk_window_reparent (GdkWindow *window,
_gdk_synthesize_crossing_events_for_geometry_change (window);
}
+static gboolean
+temporary_disable_extension_events (GdkWindowObject *window)
+{
+ GdkWindowObject *child;
+ GList *l;
+ gboolean res;
+
+ if (window->extension_events != 0)
+ {
+ g_object_set_data (G_OBJECT (window),
+ "gdk-window-extension-events",
+ GINT_TO_POINTER (window->extension_events));
+ gdk_input_set_extension_events ((GdkWindow *)window, 0,
+ GDK_EXTENSION_EVENTS_NONE);
+ }
+ else
+ res = FALSE;
+
+ for (l = window->children; l != NULL; l = l->next)
+ {
+ child = l->data;
+
+ if (window->impl_window == child->impl_window)
+ res |= temporary_disable_extension_events (window);
+ }
+
+ return res;
+}
+
+static void
+reenable_extension_events (GdkWindowObject *window)
+{
+ GdkWindowObject *child;
+ GList *l;
+ int mask;
+
+ mask = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window),
+ "gdk-window-extension-events"));
+
+ if (mask != 0)
+ {
+ /* We don't have the mode here, so we pass in cursor.
+ This works with the current code since mode is not
+ stored except as part of the mask, and cursor doesn't
+ change the mask. */
+ gdk_input_set_extension_events ((GdkWindow *)window, mask,
+ GDK_EXTENSION_EVENTS_CURSOR);
+ g_object_set_data (G_OBJECT (window),
+ "gdk-window-extension-events",
+ NULL);
+ }
+
+ for (l = window->children; l != NULL; l = l->next)
+ {
+ child = l->data;
+
+ if (window->impl_window == child->impl_window)
+ reenable_extension_events (window);
+ }
+}
+
/**
* gdk_window_ensure_native:
* @window: a #GdkWindow
@@ -1758,6 +1819,7 @@ gdk_window_ensure_native (GdkWindow *window)
GdkWindowObject *above;
GList listhead;
GdkWindowImplIface *impl_iface;
+ gboolean disabled_extension_events;
g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
@@ -1778,6 +1840,12 @@ gdk_window_ensure_native (GdkWindow *window)
/* Need to create a native window */
+ /* First we disable any extension events on the window or its
+ descendants to handle the native input window moving */
+ disabled_extension_events = FALSE;
+ if (impl_window->input_window)
+ disabled_extension_events = temporary_disable_extension_events (private);
+
screen = gdk_drawable_get_screen (window);
visual = gdk_drawable_get_visual (window);
@@ -1831,6 +1899,9 @@ gdk_window_ensure_native (GdkWindow *window)
if (gdk_window_is_viewable (window))
impl_iface->show (window, FALSE);
+ if (disabled_extension_events)
+ temporary_enable_extension_events (private);
+
return TRUE;
}