Chromium Code Reviews| 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() { | |
| 321 bool is_locked = true; | |
| 322 HDESK input_desk = ::OpenInputDesktop(0, 0, GENERIC_READ); | |
|
cpu_(ooo_6.6-7.5)
2014/01/19 20:52:45
Opening the input desktop still has me confused. Y
| |
| 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 } | |
| 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 |