diff options
Diffstat (limited to 'sway/tree/layout.c')
-rw-r--r-- | sway/tree/layout.c | 96 |
1 files changed, 81 insertions, 15 deletions
diff --git a/sway/tree/layout.c b/sway/tree/layout.c index 5e8f4c56..be494791 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c | |||
@@ -364,7 +364,12 @@ static swayc_t *get_swayc_in_output_direction(swayc_t *output, | |||
364 | ws = swayc_parent_by_type(ws, C_WORKSPACE); | 364 | ws = swayc_parent_by_type(ws, C_WORKSPACE); |
365 | } | 365 | } |
366 | 366 | ||
367 | if (ws && ws->children->length > 0) { | 367 | if (ws == NULL) { |
368 | wlr_log(L_ERROR, "got an output without a workspace"); | ||
369 | return NULL; | ||
370 | } | ||
371 | |||
372 | if (ws->children->length > 0) { | ||
368 | switch (dir) { | 373 | switch (dir) { |
369 | case MOVE_LEFT: | 374 | case MOVE_LEFT: |
370 | // get most right child of new output | 375 | // get most right child of new output |
@@ -395,12 +400,61 @@ static swayc_t *get_swayc_in_output_direction(swayc_t *output, | |||
395 | } | 400 | } |
396 | } | 401 | } |
397 | 402 | ||
398 | return output; | 403 | return ws; |
399 | } | 404 | } |
400 | 405 | ||
401 | static void get_absolute_center_position(swayc_t *container, int *x, int *y) { | 406 | static void get_layout_center_position(swayc_t *container, int *x, int *y) { |
402 | *x = container->x + container->width/2; | 407 | // FIXME view coords are inconsistently referred to in layout/output systems |
403 | *y = container->y + container->height/2; | 408 | if (container->type == C_OUTPUT) { |
409 | *x = container->x + container->width/2; | ||
410 | *y = container->y + container->height/2; | ||
411 | } else { | ||
412 | swayc_t *output = swayc_parent_by_type(container, C_OUTPUT); | ||
413 | if (container->type == C_WORKSPACE) { | ||
414 | // Workspace coordinates are actually wrong/arbitrary, but should | ||
415 | // be same as output. | ||
416 | *x = output->x; | ||
417 | *y = output->y; | ||
418 | } else { | ||
419 | *x = output->x + container->x; | ||
420 | *y = output->y + container->y; | ||
421 | } | ||
422 | } | ||
423 | } | ||
424 | |||
425 | static bool sway_dir_to_wlr(enum movement_direction dir, enum wlr_direction *out) { | ||
426 | *out = 0; | ||
427 | switch (dir) { | ||
428 | case MOVE_UP: | ||
429 | *out = WLR_DIRECTION_UP; | ||
430 | break; | ||
431 | case MOVE_DOWN: | ||
432 | *out = WLR_DIRECTION_DOWN; | ||
433 | break; | ||
434 | case MOVE_LEFT: | ||
435 | *out = WLR_DIRECTION_LEFT; | ||
436 | break; | ||
437 | case MOVE_RIGHT: | ||
438 | *out = WLR_DIRECTION_RIGHT; | ||
439 | break; | ||
440 | default: | ||
441 | break; | ||
442 | } | ||
443 | |||
444 | return *out != 0; | ||
445 | } | ||
446 | |||
447 | static swayc_t *sway_output_from_wlr(struct wlr_output *output) { | ||
448 | if (output == NULL) { | ||
449 | return NULL; | ||
450 | } | ||
451 | for (int i = 0; i < root_container.children->length; ++i) { | ||
452 | swayc_t *o = root_container.children->items[i]; | ||
453 | if (o->type == C_OUTPUT && o->sway_output->wlr_output == output) { | ||
454 | return o; | ||
455 | } | ||
456 | } | ||
457 | return NULL; | ||
404 | } | 458 | } |
405 | 459 | ||
406 | static swayc_t *get_swayc_in_direction_under(swayc_t *container, | 460 | static swayc_t *get_swayc_in_direction_under(swayc_t *container, |
@@ -435,7 +489,7 @@ static swayc_t *get_swayc_in_direction_under(swayc_t *container, | |||
435 | // If moving to an adjacent output we need a starting position (since this | 489 | // If moving to an adjacent output we need a starting position (since this |
436 | // output might border to multiple outputs). | 490 | // output might border to multiple outputs). |
437 | //struct wlc_point abs_pos; | 491 | //struct wlc_point abs_pos; |
438 | //get_absolute_center_position(container, &abs_pos); | 492 | //get_layout_center_position(container, &abs_pos); |
439 | 493 | ||
440 | 494 | ||
441 | // TODO WLR fullscreen | 495 | // TODO WLR fullscreen |
@@ -443,7 +497,7 @@ static swayc_t *get_swayc_in_direction_under(swayc_t *container, | |||
443 | if (container->type == C_VIEW && swayc_is_fullscreen(container)) { | 497 | if (container->type == C_VIEW && swayc_is_fullscreen(container)) { |
444 | wlr_log(L_DEBUG, "Moving from fullscreen view, skipping to output"); | 498 | wlr_log(L_DEBUG, "Moving from fullscreen view, skipping to output"); |
445 | container = swayc_parent_by_type(container, C_OUTPUT); | 499 | container = swayc_parent_by_type(container, C_OUTPUT); |
446 | get_absolute_center_position(container, &abs_pos); | 500 | get_layout_center_position(container, &abs_pos); |
447 | swayc_t *output = swayc_adjacent_output(container, dir, &abs_pos, true); | 501 | swayc_t *output = swayc_adjacent_output(container, dir, &abs_pos, true); |
448 | return get_swayc_in_output_direction(output, dir); | 502 | return get_swayc_in_output_direction(output, dir); |
449 | } | 503 | } |
@@ -460,17 +514,29 @@ static swayc_t *get_swayc_in_direction_under(swayc_t *container, | |||
460 | int desired; | 514 | int desired; |
461 | int idx = index_child(container); | 515 | int idx = index_child(container); |
462 | if (parent->type == C_ROOT) { | 516 | if (parent->type == C_ROOT) { |
463 | // TODO | 517 | enum wlr_direction wlr_dir = 0; |
464 | /* | 518 | if (!sway_assert(sway_dir_to_wlr(dir, &wlr_dir), |
519 | "got invalid direction: %d", dir)) { | ||
520 | return NULL; | ||
521 | } | ||
522 | int lx, ly; | ||
523 | get_layout_center_position(container, &lx, &ly); | ||
465 | struct wlr_output_layout *layout = root_container.sway_root->output_layout; | 524 | struct wlr_output_layout *layout = root_container.sway_root->output_layout; |
466 | wlr_output_layout_adjacent_output(layout, container->sway_output->wlr_output); | 525 | struct wlr_output *wlr_adjacent = |
467 | //swayc_t *output = swayc_adjacent_output(container, dir, &abs_pos, true); | 526 | wlr_output_layout_adjacent_output(layout, wlr_dir, |
468 | if (!output || output == container) { | 527 | container->sway_output->wlr_output, lx, ly); |
528 | swayc_t *adjacent = sway_output_from_wlr(wlr_adjacent); | ||
529 | |||
530 | if (!adjacent || adjacent == container) { | ||
469 | return wrap_candidate; | 531 | return wrap_candidate; |
470 | } | 532 | } |
471 | wlr_log(L_DEBUG, "Moving between outputs"); | 533 | swayc_t *next = get_swayc_in_output_direction(adjacent, dir, seat); |
472 | return get_swayc_in_output_direction(output, dir, seat); | 534 | if (next->children->length) { |
473 | */ | 535 | // TODO consider floating children as well |
536 | return sway_seat_get_focus_inactive(seat, next); | ||
537 | } else { | ||
538 | return next; | ||
539 | } | ||
474 | } else { | 540 | } else { |
475 | if (dir == MOVE_LEFT || dir == MOVE_RIGHT) { | 541 | if (dir == MOVE_LEFT || dir == MOVE_RIGHT) { |
476 | if (parent->layout == L_HORIZ || parent->layout == L_TABBED) { | 542 | if (parent->layout == L_HORIZ || parent->layout == L_TABBED) { |