linux: Fix BrowserWindow.setResizable.
authorCheng Zhao <zcbenz@gmail.com>
Tue, 26 Aug 2014 05:37:37 +0000 (13:37 +0800)
committerCheng Zhao <zcbenz@gmail.com>
Tue, 26 Aug 2014 05:37:37 +0000 (13:37 +0800)
atom.gyp
atom/browser/native_window_views.cc
atom/browser/ui/x/x_window_utils.cc [new file with mode: 0644]
atom/browser/ui/x/x_window_utils.h [new file with mode: 0644]

index 9d11582..df9cf20 100644 (file)
--- a/atom.gyp
+++ b/atom.gyp
       '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',
index baf5552..5524711 100644 (file)
@@ -8,12 +8,6 @@
 #include <shobjidl.h>
 #endif
 
-#if defined(USE_X11)
-#include <X11/extensions/XInput2.h>
-#include <X11/extensions/Xrandr.h>
-#include <X11/Xlib.h>
-#endif
-
 #include <string>
 #include <vector>
 
@@ -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 (file)
index 0000000..e2dbbb5
--- /dev/null
@@ -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 (file)
index 0000000..d40d7f0
--- /dev/null
@@ -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 <X11/extensions/XInput2.h>
+#include <X11/extensions/Xrandr.h>
+#include <X11/Xlib.h>
+
+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_