This commit is contained in:
S. Christoffer Eliesen 2015-10-21 22:39:04 +00:00
commit c97a9f4184
4 changed files with 118 additions and 1 deletions

View file

@ -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

View file

@ -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) {

View file

@ -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) {

View file

@ -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;