mirror of
https://github.com/labwc/labwc.git
synced 2026-03-02 01:40:24 -05:00
view: add for_each_view()
Helped-by: @Consolatis and @heroin-moose (by a significant amount)
This commit is contained in:
parent
a9e123393c
commit
7fde7ed2cc
3 changed files with 87 additions and 36 deletions
|
|
@ -169,23 +169,54 @@ struct xdg_toplevel_view {
|
||||||
};
|
};
|
||||||
|
|
||||||
enum lab_view_criteria {
|
enum lab_view_criteria {
|
||||||
LAB_VIEW_CRITERIA_ALL = 0,
|
LAB_VIEW_CRITERIA_NONE = 0,
|
||||||
LAB_VIEW_CRITERIA_CURRENT_WORKSPACE = 1 << 0,
|
LAB_VIEW_CRITERIA_CURRENT_WORKSPACE = 1 << 0,
|
||||||
LAB_VIEW_CRITERIA_NO_ALWAYS_ON_TOP = 1 << 1,
|
LAB_VIEW_CRITERIA_NO_ALWAYS_ON_TOP = 1 << 1,
|
||||||
LAB_VIEW_CRITERIA_NO_SKIP_WINDOW_SWITCHER = 1 << 2,
|
LAB_VIEW_CRITERIA_NO_SKIP_WINDOW_SWITCHER = 1 << 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* view_array_append - append views that match criteria to array
|
* for_each_view() - iterate over all views which match criteria
|
||||||
|
* @view: Iterator.
|
||||||
|
* @head: Head of list to iterate over.
|
||||||
|
* @criteria: Criteria to match against.
|
||||||
|
* Example:
|
||||||
|
* struct view *view;
|
||||||
|
* for_each_view(view, &server->views, LAB_VIEW_CRITERIA_NONE) {
|
||||||
|
* printf("%s\n", view_get_string_prop(view, "app_id"));
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
#define for_each_view(view, head, criteria) \
|
||||||
|
for (view = view_next(head, NULL, criteria); \
|
||||||
|
view; \
|
||||||
|
view = view_next(head, view, criteria))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* view_next() - Get next view which matches criteria.
|
||||||
|
* @head: Head of list to iterate over.
|
||||||
|
* @view: Current view from which to find the next one. If NULL is provided as
|
||||||
|
* the view argument, the start of the list will be used.
|
||||||
|
* @criteria: Criteria to match against.
|
||||||
|
*
|
||||||
|
* Returns NULL if there are no views matching the criteria.
|
||||||
|
*/
|
||||||
|
struct view *view_next(struct wl_list *head, struct view *view,
|
||||||
|
enum lab_view_criteria criteria);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* view_array_append() - Append views that match criteria to array
|
||||||
* @server: server context
|
* @server: server context
|
||||||
* @views: arrays to append to
|
* @views: arrays to append to
|
||||||
* @criteria: criteria to match against
|
* @criteria: criteria to match against
|
||||||
*
|
*
|
||||||
|
* This function is useful in cases where the calling function may change the
|
||||||
|
* stacking order or where it needs to iterate over the views multiple times,
|
||||||
|
* for example to get the number of views before processing them.
|
||||||
|
*
|
||||||
* Note: This array has a very short shelf-life so it is intended to be used
|
* Note: This array has a very short shelf-life so it is intended to be used
|
||||||
* with a single-use-throw-away approach.
|
* with a single-use-throw-away approach.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
*
|
|
||||||
* struct view **view;
|
* struct view **view;
|
||||||
* struct wl_array views;
|
* struct wl_array views;
|
||||||
* wl_array_init(&views);
|
* wl_array_init(&views);
|
||||||
|
|
|
||||||
5
scripts/checkpatch.pl
vendored
5
scripts/checkpatch.pl
vendored
|
|
@ -5526,10 +5526,11 @@ sub process {
|
||||||
# because (as opposed to Linux coding style) we use
|
# because (as opposed to Linux coding style) we use
|
||||||
# braces for single statement blocks.
|
# braces for single statement blocks.
|
||||||
#
|
#
|
||||||
# include/ssd-internal.h contains a macro that we can't
|
# We ignore a couple of header-files which contain
|
||||||
# deal with, so ignore that
|
# macros that we cannot deal with.
|
||||||
#
|
#
|
||||||
if ($starts_with_if_while_etc && !length($s)
|
if ($starts_with_if_while_etc && !length($s)
|
||||||
|
&& $filename ne "include/view.h"
|
||||||
&& $filename ne "include/ssd-internal.h") {
|
&& $filename ne "include/ssd-internal.h") {
|
||||||
CHK("BRACES", "[labwc-custom] open brace { expected after if/while/for/switch - even with single statement blocks");
|
CHK("BRACES", "[labwc-custom] open brace { expected after if/while/for/switch - even with single statement blocks");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
81
src/view.c
81
src/view.c
|
|
@ -19,44 +19,63 @@
|
||||||
#define LAB_FALLBACK_WIDTH 640
|
#define LAB_FALLBACK_WIDTH 640
|
||||||
#define LAB_FALLBACK_HEIGHT 480
|
#define LAB_FALLBACK_HEIGHT 480
|
||||||
|
|
||||||
|
static bool
|
||||||
|
matches_criteria(struct view *view, enum lab_view_criteria criteria)
|
||||||
|
{
|
||||||
|
if (!isfocusable(view)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (criteria & LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) {
|
||||||
|
/*
|
||||||
|
* Always-on-top views are always on the current desktop and are
|
||||||
|
* special in that they live in a different tree.
|
||||||
|
*/
|
||||||
|
struct server *server = view->server;
|
||||||
|
if (view->scene_tree->node.parent != server->workspace_current->tree
|
||||||
|
&& !view_is_always_on_top(view)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (criteria & LAB_VIEW_CRITERIA_NO_ALWAYS_ON_TOP) {
|
||||||
|
if (view_is_always_on_top(view)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (criteria & LAB_VIEW_CRITERIA_NO_SKIP_WINDOW_SWITCHER) {
|
||||||
|
if (window_rules_get_property(view, "skipWindowSwitcher") == LAB_PROP_TRUE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct view *
|
||||||
|
view_next(struct wl_list *head, struct view *view, enum lab_view_criteria criteria)
|
||||||
|
{
|
||||||
|
assert(head);
|
||||||
|
|
||||||
|
struct wl_list *elm = view ? &view->link : head;
|
||||||
|
|
||||||
|
for (elm = elm->next; elm != head; elm = elm->next) {
|
||||||
|
view = wl_container_of(elm, view, link);
|
||||||
|
if (matches_criteria(view, criteria)) {
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
struct view *view;
|
struct view *view;
|
||||||
wl_list_for_each(view, &server->views, link)
|
for_each_view(view, &server->views, criteria) {
|
||||||
{
|
struct view **entry = wl_array_add(views, sizeof(*entry));
|
||||||
if (!isfocusable(view)) {
|
if (!entry) {
|
||||||
|
wlr_log(WLR_ERROR, "wl_array_add(): out of memory");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (criteria & LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) {
|
|
||||||
/*
|
|
||||||
* Always-on-top views are always on the current
|
|
||||||
* desktop and are special in that they live in a
|
|
||||||
* different tree.
|
|
||||||
*/
|
|
||||||
if (view_is_always_on_top(view)) {
|
|
||||||
goto next;
|
|
||||||
}
|
|
||||||
if (view->scene_tree->node.parent != server->workspace_current->tree) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
next:
|
|
||||||
if (criteria & LAB_VIEW_CRITERIA_NO_ALWAYS_ON_TOP) {
|
|
||||||
if (view_is_always_on_top(view)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (criteria & LAB_VIEW_CRITERIA_NO_SKIP_WINDOW_SWITCHER) {
|
|
||||||
if (window_rules_get_property(view, "skipWindowSwitcher")
|
|
||||||
== LAB_PROP_TRUE) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct view **entry = wl_array_add(views, sizeof(*entry));
|
|
||||||
*entry = view;
|
*entry = view;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue