diff --git a/ChangeLog b/ChangeLog index 159f002e03..c1352b7385 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,18 @@ 2005-06-27 Matthias Clasen + * 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 + * 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 + * 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; + 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); + 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); + 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);