From e26bf9dcefcd0c0536c18d80432f6df304e08ed4 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Wed, 8 Jun 2011 23:01:02 +0200 Subject: [PATCH] display: get crossing/focus events details via helper functions --- src/core/display.c | 51 +++++++++++++++++----------- src/core/input-events.c | 74 +++++++++++++++++++++++++++++++++++++++++ src/core/input-events.h | 8 +++++ 3 files changed, 113 insertions(+), 20 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index 36d396c34..a34daa1e1 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1611,14 +1611,20 @@ event_callback (XEvent *event, event->xany.serial); } } - else if (event->type == LeaveNotify && - event->xcrossing.mode == NotifyUngrab && - modified == display->ungrab_should_not_cause_focus_window) + else if (meta_input_event_is_type (display, event, LeaveNotify)) { - add_ignored_serial (display, event->xany.serial); - meta_topic (META_DEBUG_FOCUS, - "Adding LeaveNotify serial %lu to ignored focus serials\n", - event->xany.serial); + guint mode; + + meta_input_event_get_crossing_details (display, event, &mode, NULL); + + if (mode == NotifyUngrab && + modified == display->ungrab_should_not_cause_focus_window) + { + add_ignored_serial (display, event->xany.serial); + meta_topic (META_DEBUG_FOCUS, + "Adding LeaveNotify serial %lu to ignored focus serials\n", + event->xany.serial); + } } if (modified != None) @@ -1721,8 +1727,8 @@ event_callback (XEvent *event, { Window xwindow = meta_input_event_get_window (display, event); Time evtime = meta_input_event_get_time (display, event); + guint n_button, state, mode, detail; gdouble ev_root_x, ev_root_y; - guint n_button, state; if (window && !window->override_redirect && ((evtype == KeyPress) || (evtype == ButtonPress))) @@ -2004,13 +2010,14 @@ event_callback (XEvent *event, evtime); } + meta_input_event_get_crossing_details (display, event, &mode, &detail); + /* Check if we've entered a window; do this even if window->has_focus to * avoid races. */ if (window && !serial_is_ignored (display, event->xany.serial) && - event->xcrossing.mode != NotifyGrab && - event->xcrossing.mode != NotifyUngrab && - event->xcrossing.detail != NotifyInferior && + mode != NotifyGrab && mode != NotifyUngrab && + detail != NotifyInferior && meta_display_focus_sentinel_clear (display)) { switch (meta_prefs_get_focus_mode ()) @@ -2083,15 +2090,19 @@ event_callback (XEvent *event, meta_window_handle_mouse_grab_op_event (window, event); else if (window != NULL) { + meta_input_event_get_crossing_details (display, event, + &mode, &detail); + if (window->type == META_WINDOW_DOCK && - event->xcrossing.mode != NotifyGrab && - event->xcrossing.mode != NotifyUngrab && + mode != NotifyGrab && mode != NotifyUngrab && !window->has_focus) meta_window_lower (window); } break; case FocusIn: case FocusOut: + meta_input_event_get_crossing_details (display, event, + &mode, &detail); if (window) { meta_window_notify_focus (window, event); @@ -2105,8 +2116,8 @@ event_callback (XEvent *event, evtype == FocusOut ? "out" : "???", xwindow, - meta_event_mode_to_string (event->xfocus.mode), - meta_event_detail_to_string (event->xfocus.detail)); + meta_event_mode_to_string (mode), + meta_event_detail_to_string (detail)); } else { @@ -2123,11 +2134,11 @@ event_callback (XEvent *event, evtype == FocusOut ? "out" : "???", xwindow, - meta_event_mode_to_string (event->xfocus.mode), - meta_event_detail_to_string (event->xfocus.detail)); + meta_event_mode_to_string (mode), + meta_event_detail_to_string (detail)); if (evtype == FocusIn && - event->xfocus.detail == NotifyDetailNone) + detail == NotifyDetailNone) { meta_topic (META_DEBUG_FOCUS, "Focus got set to None, probably due to " @@ -2138,8 +2149,8 @@ event_callback (XEvent *event, meta_display_get_current_time_roundtrip (display)); } else if (evtype == FocusIn && - event->xfocus.mode == NotifyNormal && - event->xfocus.detail == NotifyInferior) + mode == NotifyNormal && + detail == NotifyInferior) { meta_topic (META_DEBUG_FOCUS, "Focus got set to root window, probably due to " diff --git a/src/core/input-events.c b/src/core/input-events.c index e17987165..b21a30453 100644 --- a/src/core/input-events.c +++ b/src/core/input-events.c @@ -122,6 +122,18 @@ meta_input_event_get_type (MetaDisplay *display, return FALSE; } +gboolean +meta_input_event_is_type (MetaDisplay *display, + XEvent *ev, + guint ev_type) +{ + guint type; + + if (!meta_input_event_get_type (display, ev, &type)) + return FALSE; + + return (type == ev_type); +} Window meta_input_event_get_window (MetaDisplay *display, @@ -540,3 +552,65 @@ meta_input_event_get_button (MetaDisplay *display, return FALSE; } + +/* NB: Also works for focus in/out events */ +gboolean +meta_input_event_get_crossing_details (MetaDisplay *display, + XEvent *ev, + guint *mode_out, + guint *detail_out) +{ + gboolean retval = TRUE; + guint mode, detail; + +#ifdef HAVE_XINPUT2 + if (ev->type == GenericEvent && + ev->xcookie.extension == display->xinput2_opcode) + { + XIEvent *xev; + + g_assert (display->have_xinput2 == TRUE); + + xev = (XIEvent *) ev->xcookie.data; + + if (xev->evtype == XI_Enter || + xev->evtype == XI_Leave || + xev->evtype == XI_FocusIn || + xev->evtype == XI_FocusOut) + { + mode = ((XIEnterEvent *) xev)->mode; + detail = ((XIEnterEvent *) xev)->detail; + } + else + retval = FALSE; + } + else +#endif /* HAVE_XINPUT2 */ + { + if (ev->type == EnterNotify || + ev->type == LeaveNotify) + { + mode = ev->xcrossing.mode; + detail = ev->xcrossing.detail; + } + else if (ev->type == FocusIn || + ev->type == FocusOut) + { + mode = ev->xfocus.mode; + detail = ev->xfocus.detail; + } + else + retval = FALSE; + } + + if (retval) + { + if (mode_out) + *mode_out = mode; + + if (detail_out) + *detail_out = detail; + } + + return retval; +} diff --git a/src/core/input-events.h b/src/core/input-events.h index 9cc39ead2..46eba8089 100644 --- a/src/core/input-events.h +++ b/src/core/input-events.h @@ -38,6 +38,9 @@ gboolean meta_input_event_get_type (MetaDisplay *display, XEvent *ev, guint *ev_type); +gboolean meta_input_event_is_type (MetaDisplay *display, + XEvent *ev, + guint ev_type); Window meta_input_event_get_window (MetaDisplay *display, XEvent *ev); @@ -63,5 +66,10 @@ gboolean meta_input_event_get_keycode (MetaDisplay *display, gboolean meta_input_event_get_button (MetaDisplay *display, XEvent *event, guint *button); +gboolean meta_input_event_get_crossing_details (MetaDisplay *display, + XEvent *ev, + guint *mode_out, + guint *detail_out); + #endif /* META_EVENT_H */