]> git.mdlowis.com Git - proto/labwc.git/commitdiff
action: support {Go,Send}ToDesktop 'wrap' option
authorTomi Ollila <tomi.ollila@iki.fi>
Sun, 14 May 2023 17:44:59 +0000 (20:44 +0300)
committerConsolatis <35009135+Consolatis@users.noreply.github.com>
Sun, 21 May 2023 20:32:07 +0000 (22:32 +0200)
Make wrap 'true' by default for both GoToDesktop and SendToDesktop,
in order to default to the current behaviour, and to stay consistent
with Openbox behaviour.

docs/labwc-actions.5.scd
docs/rc.xml.all
include/workspaces.h
src/action.c
src/workspaces.c

index 755955916a63c11b73b77233c2aa01bb19c40c13..0e47d8bbbaa00e4dc6c0ede95a708479ceb3aff9 100644 (file)
@@ -91,14 +91,17 @@ Actions are used in menus and keyboard/mouse bindings.
        to the center of the window. If the given output does not contain
        any windows, the cursor is centered on the given output.
 
-*<action name="GoToDesktop" to="value" />*
+*<action name="GoToDesktop" to="value" wrap="yes" />*
        Switch to workspace.
 
        *to* The workspace to switch to. Supported values are "last", "left",
        "right" or the full name of a workspace or its index (starting at 1)
        as configured in rc.xml.
 
-*<action name="SendToDesktop" to="value" follow="yes" />*
+       *wrap* [yes|no] Wrap around from last desktop to first, and vice
+       versa. Default yes.
+
+*<action name="SendToDesktop" to="value" follow="yes" wrap="yes" />*
        Send active window to workspace.
 
        *to* The workspace to send the window to. Supported values are the same
@@ -106,6 +109,9 @@ Actions are used in menus and keyboard/mouse bindings.
 
        *follow* [yes|no] Also switch to the specified workspace. Default yes.
 
+       *wrap* [yes|no] Wrap around from last desktop to first, and vice
+       versa. Default yes.
+
 *<action name="None">*
        If used as the only action for a binding: clear an earlier defined binding.
 
index 8ee880242867313c9e8fc62aae587cf345854ce6..d4883ed0aa704ff192408199fc2e48c63a06959c 100644 (file)
         <action name="ShowMenu" menu="root-menu" />
       </mousebind>
       <mousebind direction="Up" action="Scroll">
-        <action name="GoToDesktop" to="left" />
+        <action name="GoToDesktop" to="left" wrap="yes" />
       </mousebind>
       <mousebind direction="Down" action="Scroll">
-        <action name="GoToDesktop" to="right" />
+        <action name="GoToDesktop" to="right" wrap="yes" />
       </mousebind>
     </context>
 
index a8a4ee7b61529693e84478075c212d95f43d01d8..e533f7f90e0441e11be78849fd6c57ce12f4fcfa 100644 (file)
@@ -23,6 +23,7 @@ void workspaces_init(struct server *server);
 void workspaces_switch_to(struct workspace *target);
 void workspaces_destroy(struct server *server);
 void workspaces_osd_hide(struct seat *seat);
-struct workspace *workspaces_find(struct workspace *anchor, const char *name);
+struct workspace *workspaces_find(struct workspace *anchor, const char *name,
+       bool wrap);
 
 #endif /* LABWC_WORKSPACES_H */
index f9b67979e980cda196fcf3245667c35cf873a9e0..0134270a0049b2428fa121dccbc832467bfd4966 100644 (file)
@@ -179,6 +179,10 @@ action_arg_from_xml_node(struct action *action, char *nodename, char *content)
                        action_arg_add_str(action, argument, content);
                        goto cleanup;
                }
+               if (!strcmp(argument, "wrap")) {
+                       action_arg_add_bool(action, argument, parse_bool(content, true));
+                       goto cleanup;
+               }
                break;
        case ACTION_TYPE_SNAP_TO_REGION:
                if (!strcmp(argument, "region")) {
@@ -546,18 +550,21 @@ actions_run(struct view *activator, struct server *server,
                                        resize_edges);
                        }
                        break;
