]> Pileus Git - ~andy/gtk/blobdiff - gdk/x11/gdkevents-x11.c
Merge branch 'master' into client-side-windows
[~andy/gtk] / gdk / x11 / gdkevents-x11.c
index 3e4eb1e36fae69395b7a4a91da2797c2159a0567..8d3141a8ee2b79b0b0c96942d24e7b9be8cb80fb 100644 (file)
@@ -313,7 +313,7 @@ gdk_event_get_graphics_expose (GdkWindow *window)
   GdkEvent *event;
   
   g_return_val_if_fail (window != NULL, NULL);
-  
+
   XIfEvent (GDK_WINDOW_XDISPLAY (window), &xevent, 
            graphics_expose_predicate, (XPointer) window);
   
@@ -867,6 +867,24 @@ set_user_time (GdkWindow *window,
                                   gdk_event_get_time (event));
 }
 
+static gboolean
+is_parent_of (GdkWindow *parent,
+              GdkWindow *child)
+{
+  GdkWindow *w;
+
+  w = child;
+  while (w != NULL)
+    {
+      if (w == parent)
+       return TRUE;
+
+      w = gdk_window_get_parent (w);
+    }
+
+  return FALSE;
+}
+
 static gboolean
 gdk_event_translate (GdkDisplay *display,
                     GdkEvent   *event,
@@ -879,7 +897,6 @@ gdk_event_translate (GdkDisplay *display,
   GdkWindow *filter_window;
   GdkWindowImplX11 *window_impl = NULL;
   gboolean return_val;
-  gint xoffset, yoffset;
   GdkScreen *screen = NULL;
   GdkScreenX11 *screen_x11 = NULL;
   GdkToplevelX11 *toplevel = NULL;
@@ -942,6 +959,24 @@ gdk_event_translate (GdkDisplay *display,
     
   if (window != NULL)
     {
+      /* Apply keyboard grabs to non-native windows */
+      if (/* Is key event */
+         (xevent->type == KeyPress || xevent->type == KeyRelease) &&
+         /* And we have a grab */
+         display->keyboard_grab.window != NULL &&
+         (
+          /* The window is not a descendant of the grabbed window */
+          !is_parent_of ((GdkWindow *)display->keyboard_grab.window, window) ||
+          /* Or owner event is false */
+          !display->keyboard_grab.owner_events
+          )
+         )
+        {
+         /* Report key event against grab window */
+          window = display->keyboard_grab.window;;
+          window_private = (GdkWindowObject *) window;
+        }
+
       window_impl = GDK_WINDOW_IMPL_X11 (window_private->impl);
       
       /* Move key events on focus window to the real toplevel, and
@@ -1041,16 +1076,6 @@ gdk_event_translate (GdkDisplay *display,
 
   return_val = TRUE;
 
-  if (window)
-    {
-      _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
-    }
-  else
-    {
-      xoffset = 0;
-      yoffset = 0;
-    }
-
   switch (xevent->type)
     {
     case KeyPress:
@@ -1129,8 +1154,8 @@ gdk_event_translate (GdkDisplay *display,
 
          event->scroll.window = window;
          event->scroll.time = xevent->xbutton.time;
-         event->scroll.x = xevent->xbutton.x + xoffset;
-         event->scroll.y = xevent->xbutton.y + yoffset;
+         event->scroll.x = xevent->xbutton.x;
+         event->scroll.y = xevent->xbutton.y;
          event->scroll.x_root = (gfloat)xevent->xbutton.x_root;
          event->scroll.y_root = (gfloat)xevent->xbutton.y_root;
          event->scroll.state = (GdkModifierType) xevent->xbutton.state;
@@ -1148,8 +1173,8 @@ gdk_event_translate (GdkDisplay *display,
          event->button.type = GDK_BUTTON_PRESS;
          event->button.window = window;
          event->button.time = xevent->xbutton.time;
-         event->button.x = xevent->xbutton.x + xoffset;
-         event->button.y = xevent->xbutton.y + yoffset;
+         event->button.x = xevent->xbutton.x;
+         event->button.y = xevent->xbutton.y;
          event->button.x_root = (gfloat)xevent->xbutton.x_root;
          event->button.y_root = (gfloat)xevent->xbutton.y_root;
          event->button.axes = NULL;
@@ -1162,14 +1187,11 @@ gdk_event_translate (GdkDisplay *display,
              return_val = FALSE;
              break;
            }
-
-         _gdk_event_button_generate (display, event);
           break;
        }
 
       set_user_time (window, event);
 
-      _gdk_xgrab_check_button_event (window, xevent);
       break;
       
     case ButtonRelease:
@@ -1198,8 +1220,8 @@ gdk_event_translate (GdkDisplay *display,
       event->button.type = GDK_BUTTON_RELEASE;
       event->button.window = window;
       event->button.time = xevent->xbutton.time;
-      event->button.x = xevent->xbutton.x + xoffset;
-      event->button.y = xevent->xbutton.y + yoffset;
+      event->button.x = xevent->xbutton.x;
+      event->button.y = xevent->xbutton.y;
       event->button.x_root = (gfloat)xevent->xbutton.x_root;
       event->button.y_root = (gfloat)xevent->xbutton.y_root;
       event->button.axes = NULL;
@@ -1208,12 +1230,8 @@ gdk_event_translate (GdkDisplay *display,
       event->button.device = display->core_pointer;
 
       if (!set_screen_from_root (display, event, xevent->xbutton.root))
-       {
-         return_val = FALSE;
-         break;
-       }
-
-      _gdk_xgrab_check_button_event (window, xevent);
+       return_val = FALSE;
+      
       break;
       
     case MotionNotify:
@@ -1234,8 +1252,8 @@ gdk_event_translate (GdkDisplay *display,
       event->motion.type = GDK_MOTION_NOTIFY;
       event->motion.window = window;
       event->motion.time = xevent->xmotion.time;
-      event->motion.x = xevent->xmotion.x + xoffset;
-      event->motion.y = xevent->xmotion.y + yoffset;
+      event->motion.x = xevent->xmotion.x;
+      event->motion.y = xevent->xmotion.y;
       event->motion.x_root = (gfloat)xevent->xmotion.x_root;
       event->motion.y_root = (gfloat)xevent->xmotion.y_root;
       event->motion.axes = NULL;
@@ -1304,8 +1322,8 @@ gdk_event_translate (GdkDisplay *display,
        event->crossing.subwindow = NULL;
       
       event->crossing.time = xevent->xcrossing.time;
-      event->crossing.x = xevent->xcrossing.x + xoffset;
-      event->crossing.y = xevent->xcrossing.y + yoffset;
+      event->crossing.x = xevent->xcrossing.x;
+      event->crossing.y = xevent->xcrossing.y;
       event->crossing.x_root = xevent->xcrossing.x_root;
       event->crossing.y_root = xevent->xcrossing.y_root;
       
@@ -1399,8 +1417,8 @@ gdk_event_translate (GdkDisplay *display,
        event->crossing.subwindow = NULL;
       
       event->crossing.time = xevent->xcrossing.time;
-      event->crossing.x = xevent->xcrossing.x + xoffset;
-      event->crossing.y = xevent->xcrossing.y + yoffset;
+      event->crossing.x = xevent->xcrossing.x;
+      event->crossing.y = xevent->xcrossing.y;
       event->crossing.x_root = xevent->xcrossing.x_root;
       event->crossing.y_root = xevent->xcrossing.y_root;
       
@@ -1596,8 +1614,8 @@ gdk_event_translate (GdkDisplay *display,
       {
        GdkRectangle expose_rect;
 
-       expose_rect.x = xevent->xexpose.x + xoffset;
-       expose_rect.y = xevent->xexpose.y + yoffset;
+       expose_rect.x = xevent->xexpose.x;
+       expose_rect.y = xevent->xexpose.y;
        expose_rect.width = xevent->xexpose.width;
        expose_rect.height = xevent->xexpose.height;
 
@@ -1636,8 +1654,8 @@ gdk_event_translate (GdkDisplay *display,
             break;
           }
         
-       expose_rect.x = xevent->xgraphicsexpose.x + xoffset;
-       expose_rect.y = xevent->xgraphicsexpose.y + yoffset;
+       expose_rect.x = xevent->xgraphicsexpose.x;
+       expose_rect.y = xevent->xgraphicsexpose.y;
        expose_rect.width = xevent->xgraphicsexpose.width;
        expose_rect.height = xevent->xgraphicsexpose.height;
            
@@ -1826,9 +1844,9 @@ gdk_event_translate (GdkDisplay *display,
                           : ""));
       if (window && GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT)
         { 
-         window_impl->width = xevent->xconfigure.width;
-         window_impl->height = xevent->xconfigure.height;
-         
+         window_private->width = xevent->xconfigure.width;
+         window_private->height = xevent->xconfigure.height;
+
          _gdk_x11_drawable_update_size (window_private->impl);
          _gdk_x11_screen_size_changed (screen, xevent);
         }
@@ -1847,7 +1865,7 @@ gdk_event_translate (GdkDisplay *display,
        }
 #endif
 
-    if (!window ||
+      if (!window ||
          xevent->xconfigure.event != xevent->xconfigure.window ||
           GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD ||
           GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT)
@@ -1887,9 +1905,10 @@ gdk_event_translate (GdkDisplay *display,
            }
          window_private->x = event->configure.x;
          window_private->y = event->configure.y;
-         window_impl->width = xevent->xconfigure.width;
-         window_impl->height = xevent->xconfigure.height;
+         window_private->width = xevent->xconfigure.width;
+         window_private->height = xevent->xconfigure.height;
          
+         _gdk_window_update_size (window);
          _gdk_x11_drawable_update_size (window_private->impl);
          
          if (window_private->resize_count >= 1)
@@ -1985,7 +2004,10 @@ gdk_event_translate (GdkDisplay *display,
       event->selection.window = window;
       event->selection.selection = gdk_x11_xatom_to_atom_for_display (display, xevent->xselection.selection);
       event->selection.target = gdk_x11_xatom_to_atom_for_display (display, xevent->xselection.target);
-      event->selection.property = gdk_x11_xatom_to_atom_for_display (display, xevent->xselection.property);
+      if (xevent->xselection.property == None)
+        event->selection.property = GDK_NONE;
+      else
+        event->selection.property = gdk_x11_xatom_to_atom_for_display (display, xevent->xselection.property);
       event->selection.time = xevent->xselection.time;
       
       break;
@@ -2107,14 +2129,13 @@ gdk_event_translate (GdkDisplay *display,
       else
 #endif
 #ifdef HAVE_RANDR
-      if (xevent->type - display_x11->xrandr_event_base == RRNotify)
+      if (xevent->type - display_x11->xrandr_event_base == RRScreenChangeNotify ||
+          xevent->type - display_x11->xrandr_event_base == RRNotify)
        {
-           XRRNotifyEvent *notify = (XRRNotifyEvent *)xevent;
-           
-           if (screen)
-               _gdk_x11_screen_process_monitors_change (screen);
+          if (screen)
+            _gdk_x11_screen_size_changed (screen, xevent);
        }
-      else 
+      else
 #endif
 #if defined(HAVE_XCOMPOSITE) && defined (HAVE_XDAMAGE) && defined (HAVE_XFIXES)
       if (display_x11->have_xdamage && window_private && window_private->composited &&
@@ -2178,7 +2199,7 @@ gdk_event_translate (GdkDisplay *display,
   
   if (window)
     g_object_unref (window);
-  
+
   return return_val;
 }
 
@@ -2299,6 +2320,7 @@ _gdk_events_queue (GdkDisplay *display)
       if (gdk_event_translate (display, event, &xevent, FALSE))
        {
          ((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING;
+          _gdk_windowing_got_event (display, node, event, xevent.xany.serial);
        }
       else
        {
@@ -2614,23 +2636,20 @@ fetch_net_wm_check_window (GdkScreen *screen)
   gulong bytes_after;
   guchar *data;
   Window *xwindow;
-  
-  /* This function is very slow on every call if you are not running a
-   * spec-supporting WM. For now not optimized, because it isn't in
-   * any critical code paths, but if you used it somewhere that had to
-   * be fast you want to avoid "GTK is slow with old WMs" complaints.
-   * Probably at that point the function should be changed to query
-   * _NET_SUPPORTING_WM_CHECK only once every 10 seconds or something.
-   */
+  GTimeVal tv;
   
   screen_x11 = GDK_SCREEN_X11 (screen);
   display = screen_x11->display;
 
   g_return_if_fail (GDK_DISPLAY_X11 (display)->trusted_client);
   
-  if (screen_x11->wmspec_check_window != None)
-    return; /* already have it */
-  
+  g_get_current_time (&tv);
+      
+  if (ABS  (tv.tv_sec - screen_x11->last_wmspec_check_time) < 15)
+    return; /* we've checked recently */
+
+  screen_x11->last_wmspec_check_time = tv.tv_sec;
+
   data = NULL;
   XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), screen_x11->xroot_window,
                      gdk_x11_get_xatom_by_name_for_display (display, "_NET_SUPPORTING_WM_CHECK"),
@@ -2646,6 +2665,12 @@ fetch_net_wm_check_window (GdkScreen *screen)
 
   xwindow = (Window *)data;
 
+  if (screen_x11->wmspec_check_window == *xwindow)
+    {
+      XFree (xwindow);
+      return;
+    }
+
   gdk_error_trap_push ();
   
   /* Find out if this WM goes away, so we can reset everything. */
@@ -2744,6 +2769,15 @@ struct _NetWmSupportedAtoms
   gulong n_atoms;
 };
 
+static void
+cleanup_atoms(gpointer data)
+{
+  NetWmSupportedAtoms *supported_atoms = data;
+  if (supported_atoms->atoms)
+      XFree (supported_atoms->atoms);
+  g_free (supported_atoms);
+}
+
 /**
  * gdk_x11_screen_supports_net_wm_hint:
  * @screen: the relevant #GdkScreen.
@@ -2789,7 +2823,7 @@ gdk_x11_screen_supports_net_wm_hint (GdkScreen *screen,
   if (!supported_atoms)
     {
       supported_atoms = g_new0 (NetWmSupportedAtoms, 1);
-      g_object_set_data (G_OBJECT (screen), "gdk-net-wm-supported-atoms", supported_atoms);
+      g_object_set_data_full (G_OBJECT (screen), "gdk-net-wm-supported-atoms", supported_atoms, cleanup_atoms);
     }
 
   fetch_net_wm_check_window (screen);