void output_manager_init(struct server *server);
struct output *output_from_wlr_output(struct server *server,
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_from_cursor_coords(struct server *server);
void handle_output_power_manager_set_mode(struct wl_listener *listener,
}
}
+/*
+ * 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
layers_arrange(struct output *output)
{
wlr_output_effective_resolution(output->wlr_output,
&full_area.width, &full_area.height);
struct wlr_box usable_area = full_area;
- struct wlr_box old_usable_area = output->usable_area;
struct server *server = output->server;
struct wlr_scene_output *scene_output =
!seat->focused_layer->current.keyboard_interactive) {
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
if (committed || 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);
}
}
struct wlr_layer_surface_v1 *layer_surface =
layer->scene_layer_surface->layer_surface;
if (layer_surface->output) {
- layers_arrange(layer_surface->output->data);
+ output_update_usable_area(layer_surface->output->data);
}
struct seat *seat = &layer->server->seat;
if (seat->focused_layer == layer_surface) {
handle_map(struct wl_listener *listener, void *data)
{
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
* call wlr_surface_send_enter() from here since that will be done
*/
struct wlr_layer_surface_v1_state old_state = layer_surface->current;
layer_surface->current = layer_surface->pending;
- layers_arrange(output);
+ output_update_usable_area(output);
layer_surface->current = old_state;
}
static void
output_update_for_layout_change(struct server *server)
{
- /* Adjust window positions/sizes */
- desktop_arrange_all_views(server);
+ output_update_all_usable_areas(server, /*enforce_view_arrange*/ true);
/*
* "Move" each wlr_output_cursor (in per-output coordinates) to
wlr_log(WLR_ERROR,
"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);
}
}
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
output_usable_area_in_layout_coords(struct output *output)
{