summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2005-06-27 18:37:41 +0000
committerMatthias Clasen <matthiasc@src.gnome.org>2005-06-27 18:37:41 +0000
commitc719b4bf3d66b117003e4703eea5e15cfac8ebe5 (patch)
tree442577d6e5e3bbbb7070682fa6872ba63dceafe3
parentddd27f21a68f8f941adfd1f7781d2a882936e768 (diff)
downloadgtk+-c719b4bf3d66b117003e4703eea5e15cfac8ebe5.tar.gz
Avoid a segfault. (#309054)
2005-06-27 Matthias Clasen <mclasen@redhat.com> * modules/input/gtkimcontextxim.c (gtk_im_context_xim_finalize): Avoid a segfault. (#309054) * gdk/x11/gdkdisplay-x11.h (struct _GdkDisplayX11): Add fields for grab timestamps. * gdk/x11/gdkmain-x11.c (gdk_pointer_grab, gdk_keyboard_grab): Store grab timestamps when grabbing. * gdk/x11/gdkdisplay-x11.c (gdk_display_keyboard_ungrab) (gdk_display_pointer_ungrab): Don't unset the grab_window if the timestamps indicate that the ungrab will fails.
-rw-r--r--ChangeLog13
-rw-r--r--ChangeLog.pre-2-1013
-rw-r--r--ChangeLog.pre-2-813
-rw-r--r--gdk/x11/gdkdisplay-x11.c23
-rw-r--r--gdk/x11/gdkdisplay-x11.h2
-rw-r--r--gdk/x11/gdkmain-x11.c16
-rw-r--r--modules/input/gtkimcontextxim.c34
7 files changed, 92 insertions, 22 deletions
diff --git a/ChangeLog b/ChangeLog
index 159f002e03..c1352b7385 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,18 @@
2005-06-27 Matthias Clasen <mclasen@redhat.com>
+ * modules/input/gtkimcontextxim.c (gtk_im_context_xim_finalize):
+ Avoid a segfault. (#309054)
+
+ * gdk/x11/gdkdisplay-x11.h (struct _GdkDisplayX11): Add
+ fields for grab timestamps.
+
+ * gdk/x11/gdkmain-x11.c (gdk_pointer_grab, gdk_keyboard_grab):
+ Store grab timestamps when grabbing.
+
+ * gdk/x11/gdkdisplay-x11.c (gdk_display_keyboard_ungrab)
+ (gdk_display_pointer_ungrab): Don't unset the grab_window
+ if the timestamps indicate that the ungrab will fails.
+
* gtk/gtkmenu.c (gtk_menu_grab_notify): Cancel menus when
they are grab-shadowed by something thats not a
submenu. (#145416, Euan MacGregor)
diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10
index 159f002e03..c1352b7385 100644
--- a/ChangeLog.pre-2-10
+++ b/ChangeLog.pre-2-10
@@ -1,5 +1,18 @@
2005-06-27 Matthias Clasen <mclasen@redhat.com>
+ * modules/input/gtkimcontextxim.c (gtk_im_context_xim_finalize):
+ Avoid a segfault. (#309054)
+
+ * gdk/x11/gdkdisplay-x11.h (struct _GdkDisplayX11): Add
+ fields for grab timestamps.
+
+ * gdk/x11/gdkmain-x11.c (gdk_pointer_grab, gdk_keyboard_grab):
+ Store grab timestamps when grabbing.
+
+ * gdk/x11/gdkdisplay-x11.c (gdk_display_keyboard_ungrab)
+ (gdk_display_pointer_ungrab): Don't unset the grab_window
+ if the timestamps indicate that the ungrab will fails.
+
* gtk/gtkmenu.c (gtk_menu_grab_notify): Cancel menus when
they are grab-shadowed by something thats not a
submenu. (#145416, Euan MacGregor)
diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8
index 159f002e03..c1352b7385 100644
--- a/ChangeLog.pre-2-8
+++ b/ChangeLog.pre-2-8
@@ -1,5 +1,18 @@
2005-06-27 Matthias Clasen <mclasen@redhat.com>
+ * modules/input/gtkimcontextxim.c (gtk_im_context_xim_finalize):
+ Avoid a segfault. (#309054)
+
+ * gdk/x11/gdkdisplay-x11.h (struct _GdkDisplayX11): Add
+ fields for grab timestamps.
+
+ * gdk/x11/gdkmain-x11.c (gdk_pointer_grab, gdk_keyboard_grab):
+ Store grab timestamps when grabbing.
+
+ * gdk/x11/gdkdisplay-x11.c (gdk_display_keyboard_ungrab)
+ (gdk_display_pointer_ungrab): Don't unset the grab_window
+ if the timestamps indicate that the ungrab will fails.
+
* gtk/gtkmenu.c (gtk_menu_grab_notify): Cancel menus when
they are grab-shadowed by something thats not a
submenu. (#145416, Euan MacGregor)
diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c
index b73f0ea7e1..66cdc82800 100644
--- a/gdk/x11/gdkdisplay-x11.c
+++ b/gdk/x11/gdkdisplay-x11.c
@@ -488,6 +488,11 @@ _gdk_x11_display_is_root_window (GdkDisplay *display,
return FALSE;
}
+#define XSERVER_TIME_IS_LATER(time1, time2) \
+ ( (( time1 > time2 ) && ( time1 - time2 < ((guint32)-1)/2 )) || \
+ (( time1 < time2 ) && ( time2 - time1 > ((guint32)-1)/2 )) \
+ )
+
/**
* gdk_display_pointer_ungrab:
* @display: a #GdkDisplay.
@@ -502,16 +507,21 @@ gdk_display_pointer_ungrab (GdkDisplay *display,
guint32 time)
{
Display *xdisplay;
-
+ GdkDisplayX11 *display_x11;
+
g_return_if_fail (GDK_IS_DISPLAY (display));
+ display_x11 = GDK_DISPLAY_X11 (display);
xdisplay = GDK_DISPLAY_XDISPLAY (display);
_gdk_input_ungrab_pointer (display, time);
XUngrabPointer (xdisplay, time);
XFlush (xdisplay);
-
- GDK_DISPLAY_X11 (display)->pointer_xgrab_window = NULL;
+
+ if (time == GDK_CURRENT_TIME ||
+ display_x11->pointer_xgrab_time == GDK_CURRENT_TIME ||
+ !XSERVER_TIME_IS_LATER (display_x11->pointer_xgrab_time, time))
+ display_x11->pointer_xgrab_window = NULL;
}
/**
@@ -546,15 +556,20 @@ gdk_display_keyboard_ungrab (GdkDisplay *display,
guint32 time)
{
Display *xdisplay;
+ GdkDisplayX11 *display_x11;
g_return_if_fail (GDK_IS_DISPLAY (display));
+ display_x11 = GDK_DISPLAY_X11 (display);
xdisplay = GDK_DISPLAY_XDISPLAY (display);
XUngrabKeyboard (xdisplay, time);
XFlush (xdisplay);
- GDK_DISPLAY_X11 (display)->keyboard_xgrab_window = NULL;
+ if (time == GDK_CURRENT_TIME ||
+ display_x11->keyboard_xgrab_time == GDK_CURRENT_TIME ||
+ !XSERVER_TIME_IS_LATER (display_x11->keyboard_xgrab_time, time))
+ display_x11->keyboard_xgrab_window = NULL;
}
/**
diff --git a/gdk/x11/gdkdisplay-x11.h b/gdk/x11/gdkdisplay-x11.h
index 198bf6a727..3e69fa5644 100644
--- a/gdk/x11/gdkdisplay-x11.h
+++ b/gdk/x11/gdkdisplay-x11.h
@@ -88,10 +88,12 @@ struct _GdkDisplayX11
GdkWindowObject *pointer_xgrab_window;
gulong pointer_xgrab_serial;
gboolean pointer_xgrab_owner_events;
+ guint32 pointer_xgrab_time;
GdkWindowObject *keyboard_xgrab_window;
gulong keyboard_xgrab_serial;
gboolean keyboard_xgrab_owner_events;
+ guint32 keyboard_xgrab_time;
/* drag and drop information */
GdkDragContext *current_dest_drag;
diff --git a/gdk/x11/gdkmain-x11.c b/gdk/x11/gdkmain-x11.c
index 3d60d3294a..366f709fe7 100644
--- a/gdk/x11/gdkmain-x11.c
+++ b/gdk/x11/gdkmain-x11.c
@@ -251,17 +251,19 @@ gdk_pointer_grab (GdkWindow * window,
if (return_val == GrabSuccess)
{
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window));
-#if 0
if (display_x11->pointer_xgrab_window != NULL)
{
+ g_print ("overgrab pointer\n");
+#if 0
generate_grab_broken_event (GDK_WINDOW (display_x11->pointer_xgrab_window),
FALSE);
- }
#endif
+ }
display_x11->pointer_xgrab_window = (GdkWindowObject *)window;
display_x11->pointer_xgrab_serial = serial;
display_x11->pointer_xgrab_owner_events = owner_events;
+ display_x11->pointer_xgrab_time = time;
}
return gdk_x11_convert_grab_status (return_val);
@@ -356,16 +358,18 @@ gdk_keyboard_grab (GdkWindow * window,
if (return_val == GrabSuccess)
{
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (gdk_drawable_get_display (window));
-#if 0
if (display_x11->keyboard_xgrab_window != NULL)
{
+ g_print ("overgrab keyboard\n");
+#if 0
generate_grab_broken_event (GDK_WINDOW (display_x11->keyboard_xgrab_window),
TRUE);
- }
#endif
+ }
display_x11->keyboard_xgrab_window = (GdkWindowObject *)window;
display_x11->keyboard_xgrab_serial = serial;
display_x11->keyboard_xgrab_owner_events = owner_events;
+ display_x11->keyboard_xgrab_time = time;
}
return gdk_x11_convert_grab_status (return_val);
@@ -435,6 +439,7 @@ _gdk_xgrab_check_unmap (GdkWindow *window,
if (tmp)
{
+ g_print ("pointer grab broken from check unmap\n");
generate_grab_broken_event (GDK_WINDOW (display_x11->pointer_xgrab_window),
FALSE);
display_x11->pointer_xgrab_window = NULL;
@@ -453,6 +458,7 @@ _gdk_xgrab_check_unmap (GdkWindow *window,
if (tmp)
{
+ g_print ("keyboard grab broken from check unmap\n");
generate_grab_broken_event (GDK_WINDOW (display_x11->keyboard_xgrab_window),
TRUE);
display_x11->keyboard_xgrab_window = NULL;
@@ -474,6 +480,7 @@ _gdk_xgrab_check_destroy (GdkWindow *window)
if ((GdkWindowObject *)window == display_x11->pointer_xgrab_window)
{
+ g_print ("pointer grab broken from check destroy\n");
generate_grab_broken_event (GDK_WINDOW (display_x11->pointer_xgrab_window),
FALSE);
display_x11->pointer_xgrab_window = NULL;
@@ -481,6 +488,7 @@ _gdk_xgrab_check_destroy (GdkWindow *window)
if ((GdkWindowObject *)window == display_x11->keyboard_xgrab_window)
{
+ g_print ("keyboard grab broken from check destroy\n");
generate_grab_broken_event (GDK_WINDOW (display_x11->keyboard_xgrab_window),
TRUE);
display_x11->keyboard_xgrab_window = NULL;
diff --git a/modules/input/gtkimcontextxim.c b/modules/input/gtkimcontextxim.c
index 86c972d238..c210a2c52e 100644
--- a/modules/input/gtkimcontextxim.c
+++ b/modules/input/gtkimcontextxim.c
@@ -567,20 +567,26 @@ gtk_im_context_xim_finalize (GObject *obj)
if (context_xim->im_info)
{
- GdkDisplay *display;
- XIMCallback im_destroy_callback;
-
- display = gdk_screen_get_display (context_xim->im_info->screen);
- XUnregisterIMInstantiateCallback (GDK_DISPLAY_XDISPLAY (display),
- NULL, NULL, NULL,
- xim_instantiate_callback,
- (XPointer)context_xim->im_info);
-
- im_destroy_callback.client_data = NULL;
- im_destroy_callback.callback = NULL;
- XSetIMValues (context_xim->im_info->im,
- XNDestroyCallback, &im_destroy_callback,
- NULL);
+ if (context_xim->im_info->reconnecting)
+ {
+ GdkDisplay *display;
+
+ display = gdk_screen_get_display (context_xim->im_info->screen);
+ XUnregisterIMInstantiateCallback (GDK_DISPLAY_XDISPLAY (display),
+ NULL, NULL, NULL,
+ xim_instantiate_callback,
+ (XPointer)context_xim->im_info);
+ }
+ else
+ {
+ XIMCallback im_destroy_callback;
+
+ im_destroy_callback.client_data = NULL;
+ im_destroy_callback.callback = NULL;
+ XSetIMValues (context_xim->im_info->im,
+ XNDestroyCallback, &im_destroy_callback,
+ NULL);
+ }
}
set_ic_client_window (context_xim, NULL);