aboutsummaryrefslogtreecommitdiffstats
path: root/sway/tree/layout.c
diff options
context:
space:
mode:
authorLibravatar Tony Crisci <tony@dubstepdish.com>2018-02-14 14:30:27 -0500
committerLibravatar Tony Crisci <tony@dubstepdish.com>2018-02-14 14:30:27 -0500
commit946d9459c57fc38b2536d40a45b7d4c9186b6734 (patch)
tree0fe98d3382dccb56a09f90ddeb5938d880234d1c /sway/tree/layout.c
parentremove old focus member (diff)
downloadsway-946d9459c57fc38b2536d40a45b7d4c9186b6734.tar.gz
sway-946d9459c57fc38b2536d40a45b7d4c9186b6734.tar.zst
sway-946d9459c57fc38b2536d40a45b7d4c9186b6734.zip
get swayc in direction
Diffstat (limited to 'sway/tree/layout.c')
-rw-r--r--sway/tree/layout.c174
1 files changed, 174 insertions, 0 deletions
diff --git a/sway/tree/layout.c b/sway/tree/layout.c
index 3651d279..9768279a 100644
--- a/sway/tree/layout.c
+++ b/sway/tree/layout.c
@@ -10,6 +10,7 @@
10#include "sway/layout.h" 10#include "sway/layout.h"
11#include "sway/output.h" 11#include "sway/output.h"
12#include "sway/view.h" 12#include "sway/view.h"
13#include "sway/input/seat.h"
13#include "list.h" 14#include "list.h"
14#include "log.h" 15#include "log.h"
15 16
@@ -346,3 +347,176 @@ void apply_vert_layout(swayc_t *container,
346 */ 347 */
347 } 348 }
348} 349}
350
351/**
352 * Get swayc in the direction of newly entered output.
353 */
354static swayc_t *get_swayc_in_output_direction(swayc_t *output,
355 enum movement_direction dir, struct sway_seat *seat) {
356 // XXX is this really a seat function or can we do it with the default
357 // seat?
358 if (!output) {
359 return NULL;
360 }
361
362 swayc_t *ws = sway_seat_get_focus_inactive(seat, output);
363 if (ws->type != C_WORKSPACE) {
364 ws = swayc_parent_by_type(ws, C_WORKSPACE);
365 }
366
367 if (ws && ws->children->length > 0) {
368 switch (dir) {
369 case MOVE_LEFT:
370 // get most right child of new output
371 return ws->children->items[ws->children->length-1];
372 case MOVE_RIGHT:
373 // get most left child of new output
374 return ws->children->items[0];
375 case MOVE_UP:
376 case MOVE_DOWN:
377 {
378 swayc_t *focused = sway_seat_get_focus_inactive(seat, ws);
379 if (focused && focused->parent) {
380 swayc_t *parent = focused->parent;
381 if (parent->layout == L_VERT) {
382 if (dir == MOVE_UP) {
383 // get child furthest down on new output
384 return parent->children->items[parent->children->length-1];
385 } else if (dir == MOVE_DOWN) {
386 // get child furthest up on new output
387 return parent->children->items[0];
388 }
389 }
390 return focused;
391 }
392 break;
393 }
394 default:
395 break;
396 }
397 }
398
399 return output;
400}
401
402static void get_absolute_center_position(swayc_t *container, int *x, int *y) {
403 *x = container->x + container->width/2;
404 *y = container->y + container->height/2;
405}
406
407static swayc_t *get_swayc_in_direction_under(swayc_t *container,
408 enum movement_direction dir, struct sway_seat *seat, swayc_t *limit) {
409 if (dir == MOVE_CHILD) {
410 return sway_seat_get_focus_inactive(seat, container);
411 }
412
413 swayc_t *parent = container->parent;
414 if (dir == MOVE_PARENT) {
415 if (parent->type == C_OUTPUT) {
416 return NULL;
417 } else {
418 return parent;
419 }
420 }
421
422 if (dir == MOVE_PREV || dir == MOVE_NEXT) {
423 int focused_idx = index_child(container);
424 if (focused_idx == -1) {
425 return NULL;
426 } else {
427 int desired = (focused_idx + (dir == MOVE_NEXT ? 1 : -1)) %
428 parent->children->length;
429 if (desired < 0) {
430 desired += parent->children->length;
431 }
432 return parent->children->items[desired];
433 }
434 }
435
436 // If moving to an adjacent output we need a starting position (since this
437 // output might border to multiple outputs).
438 //struct wlc_point abs_pos;
439 //get_absolute_center_position(container, &abs_pos);
440
441
442 // TODO WLR fullscreen
443 /*
444 if (container->type == C_VIEW && swayc_is_fullscreen(container)) {
445 wlr_log(L_DEBUG, "Moving from fullscreen view, skipping to output");
446 container = swayc_parent_by_type(container, C_OUTPUT);
447 get_absolute_center_position(container, &abs_pos);
448 swayc_t *output = swayc_adjacent_output(container, dir, &abs_pos, true);
449 return get_swayc_in_output_direction(output, dir);
450 }
451 if (container->type == C_WORKSPACE && container->fullscreen) {
452 sway_log(L_DEBUG, "Moving to fullscreen view");
453 return container->fullscreen;
454 }
455 */
456
457 swayc_t *wrap_candidate = NULL;
458 while (true) {
459 // Test if we can even make a difference here
460 bool can_move = false;
461 int desired;
462 int idx = index_child(container);
463 if (parent->type == C_ROOT) {
464 struct wlr_output_layout *layout = root_container.sway_root->output_layout;
465 wlr_output_layout_adjacent_output(layout, container->sway_output->wlr_output);
466 //swayc_t *output = swayc_adjacent_output(container, dir, &abs_pos, true);
467 if (!output || output == container) {
468 return wrap_candidate;
469 }
470 wlr_log(L_DEBUG, "Moving between outputs");
471 return get_swayc_in_output_direction(output, dir, seat);
472 } else {
473 if (dir == MOVE_LEFT || dir == MOVE_RIGHT) {
474 if (parent->layout == L_HORIZ || parent->layout == L_TABBED) {
475 can_move = true;
476 desired = idx + (dir == MOVE_LEFT ? -1 : 1);
477 }
478 } else {
479 if (parent->layout == L_VERT || parent->layout == L_STACKED) {
480 can_move = true;
481 desired = idx + (dir == MOVE_UP ? -1 : 1);
482 }
483 }
484 }
485
486 if (can_move) {
487 // TODO handle floating
488 if (desired < 0 || desired >= parent->children->length) {
489 can_move = false;
490 int len = parent->children->length;
491 if (!wrap_candidate && len > 1) {
492 if (desired < 0) {
493 wrap_candidate = parent->children->items[len-1];
494 } else {
495 wrap_candidate = parent->children->items[0];
496 }
497 if (config->force_focus_wrapping) {
498 return wrap_candidate;
499 }
500 }
501 } else {
502 wlr_log(L_DEBUG, "%s cont %d-%p dir %i sibling %d: %p", __func__,
503 idx, container, dir, desired, parent->children->items[desired]);
504 return parent->children->items[desired];
505 }
506 }
507
508 if (!can_move) {
509 container = parent;
510 parent = parent->parent;
511 if (!parent || container == limit) {
512 // wrapping is the last chance
513 return wrap_candidate;
514 }
515 }
516 }
517}
518
519swayc_t *get_swayc_in_direction(swayc_t *container, struct sway_seat *seat,
520 enum movement_direction dir) {
521 return get_swayc_in_direction_under(container, dir, seat, NULL);
522}