mirror of
https://github.com/swaywm/sway.git
synced 2024-12-01 02:49:26 +00:00
Switch to adjacent output when hitting output edge.
container: Add neighbours struct (for output containers). In order to move the mouse between the outputs this struct is added to keep track of each outputs' neighbours. Neighbour relationships are updated during output creation/destruction and output command invocation (e.g. via config reload).
This commit is contained in:
parent
3e2579b22c
commit
9f45a67f2c
|
@ -27,6 +27,15 @@ enum swayc_layouts{
|
|||
L_LAYOUTS,
|
||||
};
|
||||
|
||||
// This is meant to be used by outputs who need to know who their adjacent
|
||||
// outputs are in order for "mouse between outputs" to work.
|
||||
//
|
||||
// (This is obviously a naïve implementation since it assumes a single,
|
||||
// perfectly aligned neighbour per edge.)
|
||||
struct swayc_neighbours {
|
||||
struct sway_container *top, *right, *bottom, *left;
|
||||
};
|
||||
|
||||
struct sway_container {
|
||||
wlc_handle handle;
|
||||
|
||||
|
@ -54,6 +63,8 @@ struct sway_container {
|
|||
|
||||
struct sway_container *parent;
|
||||
struct sway_container *focused;
|
||||
|
||||
struct swayc_neighbours *neighbours;
|
||||
};
|
||||
|
||||
enum visibility_mask {
|
||||
|
@ -70,6 +81,7 @@ swayc_t *new_container(swayc_t *child, enum swayc_layouts layout);
|
|||
swayc_t *new_view(swayc_t *sibling, wlc_handle handle);
|
||||
// Creates view as a new floating view which is in the active workspace
|
||||
swayc_t *new_floating_view(wlc_handle handle);
|
||||
void reset_neighbour_relations(swayc_t *output);
|
||||
|
||||
// Container Destroying
|
||||
|
||||
|
|
|
@ -310,6 +310,41 @@ void apply_output_config(struct output_config *oc, swayc_t *output) {
|
|||
}
|
||||
output->x = x;
|
||||
}
|
||||
|
||||
// Populate neighbours struct for given output. Will also update reverse
|
||||
// relations.
|
||||
reset_neighbour_relations(output);
|
||||
|
||||
for(int i = 0; i < root_container.children->length; ++i) {
|
||||
swayc_t *c = root_container.children->items[i];
|
||||
if (c == output || c->type != C_OUTPUT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO: This implementation is naïve: We assume all outputs are
|
||||
// perfectly aligned.
|
||||
if (c->y == output->y) {
|
||||
if (c->x + c->width == output->x) {
|
||||
sway_log(L_DEBUG, "%s is right of %s", output->name, c->name);
|
||||
c->neighbours->right = output;
|
||||
output->neighbours->left = c;
|
||||
} else if (output->x + output->width == c->x) {
|
||||
sway_log(L_DEBUG, "%s is left of %s", output->name, c->name);
|
||||
c->neighbours->left = output;
|
||||
output->neighbours->right = c;
|
||||
}
|
||||
} else if (c->x == output->x) {
|
||||
if (c->y + c->height == output->y) {
|
||||
sway_log(L_DEBUG, "%s is below %s", output->name, c->name);
|
||||
c->neighbours->bottom = output;
|
||||
output->neighbours->top = c;
|
||||
} else if (output->y + output->height == c->y) {
|
||||
sway_log(L_DEBUG, "%s is above %s", output->name, c->name);
|
||||
c->neighbours->top = output;
|
||||
output->neighbours->bottom = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char *do_var_replacement(char *str) {
|
||||
|
|
|
@ -19,9 +19,18 @@ static swayc_t *new_swayc(enum swayc_types type) {
|
|||
c->gaps = -1;
|
||||
c->layout = L_NONE;
|
||||
c->type = type;
|
||||
|
||||
if (type != C_VIEW) {
|
||||
c->children = create_list();
|
||||
}
|
||||
if (type == C_OUTPUT) {
|
||||
c->neighbours = malloc(sizeof(struct swayc_neighbours));
|
||||
c->neighbours->top = NULL;
|
||||
c->neighbours->right = NULL;
|
||||
c->neighbours->bottom = NULL;
|
||||
c->neighbours->left = NULL;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
@ -49,6 +58,9 @@ static void free_swayc(swayc_t *cont) {
|
|||
if (cont->name) {
|
||||
free(cont->name);
|
||||
}
|
||||
if (cont->neighbours) {
|
||||
free(cont->neighbours);
|
||||
}
|
||||
free(cont);
|
||||
}
|
||||
|
||||
|
@ -292,6 +304,8 @@ swayc_t *destroy_output(swayc_t *output) {
|
|||
arrange_windows(root_container.children->items[p], -1, -1);
|
||||
}
|
||||
}
|
||||
|
||||
reset_neighbour_relations(output);
|
||||
sway_log(L_DEBUG, "OUTPUT: Destroying output '%lu'", output->handle);
|
||||
free_swayc(output);
|
||||
return &root_container;
|
||||
|
@ -349,8 +363,29 @@ swayc_t *destroy_view(swayc_t *view) {
|
|||
return parent;
|
||||
}
|
||||
|
||||
// Container lookup
|
||||
// Modify container
|
||||
|
||||
// Make output inaccesible via its neighbours.
|
||||
void reset_neighbour_relations(swayc_t *output) {
|
||||
if (output->neighbours->top) {
|
||||
output->neighbours->top->neighbours->bottom = NULL;
|
||||
output->neighbours->top = NULL;
|
||||
}
|
||||
if (output->neighbours->right) {
|
||||
output->neighbours->right->neighbours->left = NULL;
|
||||
output->neighbours->right = NULL;
|
||||
}
|
||||
if (output->neighbours->bottom) {
|
||||
output->neighbours->bottom->neighbours->top = NULL;
|
||||
output->neighbours->bottom = NULL;
|
||||
}
|
||||
if (output->neighbours->left) {
|
||||
output->neighbours->left->neighbours->right = NULL;
|
||||
output->neighbours->left = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Container lookup
|
||||
|
||||
swayc_t *swayc_by_test(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data) {
|
||||
if (!container->children) {
|
||||
|
|
|
@ -353,6 +353,41 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier
|
|||
}
|
||||
|
||||
static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct wlc_origin *origin) {
|
||||
// Switch to adjacent output if touching output edge.
|
||||
//
|
||||
// Since this doesn't currently support moving windows between outputs we
|
||||
// don't do the switch if the pointer is in a mode.
|
||||
if (!pointer_state.mode) {
|
||||
swayc_t *output = swayc_active_output();
|
||||
|
||||
if (origin->x == 0) {
|
||||
swayc_t *adjacent = output->neighbours->left;
|
||||
if (adjacent) {
|
||||
sway_log(L_DEBUG, "%s: Left adjacent output is: %s", output->name, adjacent->name);
|
||||
workspace_switch(adjacent->focused);
|
||||
}
|
||||
} else if ((double)origin->x == output->width) {
|
||||
swayc_t *adjacent = output->neighbours->right;
|
||||
if (adjacent) {
|
||||
sway_log(L_DEBUG, "%s: Right adjacent output is: %s", output->name, adjacent->name);
|
||||
workspace_switch(adjacent->focused);
|
||||
}
|
||||
}
|
||||
if (origin->y == 0) {
|
||||
swayc_t *adjacent = output->neighbours->top;
|
||||
if (adjacent) {
|
||||
sway_log(L_DEBUG, "%s: Top adjacent output is: %s", output->name, adjacent->name);
|
||||
workspace_switch(adjacent->focused);
|
||||
}
|
||||
} else if ((double)origin->y == output->height) {
|
||||
swayc_t *adjacent = output->neighbours->bottom;
|
||||
if (adjacent) {
|
||||
sway_log(L_DEBUG, "%s: Bottom adjacent output is: %s", output->name, adjacent->name);
|
||||
workspace_switch(adjacent->focused);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update pointer origin
|
||||
pointer_state.delta.x = origin->x - pointer_state.origin.x;
|
||||
pointer_state.delta.y = origin->y - pointer_state.origin.y;
|
||||
|
|
Loading…
Reference in a new issue