core: Move remaining default focus window handling to workspace
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2489>
This commit is contained in:
parent
3a96ef023b
commit
b4b9a7c90f
@ -411,9 +411,6 @@ gboolean meta_display_apply_startup_properties (MetaDisplay *display,
|
||||
void meta_display_queue_workarea_recalc (MetaDisplay *display);
|
||||
void meta_display_queue_check_fullscreen (MetaDisplay *display);
|
||||
|
||||
MetaWindow *meta_display_get_pointer_window (MetaDisplay *display,
|
||||
MetaWindow *not_this_one);
|
||||
|
||||
MetaWindow *meta_display_get_window_from_id (MetaDisplay *display,
|
||||
uint64_t window_id);
|
||||
uint64_t meta_display_generate_window_id (MetaDisplay *display);
|
||||
|
@ -3794,30 +3794,6 @@ meta_display_get_monitor_in_fullscreen (MetaDisplay *display,
|
||||
purposes */ return logical_monitor->in_fullscreen == TRUE;
|
||||
}
|
||||
|
||||
MetaWindow *
|
||||
meta_display_get_pointer_window (MetaDisplay *display,
|
||||
MetaWindow *not_this_one)
|
||||
{
|
||||
MetaWorkspaceManager *workspace_manager = display->workspace_manager;
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
|
||||
MetaWindow *window;
|
||||
graphene_point_t point;
|
||||
|
||||
if (not_this_one)
|
||||
meta_topic (META_DEBUG_FOCUS,
|
||||
"Focusing mouse window excluding %s", not_this_one->desc);
|
||||
|
||||
meta_cursor_tracker_get_pointer (cursor_tracker, &point, NULL);
|
||||
|
||||
window = meta_stack_get_default_focus_window_at_point (display->stack,
|
||||
workspace_manager->active_workspace,
|
||||
not_this_one,
|
||||
point.x, point.y);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
void
|
||||
meta_display_focus_default_window (MetaDisplay *display,
|
||||
guint32 timestamp)
|
||||
|
125
src/core/stack.c
125
src/core/stack.c
@ -50,6 +50,7 @@ static void stack_do_constrain (MetaStack *stack);
|
||||
static void stack_do_resort (MetaStack *stack);
|
||||
static void stack_ensure_sorted (MetaStack *stack);
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_DISPLAY = 1,
|
||||
@ -1007,110 +1008,6 @@ meta_stack_get_below (MetaStack *stack,
|
||||
return below;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
window_contains_point (MetaWindow *window,
|
||||
int root_x,
|
||||
int root_y)
|
||||
{
|
||||
MetaRectangle rect;
|
||||
|
||||
meta_window_get_frame_rect (window, &rect);
|
||||
|
||||
return META_POINT_IN_RECT (root_x, root_y, rect);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
window_can_get_default_focus (MetaWindow *window,
|
||||
MetaWorkspace *workspace)
|
||||
{
|
||||
if (window->unmaps_pending > 0)
|
||||
return FALSE;
|
||||
|
||||
if (window->unmanaging)
|
||||
return FALSE;
|
||||
|
||||
if (!meta_window_is_focusable (window))
|
||||
return FALSE;
|
||||
|
||||
if (!meta_window_showing_on_its_workspace (window))
|
||||
return FALSE;
|
||||
|
||||
if (!meta_window_located_on_workspace (window, workspace))
|
||||
return FALSE;
|
||||
|
||||
if (window->type == META_WINDOW_DOCK)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static MetaWindow *
|
||||
get_default_focus_window (MetaStack *stack,
|
||||
MetaWorkspace *workspace,
|
||||
MetaWindow *not_this_one,
|
||||
gboolean must_be_at_point,
|
||||
int root_x,
|
||||
int root_y)
|
||||
{
|
||||
/* Find the topmost, focusable, mapped, window.
|
||||
* not_this_one is being unfocused or going away, so exclude it.
|
||||
*/
|
||||
|
||||
GList *l;
|
||||
|
||||
stack_ensure_sorted (stack);
|
||||
|
||||
/* top of this layer is at the front of the list */
|
||||
for (l = stack->sorted; l != NULL; l = l->next)
|
||||
{
|
||||
MetaWindow *window = l->data;
|
||||
|
||||
if (!window)
|
||||
continue;
|
||||
|
||||
if (window == not_this_one)
|
||||
continue;
|
||||
|
||||
if (!window_can_get_default_focus (window, workspace))
|
||||
continue;
|
||||
|
||||
if (must_be_at_point && !window_contains_point (window, root_x, root_y))
|
||||
continue;
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MetaWindow *
|
||||
meta_stack_get_default_focus_window_at_point (MetaStack *stack,
|
||||
MetaWorkspace *workspace,
|
||||
MetaWindow *not_this_one,
|
||||
int root_x,
|
||||
int root_y)
|
||||
{
|
||||
g_return_val_if_fail (META_IS_STACK (stack), NULL);
|
||||
g_return_val_if_fail (META_IS_WORKSPACE (workspace), NULL);
|
||||
g_return_val_if_fail (!not_this_one || META_IS_WINDOW (not_this_one), NULL);
|
||||
|
||||
return get_default_focus_window (stack, workspace, not_this_one,
|
||||
TRUE, root_x, root_y);
|
||||
}
|
||||
|
||||
MetaWindow *
|
||||
meta_stack_get_default_focus_window (MetaStack *stack,
|
||||
MetaWorkspace *workspace,
|
||||
MetaWindow *not_this_one)
|
||||
{
|
||||
g_return_val_if_fail (META_IS_STACK (stack), NULL);
|
||||
g_return_val_if_fail (META_IS_WORKSPACE (workspace), NULL);
|
||||
g_return_val_if_fail (!not_this_one || META_IS_WINDOW (not_this_one), NULL);
|
||||
|
||||
return get_default_focus_window (stack, workspace, not_this_one,
|
||||
FALSE, 0, 0);
|
||||
}
|
||||
|
||||
GList *
|
||||
meta_stack_list_windows (MetaStack *stack,
|
||||
MetaWorkspace *workspace)
|
||||
@ -1139,26 +1036,6 @@ meta_stack_list_windows (MetaStack *stack,
|
||||
return workspace_windows;
|
||||
}
|
||||
|
||||
GList *
|
||||
meta_stack_get_default_focus_candidates (MetaStack *stack,
|
||||
MetaWorkspace *workspace)
|
||||
{
|
||||
GList *windows = meta_stack_list_windows (stack, workspace);
|
||||
GList *l;
|
||||
|
||||
for (l = windows; l;)
|
||||
{
|
||||
GList *next = l->next;
|
||||
|
||||
if (!window_can_get_default_focus (l->data, workspace))
|
||||
windows = g_list_delete_link (windows, l);
|
||||
|
||||
l = next;
|
||||
}
|
||||
|
||||
return windows;
|
||||
}
|
||||
|
||||
int
|
||||
meta_stack_windows_cmp (MetaStack *stack,
|
||||
MetaWindow *window_a,
|
||||
|
@ -257,72 +257,6 @@ MetaWindow * meta_stack_get_below (MetaStack *stack,
|
||||
MetaWindow *window,
|
||||
gboolean only_within_layer);
|
||||
|
||||
/**
|
||||
* meta_stack_get_default_focus_window:
|
||||
* @stack: The stack to search.
|
||||
* @workspace: %NULL to search all workspaces; otherwise only windows
|
||||
* from that workspace will be returned.
|
||||
* @not_this_one: Window to ignore because it's being unfocussed or
|
||||
* going away.
|
||||
*
|
||||
* Find the topmost, focusable, mapped, window in a stack. If you supply
|
||||
* a window as @not_this_one, we won't return that one (presumably
|
||||
* because it's going to be going away). But if you do supply @not_this_one
|
||||
* and we find its parent, we'll return that; and if @not_this_one is in
|
||||
* a group, we'll return the top window of that group.
|
||||
*
|
||||
* Also, we are prejudiced against dock windows. Every kind of window, even
|
||||
* the desktop, will be returned in preference to a dock window.
|
||||
*
|
||||
* Returns: The window matching all these constraints or %NULL if none does.
|
||||
*/
|
||||
MetaWindow * meta_stack_get_default_focus_window (MetaStack *stack,
|
||||
MetaWorkspace *workspace,
|
||||
MetaWindow *not_this_one);
|
||||
|
||||
/**
|
||||
* meta_stack_get_default_focus_window_at_point:
|
||||
* @stack: The stack to search.
|
||||
* @workspace: %NULL to search all workspaces; otherwise only windows
|
||||
* from that workspace will be returned.
|
||||
* @not_this_one: Window to ignore because it's being unfocussed or
|
||||
* going away.
|
||||
* @root_x: The returned window must contain this point,
|
||||
* unless it's a dock.
|
||||
* @root_y: See root_x.
|
||||
*
|
||||
* Find the topmost, focusable, mapped, window in a stack. If you supply
|
||||
* a window as @not_this_one, we won't return that one (presumably
|
||||
* because it's going to be going away). But if you do supply @not_this_one
|
||||
* and we find its parent, we'll return that; and if @not_this_one is in
|
||||
* a group, we'll return the top window of that group.
|
||||
*
|
||||
* Also, we are prejudiced against dock windows. Every kind of window, even
|
||||
* the desktop, will be returned in preference to a dock window.
|
||||
*
|
||||
* Returns: The window matching all these constraints or %NULL if none does.
|
||||
*/
|
||||
MetaWindow * meta_stack_get_default_focus_window_at_point (MetaStack *stack,
|
||||
MetaWorkspace *workspace,
|
||||
MetaWindow *not_this_one,
|
||||
int root_x,
|
||||
int root_y);
|
||||
|
||||
/**
|
||||
* meta_stack_get_default_focus_candidates:
|
||||
* @stack: The stack to examine.
|
||||
* @workspace: If not %NULL, only windows on this workspace will be
|
||||
* returned; otherwise all windows in the stack will be
|
||||
* returned.
|
||||
*
|
||||
* Returns all the focus candidate windows in the stack, in order.
|
||||
*
|
||||
* Returns: (transfer container) (element-type Meta.Window):
|
||||
* A #GList of #MetaWindow, in stacking order, honouring layers.
|
||||
*/
|
||||
GList * meta_stack_get_default_focus_candidates (MetaStack *stack,
|
||||
MetaWorkspace *workspace);
|
||||
|
||||
/**
|
||||
* meta_stack_list_windows:
|
||||
* @stack: The stack to examine.
|
||||
@ -403,4 +337,5 @@ void meta_stack_set_positions (MetaStack *stack,
|
||||
|
||||
void meta_stack_update_window_tile_matches (MetaStack *stack,
|
||||
MetaWorkspace *workspace);
|
||||
|
||||
#endif
|
||||
|
@ -5058,9 +5058,15 @@ meta_window_update_appears_focused (MetaWindow *window)
|
||||
workspace = meta_window_get_workspace (window);
|
||||
|
||||
if (workspace && workspace != workspace_manager->active_workspace)
|
||||
appears_focused = window == meta_workspace_get_default_focus_window (workspace);
|
||||
{
|
||||
appears_focused =
|
||||
window == meta_workspace_get_default_focus_window (workspace, NULL) &&
|
||||
meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK;
|
||||
}
|
||||
else
|
||||
appears_focused = window->has_focus || window->attached_focus_window;
|
||||
{
|
||||
appears_focused = window->has_focus || window->attached_focus_window;
|
||||
}
|
||||
|
||||
if (window->appears_focused == appears_focused)
|
||||
return;
|
||||
|
@ -92,10 +92,16 @@ GList* meta_workspace_get_onscreen_region (MetaWorkspace *workspace);
|
||||
GList * meta_workspace_get_onmonitor_region (MetaWorkspace *workspace,
|
||||
MetaLogicalMonitor *logical_monitor);
|
||||
|
||||
MetaWindow * meta_workspace_get_default_focus_window (MetaWorkspace *workspace);
|
||||
void meta_workspace_focus_default_window (MetaWorkspace *workspace,
|
||||
MetaWindow *not_this_one,
|
||||
guint32 timestamp);
|
||||
MetaWindow * meta_workspace_get_default_focus_window (MetaWorkspace *workspace,
|
||||
MetaWindow *not_this_one);
|
||||
MetaWindow * meta_workspace_get_default_focus_window_at_point (MetaWorkspace *workspace,
|
||||
MetaWindow *not_this_one,
|
||||
int root_x,
|
||||
int root_y);
|
||||
GList * meta_workspace_get_default_focus_candidates (MetaWorkspace *workspace);
|
||||
|
||||
const char* meta_workspace_get_name (MetaWorkspace *workspace);
|
||||
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "backends/meta-backend-private.h"
|
||||
#include "backends/meta-cursor-tracker-private.h"
|
||||
#include "backends/meta-logical-monitor.h"
|
||||
#include "cogl/cogl.h"
|
||||
#include "core/boxes-private.h"
|
||||
@ -53,6 +54,8 @@ void meta_workspace_queue_calc_showing (MetaWorkspace *workspace);
|
||||
static void focus_ancestor_or_mru_window (MetaWorkspace *workspace,
|
||||
MetaWindow *not_this_one,
|
||||
guint32 timestamp);
|
||||
static MetaWindow * get_pointer_window (MetaWorkspace *workspace,
|
||||
MetaWindow *not_this_one);
|
||||
|
||||
G_DEFINE_TYPE (MetaWorkspace, meta_workspace, G_TYPE_OBJECT);
|
||||
|
||||
@ -1330,7 +1333,8 @@ meta_workspace_focus_default_window (MetaWorkspace *workspace,
|
||||
else
|
||||
{
|
||||
MetaWindow * window;
|
||||
window = meta_display_get_pointer_window (workspace->display, not_this_one);
|
||||
|
||||
window = get_pointer_window (workspace, not_this_one);
|
||||
if (window &&
|
||||
window->type != META_WINDOW_DOCK &&
|
||||
window->type != META_WINDOW_DESKTOP)
|
||||
@ -1381,7 +1385,8 @@ is_focusable (MetaWindow *window,
|
||||
MetaWorkspace *workspace)
|
||||
{
|
||||
return !window->unmanaging &&
|
||||
window->mapped &&
|
||||
window->unmaps_pending == 0 &&
|
||||
window->type != META_WINDOW_DOCK &&
|
||||
meta_window_is_focusable (window) &&
|
||||
meta_window_located_on_workspace (window, workspace) &&
|
||||
meta_window_showing_on_its_workspace (window);
|
||||
@ -1402,11 +1407,91 @@ find_focusable_ancestor (MetaWindow *window,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static MetaWindow *
|
||||
get_default_focus_window (MetaWorkspace *workspace,
|
||||
MetaWindow *not_this_one)
|
||||
GList *
|
||||
meta_workspace_get_default_focus_candidates (MetaWorkspace *workspace)
|
||||
{
|
||||
GList *l;
|
||||
GList *candidates = NULL;
|
||||
|
||||
for (l = workspace->mru_list; l; l = l->next)
|
||||
{
|
||||
MetaWindow *window = l->data;
|
||||
|
||||
g_assert (window);
|
||||
|
||||
if (!is_focusable (window, workspace))
|
||||
continue;
|
||||
|
||||
candidates = g_list_prepend (candidates, window);
|
||||
}
|
||||
|
||||
return candidates;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
window_contains_point (MetaWindow *window,
|
||||
int root_x,
|
||||
int root_y)
|
||||
{
|
||||
MetaRectangle rect;
|
||||
|
||||
meta_window_get_frame_rect (window, &rect);
|
||||
|
||||
return META_POINT_IN_RECT (root_x, root_y, rect);
|
||||
}
|
||||
|
||||
MetaWindow *
|
||||
meta_workspace_get_default_focus_window_at_point (MetaWorkspace *workspace,
|
||||
MetaWindow *not_this_one,
|
||||
int root_x,
|
||||
int root_y)
|
||||
{
|
||||
g_autoptr (GList) sorted = NULL;
|
||||
GList *l;
|
||||
MetaStack *stack;
|
||||
|
||||
g_return_val_if_fail (META_IS_WORKSPACE (workspace), NULL);
|
||||
g_return_val_if_fail (!not_this_one || META_IS_WINDOW (not_this_one), NULL);
|
||||
|
||||
stack = workspace->display->stack;
|
||||
|
||||
g_return_val_if_fail (META_IS_STACK (stack), NULL);
|
||||
|
||||
/* Find the topmost, focusable, mapped, window.
|
||||
* not_this_one is being unfocused or going away, so exclude it.
|
||||
*/
|
||||
sorted = g_list_reverse (meta_stack_list_windows (stack, workspace));
|
||||
|
||||
/* top of this layer is at the front of the list */
|
||||
for (l = sorted; l != NULL; l = l->next)
|
||||
{
|
||||
MetaWindow *window = l->data;
|
||||
|
||||
g_assert (window);
|
||||
|
||||
if (window == not_this_one)
|
||||
continue;
|
||||
|
||||
if (!is_focusable (window, workspace))
|
||||
continue;
|
||||
|
||||
if (!window_contains_point (window, root_x, root_y))
|
||||
continue;
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MetaWindow *
|
||||
meta_workspace_get_default_focus_window (MetaWorkspace *workspace,
|
||||
MetaWindow *not_this_one)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
g_return_val_if_fail (META_IS_WORKSPACE (workspace), NULL);
|
||||
g_return_val_if_fail (!not_this_one || META_IS_WINDOW (not_this_one), NULL);
|
||||
|
||||
for (l = workspace->mru_list; l; l = l->next)
|
||||
{
|
||||
@ -1426,17 +1511,23 @@ get_default_focus_window (MetaWorkspace *workspace,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MetaWindow *
|
||||
meta_workspace_get_default_focus_window (MetaWorkspace *workspace)
|
||||
static MetaWindow *
|
||||
get_pointer_window (MetaWorkspace *workspace,
|
||||
MetaWindow *not_this_one)
|
||||
{
|
||||
if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK)
|
||||
{
|
||||
return get_default_focus_window (workspace, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
|
||||
graphene_point_t point;
|
||||
|
||||
if (not_this_one)
|
||||
meta_topic (META_DEBUG_FOCUS,
|
||||
"Focusing mouse window excluding %s", not_this_one->desc);
|
||||
|
||||
meta_cursor_tracker_get_pointer (cursor_tracker, &point, NULL);
|
||||
|
||||
return meta_workspace_get_default_focus_window_at_point (workspace,
|
||||
not_this_one,
|
||||
point.x, point.y);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -1515,7 +1606,7 @@ focus_ancestor_or_mru_window (MetaWorkspace *workspace,
|
||||
}
|
||||
}
|
||||
|
||||
window = get_default_focus_window (workspace, not_this_one);
|
||||
window = meta_workspace_get_default_focus_window (workspace, not_this_one);
|
||||
|
||||
if (window)
|
||||
{
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
|
||||
#include "core/meta-workspace-manager-private.h"
|
||||
#include "core/workspace-private.h"
|
||||
#include "meta/meta-x11-errors.h"
|
||||
#include "wayland/meta-wayland-data-device.h"
|
||||
#include "wayland/meta-xwayland-private.h"
|
||||
@ -726,10 +727,9 @@ pick_drop_surface (MetaWaylandCompositor *compositor,
|
||||
graphene_point_t pos;
|
||||
|
||||
clutter_event_get_coords (event, &pos.x, &pos.y);
|
||||
focus_window = meta_stack_get_default_focus_window_at_point (display->stack,
|
||||
workspace,
|
||||
NULL,
|
||||
pos.x, pos.y);
|
||||
focus_window = meta_workspace_get_default_focus_window_at_point (workspace,
|
||||
NULL,
|
||||
pos.x, pos.y);
|
||||
return focus_window ? focus_window->surface : NULL;
|
||||
}
|
||||
|
||||
|
@ -901,7 +901,6 @@ maybe_focus_default_window (MetaDisplay *display,
|
||||
guint32 timestamp)
|
||||
{
|
||||
MetaWorkspace *workspace;
|
||||
MetaStack *stack = display->stack;
|
||||
g_autoptr (GList) focusable_windows = NULL;
|
||||
g_autoptr (GQueue) focus_candidates = NULL;
|
||||
GList *l;
|
||||
@ -917,7 +916,7 @@ maybe_focus_default_window (MetaDisplay *display,
|
||||
* focused window, will stop the chained requests.
|
||||
*/
|
||||
focusable_windows =
|
||||
meta_stack_get_default_focus_candidates (stack, workspace);
|
||||
meta_workspace_get_default_focus_candidates (workspace);
|
||||
focus_candidates = g_queue_new ();
|
||||
|
||||
for (l = g_list_last (focusable_windows); l; l = l->prev)
|
||||
|
Loading…
Reference in New Issue
Block a user