This commit is contained in:
Copilot 2026-03-01 17:17:53 +08:00 committed by GitHub
commit 91c104f408
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 31 additions and 3 deletions

View file

@ -362,10 +362,11 @@ func (w *windowsWebviewWindow) run() {
if options.AlwaysOnTop {
exStyle |= w32.WS_EX_TOPMOST
}
// If we're frameless, we need to add the WS_EX_TOOLWINDOW style to hide the window from the taskbar
// WS_EX_TOOLWINDOW hides the window from the taskbar without blocking keyboard focus.
// WS_EX_NOACTIVATE (previously used here) prevents the window from being activated,
// which blocks keyboard focus and input.
if options.Windows.HiddenOnTaskbar {
//exStyle |= w32.WS_EX_TOOLWINDOW
exStyle |= w32.WS_EX_NOACTIVATE
exStyle |= w32.WS_EX_TOOLWINDOW
} else {
exStyle |= w32.WS_EX_APPWINDOW
}
@ -692,6 +693,13 @@ func (w *windowsWebviewWindow) setPhysicalBounds(physicalBounds Rect) {
w32.SWP_NOZORDER|w32.SWP_NOACTIVATE,
)
w.ignoreDPIChangeResizing = previousFlag
// For WS_EX_LAYERED windows (frameless+transparent or IgnoreMouseEvents), the hit-test
// region is not updated by SetWindowPos alone. Calling SetLayeredWindowAttributes refreshes
// the layered region so that the full new window area responds to mouse events.
if exStyle := w32.GetWindowLong(w.hwnd, w32.GWL_EXSTYLE); exStyle&w32.WS_EX_LAYERED != 0 {
w32.SetLayeredWindowAttributes(w.hwnd, 0, 255, w32.LWA_ALPHA)
}
}
// Get window dip bounds

View file

@ -397,6 +397,12 @@ const (
WS_EX_NOACTIVATE = 0x08000000
)
// SetLayeredWindowAttributes flags
const (
LWA_COLORKEY = 0x00000001
LWA_ALPHA = 0x00000002
)
// Window message constants
const (
WM_APP = 32768

View file

@ -156,6 +156,7 @@ var (
procCallNextHookEx = moduser32.NewProc("CallNextHookEx")
procGetForegroundWindow = moduser32.NewProc("GetForegroundWindow")
procUpdateLayeredWindow = moduser32.NewProc("UpdateLayeredWindow")
procSetLayeredWindowAttributes = moduser32.NewProc("SetLayeredWindowAttributes")
getDisplayConfig = moduser32.NewProc("GetDisplayConfigBufferSizes")
queryDisplayConfig = moduser32.NewProc("QueryDisplayConfig")
@ -317,6 +318,19 @@ func UpdateLayeredWindow(hwnd HWND, hdcDst HDC, pptDst *POINT, psize *SIZE,
return ret != 0
}
// SetLayeredWindowAttributes sets the opacity and transparency color key of a layered window.
// crKey: the transparency color key (use 0 if not using LWA_COLORKEY)
// bAlpha: the opacity value (0 = transparent, 255 = opaque); used when dwFlags includes LWA_ALPHA
// dwFlags: LWA_COLORKEY and/or LWA_ALPHA
func SetLayeredWindowAttributes(hwnd HWND, crKey COLORREF, bAlpha byte, dwFlags DWORD) bool {
ret, _, _ := procSetLayeredWindowAttributes.Call(
uintptr(hwnd),
uintptr(crKey),
uintptr(bAlpha),
uintptr(dwFlags))
return ret != 0
}
func PostThreadMessage(threadID HANDLE, msg int, wp, lp uintptr) {
procPostThreadMessageW.Call(threadID, uintptr(msg), wp, lp)
}