diff --git a/docs/labwc-actions.5.scd b/docs/labwc-actions.5.scd index 47ee1801..dc6b3fd9 100644 --- a/docs/labwc-actions.5.scd +++ b/docs/labwc-actions.5.scd @@ -294,9 +294,11 @@ Actions are used in menus and keyboard/mouse bindings. fullscreen. If *output* is specified, the window will be sent directly to the - specified output and *direction* is ignored. If *output* is omitted, + specified output and *direction* is ignored. *output* may also be + "next" or "prev" to move to the next or previous output in the + server.outputs list, with wraparound. If *output* is omitted, *direction* may be one of "left", "right", "up" or "down" to indicate - that the window should be moved to the next output in that direction + that the window should be moved to the next output in the direction (if one exists). *wrap* [yes|no] When using the direction attribute, wrap around from diff --git a/src/action.c b/src/action.c index daf8fb30..01a1e096 100644 --- a/src/action.c +++ b/src/action.c @@ -997,17 +997,34 @@ match_queries(struct view *view, struct action *action) static struct output * get_target_output(struct output *output, struct action *action) { - const char *output_name = action_get_str(action, "output", NULL); + const char *output_arg = action_get_str(action, "output", NULL); struct output *target = NULL; - if (output_name) { - target = output_from_name(output_name); + if (output_arg) { + if (!strcasecmp(output_arg, "next")) { + struct wl_list *list_item = output->link.next; + if (list_item == &server.outputs) { + list_item = server.outputs.next; + } + target = wl_container_of(list_item, target, link); + } else if (!strcasecmp(output_arg, "prev")) { + struct wl_list *list_item = output->link.prev; + if (list_item == &server.outputs) { + list_item = server.outputs.prev; + } + target = wl_container_of(list_item, target, link); + } else { + target = output_from_name(output_arg); + } } else { enum lab_edge edge = action_get_int(action, "direction", LAB_EDGE_NONE); bool wrap = action_get_bool(action, "wrap", false); target = output_get_adjacent(output, edge, wrap); } + if (!target || !output_is_usable(target)) { + target = NULL; + } if (!target) { wlr_log(WLR_DEBUG, "Invalid output");