diff --git a/atom.gyp b/atom.gyp index 9d11582ad4b..df9cf202a51 100644 --- a/atom.gyp +++ b/atom.gyp @@ -164,6 +164,8 @@ 'atom/browser/ui/win/notify_icon_host.h', 'atom/browser/ui/win/notify_icon.cc', 'atom/browser/ui/win/notify_icon.h', + 'atom/browser/ui/x/x_window_utils.cc', + 'atom/browser/ui/x/x_window_utils.h', 'atom/browser/window_list.cc', 'atom/browser/window_list.h', 'atom/browser/window_list_observer.h', diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index baf55523cc5..5524711fdd6 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -8,12 +8,6 @@ #include #endif -#if defined(USE_X11) -#include -#include -#include -#endif - #include #include @@ -38,6 +32,7 @@ #include "atom/browser/browser.h" #include "atom/browser/ui/views/global_menu_bar_x11.h" #include "atom/browser/ui/views/frameless_view.h" +#include "atom/browser/ui/x/x_window_utils.h" #include "base/environment.h" #include "base/nix/xdg_util.h" #include "base/strings/stringprintf.h" @@ -67,29 +62,6 @@ const int kMenuBarHeight = 25; // window role for X11. int kWindowsCreated = 0; -::Atom GetAtom(const char* name) { - return XInternAtom(gfx::GetXDisplay(), name, false); -} - -void SetWMSpecState(::Window xwindow, bool enabled, ::Atom state) { - XEvent xclient; - memset(&xclient, 0, sizeof(xclient)); - xclient.type = ClientMessage; - xclient.xclient.window = xwindow; - xclient.xclient.message_type = GetAtom("_NET_WM_STATE"); - xclient.xclient.format = 32; - xclient.xclient.data.l[0] = enabled ? 1 : 0; - xclient.xclient.data.l[1] = state; - xclient.xclient.data.l[2] = None; - xclient.xclient.data.l[3] = 1; - xclient.xclient.data.l[4] = 0; - - XDisplay* xdisplay = gfx::GetXDisplay(); - XSendEvent(xdisplay, DefaultRootWindow(xdisplay), False, - SubstructureRedirectMask | SubstructureNotifyMask, - &xclient); -} - bool ShouldUseGlobalMenuBar() { // Some DE would pretend to be Unity but don't have global application menu, // so we can not trust unity::IsRunning(). @@ -145,10 +117,15 @@ NativeWindowViews::NativeWindowViews(content::WebContents* web_contents, keyboard_event_handler_(new views::UnhandledKeyboardEventHandler), use_content_size_(false), resizable_(true) { - options.Get(switches::kResizable, &resizable_); options.Get(switches::kTitle, &title_); options.Get(switches::kAutoHideMenuBar, &menu_bar_autohide_); +#if defined(OS_WIN) + // 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(switches::kResizable, &resizable_); +#endif + if (enable_larger_than_screen_) // We need to set a default maximum window size here otherwise Windows // will not allow us to resize the window larger than scree. @@ -294,6 +271,15 @@ bool NativeWindowViews::IsFullscreen() { } void NativeWindowViews::SetSize(const gfx::Size& size) { +#if defined(USE_X11) + // On Linux the minimum and maximum size should be updated with window size + // when window is not resizable. + if (!resizable_) { + SetMaximumSize(size); + SetMinimumSize(size); + } +#endif + window_->SetSize(size); } @@ -313,8 +299,7 @@ void NativeWindowViews::SetContentSize(const gfx::Size& size) { } gfx::Rect bounds = window_->GetWindowBoundsInScreen(); - bounds.set_size(size); - window_->SetBounds(ContentBoundsToWindowBounds(bounds)); + SetSize(ContentBoundsToWindowBounds(gfx::Rect(bounds.origin(), size)).size()); } gfx::Size NativeWindowViews::GetContentSize() { @@ -361,8 +346,6 @@ gfx::Size NativeWindowViews::GetMaximumSize() { } void NativeWindowViews::SetResizable(bool resizable) { - resizable_ = resizable; - #if defined(OS_WIN) if (has_frame_) { // WS_MAXIMIZEBOX => Maximize button @@ -375,9 +358,21 @@ void NativeWindowViews::SetResizable(bool resizable) { style = (style & ~(WS_MAXIMIZEBOX | WS_THICKFRAME)) | WS_MINIMIZEBOX; ::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, style); } +#elif defined(USE_X11) + if (resizable != resizable_) { + // On Linux there is no "resizable" property of a window, we have to set + // both the minimum and maximum size to the window size to achieve it. + if (resizable) { + SetMaximumSize(gfx::Size()); + SetMinimumSize(gfx::Size()); + } else { + SetMaximumSize(GetSize()); + SetMinimumSize(GetSize()); + } + } #endif - // FIXME Implement me for X11. + resizable_ = resizable; } bool NativeWindowViews::IsResizable() { diff --git a/atom/browser/ui/x/x_window_utils.cc b/atom/browser/ui/x/x_window_utils.cc new file mode 100644 index 00000000000..e2dbbb59f14 --- /dev/null +++ b/atom/browser/ui/x/x_window_utils.cc @@ -0,0 +1,34 @@ +// Copyright (c) 2014 GitHub, Inc. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/ui/x/x_window_utils.h" + +#include "ui/base/x/x11_util.h" + +namespace atom { + +::Atom GetAtom(const char* name) { + return XInternAtom(gfx::GetXDisplay(), name, false); +} + +void SetWMSpecState(::Window xwindow, bool enabled, ::Atom state) { + XEvent xclient; + memset(&xclient, 0, sizeof(xclient)); + xclient.type = ClientMessage; + xclient.xclient.window = xwindow; + xclient.xclient.message_type = GetAtom("_NET_WM_STATE"); + xclient.xclient.format = 32; + xclient.xclient.data.l[0] = enabled ? 1 : 0; + xclient.xclient.data.l[1] = state; + xclient.xclient.data.l[2] = None; + xclient.xclient.data.l[3] = 1; + xclient.xclient.data.l[4] = 0; + + XDisplay* xdisplay = gfx::GetXDisplay(); + XSendEvent(xdisplay, DefaultRootWindow(xdisplay), False, + SubstructureRedirectMask | SubstructureNotifyMask, + &xclient); +} + +} // namespace atom diff --git a/atom/browser/ui/x/x_window_utils.h b/atom/browser/ui/x/x_window_utils.h new file mode 100644 index 00000000000..d40d7f0c612 --- /dev/null +++ b/atom/browser/ui/x/x_window_utils.h @@ -0,0 +1,22 @@ +// Copyright (c) 2014 GitHub, Inc. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_UI_X_X_WINDOW_UTILS_H_ +#define ATOM_BROWSER_UI_X_X_WINDOW_UTILS_H_ + +#include +#include +#include + +namespace atom { + +::Atom GetAtom(const char* name); + +// Sends a message to the x11 window manager, enabling or disabling the |state| +// for _NET_WM_STATE. +void SetWMSpecState(::Window xwindow, bool enabled, ::Atom state); + +} // namespace atom + +#endif // ATOM_BROWSER_UI_X_X_WINDOW_UTILS_H_