diff options
author | 2018-02-14 14:30:27 -0500 | |
---|---|---|
committer | 2018-02-14 14:30:27 -0500 | |
commit | 946d9459c57fc38b2536d40a45b7d4c9186b6734 (patch) | |
tree | 0fe98d3382dccb56a09f90ddeb5938d880234d1c /sway | |
parent | remove old focus member (diff) | |
download | sway-946d9459c57fc38b2536d40a45b7d4c9186b6734.tar.gz sway-946d9459c57fc38b2536d40a45b7d4c9186b6734.tar.zst sway-946d9459c57fc38b2536d40a45b7d4c9186b6734.zip |
get swayc in direction
Diffstat (limited to 'sway')
-rw-r--r-- | sway/input/seat.c | 10 | ||||
-rw-r--r-- | sway/tree/layout.c | 174 |
2 files changed, 184 insertions, 0 deletions
diff --git a/sway/input/seat.c b/sway/input/seat.c index 2abe8a1f..648e7914 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c | |||
@@ -358,6 +358,16 @@ swayc_t *sway_seat_get_focus(struct sway_seat *seat) { | |||
358 | return sway_seat_get_focus_inactive(seat, &root_container); | 358 | return sway_seat_get_focus_inactive(seat, &root_container); |
359 | } | 359 | } |
360 | 360 | ||
361 | swayc_t *sway_seat_get_focus_by_type(struct sway_seat *seat, | ||
362 | enum swayc_types type) { | ||
363 | swayc_t *focus = sway_seat_get_focus_inactive(seat, &root_container); | ||
364 | if (focus->type == type) { | ||
365 | return focus; | ||
366 | } | ||
367 | |||
368 | return swayc_parent_by_type(focus, type); | ||
369 | } | ||
370 | |||
361 | void sway_seat_set_config(struct sway_seat *seat, | 371 | void sway_seat_set_config(struct sway_seat *seat, |
362 | struct seat_config *seat_config) { | 372 | struct seat_config *seat_config) { |
363 | // clear configs | 373 | // clear configs |
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 | */ | ||
354 | static 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 | |||
402 | static 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 | |||
407 | static 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 | |||
519 | swayc_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 | } | ||