Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(105)

Side by Side Diff: chrome/views/focus_manager.cc

Issue 12434: Focus manager subclassing check (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 12 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/win_util.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « base/win_util.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698