From 421b75ef21f09a5e303e167abdbe31495e57a3e2 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sat, 19 Apr 2025 10:27:25 +1000 Subject: [PATCH] Multiple fixes. Thanks @kron! --- docs/src/content/docs/changelog.mdx | 3 +++ v3/pkg/application/application_windows.go | 28 ++++++++++++++++++++ v3/pkg/application/systemtray_windows.go | 16 +++++++++++ v3/pkg/application/webview_window_windows.go | 20 ++++++++++++-- v3/pkg/w32/user32.go | 6 ++--- 5 files changed, 68 insertions(+), 5 deletions(-) diff --git a/docs/src/content/docs/changelog.mdx b/docs/src/content/docs/changelog.mdx index 74eba67d9..3670469f9 100644 --- a/docs/src/content/docs/changelog.mdx +++ b/docs/src/content/docs/changelog.mdx @@ -121,6 +121,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed Webview2 detection path in HKCU by [@leaanthony](https://github.com/leaanthony). - Fixed input issue with macOS by [@leaanthony](https://github.com/leaanthony). - Fixed Windows icon generation task file name by [@yulesxoxo](https://github.com/yulesxoxo) in [#4219](https://github.com/wailsapp/wails/pull/4219). +- Fixed transparency issue for frameless windows by [@leaanthony](https://github.com/leaanthony) based on work by @kron. +- Fixed focus calls when window is disabled or minimised by [@leaanthony](https://github.com/leaanthony) based on work by @kron. +- Fixed system trays not showing after taskbar restarts by [@leaanthony](https://github.com/leaanthony) based on work by @kron. ### Changed diff --git a/v3/pkg/application/application_windows.go b/v3/pkg/application/application_windows.go index 2279e16c7..bc8428be1 100644 --- a/v3/pkg/application/application_windows.go +++ b/v3/pkg/application/application_windows.go @@ -8,7 +8,9 @@ import ( "path/filepath" "slices" "sync" + "sync/atomic" "syscall" + "time" "unsafe" "github.com/wailsapp/go-webview2/webviewloader" @@ -18,6 +20,10 @@ import ( "github.com/wailsapp/wails/v3/pkg/w32" ) +var ( + wmTaskbarCreated = w32.RegisterWindowMessage(w32.MustStringToUTF16Ptr("TaskbarCreated")) +) + type windowsApp struct { parent *App @@ -40,6 +46,9 @@ type windowsApp struct { // system theme isCurrentlyDarkMode bool currentWindowID uint + + // Restart taskbar flag + restartingTaskbar atomic.Bool } func (m *windowsApp) isDarkMode() bool { @@ -221,6 +230,17 @@ func (m *windowsApp) wndProc(hwnd w32.HWND, msg uint32, wParam, lParam uintptr) } switch msg { + case wmTaskbarCreated: + if m.restartingTaskbar.Load() { + break + } + m.restartingTaskbar.Store(true) + m.reshowSystrays() + go func() { + // 1 second debounce + time.Sleep(1000) + m.restartingTaskbar.Store(false) + }() case w32.WM_SETTINGCHANGE: settingChanged := w32.UTF16PtrToString((*uint16)(unsafe.Pointer(lParam))) if settingChanged == "ImmersiveColorSet" { @@ -297,6 +317,14 @@ func (m *windowsApp) unregisterWindow(w *windowsWebviewWindow) { } } +func (m *windowsApp) reshowSystrays() { + m.systrayMapLock.Lock() + defer m.systrayMapLock.Unlock() + for _, systray := range m.systrayMap { + systray.reshow() + } +} + func setupDPIAwareness() error { // https://learn.microsoft.com/en-us/windows/win32/hidpi/setting-the-default-dpi-awareness-for-a-process // https://learn.microsoft.com/en-us/windows/win32/hidpi/high-dpi-desktop-application-development-on-windows diff --git a/v3/pkg/application/systemtray_windows.go b/v3/pkg/application/systemtray_windows.go index e227a6f0d..2f92eb056 100644 --- a/v3/pkg/application/systemtray_windows.go +++ b/v3/pkg/application/systemtray_windows.go @@ -431,3 +431,19 @@ func (s *windowsSystemTray) Show() { func (s *windowsSystemTray) Hide() { // No-op } + +func (s *windowsSystemTray) reshow() { + // Add icons back to systray + nid := w32.NOTIFYICONDATA{ + HWnd: s.hwnd, + UID: uint32(s.parent.id), + UFlags: w32.NIF_ICON | w32.NIF_MESSAGE, + HIcon: s.currentIcon, + UCallbackMessage: WM_USER_SYSTRAY, + } + nid.CbSize = uint32(unsafe.Sizeof(nid)) + // Show the icon + if !w32.ShellNotifyIcon(w32.NIM_ADD, &nid) { + panic(syscall.GetLastError()) + } +} diff --git a/v3/pkg/application/webview_window_windows.go b/v3/pkg/application/webview_window_windows.go index 587154a11..a49255dd5 100644 --- a/v3/pkg/application/webview_window_windows.go +++ b/v3/pkg/application/webview_window_windows.go @@ -273,9 +273,12 @@ func (w *windowsWebviewWindow) run() { exStyle := w32.WS_EX_CONTROLPARENT if options.BackgroundType != BackgroundTypeSolid { - exStyle |= w32.WS_EX_NOREDIRECTIONBITMAP - if w.parent.options.IgnoreMouseEvents { + if (options.Frameless && options.BackgroundType == BackgroundTypeTransparent) || w.parent.options.IgnoreMouseEvents { + // Always if transparent and frameless exStyle |= w32.WS_EX_TRANSPARENT | w32.WS_EX_LAYERED + } else { + // Only WS_EX_NOREDIRECTIONBITMAP if not (and not solid) + exStyle |= w32.WS_EX_NOREDIRECTIONBITMAP } } if options.AlwaysOnTop { @@ -788,6 +791,14 @@ func (w *windowsWebviewWindow) setFullscreenButtonEnabled(_ bool) { func (w *windowsWebviewWindow) focus() { w32.SetForegroundWindow(w.hwnd) + + if w.isDisabled() { + return + } + if w.isMinimised() { + w.unminimise() + } + w.focusingChromium = true w.chromium.Focus() w.focusingChromium = false @@ -1041,6 +1052,11 @@ func (w *windowsWebviewWindow) disableIcon() { ) } +func (w *windowsWebviewWindow) isDisabled() bool { + style := uint32(w32.GetWindowLong(w.hwnd, w32.GWL_STYLE)) + return style&w32.WS_DISABLED != 0 +} + func (w *windowsWebviewWindow) updateTheme(isDarkMode bool) { if w32.IsCurrentlyHighContrastMode() { diff --git a/v3/pkg/w32/user32.go b/v3/pkg/w32/user32.go index 96701dffb..4117afd2e 100644 --- a/v3/pkg/w32/user32.go +++ b/v3/pkg/w32/user32.go @@ -178,6 +178,8 @@ var ( procRedrawWindow = moduser32.NewProc("RedrawWindow") + procRegisterWindowMessageW = moduser32.NewProc("RegisterWindowMessageW") + mainThread HANDLE ) @@ -299,9 +301,7 @@ func PostThreadMessage(threadID HANDLE, msg int, wp, lp uintptr) { } func RegisterWindowMessage(name *uint16) uint32 { - ret, _, _ := procRegisterWindowMessageA.Call( - uintptr(unsafe.Pointer(name))) - + ret, _, _ := procRegisterWindowMessageW.Call(uintptr(unsafe.Pointer(name))) return uint32(ret) }