win: Use native frame for browser windows.
authorCheng Zhao <zcbenz@gmail.com>
Sat, 12 Jul 2014 03:36:08 +0000 (11:36 +0800)
committerCheng Zhao <zcbenz@gmail.com>
Sat, 12 Jul 2014 03:36:08 +0000 (11:36 +0800)
atom.gyp
atom/browser/native_window_views.cc
atom/browser/ui/views/win_frame_view.cc [new file with mode: 0644]
atom/browser/ui/views/win_frame_view.h [new file with mode: 0644]

index 2e602e5..d09b559 100644 (file)
--- a/atom.gyp
+++ b/atom.gyp
       'atom/browser/ui/views/global_menu_bar_x11.h',
       'atom/browser/ui/views/linux_frame_view.cc',
       'atom/browser/ui/views/linux_frame_view.h',
+      'atom/browser/ui/views/win_frame_view.cc',
+      'atom/browser/ui/views/win_frame_view.h',
       'atom/browser/ui/win/notify_icon_host.cc',
       'atom/browser/ui/win/notify_icon_host.h',
       'atom/browser/ui/win/notify_icon.cc',
index 1d0c7b9..924d59a 100644 (file)
 #include "ui/views/controls/webview/webview.h"
 #include "ui/views/layout/fill_layout.h"
 #include "ui/views/window/client_view.h"
-#include "ui/views/window/custom_frame_view.h"
 #include "ui/views/widget/widget.h"
 
 #if defined(USE_X11)
 #include "atom/browser/ui/views/global_menu_bar_x11.h"
 #include "atom/browser/ui/views/linux_frame_view.h"
