diff --git a/docs/api/frameless-window.md b/docs/api/frameless-window.md index 84290119edce2..8bb253e1948c2 100644 --- a/docs/api/frameless-window.md +++ b/docs/api/frameless-window.md @@ -83,8 +83,10 @@ win.show() blur effect to the content below the window (i.e. other applications open on the user's system). * The window will not be transparent when DevTools is opened. -* On Windows operating systems, transparent windows will not work when DWM is +* On Windows operating systems, + * transparent windows will not work when DWM is disabled. + * transparent windows can not be maximized using the Windows system menu or by double clicking the title bar. The reasoning behind this can be seen on [this pull request](https://github.com/electron/electron/pull/28207). * On Linux, users have to put `--enable-transparent-visuals --disable-gpu` in the command line to disable GPU and allow ARGB to make transparent window, this is caused by an upstream bug that [alpha channel doesn't work on some diff --git a/shell/browser/native_window_views.cc b/shell/browser/native_window_views.cc index 1cc596f392d85..ae21549889c0e 100644 --- a/shell/browser/native_window_views.cc +++ b/shell/browser/native_window_views.cc @@ -530,7 +530,7 @@ void NativeWindowViews::Maximize() { void NativeWindowViews::Unmaximize() { #if defined(OS_WIN) - if (!(::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE) & WS_THICKFRAME)) { + if (transparent()) { SetBounds(restore_bounds_, false); return; } @@ -540,21 +540,22 @@ void NativeWindowViews::Unmaximize() { } bool NativeWindowViews::IsMaximized() { - // For window without WS_THICKFRAME style, we can not call IsMaximized(). - // This path will be used for transparent windows as well. - + if (widget()->IsMaximized()) { + return true; + } else { #if defined(OS_WIN) - if (!(::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE) & WS_THICKFRAME)) { - // Compare the size of the window with the size of the display - auto display = display::Screen::GetScreen()->GetDisplayNearestWindow( - GetNativeWindow()); - // Maximized if the window is the same dimensions and placement as the - // display - return GetBounds() == display.work_area(); - } + if (transparent()) { + // Compare the size of the window with the size of the display + auto display = display::Screen::GetScreen()->GetDisplayNearestWindow( + GetNativeWindow()); + // Maximized if the window is the same dimensions and placement as the + // display + return GetBounds() == display.work_area(); + } #endif - return widget()->IsMaximized(); + return false; + } } void NativeWindowViews::Minimize() { diff --git a/shell/browser/native_window_views_win.cc b/shell/browser/native_window_views_win.cc index 9c0e0908421af..0ff2b7ad14af4 100644 --- a/shell/browser/native_window_views_win.cc +++ b/shell/browser/native_window_views_win.cc @@ -149,8 +149,8 @@ std::set NativeWindowViews::forwarding_windows_; HHOOK NativeWindowViews::mouse_hook_ = NULL; void NativeWindowViews::Maximize() { - // Only use Maximize() when window has WS_THICKFRAME style - if (::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE) & WS_THICKFRAME) { + // Only use Maximize() when window is NOT transparent style + if (!transparent()) { if (IsVisible()) widget()->Maximize(); else @@ -324,8 +324,31 @@ bool NativeWindowViews::PreHandleMSG(UINT message, GET_Y_LPARAM(l_param), &prevent_default); return prevent_default; } - default: + case WM_SYSCOMMAND: { + // Mask is needed to account for double clicking title bar to maximize + WPARAM max_mask = 0xFFF0; + if (transparent() && ((w_param & max_mask) == SC_MAXIMIZE)) { + return true; + } + return false; + } + case WM_INITMENU: { + // This is handling the scenario where the menu might get triggered by the + // user doing "alt + space" resulting in system maximization and restore + // being used on transparent windows when that does not work. + if (transparent()) { + HMENU menu = GetSystemMenu(GetAcceleratedWidget(), false); + EnableMenuItem(menu, SC_MAXIMIZE, + MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + EnableMenuItem(menu, SC_RESTORE, + MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + return true; + } + return false; + } + default: { return false; + } } }