diff options
-rw-r--r-- | ui/gfx/screen_aura.cc | 3 | ||||
-rw-r--r-- | ui/views/views.gyp | 16 | ||||
-rw-r--r-- | ui/views/widget/desktop_native_widget_helper_aura.cc | 16 | ||||
-rw-r--r-- | ui/views/widget/desktop_native_widget_helper_aura.h | 12 | ||||
-rw-r--r-- | ui/views/widget/native_widget_aura.cc | 6 | ||||
-rw-r--r-- | ui/views/widget/native_widget_helper_aura.h | 4 | ||||
-rw-r--r-- | ui/views/widget/native_widget_win.cc | 9 | ||||
-rw-r--r-- | ui/views/widget/widget_hwnd_utils.cc | 14 | ||||
-rw-r--r-- | ui/views/widget/widget_hwnd_utils.h | 22 | ||||
-rw-r--r-- | ui/views/widget/widget_message_filter.cc | 131 | ||||
-rw-r--r-- | ui/views/widget/widget_message_filter.h | 59 |
11 files changed, 278 insertions, 14 deletions
diff --git a/ui/gfx/screen_aura.cc b/ui/gfx/screen_aura.cc index 1631095..4337ede 100644 --- a/ui/gfx/screen_aura.cc +++ b/ui/gfx/screen_aura.cc @@ -23,7 +23,6 @@ void Screen::SetInstance(ScreenImpl* screen) { g_instance_ = screen; } -#if defined(USE_ASH) // TODO(oshima): Implement ScreenImpl for Linux/aura and remove this // ifdef. @@ -62,6 +61,4 @@ Monitor Screen::GetMonitorMatching(const gfx::Rect& match_rect) { return g_instance_->GetMonitorNearestPoint(match_rect.CenterPoint()); } -#endif - } // namespace gfx diff --git a/ui/views/views.gyp b/ui/views/views.gyp index 8f04603..7919b8e 100644 --- a/ui/views/views.gyp +++ b/ui/views/views.gyp @@ -344,6 +344,10 @@ 'widget/widget.h', 'widget/widget_delegate.cc', 'widget/widget_delegate.h', + 'widget/widget_hwnd_utils.cc', + 'widget/widget_hwnd_utils.h', + 'widget/widget_message_filter.cc', + 'widget/widget_message_filter.h', 'window/client_view.cc', 'window/client_view.h', 'window/custom_frame_view.cc', @@ -432,6 +436,18 @@ 'events/event_x.cc', ], }], + ['use_aura==0 or OS!="win"', { + 'sources!': [ + 'widget/widget_message_filter.cc', + 'widget/widget_message_filter.h', + ], + }], + ['OS!="win"', { + 'sources!': [ + 'widget/widget_hwnd_utils.cc', + 'widget/widget_hwnd_utils.h', + ], + }], ], }, # target_name: views { diff --git a/ui/views/widget/desktop_native_widget_helper_aura.cc b/ui/views/widget/desktop_native_widget_helper_aura.cc index 26af57e..fb6ec2d 100644 --- a/ui/views/widget/desktop_native_widget_helper_aura.cc +++ b/ui/views/widget/desktop_native_widget_helper_aura.cc @@ -4,12 +4,17 @@ #include "ui/views/widget/desktop_native_widget_helper_aura.h" -#include "ui/views/widget/native_widget_aura.h" #include "ui/aura/root_window.h" #include "ui/aura/desktop/desktop_activation_client.h" #include "ui/aura/desktop/desktop_dispatcher_client.h" #include "ui/aura/desktop/desktop_root_window_event_filter.h" #include "ui/aura/client/dispatcher_client.h" +#include "ui/views/widget/native_widget_aura.h" + +#if defined(OS_WIN) +#include "ui/base/win/hwnd_subclass.h" +#include "ui/views/widget/widget_message_filter.h" +#endif namespace views { @@ -29,6 +34,7 @@ void DesktopNativeWidgetHelperAura::PreInitialize( bounds.set_size(gfx::Size(100, 100)); } root_window_.reset(new aura::RootWindow(bounds)); + root_window_->Init(); root_window_->SetEventFilter( new aura::DesktopRootWindowEventFilter(root_window_.get())); root_window_->AddRootWindowObserver(this); @@ -40,6 +46,14 @@ void DesktopNativeWidgetHelperAura::PreInitialize( new aura::DesktopDispatcherClient); } +void DesktopNativeWidgetHelperAura::PostInitialize() { +#if defined(OS_WIN) + subclass_.reset(new ui::HWNDSubclass(root_window_->GetAcceleratedWidget())); + subclass_->SetFilter(new WidgetMessageFilter(root_window_.get(), + widget_->GetWidget())); +#endif +} + void DesktopNativeWidgetHelperAura::ShowRootWindow() { if (root_window_.get()) root_window_->ShowRootWindow(); diff --git a/ui/views/widget/desktop_native_widget_helper_aura.h b/ui/views/widget/desktop_native_widget_helper_aura.h index ed6ab90..34d78df 100644 --- a/ui/views/widget/desktop_native_widget_helper_aura.h +++ b/ui/views/widget/desktop_native_widget_helper_aura.h @@ -16,8 +16,15 @@ namespace aura { class RootWindow; } +namespace ui { +#if defined(OS_WIN) +class HWNDSubclass; +#endif +} + namespace views { class NativeWidgetAura; +class WidgetMessageFilter; // Implementation of non-Ash desktop integration code, allowing // NativeWidgetAuras to work in a traditional desktop environment. @@ -30,6 +37,7 @@ class VIEWS_EXPORT DesktopNativeWidgetHelperAura // Overridden from aura::NativeWidgetHelperAura: virtual void PreInitialize(const Widget::InitParams& params) OVERRIDE; + virtual void PostInitialize() OVERRIDE; virtual void ShowRootWindow() OVERRIDE; virtual aura::RootWindow* GetRootWindow() OVERRIDE; virtual gfx::Rect ModifyAndSetBounds(const gfx::Rect& bounds) OVERRIDE; @@ -48,6 +56,10 @@ class VIEWS_EXPORT DesktopNativeWidgetHelperAura // Optionally, a RootWindow that we attach ourselves to. scoped_ptr<aura::RootWindow> root_window_; +#if defined(OS_WIN) + scoped_ptr<ui::HWNDSubclass> subclass_; +#endif + DISALLOW_COPY_AND_ASSIGN(DesktopNativeWidgetHelperAura); }; diff --git a/ui/views/widget/native_widget_aura.cc b/ui/views/widget/native_widget_aura.cc index 91f409c..b4e6d68 100644 --- a/ui/views/widget/native_widget_aura.cc +++ b/ui/views/widget/native_widget_aura.cc @@ -231,9 +231,11 @@ void NativeWidgetAura::InitNativeWidget(const Widget::InitParams& params) { aura::client::SetActivationDelegate(window_, this); - // TODO(erg): Move this somewhere else? - if (desktop_helper_.get()) + if (desktop_helper_.get()) { + desktop_helper_->PostInitialize(); + // TODO(erg): Move this somewhere else? desktop_helper_->ShowRootWindow(); + } } NonClientFrameView* NativeWidgetAura::CreateNonClientFrameView() { diff --git a/ui/views/widget/native_widget_helper_aura.h b/ui/views/widget/native_widget_helper_aura.h index b89ce0f..c8ec63c 100644 --- a/ui/views/widget/native_widget_helper_aura.h +++ b/ui/views/widget/native_widget_helper_aura.h @@ -21,6 +21,10 @@ class VIEWS_EXPORT NativeWidgetHelperAura { // set up a root_window_ for this widget. virtual void PreInitialize(const Widget::InitParams& params) = 0; + // Called at the end of InitNativeWidget; i.e. after the NativeWidgetAura's + // aura::Window has been initialized. + virtual void PostInitialize() = 0; + // Passes through a message to show the RootWindow, if it exists. virtual void ShowRootWindow() = 0; diff --git a/ui/views/widget/native_widget_win.cc b/ui/views/widget/native_widget_win.cc index c87abc8..f189746 100644 --- a/ui/views/widget/native_widget_win.cc +++ b/ui/views/widget/native_widget_win.cc @@ -47,6 +47,7 @@ #include "ui/views/widget/native_widget_delegate.h" #include "ui/views/widget/root_view.h" #include "ui/views/widget/widget_delegate.h" +#include "ui/views/widget/widget_hwnd_utils.h" #include "ui/views/window/native_frame_view.h" #pragma comment(lib, "dwmapi.lib") @@ -224,14 +225,6 @@ BOOL CALLBACK EnumerateChildWindowsForNativeWidgets(HWND hwnd, LPARAM l_param) { return TRUE; } -// Returns true if the WINDOWPOS data provided indicates the client area of -// the window may have changed size. This can be caused by the window being -// resized or its frame changing. -bool DidClientAreaSizeChange(const WINDOWPOS* window_pos) { - return !(window_pos->flags & SWP_NOSIZE) || - window_pos->flags & SWP_FRAMECHANGED; -} - // Callback used to notify child windows that the top level window received a // DWMCompositionChanged message. BOOL CALLBACK SendDwmCompositionChanged(HWND window, LPARAM param) { diff --git a/ui/views/widget/widget_hwnd_utils.cc b/ui/views/widget/widget_hwnd_utils.cc new file mode 100644 index 0000000..cb7ef1d --- /dev/null +++ b/ui/views/widget/widget_hwnd_utils.cc @@ -0,0 +1,14 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/views/widget/widget_hwnd_utils.h" + +namespace views { + +bool DidClientAreaSizeChange(const WINDOWPOS* window_pos) { + return !(window_pos->flags & SWP_NOSIZE) || + window_pos->flags & SWP_FRAMECHANGED; +} + +} // namespace views diff --git a/ui/views/widget/widget_hwnd_utils.h b/ui/views/widget/widget_hwnd_utils.h new file mode 100644 index 0000000..cf7010d --- /dev/null +++ b/ui/views/widget/widget_hwnd_utils.h @@ -0,0 +1,22 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_VIEWS_WIDGET_WIDGET_HWND_UTILS_H_ +#define UI_VIEWS_WIDGET_WIDGET_HWND_UTILS_H_ +#pragma once + +#include <windows.h> + +// Functions shared by native_widget_win.cc and widget_message_filter.cc: + +namespace views { + +// Returns true if the WINDOWPOS data provided indicates the client area of +// the window may have changed size. This can be caused by the window being +// resized or its frame changing. +bool DidClientAreaSizeChange(const WINDOWPOS* window_pos); + +} // namespace views + +#endif // UI_VIEWS_WIDGET_WIDGET_HWND_UTILS_H_ diff --git a/ui/views/widget/widget_message_filter.cc b/ui/views/widget/widget_message_filter.cc new file mode 100644 index 0000000..f2239e6 --- /dev/null +++ b/ui/views/widget/widget_message_filter.cc @@ -0,0 +1,131 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/views/widget/widget_message_filter.h" + +#include <windowsx.h> + +#include "ui/aura/root_window.h" +#include "ui/gfx/canvas_skia_paint.h" +#include "ui/gfx/insets.h" +#include "ui/gfx/path.h" +#include "ui/views/window/non_client_view.h" +#include "ui/views/widget/widget.h" +#include "ui/views/widget/widget_hwnd_utils.h" + +namespace views { + +WidgetMessageFilter::WidgetMessageFilter(aura::RootWindow* root_window, + Widget* widget) + : root_window_(root_window), + widget_(widget) { + hwnd_ = root_window_->GetAcceleratedWidget(); + ClientAreaSizeChanged(); +} + +WidgetMessageFilter::~WidgetMessageFilter() { +} + +bool WidgetMessageFilter::FilterMessage(HWND hwnd, + UINT message, + WPARAM w_param, + LPARAM l_param, + LRESULT* l_result) { + switch (message) { + case WM_NCCALCSIZE: + return OnNCCalcSize(w_param, l_param, l_result); + case WM_NCHITTEST: + return OnNCHitTest(GET_X_LPARAM(l_param), + GET_Y_LPARAM(l_param), + l_result); + case WM_NCPAINT: + return OnNCPaint(reinterpret_cast<HRGN>(w_param)); + case WM_SIZE: + OnSize(); + return false; + case WM_WINDOWPOSCHANGED: + OnWindowPosChanged(reinterpret_cast<WINDOWPOS*>(l_param)); + return false; + } + return false; +} + +bool WidgetMessageFilter::OnNCCalcSize(WPARAM w_param, + LPARAM l_param, + LRESULT* l_result) { + gfx::Insets insets = GetClientAreaInsets(); + if (insets.empty()) { + *l_result = 0; + return false; + } + + RECT* client_rect = w_param ? + &(reinterpret_cast<NCCALCSIZE_PARAMS*>(l_param)->rgrc[0]) : + reinterpret_cast<RECT*>(l_param); + client_rect->left += insets.left(); + client_rect->top += insets.top(); + client_rect->bottom -= insets.bottom(); + client_rect->right -= insets.right(); + + if (insets.left() == 0 || insets.top() == 0) + *l_result = 0; + else + *l_result = w_param ? WVR_REDRAW : 0; + return true; +} + +bool WidgetMessageFilter::OnNCHitTest(int x, int y, LRESULT* l_result) { + POINT temp = { x, y }; + MapWindowPoints(HWND_DESKTOP, hwnd_, &temp, 1); + int component = widget_->GetNonClientComponent(gfx::Point(temp)); + if (component != HTNOWHERE) { + *l_result = component; + return true; + } + return false; +} + +bool WidgetMessageFilter::OnNCPaint(HRGN update_region) { + NOTIMPLEMENTED(); + return true; +} + +void WidgetMessageFilter::OnSize() { + // ResetWindowRegion is going to trigger WM_NCPAINT. By doing it after we've + // invoked OnSize we ensure the RootView has been laid out. + ResetWindowRegion(false); +} + +void WidgetMessageFilter::OnWindowPosChanged(WINDOWPOS* window_pos) { + if (DidClientAreaSizeChange(window_pos)) + ClientAreaSizeChanged(); +} + +gfx::Insets WidgetMessageFilter::GetClientAreaInsets() const { + // TODO(beng): native frame + return gfx::Insets(0, 0, 1, 0); +} + +bool WidgetMessageFilter::WidgetSizeIsClientSize() const { + // TODO(beng): + return false; +} + +void WidgetMessageFilter::ClientAreaSizeChanged() { + RECT r; + if (WidgetSizeIsClientSize()) + GetClientRect(hwnd_, &r); + else + GetWindowRect(hwnd_, &r); + gfx::Size s(std::max(0, static_cast<int>(r.right - r.left)), + std::max(0, static_cast<int>(r.bottom - r.top))); + widget_->OnNativeWidgetSizeChanged(s); +} + +void WidgetMessageFilter::ResetWindowRegion(bool force) { + NOTIMPLEMENTED(); +} + + +} // namespace views diff --git a/ui/views/widget/widget_message_filter.h b/ui/views/widget/widget_message_filter.h new file mode 100644 index 0000000..a453d58 --- /dev/null +++ b/ui/views/widget/widget_message_filter.h @@ -0,0 +1,59 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_VIEWS_WIDGET_WIDGET_MESSAGE_FILTER_H_ +#define UI_VIEWS_WIDGET_WIDGET_MESSAGE_FILTER_H_ +#pragma once + +#include "ui/base/win/hwnd_subclass.h" + +namespace aura { +class RootWindow; +} + +namespace gfx { +class Insets; +} + +namespace views { + +class Widget; + +// A message filter that implements a custom frame look for views Widgets. +class WidgetMessageFilter : public ui::HWNDMessageFilter { + public: + WidgetMessageFilter(aura::RootWindow* root_window, Widget* widget); + virtual ~WidgetMessageFilter(); + + private: + // Overridden from ui::HWNDMessageFilter: + virtual bool FilterMessage(HWND hwnd, + UINT message, + WPARAM w_param, + LPARAM l_param, + LRESULT* l_result) OVERRIDE; + + // Message handlers. + bool OnNCCalcSize(WPARAM w_param, LPARAM l_param, LRESULT* l_result); + bool OnNCHitTest(int x, int y, LRESULT* l_result); + bool OnNCPaint(HRGN update_region); + void OnSize(); + void OnWindowPosChanged(WINDOWPOS* window_pos); + + // TODO(beng): Lift documentation from NativeWidgetWin. + gfx::Insets GetClientAreaInsets() const; + bool WidgetSizeIsClientSize() const; + void ClientAreaSizeChanged(); + void ResetWindowRegion(bool force); + + aura::RootWindow* root_window_; + Widget* widget_; + HWND hwnd_; + + DISALLOW_COPY_AND_ASSIGN(WidgetMessageFilter); +}; + +} // namespace views + +#endif // UI_VIEWS_WIDGET_WIDGET_MESSAGE_FILTER_H_ |