+#elif defined(OS_WIN)
+#include "atom/browser/ui/views/win_frame_view.h"
 #endif
 
 namespace atom {
@@ -63,14 +64,24 @@ NativeWindowViews::NativeWindowViews(content::WebContents* web_contents,
   options.Get(switches::kResizable, &resizable_);
   options.Get(switches::kTitle, &title_);
 
+  int width = 800, height = 600;
+  options.Get(switches::kWidth, &width);
+  options.Get(switches::kHeight, &height);
+  gfx::Rect bounds(0, 0, width, height);
+
   window_->AddObserver(this);
 
   views::Widget::InitParams params;
   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+  params.bounds = bounds;
   params.delegate = this;
   params.type = views::Widget::InitParams::TYPE_WINDOW;
   params.top_level = true;
+
+#if defined(USE_X11)
+  // In X11 the window frame is drawn by the application.
   params.remove_standard_frame = true;
+#endif
 
   bool skip_taskbar = false;
   if (options.Get(switches::kSkipTaskbar, &skip_taskbar) && skip_taskbar)
@@ -83,18 +94,14 @@ NativeWindowViews::NativeWindowViews(content::WebContents* web_contents,
   set_background(views::Background::CreateStandardPanelBackground());
   AddChildView(web_view_);
 
-  int width = 800, height = 600;
-  options.Get(switches::kWidth, &width);
-  options.Get(switches::kHeight, &height);
-
   bool use_content_size;
-  gfx::Rect bounds(0, 0, width, height);
   if (has_frame_ &&
       options.Get(switches::kUseContentSize, &use_content_size) &&
       use_content_size)
     bounds = window_->non_client_view()->GetWindowBoundsForClientBounds(bounds);
 
   window_->CenterWindow(bounds.size());
+  Layout();
 }
 
 NativeWindowViews::~NativeWindowViews() {
@@ -388,11 +395,12 @@ views::NonClientFrameView* NativeWindowViews::CreateNonClientFrameView(
 #if defined(USE_X11)
   LinuxFrameView* frame_view =  new LinuxFrameView;
   frame_view->Init(this, widget);
+  return frame_view;
+#elif defined(OS_WIN)
+  return new WinFrameView(widget);
 #else
-  views::CustomFrameView* frame_view = new views::CustomFrameView;
-  frame_view->Init(widget);
+  return NULL;
 #endif
-  return frame_view;
 }
 
 void NativeWindowViews::HandleKeyboardEvent(
diff --git a/atom/browser/ui/views/win_frame_view.cc b/atom/browser/ui/views/win_frame_view.cc
new file mode 100644 (file)
index 0000000..0317ec8
--- /dev/null
@@ -0,0 +1,85 @@
+// 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/views/win_frame_view.h"
+
+#include "ui/views/widget/widget.h"
+#include "ui/views/win/hwnd_util.h"
+
+namespace atom {
+
+namespace {
+
+const char kViewClassName[] = "WinFrameView";
+
+}  // namespace
+
+
+WinFrameView::WinFrameView(views::Widget* frame)
+    : frame_(frame) {
+}
+
+WinFrameView::~WinFrameView() {
+}
+
+
+gfx::Rect WinFrameView::GetBoundsForClientView() const {
+  return gfx::Rect(0, 0, width(), height());
+}
+
+gfx::Rect WinFrameView::GetWindowBoundsForClientBounds(
+    const gfx::Rect& client_bounds) const {
+  gfx::Size size(client_bounds.size());
+  ClientAreaSizeToWindowSize(&size);
+  return gfx::Rect(client_bounds.origin(), size);
+}
+
+int WinFrameView::NonClientHitTest(const gfx::Point& point) {
+  return frame_->client_view()->NonClientHitTest(point);
+}
+
+void WinFrameView::GetWindowMask(const gfx::Size& size,
+                                 gfx::Path* window_mask) {
+  // Nothing to do, we use the default window mask.
+}
+
+void WinFrameView::ResetWindowControls() {
+  // Nothing to do.
+}
+
+void WinFrameView::UpdateWindowIcon() {
+  // Nothing to do.
+}
+
+void WinFrameView::UpdateWindowTitle() {
+  // Nothing to do.
+}
+
+gfx::Size WinFrameView::GetPreferredSize() {
+  gfx::Size client_preferred_size = frame_->client_view()->GetPreferredSize();
+  return frame_->non_client_view()->GetWindowBoundsForClientBounds(
+      gfx::Rect(client_preferred_size)).size();
+}
+
+gfx::Size WinFrameView::GetMinimumSize() {
+  return frame_->client_view()->GetMinimumSize();
+}
+
+gfx::Size WinFrameView::GetMaximumSize() {
+  return frame_->client_view()->GetMaximumSize();
+}
+
+const char* WinFrameView::GetClassName() const {
+  return kViewClassName;
+}
+
+void WinFrameView::ClientAreaSizeToWindowSize(gfx::Size* size) const {
+  // AdjustWindowRect seems to return a wrong window size.
+  gfx::Size window = frame_->GetWindowBoundsInScreen().size();
+  gfx::Size client = frame_->GetClientAreaBoundsInScreen().size();
+  size->set_width(size->width() + window.width() - client.width());
+  size->set_height(size->height() + window.height() - client.height());
+}
+
+}  // namespace atom
diff --git a/atom/browser/ui/views/win_frame_view.h b/atom/browser/ui/views/win_frame_view.h
new file mode 100644 (file)
index 0000000..499b0bb
--- /dev/null
@@ -0,0 +1,49 @@
+// 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_VIEWS_WIN_FRAME_VIEW_H_
+#define ATOM_BROWSER_UI_VIEWS_WIN_FRAME_VIEW_H_
+
+#include "ui/views/window/non_client_view.h"
+
+namespace views {
+class Widget;
+}
+
+namespace atom {
+
+class WinFrameView : public views::NonClientFrameView {
+ public:
+  explicit WinFrameView(views::Widget* widget);
+  virtual ~WinFrameView();
+
+  // views::NonClientFrameView:
+  virtual gfx::Rect GetBoundsForClientView() const OVERRIDE;
+  virtual gfx::Rect GetWindowBoundsForClientBounds(
+      const gfx::Rect& client_bounds) const OVERRIDE;
+  virtual int NonClientHitTest(const gfx::Point& point) OVERRIDE;
+  virtual void GetWindowMask(const gfx::Size& size,
+                             gfx::Path* window_mask) OVERRIDE;
+  virtual void ResetWindowControls() OVERRIDE;
+  virtual void UpdateWindowIcon() OVERRIDE;
+  virtual void UpdateWindowTitle() OVERRIDE;
+
+  // views::View:
+  virtual gfx::Size GetPreferredSize() OVERRIDE;
+  virtual gfx::Size GetMinimumSize() OVERRIDE;
+  virtual gfx::Size GetMaximumSize() OVERRIDE;
+  virtual const char* GetClassName() const OVERRIDE;
+
+ private:
+  void ClientAreaSizeToWindowSize(gfx::Size* size) const;
+
+  // Our containing frame.
+  views::Widget* frame_;
+
+  DISALLOW_COPY_AND_ASSIGN(WinFrameView);
+};
+
+}  // namespace atom
+
+#endif  // ATOM_BROWSER_UI_VIEWS_WIN_FRAME_VIEW_H_