Browse Source

fix: WCO respects maximizable/closable/minimizable (#34733)

Co-authored-by: Shelley Vohr <[email protected]>
trop[bot] 2 years ago
parent
commit
4d060f0395

+ 15 - 0
shell/browser/native_window_views.cc

@@ -875,6 +875,11 @@ bool NativeWindowViews::IsMovable() {
 void NativeWindowViews::SetMinimizable(bool minimizable) {
 #if defined(OS_WIN)
   FlipWindowStyle(GetAcceleratedWidget(), minimizable, WS_MINIMIZEBOX);
+  if (titlebar_overlay_enabled()) {
+    auto* frame_view =
+        static_cast<WinFrameView*>(widget()->non_client_view()->frame_view());
+    frame_view->caption_button_container()->UpdateButtons();
+  }
 #endif
   minimizable_ = minimizable;
 }
@@ -890,6 +895,11 @@ bool NativeWindowViews::IsMinimizable() {
 void NativeWindowViews::SetMaximizable(bool maximizable) {
 #if defined(OS_WIN)
   FlipWindowStyle(GetAcceleratedWidget(), maximizable, WS_MAXIMIZEBOX);
+  if (titlebar_overlay_enabled()) {
+    auto* frame_view =
+        static_cast<WinFrameView*>(widget()->non_client_view()->frame_view());
+    frame_view->caption_button_container()->UpdateButtons();
+  }
 #endif
   maximizable_ = maximizable;
 }
@@ -925,6 +935,11 @@ void NativeWindowViews::SetClosable(bool closable) {
   } else {
     EnableMenuItem(menu, SC_CLOSE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
   }
+  if (titlebar_overlay_enabled()) {
+    auto* frame_view =
+        static_cast<WinFrameView*>(widget()->non_client_view()->frame_view());
+    frame_view->caption_button_container()->UpdateButtons();
+  }
 #endif
 }
 

+ 20 - 1
shell/browser/ui/views/win_caption_button_container.cc

@@ -148,11 +148,30 @@ void WinCaptionButtonContainer::UpdateButtons() {
   restore_button_->SetVisible(is_maximized);
   maximize_button_->SetVisible(!is_maximized);
 
+  const bool minimizable = frame_view_->window()->IsMinimizable();
+  minimize_button_->SetEnabled(minimizable);
+
   // In touch mode, windows cannot be taken out of fullscreen or tiled mode, so
   // the maximize/restore button should be disabled.
   const bool is_touch = ui::TouchUiController::Get()->touch_ui();
   restore_button_->SetEnabled(!is_touch);
-  maximize_button_->SetEnabled(!is_touch);
+
+  // The maximize button should only be enabled if the window is
+  // maximizable *and* touch mode is disabled.
+  const bool maximizable = frame_view_->window()->IsMaximizable();
+  maximize_button_->SetEnabled(!is_touch && maximizable);
+
+  const bool closable = frame_view_->window()->IsClosable();
+  close_button_->SetEnabled(closable);
+
+  // If all three of closable, maximizable, and minimizable are disabled,
+  // Windows natively only shows the disabled closable button. Copy that
+  // behavior here.
+  if (!maximizable && !closable && !minimizable) {
+    minimize_button_->SetVisible(false);
+    maximize_button_->SetVisible(false);
+  }
+
   InvalidateLayout();
 }
 }  // namespace electron

+ 5 - 5
shell/browser/ui/views/win_caption_button_container.h

@@ -41,6 +41,11 @@ class WinCaptionButtonContainer : public views::View,
   gfx::Size GetButtonSize() const;
   void SetButtonSize(gfx::Size size);
 
+  // Sets caption button visibility and enabled state based on window state.
+  // Only one of maximize or restore button should ever be visible at the same
+  // time, and both are disabled in tablet UI mode.
+  void UpdateButtons();
+
  private:
   // views::View:
   void AddedToWidget() override;
@@ -52,11 +57,6 @@ class WinCaptionButtonContainer : public views::View,
 
   void ResetWindowControls();
 
-  // Sets caption button visibility and enabled state based on window state.
-  // Only one of maximize or restore button should ever be visible at the same
-  // time, and both are disabled in tablet UI mode.
-  void UpdateButtons();
-
   WinFrameView* const frame_view_;
   WinCaptionButton* const minimize_button_;
   WinCaptionButton* const maximize_button_;

+ 4 - 0
shell/browser/ui/views/win_frame_view.h

@@ -13,6 +13,7 @@
 #include "shell/browser/native_window_views.h"
 #include "shell/browser/ui/views/frameless_view.h"
 #include "shell/browser/ui/views/win_caption_button.h"
+#include "shell/browser/ui/views/win_caption_button_container.h"
 
 namespace electron {
 
@@ -43,6 +44,9 @@ class WinFrameView : public FramelessView {
 
   NativeWindowViews* window() const { return window_; }
   views::Widget* frame() const { return frame_; }
+  WinCaptionButtonContainer* caption_button_container() {
+    return caption_button_container_;
+  }
 
   bool IsMaximized() const;