mirror of
https://github.com/swaywm/sway
synced 2024-11-18 00:24:17 +01:00
get swayc in direction
This commit is contained in:
parent
93084c9cf8
commit
946d9459c5
@ -60,6 +60,9 @@ swayc_t *sway_seat_get_focus(struct sway_seat *seat);
|
||||
|
||||
swayc_t *sway_seat_get_focus_inactive(struct sway_seat *seat, swayc_t *container);
|
||||
|
||||
swayc_t *sway_seat_get_focus_by_type(struct sway_seat *seat,
|
||||
enum swayc_types type);
|
||||
|
||||
void sway_seat_set_config(struct sway_seat *seat, struct seat_config *seat_config);
|
||||
|
||||
#endif
|
||||
|
@ -4,6 +4,18 @@
|
||||
#include <wlr/types/wlr_output_layout.h>
|
||||
#include "sway/container.h"
|
||||
|
||||
enum movement_direction {
|
||||
MOVE_LEFT,
|
||||
MOVE_RIGHT,
|
||||
MOVE_UP,
|
||||
MOVE_DOWN,
|
||||
MOVE_PARENT,
|
||||
MOVE_CHILD,
|
||||
MOVE_NEXT,
|
||||
MOVE_PREV,
|
||||
MOVE_FIRST
|
||||
};
|
||||
|
||||
struct sway_container;
|
||||
|
||||
struct sway_root {
|
||||
@ -25,5 +37,7 @@ struct sway_container *remove_child(struct sway_container *child);
|
||||
enum swayc_layouts default_layout(struct sway_container *output);
|
||||
void sort_workspaces(struct sway_container *output);
|
||||
void arrange_windows(struct sway_container *container, double width, double height);
|
||||
swayc_t *get_swayc_in_direction(swayc_t *container,
|
||||
struct sway_seat *seat, enum movement_direction dir);
|
||||
|
||||
#endif
|
||||
|
@ -358,6 +358,16 @@ swayc_t *sway_seat_get_focus(struct sway_seat *seat) {
|
||||
return sway_seat_get_focus_inactive(seat, &root_container);
|
||||
}
|
||||
|
||||
swayc_t *sway_seat_get_focus_by_type(struct sway_seat *seat,
|
||||
enum swayc_types type) {
|
||||
swayc_t *focus = sway_seat_get_focus_inactive(seat, &root_container);
|
||||
if (focus->type == type) {
|
||||
return focus;
|
||||
}
|
||||
|
||||
return swayc_parent_by_type(focus, type);
|
||||
}
|
||||
|
||||
void sway_seat_set_config(struct sway_seat *seat,
|
||||
struct seat_config *seat_config) {
|
||||
// clear configs
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "sway/layout.h"
|
||||
#include "sway/output.h"
|
||||
#include "sway/view.h"
|
||||
#include "sway/input/seat.h"
|
||||
#include "list.h"
|
||||
#include "log.h"
|
||||
|
||||
@ -346,3 +347,176 @@ void apply_vert_layout(swayc_t *container,
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get swayc in the direction of newly entered output.
|
||||
*/
|
||||
static swayc_t *get_swayc_in_output_direction(swayc_t *output,
|
||||
enum movement_direction dir, struct sway_seat *seat) {
|
||||
// XXX is this really a seat function or can we do it with the default
|
||||
// seat?
|
||||
if (!output) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
swayc_t *ws = sway_seat_get_focus_inactive(seat, output);
|
||||
if (ws->type != C_WORKSPACE) {
|
||||
ws = swayc_parent_by_type(ws, C_WORKSPACE);
|
||||
}
|
||||
|
||||
if (ws && ws->children->length > 0) {
|
||||
switch (dir) {
|
||||
case MOVE_LEFT:
|
||||
// get most right child of new output
|
||||
return ws->children->items[ws->children->length-1];
|
||||
case MOVE_RIGHT:
|
||||
// get most left child of new output
|
||||
return ws->children->items[0];
|
||||
case MOVE_UP:
|
||||
case MOVE_DOWN:
|
||||
{
|
||||
swayc_t *focused = sway_seat_get_focus_inactive(seat, ws);
|
||||
if (focused && focused->parent) {
|
||||
swayc_t *parent = focused->parent;
|
||||
if (parent->layout == L_VERT) {
|
||||
if (dir == MOVE_UP) {
|
||||
// get child furthest down on new output
|
||||
return parent->children->items[parent->children->length-1];
|
||||
} else if (dir == MOVE_DOWN) {
|
||||
// get child furthest up on new output
|
||||
return parent->children->items[0];
|
||||
}
|
||||
}
|
||||
return focused;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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 swayc_t *get_swayc_in_direction_under(swayc_t *container,
|
||||
enum movement_direction dir, struct sway_seat *seat, swayc_t *limit) {
|
||||
if (dir == MOVE_CHILD) {
|
||||
return sway_seat_get_focus_inactive(seat, container);
|
||||
}
|
||||
|
||||
swayc_t *parent = container->parent;
|
||||
if (dir == MOVE_PARENT) {
|
||||
if (parent->type == C_OUTPUT) {
|
||||
return NULL;
|
||||
} else {
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
|
||||
if (dir == MOVE_PREV || dir == MOVE_NEXT) {
|
||||
int focused_idx = index_child(container);
|
||||
if (focused_idx == -1) {
|
||||
return NULL;
|
||||
} else {
|
||||
int desired = (focused_idx + (dir == MOVE_NEXT ? 1 : -1)) %
|
||||
parent->children->length;
|
||||
if (desired < 0) {
|
||||
desired += parent->children->length;
|
||||
}
|
||||
return parent->children->items[desired];
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
|
||||
// TODO WLR fullscreen
|
||||
/*
|
||||
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);
|
||||
swayc_t *output = swayc_adjacent_output(container, dir, &abs_pos, true);
|
||||
return get_swayc_in_output_direction(output, dir);
|
||||
}
|
||||
if (container->type == C_WORKSPACE && container->fullscreen) {
|
||||
sway_log(L_DEBUG, "Moving to fullscreen view");
|
||||
return container->fullscreen;
|
||||
}
|
||||
*/
|
||||
|
||||
swayc_t *wrap_candidate = NULL;
|
||||
while (true) {
|
||||
// Test if we can even make a difference here
|
||||
bool can_move = false;
|
||||
int desired;
|
||||
int idx = index_child(container);
|
||||
if (parent->type == C_ROOT) {
|
||||
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) {
|
||||
return wrap_candidate;
|
||||
}
|
||||
wlr_log(L_DEBUG, "Moving between outputs");
|
||||
return get_swayc_in_output_direction(output, dir, seat);
|
||||
} else {
|
||||
if (dir == MOVE_LEFT || dir == MOVE_RIGHT) {
|
||||
if (parent->layout == L_HORIZ || parent->layout == L_TABBED) {
|
||||
can_move = true;
|
||||
desired = idx + (dir == MOVE_LEFT ? -1 : 1);
|
||||
}
|
||||
} else {
|
||||
if (parent->layout == L_VERT || parent->layout == L_STACKED) {
|
||||
can_move = true;
|
||||
desired = idx + (dir == MOVE_UP ? -1 : 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (can_move) {
|
||||
// TODO handle floating
|
||||
if (desired < 0 || desired >= parent->children->length) {
|
||||
can_move = false;
|
||||
int len = parent->children->length;
|
||||
if (!wrap_candidate && len > 1) {
|
||||
if (desired < 0) {
|
||||
wrap_candidate = parent->children->items[len-1];
|
||||
} else {
|
||||
wrap_candidate = parent->children->items[0];
|
||||
}
|
||||
if (config->force_focus_wrapping) {
|
||||
return wrap_candidate;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
wlr_log(L_DEBUG, "%s cont %d-%p dir %i sibling %d: %p", __func__,
|
||||
idx, container, dir, desired, parent->children->items[desired]);
|
||||
return parent->children->items[desired];
|
||||
}
|
||||
}
|
||||
|
||||
if (!can_move) {
|
||||
container = parent;
|
||||
parent = parent->parent;
|
||||
if (!parent || container == limit) {
|
||||
// wrapping is the last chance
|
||||
return wrap_candidate;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
swayc_t *get_swayc_in_direction(swayc_t *container, struct sway_seat *seat,
|
||||
enum movement_direction dir) {
|
||||
return get_swayc_in_direction_under(container, dir, seat, NULL);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user