mirror of
https://github.com/labwc/labwc.git
synced 2025-11-03 09:01:51 -05:00
desktop: refactor desktop_cycle_view()
...in preparation for using common window-rule criteria with osd.c No functional change intended. Related-to #1454
This commit is contained in:
parent
6a35e8e78c
commit
777e6bb868
3 changed files with 77 additions and 90 deletions
|
|
@ -321,6 +321,15 @@ bool view_matches_query(struct view *view, struct view_query *query);
|
||||||
struct view *view_next(struct wl_list *head, struct view *view,
|
struct view *view_next(struct wl_list *head, struct view *view,
|
||||||
enum lab_view_criteria criteria);
|
enum lab_view_criteria criteria);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Same as `view_next()` except that they iterate one whole cycle rather than
|
||||||
|
* stopping at the list-head
|
||||||
|
*/
|
||||||
|
struct view *view_next_no_head_stop(struct wl_list *head, struct view *from,
|
||||||
|
enum lab_view_criteria criteria);
|
||||||
|
struct view *view_prev_no_head_stop(struct wl_list *head, struct view *from,
|
||||||
|
enum lab_view_criteria criteria);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* view_array_append() - Append views that match criteria to array
|
* view_array_append() - Append views that match criteria to array
|
||||||
* @server: server context
|
* @server: server context
|
||||||
|
|
|
||||||
116
src/desktop.c
116
src/desktop.c
|
|
@ -106,109 +106,45 @@ desktop_focus_view_or_surface(struct seat *seat, struct view *view,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct wl_list *
|
|
||||||
get_prev_item(struct wl_list *item)
|
|
||||||
{
|
|
||||||
return item->prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct wl_list *
|
|
||||||
get_next_item(struct wl_list *item)
|
|
||||||
{
|
|
||||||
return item->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct view *
|
|
||||||
first_view(struct server *server)
|
|
||||||
{
|
|
||||||
struct wlr_scene_node *node;
|
|
||||||
struct wl_list *list_head =
|
|
||||||
&server->workspace_current->tree->children;
|
|
||||||
wl_list_for_each_reverse(node, list_head, link) {
|
|
||||||
if (!node->data) {
|
|
||||||
/* We found some non-view, most likely the region overlay */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
struct view *view = node_view_from_node(node);
|
|
||||||
if (view_is_focusable(view)) {
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct view *
|
struct view *
|
||||||
desktop_cycle_view(struct server *server, struct view *start_view,
|
desktop_cycle_view(struct server *server, struct view *start_view,
|
||||||
enum lab_cycle_dir dir)
|
enum lab_cycle_dir dir)
|
||||||
{
|
{
|
||||||
|
/* Make sure to have all nodes in their actual ordering */
|
||||||
|
osd_preview_restore(server);
|
||||||
|
|
||||||
|
struct view *(*iter)(struct wl_list *head, struct view *view,
|
||||||
|
enum lab_view_criteria criteria);
|
||||||
|
bool forwards = dir == LAB_CYCLE_DIR_FORWARD;
|
||||||
|
iter = forwards ? view_next_no_head_stop : view_prev_no_head_stop;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Views are listed in stacking order, topmost first. Usually
|
* TODO: These criteria are the same as in display_osd() in osd.c
|
||||||
* the topmost view is already focused, so we pre-select the
|
* for the time being.
|
||||||
* view second from the top:
|
*
|
||||||
|
* A future improvement could be to make this configurable for example
|
||||||
|
* in rc.xml and then use rc.cycle_view_criteria (or whatever) both
|
||||||
|
* here and in the osd.c window-switcher code
|
||||||
|
*/
|
||||||
|
enum lab_view_criteria criteria = LAB_VIEW_CRITERIA_CURRENT_WORKSPACE
|
||||||
|
| LAB_VIEW_CRITERIA_NO_ALWAYS_ON_TOP
|
||||||
|
| LAB_VIEW_CRITERIA_NO_SKIP_WINDOW_SWITCHER;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Views are listed in stacking order, topmost first. Usually the
|
||||||
|
* topmost view is already focused, so when iterating in the forward
|
||||||
|
* direction we pre-select the view second from the top:
|
||||||
*
|
*
|
||||||
* View #1 (on top, currently focused)
|
* View #1 (on top, currently focused)
|
||||||
* View #2 (pre-selected)
|
* View #2 (pre-selected)
|
||||||
* View #3
|
* View #3
|
||||||
* ...
|
* ...
|
||||||
*
|
|
||||||
* This assumption doesn't always hold with XWayland views,
|
|
||||||
* where a main application window may be focused but an
|
|
||||||
* focusable sub-view (e.g. an about dialog) may still be on
|
|
||||||
* top of it. In that case, we pre-select the sub-view:
|
|
||||||
*
|
|
||||||
* Sub-view of #1 (on top, pre-selected)
|
|
||||||
* Main view #1 (currently focused)
|
|
||||||
* Main view #2
|
|
||||||
* ...
|
|
||||||
*
|
|
||||||
* The general rule is:
|
|
||||||
*
|
|
||||||
* - Pre-select the top view if NOT already focused
|
|
||||||
* - Otherwise select the view second from the top
|
|
||||||
*/
|
*/
|
||||||
|
if (!start_view && forwards) {
|
||||||
/* Make sure to have all nodes in their actual ordering */
|
start_view = iter(&server->views, NULL, criteria);
|
||||||
osd_preview_restore(server);
|
|
||||||
|
|
||||||
if (!start_view) {
|
|
||||||
start_view = first_view(server);
|
|
||||||
if (!start_view || start_view != server->active_view) {
|
|
||||||
return start_view; /* may be NULL */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
struct view *view = start_view;
|
|
||||||
struct wlr_scene_node *node = &view->scene_tree->node;
|
|
||||||
|
|
||||||
assert(node->parent);
|
return iter(&server->views, start_view, criteria);
|
||||||
struct wl_list *list_head = &node->parent->children;
|
|
||||||
struct wl_list *list_item = &node->link;
|
|
||||||
struct wl_list *(*iter)(struct wl_list *list);
|
|
||||||
|
|
||||||
/* Scene nodes are ordered like last node == displayed topmost */
|
|
||||||
iter = dir == LAB_CYCLE_DIR_FORWARD ? get_prev_item : get_next_item;
|
|
||||||
|
|
||||||
do {
|
|
||||||
list_item = iter(list_item);
|
|
||||||
if (list_item == list_head) {
|
|
||||||
/* Start / End of list reached. Roll over */
|
|
||||||
list_item = iter(list_item);
|
|
||||||
}
|
|
||||||
node = wl_container_of(list_item, node, link);
|
|
||||||
if (!node->data) {
|
|
||||||
/* We found some non-view, most likely the region overlay */
|
|
||||||
view = NULL;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
view = node_view_from_node(node);
|
|
||||||
|
|
||||||
enum property skip = window_rules_get_property(view, "skipWindowSwitcher");
|
|
||||||
if (view_is_focusable(view) && skip != LAB_PROP_TRUE) {
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
} while (view != start_view);
|
|
||||||
|
|
||||||
/* No focusable views found, including the one we started with */
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct view *
|
struct view *
|
||||||
|
|
|
||||||
42
src/view.c
42
src/view.c
|
|
@ -137,6 +137,48 @@ view_next(struct wl_list *head, struct view *view, enum lab_view_criteria criter
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct view *
|
||||||
|
view_next_no_head_stop(struct wl_list *head, struct view *from,
|
||||||
|
enum lab_view_criteria criteria)
|
||||||
|
{
|
||||||
|
assert(head);
|
||||||
|
|
||||||
|
struct wl_list *elm = from ? &from->link : head;
|
||||||
|
|
||||||
|
struct wl_list *end = elm;
|
||||||
|
for (elm = elm->next; elm != end; elm = elm->next) {
|
||||||
|
if (elm == head) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
struct view *view = wl_container_of(elm, view, link);
|
||||||
|
if (matches_criteria(view, criteria)) {
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return from;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct view *
|
||||||
|
view_prev_no_head_stop(struct wl_list *head, struct view *from,
|
||||||
|
enum lab_view_criteria criteria)
|
||||||
|
{
|
||||||
|
assert(head);
|
||||||
|
|
||||||
|
struct wl_list *elm = from ? &from->link : head;
|
||||||
|
|
||||||
|
struct wl_list *end = elm;
|
||||||
|
for (elm = elm->prev; elm != end; elm = elm->prev) {
|
||||||
|
if (elm == head) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
struct view *view = wl_container_of(elm, view, link);
|
||||||
|
if (matches_criteria(view, criteria)) {
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return from;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
view_array_append(struct server *server, struct wl_array *views,
|
view_array_append(struct server *server, struct wl_array *views,
|
||||||
enum lab_view_criteria criteria)
|
enum lab_view_criteria criteria)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue