]> git.mdlowis.com Git - proto/labwc.git/commitdiff
view: add view_for_each_reverse() macro
authorConsolatis <35009135+Consolatis@users.noreply.github.com>
Tue, 12 Nov 2024 19:34:29 +0000 (20:34 +0100)
committerJohan Malm <johanmalm@users.noreply.github.com>
Mon, 25 Nov 2024 19:21:43 +0000 (19:21 +0000)
include/view.h
src/view.c

index bffdea07ae545e0370071f4c1b8f6a166ac88cdf..19b04939414719558336e772614c52493a63739b 100644 (file)
@@ -381,11 +381,27 @@ bool view_matches_query(struct view *view, struct view_query *query);
  *             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;                                      \
+#define for_each_view(view, head, criteria)           \
+       for (view = view_next(head, NULL, criteria);  \
+            view;                                    \
             view = view_next(head, view, criteria))
 
+/**
+ * for_each_view_reverse() - 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_reverse(view, &server->views, LAB_VIEW_CRITERIA_NONE) {
+ *             printf("%s\n", view_get_string_prop(view, "app_id"));
+ *     }
+ */
+#define for_each_view_reverse(view, head, criteria)   \
+       for (view = view_prev(head, NULL, criteria);  \
+            view;                                    \
+            view = view_prev(head, view, criteria))
+
 /**
  * view_next() - Get next view which matches criteria.
  * @head: Head of list to iterate over.
@@ -398,6 +414,18 @@ bool view_matches_query(struct view *view, struct view_query *query);
 struct view *view_next(struct wl_list *head, struct view *view,
        enum lab_view_criteria criteria);
 
+/**
+ * view_prev() - Get previous view which matches criteria.
+ * @head: Head of list to iterate over.
+ * @view: Current view from which to find the previous one. If NULL is provided
+ *        as the view argument, the end of the list will be used.
+ * @criteria: Criteria to match against.
+ *
+ * Returns NULL if there are no views matching the criteria.
+ */
+struct view *view_prev(struct wl_list *head, struct view *view,
+       enum lab_view_criteria criteria);
+
 /*
  * Same as `view_next()` except that they iterate one whole cycle rather than
  * stopping at the list-head
index d64fddad683af524a2e6ea3d8adf952751492682..74a7528605150cc1001edc87de5768e0658eb075 100644 (file)
@@ -269,6 +269,22 @@ view_next(struct wl_list *head, struct view *view, enum lab_view_criteria criter
        return NULL;
 }
 
+struct view *
+view_prev(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->prev; elm != head; elm = elm->prev) {
+               view = wl_container_of(elm, view, link);
+               if (matches_criteria(view, criteria)) {
+                       return view;
+               }
+       }
+       return NULL;
+}
+
 struct view *
 view_next_no_head_stop(struct wl_list *head, struct view *from,
                enum lab_view_criteria criteria)