aboutsummaryrefslogtreecommitdiff
path: root/sway
diff options
context:
space:
mode:
Diffstat (limited to 'sway')
-rw-r--r--sway/tree/layout.c86
1 files changed, 73 insertions, 13 deletions
diff --git a/sway/tree/layout.c b/sway/tree/layout.c
index 5e8f4c56..6a574303 100644
--- a/sway/tree/layout.c
+++ b/sway/tree/layout.c
@@ -398,9 +398,58 @@ static swayc_t *get_swayc_in_output_direction(swayc_t *output,
return output;
}
-static void get_absolute_center_position(swayc_t *container, int *x, int *y) {
- *x = container->x + container->width/2;
- *y = container->y + container->height/2;
+static void get_layout_center_position(swayc_t *container, int *x, int *y) {
+ // FIXME view coords are inconsistently referred to in layout/output systems
+ if (container->type == C_OUTPUT) {
+ *x = container->x + container->width/2;
+ *y = container->y + container->height/2;
+ } else {
+ swayc_t *output = swayc_parent_by_type(container, C_OUTPUT);
+ if (container->type == C_WORKSPACE) {
+ // Workspace coordinates are actually wrong/arbitrary, but should
+ // be same as output.
+ *x = output->x;
+ *y = output->y;
+ } else {
+ *x = output->x + container->x;
+ *y = output->y + container->y;
+ }
+ }
+}
+
+static bool sway_dir_to_wlr(enum movement_direction dir, enum wlr_direction *out) {
+ *out = 0;
+ switch (dir) {
+ case MOVE_UP:
+ *out = WLR_DIRECTION_UP;
+ break;
+ case MOVE_DOWN:
+ *out = WLR_DIRECTION_DOWN;
+ break;
+ case MOVE_LEFT:
+ *out = WLR_DIRECTION_LEFT;
+ break;
+ case MOVE_RIGHT:
+ *out = WLR_DIRECTION_RIGHT;
+ break;
+ default:
+ break;
+ }
+
+ return *out != 0;
+}
+
+static swayc_t *sway_output_from_wlr(struct wlr_output *output) {
+ if (output == NULL) {
+ return NULL;
+ }
+ for (int i = 0; i < root_container.children->length; ++i) {
+ swayc_t *o = root_container.children->items[i];
+ if (o->type == C_OUTPUT && o->sway_output->wlr_output == output) {
+ return o;
+ }
+ }
+ return NULL;
}
static swayc_t *get_swayc_in_direction_under(swayc_t *container,
@@ -435,7 +484,7 @@ static swayc_t *get_swayc_in_direction_under(swayc_t *container,
// If moving to an adjacent output we need a starting position (since this
// output might border to multiple outputs).
//struct wlc_point abs_pos;
- //get_absolute_center_position(container, &abs_pos);
+ //get_layout_center_position(container, &abs_pos);
// TODO WLR fullscreen
@@ -443,7 +492,7 @@ static swayc_t *get_swayc_in_direction_under(swayc_t *container,
if (container->type == C_VIEW && swayc_is_fullscreen(container)) {
wlr_log(L_DEBUG, "Moving from fullscreen view, skipping to output");
container = swayc_parent_by_type(container, C_OUTPUT);
- get_absolute_center_position(container, &abs_pos);
+ get_layout_center_position(container, &abs_pos);
swayc_t *output = swayc_adjacent_output(container, dir, &abs_pos, true);
return get_swayc_in_output_direction(output, dir);
}
@@ -460,17 +509,28 @@ static swayc_t *get_swayc_in_direction_under(swayc_t *container,
int desired;
int idx = index_child(container);
if (parent->type == C_ROOT) {
- // TODO
- /*
+ enum wlr_direction wlr_dir = 0;
+ if (!sway_assert(sway_dir_to_wlr(dir, &wlr_dir),
+ "got invalid direction: %d", dir)) {
+ return NULL;
+ }
+ int lx, ly;
+ get_layout_center_position(container, &lx, &ly);
struct wlr_output_layout *layout = root_container.sway_root->output_layout;
- wlr_output_layout_adjacent_output(layout, container->sway_output->wlr_output);
- //swayc_t *output = swayc_adjacent_output(container, dir, &abs_pos, true);
- if (!output || output == container) {
+ struct wlr_output *wlr_adjacent =
+ wlr_output_layout_adjacent_output(layout, wlr_dir,
+ container->sway_output->wlr_output, lx, ly);
+ swayc_t *adjacent = sway_output_from_wlr(wlr_adjacent);
+
+ if (!adjacent || adjacent == container) {
return wrap_candidate;
}
- wlr_log(L_DEBUG, "Moving between outputs");
- return get_swayc_in_output_direction(output, dir, seat);
- */
+ // TODO descend into the focus-inactive of the physically closest
+ // view of the output
+ //swayc_t *new_con = get_swayc_in_output_direction(adjacent, dir, seat);
+ swayc_t *new_con = sway_seat_get_focus_inactive(seat, adjacent);
+ return new_con;
+
} else {
if (dir == MOVE_LEFT || dir == MOVE_RIGHT) {
if (parent->layout == L_HORIZ || parent->layout == L_TABBED) {