From aaf039bcfff0ed7f0c1105af531b0bcb96457963 Mon Sep 17 00:00:00 2001 From: stffabi Date: Wed, 11 Jan 2023 15:22:48 +0100 Subject: [PATCH] [windows] Disable frameless decorations during fullscreen (#2288) Otherwise this leads to thin transparent lines on the window borders on older Windows versions. --- .../frontend/desktop/windows/win32/window.go | 9 ++-- .../frontend/desktop/windows/window.go | 41 +++++++++++++------ website/src/pages/changelog.mdx | 2 +- 3 files changed, 35 insertions(+), 17 deletions(-) diff --git a/v2/internal/frontend/desktop/windows/win32/window.go b/v2/internal/frontend/desktop/windows/win32/window.go index 1d6c9438c..6028789de 100644 --- a/v2/internal/frontend/desktop/windows/win32/window.go +++ b/v2/internal/frontend/desktop/windows/win32/window.go @@ -81,14 +81,17 @@ type MONITORINFO struct { DwFlags uint32 } -func ExtendFrameIntoClientArea(hwnd uintptr) { +func ExtendFrameIntoClientArea(hwnd uintptr, extend bool) { // -1: Adds the default frame styling (aero shadow and e.g. rounded corners on Windows 11) // Also shows the caption buttons if transparent ant translucent but they don't work. // 0: Adds the default frame styling but no aero shadow, does not show the caption buttons. // 1: Adds the default frame styling (aero shadow and e.g. rounded corners on Windows 11) but no caption buttons // are shown if transparent ant translucent. - margins := &MARGINS{1, 1, 1, 1} // Only extend 1 pixel to have the default frame styling but no caption buttons - if err := dwmExtendFrameIntoClientArea(hwnd, margins); err != nil { + var margins MARGINS + if extend { + margins = MARGINS{1, 1, 1, 1} // Only extend 1 pixel to have the default frame styling but no caption buttons + } + if err := dwmExtendFrameIntoClientArea(hwnd, &margins); err != nil { log.Fatal(fmt.Errorf("DwmExtendFrameIntoClientArea failed: %s", err)) } } diff --git a/v2/internal/frontend/desktop/windows/window.go b/v2/internal/frontend/desktop/windows/window.go index f57b4cb6a..c6db8567a 100644 --- a/v2/internal/frontend/desktop/windows/window.go +++ b/v2/internal/frontend/desktop/windows/window.go @@ -31,6 +31,8 @@ type Window struct { theme winoptions.Theme themeChanged bool + framelessWithDecorations bool + OnSuspend func() OnResume func() dragging bool @@ -39,6 +41,8 @@ type Window struct { } func NewWindow(parent winc.Controller, appoptions *options.App, versionInfo *operatingsystem.WindowsVersionInfo, chromium *edge.Chromium) *Window { + windowsOptions := appoptions.Windows + result := &Window{ frontendOptions: appoptions, minHeight: appoptions.MinHeight, @@ -49,13 +53,15 @@ func NewWindow(parent winc.Controller, appoptions *options.App, versionInfo *ope isActive: true, themeChanged: true, chromium: chromium, + + framelessWithDecorations: appoptions.Frameless && (windowsOptions == nil || !windowsOptions.DisableFramelessWindowDecorations), } result.SetIsForm(true) var exStyle int - if appoptions.Windows != nil { + if windowsOptions != nil { exStyle = w32.WS_EX_CONTROLPARENT | w32.WS_EX_APPWINDOW - if appoptions.Windows.WindowIsTranslucent { + if windowsOptions.WindowIsTranslucent { exStyle |= w32.WS_EX_NOREDIRECTIONBITMAP } } @@ -72,7 +78,7 @@ func NewWindow(parent winc.Controller, appoptions *options.App, versionInfo *ope result.SetParent(parent) loadIcon := true - if appoptions.Windows != nil && appoptions.Windows.DisableWindowIcon == true { + if windowsOptions != nil && windowsOptions.DisableWindowIcon == true { loadIcon = false } if loadIcon { @@ -85,8 +91,8 @@ func NewWindow(parent winc.Controller, appoptions *options.App, versionInfo *ope win32.SetBackgroundColour(result.Handle(), appoptions.BackgroundColour.R, appoptions.BackgroundColour.G, appoptions.BackgroundColour.B) } - if appoptions.Windows != nil { - result.theme = appoptions.Windows.Theme + if windowsOptions != nil { + result.theme = windowsOptions.Theme } else { result.theme = winoptions.SystemDefault } @@ -102,18 +108,18 @@ func NewWindow(parent winc.Controller, appoptions *options.App, versionInfo *ope result.UpdateTheme() - if appoptions.Windows != nil { - result.OnSuspend = appoptions.Windows.OnSuspend - result.OnResume = appoptions.Windows.OnResume - if appoptions.Windows.WindowIsTranslucent { + if windowsOptions != nil { + result.OnSuspend = windowsOptions.OnSuspend + result.OnResume = windowsOptions.OnResume + if windowsOptions.WindowIsTranslucent { if !win32.SupportsBackdropTypes() { result.SetTranslucentBackground() } else { - win32.EnableTranslucency(result.Handle(), win32.BackdropType(appoptions.Windows.BackdropType)) + win32.EnableTranslucency(result.Handle(), win32.BackdropType(windowsOptions.BackdropType)) } } - if appoptions.Windows.DisableWindowIcon { + if windowsOptions.DisableWindowIcon { result.DisableIcon() } } @@ -131,6 +137,12 @@ func NewWindow(parent winc.Controller, appoptions *options.App, versionInfo *ope } func (w *Window) Fullscreen() { + if w.Form.IsFullScreen() { + return + } + if w.framelessWithDecorations { + win32.ExtendFrameIntoClientArea(w.Handle(), false) + } w.Form.SetMaxSize(0, 0) w.Form.SetMinSize(0, 0) w.Form.Fullscreen() @@ -140,6 +152,9 @@ func (w *Window) UnFullscreen() { if !w.Form.IsFullScreen() { return } + if w.framelessWithDecorations { + win32.ExtendFrameIntoClientArea(w.Handle(), true) + } w.Form.UnFullscreen() w.SetMinSize(w.minWidth, w.minHeight) w.SetMaxSize(w.maxWidth, w.maxHeight) @@ -231,8 +246,8 @@ func (w *Window) WndProc(msg uint32, wparam, lparam uintptr) uintptr { // This Option is not affected by returning 0 in WM_NCCALCSIZE. // As a result we have hidden the titlebar but still have the default window frame styling. // See: https://docs.microsoft.com/en-us/windows/win32/api/dwmapi/nf-dwmapi-dwmextendframeintoclientarea#remarks - if winoptions := w.frontendOptions.Windows; winoptions == nil || !winoptions.DisableFramelessWindowDecorations { - win32.ExtendFrameIntoClientArea(w.Handle()) + if w.framelessWithDecorations { + win32.ExtendFrameIntoClientArea(w.Handle(), true) } case w32.WM_NCCALCSIZE: // Disable the standard frame by allowing the client area to take the full diff --git a/website/src/pages/changelog.mdx b/website/src/pages/changelog.mdx index 71617b863..9e0423f4a 100644 --- a/website/src/pages/changelog.mdx +++ b/website/src/pages/changelog.mdx @@ -19,7 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added `EnableFraudulentWebsiteDetection` option to opt-in to scan services for fraudulent content, such as malware or phishing attempts. Older releases had the scan services per default activated. Added by @stffabi in [PR](https://github.com/wailsapp/wails/pull/2269) ### Changed -- Improved fullscreen mode for frameless window on Windows. Changed by @stffabi in [PR](https://github.com/wailsapp/wails/pull/2279) +- Improved fullscreen mode for frameless window on Windows. Changed by @stffabi in [PR](https://github.com/wailsapp/wails/pull/2279) and [PR](https://github.com/wailsapp/wails/pull/2288) - On Windows unmaximising a window has no effect anymore when the window is in fullscreen mode, this makes it consistent with e.g. macOS. Changed by @stffabi in [PR](https://github.com/wailsapp/wails/pull/2279) - Frameless resize now sets the cursor on documentElement, otherwise resizing cursor won't be shown outside of the body rectangle. Changed by @stffabi in [PR](https://github.com/wailsapp/wails/pull/2289)