This reverts commit e28e6484e8.
This change tried to remove nodes from all points of reference to allow
immediate destruction. However, it missed things like the children lists
cloned by transaction states of parent nodes.
Adding all that extra cleanup would not be in the spirit of a PR
claiming to simplify teardown. Let's wait for someone to come up with a
cleaner approach instead.
Fixes: https://github.com/swaywm/sway/pull/8738
A sway_node may end up being referenced in either a queued transaction,
pending transaction or as a dirty node. To manage this, the transaction
system has been responsible for destroying containers, workspaces and
outputs at the end of their last referenced transaction.
This significantly complicates the teardown flow of surfaces and
outputs. Instead, remove the node from transactions and dirty lists so
that the callsite can remove and free the node immediately.
When an output is destroyed, we go through the process of disabling it.
This includes evacuating all content away from the output, which can
lead to various modifications to the scene. With the scene_output still
present, this can lead to things like output_enter events being emitted
for the output currently being destroyed.
Ensure that the scene output is destroyed first and that the output is
immediately considered disabled.
References: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3974
When the repaint timer fires, we check if the sway_output is disabled,
and if so, skip the output commit after having reset frame_pending.
The sway_output enable flag is only updated if the output is disabled
and removed from the layout, not if the power is disabled for e.g. idle.
This can lead to situations where a commit is attempted on a disabled
output, which will lead to an attempted and failed primary swapchain
allocation.
Use the wlr_output.enabled state to check if the output is active.
The teardown of a sway_output is split in two: begin_destroy and
output_destroy. The former clears some state such as NULL'ing the
reference to wlr_output, while the latter frees the struct and its
remaining resources.
If an output is destroyed while a repaint timer is pending, future frame
callbacks will no longer occur as the listener is torn down in
begin_destroy, but the repaint timer is not torn down and may still
fire until output_destroy is hit. As begin_destroy cleared the reference
to wlr_output, this leads to a NULL-pointer dereference.
Tear down the repaint timer in begin_destroy as there is no need for it.
Fixes: fdc4318ac6 ("desktop/output: Clear frame_pending even output is disabled")
IPC clients generally expect executed commands to have taken effect when
the command completes, while delayed modeset means that it can take
several milliseconds more before e.g. an output is enabled.
However, modesetting on every output command in the IPC call could on
systems with already slow modesetting behavior lead to an unresponsive
system for a not insignificant period of time.
To strike a balance, force modeset once all the commands of this IPC
call have executed if a modeset is pending.
Some commands require outputs to be enabled. These commands are deferred
to allow outputs to be discovered, but the delayed modeset might only
run some time later.
Force a modeset to occur before running deferred commands.
Fixes: https://github.com/swaywm/sway/issues/8433
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 4f9ce4675c. 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: 4f9ce4675c ("tree/arrange: Remove redundant output geometry update")
Instead of using a single finalized output config per output, accept a
regular list of output configs like the one ultimately stored for
configuration purposes. This allows the output management code to test
an augmented configuration while still using the same output config
logic, without having to mutate the stored configuration.
This in turn allows us to make a few APIs private. A bug note about an
existing issue with derade to off is added as well.
Output layout changes originate from the centralized modeset
infrastructure and request_state which already takes care of arranging
and updating outputs as needed.
The reasoning for using a commit handler is to ensure that all paths for
output changes are correctly handled. With the centralized modeset
infrastructure in place, we can move the logic there. This allows us to
be smarter and avoid extraneous arranges, output manager updates and
transaction commits.
The side-effect is a minor duplication for the special-case
request_state, but the shared path will be relied upon further in future
commits to justify this duplication.
1e0031781f refactored repaint to accumulate all changes in a single
wlr_output_state and commit them at the end of the repaint loop,
replacing a call to wlr_scene_output_commit. wlr_scene_output_commit
contains an early bail-out when no frame has been requested and no
damage has accumulated, which was not replicated as part of this
refactor, causing the repaint loop to never pause.
Replicate the logic to stop the repaint loop as needed.
Fixes: 1e0031781f ("desktop/output: unify page-flip codepath")
Instead of having a special codepath for applying gamma LUTs, have
a single codepath for regular page-flips and gamma LUT updates.
Should make it easier to add more logic on top e.g. for tearing
page-flips.
We were only passing the color transform when calling
wlr_scene_output_commit(). However when modesetting or pushing a
new gamma LUT we render via wlr_scene_output_build_state(). Pass
the color transform there as well.
The original sway output config implementation enabled one output at a
time, testing modes, render formats and VRR support as it went along.
While this sort of fallback is easy to do, it has the downside of not
considering the effect of neighbor outputs on the configuration
viability.
With backend-wide commits, we can now better consider the effect of
neighbor outputs, but to handle the fact that we commit all outputs at
once we need to perform a more elaborate search of viable
configurations.
Implement a recursive configuration search for when the primary
configuration failed to apply.
We want to check if a config_head existed for the current
matched_output_config, so we should check cfg->output. sway_output is a
temporary variable from a previous wl_list_for_each, and does not
contain anything useful to us.
Fixes: https://github.com/swaywm/sway/issues/8128