Repository navigation
fix(configurator): reopen open edits only once their row can hold them - #437
Merged
Merged
Conversation
GTK 4.24 closes a popover it cannot place, and the configurator reports that close as the user canceling the edit. After a language change the rebuilt page reopened a recording or text edit before the page had a layout or its restored scroll, so the row was off screen and the edit ended. Rebuilt pages now settle first: the scroll is restored after the first layout, and a PagesLaidOut message ends settling. Editor popovers open only when the pages have settled, no Leave confirmation is pending, and the row is shown and laid out, scrolling the row into view when a translation moved it. Focus and selection inside a popover that has not reopened yet are restored when it opens.
The Leave scenario queued the language change and Reload in one main loop turn. On GTK 4.14 focus stays on the edited row while its recorder is open, so the rebuild puts focus back on the new row, and that selection ran after Reload and withdrew the confirmation. A real click on Reload always comes after the rebuild's refresh, so the test now runs the queued messages first and asserts that the pages are still settling.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
On newer GTK, changing the interface language while a shortcut is being
recorded or text-edited cancels the edit. The configurator is meant to carry
open edits across the language rebuild. That works on GTK 4.14, which CI
uses, but not on GTK 4.24.
app::component::tests::language_changes_rebuild_the_window_in_placeshowsthis with GTK 4.24 and Weston 15.
Cause
GTK 4.24 closes a popover it cannot place.
gtk_popover_native_layoutcallsgtk_popover_popdownwhen the compositor gives the popup less than itsminimum size, which is what happens once the anchor row is outside the view.
GTK 4.14 does not have that check.
field_canceledthen reports the closeas the user canceling the edit.
A language change hit this path in two ways:
rebuild_if_language_changedreopened the edit's popover on the new row.At that moment the new page has no layout and is at scroll 0, so the row
is off screen. The saved scroll is restored only after the first
allocation.
row can be taller. In the test, the Undo row ends up 560 px down a 446 px
view at the restored offset after switching to Chinese.
The test also started recording on a row far below the visible part of the
page. A real recording starts from a click on its row, so that row is always
on screen.
Changes
pages/mod.rs: a settle ticket per rebuild. A newer rebuild makes an olderticket stale.
component/rebuild.rs: the rebuild takes a ticket before its firstrefresh. A new
settlestep:Message::PagesLaidOutFocus that was inside a popover that has not reopened yet is restored, with
its caret and selection, right after the popover opens. If the edit ends
before the popover reopens, the saved focus is dropped. A rebuild that
starts before the previous one settled carries over that rebuild's scroll
for the same page, unless the page has a scroll of its own.
pages/keybindings/widgets.rs:PopoverPresenteropens the recorder andtext-editor popovers only when all of these hold:
select its row and that withdraws the confirmation
If the row is outside the view, it scrolls the row into view and opens the
popover after the next layout. A row that is not showing, on another page
or in a hidden category, opens once it is shown and laid out.
messages.rsandupdate/mod.rs:PagesLaidOutchanges no state. It isallowed while a document replacement is in flight and does not withdraw a
pending Leave confirmation.
Tests
The GTK scenario, with existing assertions unchanged:
switch the test waits for the rebuilt page to reopen the open edit, and
asserts that each popover opened with its row on screen. The listeners
attach when the rebuilt page becomes visible, before its first refresh.
Without the production changes this check fails with
[false]on GTK 4.24.on that row does not get the old selection.
recorder reopens once, on screen, after the confirmation is canceled.
and closed, and reopens when the category is shown again.
The Leave, old-selection, two-change and hidden-category checks each fail
when the production change they cover is removed.
A unit test covers the settle ticket.
Validation
./tools/test-gtk-widgets.shand./tools/lint-and-test.shpass withGTK 4.24.1 and Weston 15.
cargo clippywith--all-featuresand with--no-default-features, andcargo fmt --check, pass.Not changed
model does not track it, which was already the case before this change.
ubuntu-24.04(ci: build the Nix flake and check the minimum Rust version #436) can be removed once thisscenario passes on a newer runner image.