OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/views/win/hwnd_message_handler.h" | 5 #include "ui/views/win/hwnd_message_handler.h" |
6 | 6 |
7 #include <dwmapi.h> | 7 #include <dwmapi.h> |
8 #include <shellapi.h> | 8 #include <shellapi.h> |
9 #include <wtsapi32.h> | |
10 #pragma comment(lib, "wtsapi32.lib") | |
9 | 11 |
10 #include "base/bind.h" | 12 #include "base/bind.h" |
11 #include "base/debug/trace_event.h" | 13 #include "base/debug/trace_event.h" |
12 #include "base/win/win_util.h" | 14 #include "base/win/win_util.h" |
13 #include "base/win/windows_version.h" | 15 #include "base/win/windows_version.h" |
14 #include "ui/base/touch/touch_enabled.h" | 16 #include "ui/base/touch/touch_enabled.h" |
15 #include "ui/base/win/mouse_wheel_util.h" | 17 #include "ui/base/win/mouse_wheel_util.h" |
16 #include "ui/base/win/shell.h" | 18 #include "ui/base/win/shell.h" |
17 #include "ui/base/win/touch_input.h" | 19 #include "ui/base/win/touch_input.h" |
18 #include "ui/events/event.h" | 20 #include "ui/events/event.h" |
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
308 } | 310 } |
309 | 311 |
310 void AddScrollStylesToWindow(HWND window) { | 312 void AddScrollStylesToWindow(HWND window) { |
311 if (::IsWindow(window)) { | 313 if (::IsWindow(window)) { |
312 long current_style = ::GetWindowLong(window, GWL_STYLE); | 314 long current_style = ::GetWindowLong(window, GWL_STYLE); |
313 ::SetWindowLong(window, GWL_STYLE, | 315 ::SetWindowLong(window, GWL_STYLE, |
314 current_style | WS_VSCROLL | WS_HSCROLL); | 316 current_style | WS_VSCROLL | WS_HSCROLL); |
315 } | 317 } |
316 } | 318 } |
317 | 319 |
320 bool IsWorkstationLocked() { | |
sky
2014/01/24 00:36:07
This looks like a copy of that in idle_win. How ab
| |
321 bool is_locked = true; | |
322 HDESK input_desk = ::OpenInputDesktop(0, 0, GENERIC_READ); | |
323 if (input_desk) { | |
324 wchar_t name[256] = {0}; | |
325 DWORD needed = 0; | |
326 if (::GetUserObjectInformation( | |
327 input_desk, UOI_NAME, name, sizeof(name), &needed)) { | |
328 is_locked = lstrcmpi(name, L"default") != 0; | |
329 } | |
330 ::CloseDesktop(input_desk); | |
331 } | |
332 return is_locked; | |
333 } | |
cpu_(ooo_6.6-7.5)
2014/01/23 23:01:13
if ::OpenInputDesktop fails I don't know if it is
| |
334 | |
318 } // namespace | 335 } // namespace |
319 | 336 |
320 // A scoping class that prevents a window from being able to redraw in response | 337 // A scoping class that prevents a window from being able to redraw in response |
321 // to invalidations that may occur within it for the lifetime of the object. | 338 // to invalidations that may occur within it for the lifetime of the object. |
322 // | 339 // |
323 // Why would we want such a thing? Well, it turns out Windows has some | 340 // Why would we want such a thing? Well, it turns out Windows has some |
324 // "unorthodox" behavior when it comes to painting its non-client areas. | 341 // "unorthodox" behavior when it comes to painting its non-client areas. |
325 // Occasionally, Windows will paint portions of the default non-client area | 342 // Occasionally, Windows will paint portions of the default non-client area |
326 // right over the top of the custom frame. This is not simply fixed by handling | 343 // right over the top of the custom frame. This is not simply fixed by handling |
327 // WM_NCPAINT/WM_PAINT, with some investigation it turns out that this | 344 // WM_NCPAINT/WM_PAINT, with some investigation it turns out that this |
(...skipping 952 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1280 POINT position = {wr.left, wr.top}; | 1297 POINT position = {wr.left, wr.top}; |
1281 HDC dib_dc = skia::BeginPlatformPaint(layered_window_contents_->sk_canvas()); | 1298 HDC dib_dc = skia::BeginPlatformPaint(layered_window_contents_->sk_canvas()); |
1282 POINT zero = {0, 0}; | 1299 POINT zero = {0, 0}; |
1283 BLENDFUNCTION blend = {AC_SRC_OVER, 0, layered_alpha_, AC_SRC_ALPHA}; | 1300 BLENDFUNCTION blend = {AC_SRC_OVER, 0, layered_alpha_, AC_SRC_ALPHA}; |
1284 UpdateLayeredWindow(hwnd(), NULL, &position, &size, dib_dc, &zero, | 1301 UpdateLayeredWindow(hwnd(), NULL, &position, &size, dib_dc, &zero, |
1285 RGB(0xFF, 0xFF, 0xFF), &blend, ULW_ALPHA); | 1302 RGB(0xFF, 0xFF, 0xFF), &blend, ULW_ALPHA); |
1286 invalid_rect_.SetRect(0, 0, 0, 0); | 1303 invalid_rect_.SetRect(0, 0, 0, 0); |
1287 skia::EndPlatformPaint(layered_window_contents_->sk_canvas()); | 1304 skia::EndPlatformPaint(layered_window_contents_->sk_canvas()); |
1288 } | 1305 } |
1289 | 1306 |
1307 void HWNDMessageHandler::ForceRedrawWindow(int attempts) { | |
1308 if (IsWorkstationLocked()) { | |
1309 // Presents will continue to fail as long as the input desktop is | |
1310 // unavailable. | |
1311 if (--attempts <= 0) | |
1312 return; | |
1313 base::MessageLoop::current()->PostDelayedTask( | |
1314 FROM_HERE, | |
1315 base::Bind(&HWNDMessageHandler::ForceRedrawWindow, | |
1316 weak_factory_.GetWeakPtr(), | |
1317 attempts), | |
1318 base::TimeDelta::FromMilliseconds(500)); | |
1319 return; | |
1320 } | |
1321 InvalidateRect(hwnd(), NULL, FALSE); | |
1322 } | |
1323 | |
1290 // Message handlers ------------------------------------------------------------ | 1324 // Message handlers ------------------------------------------------------------ |
1291 | 1325 |
1292 void HWNDMessageHandler::OnActivateApp(BOOL active, DWORD thread_id) { | 1326 void HWNDMessageHandler::OnActivateApp(BOOL active, DWORD thread_id) { |
1293 if (delegate_->IsWidgetWindow() && !active && | 1327 if (delegate_->IsWidgetWindow() && !active && |
1294 thread_id != GetCurrentThreadId()) { | 1328 thread_id != GetCurrentThreadId()) { |
1295 delegate_->HandleAppDeactivated(); | 1329 delegate_->HandleAppDeactivated(); |
1296 // Also update the native frame if it is rendering the non-client area. | 1330 // Also update the native frame if it is rendering the non-client area. |
1297 if (!remove_standard_frame_ && !delegate_->IsUsingCustomFrame()) | 1331 if (!remove_standard_frame_ && !delegate_->IsUsingCustomFrame()) |
1298 DefWindowProcWithRedrawLock(WM_NCACTIVATE, FALSE, 0); | 1332 DefWindowProcWithRedrawLock(WM_NCACTIVATE, FALSE, 0); |
1299 } | 1333 } |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1379 #if !defined(USE_AURA) | 1413 #if !defined(USE_AURA) |
1380 // We need to add ourselves as a message loop observer so that we can repaint | 1414 // We need to add ourselves as a message loop observer so that we can repaint |
1381 // aggressively if the contents of our window become invalid. Unfortunately | 1415 // aggressively if the contents of our window become invalid. Unfortunately |
1382 // WM_PAINT messages are starved and we get flickery redrawing when resizing | 1416 // WM_PAINT messages are starved and we get flickery redrawing when resizing |
1383 // if we do not do this. | 1417 // if we do not do this. |
1384 base::MessageLoopForUI::current()->AddObserver(this); | 1418 base::MessageLoopForUI::current()->AddObserver(this); |
1385 #endif | 1419 #endif |
1386 | 1420 |
1387 delegate_->HandleCreate(); | 1421 delegate_->HandleCreate(); |
1388 | 1422 |
1423 WTSRegisterSessionNotification(hwnd(), NOTIFY_FOR_THIS_SESSION); | |
1424 | |
1389 // TODO(beng): move more of NWW::OnCreate here. | 1425 // TODO(beng): move more of NWW::OnCreate here. |
1390 return 0; | 1426 return 0; |
1391 } | 1427 } |
1392 | 1428 |
1393 void HWNDMessageHandler::OnDestroy() { | 1429 void HWNDMessageHandler::OnDestroy() { |
1430 WTSUnRegisterSessionNotification(hwnd()); | |
1394 delegate_->HandleDestroying(); | 1431 delegate_->HandleDestroying(); |
1395 } | 1432 } |
1396 | 1433 |
1397 void HWNDMessageHandler::OnDisplayChange(UINT bits_per_pixel, | 1434 void HWNDMessageHandler::OnDisplayChange(UINT bits_per_pixel, |
1398 const CSize& screen_size) { | 1435 const CSize& screen_size) { |
1399 delegate_->HandleDisplayChange(); | 1436 delegate_->HandleDisplayChange(); |
1400 } | 1437 } |
1401 | 1438 |
1402 LRESULT HWNDMessageHandler::OnDwmCompositionChanged(UINT msg, | 1439 LRESULT HWNDMessageHandler::OnDwmCompositionChanged(UINT msg, |
1403 WPARAM w_param, | 1440 WPARAM w_param, |
(...skipping 641 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2045 | 2082 |
2046 LRESULT HWNDMessageHandler::OnScrollMessage(UINT message, | 2083 LRESULT HWNDMessageHandler::OnScrollMessage(UINT message, |
2047 WPARAM w_param, | 2084 WPARAM w_param, |
2048 LPARAM l_param) { | 2085 LPARAM l_param) { |
2049 MSG msg = { hwnd(), message, w_param, l_param, GetMessageTime() }; | 2086 MSG msg = { hwnd(), message, w_param, l_param, GetMessageTime() }; |
2050 ui::ScrollEvent event(msg); | 2087 ui::ScrollEvent event(msg); |
2051 delegate_->HandleScrollEvent(event); | 2088 delegate_->HandleScrollEvent(event); |
2052 return 0; | 2089 return 0; |
2053 } | 2090 } |
2054 | 2091 |
2092 void HWNDMessageHandler::OnSessionChange(WPARAM status_code, | |
2093 PWTSSESSION_NOTIFICATION session_id) { | |
2094 // Direct3D presents are ignored while the screen is locked, so force the | |
2095 // window to be redrawn on unlock. | |
2096 if (status_code == WTS_SESSION_UNLOCK) | |
2097 ForceRedrawWindow(10); | |
2098 | |
2099 SetMsgHandled(FALSE); | |
2100 } | |
2101 | |
2055 LRESULT HWNDMessageHandler::OnSetCursor(UINT message, | 2102 LRESULT HWNDMessageHandler::OnSetCursor(UINT message, |
2056 WPARAM w_param, | 2103 WPARAM w_param, |
2057 LPARAM l_param) { | 2104 LPARAM l_param) { |
2058 // Reimplement the necessary default behavior here. Calling DefWindowProc can | 2105 // Reimplement the necessary default behavior here. Calling DefWindowProc can |
2059 // trigger weird non-client painting for non-glass windows with custom frames. | 2106 // trigger weird non-client painting for non-glass windows with custom frames. |
2060 // Using a ScopedRedrawLock to prevent caption rendering artifacts may allow | 2107 // Using a ScopedRedrawLock to prevent caption rendering artifacts may allow |
2061 // content behind this window to incorrectly paint in front of this window. | 2108 // content behind this window to incorrectly paint in front of this window. |
2062 // Invalidating the window to paint over either set of artifacts is not ideal. | 2109 // Invalidating the window to paint over either set of artifacts is not ideal. |
2063 wchar_t* cursor = IDC_ARROW; | 2110 wchar_t* cursor = IDC_ARROW; |
2064 switch (LOWORD(l_param)) { | 2111 switch (LOWORD(l_param)) { |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2357 SetMsgHandled(FALSE); | 2404 SetMsgHandled(FALSE); |
2358 } | 2405 } |
2359 | 2406 |
2360 void HWNDMessageHandler::HandleTouchEvents(const TouchEvents& touch_events) { | 2407 void HWNDMessageHandler::HandleTouchEvents(const TouchEvents& touch_events) { |
2361 base::WeakPtr<HWNDMessageHandler> ref(weak_factory_.GetWeakPtr()); | 2408 base::WeakPtr<HWNDMessageHandler> ref(weak_factory_.GetWeakPtr()); |
2362 for (size_t i = 0; i < touch_events.size() && ref; ++i) | 2409 for (size_t i = 0; i < touch_events.size() && ref; ++i) |
2363 delegate_->HandleTouchEvent(touch_events[i]); | 2410 delegate_->HandleTouchEvent(touch_events[i]); |
2364 } | 2411 } |
2365 | 2412 |
2366 } // namespace views | 2413 } // namespace views |
OLD | NEW |