From ef51e4e1086de720b66b6e6e8f45b907f6aa7315 Mon Sep 17 00:00:00 2001 From: evgenyzinoviev Date: Fri, 22 Jan 2016 22:24:33 +0100 Subject: [PATCH] maximizable and fullscreenable --- atom/browser/api/atom_api_window.cc | 20 ++++++++++ atom/browser/api/atom_api_window.h | 4 ++ atom/browser/native_window.cc | 4 ++ atom/browser/native_window.h | 4 ++ atom/browser/native_window_mac.h | 5 ++- atom/browser/native_window_mac.mm | 76 +++++++++++++++++++++++++------------ atom/browser/native_window_views.cc | 40 ++++++++++++++----- atom/browser/native_window_views.h | 4 ++ atom/common/options_switches.cc | 38 ++++++++++--------- atom/common/options_switches.h | 2 + 10 files changed, 143 insertions(+), 54 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 5ff9cab..5bf15a0 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -424,6 +424,22 @@ bool Window::IsMinimizable() { return window_->IsMinimizable(); } +void Window::SetMaximizable(bool maximizable) { + window_->SetMaximizable(maximizable); +} + +bool Window::IsMaximizable() { + return window_->IsMaximizable(); +} + +void Window::SetFullscreenable(bool fullscreenable) { + window_->SetFullscreenable(fullscreenable); +} + +bool Window::IsFullscreenable() { + return window_->IsFullscreenable(); +} + void Window::SetClosable(bool closable) { window_->SetClosable(closable); } @@ -687,6 +703,10 @@ void Window::BuildPrototype(v8::Isolate* isolate, .SetMethod("isMovable", &Window::IsMovable) .SetMethod("setMinimizable", &Window::SetMinimizable) .SetMethod("isMinimizable", &Window::IsMinimizable) + .SetMethod("setMaximizable", &Window::SetMaximizable) + .SetMethod("isMaximizable", &Window::IsMaximizable) + .SetMethod("setFullscreenable", &Window::SetFullscreenable) + .SetMethod("isFullscreenable", &Window::IsFullscreenable) .SetMethod("setClosable", &Window::SetClosable) .SetMethod("isClosable", &Window::IsClosable) .SetMethod("setAlwaysOnTop", &Window::SetAlwaysOnTop) diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index ae10fa9..97d7d45 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -110,6 +110,10 @@ class Window : public mate::TrackableObject, bool IsMovable(); void SetMinimizable(bool minimizable); bool IsMinimizable(); + void SetMaximizable(bool maximizable); + bool IsMaximizable(); + void SetFullscreenable(bool fullscreenable); + bool IsFullscreenable(); void SetClosable(bool closable); bool IsClosable(); void SetAlwaysOnTop(bool top); diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 1f330a2..69bebc1 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -128,6 +128,10 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) { if (options.Get(options::kClosable, &closable)) { SetClosable(closable); } + bool maximizable; + if (options.Get(options::kMaximizable, &maximizable)) { + SetMaximizable(maximizable); + } #endif bool top; if (options.Get(options::kAlwaysOnTop, &top) && top) { diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index d379db2..31a104b 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -129,6 +129,10 @@ class NativeWindow : public base::SupportsUserData, virtual bool IsMovable() = 0; virtual void SetMinimizable(bool minimizable) = 0; virtual bool IsMinimizable() = 0; + virtual void SetMaximizable(bool maximizable) = 0; + virtual bool IsMaximizable() = 0; + virtual void SetFullscreenable(bool fullscreenable) = 0; + virtual bool IsFullscreenable() = 0; virtual void SetClosable(bool closable) = 0; virtual bool IsClosable() = 0; virtual void SetAlwaysOnTop(bool top) = 0; diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index 45c974c..9b9a702 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -52,6 +52,10 @@ class NativeWindowMac : public NativeWindow { bool IsMovable() override; void SetMinimizable(bool minimizable) override; bool IsMinimizable() override; + void SetMaximizable(bool maximizable) override; + bool IsMaximizable() override; + void SetFullscreenable(bool fullscreenable) override; + bool IsFullscreenable() override; void SetClosable(bool closable) override; bool IsClosable() override; void SetAlwaysOnTop(bool top) override; @@ -106,7 +110,6 @@ class NativeWindowMac : public NativeWindow { gfx::Size WindowSizeToContentSize(const gfx::Size& size) override; void UpdateDraggableRegions( const std::vector& regions) override; - void FixZoomButton(); void InstallView(); void UninstallView(); diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 1c91c5e..db42b37 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -371,6 +371,12 @@ NativeWindowMac::NativeWindowMac( bool minimizable = true; options.Get(options::kMinimizable, &minimizable); + + bool maximizable = true; + options.Get(options::kMaximizable, &maximizable); + + bool fullscreenable = true; + options.Get(options::kFullscreenable, &fullscreenable); bool closable = true; options.Get(options::kClosable, &closable); @@ -486,11 +492,10 @@ NativeWindowMac::NativeWindowMac( // Disable fullscreen button when 'fullscreen' is specified to false. bool fullscreen = false; - if (!(options.Get(options::kFullscreen, &fullscreen) && - !fullscreen)) { - NSUInteger collectionBehavior = [window_ collectionBehavior]; - collectionBehavior |= NSWindowCollectionBehaviorFullScreenPrimary; - [window_ setCollectionBehavior:collectionBehavior]; + options.Get(options::kFullscreen, &fullscreen); + + if (fullscreenable) { + SetFullscreenable(true); } else if (base::mac::IsOSElCapitanOrLater()) { // On EL Capitan this flag is required to hide fullscreen button. NSUInteger collectionBehavior = [window_ collectionBehavior]; @@ -499,8 +504,8 @@ NativeWindowMac::NativeWindowMac( } // Disable zoom button if window is not resizable - if (!resizable) { - [[window_ standardWindowButton:NSWindowZoomButton] setEnabled:NO]; + if (!maximizable) { + SetMaximizable(false); } NSView* view = inspectable_web_contents()->GetView()->GetNativeView(); @@ -648,12 +653,8 @@ void NativeWindowMac::SetResizable(bool resizable) { // to explicitly disables that. ScopedDisableResize disable_resize; if (resizable) { - [[window_ standardWindowButton:NSWindowZoomButton] setEnabled:YES]; [window_ setStyleMask:[window_ styleMask] | NSResizableWindowMask]; } else { - // If we disable the button before changing the styleMask, button is not - // disabled. Looks like a bug in Cocoa (OS X 10.10.5) - [window_ setStyleMask:[window_ styleMask] & (~NSResizableWindowMask)]; [[window_ standardWindowButton:NSWindowZoomButton] setEnabled:NO]; } } @@ -671,25 +672,62 @@ bool NativeWindowMac::IsMovable() { } void NativeWindowMac::SetMinimizable(bool minimizable) { + bool maximizable = IsMaximizable(); if (minimizable) { [window_ setStyleMask:[window_ styleMask] | NSMiniaturizableWindowMask]; } else { [window_ setStyleMask:[window_ styleMask] & (~NSMiniaturizableWindowMask)]; } - FixZoomButton(); + // If fullscreen has not been disabled via `fullscreenable: false` (i.e. when + // collectionBehavior has NSWindowCollectionBehaviorFullScreenPrimary mask), + // zoom button is reset to it's default (enabled) state when window's + // styleMask has been changed. So if the button was disabled, we have to + // disable it again. I think it's a bug in Cocoa. + if (!maximizable) { + SetMaximizable(false); + } } bool NativeWindowMac::IsMinimizable() { return [window_ styleMask] & NSMiniaturizableWindowMask; } +void NativeWindowMac::SetMaximizable(bool maximizable) { + [[window_ standardWindowButton:NSWindowZoomButton] setEnabled:maximizable]; +} + +bool NativeWindowMac::IsMaximizable() { + return [[window_ standardWindowButton:NSWindowZoomButton] isEnabled]; +} + +void NativeWindowMac::SetFullscreenable(bool fullscreenable) { + bool maximizable = IsMaximizable(); + NSUInteger collectionBehavior = [window_ collectionBehavior]; + if (fullscreenable) { + collectionBehavior |= NSWindowCollectionBehaviorFullScreenPrimary; + } else { + collectionBehavior &= (~NSWindowCollectionBehaviorFullScreenPrimary); + } + [window_ setCollectionBehavior:collectionBehavior]; + if (!maximizable) { + SetMaximizable(false); + } +} + +bool NativeWindowMac::IsFullscreenable() { + return [window_ collectionBehavior] & NSWindowCollectionBehaviorFullScreenPrimary; +} + void NativeWindowMac::SetClosable(bool closable) { + bool maximizable = IsMaximizable(); if (closable) { [window_ setStyleMask:[window_ styleMask] | NSClosableWindowMask]; } else { [window_ setStyleMask:[window_ styleMask] & (~NSClosableWindowMask)]; } - FixZoomButton(); + if (!maximizable) { + SetMaximizable(false); + } } bool NativeWindowMac::IsClosable() { @@ -700,18 +738,6 @@ void NativeWindowMac::SetAlwaysOnTop(bool top) { [window_ setLevel:(top ? NSFloatingWindowLevel : NSNormalWindowLevel)]; } -void NativeWindowMac::FixZoomButton() { - // If fullscreen has not been disabled via `fullscreen: false` (i.e. when - // collectionBehavior has NSWindowCollectionBehaviorFullScreenPrimary mask), - // zoom button is reset to it's default (enabled) state when window's - // styleMask has been changed. So if the button was disabled, we have to - // disable it again. I think it's a bug in Cocoa. - if ([window_ collectionBehavior] & NSWindowCollectionBehaviorFullScreenPrimary - && !([window_ styleMask] & NSResizableWindowMask)) { - [[window_ standardWindowButton:NSWindowZoomButton] setEnabled:NO]; - } -} - bool NativeWindowMac::IsAlwaysOnTop() { return [window_ level] == NSFloatingWindowLevel; } diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index e97a1f3..012f6c6 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -139,6 +139,7 @@ NativeWindowViews::NativeWindowViews( options.Get(options::kResizable, &resizable_); options.Get(options::kMovable, &movable_); options.Get(options::kMinimizable, &minimizable_); + options.Get(options::kMaximizable, &maximizable_); #endif if (enable_larger_than_screen()) @@ -187,9 +188,7 @@ NativeWindowViews::NativeWindowViews( window_->Init(params); bool fullscreen = false; - if (options.Get(options::kFullscreen, &fullscreen) && !fullscreen) { - maximizable_ = false; - } + options.Get(options::kFullscreen, &fullscreen); #if defined(USE_X11) // Start monitoring window states. @@ -245,11 +244,6 @@ NativeWindowViews::NativeWindowViews( DWORD style = ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE); style |= WS_THICKFRAME | WS_CAPTION | WS_MINIMIZEBOX; - if (!maximizable_) { - style &= (~WS_MAXIMIZEBOX); - } else { - style |= WS_MAXIMIZEBOX; - } if (transparent()) { DWORD ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE); @@ -441,9 +435,8 @@ void NativeWindowViews::SetResizable(bool resizable) { DWORD style = ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE); if (resizable) { style |= WS_THICKFRAME; - if (maximizable_) style |= WS_MAXIMIZEBOX; } else { - style &= ~(WS_THICKFRAME | WS_MAXIMIZEBOX); + style &= ~(WS_THICKFRAME); } ::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, style); } @@ -505,6 +498,33 @@ bool NativeWindowViews::IsMinimizable() { #endif } +void NativeWindowViews::SetMaximizable(bool maximizable) { +#if defined(OS_WIN) + DWORD style = ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE); + if (maximizable) { + style |= WS_MAXIMIZEBOX; + } else { + style &= (~WS_MAXIMIZEBOX); + } + ::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, style); +#endif +} + +bool NativeWindowViews::IsMaximizable() { +#if defined(OS_WIN) + return ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE) & WS_MAXIMIZEBOX; +#elif defined(USE_X11) + return true; +#endif +} + +void NativeWindowViews::SetFullscreenable(bool maximizable) { +} + +bool NativeWindowViews::IsFullscreenable() { + return true; +} + void NativeWindowViews::SetClosable(bool closable) { #if defined(OS_WIN) HMENU menu = GetSystemMenu(GetAcceleratedWidget(), false); diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index d3117e5..7f947b8 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -72,6 +72,10 @@ class NativeWindowViews : public NativeWindow, bool IsMovable() override; void SetMinimizable(bool minimizable) override; bool IsMinimizable() override; + void SetMaximizable(bool maximizable) override; + bool IsMaximizable() override; + void SetFullscreenable(bool fullscreenable) override; + bool IsFullscreenable() override; void SetClosable(bool closable) override; bool IsClosable() override; void SetAlwaysOnTop(bool top) override; diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index e14a63e..505c386 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -8,24 +8,26 @@ namespace atom { namespace options { -const char kTitle[] = "title"; -const char kIcon[] = "icon"; -const char kFrame[] = "frame"; -const char kShow[] = "show"; -const char kCenter[] = "center"; -const char kX[] = "x"; -const char kY[] = "y"; -const char kWidth[] = "width"; -const char kHeight[] = "height"; -const char kMinWidth[] = "minWidth"; -const char kMinHeight[] = "minHeight"; -const char kMaxWidth[] = "maxWidth"; -const char kMaxHeight[] = "maxHeight"; -const char kResizable[] = "resizable"; -const char kMovable[] = "movable"; -const char kMinimizable[] = "minimizable"; -const char kClosable[] = "closable"; -const char kFullscreen[] = "fullscreen"; +const char kTitle[] = "title"; +const char kIcon[] = "icon"; +const char kFrame[] = "frame"; +const char kShow[] = "show"; +const char kCenter[] = "center"; +const char kX[] = "x"; +const char kY[] = "y"; +const char kWidth[] = "width"; +const char kHeight[] = "height"; +const char kMinWidth[] = "minWidth"; +const char kMinHeight[] = "minHeight"; +const char kMaxWidth[] = "maxWidth"; +const char kMaxHeight[] = "maxHeight"; +const char kResizable[] = "resizable"; +const char kMovable[] = "movable"; +const char kMinimizable[] = "minimizable"; +const char kMaximizable[] = "maximizable"; +const char kFullscreenable[] = "fullscreenable"; +const char kClosable[] = "closable"; +const char kFullscreen[] = "fullscreen"; // Whether the window should show in taskbar. const char kSkipTaskbar[] = "skipTaskbar"; diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index f7b68f2..476baaf 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -25,6 +25,8 @@ extern const char kMaxHeight[]; extern const char kResizable[]; extern const char kMovable[]; extern const char kMinimizable[]; +extern const char kMaximizable[]; +extern const char kFullscreenable[]; extern const char kClosable[]; extern const char kFullscreen[]; extern const char kSkipTaskbar[]; -- 2.7.4