|
|
@ -73,15 +73,13 @@ void wlr_output_layout_destroy(struct wlr_output_layout *layout) {
|
|
|
|
free(layout);
|
|
|
|
free(layout);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static struct wlr_box *output_layout_output_get_box(
|
|
|
|
static void output_layout_output_get_box(
|
|
|
|
struct wlr_output_layout_output *l_output) {
|
|
|
|
struct wlr_output_layout_output *l_output,
|
|
|
|
l_output->state->_box.x = l_output->x;
|
|
|
|
struct wlr_box *box) {
|
|
|
|
l_output->state->_box.y = l_output->y;
|
|
|
|
box->x = l_output->x;
|
|
|
|
int width, height;
|
|
|
|
box->y = l_output->y;
|
|
|
|
wlr_output_effective_resolution(l_output->output, &width, &height);
|
|
|
|
wlr_output_effective_resolution(l_output->output,
|
|
|
|
l_output->state->_box.width = width;
|
|
|
|
&box->width, &box->height);
|
|
|
|
l_output->state->_box.height = height;
|
|
|
|
|
|
|
|
return &l_output->state->_box;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -98,15 +96,17 @@ static void output_layout_reconfigure(struct wlr_output_layout *layout) {
|
|
|
|
// find the rightmost x coordinate occupied by a manually configured output
|
|
|
|
// find the rightmost x coordinate occupied by a manually configured output
|
|
|
|
// in the layout
|
|
|
|
// in the layout
|
|
|
|
struct wlr_output_layout_output *l_output;
|
|
|
|
struct wlr_output_layout_output *l_output;
|
|
|
|
|
|
|
|
struct wlr_box output_box;
|
|
|
|
|
|
|
|
|
|
|
|
wl_list_for_each(l_output, &layout->outputs, link) {
|
|
|
|
wl_list_for_each(l_output, &layout->outputs, link) {
|
|
|
|
if (l_output->state->auto_configured) {
|
|
|
|
if (l_output->state->auto_configured) {
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct wlr_box *box = output_layout_output_get_box(l_output);
|
|
|
|
output_layout_output_get_box(l_output, &output_box);
|
|
|
|
if (box->x + box->width > max_x) {
|
|
|
|
if (output_box.x + output_box.width > max_x) {
|
|
|
|
max_x = box->x + box->width;
|
|
|
|
max_x = output_box.x + output_box.width;
|
|
|
|
max_x_y = box->y;
|
|
|
|
max_x_y = output_box.y;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -120,10 +120,10 @@ static void output_layout_reconfigure(struct wlr_output_layout *layout) {
|
|
|
|
if (!l_output->state->auto_configured) {
|
|
|
|
if (!l_output->state->auto_configured) {
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
struct wlr_box *box = output_layout_output_get_box(l_output);
|
|
|
|
output_layout_output_get_box(l_output, &output_box);
|
|
|
|
l_output->x = max_x;
|
|
|
|
l_output->x = max_x;
|
|
|
|
l_output->y = max_x_y;
|
|
|
|
l_output->y = max_x_y;
|
|
|
|
max_x += box->width;
|
|
|
|
max_x += output_box.width;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
wlr_signal_emit_safe(&layout->events.change, layout);
|
|
|
|
wlr_signal_emit_safe(&layout->events.change, layout);
|
|
|
@ -242,8 +242,9 @@ bool wlr_output_layout_contains_point(struct wlr_output_layout *layout,
|
|
|
|
if (reference) {
|
|
|
|
if (reference) {
|
|
|
|
struct wlr_output_layout_output *l_output =
|
|
|
|
struct wlr_output_layout_output *l_output =
|
|
|
|
wlr_output_layout_get(layout, reference);
|
|
|
|
wlr_output_layout_get(layout, reference);
|
|
|
|
struct wlr_box *box = output_layout_output_get_box(l_output);
|
|
|
|
struct wlr_box output_box;
|
|
|
|
return wlr_box_contains_point(box, lx, ly);
|
|
|
|
output_layout_output_get_box(l_output, &output_box);
|
|
|
|
|
|
|
|
return wlr_box_contains_point(&output_box, lx, ly);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
return !!wlr_output_layout_output_at(layout, lx, ly);
|
|
|
|
return !!wlr_output_layout_output_at(layout, lx, ly);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -256,9 +257,9 @@ bool wlr_output_layout_intersects(struct wlr_output_layout *layout,
|
|
|
|
if (reference == NULL) {
|
|
|
|
if (reference == NULL) {
|
|
|
|
struct wlr_output_layout_output *l_output;
|
|
|
|
struct wlr_output_layout_output *l_output;
|
|
|
|
wl_list_for_each(l_output, &layout->outputs, link) {
|
|
|
|
wl_list_for_each(l_output, &layout->outputs, link) {
|
|
|
|
struct wlr_box *output_box =
|
|
|
|
struct wlr_box output_box;
|
|
|
|
output_layout_output_get_box(l_output);
|
|
|
|
output_layout_output_get_box(l_output, &output_box);
|
|
|
|
if (wlr_box_intersection(&out_box, output_box, target_lbox)) {
|
|
|
|
if (wlr_box_intersection(&out_box, &output_box, target_lbox)) {
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -270,8 +271,9 @@ bool wlr_output_layout_intersects(struct wlr_output_layout *layout,
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct wlr_box *output_box = output_layout_output_get_box(l_output);
|
|
|
|
struct wlr_box output_box;
|
|
|
|
return wlr_box_intersection(&out_box, output_box, target_lbox);
|
|
|
|
output_layout_output_get_box(l_output, &output_box);
|
|
|
|
|
|
|
|
return wlr_box_intersection(&out_box, &output_box, target_lbox);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -279,8 +281,9 @@ struct wlr_output *wlr_output_layout_output_at(struct wlr_output_layout *layout,
|
|
|
|
double lx, double ly) {
|
|
|
|
double lx, double ly) {
|
|
|
|
struct wlr_output_layout_output *l_output;
|
|
|
|
struct wlr_output_layout_output *l_output;
|
|
|
|
wl_list_for_each(l_output, &layout->outputs, link) {
|
|
|
|
wl_list_for_each(l_output, &layout->outputs, link) {
|
|
|
|
struct wlr_box *box = output_layout_output_get_box(l_output);
|
|
|
|
struct wlr_box output_box;
|
|
|
|
if (wlr_box_contains_point(box, lx, ly)) {
|
|
|
|
output_layout_output_get_box(l_output, &output_box);
|
|
|
|
|
|
|
|
if (wlr_box_contains_point(&output_box, lx, ly)) {
|
|
|
|
return l_output->output;
|
|
|
|
return l_output->output;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -342,8 +345,9 @@ void wlr_output_layout_closest_point(struct wlr_output_layout *layout,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double output_x, output_y, output_distance;
|
|
|
|
double output_x, output_y, output_distance;
|
|
|
|
struct wlr_box *box = output_layout_output_get_box(l_output);
|
|
|
|
struct wlr_box output_box;
|
|
|
|
wlr_box_closest_point(box, lx, ly, &output_x, &output_y);
|
|
|
|
output_layout_output_get_box(l_output, &output_box);
|
|
|
|
|
|
|
|
wlr_box_closest_point(&output_box, lx, ly, &output_x, &output_y);
|
|
|
|
|
|
|
|
|
|
|
|
// calculate squared distance suitable for comparison
|
|
|
|
// calculate squared distance suitable for comparison
|
|
|
|
output_distance =
|
|
|
|
output_distance =
|
|
|
@ -368,17 +372,17 @@ void wlr_output_layout_closest_point(struct wlr_output_layout *layout,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct wlr_box *wlr_output_layout_get_box(
|
|
|
|
void wlr_output_layout_get_box(struct wlr_output_layout *layout,
|
|
|
|
struct wlr_output_layout *layout, struct wlr_output *reference) {
|
|
|
|
struct wlr_output *reference, struct wlr_box *dest_box) {
|
|
|
|
struct wlr_output_layout_output *l_output;
|
|
|
|
struct wlr_output_layout_output *l_output;
|
|
|
|
if (reference) {
|
|
|
|
if (reference) {
|
|
|
|
// output extents
|
|
|
|
// output extents
|
|
|
|
l_output = wlr_output_layout_get(layout, reference);
|
|
|
|
l_output = wlr_output_layout_get(layout, reference);
|
|
|
|
|
|
|
|
|
|
|
|
if (l_output) {
|
|
|
|
if (l_output) {
|
|
|
|
return output_layout_output_get_box(l_output);
|
|
|
|
output_layout_output_get_box(l_output, dest_box);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
return NULL;
|
|
|
|
dest_box->width = dest_box->height = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
// layout extents
|
|
|
|
// layout extents
|
|
|
@ -387,31 +391,28 @@ struct wlr_box *wlr_output_layout_get_box(
|
|
|
|
min_x = min_y = INT_MAX;
|
|
|
|
min_x = min_y = INT_MAX;
|
|
|
|
max_x = max_y = INT_MIN;
|
|
|
|
max_x = max_y = INT_MIN;
|
|
|
|
wl_list_for_each(l_output, &layout->outputs, link) {
|
|
|
|
wl_list_for_each(l_output, &layout->outputs, link) {
|
|
|
|
struct wlr_box *box = output_layout_output_get_box(l_output);
|
|
|
|
struct wlr_box output_box;
|
|
|
|
if (box->x < min_x) {
|
|
|
|
output_layout_output_get_box(l_output, &output_box);
|
|
|
|
min_x = box->x;
|
|
|
|
if (output_box.x < min_x) {
|
|
|
|
|
|
|
|
min_x = output_box.x;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (box->y < min_y) {
|
|
|
|
if (output_box.y < min_y) {
|
|
|
|
min_y = box->y;
|
|
|
|
min_y = output_box.y;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (box->x + box->width > max_x) {
|
|
|
|
if (output_box.x + output_box.width > max_x) {
|
|
|
|
max_x = box->x + box->width;
|
|
|
|
max_x = output_box.x + output_box.width;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (box->y + box->height > max_y) {
|
|
|
|
if (output_box.y + output_box.height > max_y) {
|
|
|
|
max_y = box->y + box->height;
|
|
|
|
max_y = output_box.y + output_box.height;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
layout->state->_box.x = min_x;
|
|
|
|
dest_box->x = min_x;
|
|
|
|
layout->state->_box.y = min_y;
|
|
|
|
dest_box->y = min_y;
|
|
|
|
layout->state->_box.width = max_x - min_x;
|
|
|
|
dest_box->width = max_x - min_x;
|
|
|
|
layout->state->_box.height = max_y - min_y;
|
|
|
|
dest_box->height = max_y - min_y;
|
|
|
|
|
|
|
|
|
|
|
|
return &layout->state->_box;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// not reached
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void wlr_output_layout_add_auto(struct wlr_output_layout *layout,
|
|
|
|
void wlr_output_layout_add_auto(struct wlr_output_layout *layout,
|
|
|
@ -442,9 +443,10 @@ struct wlr_output *wlr_output_layout_get_center_output(
|
|
|
|
return NULL;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct wlr_box *extents = wlr_output_layout_get_box(layout, NULL);
|
|
|
|
struct wlr_box extents;
|
|
|
|
double center_x = extents->width / 2. + extents->x;
|
|
|
|
wlr_output_layout_get_box(layout, NULL, &extents);
|
|
|
|
double center_y = extents->height / 2. + extents->y;
|
|
|
|
double center_x = extents.width / 2. + extents.x;
|
|
|
|
|
|
|
|
double center_y = extents.height / 2. + extents.y;
|
|
|
|
|
|
|
|
|
|
|
|
double dest_x = 0, dest_y = 0;
|
|
|
|
double dest_x = 0, dest_y = 0;
|
|
|
|
wlr_output_layout_closest_point(layout, NULL, center_x, center_y,
|
|
|
|
wlr_output_layout_closest_point(layout, NULL, center_x, center_y,
|
|
|
@ -464,7 +466,8 @@ static struct wlr_output *wlr_output_layout_output_in_direction(
|
|
|
|
enum distance_selection_method distance_method) {
|
|
|
|
enum distance_selection_method distance_method) {
|
|
|
|
assert(reference);
|
|
|
|
assert(reference);
|
|
|
|
|
|
|
|
|
|
|
|
struct wlr_box *ref_box = wlr_output_layout_get_box(layout, reference);
|
|
|
|
struct wlr_box ref_box;
|
|
|
|
|
|
|
|
wlr_output_layout_get_box(layout, reference, &ref_box);
|
|
|
|
|
|
|
|
|
|
|
|
double min_distance = (distance_method == NEAREST) ? DBL_MAX : DBL_MIN;
|
|
|
|
double min_distance = (distance_method == NEAREST) ? DBL_MAX : DBL_MIN;
|
|
|
|
struct wlr_output *closest_output = NULL;
|
|
|
|
struct wlr_output *closest_output = NULL;
|
|
|
@ -473,21 +476,23 @@ static struct wlr_output *wlr_output_layout_output_in_direction(
|
|
|
|
if (reference != NULL && reference == l_output->output) {
|
|
|
|
if (reference != NULL && reference == l_output->output) {
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
struct wlr_box *box = output_layout_output_get_box(l_output);
|
|
|
|
|
|
|
|
|
|
|
|
struct wlr_box box;
|
|
|
|
|
|
|
|
output_layout_output_get_box(l_output, &box);
|
|
|
|
|
|
|
|
|
|
|
|
bool match = false;
|
|
|
|
bool match = false;
|
|
|
|
// test to make sure this output is in the given direction
|
|
|
|
// test to make sure this output is in the given direction
|
|
|
|
if (direction & WLR_DIRECTION_LEFT) {
|
|
|
|
if (direction & WLR_DIRECTION_LEFT) {
|
|
|
|
match = box->x + box->width <= ref_box->x || match;
|
|
|
|
match = box.x + box.width <= ref_box.x || match;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (direction & WLR_DIRECTION_RIGHT) {
|
|
|
|
if (direction & WLR_DIRECTION_RIGHT) {
|
|
|
|
match = box->x >= ref_box->x + ref_box->width || match;
|
|
|
|
match = box.x >= ref_box.x + ref_box.width || match;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (direction & WLR_DIRECTION_UP) {
|
|
|
|
if (direction & WLR_DIRECTION_UP) {
|
|
|
|
match = box->y + box->height <= ref_box->y || match;
|
|
|
|
match = box.y + box.height <= ref_box.y || match;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (direction & WLR_DIRECTION_DOWN) {
|
|
|
|
if (direction & WLR_DIRECTION_DOWN) {
|
|
|
|
match = box->y >= ref_box->y + ref_box->height || match;
|
|
|
|
match = box.y >= ref_box.y + ref_box.height || match;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!match) {
|
|
|
|
if (!match) {
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|