Index: chrome/views/focus_manager.cc |
=================================================================== |
--- chrome/views/focus_manager.cc (revision 5976) |
+++ chrome/views/focus_manager.cc (working copy) |
@@ -4,6 +4,7 @@ |
#include <algorithm> |
+#include "base/histogram.h" |
#include "base/logging.h" |
#include "base/win_util.h" |
#include "chrome/browser/render_widget_host_view_win.h" |
@@ -30,6 +31,15 @@ |
// - prevent tab key events from being sent to views. |
static const wchar_t* const kViewKey = L"__CHROME_VIEW__"; |
+// A property set to 1 to indicate whether the focus manager has subclassed that |
+// window. We are doing this to ensure we are not subclassing several times. |
+// Subclassing twice is not a problem if no one is subclassing the HWND between |
+// the 2 subclassing (the 2 subclassing is ignored since the WinProc is the same |
+// as the current one). However if some other app goes and subclasses the HWND |
+// between the 2 subclassing, we will end up subclassing twice. |
+// This flag lets us test that whether we have or not subclassed yet. |
+static const wchar_t* const kSubclassed = L"__FOCUS_SUBCLASS_INSTALLED__"; |
+ |
namespace views { |
static bool IsCompatibleWithMouseWheelRedirection(HWND window) { |
@@ -209,15 +219,29 @@ |
// static |
void FocusManager::InstallFocusSubclass(HWND window, View* view) { |
DCHECK(window); |
- win_util::Subclass(window, &FocusWindowCallback); |
+ |
+ bool already_subclassed = reinterpret_cast<bool>(GetProp(window, |
+ kSubclassed)); |
+ if (already_subclassed && |
+ !win_util::IsSubclassed(window, &FocusWindowCallback)) { |
+ NOTREACHED() << " FocusManager sub-classed twice"; |
+ // Track in UMA so we know if this case happens. |
+ UMA_HISTOGRAM_COUNTS(L"FocusManager.MultipleSubclass", 1); |
+ } else { |
+ bool success = win_util::Subclass(window, &FocusWindowCallback); |
+ DCHECK(success); |
+ SetProp(window, kSubclassed, reinterpret_cast<HANDLE>(true)); |
+ } |
if (view) |
SetProp(window, kViewKey, view); |
} |
void FocusManager::UninstallFocusSubclass(HWND window) { |
DCHECK(window); |
- if (win_util::Unsubclass(window, &FocusWindowCallback)) |
+ if (win_util::Unsubclass(window, &FocusWindowCallback)) { |
RemoveProp(window, kViewKey); |
+ RemoveProp(window, kSubclassed); |
+ } |
} |
// static |