Merge pull request #4215 from atom/fix-fullscreenable

Add tests for "-able" options and methods
This commit is contained in:
Cheng Zhao 2016-01-24 15:20:16 +08:00
commit 45798d1933
13 changed files with 289 additions and 197 deletions

View file

@ -432,12 +432,12 @@ bool Window::IsMaximizable() {
return window_->IsMaximizable(); return window_->IsMaximizable();
} }
void Window::SetFullscreenable(bool fullscreenable) { void Window::SetFullScreenable(bool fullscreenable) {
window_->SetFullscreenable(fullscreenable); window_->SetFullScreenable(fullscreenable);
} }
bool Window::IsFullscreenable() { bool Window::IsFullScreenable() {
return window_->IsFullscreenable(); return window_->IsFullScreenable();
} }
void Window::SetClosable(bool closable) { void Window::SetClosable(bool closable) {
@ -713,8 +713,8 @@ void Window::BuildPrototype(v8::Isolate* isolate,
.SetMethod("isMinimizable", &Window::IsMinimizable) .SetMethod("isMinimizable", &Window::IsMinimizable)
.SetMethod("setMaximizable", &Window::SetMaximizable) .SetMethod("setMaximizable", &Window::SetMaximizable)
.SetMethod("isMaximizable", &Window::IsMaximizable) .SetMethod("isMaximizable", &Window::IsMaximizable)
.SetMethod("setFullscreenable", &Window::SetFullscreenable) .SetMethod("setFullScreenable", &Window::SetFullScreenable)
.SetMethod("isFullscreenable", &Window::IsFullscreenable) .SetMethod("isFullScreenable", &Window::IsFullScreenable)
.SetMethod("setClosable", &Window::SetClosable) .SetMethod("setClosable", &Window::SetClosable)
.SetMethod("isClosable", &Window::IsClosable) .SetMethod("isClosable", &Window::IsClosable)
.SetMethod("setAlwaysOnTop", &Window::SetAlwaysOnTop) .SetMethod("setAlwaysOnTop", &Window::SetAlwaysOnTop)

View file

@ -112,8 +112,8 @@ class Window : public mate::TrackableObject<Window>,
bool IsMinimizable(); bool IsMinimizable();
void SetMaximizable(bool maximizable); void SetMaximizable(bool maximizable);
bool IsMaximizable(); bool IsMaximizable();
void SetFullscreenable(bool fullscreenable); void SetFullScreenable(bool fullscreenable);
bool IsFullscreenable(); bool IsFullScreenable();
void SetClosable(bool closable); void SetClosable(bool closable);
bool IsClosable(); bool IsClosable();
void SetAlwaysOnTop(bool top); void SetAlwaysOnTop(bool top);

View file

@ -116,23 +116,19 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) {
SetSizeConstraints(size_constraints); SetSizeConstraints(size_constraints);
} }
#if defined(OS_WIN) || defined(USE_X11) #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; bool closable;
if (options.Get(options::kClosable, &closable)) { if (options.Get(options::kClosable, &closable)) {
SetClosable(closable); SetClosable(closable);
} }
bool maximizable;
if (options.Get(options::kMaximizable, &maximizable)) {
SetMaximizable(maximizable);
}
#endif #endif
bool movable;
if (options.Get(options::kMovable, &movable)) {
SetMovable(movable);
}
bool has_shadow;
if (options.Get(options::kHasShadow, &has_shadow)) {
SetHasShadow(has_shadow);
}
bool top; bool top;
if (options.Get(options::kAlwaysOnTop, &top) && top) { if (options.Get(options::kAlwaysOnTop, &top) && top) {
SetAlwaysOnTop(true); SetAlwaysOnTop(true);
@ -563,13 +559,6 @@ void NativeWindow::OnCapturePageDone(const CapturePageCallback& callback,
callback.Run(bitmap); callback.Run(bitmap);
} }
void NativeWindow::SetHasShadow(bool has_shadow) {
}
bool NativeWindow::HasShadow() {
return true;
}
SkColor NativeWindow::ParseHexColor(const std::string& name) { SkColor NativeWindow::ParseHexColor(const std::string& name) {
SkColor result = 0xFF000000; SkColor result = 0xFF000000;
unsigned value = 0; unsigned value = 0;

View file

@ -131,8 +131,8 @@ class NativeWindow : public base::SupportsUserData,
virtual bool IsMinimizable() = 0; virtual bool IsMinimizable() = 0;
virtual void SetMaximizable(bool maximizable) = 0; virtual void SetMaximizable(bool maximizable) = 0;
virtual bool IsMaximizable() = 0; virtual bool IsMaximizable() = 0;
virtual void SetFullscreenable(bool fullscreenable) = 0; virtual void SetFullScreenable(bool fullscreenable) = 0;
virtual bool IsFullscreenable() = 0; virtual bool IsFullScreenable() = 0;
virtual void SetClosable(bool closable) = 0; virtual void SetClosable(bool closable) = 0;
virtual bool IsClosable() = 0; virtual bool IsClosable() = 0;
virtual void SetAlwaysOnTop(bool top) = 0; virtual void SetAlwaysOnTop(bool top) = 0;
@ -145,8 +145,8 @@ class NativeWindow : public base::SupportsUserData,
virtual void SetKiosk(bool kiosk) = 0; virtual void SetKiosk(bool kiosk) = 0;
virtual bool IsKiosk() = 0; virtual bool IsKiosk() = 0;
virtual void SetBackgroundColor(const std::string& color_name) = 0; virtual void SetBackgroundColor(const std::string& color_name) = 0;
virtual void SetHasShadow(bool has_shadow); virtual void SetHasShadow(bool has_shadow) = 0;
virtual bool HasShadow(); virtual bool HasShadow() = 0;
virtual void SetRepresentedFilename(const std::string& filename); virtual void SetRepresentedFilename(const std::string& filename);
virtual std::string GetRepresentedFilename(); virtual std::string GetRepresentedFilename();
virtual void SetDocumentEdited(bool edited); virtual void SetDocumentEdited(bool edited);

View file

@ -54,8 +54,8 @@ class NativeWindowMac : public NativeWindow {
bool IsMinimizable() override; bool IsMinimizable() override;
void SetMaximizable(bool maximizable) override; void SetMaximizable(bool maximizable) override;
bool IsMaximizable() override; bool IsMaximizable() override;
void SetFullscreenable(bool fullscreenable) override; void SetFullScreenable(bool fullscreenable) override;
bool IsFullscreenable() override; bool IsFullScreenable() override;
void SetClosable(bool closable) override; void SetClosable(bool closable) override;
bool IsClosable() override; bool IsClosable() override;
void SetAlwaysOnTop(bool top) override; void SetAlwaysOnTop(bool top) override;
@ -120,6 +120,10 @@ class NativeWindowMac : public NativeWindow {
// whehter we can drag. // whehter we can drag.
void UpdateDraggableRegionViews(const std::vector<DraggableRegion>& regions); void UpdateDraggableRegionViews(const std::vector<DraggableRegion>& 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<AtomNSWindow> window_; base::scoped_nsobject<AtomNSWindow> window_;
base::scoped_nsobject<AtomNSWindowDelegate> window_delegate_; base::scoped_nsobject<AtomNSWindowDelegate> window_delegate_;

View file

@ -371,13 +371,10 @@ NativeWindowMac::NativeWindowMac(
bool minimizable = true; bool minimizable = true;
options.Get(options::kMinimizable, &minimizable); options.Get(options::kMinimizable, &minimizable);
bool maximizable = true; bool maximizable = true;
options.Get(options::kMaximizable, &maximizable); options.Get(options::kMaximizable, &maximizable);
bool fullscreenable = true;
options.Get(options::kFullscreenable, &fullscreenable);
bool closable = true; bool closable = true;
options.Get(options::kClosable, &closable); options.Get(options::kClosable, &closable);
@ -397,12 +394,12 @@ NativeWindowMac::NativeWindowMac(
useStandardWindow = false; useStandardWindow = false;
} }
NSUInteger styleMask = NSTitledWindowMask | NSClosableWindowMask; NSUInteger styleMask = NSTitledWindowMask;
if (minimizable) { if (minimizable) {
styleMask |= NSMiniaturizableWindowMask; styleMask |= NSMiniaturizableWindowMask;
} }
if (!closable) { if (closable) {
styleMask &= ~NSClosableWindowMask; styleMask |= NSClosableWindowMask;
} }
if (!useStandardWindow || transparent() || !has_frame()) { if (!useStandardWindow || transparent() || !has_frame()) {
styleMask |= NSTexturedBackgroundWindowMask; styleMask |= NSTexturedBackgroundWindowMask;
@ -452,12 +449,6 @@ NativeWindowMac::NativeWindowMac(
if (!has_frame()) if (!has_frame())
[window_ setOpaque:NO]; [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. // We will manage window's lifetime ourselves.
[window_ setReleasedWhenClosed:NO]; [window_ setReleasedWhenClosed:NO];
@ -475,11 +466,6 @@ NativeWindowMac::NativeWindowMac(
set_force_using_draggable_region(true); 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. // On OS X the initial window size doesn't include window frame.
bool use_content_size = false; bool use_content_size = false;
options.Get(options::kUseContentSize, &use_content_size); options.Get(options::kUseContentSize, &use_content_size);
@ -496,18 +482,14 @@ NativeWindowMac::NativeWindowMac(
options.Get(options::kDisableAutoHideCursor, &disableAutoHideCursor); options.Get(options::kDisableAutoHideCursor, &disableAutoHideCursor);
[window_ setDisableAutoHideCursor: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; bool fullscreen = false;
options.Get(options::kFullscreen, &fullscreen); if (options.Get(options::kFullscreen, &fullscreen) && !fullscreen)
fullscreenable = false;
if (fullscreenable) { SetFullScreenable(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];
}
// Disable zoom button if window is not resizable // Disable zoom button if window is not resizable
if (!maximizable) { if (!maximizable) {
@ -655,18 +637,10 @@ void NativeWindowMac::SetContentSizeConstraints(
} }
void NativeWindowMac::SetResizable(bool resizable) { void NativeWindowMac::SetResizable(bool resizable) {
bool maximizable = IsMaximizable();
// Change styleMask for frameless causes the window to change size, so we have // Change styleMask for frameless causes the window to change size, so we have
// to explicitly disables that. // to explicitly disables that.
ScopedDisableResize disable_resize; ScopedDisableResize disable_resize;
if (resizable) { SetStyleMask(resizable, NSResizableWindowMask);
[window_ setStyleMask:[window_ styleMask] | NSResizableWindowMask];
} else {
[window_ setStyleMask:[window_ styleMask] & (~NSResizableWindowMask)];
}
if (!maximizable) {
SetMaximizable(false);
}
} }
bool NativeWindowMac::IsResizable() { bool NativeWindowMac::IsResizable() {
@ -682,20 +656,7 @@ bool NativeWindowMac::IsMovable() {
} }
void NativeWindowMac::SetMinimizable(bool minimizable) { void NativeWindowMac::SetMinimizable(bool minimizable) {
bool maximizable = IsMaximizable(); SetStyleMask(minimizable, NSMiniaturizableWindowMask);
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);
}
} }
bool NativeWindowMac::IsMinimizable() { bool NativeWindowMac::IsMinimizable() {
@ -710,34 +671,21 @@ bool NativeWindowMac::IsMaximizable() {
return [[window_ standardWindowButton:NSWindowZoomButton] isEnabled]; return [[window_ standardWindowButton:NSWindowZoomButton] isEnabled];
} }
void NativeWindowMac::SetFullscreenable(bool fullscreenable) { void NativeWindowMac::SetFullScreenable(bool fullscreenable) {
bool maximizable = IsMaximizable(); SetCollectionBehavior(
NSUInteger collectionBehavior = [window_ collectionBehavior]; fullscreenable, NSWindowCollectionBehaviorFullScreenPrimary);
if (fullscreenable) { // On EL Capitan this flag is required to hide fullscreen button.
collectionBehavior |= NSWindowCollectionBehaviorFullScreenPrimary; SetCollectionBehavior(
} else { !fullscreenable, NSWindowCollectionBehaviorFullScreenAuxiliary);
collectionBehavior &= (~NSWindowCollectionBehaviorFullScreenPrimary);
}
[window_ setCollectionBehavior:collectionBehavior];
if (!maximizable) {
SetMaximizable(false);
}
} }
bool NativeWindowMac::IsFullscreenable() { bool NativeWindowMac::IsFullScreenable() {
return [window_ collectionBehavior] & NSWindowCollectionBehaviorFullScreenPrimary; NSUInteger collectionBehavior = [window_ collectionBehavior];
return collectionBehavior & NSWindowCollectionBehaviorFullScreenPrimary;
} }
void NativeWindowMac::SetClosable(bool closable) { void NativeWindowMac::SetClosable(bool closable) {
bool maximizable = IsMaximizable(); SetStyleMask(closable, NSClosableWindowMask);
if (closable) {
[window_ setStyleMask:[window_ styleMask] | NSClosableWindowMask];
} else {
[window_ setStyleMask:[window_ styleMask] & (~NSClosableWindowMask)];
}
if (!maximizable) {
SetMaximizable(false);
}
} }
bool NativeWindowMac::IsClosable() { bool NativeWindowMac::IsClosable() {
@ -904,13 +852,7 @@ void NativeWindowMac::ShowDefinitionForSelection() {
} }
void NativeWindowMac::SetVisibleOnAllWorkspaces(bool visible) { void NativeWindowMac::SetVisibleOnAllWorkspaces(bool visible) {
NSUInteger collectionBehavior = [window_ collectionBehavior]; SetCollectionBehavior(visible, NSWindowCollectionBehaviorCanJoinAllSpaces);
if (visible) {
collectionBehavior |= NSWindowCollectionBehaviorCanJoinAllSpaces;
} else {
collectionBehavior &= ~NSWindowCollectionBehaviorCanJoinAllSpaces;
}
[window_ setCollectionBehavior:collectionBehavior];
} }
bool NativeWindowMac::IsVisibleOnAllWorkspaces() { bool NativeWindowMac::IsVisibleOnAllWorkspaces() {
@ -1067,6 +1009,30 @@ void NativeWindowMac::UpdateDraggableRegionViews(
[window_ setMovableByWindowBackground:YES]; [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 // static
NativeWindow* NativeWindow::Create( NativeWindow* NativeWindow::Create(
brightray::InspectableWebContents* inspectable_web_contents, brightray::InspectableWebContents* inspectable_web_contents,

View file

@ -59,6 +59,17 @@ const int kMenuBarHeight = 20;
const int kMenuBarHeight = 25; const int kMenuBarHeight = 25;
#endif #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) { bool IsAltKey(const content::NativeWebKeyboardEvent& event) {
return event.windowsKeyCode == ui::VKEY_MENU; return event.windowsKeyCode == ui::VKEY_MENU;
} }
@ -103,9 +114,9 @@ NativeWindowViews::NativeWindowViews(
menu_bar_alt_pressed_(false), menu_bar_alt_pressed_(false),
keyboard_event_handler_(new views::UnhandledKeyboardEventHandler), keyboard_event_handler_(new views::UnhandledKeyboardEventHandler),
use_content_size_(false), use_content_size_(false),
movable_(true),
resizable_(true), resizable_(true),
maximizable_(true), maximizable_(true),
movable_(true),
minimizable_(true) { minimizable_(true) {
options.Get(options::kTitle, &title_); options.Get(options::kTitle, &title_);
options.Get(options::kAutoHideMenuBar, &menu_bar_autohide_); 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 // On Windows we rely on the CanResize() to indicate whether window can be
// resized, and it should be set before window is created. // resized, and it should be set before window is created.
options.Get(options::kResizable, &resizable_); options.Get(options::kResizable, &resizable_);
options.Get(options::kMovable, &movable_);
options.Get(options::kMinimizable, &minimizable_); options.Get(options::kMinimizable, &minimizable_);
options.Get(options::kMaximizable, &maximizable_); options.Get(options::kMaximizable, &maximizable_);
#endif #endif
@ -145,6 +155,11 @@ NativeWindowViews::NativeWindowViews(
if (transparent()) if (transparent())
params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; 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 = views::Widget::InitParams::SHADOW_TYPE_NONE;
#if defined(OS_WIN) #if defined(OS_WIN)
params.native_widget = params.native_widget =
new views::DesktopNativeWidgetAura(window_.get()); new views::DesktopNativeWidgetAura(window_.get());
@ -216,25 +231,29 @@ NativeWindowViews::NativeWindowViews(
last_window_state_ = ui::SHOW_STATE_FULLSCREEN; last_window_state_ = ui::SHOW_STATE_FULLSCREEN;
else else
last_window_state_ = ui::SHOW_STATE_NORMAL; last_window_state_ = ui::SHOW_STATE_NORMAL;
last_normal_size_ = gfx::Size(widget_size_); last_normal_size_ = gfx::Size(widget_size_);
DWORD style = ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE); if (!has_frame()) {
style |= WS_THICKFRAME | WS_CAPTION | WS_MINIMIZEBOX; // Set Window style so that we get a minimize and maximize animation when
// frameless.
if (transparent()) { DWORD frame_style = WS_CAPTION;
DWORD ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE); if (resizable_)
ex_style |= WS_EX_COMPOSITED; frame_style |= WS_THICKFRAME;
::SetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE, ex_style); if (minimizable_)
frame_style |= WS_MINIMIZEBOX;
if (!has_frame()) { if (maximizable_)
// We should not show a frame for transparent window. frame_style |= WS_MAXIMIZEBOX;
style &= ~(WS_THICKFRAME | WS_CAPTION); // 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()) { if (transparent()) {
::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, style); // 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 #endif
@ -245,11 +264,6 @@ NativeWindowViews::NativeWindowViews(
window_->FrameTypeChanged(); 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(); gfx::Size size = bounds.size();
if (has_frame() && if (has_frame() &&
options.Get(options::kUseContentSize, &use_content_size_) && options.Get(options::kUseContentSize, &use_content_size_) &&
@ -405,18 +419,8 @@ void NativeWindowViews::SetContentSizeConstraints(
void NativeWindowViews::SetResizable(bool resizable) { void NativeWindowViews::SetResizable(bool resizable) {
#if defined(OS_WIN) #if defined(OS_WIN)
// WS_MAXIMIZEBOX => Maximize button if (!transparent())
// WS_MINIMIZEBOX => Minimize button FlipWindowStyle(GetAcceleratedWidget(), resizable, WS_THICKFRAME);
// 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);
}
#elif defined(USE_X11) #elif defined(USE_X11)
if (resizable != resizable_) { if (resizable != resizable_) {
// On Linux there is no "resizable" property of a window, we have to set // On Linux there is no "resizable" property of a window, we have to set
@ -437,7 +441,11 @@ void NativeWindowViews::SetResizable(bool resizable) {
} }
bool NativeWindowViews::IsResizable() { bool NativeWindowViews::IsResizable() {
return resizable_; #if defined(OS_WIN)
return ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE) & WS_THICKFRAME;
#else
return CanResize();
#endif
} }
void NativeWindowViews::SetMovable(bool movable) { void NativeWindowViews::SetMovable(bool movable) {
@ -447,58 +455,45 @@ void NativeWindowViews::SetMovable(bool movable) {
bool NativeWindowViews::IsMovable() { bool NativeWindowViews::IsMovable() {
#if defined(OS_WIN) #if defined(OS_WIN)
return movable_; return movable_;
#elif defined(USE_X11) #else
return true; return true; // Not implemented on Linux.
#endif #endif
} }
void NativeWindowViews::SetMinimizable(bool minimizable) { void NativeWindowViews::SetMinimizable(bool minimizable) {
#if defined(OS_WIN) #if defined(OS_WIN)
if (!transparent()) { FlipWindowStyle(GetAcceleratedWidget(), minimizable, WS_MINIMIZEBOX);
DWORD style = ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE);
if (minimizable)
style |= WS_MINIMIZEBOX;
else
style &= (~WS_MINIMIZEBOX);
::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, style);
}
#endif #endif
minimizable_ = minimizable; minimizable_ = minimizable;
} }
bool NativeWindowViews::IsMinimizable() { bool NativeWindowViews::IsMinimizable() {
#if defined(OS_WIN) #if defined(OS_WIN)
return ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE) & WS_MINIMIZEBOX; return ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE) & WS_MINIMIZEBOX;
#elif defined(USE_X11) #else
return true; return true; // Not implemented on Linux.
#endif #endif
} }
void NativeWindowViews::SetMaximizable(bool maximizable) { void NativeWindowViews::SetMaximizable(bool maximizable) {
#if defined(OS_WIN) #if defined(OS_WIN)
DWORD style = ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE); FlipWindowStyle(GetAcceleratedWidget(), maximizable, WS_MAXIMIZEBOX);
if (maximizable) {
style |= WS_MAXIMIZEBOX;
} else {
style &= (~WS_MAXIMIZEBOX);
}
::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, style);
#endif #endif
maximizable_ = maximizable;
} }
bool NativeWindowViews::IsMaximizable() { bool NativeWindowViews::IsMaximizable() {
#if defined(OS_WIN) #if defined(OS_WIN)
return ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE) & WS_MAXIMIZEBOX; return ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE) & WS_MAXIMIZEBOX;
#elif defined(USE_X11) #else
return true; return true; // Not implemented on Linux.
#endif #endif
} }
void NativeWindowViews::SetFullscreenable(bool maximizable) { void NativeWindowViews::SetFullScreenable(bool maximizable) {
} }
bool NativeWindowViews::IsFullscreenable() { bool NativeWindowViews::IsFullScreenable() {
return true; return true;
} }
@ -606,6 +601,16 @@ void NativeWindowViews::SetBackgroundColor(const std::string& color_name) {
#endif #endif
} }
void NativeWindowViews::SetHasShadow(bool has_shadow) {
wm::SetShadowType(
GetNativeWindow(),
has_shadow ? wm::SHADOW_TYPE_RECTANGULAR : wm::SHADOW_TYPE_NONE);
}
bool NativeWindowViews::HasShadow() {
return wm::GetShadowType(GetNativeWindow()) != wm::SHADOW_TYPE_NONE;
}
void NativeWindowViews::SetMenu(ui::MenuModel* menu_model) { void NativeWindowViews::SetMenu(ui::MenuModel* menu_model) {
if (menu_model == nullptr) { if (menu_model == nullptr) {
// Remove accelerators // Remove accelerators
@ -786,7 +791,7 @@ bool NativeWindowViews::CanResize() const {
} }
bool NativeWindowViews::CanMaximize() const { bool NativeWindowViews::CanMaximize() const {
return resizable_; return resizable_ && maximizable_;
} }
bool NativeWindowViews::CanMinimize() const { bool NativeWindowViews::CanMinimize() const {

View file

@ -74,8 +74,8 @@ class NativeWindowViews : public NativeWindow,
bool IsMinimizable() override; bool IsMinimizable() override;
void SetMaximizable(bool maximizable) override; void SetMaximizable(bool maximizable) override;
bool IsMaximizable() override; bool IsMaximizable() override;
void SetFullscreenable(bool fullscreenable) override; void SetFullScreenable(bool fullscreenable) override;
bool IsFullscreenable() override; bool IsFullScreenable() override;
void SetClosable(bool closable) override; void SetClosable(bool closable) override;
bool IsClosable() override; bool IsClosable() override;
void SetAlwaysOnTop(bool top) override; void SetAlwaysOnTop(bool top) override;
@ -88,6 +88,8 @@ class NativeWindowViews : public NativeWindow,
void SetKiosk(bool kiosk) override; void SetKiosk(bool kiosk) override;
bool IsKiosk() override; bool IsKiosk() override;
void SetBackgroundColor(const std::string& color_name) 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; void SetMenu(ui::MenuModel* menu_model) override;
gfx::NativeWindow GetNativeWindow() override; gfx::NativeWindow GetNativeWindow() override;
void SetOverlayIcon(const gfx::Image& overlay, void SetOverlayIcon(const gfx::Image& overlay,
@ -206,9 +208,9 @@ class NativeWindowViews : public NativeWindow,
accelerator_util::AcceleratorTable accelerator_table_; accelerator_util::AcceleratorTable accelerator_table_;
bool use_content_size_; bool use_content_size_;
bool movable_;
bool resizable_; bool resizable_;
bool maximizable_; bool maximizable_;
bool movable_;
bool minimizable_; bool minimizable_;
std::string title_; std::string title_;
gfx::Size widget_size_; gfx::Size widget_size_;

View file

@ -96,9 +96,8 @@ bool NativeWindowViews::PreHandleMSG(
return false; return false;
case WM_MOVING: { case WM_MOVING: {
if (!movable_) { if (!movable_)
::GetWindowRect(GetAcceleratedWidget(), (LPRECT)l_param); ::GetWindowRect(GetAcceleratedWidget(), (LPRECT)l_param);
}
return false; return false;
} }

View file

@ -25,7 +25,7 @@ const char kResizable[] = "resizable";
const char kMovable[] = "movable"; const char kMovable[] = "movable";
const char kMinimizable[] = "minimizable"; const char kMinimizable[] = "minimizable";
const char kMaximizable[] = "maximizable"; const char kMaximizable[] = "maximizable";
const char kFullscreenable[] = "fullscreenable"; const char kFullScreenable[] = "fullscreenable";
const char kClosable[] = "closable"; const char kClosable[] = "closable";
const char kFullscreen[] = "fullscreen"; const char kFullscreen[] = "fullscreen";

View file

@ -26,7 +26,7 @@ extern const char kResizable[];
extern const char kMovable[]; extern const char kMovable[];
extern const char kMinimizable[]; extern const char kMinimizable[];
extern const char kMaximizable[]; extern const char kMaximizable[];
extern const char kFullscreenable[]; extern const char kFullScreenable[];
extern const char kClosable[]; extern const char kClosable[];
extern const char kFullscreen[]; extern const char kFullscreen[];
extern const char kSkipTaskbar[]; extern const char kSkipTaskbar[];

View file

@ -575,14 +575,14 @@ nothing.
Returns whether the window can be manually maximized by user. On Linux always Returns whether the window can be manually maximized by user. On Linux always
returns `true`. returns `true`.
### `win.setFullscreenable(fullscreenable)` _OS X_ ### `win.setFullScreenable(fullscreenable)` _OS X_
* `fullscreenable` Boolean * `fullscreenable` Boolean
Sets whether the maximize/zoom window button toggles fullscreen mode or Sets whether the maximize/zoom window button toggles fullscreen mode or
maximizes the window. On Windows and Linux does nothing. 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 Returns whether the maximize/zoom window button toggles fullscreen mode or
maximizes the window. On Windows and Linux always returns `true`. maximizes the window. On Windows and Linux always returns `true`.

View file

@ -1,3 +1,5 @@
'use strict';
const assert = require('assert'); const assert = require('assert');
const fs = require('fs'); const fs = require('fs');
const path = require('path'); const path = require('path');
@ -192,19 +194,6 @@ describe('browser-window module', function() {
return assert.equal(w.id, BrowserWindow.fromId(w.id).id); 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() { describe('"useContentSize" option', function() {
it('make window created with content size when used', function() { it('make window created with content size when used', function() {
var contentSize; var contentSize;
@ -306,6 +295,7 @@ describe('browser-window module', function() {
return assert.equal(after[1], size.height); return assert.equal(after[1], size.height);
}); });
}); });
describe('"web-preferences" option', function() { describe('"web-preferences" option', function() {
afterEach(function() { afterEach(function() {
return ipcMain.removeAllListeners('answer'); return ipcMain.removeAllListeners('answer');
@ -491,4 +481,141 @@ describe('browser-window module', function() {
return assert.equal(size[1], 600); 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() {
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);
});
});
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);
});
});
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();
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);
w.setHasShadow(true);
assert.equal(w.hasShadow(), true);
});
});
});
}); });