]> Pileus Git - ~andy/gtk/commitdiff
Avoid a segfault. (#309054)
authorMatthias Clasen <mclasen@redhat.com>
Mon, 27 Jun 2005 18:37:41 +0000 (18:37 +0000)
committerMatthias Clasen <matthiasc@src.gnome.org>
Mon, 27 Jun 2005 18:37:41 +0000 (18:37 +0000)
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.

ChangeLog
ChangeLog.pre-2-10
ChangeLog.pre-2-8
gdk/x11/gdkdisplay-x11.c
gdk/x11/gdkdisplay-x11.h
gdk/x11/gdkmain-x11.c
modules/input/gtkimcontextxim.c

index 159f002e03d6639f32ca72e262cddcd2d1e952fd..c1352b7385e3723a72648870e2cfaf5bc5b97578 100644 (file)
--- 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)
index 159f002e03d6639f32ca72e262cddcd2d1e952fd..c1352b7385e3723a72648870e2cfaf5bc5b97578 100644 (file)
@@ -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)
index 159f002e03d6639f32ca72e262cddcd2d1e952fd..c1352b7385e3723a72648870e2cfaf5bc5b97578 100644 (file)
@@ -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)
index b73f0ea7e11617e5d734e223eefcf2f54546b661..66cdc828004c7a0648c3dd2dae90f0753faded41 100644 (file)
@@ -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;
 }
 
 /**
index 198bf6a72721f7ad729ee541e19b3bdbaba286b6..3e69fa5644f600e3ac460a62fb7721abe0023b82 100644 (file)
@@ -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;
index 3d60d3294a7d08419b55a8faf4a09a4fb625f2d2..366f709fe78eecef28e0b9ff360b40bae7b4903e 100644 (file)
@@ -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;
index 86c972d238d4fc40bb0eda2ebb96a49d1f1a1ef2..c210a2c52ea957bda8389a274814d2382ff6973c 100644 (file)
@@ -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);