]> git.mdlowis.com Git - proto/labwc.git/commitdiff
action: allow configurable policy in AutoPlace action
authorAndrew J. Hesford <ajh@sideband.org>
Tue, 7 May 2024 13:46:05 +0000 (09:46 -0400)
committerJohan Malm <johanmalm@users.noreply.github.com>
Sun, 19 May 2024 16:32:52 +0000 (17:32 +0100)
Closes: #1784.
docs/labwc-actions.5.scd
include/config/rcxml.h
include/view.h
src/action.c
src/config/rcxml.c
src/view.c
src/xdg.c
src/xwayland.c

index db0ce5cd00a1d0c8c4343c4ce01190fe3ba4e544..097cd5c2811015178ec6caa444f543b32d7af243 100644 (file)
@@ -251,9 +251,12 @@ Actions are used in menus and keyboard/mouse bindings.
        *output_name* The name of virtual output. If not supplied, will remove
        the last virtual output added.
 
-*<action name="AutoPlace" />*
-       Use the automatic placement policy to move the active window to a
-       position on its output that will minimize overlap with other windows.
+*<action name="AutoPlace" policy="value"/>*
+       Reposition the window according to the desired placement policy.
+
+       *policy* [automatic|cursor|center] Use the specified policy, which has
+       the same meaning as the corresponding value for *<placement><policy>*.
+       Default is automatic.
 
 *<action name="Shade" />*++
 *<action name="Unshade" />*++
index 80916ea1909181c5eb037616cca93ba8a6db9d8a..d308daa629b7331b1863287101a69c6de1ff3a6f 100644 (file)
@@ -16,7 +16,8 @@
 #include "theme.h"
 
 enum view_placement_policy {
-       LAB_PLACE_CENTER = 0,
+       LAB_PLACE_INVALID = 0,
+       LAB_PLACE_CENTER,
        LAB_PLACE_CURSOR,
        LAB_PLACE_AUTOMATIC
 };
index cb7e70dc48beb3439491789ec0bf41d36213aacb..b0e2a41e680ae17b74956cc5e7c476695788d9a7 100644 (file)
@@ -456,10 +456,13 @@ int view_effective_height(struct view *view, bool use_pending);
 void view_center(struct view *view, const struct wlr_box *ref);
 
 /**
- * view_place_initial - apply initial placement strategy to view
+ * view_place_by_policy - apply placement strategy to view
  * @view: view to be placed
+ * @allow_cursor: set to false to ignore center-on-cursor policy
+ * @policy: placement policy to apply
  */
-void view_place_initial(struct view *view, bool allow_cursor);
+void view_place_by_policy(struct view *view, bool allow_cursor,
+       enum view_placement_policy);
 void view_constrain_size_to_that_of_usable_area(struct view *view);
 
 void view_restore_to(struct view *view, struct wlr_box geometry);
@@ -525,6 +528,7 @@ struct output *view_get_adjacent_output(struct view *view, enum view_edge edge,
        bool wrap);
 enum view_axis view_axis_parse(const char *direction);
 enum view_edge view_edge_parse(const char *direction);
+enum view_placement_policy view_placement_parse(const char *policy);
 
 /* xdg.c */
 struct wlr_xdg_surface *xdg_surface_from_view(struct view *view);
index 78c71d98c6d53fcf9b0444acc2da9c3030936097..db2b7557ac01e68d3988182827eb8c47cd423338 100644 (file)
@@ -422,6 +422,19 @@ action_arg_from_xml_node(struct action *action, const char *nodename, const char
                        goto cleanup;
                }
                break;
