| 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 <oleacc.h> | 8 #include <oleacc.h> |
| 9 #include <shellapi.h> | 9 #include <shellapi.h> |
| 10 #include <tchar.h> | 10 #include <tchar.h> |
| 11 | 11 |
| 12 #include <utility> | 12 #include <utility> |
| 13 | 13 |
| 14 #include "base/bind.h" | 14 #include "base/bind.h" |
| 15 #include "base/bind_helpers.h" | 15 #include "base/bind_helpers.h" |
| 16 #include "base/debug/alias.h" | 16 #include "base/debug/alias.h" |
| 17 #include "base/location.h" |
| 17 #include "base/macros.h" | 18 #include "base/macros.h" |
| 19 #include "base/single_thread_task_runner.h" |
| 20 #include "base/threading/thread_task_runner_handle.h" |
| 18 #include "base/trace_event/trace_event.h" | 21 #include "base/trace_event/trace_event.h" |
| 19 #include "base/win/scoped_gdi_object.h" | 22 #include "base/win/scoped_gdi_object.h" |
| 20 #include "base/win/windows_version.h" | 23 #include "base/win/windows_version.h" |
| 21 #include "ui/base/touch/touch_enabled.h" | 24 #include "ui/base/touch/touch_enabled.h" |
| 22 #include "ui/base/view_prop.h" | 25 #include "ui/base/view_prop.h" |
| 23 #include "ui/base/win/internal_constants.h" | 26 #include "ui/base/win/internal_constants.h" |
| 24 #include "ui/base/win/lock_state.h" | 27 #include "ui/base/win/lock_state.h" |
| 25 #include "ui/base/win/mouse_wheel_util.h" | 28 #include "ui/base/win/mouse_wheel_util.h" |
| 26 #include "ui/base/win/shell.h" | 29 #include "ui/base/win/shell.h" |
| 27 #include "ui/base/win/touch_input.h" | 30 #include "ui/base/win/touch_input.h" |
| (...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 415 | 418 |
| 416 // Re-enable flicks which removes the window property. | 419 // Re-enable flicks which removes the window property. |
| 417 base::win::EnableFlicks(hwnd()); | 420 base::win::EnableFlicks(hwnd()); |
| 418 | 421 |
| 419 if (!waiting_for_close_now_) { | 422 if (!waiting_for_close_now_) { |
| 420 // And we delay the close so that if we are called from an ATL callback, | 423 // And we delay the close so that if we are called from an ATL callback, |
| 421 // we don't destroy the window before the callback returned (as the caller | 424 // we don't destroy the window before the callback returned (as the caller |
| 422 // may delete ourselves on destroy and the ATL callback would still | 425 // may delete ourselves on destroy and the ATL callback would still |
| 423 // dereference us when the callback returns). | 426 // dereference us when the callback returns). |
| 424 waiting_for_close_now_ = true; | 427 waiting_for_close_now_ = true; |
| 425 base::MessageLoop::current()->PostTask( | 428 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 426 FROM_HERE, | 429 FROM_HERE, |
| 427 base::Bind(&HWNDMessageHandler::CloseNow, weak_factory_.GetWeakPtr())); | 430 base::Bind(&HWNDMessageHandler::CloseNow, weak_factory_.GetWeakPtr())); |
| 428 } | 431 } |
| 429 } | 432 } |
| 430 | 433 |
| 431 void HWNDMessageHandler::CloseNow() { | 434 void HWNDMessageHandler::CloseNow() { |
| 432 // We may already have been destroyed if the selection resulted in a tab | 435 // We may already have been destroyed if the selection resulted in a tab |
| 433 // switch which will have reactivated the browser window and closed us, so | 436 // switch which will have reactivated the browser window and closed us, so |
| 434 // we need to check to see if we're still a window before trying to destroy | 437 // we need to check to see if we're still a window before trying to destroy |
| 435 // ourself. | 438 // ourself. |
| (...skipping 809 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1245 lock_updates_count_ = 0; | 1248 lock_updates_count_ = 0; |
| 1246 } | 1249 } |
| 1247 } | 1250 } |
| 1248 | 1251 |
| 1249 void HWNDMessageHandler::ForceRedrawWindow(int attempts) { | 1252 void HWNDMessageHandler::ForceRedrawWindow(int attempts) { |
| 1250 if (ui::IsWorkstationLocked()) { | 1253 if (ui::IsWorkstationLocked()) { |
| 1251 // Presents will continue to fail as long as the input desktop is | 1254 // Presents will continue to fail as long as the input desktop is |
| 1252 // unavailable. | 1255 // unavailable. |
| 1253 if (--attempts <= 0) | 1256 if (--attempts <= 0) |
| 1254 return; | 1257 return; |
| 1255 base::MessageLoop::current()->PostDelayedTask( | 1258 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 1256 FROM_HERE, | 1259 FROM_HERE, base::Bind(&HWNDMessageHandler::ForceRedrawWindow, |
| 1257 base::Bind(&HWNDMessageHandler::ForceRedrawWindow, | 1260 weak_factory_.GetWeakPtr(), attempts), |
| 1258 weak_factory_.GetWeakPtr(), | |
| 1259 attempts), | |
| 1260 base::TimeDelta::FromMilliseconds(500)); | 1261 base::TimeDelta::FromMilliseconds(500)); |
| 1261 return; | 1262 return; |
| 1262 } | 1263 } |
| 1263 InvalidateRect(hwnd(), NULL, FALSE); | 1264 InvalidateRect(hwnd(), NULL, FALSE); |
| 1264 } | 1265 } |
| 1265 | 1266 |
| 1266 bool HWNDMessageHandler::HasSystemFrame() const { | 1267 bool HWNDMessageHandler::HasSystemFrame() const { |
| 1267 return delegate_->HasFrame() && | 1268 return delegate_->HasFrame() && |
| 1268 delegate_->GetFrameMode() == FrameMode::SYSTEM_DRAWN; | 1269 delegate_->GetFrameMode() == FrameMode::SYSTEM_DRAWN; |
| 1269 } | 1270 } |
| (...skipping 838 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2108 | 2109 |
| 2109 // We add the WS_VSCROLL and WS_HSCROLL styles to top level windows to ensure | 2110 // We add the WS_VSCROLL and WS_HSCROLL styles to top level windows to ensure |
| 2110 // that legacy trackpad/trackpoint drivers generate the WM_VSCROLL and | 2111 // that legacy trackpad/trackpoint drivers generate the WM_VSCROLL and |
| 2111 // WM_HSCROLL messages and scrolling works. | 2112 // WM_HSCROLL messages and scrolling works. |
| 2112 // We want the scroll styles to be present on the window. However we don't | 2113 // We want the scroll styles to be present on the window. However we don't |
| 2113 // want Windows to draw the scrollbars. To achieve this we hide the scroll | 2114 // want Windows to draw the scrollbars. To achieve this we hide the scroll |
| 2114 // bars and readd them to the window style in a posted task to ensure that we | 2115 // bars and readd them to the window style in a posted task to ensure that we |
| 2115 // don't get nested WM_SIZE messages. | 2116 // don't get nested WM_SIZE messages. |
| 2116 if (needs_scroll_styles_ && !in_size_loop_) { | 2117 if (needs_scroll_styles_ && !in_size_loop_) { |
| 2117 ShowScrollBar(hwnd(), SB_BOTH, FALSE); | 2118 ShowScrollBar(hwnd(), SB_BOTH, FALSE); |
| 2118 base::MessageLoop::current()->PostTask( | 2119 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 2119 FROM_HERE, base::Bind(&AddScrollStylesToWindow, hwnd())); | 2120 FROM_HERE, base::Bind(&AddScrollStylesToWindow, hwnd())); |
| 2120 } | 2121 } |
| 2121 } | 2122 } |
| 2122 | 2123 |
| 2123 void HWNDMessageHandler::OnSysCommand(UINT notification_code, | 2124 void HWNDMessageHandler::OnSysCommand(UINT notification_code, |
| 2124 const gfx::Point& point) { | 2125 const gfx::Point& point) { |
| 2125 if (!delegate_->ShouldHandleSystemCommands()) | 2126 if (!delegate_->ShouldHandleSystemCommands()) |
| 2126 return; | 2127 return; |
| 2127 | 2128 |
| 2128 // Windows uses the 4 lower order bits of |notification_code| for type- | 2129 // Windows uses the 4 lower order bits of |notification_code| for type- |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2220 last_touch_message_time_ = ::GetMessageTime(); | 2221 last_touch_message_time_ = ::GetMessageTime(); |
| 2221 | 2222 |
| 2222 gfx::Point touch_point(point.x, point.y); | 2223 gfx::Point touch_point(point.x, point.y); |
| 2223 unsigned int touch_id = id_generator_.GetGeneratedID(input[i].dwID); | 2224 unsigned int touch_id = id_generator_.GetGeneratedID(input[i].dwID); |
| 2224 | 2225 |
| 2225 if (input[i].dwFlags & TOUCHEVENTF_DOWN) { | 2226 if (input[i].dwFlags & TOUCHEVENTF_DOWN) { |
| 2226 touch_ids_.insert(input[i].dwID); | 2227 touch_ids_.insert(input[i].dwID); |
| 2227 GenerateTouchEvent(ui::ET_TOUCH_PRESSED, touch_point, touch_id, | 2228 GenerateTouchEvent(ui::ET_TOUCH_PRESSED, touch_point, touch_id, |
| 2228 event_time, &touch_events); | 2229 event_time, &touch_events); |
| 2229 touch_down_contexts_++; | 2230 touch_down_contexts_++; |
| 2230 base::MessageLoop::current()->PostDelayedTask( | 2231 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 2231 FROM_HERE, | 2232 FROM_HERE, base::Bind(&HWNDMessageHandler::ResetTouchDownContext, |
| 2232 base::Bind(&HWNDMessageHandler::ResetTouchDownContext, | 2233 weak_factory_.GetWeakPtr()), |
| 2233 weak_factory_.GetWeakPtr()), | |
| 2234 base::TimeDelta::FromMilliseconds(kTouchDownContextResetTimeout)); | 2234 base::TimeDelta::FromMilliseconds(kTouchDownContextResetTimeout)); |
| 2235 } else { | 2235 } else { |
| 2236 if (input[i].dwFlags & TOUCHEVENTF_MOVE) { | 2236 if (input[i].dwFlags & TOUCHEVENTF_MOVE) { |
| 2237 GenerateTouchEvent(ui::ET_TOUCH_MOVED, touch_point, touch_id, | 2237 GenerateTouchEvent(ui::ET_TOUCH_MOVED, touch_point, touch_id, |
| 2238 event_time, &touch_events); | 2238 event_time, &touch_events); |
| 2239 } | 2239 } |
| 2240 | 2240 |
| 2241 if (input[i].dwFlags & TOUCHEVENTF_UP) { | 2241 if (input[i].dwFlags & TOUCHEVENTF_UP) { |
| 2242 touch_ids_.erase(input[i].dwID); | 2242 touch_ids_.erase(input[i].dwID); |
| 2243 GenerateTouchEvent(ui::ET_TOUCH_RELEASED, touch_point, touch_id, | 2243 GenerateTouchEvent(ui::ET_TOUCH_RELEASED, touch_point, touch_id, |
| 2244 event_time, &touch_events); | 2244 event_time, &touch_events); |
| 2245 id_generator_.ReleaseNumber(input[i].dwID); | 2245 id_generator_.ReleaseNumber(input[i].dwID); |
| 2246 } | 2246 } |
| 2247 } | 2247 } |
| 2248 } | 2248 } |
| 2249 // Handle the touch events asynchronously. We need this because touch | 2249 // Handle the touch events asynchronously. We need this because touch |
| 2250 // events on windows don't fire if we enter a modal loop in the context of | 2250 // events on windows don't fire if we enter a modal loop in the context of |
| 2251 // a touch event. | 2251 // a touch event. |
| 2252 base::MessageLoop::current()->PostTask( | 2252 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 2253 FROM_HERE, | 2253 FROM_HERE, base::Bind(&HWNDMessageHandler::HandleTouchEvents, |
| 2254 base::Bind(&HWNDMessageHandler::HandleTouchEvents, | 2254 weak_factory_.GetWeakPtr(), touch_events)); |
| 2255 weak_factory_.GetWeakPtr(), touch_events)); | |
| 2256 } | 2255 } |
| 2257 CloseTouchInputHandle(reinterpret_cast<HTOUCHINPUT>(l_param)); | 2256 CloseTouchInputHandle(reinterpret_cast<HTOUCHINPUT>(l_param)); |
| 2258 SetMsgHandled(FALSE); | 2257 SetMsgHandled(FALSE); |
| 2259 return 0; | 2258 return 0; |
| 2260 } | 2259 } |
| 2261 | 2260 |
| 2262 void HWNDMessageHandler::OnWindowPosChanging(WINDOWPOS* window_pos) { | 2261 void HWNDMessageHandler::OnWindowPosChanging(WINDOWPOS* window_pos) { |
| 2263 if (ignore_window_pos_changes_) { | 2262 if (ignore_window_pos_changes_) { |
| 2264 // If somebody's trying to toggle our visibility, change the nonclient area, | 2263 // If somebody's trying to toggle our visibility, change the nonclient area, |
| 2265 // change our Z-order, or activate us, we should probably let it go through. | 2264 // change our Z-order, or activate us, we should probably let it go through. |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2313 window_pos->cy = new_window_rect.height(); | 2312 window_pos->cy = new_window_rect.height(); |
| 2314 // WARNING! Don't set SWP_FRAMECHANGED here, it breaks moving the child | 2313 // WARNING! Don't set SWP_FRAMECHANGED here, it breaks moving the child |
| 2315 // HWNDs for some reason. | 2314 // HWNDs for some reason. |
| 2316 window_pos->flags &= ~(SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW); | 2315 window_pos->flags &= ~(SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW); |
| 2317 window_pos->flags |= SWP_NOCOPYBITS; | 2316 window_pos->flags |= SWP_NOCOPYBITS; |
| 2318 | 2317 |
| 2319 // Now ignore all immediately-following SetWindowPos() changes. Windows | 2318 // Now ignore all immediately-following SetWindowPos() changes. Windows |
| 2320 // likes to (incorrectly) recalculate what our position/size should be | 2319 // likes to (incorrectly) recalculate what our position/size should be |
| 2321 // and send us further updates. | 2320 // and send us further updates. |
| 2322 ignore_window_pos_changes_ = true; | 2321 ignore_window_pos_changes_ = true; |
| 2323 base::MessageLoop::current()->PostTask( | 2322 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 2324 FROM_HERE, | 2323 FROM_HERE, base::Bind(&HWNDMessageHandler::StopIgnoringPosChanges, |
| 2325 base::Bind(&HWNDMessageHandler::StopIgnoringPosChanges, | 2324 weak_factory_.GetWeakPtr())); |
| 2326 weak_factory_.GetWeakPtr())); | |
| 2327 } | 2325 } |
| 2328 last_monitor_ = monitor; | 2326 last_monitor_ = monitor; |
| 2329 last_monitor_rect_ = monitor_rect; | 2327 last_monitor_rect_ = monitor_rect; |
| 2330 last_work_area_ = work_area; | 2328 last_work_area_ = work_area; |
| 2331 } | 2329 } |
| 2332 } | 2330 } |
| 2333 | 2331 |
| 2334 RECT window_rect; | 2332 RECT window_rect; |
| 2335 gfx::Size old_size; | 2333 gfx::Size old_size; |
| 2336 if (GetWindowRect(hwnd(), &window_rect)) | 2334 if (GetWindowRect(hwnd(), &window_rect)) |
| (...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2738 MONITORINFO monitor_info = {sizeof(monitor_info)}; | 2736 MONITORINFO monitor_info = {sizeof(monitor_info)}; |
| 2739 GetMonitorInfo(MonitorFromWindow(hwnd(), MONITOR_DEFAULTTOPRIMARY), | 2737 GetMonitorInfo(MonitorFromWindow(hwnd(), MONITOR_DEFAULTTOPRIMARY), |
| 2740 &monitor_info); | 2738 &monitor_info); |
| 2741 gfx::Rect shrunk_rect(monitor_info.rcMonitor); | 2739 gfx::Rect shrunk_rect(monitor_info.rcMonitor); |
| 2742 shrunk_rect.set_height(shrunk_rect.height() - 1); | 2740 shrunk_rect.set_height(shrunk_rect.height() - 1); |
| 2743 background_fullscreen_hack_ = true; | 2741 background_fullscreen_hack_ = true; |
| 2744 SetBoundsInternal(shrunk_rect, false); | 2742 SetBoundsInternal(shrunk_rect, false); |
| 2745 } | 2743 } |
| 2746 | 2744 |
| 2747 } // namespace views | 2745 } // namespace views |
| OLD | NEW |