summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ui/gfx/screen_aura.cc3
-rw-r--r--ui/views/views.gyp16
-rw-r--r--ui/views/widget/desktop_native_widget_helper_aura.cc16
-rw-r--r--ui/views/widget/desktop_native_widget_helper_aura.h12
-rw-r--r--ui/views/widget/native_widget_aura.cc6
-rw-r--r--ui/views/widget/native_widget_helper_aura.h4
-rw-r--r--ui/views/widget/native_widget_win.cc9
-rw-r--r--ui/views/widget/widget_hwnd_utils.cc14
-rw-r--r--ui/views/widget/widget_hwnd_utils.h22
-rw-r--r--ui/views/widget/widget_message_filter.cc131
-rw-r--r--ui/views/widget/widget_message_filter.h59
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_