diff --git a/examples/output-layout.c b/examples/output-layout.c index bdc8d352e4..4f7b1c3e0f 100644 --- a/examples/output-layout.c +++ b/examples/output-layout.c @@ -76,10 +76,10 @@ static void animate_cat(struct sample_state *sample, if (ur_collision && ul_collision && ll_collision && lr_collision) { // oops we went off the screen somehow - struct wlr_output_layout_output *l_output = - wlr_output_layout_get(sample->layout, output); - sample->x_offs = l_output->x + 20; - sample->y_offs = l_output->y + 20; + struct wlr_box box; + wlr_output_layout_get_box(sample->layout, output, &box); + sample->x_offs = box.x + 20; + sample->y_offs = box.y + 20; } else if (ur_collision && ul_collision) { sample->y_vel = fabs(sample->y_vel); } else if (lr_collision && ll_collision) { diff --git a/include/types/wlr_output_layout.h b/include/types/wlr_output_layout.h new file mode 100644 index 0000000000..968fdc485e --- /dev/null +++ b/include/types/wlr_output_layout.h @@ -0,0 +1,26 @@ +#ifndef TYPES_WLR_OUTPUT_LAYOUT_H +#define TYPES_WLR_OUTPUT_LAYOUT_H + +#include + +struct wlr_output_layout_output { + struct wlr_output_layout *layout; + struct wlr_output *output; + int x, y; + struct wl_list link; + bool auto_configured; + + struct { + struct wl_signal destroy; + } events; + + struct wl_listener mode; + struct wl_listener scale; + struct wl_listener transform; + struct wl_listener output_destroy; +}; + +struct wlr_output_layout_output *wlr_output_layout_get( + struct wlr_output_layout *layout, struct wlr_output *reference); + +#endif diff --git a/include/wlr/types/wlr_output_layout.h b/include/wlr/types/wlr_output_layout.h index 759c8ccf4f..0308a1a800 100644 --- a/include/wlr/types/wlr_output_layout.h +++ b/include/wlr/types/wlr_output_layout.h @@ -21,19 +21,6 @@ struct wlr_output_layout { void *data; }; -struct wlr_output_layout_output_state; - -struct wlr_output_layout_output { - struct wlr_output *output; - int x, y; - struct wl_list link; - struct wlr_output_layout_output_state *state; - - struct { - struct wl_signal destroy; - } events; -}; - /** * Creates a wlr_output_layout, which can be used to describing outputs in * physical space relative to one another, and perform various useful operations @@ -43,9 +30,6 @@ struct wlr_output_layout *wlr_output_layout_create(); void wlr_output_layout_destroy(struct wlr_output_layout *layout); -struct wlr_output_layout_output *wlr_output_layout_get( - struct wlr_output_layout *layout, struct wlr_output *reference); - struct wlr_output *wlr_output_layout_output_at(struct wlr_output_layout *layout, double lx, double ly); @@ -82,10 +66,11 @@ void wlr_output_layout_closest_point(struct wlr_output_layout *layout, /** * Get the box of the layout for the given reference output in layout * coordinates. If `reference` is NULL, the box will be for the extents of the - * entire layout. + * entire layout. Returns false if the reference output is present and not in + * the layout or there are no outputs in the layout. */ -struct wlr_box *wlr_output_layout_get_box( - struct wlr_output_layout *layout, struct wlr_output *reference); +bool wlr_output_layout_get_box(struct wlr_output_layout *layout, + struct wlr_output *reference, struct wlr_box *box); /** * Add an auto configured output to the layout. This will place the output in a diff --git a/rootston/desktop.c b/rootston/desktop.c index a6f9e9a078..2ab496e030 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -199,13 +199,13 @@ void view_arrange_maximized(struct roots_view *view) { struct wlr_output *output = view_get_output(view); struct roots_output *roots_output = output->data; - struct wlr_box *output_box = - wlr_output_layout_get_box(view->desktop->layout, output); + struct wlr_box output_box; + wlr_output_layout_get_box(view->desktop->layout, output, &output_box); struct wlr_box usable_area; memcpy(&usable_area, &roots_output->usable_area, sizeof(struct wlr_box)); - usable_area.x += output_box->x; - usable_area.y += output_box->y; + usable_area.x += output_box.x; + usable_area.y += output_box.y; view_move_resize(view, usable_area.x, usable_area.y, usable_area.width, usable_area.height); @@ -274,10 +274,10 @@ void view_set_fullscreen(struct roots_view *view, bool fullscreen, view->saved.width = view_box.width; view->saved.height = view_box.height; - struct wlr_box *output_box = - wlr_output_layout_get_box(view->desktop->layout, output); - view_move_resize(view, output_box->x, output_box->y, output_box->width, - output_box->height); + struct wlr_box output_box; + wlr_output_layout_get_box(view->desktop->layout, output, &output_box); + view_move_resize(view, output_box.x, output_box.y, output_box.width, + output_box.height); view_rotate(view, 0); roots_output->fullscreen_view = view; @@ -341,14 +341,14 @@ bool view_center(struct roots_view *view) { return false; } - const struct wlr_output_layout_output *l_output = - wlr_output_layout_get(desktop->layout, output); + struct wlr_box layout_box; + wlr_output_layout_get_box(desktop->layout, output, &layout_box); int width, height; wlr_output_effective_resolution(output, &width, &height); - double view_x = (double)(width - box.width) / 2 + l_output->x; - double view_y = (double)(height - box.height) / 2 + l_output->y; + double view_x = (double)(width - box.width) / 2 + layout_box.x; + double view_y = (double)(height - box.height) / 2 + layout_box.y; view_move(view, view_x, view_y); return true; @@ -717,10 +717,10 @@ static void handle_layout_change(struct wl_listener *listener, void *data) { return; } - struct wlr_box *center_output_box = - wlr_output_layout_get_box(desktop->layout, center_output); - double center_x = center_output_box->x + center_output_box->width/2; - double center_y = center_output_box->y + center_output_box->height/2; + struct wlr_box center_output_box; + wlr_output_layout_get_box(desktop->layout, center_output, ¢er_output_box); + double center_x = center_output_box.x + center_output_box.width/2; + double center_y = center_output_box.y + center_output_box.height/2; struct roots_view *view; wl_list_for_each(view, &desktop->views, link) { diff --git a/rootston/output.c b/rootston/output.c index 353d431f46..0f759e0118 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -402,8 +402,8 @@ static void render_output(struct roots_output *output) { float clear_color[] = {0.25f, 0.25f, 0.25f, 1.0f}; - const struct wlr_box *output_box = - wlr_output_layout_get_box(desktop->layout, wlr_output); + struct wlr_box output_box; + wlr_output_layout_get_box(desktop->layout, wlr_output, &output_box); // Check if we can delegate the fullscreen surface to the output if (output->fullscreen_view != NULL && @@ -413,10 +413,10 @@ static void render_output(struct roots_output *output) { // Make sure the view is centered on screen struct wlr_box view_box; view_get_box(view, &view_box); - double view_x = (double)(output_box->width - view_box.width) / 2 + - output_box->x; - double view_y = (double)(output_box->height - view_box.height) / 2 + - output_box->y; + double view_x = (double)(output_box.width - view_box.width) / 2 + + output_box.x; + double view_y = (double)(output_box.height - view_box.height) / 2 + + output_box.y; view_move(view, view_x, view_y); if (has_standalone_surface(view)) { @@ -468,9 +468,9 @@ static void render_output(struct roots_output *output) { wlr_renderer_clear(renderer, clear_color); } - render_layer(output, output_box, &data, + render_layer(output, &output_box, &data, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]); - render_layer(output, output_box, &data, + render_layer(output, &output_box, &data, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]); // If a view is fullscreen on this output, render it @@ -502,7 +502,7 @@ static void render_output(struct roots_output *output) { render_view(view, &data); } // Render top layer above shell views - render_layer(output, output_box, &data, + render_layer(output, &output_box, &data, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); } @@ -511,7 +511,7 @@ static void render_output(struct roots_output *output) { drag_icons_for_each_surface(server->input, render_surface, &data.layout, &data); - render_layer(output, output_box, &data, + render_layer(output, &output_box, &data, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); renderer_end: @@ -621,10 +621,10 @@ static void damage_whole_surface(struct wlr_surface *surface, int sx, int sy, void output_damage_whole_local_surface(struct roots_output *output, struct wlr_surface *surface, double ox, double oy, float rotation) { - struct wlr_output_layout_output *layout = wlr_output_layout_get( - output->desktop->layout, output->wlr_output); + struct wlr_box box; + wlr_output_layout_get_box(output->desktop->layout, output->wlr_output, &box); struct damage_data data = { .output = output }; - surface_for_each_surface(surface, ox + layout->x, oy + layout->y, 0, + surface_for_each_surface(surface, ox + box.x, oy + box.y, 0, &data.layout, damage_whole_surface, &data); } @@ -703,10 +703,10 @@ static void damage_from_surface(struct wlr_surface *surface, int sx, int sy, void output_damage_from_local_surface(struct roots_output *output, struct wlr_surface *surface, double ox, double oy, float rotation) { - struct wlr_output_layout_output *layout = wlr_output_layout_get( - output->desktop->layout, output->wlr_output); + struct wlr_box box; + wlr_output_layout_get_box(output->desktop->layout, output->wlr_output, &box); struct damage_data data = { .output = output }; - surface_for_each_surface(surface, ox + layout->x, oy + layout->y, 0, + surface_for_each_surface(surface, ox + box.x, oy + box.y, 0, &data.layout, damage_from_surface, &data); } diff --git a/types/wlr_cursor.c b/types/wlr_cursor.c index 32d990cf54..1c1665358b 100644 --- a/types/wlr_cursor.c +++ b/types/wlr_cursor.c @@ -9,6 +9,7 @@ #include #include #include "util/signal.h" +#include "types/wlr_output_layout.h" struct wlr_cursor_device { struct wlr_cursor *cursor; @@ -203,46 +204,51 @@ static void cursor_warp_unchecked(struct wlr_cursor *cur, * Absolute movement for touch and pen devices will be relative to this box and * pointer movement will be constrained to this box. * - * If none of these are set, returns NULL and absolute movement should be + * If none of these are set, returns false and absolute movement should be * relative to the extents of the layout. */ -static struct wlr_box *get_mapping(struct wlr_cursor *cur, - struct wlr_input_device *dev) { +static bool get_mapping(struct wlr_cursor *cur, + struct wlr_input_device *dev, struct wlr_box *box) { assert(cur->state->layout); struct wlr_cursor_device *c_device = get_cursor_device(cur, dev); if (c_device) { if (c_device->mapped_box) { - return c_device->mapped_box; + memcpy(box, c_device->mapped_box, sizeof(struct wlr_box)); + return true; } - if (c_device->mapped_output) { - return wlr_output_layout_get_box(cur->state->layout, - c_device->mapped_output); + if (c_device->mapped_output && + wlr_output_layout_get_box(cur->state->layout, + c_device->mapped_output, box)) { + return true; } } if (cur->state->mapped_box) { - return cur->state->mapped_box; + memcpy(box, cur->state->mapped_box, sizeof(struct wlr_box)); + return true; } - if (cur->state->mapped_output) { - return wlr_output_layout_get_box(cur->state->layout, - cur->state->mapped_output); + + if (cur->state->mapped_output && + wlr_output_layout_get_box(cur->state->layout, + cur->state->mapped_output, box)) { + return true; } - return NULL; + return false; } bool wlr_cursor_warp(struct wlr_cursor *cur, struct wlr_input_device *dev, double lx, double ly) { assert(cur->state->layout); + struct wlr_box mapping; bool result = false; - struct wlr_box *mapping = get_mapping(cur, dev); - if (mapping) { - result = wlr_box_contains_point(mapping, lx, ly); + if (get_mapping(cur, dev, &mapping)) { + result = wlr_box_contains_point(&mapping, lx, ly); } else { - result = wlr_output_layout_contains_point(cur->state->layout, NULL, - lx, ly); + result = + wlr_output_layout_contains_point(cur->state->layout, NULL, lx, ly); } if (result) { @@ -254,9 +260,9 @@ bool wlr_cursor_warp(struct wlr_cursor *cur, struct wlr_input_device *dev, static void cursor_warp_closest(struct wlr_cursor *cur, struct wlr_input_device *dev, double lx, double ly) { - struct wlr_box *mapping = get_mapping(cur, dev); - if (mapping) { - wlr_box_closest_point(mapping, lx, ly, &lx, &ly); + struct wlr_box mapping; + if (get_mapping(cur, dev, &mapping)) { + wlr_box_closest_point(&mapping, lx, ly, &lx, &ly); } else { wlr_output_layout_closest_point(cur->state->layout, NULL, lx, ly, &lx, &ly); @@ -270,13 +276,17 @@ void wlr_cursor_absolute_to_layout_coords(struct wlr_cursor *cur, double *lx, double *ly) { assert(cur->state->layout); - struct wlr_box *mapping = get_mapping(cur, dev); - if (!mapping) { - mapping = wlr_output_layout_get_box(cur->state->layout, NULL); + struct wlr_box mapping; + if (!get_mapping(cur, dev, &mapping) && + !wlr_output_layout_get_box(cur->state->layout, NULL, &mapping)) { + // no outputs in the layout + *lx = 0; + *ly = 0; + return; } - *lx = !isnan(x) ? mapping->width * x + mapping->x : cur->x; - *ly = !isnan(y) ? mapping->height * y + mapping->y : cur->y; + *lx = !isnan(x) ? mapping.width * x + mapping.x : cur->x; + *ly = !isnan(y) ? mapping.height * y + mapping.y : cur->y; } void wlr_cursor_warp_absolute(struct wlr_cursor *cur, diff --git a/types/wlr_output_layout.c b/types/wlr_output_layout.c index bb1d399a3e..bac87d6a30 100644 --- a/types/wlr_output_layout.c +++ b/types/wlr_output_layout.c @@ -7,24 +7,12 @@ #include #include #include "util/signal.h" +#include "types/wlr_output_layout.h" struct wlr_output_layout_state { struct wlr_box _box; // should never be read directly, use the getter }; -struct wlr_output_layout_output_state { - struct wlr_output_layout *layout; - struct wlr_output_layout_output *l_output; - - struct wlr_box _box; // should never be read directly, use the getter - bool auto_configured; - - struct wl_listener mode; - struct wl_listener scale; - struct wl_listener transform; - struct wl_listener output_destroy; -}; - struct wlr_output_layout *wlr_output_layout_create(void) { struct wlr_output_layout *layout = calloc(1, sizeof(struct wlr_output_layout)); @@ -49,12 +37,11 @@ static void output_layout_output_destroy( struct wlr_output_layout_output *l_output) { wlr_signal_emit_safe(&l_output->events.destroy, l_output); wlr_output_destroy_global(l_output->output); - wl_list_remove(&l_output->state->mode.link); - wl_list_remove(&l_output->state->scale.link); - wl_list_remove(&l_output->state->transform.link); - wl_list_remove(&l_output->state->output_destroy.link); + wl_list_remove(&l_output->mode.link); + wl_list_remove(&l_output->scale.link); + wl_list_remove(&l_output->transform.link); + wl_list_remove(&l_output->output_destroy.link); wl_list_remove(&l_output->link); - free(l_output->state); free(l_output); } @@ -74,15 +61,15 @@ void wlr_output_layout_destroy(struct wlr_output_layout *layout) { free(layout); } -static struct wlr_box *output_layout_output_get_box( - struct wlr_output_layout_output *l_output) { - l_output->state->_box.x = l_output->x; - l_output->state->_box.y = l_output->y; +void output_layout_output_get_box( + struct wlr_output_layout_output *l_output, struct wlr_box *box) { + assert(l_output != NULL); + box->x = l_output->x; + box->y = l_output->y; int width, height; wlr_output_effective_resolution(l_output->output, &width, &height); - l_output->state->_box.width = width; - l_output->state->_box.height = height; - return &l_output->state->_box; + box->width = width; + box->height = height; } /** @@ -100,14 +87,15 @@ static void output_layout_reconfigure(struct wlr_output_layout *layout) { // in the layout struct wlr_output_layout_output *l_output; wl_list_for_each(l_output, &layout->outputs, link) { - if (l_output->state->auto_configured) { + if (l_output->auto_configured) { continue; } - struct wlr_box *box = output_layout_output_get_box(l_output); - if (box->x + box->width > max_x) { - max_x = box->x + box->width; - max_x_y = box->y; + struct wlr_box box; + output_layout_output_get_box(l_output, &box); + if (box.x + box.width > max_x) { + max_x = box.x + box.width; + max_x_y = box.y; } } @@ -118,13 +106,14 @@ static void output_layout_reconfigure(struct wlr_output_layout *layout) { } wl_list_for_each(l_output, &layout->outputs, link) { - if (!l_output->state->auto_configured) { + if (!l_output->auto_configured) { continue; } - struct wlr_box *box = output_layout_output_get_box(l_output); + struct wlr_box box; + output_layout_output_get_box(l_output, &box); l_output->x = max_x; l_output->y = max_x_y; - max_x += box->width; + max_x += box.width; } wl_list_for_each(l_output, &layout->outputs, link) { @@ -135,28 +124,28 @@ static void output_layout_reconfigure(struct wlr_output_layout *layout) { } static void handle_output_mode(struct wl_listener *listener, void *data) { - struct wlr_output_layout_output_state *state = - wl_container_of(listener, state, mode); - output_layout_reconfigure(state->layout); + struct wlr_output_layout_output *l_output = + wl_container_of(listener, l_output, mode); + output_layout_reconfigure(l_output->layout); } static void handle_output_scale(struct wl_listener *listener, void *data) { - struct wlr_output_layout_output_state *state = - wl_container_of(listener, state, scale); - output_layout_reconfigure(state->layout); + struct wlr_output_layout_output *l_output = + wl_container_of(listener, l_output, scale); + output_layout_reconfigure(l_output->layout); } static void handle_output_transform(struct wl_listener *listener, void *data) { - struct wlr_output_layout_output_state *state = - wl_container_of(listener, state, transform); - output_layout_reconfigure(state->layout); + struct wlr_output_layout_output *l_output = + wl_container_of(listener, l_output, transform); + output_layout_reconfigure(l_output->layout); } static void handle_output_destroy(struct wl_listener *listener, void *data) { - struct wlr_output_layout_output_state *state = - wl_container_of(listener, state, output_destroy); - struct wlr_output_layout *layout = state->layout; - output_layout_output_destroy(state->l_output); + struct wlr_output_layout_output *l_output = + wl_container_of(listener, l_output, output_destroy); + struct wlr_output_layout *layout = l_output->layout; + output_layout_output_destroy(l_output); output_layout_reconfigure(layout); } @@ -167,25 +156,20 @@ static struct wlr_output_layout_output *output_layout_output_create( if (l_output == NULL) { return NULL; } - l_output->state = calloc(1, sizeof(struct wlr_output_layout_output_state)); - if (l_output->state == NULL) { - free(l_output); - return NULL; - } - l_output->state->l_output = l_output; - l_output->state->layout = layout; + + l_output->layout = layout; l_output->output = output; wl_signal_init(&l_output->events.destroy); wl_list_insert(&layout->outputs, &l_output->link); - wl_signal_add(&output->events.mode, &l_output->state->mode); - l_output->state->mode.notify = handle_output_mode; - wl_signal_add(&output->events.scale, &l_output->state->scale); - l_output->state->scale.notify = handle_output_scale; - wl_signal_add(&output->events.transform, &l_output->state->transform); - l_output->state->transform.notify = handle_output_transform; - wl_signal_add(&output->events.destroy, &l_output->state->output_destroy); - l_output->state->output_destroy.notify = handle_output_destroy; + wl_signal_add(&output->events.mode, &l_output->mode); + l_output->mode.notify = handle_output_mode; + wl_signal_add(&output->events.scale, &l_output->scale); + l_output->scale.notify = handle_output_scale; + wl_signal_add(&output->events.transform, &l_output->transform); + l_output->transform.notify = handle_output_transform; + wl_signal_add(&output->events.destroy, &l_output->output_destroy); + l_output->output_destroy.notify = handle_output_destroy; return l_output; } @@ -203,7 +187,7 @@ void wlr_output_layout_add(struct wlr_output_layout *layout, } l_output->x = lx; l_output->y = ly; - l_output->state->auto_configured = false; + l_output->auto_configured = false; output_layout_reconfigure(layout); wlr_output_create_global(output); wlr_signal_emit_safe(&layout->events.add, l_output); @@ -225,8 +209,14 @@ bool wlr_output_layout_contains_point(struct wlr_output_layout *layout, if (reference) { struct wlr_output_layout_output *l_output = wlr_output_layout_get(layout, reference); - struct wlr_box *box = output_layout_output_get_box(l_output); - return wlr_box_contains_point(box, lx, ly); + + if (l_output == NULL) { + return false; + } + + struct wlr_box box; + output_layout_output_get_box(l_output, &box); + return wlr_box_contains_point(&box, lx, ly); } else { return !!wlr_output_layout_output_at(layout, lx, ly); } @@ -239,9 +229,9 @@ bool wlr_output_layout_intersects(struct wlr_output_layout *layout, if (reference == NULL) { struct wlr_output_layout_output *l_output; wl_list_for_each(l_output, &layout->outputs, link) { - struct wlr_box *output_box = - output_layout_output_get_box(l_output); - if (wlr_box_intersection(output_box, target_lbox, &out_box)) { + struct wlr_box output_box; + output_layout_output_get_box(l_output, &output_box); + if (wlr_box_intersection(&output_box, target_lbox, &out_box)) { return true; } } @@ -253,8 +243,9 @@ bool wlr_output_layout_intersects(struct wlr_output_layout *layout, return false; } - struct wlr_box *output_box = output_layout_output_get_box(l_output); - return wlr_box_intersection(output_box, target_lbox, &out_box); + struct wlr_box output_box; + output_layout_output_get_box(l_output, &output_box); + return wlr_box_intersection(&output_box, target_lbox, &out_box); } } @@ -262,8 +253,9 @@ struct wlr_output *wlr_output_layout_output_at(struct wlr_output_layout *layout, double lx, double ly) { struct wlr_output_layout_output *l_output; wl_list_for_each(l_output, &layout->outputs, link) { - struct wlr_box *box = output_layout_output_get_box(l_output); - if (wlr_box_contains_point(box, lx, ly)) { + struct wlr_box box; + output_layout_output_get_box(l_output, &box); + if (wlr_box_contains_point(&box, lx, ly)) { return l_output->output; } } @@ -277,7 +269,7 @@ void wlr_output_layout_move(struct wlr_output_layout *layout, if (l_output) { l_output->x = lx; l_output->y = ly; - l_output->state->auto_configured = false; + l_output->auto_configured = false; output_layout_reconfigure(layout); } else { wlr_log(L_ERROR, "output not found in this layout: %s", output->name); @@ -325,8 +317,9 @@ void wlr_output_layout_closest_point(struct wlr_output_layout *layout, } double output_x, output_y, output_distance; - struct wlr_box *box = output_layout_output_get_box(l_output); - wlr_box_closest_point(box, lx, ly, &output_x, &output_y); + struct wlr_box box; + output_layout_output_get_box(l_output, &box); + wlr_box_closest_point(&box, lx, ly, &output_x, &output_y); // calculate squared distance suitable for comparison output_distance = @@ -351,24 +344,32 @@ void wlr_output_layout_closest_point(struct wlr_output_layout *layout, } } -struct wlr_box *wlr_output_layout_get_box( - struct wlr_output_layout *layout, struct wlr_output *reference) { +bool wlr_output_layout_get_box(struct wlr_output_layout *layout, + struct wlr_output *reference, struct wlr_box *box) { + assert(layout != NULL); + + if (wl_list_empty(&layout->outputs)) { + return false; + } + struct wlr_output_layout_output *l_output; if (reference) { // output extents l_output = wlr_output_layout_get(layout, reference); if (l_output) { - return output_layout_output_get_box(l_output); + output_layout_output_get_box(l_output, box); + return true; } else { - return NULL; + return false; } } else { // layout extents int min_x = INT_MAX, min_y = INT_MAX; int max_x = INT_MIN, max_y = INT_MIN; 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; + output_layout_output_get_box(l_output, &output_box); if (box->x < min_x) { min_x = box->x; @@ -384,12 +385,12 @@ struct wlr_box *wlr_output_layout_get_box( } } - layout->state->_box.x = min_x; - layout->state->_box.y = min_y; - layout->state->_box.width = max_x - min_x; - layout->state->_box.height = max_y - min_y; + box->x = min_x; + box->y = min_y; + box->width = max_x - min_x; + box->height = max_y - min_y; - return &layout->state->_box; + return true; } // not reached @@ -407,7 +408,7 @@ void wlr_output_layout_add_auto(struct wlr_output_layout *layout, } } - l_output->state->auto_configured = true; + l_output->auto_configured = true; output_layout_reconfigure(layout); wlr_output_create_global(output); wlr_signal_emit_safe(&layout->events.add, l_output); @@ -415,13 +416,12 @@ void wlr_output_layout_add_auto(struct wlr_output_layout *layout, struct wlr_output *wlr_output_layout_get_center_output( struct wlr_output_layout *layout) { - if (wl_list_empty(&layout->outputs)) { + struct wlr_box extents; + if (!wlr_output_layout_get_box(layout, NULL, &extents)) { return NULL; } - - struct wlr_box *extents = wlr_output_layout_get_box(layout, NULL); - double center_x = extents->width / 2 + extents->x; - 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; wlr_output_layout_closest_point(layout, NULL, center_x, center_y, @@ -436,7 +436,11 @@ struct wlr_output *wlr_output_layout_adjacent_output( struct wlr_output *reference, double ref_lx, double ref_ly) { assert(reference); - struct wlr_box *ref_box = wlr_output_layout_get_box(layout, reference); + struct wlr_box ref_box; + if (!wlr_output_layout_get_box(layout, reference, &ref_box)) { + // empty layout or invalid reference + return NULL; + } double min_distance = DBL_MAX; struct wlr_output *closest_output = NULL; @@ -445,21 +449,22 @@ struct wlr_output *wlr_output_layout_adjacent_output( if (reference != NULL && reference == l_output->output) { 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; // test to make sure this output is in the given direction 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) { - 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) { - match = box->y + box->height <= ref_box->y || match; + match = box.y + box.height <= ref_box.y || match; } 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) { continue; diff --git a/types/wlr_xdg_output.c b/types/wlr_xdg_output.c index 1015500362..ccbbc1fe13 100644 --- a/types/wlr_xdg_output.c +++ b/types/wlr_xdg_output.c @@ -6,6 +6,7 @@ #include #include #include "xdg-output-unstable-v1-protocol.h" +#include "types/wlr_output_layout.h" #define OUTPUT_MANAGER_VERSION 2