]> Pileus Git - ~andy/gtk/blobdiff - gdk/x11/gdkevents-x11.c
Call the filters on the window where the event is received, not on the
[~andy/gtk] / gdk / x11 / gdkevents-x11.c
index c1a44b94b0ce6392e8b41958dae3bcaab96f6649..e32fe2182b29e0ed00d7a3a1e77b9078ba9fc2d2 100644 (file)
@@ -315,6 +315,7 @@ gdk_event_apply_filters (XEvent *xevent,
  *
  * Adds a filter to be called when X ClientMessage events are received.
  *
+ * Since: 2.2
  **/ 
 void 
 gdk_display_add_client_message_filter (GdkDisplay   *display,
@@ -576,6 +577,17 @@ translate_key_event (GdkDisplay *display,
       if (event->key.string)
        event->key.length = bytes_written;
     }
+  else if (event->key.keyval == GDK_Escape)
+    {
+      event->key.length = 1;
+      event->key.string = g_strdup ("\033");
+    }
+  else if (event->key.keyval == GDK_Return ||
+         event->key.keyval == GDK_KP_Enter)
+    {
+      event->key.length = 1;
+      event->key.string = g_strdup ("\r");
+    }
 
   if (!event->key.string)
     {
@@ -647,6 +659,26 @@ get_real_window (XEvent *event)
     }
 }
 
+#ifdef G_ENABLE_DEBUG
+static const char notify_modes[][18] = {
+  "NotifyNormal",
+  "NotifyGrab",
+  "NotifyUngrab",
+  "NotifyWhileGrabbed"
+};
+
+static const char notify_details[][22] = {
+  "NotifyAncestor",
+  "NotifyVirtual",
+  "NotifyInferior",
+  "NotifyNonlinear",
+  "NotifyNonlinearVirtual",
+  "NotifyPointer",
+  "NotifyPointerRoot",
+  "NotifyDetailNone"
+};
+#endif
+
 static gboolean
 gdk_event_translate (GdkDisplay *display,
                     GdkEvent   *event,
@@ -656,6 +688,7 @@ gdk_event_translate (GdkDisplay *display,
   
   GdkWindow *window;
   GdkWindowObject *window_private;
+  GdkWindow *filter_window;
   GdkWindowImplX11 *window_impl = NULL;
   gint return_val;
   gint xoffset, yoffset;
@@ -710,6 +743,14 @@ gdk_event_translate (GdkDisplay *display,
   window = gdk_window_lookup_for_display (display, xwindow);
   window_private = (GdkWindowObject *) window;
 
+  /* We always run the filters for the window where the event
+   * is delivered, not the window that it relates to
+   */
+  if (xevent->xany.window == xwindow)
+    filter_window = window;
+  else
+    filter_window = gdk_window_lookup_for_display (display, xevent->xany.window);
+
   if (window)
     {
       screen = GDK_WINDOW_SCREEN (window);
@@ -759,17 +800,26 @@ gdk_event_translate (GdkDisplay *display,
          goto done;
        }
     }
-  else if (window_private)
+  else if (filter_window)
     {
       /* Apply per-window filters */
+      GdkWindowObject *filter_private = (GdkWindowObject *) filter_window;
       GdkFilterReturn result;
-      result = gdk_event_apply_filters (xevent, event,
-                                       window_private->filters);
-      
-      if (result != GDK_FILTER_CONTINUE)
+
+      if (filter_private->filters)
        {
-         return_val = (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE;
-         goto done;
+         g_object_ref (filter_window);
+         
+         result = gdk_event_apply_filters (xevent, event,
+                                           filter_private->filters);
+         
+         g_object_unref (filter_window);
+      
+         if (result != GDK_FILTER_CONTINUE)
+           {
+             return_val = (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE;
+             goto done;
+           }
        }
     }
       
@@ -1022,10 +1072,10 @@ gdk_event_translate (GdkDisplay *display,
       if (window &&
          GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD &&
          xevent->xcrossing.detail != NotifyInferior &&
-         xevent->xcrossing.focus && !window_impl->has_focus)
+         xevent->xcrossing.focus && !window_impl->has_focus_window)
        {
          gboolean had_focus = HAS_FOCUS (window_impl);
-         
+
          window_impl->has_pointer_focus = TRUE;
 
          if (HAS_FOCUS (window_impl) != had_focus)
@@ -1117,12 +1167,12 @@ gdk_event_translate (GdkDisplay *display,
       if (window &&
          GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD &&
          xevent->xcrossing.detail != NotifyInferior &&
-         xevent->xcrossing.focus && !window_impl->has_focus)
+         xevent->xcrossing.focus && !window_impl->has_focus_window)
        {
          gboolean had_focus = HAS_FOCUS (window_impl);
          
          window_impl->has_pointer_focus = FALSE;
-
+         
          if (HAS_FOCUS (window_impl) != had_focus)
            generate_focus_event (window, FALSE);
        }
@@ -1195,7 +1245,10 @@ gdk_event_translate (GdkDisplay *display,
        */
     case FocusIn:
       GDK_NOTE (EVENTS,
-               g_message ("focus in:\t\twindow: %ld", xevent->xfocus.window));
+               g_message ("focus in:\t\twindow: %ld, detail: %s, mode: %s",
+                          xevent->xfocus.window,
+                          notify_details[xevent->xfocus.detail],
+                          notify_modes[xevent->xfocus.mode]));
       
       if (window && GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD)
        {
@@ -1207,6 +1260,7 @@ gdk_event_translate (GdkDisplay *display,
            case NotifyNonlinear:
            case NotifyVirtual:
            case NotifyNonlinearVirtual:
+             window_impl->has_focus_window = TRUE;
              /* We pretend that the focus moves to the grab
               * window, so we pay attention to NotifyGrab
               * NotifyUngrab, and ignore NotifyWhileGrabbed
@@ -1234,8 +1288,11 @@ gdk_event_translate (GdkDisplay *display,
       break;
     case FocusOut:
       GDK_NOTE (EVENTS,
-               g_message ("focus out:\t\twindow: %ld", xevent->xfocus.window));
-
+               g_message ("focus out:\t\twindow: %ld, detail: %s, mode: %s",
+                          xevent->xfocus.window,
+                          notify_details[xevent->xfocus.detail],
+                          notify_modes[xevent->xfocus.mode]));
+      
       if (window && GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD)
        {
          gboolean had_focus = HAS_FOCUS (window_impl);
@@ -1246,6 +1303,7 @@ gdk_event_translate (GdkDisplay *display,
            case NotifyNonlinear:
            case NotifyVirtual:
            case NotifyNonlinearVirtual:
+             window_impl->has_focus_window = FALSE;
              if (xevent->xfocus.mode != NotifyWhileGrabbed)
                window_impl->has_focus = FALSE;
              break;
@@ -1967,17 +2025,19 @@ gdk_event_dispatch (GSource    *source,
 }
 
 /**
- * gdk_event_send_client_message_for_display :
- * @display : the #GdkDisplay for the window where the message is to be sent.
- * @event : the #GdkEvent to send, which should be a #GdkEventClient.
- * @winid : the window to send the X ClientMessage event to.
+ * gdk_event_send_client_message_for_display:
+ * @display: the #GdkDisplay for the window where the message is to be sent.
+ * @event: the #GdkEvent to send, which should be a #GdkEventClient.
+ * @winid: the window to send the X ClientMessage event to.
  *
  * Sends an X ClientMessage event to a given window.
  *
  * This could be used for communicating between different applications,
  * though the amount of data is limited to 20 bytes.
  *
- * Returns : non-zero on success.
+ * Returns: non-zero on success.
+ *
+ * Since: 2.2
  */
 gboolean
 gdk_event_send_client_message_for_display (GdkDisplay     *display,
@@ -2063,8 +2123,8 @@ gdk_event_send_client_message_to_all_recurse (GdkDisplay *display,
 
 /**
  * gdk_screen_broadcast_client_message:
- * @screen : the #GdkScreen where the event will be broadcasted.
- * @event : the #GdkEvent.
+ * @screen: the #GdkScreen where the event will be broadcasted.
+ * @event: the #GdkEvent.
  *
  * Sends an X ClientMessage event to all toplevel windows on @screen.
  *
@@ -2072,6 +2132,8 @@ gdk_event_send_client_message_to_all_recurse (GdkDisplay *display,
  * as described in the Inter-Client Communication Conventions Manual (ICCCM).
  * If no windows are found with the WM_STATE property set, the message is 
  * sent to all children of the root window.
+ *
+ * Since: 2.2
  */
 
 void
@@ -2233,6 +2295,18 @@ fetch_net_wm_check_window (GdkScreen *screen)
   _gdk_x11_screen_window_manager_changed (GDK_SCREEN (screen_x11));
 }
 
+/**
+ * gdk_x11_screen_get_window_manager_name:
+ * @screen: a #GdkScreen 
+ * 
+ * Returns the name of the window manager for @screen. 
+ * 
+ * Return value: the name of the window manager screen @screen, or 
+ * "unknown" if the window manager is unknown. The string is owned by GDK
+ * and should not be freed.
+ *
+ * Since: 2.2
+ **/
 const char*
 gdk_x11_screen_get_window_manager_name (GdkScreen *screen)
 {
@@ -2297,13 +2371,14 @@ struct _NetWmSupportedAtoms
 
 /**
  * gdk_x11_screen_supports_net_wm_hint:
- * @screen : the relevant #GdkScreen.
+ * @screen: the relevant #GdkScreen.
  * @property: a property atom.
  * 
  * This function is specific to the X11 backend of GDK, and indicates
  * whether the window manager supports a certain hint from the
  * Extended Window Manager Hints Specification. You can find this
- * specification on http://www.freedesktop.org.
+ * specification on 
+ * <ulink url="http://www.freedesktop.org">http://www.freedesktop.org</ulink>.
  *
  * When using this function, keep in mind that the window manager
  * can change over time; so you shouldn't use this function in
@@ -2315,6 +2390,8 @@ struct _NetWmSupportedAtoms
  * a window manager change.
  * 
  * Return value: %TRUE if the window manager supports @property
+ *
+ * Since: 2.2
  **/
 gboolean
 gdk_x11_screen_supports_net_wm_hint (GdkScreen *screen,
@@ -2497,8 +2574,10 @@ check_transform (const gchar *xsettings_name,
  * FIXME needs a list of valid settings here, or a link to 
  * more information.
  * 
- * Returns : %TRUE if the setting existed and a value was stored
+ * Returns: %TRUE if the setting existed and a value was stored
  *   in @value, %FALSE otherwise.
+ *
+ * Since: 2.2
  **/
 gboolean
 gdk_screen_get_setting (GdkScreen   *screen,