-               case ACTION_TYPE_GO_TO_DESKTOP:
-                       if (!arg) {
-                               wlr_log(WLR_ERROR, "Missing argument for GoToDesktop");
+               case ACTION_TYPE_GO_TO_DESKTOP: {
+                       const char *to = get_arg_value_str(action, "to", NULL);
+                       if (!to) {
+                               wlr_log(WLR_ERROR,
+                                       "Missing 'to' argument for GoToDesktop");
                                break;
                        }
+                       bool wrap = get_arg_value_bool(action, "wrap", true);
                        struct workspace *target;
-                       const char *target_name = action_str_from_arg(arg);
-                       target = workspaces_find(server->workspace_current, target_name);
+                       target = workspaces_find(server->workspace_current, to, wrap);
                        if (target) {
                                workspaces_switch_to(target);
                        }
                        break;
+               }
                case ACTION_TYPE_SEND_TO_DESKTOP:
                        if (view) {
                                const char *to = get_arg_value_str(action, "to", NULL);
@@ -567,7 +574,9 @@ actions_run(struct view *activator, struct server *server,
                                        break;
                                }
                                bool follow = get_arg_value_bool(action, "follow", true);
-                               struct workspace *target = workspaces_find(view->workspace, to);
+                               bool wrap = get_arg_value_bool(action, "wrap", true);
+                               struct workspace *target;
+                               target = workspaces_find(view->workspace, to, wrap);
                                if (target) {
                                        view_move_to_workspace(view, target);
                                        if (follow) {
index 193fd6da30d93abf791f4289c085686e9da91d36..b9560fd07e6ec3b293c86f95a930f865b7707059 100644 (file)
@@ -172,22 +172,30 @@ add_workspace(struct server *server, const char *name)
 }
 
 static struct workspace *
-get_prev(struct workspace *current, struct wl_list *workspaces)
+get_prev(struct workspace *current, struct wl_list *workspaces, bool wrap)
 {
        struct wl_list *target_link = current->link.prev;
        if (target_link == workspaces) {
-               /* Current workspace is the first one, roll over */
+               /* Current workspace is the first one */
+               if (!wrap) {
+                       return NULL;
+               }
+               /* Roll over */
                target_link = target_link->prev;
        }
        return wl_container_of(target_link, current, link);
 }
 
 static struct workspace *
-get_next(struct workspace *current, struct wl_list *workspaces)
+get_next(struct workspace *current, struct wl_list *workspaces, bool wrap)
 {
        struct wl_list *target_link = current->link.next;
        if (target_link == workspaces) {
-               /* Current workspace is the last one, roll over */
+               /* Current workspace is the last one */
+               if (!wrap) {
+                       return NULL;
+               }
+               /* Roll over */
                target_link = target_link->next;
        }
        return wl_container_of(target_link, current, link);
@@ -304,7 +312,7 @@ workspaces_osd_hide(struct seat *seat)
 }
 
 struct workspace *
-workspaces_find(struct workspace *anchor, const char *name)
+workspaces_find(struct workspace *anchor, const char *name, bool wrap)
 {
        assert(anchor);
        if (!name) {
@@ -324,9 +332,9 @@ workspaces_find(struct workspace *anchor, const char *name)
        } else if (!strcasecmp(name, "last")) {
                return anchor->server->workspace_last;
        } else if (!strcasecmp(name, "left")) {
-               return get_prev(anchor, workspaces);
+               return get_prev(anchor, workspaces, wrap);
        } else if (!strcasecmp(name, "right")) {
-               return get_next(anchor, workspaces);
+               return get_next(anchor, workspaces, wrap);
        } else {
                wl_list_for_each(target, workspaces, link) {
                        if (!strcasecmp(target->name, name)) {