Browse Source

fix: enable system maximization for frameless windows except if transparent (#28207)

* fix: move widget maximization check

* fix linting error

* change workaround to only effect transparent windows

* disable menu maximize and restore for transparent windows

* disable double clicking title bar max/unmax for transparent windows

* add docs change and address review
Michaela Laurencin 4 years ago
parent
commit
19d7a6b761

+ 3 - 1
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

+ 14 - 13
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() {

+ 26 - 3
shell/browser/native_window_views_win.cc

@@ -149,8 +149,8 @@ std::set<NativeWindowViews*> 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;
+    }
   }
 }