From 5372b6cd9137c18310836be947ee28d8cd0fd434 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 22 Jan 2016 23:47:37 -0800 Subject: [PATCH 1/9] Fullscreenable => FullScreenable --- atom/browser/api/atom_api_window.cc | 12 ++++++------ atom/browser/api/atom_api_window.h | 4 ++-- atom/browser/native_window.h | 4 ++-- atom/browser/native_window_mac.h | 4 ++-- atom/browser/native_window_mac.mm | 8 ++++---- atom/browser/native_window_views.cc | 4 ++-- atom/browser/native_window_views.h | 4 ++-- atom/common/options_switches.cc | 2 +- atom/common/options_switches.h | 2 +- docs/api/browser-window.md | 4 ++-- 10 files changed, 24 insertions(+), 24 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index cebd4ec3af..6b787e407b 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -432,12 +432,12 @@ bool Window::IsMaximizable() { return window_->IsMaximizable(); } -void Window::SetFullscreenable(bool fullscreenable) { - window_->SetFullscreenable(fullscreenable); +void Window::SetFullScreenable(bool fullscreenable) { + window_->SetFullScreenable(fullscreenable); } -bool Window::IsFullscreenable() { - return window_->IsFullscreenable(); +bool Window::IsFullScreenable() { + return window_->IsFullScreenable(); } void Window::SetClosable(bool closable) { @@ -713,8 +713,8 @@ void Window::BuildPrototype(v8::Isolate* isolate, .SetMethod("isMinimizable", &Window::IsMinimizable) .SetMethod("setMaximizable", &Window::SetMaximizable) .SetMethod("isMaximizable", &Window::IsMaximizable) - .SetMethod("setFullscreenable", &Window::SetFullscreenable) - .SetMethod("isFullscreenable", &Window::IsFullscreenable) + .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 ad5ee180fa..760fbb542b 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -112,8 +112,8 @@ class Window : public mate::TrackableObject, bool IsMinimizable(); void SetMaximizable(bool maximizable); bool IsMaximizable(); - void SetFullscreenable(bool fullscreenable); - bool IsFullscreenable(); + void SetFullScreenable(bool fullscreenable); + bool IsFullScreenable(); void SetClosable(bool closable); bool IsClosable(); void SetAlwaysOnTop(bool top); diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index bb81b11269..2b715e6535 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -131,8 +131,8 @@ class NativeWindow : public base::SupportsUserData, 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 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 98bfca67b1..83c2dffe66 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -54,8 +54,8 @@ class NativeWindowMac : public NativeWindow { bool IsMinimizable() override; void SetMaximizable(bool maximizable) override; bool IsMaximizable() override; - void SetFullscreenable(bool fullscreenable) override; - bool IsFullscreenable() 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/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 9459931d64..9a20e13188 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -376,7 +376,7 @@ NativeWindowMac::NativeWindowMac( options.Get(options::kMaximizable, &maximizable); bool fullscreenable = true; - options.Get(options::kFullscreenable, &fullscreenable); + options.Get(options::kFullScreenable, &fullscreenable); bool closable = true; options.Get(options::kClosable, &closable); @@ -501,7 +501,7 @@ NativeWindowMac::NativeWindowMac( options.Get(options::kFullscreen, &fullscreen); if (fullscreenable) { - SetFullscreenable(true); + SetFullScreenable(true); } else if (base::mac::IsOSElCapitanOrLater()) { // On EL Capitan this flag is required to hide fullscreen button. NSUInteger collectionBehavior = [window_ collectionBehavior]; @@ -710,7 +710,7 @@ bool NativeWindowMac::IsMaximizable() { return [[window_ standardWindowButton:NSWindowZoomButton] isEnabled]; } -void NativeWindowMac::SetFullscreenable(bool fullscreenable) { +void NativeWindowMac::SetFullScreenable(bool fullscreenable) { bool maximizable = IsMaximizable(); NSUInteger collectionBehavior = [window_ collectionBehavior]; if (fullscreenable) { @@ -724,7 +724,7 @@ void NativeWindowMac::SetFullscreenable(bool fullscreenable) { } } -bool NativeWindowMac::IsFullscreenable() { +bool NativeWindowMac::IsFullScreenable() { return [window_ collectionBehavior] & NSWindowCollectionBehaviorFullScreenPrimary; } diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index d6977dfd2d..c51bdce0f5 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -495,10 +495,10 @@ bool NativeWindowViews::IsMaximizable() { #endif } -void NativeWindowViews::SetFullscreenable(bool maximizable) { +void NativeWindowViews::SetFullScreenable(bool maximizable) { } -bool NativeWindowViews::IsFullscreenable() { +bool NativeWindowViews::IsFullScreenable() { return true; } diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index 7f947b8e98..98339f8aa6 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -74,8 +74,8 @@ class NativeWindowViews : public NativeWindow, bool IsMinimizable() override; void SetMaximizable(bool maximizable) override; bool IsMaximizable() override; - void SetFullscreenable(bool fullscreenable) override; - bool IsFullscreenable() 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 071c0bec77..ac63ea1b72 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -25,7 +25,7 @@ const char kResizable[] = "resizable"; const char kMovable[] = "movable"; const char kMinimizable[] = "minimizable"; const char kMaximizable[] = "maximizable"; -const char kFullscreenable[] = "fullscreenable"; +const char kFullScreenable[] = "fullscreenable"; const char kClosable[] = "closable"; const char kFullscreen[] = "fullscreen"; diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index 861ac3138f..3c198555a5 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -26,7 +26,7 @@ extern const char kResizable[]; extern const char kMovable[]; extern const char kMinimizable[]; extern const char kMaximizable[]; -extern const char kFullscreenable[]; +extern const char kFullScreenable[]; extern const char kClosable[]; extern const char kFullscreen[]; extern const char kSkipTaskbar[]; diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 0cc59fbb68..6b6fa3c160 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -575,14 +575,14 @@ nothing. Returns whether the window can be manually maximized by user. On Linux always returns `true`. -### `win.setFullscreenable(fullscreenable)` _OS X_ +### `win.setFullScreenable(fullscreenable)` _OS X_ * `fullscreenable` Boolean Sets whether the maximize/zoom window button toggles fullscreen mode or maximizes the window. On Windows and Linux does nothing. -### `win.isFullscreenable()` _OS X_ +### `win.isFullScreenable()` _OS X_ Returns whether the maximize/zoom window button toggles fullscreen mode or maximizes the window. On Windows and Linux always returns `true`. From ae7e96f181cdb6329e4892e83bc2aa21843b08f0 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 22 Jan 2016 23:51:52 -0800 Subject: [PATCH 2/9] Fix fullscreenable on EL Capitan --- atom/browser/native_window_mac.mm | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 9a20e13188..fe141869cb 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -371,13 +371,10 @@ 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); @@ -496,17 +493,15 @@ NativeWindowMac::NativeWindowMac( options.Get(options::kDisableAutoHideCursor, &disableAutoHideCursor); [window_ setDisableAutoHideCursor:disableAutoHideCursor]; - // Disable fullscreen button when 'fullscreen' is specified to false. + // Disable fullscreen button when 'fullscreenable' is false or 'fullscreen' + // is specified to false. + bool fullscreenable = true; + options.Get(options::kFullScreenable, &fullscreenable); bool fullscreen = false; - 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]; - collectionBehavior |= NSWindowCollectionBehaviorFullScreenAuxiliary; - [window_ setCollectionBehavior:collectionBehavior]; + if (options.Get(options::kFullscreen, &fullscreen) && !fullscreen) + fullscreenable = false; + if (!fullscreenable) { + SetFullScreenable(false); } // Disable zoom button if window is not resizable @@ -717,6 +712,8 @@ void NativeWindowMac::SetFullScreenable(bool fullscreenable) { collectionBehavior |= NSWindowCollectionBehaviorFullScreenPrimary; } else { collectionBehavior &= (~NSWindowCollectionBehaviorFullScreenPrimary); + // On EL Capitan this flag is required to hide fullscreen button. + collectionBehavior |= NSWindowCollectionBehaviorFullScreenAuxiliary; } [window_ setCollectionBehavior:collectionBehavior]; if (!maximizable) { From d704b3f7ba93c1a549795e820fa7ab11617d8333 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 23 Jan 2016 02:23:18 -0800 Subject: [PATCH 3/9] Reorgnize how attributes work --- atom/browser/native_window.cc | 16 +--- atom/browser/native_window_mac.mm | 11 +-- atom/browser/native_window_views.cc | 101 +++++++++++------------- atom/browser/native_window_views.h | 2 +- atom/browser/native_window_views_win.cc | 3 +- 5 files changed, 55 insertions(+), 78 deletions(-) diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 4435915db0..7d0ae5a5b7 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -116,23 +116,15 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) { SetSizeConstraints(size_constraints); } #if defined(OS_WIN) || defined(USE_X11) - bool resizable; - if (options.Get(options::kResizable, &resizable)) { - SetResizable(resizable); - } - bool minimizable; - if (options.Get(options::kMinimizable, &minimizable)) { - SetMinimizable(minimizable); - } bool closable; if (options.Get(options::kClosable, &closable)) { SetClosable(closable); } - bool maximizable; - if (options.Get(options::kMaximizable, &maximizable)) { - SetMaximizable(maximizable); - } #endif + bool movable; + if (options.Get(options::kMovable, &movable) && movable) { + SetMovable(movable); + } bool top; if (options.Get(options::kAlwaysOnTop, &top) && top) { SetAlwaysOnTop(true); diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index fe141869cb..e989ad90d4 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -394,12 +394,12 @@ NativeWindowMac::NativeWindowMac( useStandardWindow = false; } - NSUInteger styleMask = NSTitledWindowMask | NSClosableWindowMask; + NSUInteger styleMask = NSTitledWindowMask; if (minimizable) { styleMask |= NSMiniaturizableWindowMask; } - if (!closable) { - styleMask &= ~NSClosableWindowMask; + if (closable) { + styleMask |= NSClosableWindowMask; } if (!useStandardWindow || transparent() || !has_frame()) { styleMask |= NSTexturedBackgroundWindowMask; @@ -472,11 +472,6 @@ NativeWindowMac::NativeWindowMac( set_force_using_draggable_region(true); } - bool movable; - if (options.Get(options::kMovable, &movable)) { - [window_ setMovable:movable]; - } - // On OS X the initial window size doesn't include window frame. bool use_content_size = false; options.Get(options::kUseContentSize, &use_content_size); diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index c51bdce0f5..216a76ec6b 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -59,6 +59,17 @@ const int kMenuBarHeight = 20; const int kMenuBarHeight = 25; #endif +#if defined(OS_WIN) +void FlipWindowStyle(HWND handle, bool on, DWORD flag) { + DWORD style = ::GetWindowLong(handle, GWL_STYLE); + if (on) + style |= flag; + else + style &= ~flag; + ::SetWindowLong(handle, GWL_STYLE, style); +} +#endif + bool IsAltKey(const content::NativeWebKeyboardEvent& event) { return event.windowsKeyCode == ui::VKEY_MENU; } @@ -103,9 +114,9 @@ NativeWindowViews::NativeWindowViews( menu_bar_alt_pressed_(false), keyboard_event_handler_(new views::UnhandledKeyboardEventHandler), use_content_size_(false), + movable_(true), resizable_(true), maximizable_(true), - movable_(true), minimizable_(true) { options.Get(options::kTitle, &title_); options.Get(options::kAutoHideMenuBar, &menu_bar_autohide_); @@ -114,7 +125,6 @@ NativeWindowViews::NativeWindowViews( // On Windows we rely on the CanResize() to indicate whether window can be // resized, and it should be set before window is created. options.Get(options::kResizable, &resizable_); - options.Get(options::kMovable, &movable_); options.Get(options::kMinimizable, &minimizable_); options.Get(options::kMaximizable, &maximizable_); #endif @@ -216,25 +226,29 @@ NativeWindowViews::NativeWindowViews( last_window_state_ = ui::SHOW_STATE_FULLSCREEN; else last_window_state_ = ui::SHOW_STATE_NORMAL; - last_normal_size_ = gfx::Size(widget_size_); - DWORD style = ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE); - style |= WS_THICKFRAME | WS_CAPTION | WS_MINIMIZEBOX; - - if (transparent()) { - DWORD ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE); - ex_style |= WS_EX_COMPOSITED; - ::SetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE, ex_style); - - if (!has_frame()) { - // We should not show a frame for transparent window. - style &= ~(WS_THICKFRAME | WS_CAPTION); - } + if (!has_frame()) { + // Set Window style so that we get a minimize and maximize animation when + // frameless. + DWORD frame_style = WS_CAPTION; + if (resizable_) + frame_style |= WS_THICKFRAME; + if (minimizable_) + frame_style |= WS_MINIMIZEBOX; + if (maximizable_) + frame_style |= WS_MAXIMIZEBOX; + // We should not show a frame for transparent window. + if (transparent()) + frame_style &= ~(WS_THICKFRAME | WS_CAPTION); + ::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, frame_style); } - if (!transparent() || !has_frame()) { - ::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, style); + if (transparent()) { + // Transparent window on Windows has to have WS_EX_COMPOSITED style. + LONG ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE); + ex_style |= WS_EX_COMPOSITED; + ::SetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE, ex_style); } #endif @@ -405,18 +419,8 @@ void NativeWindowViews::SetContentSizeConstraints( void NativeWindowViews::SetResizable(bool resizable) { #if defined(OS_WIN) - // WS_MAXIMIZEBOX => Maximize button - // WS_MINIMIZEBOX => Minimize button - // WS_THICKFRAME => Resize handle - if (!transparent()) { - DWORD style = ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE); - if (resizable) { - style |= WS_THICKFRAME; - } else { - style &= ~(WS_THICKFRAME); - } - ::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, style); - } + if (!transparent()) + FlipWindowStyle(GetAcceleratedWidget(), resizable, WS_THICKFRAME); #elif defined(USE_X11) if (resizable != resizable_) { // On Linux there is no "resizable" property of a window, we have to set @@ -437,7 +441,7 @@ void NativeWindowViews::SetResizable(bool resizable) { } bool NativeWindowViews::IsResizable() { - return resizable_; + return CanResize(); } void NativeWindowViews::SetMovable(bool movable) { @@ -447,51 +451,38 @@ void NativeWindowViews::SetMovable(bool movable) { bool NativeWindowViews::IsMovable() { #if defined(OS_WIN) return movable_; -#elif defined(USE_X11) - return true; +#else + return true; // Not implemented on Linux. #endif } void NativeWindowViews::SetMinimizable(bool minimizable) { #if defined(OS_WIN) - if (!transparent()) { - DWORD style = ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE); - if (minimizable) - style |= WS_MINIMIZEBOX; - else - style &= (~WS_MINIMIZEBOX); - ::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, style); - } + FlipWindowStyle(GetAcceleratedWidget(), minimizable, WS_MINIMIZEBOX); #endif - minimizable_ = minimizable; } bool NativeWindowViews::IsMinimizable() { #if defined(OS_WIN) - return ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE) & WS_MINIMIZEBOX; -#elif defined(USE_X11) - return true; + return CanMinimize(); +#else + return true; // CanMinimize() Not implemented on Linux. #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); + FlipWindowStyle(GetAcceleratedWidget(), maximizable, WS_MAXIMIZEBOX); #endif + maximizable_ = maximizable; } bool NativeWindowViews::IsMaximizable() { #if defined(OS_WIN) - return ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE) & WS_MAXIMIZEBOX; -#elif defined(USE_X11) - return true; + return CanMaximize(); +#else + return true; // CanMaximize() Not implemented on Linux. #endif } @@ -786,7 +777,7 @@ bool NativeWindowViews::CanResize() const { } bool NativeWindowViews::CanMaximize() const { - return resizable_; + return resizable_ && maximizable_; } bool NativeWindowViews::CanMinimize() const { diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index 98339f8aa6..61d0f95042 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -206,9 +206,9 @@ class NativeWindowViews : public NativeWindow, accelerator_util::AcceleratorTable accelerator_table_; bool use_content_size_; + bool movable_; bool resizable_; bool maximizable_; - bool movable_; bool minimizable_; std::string title_; gfx::Size widget_size_; diff --git a/atom/browser/native_window_views_win.cc b/atom/browser/native_window_views_win.cc index 53228d5fdf..e5ed1975f8 100644 --- a/atom/browser/native_window_views_win.cc +++ b/atom/browser/native_window_views_win.cc @@ -96,9 +96,8 @@ bool NativeWindowViews::PreHandleMSG( return false; case WM_MOVING: { - if (!movable_) { + if (!movable_) ::GetWindowRect(GetAcceleratedWidget(), (LPRECT)l_param); - } return false; } From 239bfe970cfa38ce0c9618977c3ee6b31319d797 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 23 Jan 2016 02:55:12 -0800 Subject: [PATCH 4/9] Make hasShadow work on Windows/Linux --- atom/browser/native_window.cc | 11 ++++------- atom/browser/native_window.h | 4 ++-- atom/browser/native_window_mac.mm | 6 ------ atom/browser/native_window_views.cc | 18 +++++++++++++----- atom/browser/native_window_views.h | 2 ++ 5 files changed, 21 insertions(+), 20 deletions(-) diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 7d0ae5a5b7..73370d24c4 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -125,6 +125,10 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) { if (options.Get(options::kMovable, &movable) && movable) { SetMovable(movable); } + bool has_shadow; + if (options.Get(options::kHasShadow, &has_shadow)) { + SetHasShadow(has_shadow); + } bool top; if (options.Get(options::kAlwaysOnTop, &top) && top) { SetAlwaysOnTop(true); @@ -555,13 +559,6 @@ void NativeWindow::OnCapturePageDone(const CapturePageCallback& callback, callback.Run(bitmap); } -void NativeWindow::SetHasShadow(bool has_shadow) { -} - -bool NativeWindow::HasShadow() { - return true; -} - SkColor NativeWindow::ParseHexColor(const std::string& name) { SkColor result = 0xFF000000; unsigned value = 0; diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 2b715e6535..ea5f063a98 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -145,8 +145,8 @@ class NativeWindow : public base::SupportsUserData, virtual void SetKiosk(bool kiosk) = 0; virtual bool IsKiosk() = 0; virtual void SetBackgroundColor(const std::string& color_name) = 0; - virtual void SetHasShadow(bool has_shadow); - virtual bool HasShadow(); + virtual void SetHasShadow(bool has_shadow) = 0; + virtual bool HasShadow() = 0; virtual void SetRepresentedFilename(const std::string& filename); virtual std::string GetRepresentedFilename(); virtual void SetDocumentEdited(bool edited); diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index e989ad90d4..a5dd2842b6 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -449,12 +449,6 @@ NativeWindowMac::NativeWindowMac( if (!has_frame()) [window_ setOpaque:NO]; - bool has_shadow = true; - options.Get(options::kHasShadow, &has_shadow); - if (!has_shadow) { - SetHasShadow(false); - } - // We will manage window's lifetime ourselves. [window_ setReleasedWhenClosed:NO]; diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 216a76ec6b..9244a327d1 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -155,6 +155,11 @@ NativeWindowViews::NativeWindowViews( if (transparent()) params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; + // The given window is most likely not rectangular since it uses + // transparency and has no standard frame, don't show a shadow for it. + if (transparent() && !has_frame()) + params.shadow_type = Widget::InitParams::SHADOW_TYPE_NONE; + #if defined(OS_WIN) params.native_widget = new views::DesktopNativeWidgetAura(window_.get()); @@ -259,11 +264,6 @@ NativeWindowViews::NativeWindowViews( window_->FrameTypeChanged(); } - // The given window is most likely not rectangular since it uses - // transparency and has no standard frame, don't show a shadow for it. - if (transparent() && !has_frame()) - wm::SetShadowType(GetNativeWindow(), wm::SHADOW_TYPE_NONE); - gfx::Size size = bounds.size(); if (has_frame() && options.Get(options::kUseContentSize, &use_content_size_) && @@ -597,6 +597,14 @@ void NativeWindowViews::SetBackgroundColor(const std::string& color_name) { #endif } +void NativeWindowViews::SetHasShadow(bool has_shadow) { + wm::SetShadowType(GetNativeWindow(), wm::SHADOW_TYPE_NONE); +} + +bool NativeWindowViews::HasShadow() { + return wm::GetShadowType(GetNativeWindow()) != wm::SHADOW_TYPE_NONE; +} + void NativeWindowViews::SetMenu(ui::MenuModel* menu_model) { if (menu_model == nullptr) { // Remove accelerators diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index 61d0f95042..934f2aa00c 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -88,6 +88,8 @@ class NativeWindowViews : public NativeWindow, void SetKiosk(bool kiosk) override; bool IsKiosk() override; void SetBackgroundColor(const std::string& color_name) override; + void SetHasShadow(bool has_shadow) override; + bool HasShadow() override; void SetMenu(ui::MenuModel* menu_model) override; gfx::NativeWindow GetNativeWindow() override; void SetOverlayIcon(const gfx::Image& overlay, From 010cc3276ab3ce1d975cfca83599a8662b604f13 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 23 Jan 2016 03:12:19 -0800 Subject: [PATCH 5/9] Simplify the setStyleMask calls --- atom/browser/native_window_mac.h | 4 ++ atom/browser/native_window_mac.mm | 88 ++++++++++++------------------- 2 files changed, 39 insertions(+), 53 deletions(-) diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index 83c2dffe66..964126593a 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -120,6 +120,10 @@ class NativeWindowMac : public NativeWindow { // whehter we can drag. void UpdateDraggableRegionViews(const std::vector& regions); + // Set the attribute of NSWindow while work around a bug of zo0m button. + void SetStyleMask(bool on, NSUInteger flag); + void SetCollectionBehavior(bool on, NSUInteger flag); + base::scoped_nsobject window_; base::scoped_nsobject window_delegate_; diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index a5dd2842b6..bd47fef914 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -639,18 +639,10 @@ void NativeWindowMac::SetContentSizeConstraints( } void NativeWindowMac::SetResizable(bool resizable) { - bool maximizable = IsMaximizable(); // Change styleMask for frameless causes the window to change size, so we have // to explicitly disables that. ScopedDisableResize disable_resize; - if (resizable) { - [window_ setStyleMask:[window_ styleMask] | NSResizableWindowMask]; - } else { - [window_ setStyleMask:[window_ styleMask] & (~NSResizableWindowMask)]; - } - if (!maximizable) { - SetMaximizable(false); - } + SetStyleMask(resizable, NSResizableWindowMask); } bool NativeWindowMac::IsResizable() { @@ -666,20 +658,7 @@ bool NativeWindowMac::IsMovable() { } void NativeWindowMac::SetMinimizable(bool minimizable) { - bool maximizable = IsMaximizable(); - if (minimizable) { - [window_ setStyleMask:[window_ styleMask] | NSMiniaturizableWindowMask]; - } else { - [window_ setStyleMask:[window_ styleMask] & (~NSMiniaturizableWindowMask)]; - } - // 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); - } + SetStyleMask(minimizable, NSMiniaturizableWindowMask); } bool NativeWindowMac::IsMinimizable() { @@ -695,35 +674,20 @@ bool NativeWindowMac::IsMaximizable() { } void NativeWindowMac::SetFullScreenable(bool fullscreenable) { - bool maximizable = IsMaximizable(); - NSUInteger collectionBehavior = [window_ collectionBehavior]; - if (fullscreenable) { - collectionBehavior |= NSWindowCollectionBehaviorFullScreenPrimary; - } else { - collectionBehavior &= (~NSWindowCollectionBehaviorFullScreenPrimary); - // On EL Capitan this flag is required to hide fullscreen button. - collectionBehavior |= NSWindowCollectionBehaviorFullScreenAuxiliary; - } - [window_ setCollectionBehavior:collectionBehavior]; - if (!maximizable) { - SetMaximizable(false); - } + SetCollectionBehavior( + fullscreenable, NSWindowCollectionBehaviorFullScreenPrimary); + // On EL Capitan this flag is required to hide fullscreen button. + SetCollectionBehavior( + !fullscreenable, NSWindowCollectionBehaviorFullScreenAuxiliary); } bool NativeWindowMac::IsFullScreenable() { - return [window_ collectionBehavior] & NSWindowCollectionBehaviorFullScreenPrimary; + NSUInteger collectionBehavior = [window_ collectionBehavior]; + return collectionBehavior & NSWindowCollectionBehaviorFullScreenPrimary; } void NativeWindowMac::SetClosable(bool closable) { - bool maximizable = IsMaximizable(); - if (closable) { - [window_ setStyleMask:[window_ styleMask] | NSClosableWindowMask]; - } else { - [window_ setStyleMask:[window_ styleMask] & (~NSClosableWindowMask)]; - } - if (!maximizable) { - SetMaximizable(false); - } + SetStyleMask(closable, NSClosableWindowMask); } bool NativeWindowMac::IsClosable() { @@ -890,13 +854,7 @@ void NativeWindowMac::ShowDefinitionForSelection() { } void NativeWindowMac::SetVisibleOnAllWorkspaces(bool visible) { - NSUInteger collectionBehavior = [window_ collectionBehavior]; - if (visible) { - collectionBehavior |= NSWindowCollectionBehaviorCanJoinAllSpaces; - } else { - collectionBehavior &= ~NSWindowCollectionBehaviorCanJoinAllSpaces; - } - [window_ setCollectionBehavior:collectionBehavior]; + SetCollectionBehavior(visible, NSWindowCollectionBehaviorCanJoinAllSpaces); } bool NativeWindowMac::IsVisibleOnAllWorkspaces() { @@ -1053,6 +1011,30 @@ void NativeWindowMac::UpdateDraggableRegionViews( [window_ setMovableByWindowBackground:YES]; } +void NativeWindowMac::SetStyleMask(bool on, NSUInteger flag) { + bool zoom_button_enabled = IsMaximizable(); + if (on) + [window_ setStyleMask:[window_ styleMask] | flag]; + else + [window_ setStyleMask:[window_ styleMask] & (~flag)]; + // Change style mask will make the zoom button revert to default, probably + // a bug of Cocoa or OS X. + if (!zoom_button_enabled) + SetMaximizable(false); +} + +void NativeWindowMac::SetCollectionBehavior(bool on, NSUInteger flag) { + bool zoom_button_enabled = IsMaximizable(); + if (on) + [window_ setCollectionBehavior:[window_ collectionBehavior] | flag]; + else + [window_ setCollectionBehavior:[window_ collectionBehavior] & (~flag)]; + // Change collectionBehavior will make the zoom button revert to default, + // probably a bug of Cocoa or OS X. + if (!zoom_button_enabled) + SetMaximizable(false); +} + // static NativeWindow* NativeWindow::Create( brightray::InspectableWebContents* inspectable_web_contents, From c41de501cb3b230092ac931cf67e9fe37e05ecdf Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 23 Jan 2016 03:35:30 -0800 Subject: [PATCH 6/9] spec: Test the -able methods --- atom/browser/native_window.cc | 2 +- atom/browser/native_window_mac.mm | 4 +- atom/browser/native_window_views.cc | 8 +-- spec/api-browser-window-spec.js | 107 ++++++++++++++++++++++++++++ 4 files changed, 113 insertions(+), 8 deletions(-) diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 73370d24c4..732fc6301e 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -122,7 +122,7 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) { } #endif bool movable; - if (options.Get(options::kMovable, &movable) && movable) { + if (options.Get(options::kMovable, &movable)) { SetMovable(movable); } bool has_shadow; diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index bd47fef914..d109a8c3a1 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -489,9 +489,7 @@ NativeWindowMac::NativeWindowMac( bool fullscreen = false; if (options.Get(options::kFullscreen, &fullscreen) && !fullscreen) fullscreenable = false; - if (!fullscreenable) { - SetFullScreenable(false); - } + SetFullScreenable(fullscreenable); // Disable zoom button if window is not resizable if (!maximizable) { diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 9244a327d1..910a0c782b 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -465,9 +465,9 @@ void NativeWindowViews::SetMinimizable(bool minimizable) { bool NativeWindowViews::IsMinimizable() { #if defined(OS_WIN) - return CanMinimize(); + return ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE) & WS_MINIMIZEBOX; #else - return true; // CanMinimize() Not implemented on Linux. + return true; // Not implemented on Linux. #endif } @@ -480,9 +480,9 @@ void NativeWindowViews::SetMaximizable(bool maximizable) { bool NativeWindowViews::IsMaximizable() { #if defined(OS_WIN) - return CanMaximize(); + return ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE) & WS_MAXIMIZEBOX; #else - return true; // CanMaximize() Not implemented on Linux. + return true; // Not implemented on Linux. #endif } diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index 92f69d17bc..0cd0422afb 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -1,3 +1,5 @@ +'use strict'; + const assert = require('assert'); const fs = require('fs'); const path = require('path'); @@ -306,6 +308,7 @@ describe('browser-window module', function() { return assert.equal(after[1], size.height); }); }); + describe('"web-preferences" option', function() { afterEach(function() { return ipcMain.removeAllListeners('answer'); @@ -491,4 +494,108 @@ describe('browser-window module', function() { return assert.equal(size[1], 600); }); }); + + describe('window states', function() { + // Not implemented on Linux. + if (process.platform == 'linux') + return; + + describe('movable state', function() { + it('can be changed with movable option', function() { + w.destroy(); + w = new BrowserWindow({show: false, movable: false}); + assert.equal(w.isMovable(), false); + }); + + it('can be changed with setMovable method', function() { + assert.equal(w.isMovable(), true); + w.setMovable(false); + assert.equal(w.isMovable(), false); + w.setMovable(true); + assert.equal(w.isMovable(), true); + }); + }); + + describe('minimizable state', function() { + it('can be changed with minimizable option', function() { + w.destroy(); + w = new BrowserWindow({show: false, minimizable: false}); + assert.equal(w.isMinimizable(), false); + }); + + it('can be changed with setMinimizable method', function() { + assert.equal(w.isMinimizable(), true); + w.setMinimizable(false); + assert.equal(w.isMinimizable(), false); + w.setMinimizable(true); + assert.equal(w.isMinimizable(), true); + }); + }); + + describe('maximizable state', function() { + it('can be changed with maximizable option', function() { + w.destroy(); + w = new BrowserWindow({show: false, maximizable: false}); + assert.equal(w.isMaximizable(), false); + }); + + it('can be changed with setMaximizable method', function() { + assert.equal(w.isMaximizable(), true); + w.setMaximizable(false); + assert.equal(w.isMaximizable(), false); + w.setMaximizable(true); + assert.equal(w.isMaximizable(), true); + }); + + it('is not affected when changing other states', function() { + w.setMaximizable(false); + assert.equal(w.isMaximizable(), false); + w.setMinimizable(false); + assert.equal(w.isMaximizable(), false); + w.setClosable(false); + assert.equal(w.isMaximizable(), false); + }); + }); + + describe('fullscreenable state', function() { + // Only implemented on OS X. + if (process.platform != 'darwin') + return; + + it('can be changed with fullscreenable option', function() { + w.destroy(); + w = new BrowserWindow({show: false, fullscreenable: false}); + assert.equal(w.isFullScreenable(), false); + }); + + it('can be changed with setFullScreenable method', function() { + assert.equal(w.isFullScreenable(), true); + w.setFullScreenable(false); + assert.equal(w.isFullScreenable(), false); + w.setFullScreenable(true); + assert.equal(w.isFullScreenable(), true); + }); + }); + + describe('closable state', function() { + // Only implemented on OS X. + if (process.platform != 'darwin') + return; + + it('can be changed with closable option', function() { + w.destroy(); + w = new BrowserWindow({show: false, closable: false}); + assert.equal(w.isClosable(), false); + }); + + it('can be changed with setClosable method', function() { + assert.equal(w.isClosable(), true); + w.setClosable(false); + assert.equal(w.isClosable(), false); + w.setClosable(true); + assert.equal(w.isClosable(), true); + }); + }); + + }); }); From c33e8de676532b89200a2f672d04fd7a6cfcb88d Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 23 Jan 2016 03:38:19 -0800 Subject: [PATCH 7/9] spec: Improve the test for resizable --- spec/api-browser-window-spec.js | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index 0cd0422afb..b54efdde9a 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -194,19 +194,6 @@ describe('browser-window module', function() { return assert.equal(w.id, BrowserWindow.fromId(w.id).id); }); }); - describe('BrowserWindow.setResizable(resizable)', function() { - return it('does not change window size for frameless window', function() { - var s; - w.destroy(); - w = new BrowserWindow({ - show: true, - frame: false - }); - s = w.getSize(); - w.setResizable(!w.isResizable()); - return assert.deepEqual(s, w.getSize()); - }); - }); describe('"useContentSize" option', function() { it('make window created with content size when used', function() { var contentSize; @@ -578,10 +565,6 @@ describe('browser-window module', function() { }); describe('closable state', function() { - // Only implemented on OS X. - if (process.platform != 'darwin') - return; - it('can be changed with closable option', function() { w.destroy(); w = new BrowserWindow({show: false, closable: false}); @@ -597,5 +580,20 @@ describe('browser-window module', function() { }); }); + describe('resizable state', function() { + it('can be changed with resizable option', function() { + w.destroy(); + w = new BrowserWindow({show: false, resizable: false}); + assert.equal(w.isResizable(), false); + }); + + it('can be changed with setResizable method', function() { + assert.equal(w.isResizable(), true); + w.setResizable(false); + assert.equal(w.isResizable(), false); + w.setResizable(true); + assert.equal(w.isResizable(), true); + }); + }); }); }); From 8239f69139735a37a230b1716cc9aafc69c356d3 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 23 Jan 2016 03:40:28 -0800 Subject: [PATCH 8/9] spec: hasShadow state --- spec/api-browser-window-spec.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index b54efdde9a..3c98e7a42f 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -595,5 +595,21 @@ describe('browser-window module', function() { assert.equal(w.isResizable(), true); }); }); + + describe('hasShadow state', function() { + it('can be changed with hasShadow option', function() { + w.destroy(); + w = new BrowserWindow({show: false, hasShadow: false}); + assert.equal(w.hasShadow(), false); + }); + + it('can be changed with setHasShadow method', function() { + assert.equal(w.hasShadow(), true); + w.setHasShadow(false); + assert.equal(w.hasShadow(), false); + w.setHasShadow(true); + assert.equal(w.hasShadow(), true); + }); + }); }); }); From cc560a39008a8eb2b7645d00f4b20fded42edaf0 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 23 Jan 2016 20:03:56 +0800 Subject: [PATCH 9/9] spec: Fix failing tests on Windows --- atom/browser/native_window_views.cc | 10 ++++++++-- spec/api-browser-window-spec.js | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 910a0c782b..44df87da9f 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -158,7 +158,7 @@ NativeWindowViews::NativeWindowViews( // The given window is most likely not rectangular since it uses // transparency and has no standard frame, don't show a shadow for it. if (transparent() && !has_frame()) - params.shadow_type = Widget::InitParams::SHADOW_TYPE_NONE; + params.shadow_type = views::Widget::InitParams::SHADOW_TYPE_NONE; #if defined(OS_WIN) params.native_widget = @@ -441,7 +441,11 @@ void NativeWindowViews::SetResizable(bool resizable) { } bool NativeWindowViews::IsResizable() { +#if defined(OS_WIN) + return ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE) & WS_THICKFRAME; +#else return CanResize(); +#endif } void NativeWindowViews::SetMovable(bool movable) { @@ -598,7 +602,9 @@ void NativeWindowViews::SetBackgroundColor(const std::string& color_name) { } void NativeWindowViews::SetHasShadow(bool has_shadow) { - wm::SetShadowType(GetNativeWindow(), wm::SHADOW_TYPE_NONE); + wm::SetShadowType( + GetNativeWindow(), + has_shadow ? wm::SHADOW_TYPE_RECTANGULAR : wm::SHADOW_TYPE_NONE); } bool NativeWindowViews::HasShadow() { diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index 3c98e7a42f..fc8d3523c8 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -597,13 +597,19 @@ describe('browser-window module', function() { }); describe('hasShadow state', function() { + // On Window there is no shadow by default and it can not be changed + // dynamically. it('can be changed with hasShadow option', function() { w.destroy(); - w = new BrowserWindow({show: false, hasShadow: false}); - assert.equal(w.hasShadow(), false); + let hasShadow = process.platform == 'darwin' ? false : true; + w = new BrowserWindow({show: false, hasShadow: hasShadow}); + assert.equal(w.hasShadow(), hasShadow); }); it('can be changed with setHasShadow method', function() { + if (process.platform != 'darwin') + return; + assert.equal(w.hasShadow(), true); w.setHasShadow(false); assert.equal(w.hasShadow(), false);