+       case ACTION_TYPE_AUTO_PLACE:
+               if (!strcmp(argument, "policy")) {
+                       enum view_placement_policy policy =
+                               view_placement_parse(content);
+                       if (policy == LAB_PLACE_INVALID) {
+                               wlr_log(WLR_ERROR, "Invalid argument for action %s: '%s' (%s)",
+                                               action_names[action->type], argument, content);
+                       } else {
+                               action_arg_add_int(action, argument, policy);
+                       }
+                       goto cleanup;
+               }
+               break;
        }
 
        wlr_log(WLR_ERROR, "Invalid argument for action %s: '%s'",
@@ -1030,10 +1043,10 @@ actions_run(struct view *activator, struct server *server,
                        break;
                case ACTION_TYPE_AUTO_PLACE:
                        if (view) {
-                               struct wlr_box geometry = view->pending;
-                               if (placement_find_best(view, &geometry)) {
-                                       view_move(view, geometry.x, geometry.y);
-                               }
+                               enum view_placement_policy policy =
+                                       action_get_int(action, "policy", LAB_PLACE_AUTOMATIC);
+                               view_place_by_policy(view,
+                                       /* allow_cursor */ true, policy);
                        }
                        break;
                case ACTION_TYPE_TOGGLE_TEARING:
index 9884d41a33d0b391980d2f2b9607ad95ccc9618b..164e329ccb9671b68eb9e18a91f3747b8c1e776a 100644 (file)
@@ -873,11 +873,8 @@ entry(xmlNode *node, char *nodename, char *content)
        } else if (!strcasecmp(nodename, "reuseOutputMode.core")) {
                set_bool(content, &rc.reuse_output_mode);
        } else if (!strcmp(nodename, "policy.placement")) {
-               if (!strcmp(content, "automatic")) {
-                       rc.placement_policy = LAB_PLACE_AUTOMATIC;
-               } else if (!strcmp(content, "cursor")) {
-                       rc.placement_policy = LAB_PLACE_CURSOR;
-               } else {
+               rc.placement_policy = view_placement_parse(content);
+               if (rc.placement_policy == LAB_PLACE_INVALID) {
                        rc.placement_policy = LAB_PLACE_CENTER;
                }
        } else if (!strcmp(nodename, "name.theme")) {
index ee76a746f458efcf14f3c9f289c01852024a46db..ef44cbdb2ab69a050c2aeb6a47f9031652800278 100644 (file)
@@ -833,12 +833,13 @@ view_center(struct view *view, const struct wlr_box *ref)
 }
 
 void
-view_place_initial(struct view *view, bool allow_cursor)
+view_place_by_policy(struct view *view, bool allow_cursor,
+               enum view_placement_policy policy)
 {
-       if (allow_cursor && rc.placement_policy == LAB_PLACE_CURSOR) {
+       if (allow_cursor && policy == LAB_PLACE_CURSOR) {
                view_move_to_cursor(view);
                return;
-       } else if (rc.placement_policy == LAB_PLACE_AUTOMATIC) {
+       } else if (policy == LAB_PLACE_AUTOMATIC) {
                struct wlr_box geometry = view->pending;
                if (placement_find_best(view, &geometry)) {
                        view_move(view, geometry.x, geometry.y);
@@ -1866,6 +1867,24 @@ view_edge_parse(const char *direction)
        }
 }
 
+enum view_placement_policy
+view_placement_parse(const char *policy)
+{
+       if (!policy) {
+               return LAB_PLACE_CENTER;
+       }
+
+       if (!strcasecmp(policy, "automatic")) {
+               return LAB_PLACE_AUTOMATIC;
+       } else if (!strcasecmp(policy, "cursor")) {
+               return LAB_PLACE_CURSOR;
+       } else if (!strcasecmp(policy, "center")) {
+               return LAB_PLACE_CENTER;
+       }
+
+       return LAB_PLACE_INVALID;
+}
+
 void
 view_snap_to_edge(struct view *view, enum view_edge edge,
                        bool across_outputs, bool store_natural_geometry)
@@ -1969,7 +1988,8 @@ view_move_to_output(struct view *view, struct output *output)
                struct wlr_box output_area = output_usable_area_in_layout_coords(output);
                view->pending.x = output_area.x;
                view->pending.y = output_area.y;
-               view_place_initial(view, /* allow_cursor */ false);
+               view_place_by_policy(view,
+                               /* allow_cursor */ false, rc.placement_policy);
        } else if (view->maximized != VIEW_AXIS_NONE) {
                view_apply_maximized_geometry(view);
        } else if (view->tiled) {
index 488f67fd257c02f8810c33ca736fa27de09c2325..fd4e926f00a5297a33cb8ff14dce2669e54bc110 100644 (file)
--- a/src/xdg.c
+++ b/src/xdg.c
@@ -530,7 +530,7 @@ set_initial_position(struct view *view)
        }
 
        /* All other views are placed according to a configured strategy */
-       view_place_initial(view, /* allow_cursor */ true);
+       view_place_by_policy(view, /* allow_cursor */ true, rc.placement_policy);
 }
 
 static const char *
index eda5aad7a1a51ef4ec1914b66a0228fee68746f8..073a96974fadf28f169876d017a4264abccd7896 100644 (file)
@@ -571,7 +571,8 @@ set_initial_position(struct view *view,
                view_constrain_size_to_that_of_usable_area(view);
 
                if (view_is_floating(view)) {
-                       view_place_initial(view, /* allow_cursor */ true);
+                       view_place_by_policy(view,
+                               /* allow_cursor */ true, rc.placement_policy);
                } else {
                        /*
                         * View is maximized/fullscreen. Center the