[gtk+/xi2: 363/1239] Implement FocusIn/Out on top of XI2.
- From: Carlos Garnacho <carlosg src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gtk+/xi2: 363/1239] Implement FocusIn/Out on top of XI2.
- Date: Tue, 29 Sep 2009 10:46:59 +0000 (UTC)
commit 8e3bdb011101a136f0411af6c3180e76105df4ea
Author: Carlos Garnacho <carlosg gnome org>
Date: Sat Jun 20 13:54:41 2009 +0200
Implement FocusIn/Out on top of XI2.
gdk/x11/gdkdevicemanager-xi2.c | 92 ++++++++++++++++++++++++++++++++++++++++
1 files changed, 92 insertions(+), 0 deletions(-)
---
diff --git a/gdk/x11/gdkdevicemanager-xi2.c b/gdk/x11/gdkdevicemanager-xi2.c
index f003fc9..c8942d3 100644
--- a/gdk/x11/gdkdevicemanager-xi2.c
+++ b/gdk/x11/gdkdevicemanager-xi2.c
@@ -24,6 +24,8 @@
#include "gdkx.h"
#define BIT_IS_ON(ptr, bit) (((unsigned char *) (ptr))[(bit)>>3] & (1 << ((bit) & 7)))
+#define HAS_FOCUS(toplevel) ((toplevel)->has_focus || (toplevel)->has_pointer_focus)
+
static void gdk_device_manager_xi2_constructed (GObject *object);
static void gdk_device_manager_xi2_finalize (GObject *object);
@@ -540,6 +542,84 @@ translate_keyboard_string (GdkEventKey *event)
}
}
+static void
+generate_focus_event (GdkWindow *window,
+ gboolean in)
+{
+ GdkEvent event;
+
+ event.type = GDK_FOCUS_CHANGE;
+ event.focus_change.window = window;
+ event.focus_change.send_event = FALSE;
+ event.focus_change.in = in;
+
+ gdk_event_put (&event);
+}
+
+static void
+handle_focus_change (GdkWindow *window,
+ gint detail,
+ gint mode,
+ gboolean in)
+{
+ GdkToplevelX11 *toplevel;
+ gboolean had_focus;
+
+ toplevel = _gdk_x11_window_get_toplevel (window);
+
+ if (!toplevel)
+ return;
+
+ had_focus = HAS_FOCUS (toplevel);
+
+ switch (detail)
+ {
+ case NotifyAncestor:
+ case NotifyVirtual:
+ /* When the focus moves from an ancestor of the window to
+ * the window or a descendent of the window, *and* the
+ * pointer is inside the window, then we were previously
+ * receiving keystroke events in the has_pointer_focus
+ * case and are now receiving them in the
+ * has_focus_window case.
+ */
+ if (toplevel->has_pointer &&
+ mode != NotifyGrab &&
+ mode != NotifyUngrab)
+ toplevel->has_pointer_focus = (in) ? FALSE : TRUE;
+
+ /* fall through */
+ case NotifyNonlinear:
+ case NotifyNonlinearVirtual:
+ if (mode != NotifyGrab &&
+ mode != NotifyUngrab)
+ toplevel->has_focus_window = (in) ? TRUE : FALSE;
+ /* We pretend that the focus moves to the grab
+ * window, so we pay attention to NotifyGrab
+ * NotifyUngrab, and ignore NotifyWhileGrabbed
+ */
+ if (mode != NotifyWhileGrabbed)
+ toplevel->has_focus = (in) ? TRUE : FALSE;
+ break;
+ case NotifyPointer:
+ /* The X server sends NotifyPointer/NotifyGrab,
+ * but the pointer focus is ignored while a
+ * grab is in effect
+ */
+ if (mode != NotifyGrab &&
+ mode != NotifyUngrab)
+ toplevel->has_pointer_focus = (in) ? TRUE :FALSE;
+ break;
+ case NotifyInferior:
+ case NotifyPointerRoot:
+ case NotifyDetailNone:
+ break;
+ }
+
+ if (HAS_FOCUS (toplevel) != had_focus)
+ generate_focus_event (window, (in) ? TRUE : FALSE);
+}
+
static gboolean
gdk_device_manager_xi2_translate_event (GdkEventTranslator *translator,
GdkDisplay *display,
@@ -721,6 +801,18 @@ gdk_device_manager_xi2_translate_event (GdkEventTranslator *translator,
event->crossing.state = translate_state (xev->mods, xev->buttons);
}
break;
+ case XI_FocusIn:
+ case XI_FocusOut:
+ {
+ XIEnterEvent *xev = (XIEnterEvent *) ev;
+ GdkWindow *win;
+
+ win = gdk_window_lookup_for_display (display, xev->event);
+ handle_focus_change (win, xev->detail, xev->mode,
+ (ev->evtype == XI_FocusIn) ? TRUE : FALSE);
+
+ return_val = FALSE;
+ }
default:
return_val = FALSE;
break;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]