Skip to content

fix(BindCommand): disable the button while its command cannot execute - #32

Merged
tannevaled merged 1 commit into
mainfrom
fix/bindcommand-disabled
Oct 5, 2026
Merged

tannevaled merged 1 commit into
mainfrom
fix/bindcommand-disabled

Conversation

@tannevaled

Copy link
Copy Markdown
Contributor

Root cause. BindCommand passed mvvm.BindCommand a setEnabled that only swapped Button.Style (to ButtonSecondary and back). Its doc gave the reason, "a Button has no boolean disabled field", which is no longer true: Base.Disabled() exists, Button.OnEvent ignores every event while it is set, and the toolkit's focus walk skips disabled widgets. So a button whose command could not run still took clicks, Enter/Space and keyboard focus, and the host's own OnClick handler (composed before Execute) still ran. Both claimward apps (Linux and Windows) wrap BindCommand in a local bindCommand that sets Disabled by hand for this reason.

Fix. setEnabled also sets b.Disabled() to !CanExecute. The Style greying is kept as it was, so a bound button looks exactly as it did and the apps' workaround can be dropped without a visual change. The returned unbind now restores the button's prior Style and Disabled as well as OnClick, so unbinding leaves no disabled or secondary-styled button behind, and rebinding no longer captures a greyed Style as the "original".

Test. TestBindCommandDisablesTheButton puts the button in a toolkit.VBox and drives it through the container. Before the fix it fails with fired: clicks=2 runs=0 (click + Enter reached the host handler), Tab focused a button whose command cannot execute and not Disabled. After the fix it passes, including re-enabling and the unbind restore, for both a button that was enabled before binding and one that was already disabled.

Sabotage (each still passes go vet): dropping the Disabled().Set in setEnabled fails the test; dropping the restore in unbind fails unbind left the button Disabled.

Locally: gofmt clean, go vet ./..., go test ./... (100.0% statement coverage), go test -race.

README: the binding table and the BindCommand paragraph described the Style-only behaviour and the missing disabled field; both are updated.

Toolkit dependency. mvvmtk depends on github.com/go-widgets/toolkit (go.mod: v0.321.2). The fix uses only Base.Disabled() and the disabled handling already in v0.321.2 (the new test passes against it), so it needs no toolkit bump and does not depend on go-widgets/toolkit#482.

Semver: patch. No exported API is added or changed; it is a behaviour fix (a button whose command cannot execute is now inert, and unbind restores Style and Disabled).

Fixes #31

🤖 Generated with Claude Code

BindCommand reflected CanExecute only by swapping the button's Style, on
the stated ground that a Button has no disabled flag. It has one now
(Base.Disabled), and the swap alone left a button whose command cannot
run taking clicks, Enter and keyboard focus; the host's own OnClick
handler, composed before Execute, still ran.

Disabled is now bound to !CanExecute, beside the unchanged Style
greying, and unbind restores OnClick, Style and the prior Disabled
state.

Fixes #31

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@tannevaled
tannevaled merged commit 051857e into main Oct 5, 2026
14 checks passed
@tannevaled
tannevaled deleted the fix/bindcommand-disabled branch October 5, 2026 13:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BindCommand leaves a button enabled when its command cannot execute

1 participant