Ignore stale client commits on floating resize#352
Conversation
|
Note: This also applies to sway, I opened a PR there also: swaywm/sway#9215 |
9065c85 to
32e501d
Compare
Exposes scroll.animating() and scroll.pending_transactions() to Lua to allow external scripts and tests to query whether the compositor has settled. Also includes testing infrastructure updates (pytest.ini config, LSan suppressions, and helper methods in test_utils.py).
When a new view is mapped, criteria rules may configure its
geometry (e.g. `resize set`). This configuration sends a new
configure event to the client.
However, during the map event handling, we are still processing
the initial commit from the client. After the map event is
handled and the rule-configured geometry is applied via a
transaction, the compositor's commit handler (`handle_commit`)
continues.
For floating containers, `handle_commit` resizes the container to
match the client's committed buffer size. If it processes the
initial commit (which has the initial client size, not the
configured one), it overrides the configured geometry back to the
initial size.
To fix this, we introduce `is_commit_stale` helper which checks
if there is a pending or scheduled configure event with a newer
serial than the serial acknowledged by the current commit. If the
commit is stale, we ignore its size for resizing floating
containers, waiting instead for the client to acknowledge and
commit the newly configured size.
How to reproduce:
1. Register the for_window rule:
swaymsg 'for_window [title="Scratchpad Test"] move scratchpad, resize set 500 500'
2. Start the client:
foot -T "Scratchpad Test"
3. Query the scratchpad window geometry:
swaymsg -t get_tree | jq '.. | select(.name? == "__i3_scratch") | .floating_nodes[] | select(.name == "Scratchpad Test") | .rect'
On buggy versions, this will output the client's default size
instead of the configured 500x500.
Additionally:
* Make `wait_for_client_map` test utility robust by searching
all workspaces and the scratchpad for the mapped view, instead
of just checking the focused view. This allows it to be used
for windows that are moved to the scratchpad (and thus
hidden/unfocused) immediately upon mapping.
* Update `wayland-client.c` to support dynamic resizing in tests.
* Add integration test `tests/test_scratchpad_geometry.py` to
verify the fix.
32e501d to
33c92d2
Compare
|
Did you look at #115? |
|
The change where you ignore stale commits looks good in theory, but it creates a problem when you are resizing a floating window manually with the mouse. The system will ignore "old" commits that create a smoother transition. The resizing will "jump" from one state to another, ignoring intermediate states because they don't correspond to the latest serial. Edit: another issue: It doesn't solve the problem of a pending transaction state being overwritten by a new commit either. For example:
local scroll = require("scroll")
local function on_float(cbview, _)
local container = scroll.view_get_container(cbview)
if scroll.container_get_floating(container) then
scroll.command(container, "decoration shadow true; border normal")
else
scroll.command(container, "decoration shadow false; border pixel")
end
end
scroll.add_callback("view_float", on_float, nil)This script will execute a command within the callback and create a new transaction. Note this is important, if there is no command, there is no transaction and everything is good. That transaction will be queued, and because it will have to wait for the client's response, it will block committing other transactions. In the meantime... When I press So, unfortunately, there is more going on than what it seems. |
When a new view is mapped, criteria rules may configure its
geometry (e.g.
resize set). This configuration sends a newconfigure event to the client.
However, during the map event handling, we are still processing
the initial commit from the client. After the map event is
handled and the rule-configured geometry is applied via a
transaction, the compositor's commit handler (
handle_commit)continues.
For floating containers,
handle_commitresizes the container tomatch the client's committed buffer size. If it processes the
initial commit (which has the initial client size, not the
configured one), it overrides the configured geometry back to the
initial size.
To fix this, we introduce
is_commit_stalehelper which checksif there is a pending or scheduled configure event with a newer
serial than the serial acknowledged by the current commit. If the
commit is stale, we ignore its size for resizing floating
containers, waiting instead for the client to acknowledge and
commit the newly configured size.
How to reproduce:
Register the for_window rule:
swaymsg 'for_window [title="Scratchpad Test"] move scratchpad, resize set 500 500'
Start the client:
foot -T "Scratchpad Test"
Query the scratchpad window geometry:
swaymsg -t get_tree | jq '.. | select(.name? == "__i3_scratch") | .floating_nodes[] | select(.name == "Scratchpad Test") | .rect'
On buggy versions, this will output the client's default size
instead of the configured 500x500.
Additionally:
wait_for_client_maptest utility robust by searchingall workspaces and the scratchpad for the mapped view, instead
of just checking the focused view. This allows it to be used
for windows that are moved to the scratchpad (and thus
hidden/unfocused) immediately upon mapping.
wayland-client.cto support dynamic resizing in tests.tests/test_scratchpad_geometry.pytoverify the fix.