| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 <algorithm> | 5 #include <algorithm> |
| 6 | 6 |
| 7 #include "base/histogram.h" |
| 7 #include "base/logging.h" | 8 #include "base/logging.h" |
| 8 #include "base/win_util.h" | 9 #include "base/win_util.h" |
| 9 #include "chrome/browser/render_widget_host_view_win.h" | 10 #include "chrome/browser/render_widget_host_view_win.h" |
| 10 #include "chrome/common/notification_types.h" | 11 #include "chrome/common/notification_types.h" |
| 11 #include "chrome/views/accelerator.h" | 12 #include "chrome/views/accelerator.h" |
| 12 #include "chrome/views/focus_manager.h" | 13 #include "chrome/views/focus_manager.h" |
| 13 #include "chrome/views/root_view.h" | 14 #include "chrome/views/root_view.h" |
| 14 #include "chrome/views/view.h" | 15 #include "chrome/views/view.h" |
| 15 #include "chrome/views/view_storage.h" | 16 #include "chrome/views/view_storage.h" |
| 16 #include "chrome/views/widget.h" | 17 #include "chrome/views/widget.h" |
| 17 | 18 |
| 18 // The following keys are used in SetProp/GetProp to associate additional | 19 // The following keys are used in SetProp/GetProp to associate additional |
| 19 // information needed for focus tracking with a window. | 20 // information needed for focus tracking with a window. |
| 20 | 21 |
| 21 // Maps to the FocusManager instance for a top level window. See | 22 // Maps to the FocusManager instance for a top level window. See |
| 22 // CreateFocusManager/DestoryFocusManager for usage. | 23 // CreateFocusManager/DestoryFocusManager for usage. |
| 23 static const wchar_t* const kFocusManagerKey = L"__VIEW_CONTAINER__"; | 24 static const wchar_t* const kFocusManagerKey = L"__VIEW_CONTAINER__"; |
| 24 | 25 |
| 25 // Maps to the View associated with a window. | 26 // Maps to the View associated with a window. |
| 26 // We register views with window so we can: | 27 // We register views with window so we can: |
| 27 // - keep in sync the native focus with the view focus (when the native | 28 // - keep in sync the native focus with the view focus (when the native |
| 28 // component gets the focus, we get the WM_SETFOCUS event and we can focus the | 29 // component gets the focus, we get the WM_SETFOCUS event and we can focus the |
| 29 // associated view). | 30 // associated view). |
| 30 // - prevent tab key events from being sent to views. | 31 // - prevent tab key events from being sent to views. |
| 31 static const wchar_t* const kViewKey = L"__CHROME_VIEW__"; | 32 static const wchar_t* const kViewKey = L"__CHROME_VIEW__"; |
| 32 | 33 |
| 34 // A property set to 1 to indicate whether the focus manager has subclassed that |
| 35 // window. We are doing this to ensure we are not subclassing several times. |
| 36 // Subclassing twice is not a problem if no one is subclassing the HWND between |
| 37 // the 2 subclassing (the 2 subclassing is ignored since the WinProc is the same |
| 38 // as the current one). However if some other app goes and subclasses the HWND |
| 39 // between the 2 subclassing, we will end up subclassing twice. |
| 40 // This flag lets us test that whether we have or not subclassed yet. |
| 41 static const wchar_t* const kSubclassed = L"__FOCUS_SUBCLASS_INSTALLED__"; |
| 42 |
| 33 namespace views { | 43 namespace views { |
| 34 | 44 |
| 35 static bool IsCompatibleWithMouseWheelRedirection(HWND window) { | 45 static bool IsCompatibleWithMouseWheelRedirection(HWND window) { |
| 36 std::wstring class_name = win_util::GetClassName(window); | 46 std::wstring class_name = win_util::GetClassName(window); |
| 37 // Mousewheel redirection to comboboxes is a surprising and | 47 // Mousewheel redirection to comboboxes is a surprising and |
| 38 // undesireable user behavior. | 48 // undesireable user behavior. |
| 39 return !(class_name == L"ComboBox" || | 49 return !(class_name == L"ComboBox" || |
| 40 class_name == L"ComboBoxEx32"); | 50 class_name == L"ComboBoxEx32"); |
| 41 } | 51 } |
| 42 | 52 |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 // keep references to invalidated views. | 212 // keep references to invalidated views. |
| 203 NotificationService::current()->AddObserver( | 213 NotificationService::current()->AddObserver( |
| 204 focus_manager, NOTIFY_VIEW_REMOVED, NotificationService::AllSources()); | 214 focus_manager, NOTIFY_VIEW_REMOVED, NotificationService::AllSources()); |
| 205 | 215 |
| 206 return focus_manager; | 216 return focus_manager; |
| 207 } | 217 } |
| 208 | 218 |
| 209 // static | 219 // static |
| 210 void FocusManager::InstallFocusSubclass(HWND window, View* view) { | 220 void FocusManager::InstallFocusSubclass(HWND window, View* view) { |
| 211 DCHECK(window); | 221 DCHECK(window); |
| 212 win_util::Subclass(window, &FocusWindowCallback); | 222 |
| 223 bool already_subclassed = reinterpret_cast<bool>(GetProp(window, |
| 224 kSubclassed)); |
| 225 if (already_subclassed && |
| 226 !win_util::IsSubclassed(window, &FocusWindowCallback)) { |
| 227 NOTREACHED() << " FocusManager sub-classed twice"; |
| 228 // Track in UMA so we know if this case happens. |
| 229 UMA_HISTOGRAM_COUNTS(L"FocusManager.MultipleSubclass", 1); |
| 230 } else { |
| 231 bool success = win_util::Subclass(window, &FocusWindowCallback); |
| 232 DCHECK(success); |
| 233 SetProp(window, kSubclassed, reinterpret_cast<HANDLE>(true)); |
| 234 } |
| 213 if (view) | 235 if (view) |
| 214 SetProp(window, kViewKey, view); | 236 SetProp(window, kViewKey, view); |
| 215 } | 237 } |
| 216 | 238 |
| 217 void FocusManager::UninstallFocusSubclass(HWND window) { | 239 void FocusManager::UninstallFocusSubclass(HWND window) { |
| 218 DCHECK(window); | 240 DCHECK(window); |
| 219 if (win_util::Unsubclass(window, &FocusWindowCallback)) | 241 if (win_util::Unsubclass(window, &FocusWindowCallback)) { |
| 220 RemoveProp(window, kViewKey); | 242 RemoveProp(window, kViewKey); |
| 243 RemoveProp(window, kSubclassed); |
| 244 } |
| 221 } | 245 } |
| 222 | 246 |
| 223 // static | 247 // static |
| 224 FocusManager* FocusManager::GetFocusManager(HWND window) { | 248 FocusManager* FocusManager::GetFocusManager(HWND window) { |
| 225 DCHECK(window); | 249 DCHECK(window); |
| 226 FocusManager* focus_manager = | 250 FocusManager* focus_manager = |
| 227 reinterpret_cast<FocusManager*>(GetProp(window, kFocusManagerKey)); | 251 reinterpret_cast<FocusManager*>(GetProp(window, kFocusManagerKey)); |
| 228 HWND parent = GetParent(window); | 252 HWND parent = GetParent(window); |
| 229 while (!focus_manager && parent) { | 253 while (!focus_manager && parent) { |
| 230 focus_manager = | 254 focus_manager = |
| (...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 803 listener); | 827 listener); |
| 804 if (place == focus_change_listeners_.end()) { | 828 if (place == focus_change_listeners_.end()) { |
| 805 NOTREACHED() << "Removing a listener that isn't registered."; | 829 NOTREACHED() << "Removing a listener that isn't registered."; |
| 806 return; | 830 return; |
| 807 } | 831 } |
| 808 focus_change_listeners_.erase(place); | 832 focus_change_listeners_.erase(place); |
| 809 } | 833 } |
| 810 | 834 |
| 811 } // namespace views | 835 } // namespace views |
| 812 | 836 |
| OLD | NEW |