display: get crossing/focus events details via helper functions

This commit is contained in:
Carlos Garnacho 2011-06-08 23:01:02 +02:00
parent 748954a15e
commit e26bf9dcef
3 changed files with 113 additions and 20 deletions

View File

@ -1611,8 +1611,13 @@ event_callback (XEvent *event,
event->xany.serial); event->xany.serial);
} }
} }
else if (event->type == LeaveNotify && else if (meta_input_event_is_type (display, event, LeaveNotify))
event->xcrossing.mode == NotifyUngrab && {
guint mode;
meta_input_event_get_crossing_details (display, event, &mode, NULL);
if (mode == NotifyUngrab &&
modified == display->ungrab_should_not_cause_focus_window) modified == display->ungrab_should_not_cause_focus_window)
{ {
add_ignored_serial (display, event->xany.serial); add_ignored_serial (display, event->xany.serial);
@ -1620,6 +1625,7 @@ event_callback (XEvent *event,
"Adding LeaveNotify serial %lu to ignored focus serials\n", "Adding LeaveNotify serial %lu to ignored focus serials\n",
event->xany.serial); event->xany.serial);
} }
}
if (modified != None) if (modified != None)
window = meta_display_lookup_x_window (display, modified); window = meta_display_lookup_x_window (display, modified);
@ -1721,8 +1727,8 @@ event_callback (XEvent *event,
{ {
Window xwindow = meta_input_event_get_window (display, event); Window xwindow = meta_input_event_get_window (display, event);
Time evtime = meta_input_event_get_time (display, event); Time evtime = meta_input_event_get_time (display, event);
guint n_button, state, mode, detail;
gdouble ev_root_x, ev_root_y; gdouble ev_root_x, ev_root_y;
guint n_button, state;
if (window && !window->override_redirect && if (window && !window->override_redirect &&
((evtype == KeyPress) || (evtype == ButtonPress))) ((evtype == KeyPress) || (evtype == ButtonPress)))
@ -2004,13 +2010,14 @@ event_callback (XEvent *event,
evtime); 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 /* Check if we've entered a window; do this even if window->has_focus to
* avoid races. * avoid races.
*/ */
if (window && !serial_is_ignored (display, event->xany.serial) && if (window && !serial_is_ignored (display, event->xany.serial) &&
event->xcrossing.mode != NotifyGrab && mode != NotifyGrab && mode != NotifyUngrab &&
event->xcrossing.mode != NotifyUngrab && detail != NotifyInferior &&
event->xcrossing.detail != NotifyInferior &&
meta_display_focus_sentinel_clear (display)) meta_display_focus_sentinel_clear (display))
{ {
switch (meta_prefs_get_focus_mode ()) switch (meta_prefs_get_focus_mode ())
@ -2083,15 +2090,19 @@ event_callback (XEvent *event,
meta_window_handle_mouse_grab_op_event (window, event); meta_window_handle_mouse_grab_op_event (window, event);
else if (window != NULL) else if (window != NULL)
{ {
meta_input_event_get_crossing_details (display, event,
&mode, &detail);
if (window->type == META_WINDOW_DOCK && if (window->type == META_WINDOW_DOCK &&
event->xcrossing.mode != NotifyGrab && mode != NotifyGrab && mode != NotifyUngrab &&
event->xcrossing.mode != NotifyUngrab &&
!window->has_focus) !window->has_focus)
meta_window_lower (window); meta_window_lower (window);
} }
break; break;
case FocusIn: case FocusIn:
case FocusOut: case FocusOut:
meta_input_event_get_crossing_details (display, event,
&mode, &detail);
if (window) if (window)
{ {
meta_window_notify_focus (window, event); meta_window_notify_focus (window, event);
@ -2105,8 +2116,8 @@ event_callback (XEvent *event,
evtype == FocusOut ? "out" : evtype == FocusOut ? "out" :
"???", "???",
xwindow, xwindow,
meta_event_mode_to_string (event->xfocus.mode), meta_event_mode_to_string (mode),
meta_event_detail_to_string (event->xfocus.detail)); meta_event_detail_to_string (detail));
} }
else else
{ {
@ -2123,11 +2134,11 @@ event_callback (XEvent *event,
evtype == FocusOut ? "out" : evtype == FocusOut ? "out" :
"???", "???",
xwindow, xwindow,
meta_event_mode_to_string (event->xfocus.mode), meta_event_mode_to_string (mode),
meta_event_detail_to_string (event->xfocus.detail)); meta_event_detail_to_string (detail));
if (evtype == FocusIn && if (evtype == FocusIn &&
event->xfocus.detail == NotifyDetailNone) detail == NotifyDetailNone)
{ {
meta_topic (META_DEBUG_FOCUS, meta_topic (META_DEBUG_FOCUS,
"Focus got set to None, probably due to " "Focus got set to None, probably due to "
@ -2138,8 +2149,8 @@ event_callback (XEvent *event,
meta_display_get_current_time_roundtrip (display)); meta_display_get_current_time_roundtrip (display));
} }
else if (evtype == FocusIn && else if (evtype == FocusIn &&
event->xfocus.mode == NotifyNormal && mode == NotifyNormal &&
event->xfocus.detail == NotifyInferior) detail == NotifyInferior)
{ {
meta_topic (META_DEBUG_FOCUS, meta_topic (META_DEBUG_FOCUS,
"Focus got set to root window, probably due to " "Focus got set to root window, probably due to "

View File

@ -122,6 +122,18 @@ meta_input_event_get_type (MetaDisplay *display,
return FALSE; 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 Window
meta_input_event_get_window (MetaDisplay *display, meta_input_event_get_window (MetaDisplay *display,
@ -540,3 +552,65 @@ meta_input_event_get_button (MetaDisplay *display,
return FALSE; 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;
}

View File

@ -38,6 +38,9 @@
gboolean meta_input_event_get_type (MetaDisplay *display, gboolean meta_input_event_get_type (MetaDisplay *display,
XEvent *ev, XEvent *ev,
guint *ev_type); guint *ev_type);
gboolean meta_input_event_is_type (MetaDisplay *display,
XEvent *ev,
guint ev_type);
Window meta_input_event_get_window (MetaDisplay *display, Window meta_input_event_get_window (MetaDisplay *display,
XEvent *ev); XEvent *ev);
@ -63,5 +66,10 @@ gboolean meta_input_event_get_keycode (MetaDisplay *display,
gboolean meta_input_event_get_button (MetaDisplay *display, gboolean meta_input_event_get_button (MetaDisplay *display,
XEvent *event, XEvent *event,
guint *button); guint *button);
gboolean meta_input_event_get_crossing_details (MetaDisplay *display,
XEvent *ev,
guint *mode_out,
guint *detail_out);
#endif /* META_EVENT_H */ #endif /* META_EVENT_H */