From 643a47cf7d3a56ce4931299421075777f22b17e5 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 12 Jul 2014 11:36:08 +0800 Subject: [PATCH] win: Use native frame for browser windows. --- atom.gyp | 2 + atom/browser/native_window_views.cc | 28 +++++--- atom/browser/ui/views/win_frame_view.cc | 85 +++++++++++++++++++++++++ atom/browser/ui/views/win_frame_view.h | 49 ++++++++++++++ 4 files changed, 154 insertions(+), 10 deletions(-) create mode 100644 atom/browser/ui/views/win_frame_view.cc create mode 100644 atom/browser/ui/views/win_frame_view.h diff --git a/atom.gyp b/atom.gyp index 2e602e5e9d26..d09b5590161e 100644 --- a/atom.gyp +++ b/atom.gyp @@ -139,6 +139,8 @@ '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', diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 1d0c7b96a21e..924d59a89f4b 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -22,12 +22,13 @@ #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); -#else - views::CustomFrameView* frame_view = new views::CustomFrameView; - frame_view->Init(widget); -#endif return frame_view; +#elif defined(OS_WIN) + return new WinFrameView(widget); +#else + return NULL; +#endif } 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 index 000000000000..0317ec83c26b --- /dev/null +++ b/atom/browser/ui/views/win_frame_view.cc @@ -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 index 000000000000..499b0bbe0321 --- /dev/null +++ b/atom/browser/ui/views/win_frame_view.h @@ -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_