Move isfocusable() from desktop.c to view.c

This commit is contained in:
Johan Malm 2023-08-20 16:43:29 +01:00 committed by Johan Malm
parent 602d59a3b2
commit e5a6c57a6e
5 changed files with 29 additions and 24 deletions

View file

@ -388,7 +388,6 @@ struct view *desktop_cycle_view(struct server *server, struct view *start_view,
enum lab_cycle_dir dir); enum lab_cycle_dir dir);
struct view *desktop_focused_view(struct server *server); struct view *desktop_focused_view(struct server *server);
void desktop_focus_topmost_mapped_view(struct server *server); void desktop_focus_topmost_mapped_view(struct server *server);
bool isfocusable(struct view *view);
void keyboard_cancel_keybind_repeat(struct keyboard *keyboard); void keyboard_cancel_keybind_repeat(struct keyboard *keyboard);
void keyboard_key_notify(struct wl_listener *listener, void *data); void keyboard_key_notify(struct wl_listener *listener, void *data);

View file

@ -229,6 +229,20 @@ struct view *view_next(struct wl_list *head, struct view *view,
void view_array_append(struct server *server, struct wl_array *views, void view_array_append(struct server *server, struct wl_array *views,
enum lab_view_criteria criteria); enum lab_view_criteria criteria);
/**
* view_isfocusable() - Check whether or not a view can be focused
* @view: view to be checked
*
* The purpose of this test is to filter out views (generally Xwayland) which
* are not meant to be focused such as those with surfaces
* a. that have been created but never mapped;
* b. set to NULL after client minimize-request.
*
* The only views that are allowed to be focusd are those that have a surface
* and have been mapped at some point since creation.
*/
bool view_isfocusable(struct view *view);
bool view_inhibits_keybinds(struct view *view); bool view_inhibits_keybinds(struct view *view);
void view_toggle_keybinds(struct view *view); void view_toggle_keybinds(struct view *view);

View file

@ -45,7 +45,7 @@ desktop_focus_and_activate_view(struct seat *seat, struct view *view)
/* /*
* Guard against views with no mapped surfaces when handling * Guard against views with no mapped surfaces when handling
* 'request_activate' and 'request_minimize'. * 'request_activate' and 'request_minimize'.
* See notes by isfocusable() * See notes by view_isfocusable()
*/ */
if (!view->surface) { if (!view->surface) {
return; return;
@ -81,23 +81,6 @@ desktop_focus_and_activate_view(struct seat *seat, struct view *view)
seat_focus_surface(seat, view->surface); seat_focus_surface(seat, view->surface);
} }
/*
* Some xwayland apps produce unmapped surfaces on startup and also leave
* some unmapped surfaces kicking around on 'close' (for example leafpad's
* "about" dialogue). Whilst this is not normally a problem, we have to be
* careful when cycling between views. The only views we should focus are
* those that are already mapped and those that have been minimized.
*/
bool
isfocusable(struct view *view)
{
/* filter out those xwayland surfaces that have never been mapped */
if (!view->surface) {
return false;
}
return (view->mapped || view->minimized);
}
static struct wl_list * static struct wl_list *
get_prev_item(struct wl_list *item) get_prev_item(struct wl_list *item)
{ {
@ -122,7 +105,7 @@ first_view(struct server *server)
continue; continue;
} }
struct view *view = node_view_from_node(node); struct view *view = node_view_from_node(node);
if (isfocusable(view)) { if (view_isfocusable(view)) {
return view; return view;
} }
} }
@ -194,7 +177,7 @@ desktop_cycle_view(struct server *server, struct view *start_view,
view = node_view_from_node(node); view = node_view_from_node(node);
enum property skip = window_rules_get_property(view, "skipWindowSwitcher"); enum property skip = window_rules_get_property(view, "skipWindowSwitcher");
if (isfocusable(view) && skip != LAB_PROP_TRUE) { if (view_isfocusable(view) && skip != LAB_PROP_TRUE) {
return view; return view;
} }
} while (view != start_view); } while (view != start_view);
@ -269,7 +252,7 @@ desktop_focus_output(struct output *output)
continue; continue;
} }
view = node_view_from_node(node); view = node_view_from_node(node);
if (!isfocusable(view)) { if (!view_isfocusable(view)) {
continue; continue;
} }
if (wlr_output_layout_intersects(layout, if (wlr_output_layout_intersects(layout,

View file

@ -475,7 +475,7 @@ osd_update(struct server *server)
/* Outline current window */ /* Outline current window */
if (rc.window_switcher.outlines) { if (rc.window_switcher.outlines) {
if (isfocusable(server->osd_state.cycle_view)) { if (view_isfocusable(server->osd_state.cycle_view)) {
osd_update_preview_outlines(server->osd_state.cycle_view); osd_update_preview_outlines(server->osd_state.cycle_view);
} }
} }

View file

@ -22,7 +22,7 @@
static bool static bool
matches_criteria(struct view *view, enum lab_view_criteria criteria) matches_criteria(struct view *view, enum lab_view_criteria criteria)
{ {
if (!isfocusable(view)) { if (!view_isfocusable(view)) {
return false; return false;
} }
if (criteria & LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) { if (criteria & LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) {
@ -80,6 +80,15 @@ view_array_append(struct server *server, struct wl_array *views,
} }
} }
bool
view_isfocusable(struct view *view)
{
if (!view->surface) {
return false;
}
return (view->mapped || view->minimized);
}
/** /**
* All view_apply_xxx_geometry() functions must *not* modify * All view_apply_xxx_geometry() functions must *not* modify
* any state besides repositioning or resizing the view. * any state besides repositioning or resizing the view.