Skip to content

Commit

Permalink
desktop/output: Store output config on request_state
Browse files Browse the repository at this point in the history
An output backend might request any change to an output state at any
time, although currently only this is currently only used for changing
window size on the wayland and x11 backend.

Applying the configuration directly means that the current output state
becomes inconsistent with the configured state, which can cause the new
state to be reverted later if apply_stored_output_configs is called.

Before 4f9ce46. the output geometry would be updated by
arrange_outputs, but this is only done by the modeset logic now,
resulting in the stored geometry never being updated on wayland backend
window resize. This was not discovered as the stored geometry is not
used particularly often.

Solve both by storing a new output configuration and relying on the
modeset logic to apply a new state.

Fixes: 4f9ce46 ("tree/arrange: Remove redundant output geometry update")
  • Loading branch information
kennylevinsen authored and Nefsen402 committed Oct 30, 2024
1 parent e7c972b commit 1e53007
Showing 1 changed file with 38 additions and 10 deletions.
48 changes: 38 additions & 10 deletions sway/desktop/output.c
Original file line number Diff line number Diff line change
Expand Up @@ -457,19 +457,47 @@ static void handle_request_state(struct wl_listener *listener, void *data) {
struct sway_output *output =
wl_container_of(listener, output, request_state);
const struct wlr_output_event_request_state *event = data;
const struct wlr_output_state *state = event->state;

uint32_t committed = event->state->committed;
wlr_output_commit_state(output->wlr_output, event->state);
// Store the requested changes so that the active configuration is
// consistent with the current state, and to avoid duplicate logic to apply
// the changes.
struct output_config *oc = new_output_config(output->wlr_output->name);
if (!oc) {
sway_log(SWAY_ERROR, "Allocation failed");
return;
}

if (committed & (
WLR_OUTPUT_STATE_MODE |
WLR_OUTPUT_STATE_TRANSFORM |
WLR_OUTPUT_STATE_SCALE)) {
arrange_layers(output);
arrange_output(output);
transaction_commit_dirty();
int committed = state->committed;
if (committed & WLR_OUTPUT_STATE_MODE) {
if (state->mode != NULL) {
oc->width = state->mode->width;
oc->height = state->mode->height;
oc->refresh_rate = state->mode->refresh / 1000.f;
} else {
oc->width = state->custom_mode.width;
oc->height = state->custom_mode.height;
oc->refresh_rate = state->custom_mode.refresh / 1000.f;
}
committed &= ~WLR_OUTPUT_STATE_MODE;
}
if (committed & WLR_OUTPUT_STATE_SCALE) {
oc->scale = state->scale;
committed &= ~WLR_OUTPUT_STATE_SCALE;
}
if (committed & WLR_OUTPUT_STATE_TRANSFORM) {
oc->transform = state->transform;
committed &= ~WLR_OUTPUT_STATE_TRANSFORM;
}

// We do not expect or support any other changes here
assert(committed == 0);
store_output_config(oc);
apply_stored_output_configs();

update_output_manager_config(output->server);
if (server.delayed_modeset != NULL) {
wl_event_source_remove(server.delayed_modeset);
server.delayed_modeset = NULL;
}
}

Expand Down

0 comments on commit 1e53007

Please sign in to comment.