[v3 Windows] Frameless window gotchas & workarounds (hit-test, HiddenOnTaskbar, event data) #5001
harry18456
started this conversation in
General
Replies: 1 comment
-
|
Does this work better for you? #5010 |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Background
I've been building GlanceHUD — a floating
system-monitor HUD using Wails v3 alpha.72 on Windows 11. I used AI-assisted
development (vibe coding with Claude) throughout the project.
During development, the AI helped me identify several Windows-specific gotchas
through code analysis and trial-and-error. I'm sharing these here as a consolidated
reference, along with the workarounds that worked for me. I'm not sure if all of
these are known — happy to open separate issues if any are worth tracking formally.
1. Frameless + transparent window: hit-test region frozen at creation size
Related: #4871 (same symptom and root cause)
Symptom: After creating a frameless+transparent window at e.g. 400×300 and later
resizing it via
Window.SetSize, only the original 400×300 area responds to mouseevents. The expanded area is permanently click-through.
Root cause: In
webview_window_windows.go(~L318-322), frameless+transparentwindows receive
WS_EX_LAYERED | WS_EX_TRANSPARENT. On Windows, the hit-testableregion of a
WS_EX_LAYEREDwindow is fixed atCreateWindowExtime and is notupdated by subsequent
SetWindowPoscalls.setSize()(L686) only callssetBounds()→
SetWindowPos, without refreshing the layered window state.Workaround: Create the window at 3840×2160 with
Hidden: true, so thehit-test region covers any realistic content size. The frontend calls
Window.Show()after the first
SetSizecompletes.Possible upstream fix: Call
SetLayeredWindowAttributes(hwnd, 0, 255, LWA_ALPHA)after each
SetWindowPosinsetBounds()to refresh the layered region.2.
HiddenOnTaskbar: truelikely prevents window from receiving keyboard focusNote: We discovered this through source code inspection, not actual usage —
we chose to omit
HiddenOnTaskbarentirely after seeing the implementation.Flagging it here in case it affects others.
Root cause: In
webview_window_windows.goL331-334:The comment states
WS_EX_TOOLWINDOWis the intended style for hiding from thetaskbar, but it's commented out in favour of
WS_EX_NOACTIVATE.WS_EX_NOACTIVATEprevents the window from being activated, which would block keyboard focus and input.
Workaround: Omit
HiddenOnTaskbarentirely.Possible upstream fix: Use
WS_EX_TOOLWINDOWas originally intended.3.
Event.Emitwith a single arg vs. multiple args changesevent.datashape on the frontendSymptom:
event.datareceived in the frontend sometimes arrives as a directobject, sometimes wrapped in an array
[object], requiring defensive code.Root cause: In
event_manager.goL24-38:So the shape of
event.dataon the frontend depends entirely on how the Go callerinvokes
Emit. If any code path usesEmit("my-event", a, b)(two args), thefrontend receives an array; single-arg calls give a direct object.
The godoc documents this behaviour but does not explain the rationale. It's unclear
whether this asymmetry is intentional design or simply an artifact of the variadic
signature. If a caller accidentally passes two args, the frontend breaks silently.
Workaround:
Suggestion: Consider documenting this behaviour on the JS side (
Events.Ondocs),or normalising
event.datato always be a consistent shape regardless of how manyargs were passed to
Emit.System info (
wails3 doctor)Happy to provide more details or test any patches. Thanks for the great framework!
Beta Was this translation helpful? Give feedback.
All reactions