1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/aura/root_window_host_win.h"
11 #include "base/message_loop/message_loop.h"
12 #include "ui/aura/client/cursor_client.h"
13 #include "ui/aura/root_window.h"
14 #include "ui/base/cursor/cursor_loader_win.h"
15 #include "ui/events/event.h"
16 #include "ui/base/view_prop.h"
17 #include "ui/gfx/display.h"
18 #include "ui/gfx/insets.h"
19 #include "ui/gfx/screen.h"
27 bool use_popup_as_root_window_for_test
= false;
32 RootWindowHost
* RootWindowHost::Create(const gfx::Rect
& bounds
) {
33 return new RootWindowHostWin(bounds
);
37 gfx::Size
RootWindowHost::GetNativeScreenSize() {
38 return gfx::Size(GetSystemMetrics(SM_CXSCREEN
),
39 GetSystemMetrics(SM_CYSCREEN
));
42 RootWindowHostWin::RootWindowHostWin(const gfx::Rect
& bounds
)
45 saved_window_style_(0),
46 saved_window_ex_style_(0) {
47 if (use_popup_as_root_window_for_test
)
48 set_window_style(WS_POPUP
);
50 SetWindowText(hwnd(), L
"aura::RootWindow!");
53 RootWindowHostWin::~RootWindowHostWin() {
54 DestroyWindow(hwnd());
57 RootWindow
* RootWindowHostWin::GetRootWindow() {
58 return delegate_
->AsRootWindow();
61 gfx::AcceleratedWidget
RootWindowHostWin::GetAcceleratedWidget() {
65 void RootWindowHostWin::Show() {
66 ShowWindow(hwnd(), SW_SHOWNORMAL
);
69 void RootWindowHostWin::Hide() {
73 void RootWindowHostWin::ToggleFullScreen() {
74 gfx::Rect target_rect
;
77 saved_window_style_
= GetWindowLong(hwnd(), GWL_STYLE
);
78 saved_window_ex_style_
= GetWindowLong(hwnd(), GWL_EXSTYLE
);
79 GetWindowRect(hwnd(), &saved_window_rect_
);
80 SetWindowLong(hwnd(), GWL_STYLE
,
81 saved_window_style_
& ~(WS_CAPTION
| WS_THICKFRAME
));
82 SetWindowLong(hwnd(), GWL_EXSTYLE
,
83 saved_window_ex_style_
& ~(WS_EX_DLGMODALFRAME
|
84 WS_EX_WINDOWEDGE
| WS_EX_CLIENTEDGE
| WS_EX_STATICEDGE
));
87 mi
.cbSize
= sizeof(mi
);
88 GetMonitorInfo(MonitorFromWindow(hwnd(), MONITOR_DEFAULTTONEAREST
), &mi
);
89 target_rect
= gfx::Rect(mi
.rcMonitor
);
92 SetWindowLong(hwnd(), GWL_STYLE
, saved_window_style_
);
93 SetWindowLong(hwnd(), GWL_EXSTYLE
, saved_window_ex_style_
);
94 target_rect
= gfx::Rect(saved_window_rect_
);
101 target_rect
.height(),
102 SWP_NOZORDER
| SWP_NOACTIVATE
| SWP_FRAMECHANGED
);
105 gfx::Rect
RootWindowHostWin::GetBounds() const {
107 GetClientRect(hwnd(), &r
);
111 void RootWindowHostWin::SetBounds(const gfx::Rect
& bounds
) {
113 saved_window_rect_
.right
= saved_window_rect_
.left
+ bounds
.width();
114 saved_window_rect_
.bottom
= saved_window_rect_
.top
+ bounds
.height();
118 window_rect
.left
= bounds
.x();
119 window_rect
.top
= bounds
.y();
120 window_rect
.right
= bounds
.right() ;
121 window_rect
.bottom
= bounds
.bottom();
122 AdjustWindowRectEx(&window_rect
,
123 GetWindowLong(hwnd(), GWL_STYLE
),
125 GetWindowLong(hwnd(), GWL_EXSTYLE
));
131 window_rect
.right
- window_rect
.left
,
132 window_rect
.bottom
- window_rect
.top
,
133 SWP_NOMOVE
| SWP_NOOWNERZORDER
| SWP_NOREDRAW
| SWP_NOREPOSITION
);
135 // Explicity call OnHostResized when the scale has changed because
136 // the window size may not have changed.
137 float current_scale
= delegate_
->GetDeviceScaleFactor();
138 float new_scale
= gfx::Screen::GetScreenFor(
139 delegate_
->AsRootWindow()->window())->GetDisplayNearestWindow(
140 delegate_
->AsRootWindow()->window()).device_scale_factor();
141 if (current_scale
!= new_scale
)
142 delegate_
->OnHostResized(bounds
.size());
145 gfx::Insets
RootWindowHostWin::GetInsets() const {
146 return gfx::Insets();
149 void RootWindowHostWin::SetInsets(const gfx::Insets
& insets
) {
152 gfx::Point
RootWindowHostWin::GetLocationOnNativeScreen() const {
154 GetClientRect(hwnd(), &r
);
155 return gfx::Point(r
.left
, r
.top
);
159 void RootWindowHostWin::SetCursor(gfx::NativeCursor native_cursor
) {
160 // Custom web cursors are handled directly.
161 if (native_cursor
== ui::kCursorCustom
)
164 ui::CursorLoaderWin cursor_loader
;
165 cursor_loader
.SetPlatformCursor(&native_cursor
);
166 ::SetCursor(native_cursor
.platform());
169 void RootWindowHostWin::SetCapture() {
172 ::SetCapture(hwnd());
176 void RootWindowHostWin::ReleaseCapture() {
178 has_capture_
= false;
183 bool RootWindowHostWin::QueryMouseLocation(gfx::Point
* location_return
) {
184 client::CursorClient
* cursor_client
=
185 client::GetCursorClient(GetRootWindow()->window());
186 if (cursor_client
&& !cursor_client
->IsMouseEventsEnabled()) {
187 *location_return
= gfx::Point(0, 0);
193 ScreenToClient(hwnd(), &pt
);
194 const gfx::Size size
= GetBounds().size();
196 gfx::Point(max(0, min(size
.width(), static_cast<int>(pt
.x
))),
197 max(0, min(size
.height(), static_cast<int>(pt
.y
))));
198 return (pt
.x
>= 0 && static_cast<int>(pt
.x
) < size
.width() &&
199 pt
.y
>= 0 && static_cast<int>(pt
.y
) < size
.height());
202 bool RootWindowHostWin::ConfineCursorToRootWindow() {
204 GetWindowRect(hwnd(), &window_rect
);
205 return ClipCursor(&window_rect
) != 0;
208 void RootWindowHostWin::UnConfineCursor() {
212 void RootWindowHostWin::OnCursorVisibilityChanged(bool show
) {
216 void RootWindowHostWin::MoveCursorTo(const gfx::Point
& location
) {
217 // Deliberately not implemented.
220 void RootWindowHostWin::PostNativeEvent(const base::NativeEvent
& native_event
) {
222 hwnd(), native_event
.message
, native_event
.wParam
, native_event
.lParam
);
225 void RootWindowHostWin::OnDeviceScaleFactorChanged(
226 float device_scale_factor
) {
230 void RootWindowHostWin::PrepareForShutdown() {
234 void RootWindowHostWin::OnClose() {
235 // TODO: this obviously shouldn't be here.
236 base::MessageLoopForUI::current()->Quit();
239 LRESULT
RootWindowHostWin::OnKeyEvent(UINT message
,
242 MSG msg
= { hwnd(), message
, w_param
, l_param
};
243 ui::KeyEvent
keyev(msg
, message
== WM_CHAR
);
244 SetMsgHandled(delegate_
->OnHostKeyEvent(&keyev
));
248 LRESULT
RootWindowHostWin::OnMouseRange(UINT message
,
251 MSG msg
= { hwnd(), message
, w_param
, l_param
, 0,
252 { GET_X_LPARAM(l_param
), GET_Y_LPARAM(l_param
) } };
253 ui::MouseEvent
event(msg
);
254 bool handled
= false;
255 if (!(event
.flags() & ui::EF_IS_NON_CLIENT
))
256 handled
= delegate_
->OnHostMouseEvent(&event
);
257 SetMsgHandled(handled
);
261 LRESULT
RootWindowHostWin::OnCaptureChanged(UINT message
,
265 has_capture_
= false;
266 delegate_
->OnHostLostWindowCapture();
271 LRESULT
RootWindowHostWin::OnNCActivate(UINT message
,
275 delegate_
->OnHostActivated();
276 return DefWindowProc(hwnd(), message
, w_param
, l_param
);
279 void RootWindowHostWin::OnMove(const CPoint
& point
) {
281 delegate_
->OnHostMoved(gfx::Point(point
.x
, point
.y
));
284 void RootWindowHostWin::OnPaint(HDC dc
) {
285 gfx::Rect damage_rect
;
286 RECT update_rect
= {0};
287 if (GetUpdateRect(hwnd(), &update_rect
, FALSE
))
288 damage_rect
= gfx::Rect(update_rect
);
289 delegate_
->OnHostPaint(damage_rect
);
290 ValidateRect(hwnd(), NULL
);
293 void RootWindowHostWin::OnSize(UINT param
, const CSize
& size
) {
294 // Minimizing resizes the window to 0x0 which causes our layout to go all
295 // screwy, so we just ignore it.
296 if (delegate_
&& param
!= SIZE_MINIMIZED
)
297 delegate_
->OnHostResized(gfx::Size(size
.cx
, size
.cy
));
303 void SetUsePopupAsRootWindowForTest(bool use
) {
304 use_popup_as_root_window_for_test
= use
;