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,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 "

View File

@ -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;
}

View File

@ -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 */