};
enum lab_view_criteria {
- LAB_VIEW_CRITERIA_ALL = 0,
+ LAB_VIEW_CRITERIA_NONE = 0,
LAB_VIEW_CRITERIA_CURRENT_WORKSPACE = 1 << 0,
LAB_VIEW_CRITERIA_NO_ALWAYS_ON_TOP = 1 << 1,
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
* @views: arrays to append to
* @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
* with a single-use-throw-away approach.
*
* Example usage:
- *
* struct view **view;
* struct wl_array views;
* wl_array_init(&views);
# because (as opposed to Linux coding style) we use
# braces for single statement blocks.
#
- # include/ssd-internal.h contains a macro that we can't
- # deal with, so ignore that
+ # We ignore a couple of header-files which contain
+ # macros that we cannot deal with.
#
if ($starts_with_if_while_etc && !length($s)
+ && $filename ne "include/view.h"
&& $filename ne "include/ssd-internal.h") {
CHK("BRACES", "[labwc-custom] open brace { expected after if/while/for/switch - even with single statement blocks");
}
#define LAB_FALLBACK_WIDTH 640
#define LAB_FALLBACK_HEIGHT 480
-void
-view_array_append(struct server *server, struct wl_array *views,
- enum lab_view_criteria criteria)
+static bool
+matches_criteria(struct view *view, enum lab_view_criteria criteria)
{
- struct view *view;
- wl_list_for_each(view, &server->views, link)
- {
- if (!isfocusable(view)) {
- continue;
+ 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_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;
- }
+ }
+ if (criteria & LAB_VIEW_CRITERIA_NO_ALWAYS_ON_TOP) {
+ if (view_is_always_on_top(view)) {
+ return false;
}
-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) {
+ return false;
}
- if (criteria & LAB_VIEW_CRITERIA_NO_SKIP_WINDOW_SWITCHER) {
- if (window_rules_get_property(view, "skipWindowSwitcher")
- == LAB_PROP_TRUE) {
- continue;
- }
+ }
+ 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
+view_array_append(struct server *server, struct wl_array *views,
+ enum lab_view_criteria criteria)
+{
+ struct view *view;
+ for_each_view(view, &server->views, criteria) {
struct view **entry = wl_array_add(views, sizeof(*entry));
+ if (!entry) {
+ wlr_log(WLR_ERROR, "wl_array_add(): out of memory");
+ continue;
+ }
*entry = view;
}
}