output: Add output_update_usable_area/all_usable_areas()

Move the desktop_arrange_all_views() call outside layers_arrange() into
a new function, output_update_usable_area().  The new function currently
does exactly what layers_arrange() used to, but will be expanded in a
later commit.

Add output_update_all_usable_areas(), which is the same as calling
output_update_usable_area() for each output, but only calls
desktop_arrange_all_views() once.

Rebased and slightly modified by @Consolatis
This commit is contained in:
John Lindgren 2022-11-16 12:43:59 -05:00 committed by Consolatis
parent af56b68041
commit ed31381eb8
4 changed files with 54 additions and 22 deletions

View file

@ -423,6 +423,8 @@ void output_init(struct server *server);
void output_manager_init(struct server *server); void output_manager_init(struct server *server);
struct output *output_from_wlr_output(struct server *server, struct output *output_from_wlr_output(struct server *server,
struct wlr_output *wlr_output); struct wlr_output *wlr_output);
void output_update_usable_area(struct output *output);
void output_update_all_usable_areas(struct server *server, bool enforce_view_arrange);
struct wlr_box output_usable_area_in_layout_coords(struct output *output); struct wlr_box output_usable_area_in_layout_coords(struct output *output);
struct wlr_box output_usable_area_from_cursor_coords(struct server *server); struct wlr_box output_usable_area_from_cursor_coords(struct server *server);
void handle_output_power_manager_set_mode(struct wl_listener *listener, void handle_output_power_manager_set_mode(struct wl_listener *listener,

View file

@ -35,6 +35,11 @@ arrange_one_layer(struct output *output, const struct wlr_box *full_area,
} }
} }
/*
* To ensure outputs/views are left in a consistent state, this
* function should be called ONLY from output_update_usable_area()
* or output_update_all_usable_areas().
*/
void void
layers_arrange(struct output *output) layers_arrange(struct output *output)
{ {
@ -43,7 +48,6 @@ layers_arrange(struct output *output)
wlr_output_effective_resolution(output->wlr_output, wlr_output_effective_resolution(output->wlr_output,
&full_area.width, &full_area.height); &full_area.width, &full_area.height);
struct wlr_box usable_area = full_area; struct wlr_box usable_area = full_area;
struct wlr_box old_usable_area = output->usable_area;
struct server *server = output->server; struct server *server = output->server;
struct wlr_scene_output *scene_output = struct wlr_scene_output *scene_output =
@ -103,12 +107,6 @@ layers_arrange(struct output *output)
!seat->focused_layer->current.keyboard_interactive) { !seat->focused_layer->current.keyboard_interactive) {
seat_set_focus_layer(seat, NULL); seat_set_focus_layer(seat, NULL);
} }
/* Finally re-arrange all views based on usable_area */
if (!wlr_box_equal(&old_usable_area, &usable_area)) {
desktop_arrange_all_views(server);
}
cursor_update_focus(output->server);
} }
static void static void
@ -145,7 +143,12 @@ handle_surface_commit(struct wl_listener *listener, void *data)
if (committed || layer->mapped != layer_surface->mapped) { if (committed || layer->mapped != layer_surface->mapped) {
layer->mapped = layer_surface->mapped; layer->mapped = layer_surface->mapped;
layers_arrange(output); output_update_usable_area(output);
/*
* Update cursor focus here to ensure we
* enter a new/moved/resized layer surface.
*/
cursor_update_focus(layer->server);
} }
} }
@ -171,7 +174,7 @@ handle_unmap(struct wl_listener *listener, void *data)
struct wlr_layer_surface_v1 *layer_surface = struct wlr_layer_surface_v1 *layer_surface =
layer->scene_layer_surface->layer_surface; layer->scene_layer_surface->layer_surface;
if (layer_surface->output) { if (layer_surface->output) {
layers_arrange(layer_surface->output->data); output_update_usable_area(layer_surface->output->data);
} }
struct seat *seat = &layer->server->seat; struct seat *seat = &layer->server->seat;
if (seat->focused_layer == layer_surface) { if (seat->focused_layer == layer_surface) {
@ -183,7 +186,11 @@ static void
handle_map(struct wl_listener *listener, void *data) handle_map(struct wl_listener *listener, void *data)
{ {
struct lab_layer_surface *layer = wl_container_of(listener, layer, map); struct lab_layer_surface *layer = wl_container_of(listener, layer, map);
layers_arrange(layer->scene_layer_surface->layer_surface->output->data); struct wlr_output *wlr_output =
layer->scene_layer_surface->layer_surface->output;
if (wlr_output) {
output_update_usable_area(wlr_output->data);
}
/* /*
* Since moving to the wlroots scene-graph API, there is no need to * Since moving to the wlroots scene-graph API, there is no need to
* call wlr_surface_send_enter() from here since that will be done * call wlr_surface_send_enter() from here since that will be done
@ -374,7 +381,7 @@ handle_new_layer_surface(struct wl_listener *listener, void *data)
*/ */
struct wlr_layer_surface_v1_state old_state = layer_surface->current; struct wlr_layer_surface_v1_state old_state = layer_surface->current;
layer_surface->current = layer_surface->pending; layer_surface->current = layer_surface->pending;
layers_arrange(output); output_update_usable_area(output);
layer_surface->current = old_state; layer_surface->current = old_state;
} }

View file

@ -240,8 +240,7 @@ output_init(struct server *server)
static void static void
output_update_for_layout_change(struct server *server) output_update_for_layout_change(struct server *server)
{ {
/* Adjust window positions/sizes */ output_update_all_usable_areas(server, /*enforce_view_arrange*/ true);
desktop_arrange_all_views(server);
/* /*
* "Move" each wlr_output_cursor (in per-output coordinates) to * "Move" each wlr_output_cursor (in per-output coordinates) to
@ -395,11 +394,6 @@ do_output_layout_change(struct server *server)
wlr_log(WLR_ERROR, wlr_log(WLR_ERROR,
"wlr_output_manager_v1_set_configuration()"); "wlr_output_manager_v1_set_configuration()");
} }
struct output *output;
wl_list_for_each(output, &server->outputs, link) {
layers_arrange(output);
}
output_update_for_layout_change(server); output_update_for_layout_change(server);
} }
} }
@ -438,6 +432,38 @@ output_from_wlr_output(struct server *server, struct wlr_output *wlr_output)
return NULL; return NULL;
} }
/* returns true if usable area changed */
static bool
update_usable_area(struct output *output)
{
struct wlr_box old = output->usable_area;
layers_arrange(output);
return !wlr_box_equal(&old, &output->usable_area);
}
void
output_update_usable_area(struct output *output)
{
if (update_usable_area(output)) {
desktop_arrange_all_views(output->server);
}
}
void
output_update_all_usable_areas(struct server *server, bool enforce_view_arrange)
{
bool usable_area_changed = false;
struct output *output;
wl_list_for_each(output, &server->outputs, link) {
usable_area_changed |= update_usable_area(output);
}
if (usable_area_changed || enforce_view_arrange) {
desktop_arrange_all_views(server);
}
}
struct wlr_box struct wlr_box
output_usable_area_in_layout_coords(struct output *output) output_usable_area_in_layout_coords(struct output *output)
{ {

View file

@ -97,10 +97,7 @@ seat_disinhibit_input(struct seat *seat)
* Triggers a refocus of the topmost surface layer if necessary * Triggers a refocus of the topmost surface layer if necessary
* TODO: Make layer surface focus per-output based on cursor position * TODO: Make layer surface focus per-output based on cursor position
*/ */
struct output *output; output_update_all_usable_areas(seat->server, /*enforce_view_arrange*/ false);
wl_list_for_each(output, &seat->server->outputs, link) {
layers_arrange(output);
}
} }
static void static void