mirror of
https://github.com/brl/mutter.git
synced 2024-11-29 19:40:43 -05:00
core: Move window enter/leave to display
The following commits will make it possible to pass a NULL window to display_handle_window_enter/leave to represent the cursor entering the desktop. This means it can't be a method of the window class anymore. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3258>
This commit is contained in:
parent
c73e178a2d
commit
5a33b0075a
@ -353,3 +353,12 @@ gboolean meta_display_process_captured_input (MetaDisplay *display,
|
|||||||
const ClutterEvent *event);
|
const ClutterEvent *event);
|
||||||
|
|
||||||
void meta_display_cancel_input_capture (MetaDisplay *display);
|
void meta_display_cancel_input_capture (MetaDisplay *display);
|
||||||
|
|
||||||
|
void meta_display_handle_window_enter (MetaDisplay *display,
|
||||||
|
MetaWindow *window,
|
||||||
|
uint32_t timestamp_ms,
|
||||||
|
int root_x,
|
||||||
|
int root_y);
|
||||||
|
|
||||||
|
void meta_display_handle_window_leave (MetaDisplay *display,
|
||||||
|
MetaWindow *window);
|
||||||
|
@ -3803,3 +3803,156 @@ meta_display_flush_queued_window (MetaDisplay *display,
|
|||||||
window_queue_func[queue_idx] (display, windows);
|
window_queue_func[queue_idx] (display, windows);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
MetaWindow *window;
|
||||||
|
int pointer_x;
|
||||||
|
int pointer_y;
|
||||||
|
} MetaFocusData;
|
||||||
|
|
||||||
|
static void
|
||||||
|
focus_mouse_mode (MetaWindow *window,
|
||||||
|
uint32_t timestamp_ms)
|
||||||
|
{
|
||||||
|
MetaDisplay *display = window->display;
|
||||||
|
|
||||||
|
if (window->override_redirect)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (window->type != META_WINDOW_DESKTOP)
|
||||||
|
{
|
||||||
|
meta_topic (META_DEBUG_FOCUS,
|
||||||
|
"Focusing %s at time %u.", window->desc, timestamp_ms);
|
||||||
|
|
||||||
|
meta_window_focus (window, timestamp_ms);
|
||||||
|
|
||||||
|
if (meta_prefs_get_auto_raise ())
|
||||||
|
meta_display_queue_autoraise_callback (display, window);
|
||||||
|
else
|
||||||
|
meta_topic (META_DEBUG_FOCUS, "Auto raise is disabled");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* In mouse focus mode, we defocus when the mouse *enters*
|
||||||
|
* the DESKTOP window, instead of defocusing on LeaveNotify.
|
||||||
|
* This is because having the mouse enter override-redirect
|
||||||
|
* child windows unfortunately causes LeaveNotify events that
|
||||||
|
* we can't distinguish from the mouse actually leaving the
|
||||||
|
* toplevel window as we expect. But, since we filter out
|
||||||
|
* EnterNotify events on override-redirect windows, this
|
||||||
|
* alternative mechanism works great.
|
||||||
|
*/
|
||||||
|
if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_MOUSE &&
|
||||||
|
display->focus_window != NULL)
|
||||||
|
{
|
||||||
|
meta_topic (META_DEBUG_FOCUS,
|
||||||
|
"Unsetting focus from %s due to mouse entering "
|
||||||
|
"the DESKTOP window",
|
||||||
|
display->focus_window->desc);
|
||||||
|
meta_display_unset_input_focus (display, timestamp_ms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
focus_on_pointer_rest_callback (gpointer data)
|
||||||
|
{
|
||||||
|
MetaFocusData *focus_data = data;
|
||||||
|
MetaWindow *window = focus_data->window;
|
||||||
|
MetaDisplay *display = window->display;
|
||||||
|
MetaBackend *backend = backend_from_display (display);
|
||||||
|
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
|
||||||
|
graphene_point_t point;
|
||||||
|
uint32_t timestamp_ms;
|
||||||
|
|
||||||
|
if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
meta_cursor_tracker_get_pointer (cursor_tracker, &point, NULL);
|
||||||
|
|
||||||
|
if ((int) point.x != focus_data->pointer_x ||
|
||||||
|
(int) point.y != focus_data->pointer_y)
|
||||||
|
{
|
||||||
|
focus_data->pointer_x = point.x;
|
||||||
|
focus_data->pointer_y = point.y;
|
||||||
|
return G_SOURCE_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!meta_window_has_pointer (window))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
timestamp_ms = meta_display_get_current_time_roundtrip (display);
|
||||||
|
focus_mouse_mode (window, timestamp_ms);
|
||||||
|
|
||||||
|
out:
|
||||||
|
display->focus_timeout_id = 0;
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The interval, in milliseconds, we use in focus-follows-mouse
|
||||||
|
* mode to check whether the pointer has stopped moving after a
|
||||||
|
* crossing event.
|
||||||
|
*/
|
||||||
|
#define FOCUS_TIMEOUT_DELAY 25
|
||||||
|
|
||||||
|
static void
|
||||||
|
queue_pointer_rest_callback (MetaDisplay *display,
|
||||||
|
MetaWindow *window,
|
||||||
|
int pointer_x,
|
||||||
|
int pointer_y)
|
||||||
|
{
|
||||||
|
MetaFocusData *focus_data;
|
||||||
|
|
||||||
|
focus_data = g_new (MetaFocusData, 1);
|
||||||
|
focus_data->window = window;
|
||||||
|
focus_data->pointer_x = pointer_x;
|
||||||
|
focus_data->pointer_y = pointer_y;
|
||||||
|
|
||||||
|
g_clear_handle_id (&display->focus_timeout_id, g_source_remove);
|
||||||
|
|
||||||
|
display->focus_timeout_id =
|
||||||
|
g_timeout_add_full (G_PRIORITY_DEFAULT,
|
||||||
|
FOCUS_TIMEOUT_DELAY,
|
||||||
|
focus_on_pointer_rest_callback,
|
||||||
|
focus_data,
|
||||||
|
g_free);
|
||||||
|
g_source_set_name_by_id (display->focus_timeout_id,
|
||||||
|
"[mutter] focus_on_pointer_rest_callback");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_display_handle_window_enter (MetaDisplay *display,
|
||||||
|
MetaWindow *window,
|
||||||
|
uint32_t timestamp_ms,
|
||||||
|
int root_x,
|
||||||
|
int root_y)
|
||||||
|
{
|
||||||
|
switch (meta_prefs_get_focus_mode ())
|
||||||
|
{
|
||||||
|
case G_DESKTOP_FOCUS_MODE_SLOPPY:
|
||||||
|
case G_DESKTOP_FOCUS_MODE_MOUSE:
|
||||||
|
display->mouse_mode = TRUE;
|
||||||
|
if (window->type != META_WINDOW_DOCK)
|
||||||
|
{
|
||||||
|
if (meta_prefs_get_focus_change_on_pointer_rest())
|
||||||
|
queue_pointer_rest_callback (display, window, root_x, root_y);
|
||||||
|
else
|
||||||
|
focus_mouse_mode (window, timestamp_ms);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case G_DESKTOP_FOCUS_MODE_CLICK:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window->type == META_WINDOW_DOCK)
|
||||||
|
meta_window_raise (window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_display_handle_window_leave (MetaDisplay *display,
|
||||||
|
MetaWindow *window)
|
||||||
|
{
|
||||||
|
if (window->type == META_WINDOW_DOCK && !window->has_focus)
|
||||||
|
meta_window_lower (window);
|
||||||
|
}
|
||||||
|
@ -807,12 +807,6 @@ void meta_window_set_transient_for (MetaWindow *window,
|
|||||||
void meta_window_set_opacity (MetaWindow *window,
|
void meta_window_set_opacity (MetaWindow *window,
|
||||||
guint8 opacity);
|
guint8 opacity);
|
||||||
|
|
||||||
void meta_window_handle_enter (MetaWindow *window,
|
|
||||||
guint32 timestamp,
|
|
||||||
guint root_x,
|
|
||||||
guint root_y);
|
|
||||||
void meta_window_handle_leave (MetaWindow *window);
|
|
||||||
|
|
||||||
void meta_window_handle_ungrabbed_event (MetaWindow *window,
|
void meta_window_handle_ungrabbed_event (MetaWindow *window,
|
||||||
const ClutterEvent *event);
|
const ClutterEvent *event);
|
||||||
|
|
||||||
|
@ -7409,57 +7409,6 @@ meta_window_set_opacity (MetaWindow *window,
|
|||||||
meta_compositor_window_opacity_changed (window->display->compositor, window);
|
meta_compositor_window_opacity_changed (window->display->compositor, window);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
MetaWindow *window;
|
|
||||||
int pointer_x;
|
|
||||||
int pointer_y;
|
|
||||||
} MetaFocusData;
|
|
||||||
|
|
||||||
static void
|
|
||||||
mouse_mode_focus (MetaWindow *window,
|
|
||||||
guint32 timestamp)
|
|
||||||
{
|
|
||||||
MetaDisplay *display = window->display;
|
|
||||||
|
|
||||||
if (window->override_redirect)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (window->type != META_WINDOW_DESKTOP)
|
|
||||||
{
|
|
||||||
meta_topic (META_DEBUG_FOCUS,
|
|
||||||
"Focusing %s at time %u.", window->desc, timestamp);
|
|
||||||
|
|
||||||
meta_window_focus (window, timestamp);
|
|
||||||
|
|
||||||
if (meta_prefs_get_auto_raise ())
|
|
||||||
meta_display_queue_autoraise_callback (display, window);
|
|
||||||
else
|
|
||||||
meta_topic (META_DEBUG_FOCUS, "Auto raise is disabled");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* In mouse focus mode, we defocus when the mouse *enters*
|
|
||||||
* the DESKTOP window, instead of defocusing on LeaveNotify.
|
|
||||||
* This is because having the mouse enter override-redirect
|
|
||||||
* child windows unfortunately causes LeaveNotify events that
|
|
||||||
* we can't distinguish from the mouse actually leaving the
|
|
||||||
* toplevel window as we expect. But, since we filter out
|
|
||||||
* EnterNotify events on override-redirect windows, this
|
|
||||||
* alternative mechanism works great.
|
|
||||||
*/
|
|
||||||
if (meta_prefs_get_focus_mode() == G_DESKTOP_FOCUS_MODE_MOUSE &&
|
|
||||||
display->focus_window != NULL)
|
|
||||||
{
|
|
||||||
meta_topic (META_DEBUG_FOCUS,
|
|
||||||
"Unsetting focus from %s due to mouse entering "
|
|
||||||
"the DESKTOP window",
|
|
||||||
display->focus_window->desc);
|
|
||||||
meta_display_unset_input_focus (display, timestamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
window_has_pointer_wayland (MetaWindow *window)
|
window_has_pointer_wayland (MetaWindow *window)
|
||||||
{
|
{
|
||||||
@ -7509,108 +7458,6 @@ meta_window_has_pointer (MetaWindow *window)
|
|||||||
return window_has_pointer_x11 (window);
|
return window_has_pointer_x11 (window);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
window_focus_on_pointer_rest_callback (gpointer data)
|
|
||||||
{
|
|
||||||
MetaFocusData *focus_data = data;
|
|
||||||
MetaWindow *window = focus_data->window;
|
|
||||||
MetaDisplay *display = window->display;
|
|
||||||
MetaBackend *backend = backend_from_window (window);
|
|
||||||
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
|
|
||||||
graphene_point_t point;
|
|
||||||
guint32 timestamp;
|
|
||||||
|
|
||||||
if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
meta_cursor_tracker_get_pointer (cursor_tracker, &point, NULL);
|
|
||||||
|
|
||||||
if ((int) point.x != focus_data->pointer_x ||
|
|
||||||
(int) point.y != focus_data->pointer_y)
|
|
||||||
{
|
|
||||||
focus_data->pointer_x = point.x;
|
|
||||||
focus_data->pointer_y = point.y;
|
|
||||||
return G_SOURCE_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!meta_window_has_pointer (window))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
timestamp = meta_display_get_current_time_roundtrip (display);
|
|
||||||
mouse_mode_focus (window, timestamp);
|
|
||||||
|
|
||||||
out:
|
|
||||||
display->focus_timeout_id = 0;
|
|
||||||
return G_SOURCE_REMOVE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The interval, in milliseconds, we use in focus-follows-mouse
|
|
||||||
* mode to check whether the pointer has stopped moving after a
|
|
||||||
* crossing event.
|
|
||||||
*/
|
|
||||||
#define FOCUS_TIMEOUT_DELAY 25
|
|
||||||
|
|
||||||
static void
|
|
||||||
queue_focus_callback (MetaDisplay *display,
|
|
||||||
MetaWindow *window,
|
|
||||||
int pointer_x,
|
|
||||||
int pointer_y)
|
|
||||||
{
|
|
||||||
MetaFocusData *focus_data;
|
|
||||||
|
|
||||||
focus_data = g_new (MetaFocusData, 1);
|
|
||||||
focus_data->window = window;
|
|
||||||
focus_data->pointer_x = pointer_x;
|
|
||||||
focus_data->pointer_y = pointer_y;
|
|
||||||
|
|
||||||
g_clear_handle_id (&display->focus_timeout_id, g_source_remove);
|
|
||||||
|
|
||||||
display->focus_timeout_id =
|
|
||||||
g_timeout_add_full (G_PRIORITY_DEFAULT,
|
|
||||||
FOCUS_TIMEOUT_DELAY,
|
|
||||||
window_focus_on_pointer_rest_callback,
|
|
||||||
focus_data,
|
|
||||||
g_free);
|
|
||||||
g_source_set_name_by_id (display->focus_timeout_id,
|
|
||||||
"[mutter] window_focus_on_pointer_rest_callback");
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
meta_window_handle_enter (MetaWindow *window,
|
|
||||||
guint32 timestamp,
|
|
||||||
guint root_x,
|
|
||||||
guint root_y)
|
|
||||||
{
|
|
||||||
MetaDisplay *display = window->display;
|
|
||||||
|
|
||||||
switch (meta_prefs_get_focus_mode ())
|
|
||||||
{
|
|
||||||
case G_DESKTOP_FOCUS_MODE_SLOPPY:
|
|
||||||
case G_DESKTOP_FOCUS_MODE_MOUSE:
|
|
||||||
display->mouse_mode = TRUE;
|
|
||||||
if (window->type != META_WINDOW_DOCK)
|
|
||||||
{
|
|
||||||
if (meta_prefs_get_focus_change_on_pointer_rest())
|
|
||||||
queue_focus_callback (display, window, root_x, root_y);
|
|
||||||
else
|
|
||||||
mouse_mode_focus (window, timestamp);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case G_DESKTOP_FOCUS_MODE_CLICK:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (window->type == META_WINDOW_DOCK)
|
|
||||||
meta_window_raise (window);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
meta_window_handle_leave (MetaWindow *window)
|
|
||||||
{
|
|
||||||
if (window->type == META_WINDOW_DOCK && !window->has_focus)
|
|
||||||
meta_window_lower (window);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_window_handle_ungrabbed_event (MetaWindow *window,
|
meta_window_handle_ungrabbed_event (MetaWindow *window,
|
||||||
const ClutterEvent *event)
|
const ClutterEvent *event)
|
||||||
|
@ -713,7 +713,8 @@ meta_wayland_pointer_update (MetaWaylandPointer *pointer,
|
|||||||
graphene_point_t pos;
|
graphene_point_t pos;
|
||||||
|
|
||||||
clutter_event_get_coords (event, &pos.x, &pos.y);
|
clutter_event_get_coords (event, &pos.x, &pos.y);
|
||||||
meta_window_handle_enter (focus_window,
|
meta_display_handle_window_enter (focus_window->display,
|
||||||
|
focus_window,
|
||||||
clutter_event_get_time (event),
|
clutter_event_get_time (event),
|
||||||
pos.x, pos.y);
|
pos.x, pos.y);
|
||||||
}
|
}
|
||||||
|
@ -969,7 +969,8 @@ handle_input_xevent (MetaX11Display *x11_display,
|
|||||||
!meta_is_wayland_compositor () &&
|
!meta_is_wayland_compositor () &&
|
||||||
enter_event->sourceid != enter_event->deviceid)
|
enter_event->sourceid != enter_event->deviceid)
|
||||||
{
|
{
|
||||||
meta_window_handle_enter (window,
|
meta_display_handle_window_enter (display,
|
||||||
|
window,
|
||||||
enter_event->time,
|
enter_event->time,
|
||||||
enter_event->root_x,
|
enter_event->root_x,
|
||||||
enter_event->root_y);
|
enter_event->root_y);
|
||||||
@ -983,7 +984,7 @@ handle_input_xevent (MetaX11Display *x11_display,
|
|||||||
enter_event->mode != XINotifyGrab &&
|
enter_event->mode != XINotifyGrab &&
|
||||||
enter_event->mode != XINotifyUngrab)
|
enter_event->mode != XINotifyUngrab)
|
||||||
{
|
{
|
||||||
meta_window_handle_leave (window);
|
meta_display_handle_window_leave (display, window);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case XI_FocusIn:
|
case XI_FocusIn:
|
||||||
|
Loading…
Reference in New Issue
Block a user