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="MoveToOutput" name="HDMI-A-1" direction="value" />*
+*<action name="MoveToOutput" name="HDMI-A-1" direction="value" wrap="no" />*
Moves active window to other output, unless the window state is
fullscreen.
be one of "left", "right", "up" or "down" to indicate that the window
should be moved to the next output in that direction (if one exists).
+ *wrap* [yes|no] When using the direction attribute, wrap around from
+ right-to-left or top-to-bottom, and vice versa. Default no.
+
*<action name="FitToOutput" />*
Resizes active window size to width and height of the output when the
window size exceeds the output size.
}
goto cleanup;
}
+ if (!strcmp(argument, "wrap")) {
+ action_arg_add_bool(action, argument, parse_bool(content, false));
+ goto cleanup;
+ }
break;
case ACTION_TYPE_VIRTUAL_OUTPUT_ADD:
case ACTION_TYPE_VIRTUAL_OUTPUT_REMOVE:
} else {
/* Config parsing makes sure that direction is a valid direction */
enum view_edge edge = action_get_int(action, "direction", 0);
- target = view_get_adjacent_output(view, edge);
+ bool wrap = action_get_bool(action, "wrap", false);
+ target = view_get_adjacent_output(view, edge, wrap);
}
if (!target) {
wlr_log(WLR_ERROR, "Invalid output.");
#include <assert.h>
#include <stdio.h>
#include <strings.h>
+#include <wlr/types/wlr_output_layout.h>
#include "common/macros.h"
#include "common/match.h"
#include "common/mem.h"
view->output = NULL;
}
+static enum wlr_direction
+opposite_direction(enum wlr_direction direction)
+{
+ switch (direction) {
+ case WLR_DIRECTION_RIGHT:
+ return WLR_DIRECTION_LEFT;
+ case WLR_DIRECTION_LEFT:
+ return WLR_DIRECTION_RIGHT;
+ case WLR_DIRECTION_DOWN:
+ return WLR_DIRECTION_UP;
+ case WLR_DIRECTION_UP:
+ return WLR_DIRECTION_DOWN;
+ default:
+ return 0;
+ }
+}
+
+static enum wlr_direction
+get_wlr_direction(enum view_edge edge)
+{
+ switch (edge) {
+ case VIEW_EDGE_LEFT:
+ return WLR_DIRECTION_LEFT;
+ case VIEW_EDGE_RIGHT:
+ return WLR_DIRECTION_RIGHT;
+ case VIEW_EDGE_UP:
+ return WLR_DIRECTION_UP;
+ case VIEW_EDGE_DOWN:
+ return WLR_DIRECTION_DOWN;
+ case VIEW_EDGE_CENTER:
+ case VIEW_EDGE_INVALID:
+ default:
+ return 0;
+ }
+}
+
struct output *
-view_get_adjacent_output(struct view *view, enum view_edge edge)
+view_get_adjacent_output(struct view *view, enum view_edge edge, bool wrap)
{
assert(view);
struct output *output = view->output;
return NULL;
}
- struct wlr_box box = output_usable_area_in_layout_coords(view->output);
+ struct wlr_box box = output_usable_area_in_layout_coords(output);
int lx = box.x + box.width / 2;
int ly = box.y + box.height / 2;
struct wlr_output *new_output = NULL;
struct wlr_output *current_output = output->wlr_output;
struct wlr_output_layout *layout = view->server->output_layout;
- switch (edge) {
- case VIEW_EDGE_LEFT:
- new_output = wlr_output_layout_adjacent_output(
- layout, WLR_DIRECTION_LEFT, current_output, lx, ly);
- break;
- case VIEW_EDGE_RIGHT:
- new_output = wlr_output_layout_adjacent_output(
- layout, WLR_DIRECTION_RIGHT, current_output, lx, ly);
- break;
- case VIEW_EDGE_UP:
- new_output = wlr_output_layout_adjacent_output(
- layout, WLR_DIRECTION_UP, current_output, lx, ly);
- break;
- case VIEW_EDGE_DOWN:
- new_output = wlr_output_layout_adjacent_output(
- layout, WLR_DIRECTION_DOWN, current_output, lx, ly);
- break;
- default:
- break;
+ enum wlr_direction direction = get_wlr_direction(edge);
+ new_output = wlr_output_layout_adjacent_output(layout, direction,
+ current_output, lx, ly);
+
+ /*
+ * Optionally wrap around from top-to-bottom or left-to-right, and vice
+ * versa.
+ */
+ if (wrap && !new_output) {
+ new_output = wlr_output_layout_farthest_output(layout,
+ opposite_direction(direction), current_output, lx, ly);
}
- /* When "adjacent" output is the same as the original, there is no adjacent */
+ /*
+ * When "adjacent" output is the same as the original, there is no
+ * adjacent
+ */
if (!new_output || new_output == current_output) {
return NULL;
}
}
/* Otherwise, move to edge of next adjacent display, if possible */
- struct output *output = view_get_adjacent_output(view, direction);
+ struct output *output =
+ view_get_adjacent_output(view, direction, /* wrap */ false);
if (!output) {
return;
}
if (across_outputs && view->tiled == edge && view->maximized == VIEW_AXIS_NONE) {
/* We are already tiled for this edge; try to switch outputs */
- output = view_get_adjacent_output(view, edge);
+ output = view_get_adjacent_output(view, edge, /* wrap */ false);
if (!output) {
/*