Repository navigation
Conversation
… handling - Track hover with MouseRegion onEnter/onExit instead of onHover, and skip setState when hover/press state is unchanged, so pointer movement inside a button no longer rebuilds it on every event. - Make the four chrome icon painters repaint when their color changes; shouldRepaint previously returned false, so icons could keep a stale color after hover, press or brightness changes. - Render the `icon` argument, which was accepted but ignored, and give it an IconTheme with the current state color and a 16px size. - Treat a button without onPressed as disabled: use the disabled icon color, show no hover/press feedback, cancel an in-progress press when the button becomes disabled, and expose button/enabled semantics. Hover is still tracked while disabled, so re-enabling under a resting pointer shows the hover state immediately. - Use a light disabled icon color in dark mode; it was black, which is nearly invisible on a dark title bar.
This was referenced Nov 10, 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.
Problem
WindowCaptionButtonhas several state and rendering issues:MouseRegion.onHover, which callssetStateon every pointer movement inside the button, so moving the mouse over a caption button rebuilds it on every event.falsefromshouldRepaint, so an icon can keep a stale color after a hover, press or brightness change.iconconstructor argument is accepted but never rendered.onPressed: nullstill shows hover/press feedback, uses the normal icon color and exposes no semantics.Change
onEnter/onExit, andsetStateis skipped when hover/press state does not change.iconis rendered inside anIconThemecarrying the current state color and a 16px size, soIconwidgets follow hover/press/disabled colors.button+enabledsemantics. Hover is still tracked while disabled, so re-enabling under a resting pointer shows the hover state immediately.Default colors and layout are otherwise unchanged.
Tests
New
test/window_caption_button_test.dart: painter repaint on color change, hover enter/exit with no frame scheduled for in-button movement, custom icon rendering and coloring, disabled color and input handling in dark mode, disabling mid-press and re-enabling under the pointer, and semantics. These tests fail against the previous implementation.dart format --set-exit-if-changed .,flutter analyze(package and example) andflutter test(package and example) pass locally (Flutter 3.47.7, Windows), and the full CI workflow passes on the identical commit in my fork.Related
Part of a set of independent PRs, each based on
mainand mergeable on its own: widgets #598 (this), #599, #600, #601; legacy bridge #602, #603, #604, #605, #606.Touches
window_caption_button.dartlike #599 (glyph Path cache); the two merge cleanly in either order. #599 makes the repaints enabled here cheaper.