fix(installer): keep the Install button reachable when the window is shorter than the content - #428
Merged
Merged
Conversation
…shorter than the content Reported on Windows 11 at 125% scaling (#75): the Install button sat below the bottom edge with no way to get to it. "Had to grab edge of window and drag down to see the button." `.installer-container` is `height: 100vh; overflow: hidden`, and `.content` inside it is a flex item, so it never shrinks below its own content - `min-height: auto` is the default in the block axis. Content taller than the window therefore overflows a container that clips it and, because `overflow: hidden` is not user-scrollable, nothing brings it back. The window is 450x650 logical and the fresh-install pane is 581px tall: 69px of headroom for every text size, locale and installer state. v2.6.2 raised the window height, which moved that number without removing the failure mode. The pane scrolls now. `min-height: 0` lets `.content` shrink to the window, `overflow-y: auto` makes the remainder reachable. The scroll goes on `.content` rather than on `.installer-container` because the container carries `data-tauri-drag-region`, and tauri's drag.js keys off `e.target` alone (2.10.2 `e.target.getAttribute`, 2.11.5 the same check via the composed path). A scrollbar on the drag region would report the container as the mousedown target, so dragging the scrollbar would drag the window - and the scrollbar only exists in the case this fix is for. `.content` has no drag attribute, so its scrollbar is just a scrollbar. `justify-content: safe center` because centring an overflowing column pushes the top out past the start edge, where scrolling cannot reach it. Declared after the plain `center` so engines without `safe` keep today's behaviour. The four fixed heights that made the pane rigid become `min-height`. They exist to stop the box changing size between installer states, which a floor still does; as ceilings they let the option list overlap the error slot and the buttons at large text sizes. At a 2.25x text scale the option list is 221px inside its 140px box, 71px of it on top of the error container. Nothing changes at the shipped window size: every element rect is identical and no scrollbar appears. `Uninstaller.svelte` is the same component shape with the same container and the same defect, three lines apart in the same directory, so it gets the same treatment. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
PathGao
force-pushed
the
fix/installer-button-reachable
branch
from
August 3, 2026 07:53
a0158ef to
314076c
Compare
This was referenced Aug 3, 2026
PathGao
added a commit
that referenced
this pull request
Aug 5, 2026
Eleven macOS screenshots for the v2.7.0 release notes, following the pics/<version>/ convention already used by 2.6.2 and 2.6.3. Taken from local builds of master at ebc20ab and of the tag branch, against the same document throughout so the before/after pairs differ only in what they are about. Not included, and why: the installer at large text (#428) is Windows-only; a PDF "before" is impossible because macOS PDF export did not work at all until #287, so there is no earlier build to compare against; and the collapsed floating ToC is visible in several of the other shots rather than needing its own. Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This was referenced Aug 5, 2026
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.
Addresses #75 (thanks @wargoblin for the repro detail):
v2.6.2 made the installer window taller, which moved the threshold. The failure mode is still there, and it is not really about text scaling — it is about the pane being 100vh with
overflow: hidden, so any window shorter than the content hides the button and nothing scrolls it back.Why the button leaves the window
.installer-containerisheight: 100vh; overflow: hidden..contentis its flex child. A flex item'smin-heightisautoin the block axis, so.contentnever shrinks below its own content —flex: 1grows it, nothing shrinks it. When the content is taller than the window,.contentkeeps its full height, overflows the container, and the container clips it.overflow: hiddenis not user-scrollable, so there is no wheel, no scrollbar, no keyboard route to what was cut.Measured in the real component (450 wide, the shipped installer width), fresh-install state, English:
lib.rs,LogicalSize)So the button is fully visible only while the window's inner height is ≥ 505px, and fully gone below 466px. At 470px the screenshot is the issue report: a 4px sliver of blue at the bottom edge,
container.scrollHeight581 vsclientHeight470,scrollToppinned at 0.Two independent things push past that 69px on Windows, and neither is under the frontend's control: content that grows (system text size — every font size in this component is a fixed
px, and the boxes around them are fixedpxtoo), and a window that ends up shorter than requested. Both land on the same number, which is why the fix is stated in terms of that number rather than in terms of scaling.The fix
The scroll goes on
.content, not on.installer-container. The container carriesdata-tauri-drag-region, and tauri'sdrag.jskeys the drag off the mousedown target alone —e.target.getAttribute(...)in the locked 2.10.2, the same check walked over the composed path in 2.11.5. A scrollbar belongs to its scrolling element, and mousedown on it reports that element as the target, so a scrollbar on the container would start a window drag instead of scrolling — in exactly the case this PR is about, since the scrollbar only exists when the content overflows..contenthas no drag attribute; its scrollbar is just a scrollbar.safe center. Centring a column that overflows pushes the top out past the start edge, which no amount of scrolling reaches — the header would go where the button used to.safefalls back to start-alignment only when it overflows, and only then. Declared after a plaincenterso an engine withoutsafedrops the second declaration and keeps today's behaviour; both survive the production CSS minifier (verified inbuild/).Four
height→min-height(.options-container,.error-container,.notice-container,.scope-toggle). These reserve space so the box does not resize between installer states — a floor does that as well as a fixed height does. As ceilings they let content escape: at a 2.25× text scale (the Windows maximum) the option list is 221px tall inside its 140px box and lands 71px on top of the error container, which is under the buttons. A scrollable pane does not fix overlap, and the overlap is what makes the button unclickable rather than merely off-screen..installer-containeritself is untouched — stillheight: 100vh, stilloverflow: hidden, still the drag region over the whole window..contentcan no longer exceed it, so thatoverflow: hiddennow never has anything to clip.Verified in a browser
Built with
npm run buildand driven in Chromium at the installer's own 450px width, against the real components (invokestubbed to the two calls the installer makes), at both the dev server and the production build.scrollHeight === clientHeight, no scrollbarscrollTopstuck at 0scrollTop: 0Text scaling simulated by multiplying every computed
font-sizein the pane while holding the window at 450 × 650 — text grows, the window does not, which is the shape of the Windows setting:scrollTop: 180.5Drag region, hit-tested on a 3px grid over the whole window before and after:
.installer-containeris the topmost element at 0 points in both —.contentcovers it completely, and the container is the same size it always was. Worth saying plainly since the PR touches it: with target-only matching indrag.js, that means the installer window is not draggable by its background today, before this change or after. Not touched here; see Not covered.No Rust touched.
Uninstaller
Uninstaller.svelteis the same component shape — same.installer-containerwithheight: 100vh; overflow: hidden, same.contentflex child, samedata-tauri-drag-region. It carries less content (327px vs 581px), so it needs a much shorter window to break, but the mechanism is identical and it does break. Included: same defect, same file pattern, adjacent file, and the.contentblock is byte-identical to the installer's. Its fixed heights do not exist, so only the one block changed.The reporter's suggestion
That is the right instinct and it is not what this PR does. Sizing the window to content is a Rust-side change (
window.set_sizeinlib.rs), it has to cope with a window taller than the work area — where auto-size cannot help and only scrolling can — and it belongs with the larger discussion about how Markpad installs itself on Windows (#395). A scrollable pane is the floor under both: whatever the window ends up doing, the button stays reachable.Not covered
.content's width when they appear (.setup-boxshrinks from 370 to ~355, the two-button row shrinks with it), the OS text-size setting was simulated by scaling font sizes rather than by the setting itself, and browser zoom / a short viewport is a proxy for a small window, not for a display-scaling change.drag.jswere read instead.data-tauri-drag-regionon.contentor="deep"on the container, both of which change what a click on the pane does, and neither belongs in a fix for a clipped button.setup.rs,hooks.nsior the window creation.overflow-x: hidden, as before). A long translated title is cut rather than scrollable; the buttons are centred and flex-shrink, so they are not what overflows.scripts/; the numbers above come from measuring the real component in a browser, and nothing in the suite would catch a regression here.🤖 Generated with Claude Code