| 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 "views/focus/focus_manager.h" | 5 #include "views/focus/focus_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "build/build_config.h" | 9 #include "build/build_config.h" |
| 10 | 10 |
| 11 #if defined(OS_LINUX) | 11 #if defined(OS_LINUX) |
| 12 #include <gtk/gtk.h> | 12 #include <gtk/gtk.h> |
| 13 #endif | 13 #endif |
| 14 | 14 |
| 15 #include "base/histogram.h" |
| 15 #include "base/logging.h" | 16 #include "base/logging.h" |
| 16 #include "views/accelerator.h" | 17 #include "views/accelerator.h" |
| 17 #include "views/focus/view_storage.h" | 18 #include "views/focus/view_storage.h" |
| 18 #include "views/view.h" | 19 #include "views/view.h" |
| 19 #include "views/widget/root_view.h" | 20 #include "views/widget/root_view.h" |
| 20 #include "views/widget/widget.h" | 21 #include "views/widget/widget.h" |
| 21 | 22 |
| 22 #if defined(OS_WIN) | 23 #if defined(OS_WIN) |
| 23 #include "base/win_util.h" | 24 #include "base/win_util.h" |
| 24 #endif | 25 #endif |
| 25 | 26 |
| 27 // The following keys are used in SetProp/GetProp to associate additional |
| 28 // information needed for focus tracking with a window. |
| 29 |
| 30 // Maps to the FocusManager instance for a top level window. See |
| 31 // CreateFocusManager/DestoryFocusManager for usage. |
| 32 static const wchar_t* const kFocusManagerKey = L"__VIEW_CONTAINER__"; |
| 33 |
| 34 // Maps to the View associated with a window. |
| 35 // We register views with window so we can: |
| 36 // - keep in sync the native focus with the view focus (when the native |
| 37 // component gets the focus, we get the WM_SETFOCUS event and we can focus the |
| 38 // associated view). |
| 39 // - prevent tab key events from being sent to views. |
| 40 static const wchar_t* const kViewKey = L"__CHROME_VIEW__"; |
| 41 |
| 42 // A property set to 1 to indicate whether the focus manager has subclassed that |
| 43 // window. We are doing this to ensure we are not subclassing several times. |
| 44 // Subclassing twice is not a problem if no one is subclassing the HWND between |
| 45 // the 2 subclassings (the 2nd subclassing is ignored since the WinProc is the |
| 46 // same as the current one). However if some other app goes and subclasses the |
| 47 // HWND between the 2 subclassings, we will end up subclassing twice. |
| 48 // This flag lets us test that whether we have or not subclassed yet. |
| 49 static const wchar_t* const kFocusSubclassInstalled = |
| 50 L"__FOCUS_SUBCLASS_INSTALLED__"; |
| 51 |
| 26 namespace views { | 52 namespace views { |
| 27 | 53 |
| 54 #if defined(OS_WIN) |
| 55 // Callback installed via InstallFocusSubclass. |
| 56 static LRESULT CALLBACK FocusWindowCallback(HWND window, UINT message, |
| 57 WPARAM wParam, LPARAM lParam) { |
| 58 if (!::IsWindow(window)) { |
| 59 // QEMU has reported crashes when calling GetProp (this seems to happen for |
| 60 // some weird messages, not sure what they are). |
| 61 // Here we are just trying to avoid the crasher. |
| 62 NOTREACHED(); |
| 63 return 0; |
| 64 } |
| 65 |
| 66 WNDPROC original_handler = win_util::GetSuperclassWNDPROC(window); |
| 67 DCHECK(original_handler); |
| 68 FocusManager* focus_manager = FocusManager::GetFocusManager(window); |
| 69 // There are cases when we have no FocusManager for the window. This happens |
| 70 // because we subclass certain windows (such as the TabContents window) |
| 71 // but that window may not have an associated FocusManager. |
| 72 if (focus_manager) { |
| 73 switch (message) { |
| 74 case WM_NCDESTROY: |
| 75 if (!focus_manager->OnNCDestroy(window)) |
| 76 return 0; |
| 77 break; |
| 78 default: |
| 79 break; |
| 80 } |
| 81 } |
| 82 return CallWindowProc(original_handler, window, message, wParam, lParam); |
| 83 } |
| 84 |
| 85 #endif |
| 86 |
| 28 // FocusManager ----------------------------------------------------- | 87 // FocusManager ----------------------------------------------------- |
| 29 | 88 |
| 30 FocusManager::FocusManager(Widget* widget) | 89 #if defined(OS_WIN) |
| 31 : widget_(widget), | 90 // static |
| 32 focused_view_(NULL) { | 91 FocusManager* FocusManager::CreateFocusManager(HWND window, |
| 33 DCHECK(widget_); | 92 RootView* root_view) { |
| 93 DCHECK(window); |
| 94 DCHECK(root_view); |
| 95 InstallFocusSubclass(window, NULL); |
| 96 FocusManager* focus_manager = new FocusManager(window, root_view); |
| 97 SetProp(window, kFocusManagerKey, focus_manager); |
| 98 |
| 99 return focus_manager; |
| 100 } |
| 101 |
| 102 // static |
| 103 void FocusManager::InstallFocusSubclass(HWND window, View* view) { |
| 104 DCHECK(window); |
| 105 |
| 106 bool already_subclassed = |
| 107 reinterpret_cast<bool>(GetProp(window, |
| 108 kFocusSubclassInstalled)); |
| 109 if (already_subclassed && |
| 110 !win_util::IsSubclassed(window, &FocusWindowCallback)) { |
| 111 NOTREACHED() << "window sub-classed by someone other than the FocusManager"; |
| 112 // Track in UMA so we know if this case happens. |
| 113 UMA_HISTOGRAM_COUNTS("FocusManager.MultipleSubclass", 1); |
| 114 } else { |
| 115 win_util::Subclass(window, &FocusWindowCallback); |
| 116 SetProp(window, kFocusSubclassInstalled, reinterpret_cast<HANDLE>(true)); |
| 117 } |
| 118 if (view) |
| 119 SetProp(window, kViewKey, view); |
| 120 } |
| 121 |
| 122 void FocusManager::UninstallFocusSubclass(HWND window) { |
| 123 DCHECK(window); |
| 124 if (win_util::Unsubclass(window, &FocusWindowCallback)) { |
| 125 RemoveProp(window, kViewKey); |
| 126 RemoveProp(window, kFocusSubclassInstalled); |
| 127 } |
| 128 } |
| 129 |
| 130 #endif |
| 131 |
| 132 // static |
| 133 FocusManager* FocusManager::GetFocusManager(gfx::NativeView window) { |
| 134 #if defined(OS_WIN) |
| 135 DCHECK(window); |
| 136 |
| 137 // In case parent windows belong to a different process, yet |
| 138 // have the kFocusManagerKey property set, we have to be careful |
| 139 // to also check the process id of the window we're checking. |
| 140 DWORD window_pid = 0, current_pid = GetCurrentProcessId(); |
| 141 FocusManager* focus_manager; |
| 142 for (focus_manager = NULL; focus_manager == NULL && IsWindow(window); |
| 143 window = GetParent(window)) { |
| 144 GetWindowThreadProcessId(window, &window_pid); |
| 145 if (current_pid != window_pid) |
| 146 break; |
| 147 focus_manager = reinterpret_cast<FocusManager*>( |
| 148 GetProp(window, kFocusManagerKey)); |
| 149 } |
| 150 return focus_manager; |
| 151 #else |
| 152 NOTIMPLEMENTED(); |
| 153 return NULL; |
| 154 #endif |
| 155 } |
| 156 |
| 157 #if defined(OS_WIN) |
| 158 // static |
| 159 View* FocusManager::GetViewForWindow(gfx::NativeView window, bool look_in_parent
s) { |
| 160 DCHECK(window); |
| 161 do { |
| 162 View* v = reinterpret_cast<View*>(GetProp(window, kViewKey)); |
| 163 if (v) |
| 164 return v; |
| 165 } while (look_in_parents && (window = ::GetParent(window))); |
| 166 return NULL; |
| 167 } |
| 168 |
| 169 FocusManager::FocusManager(HWND root, RootView* root_view) |
| 170 : root_(root), |
| 171 top_root_view_(root_view), |
| 172 focused_view_(NULL), |
| 173 ignore_set_focus_msg_(false) { |
| 34 stored_focused_view_storage_id_ = | 174 stored_focused_view_storage_id_ = |
| 35 ViewStorage::GetSharedInstance()->CreateStorageID(); | 175 ViewStorage::GetSharedInstance()->CreateStorageID(); |
| 176 DCHECK(root_); |
| 36 } | 177 } |
| 178 #endif |
| 37 | 179 |
| 38 FocusManager::~FocusManager() { | 180 FocusManager::~FocusManager() { |
| 39 // If there are still registered FocusChange listeners, chances are they were | 181 // If there are still registered FocusChange listeners, chances are they were |
| 40 // leaked so warn about them. | 182 // leaked so warn about them. |
| 41 DCHECK(focus_change_listeners_.empty()); | 183 DCHECK(focus_change_listeners_.empty()); |
| 42 } | 184 } |
| 43 | 185 |
| 44 #if defined(OS_WIN) | 186 #if defined(OS_WIN) |
| 45 // Message handlers. | 187 // Message handlers. |
| 188 bool FocusManager::OnNCDestroy(HWND window) { |
| 189 // Window is being destroyed, undo the subclassing. |
| 190 FocusManager::UninstallFocusSubclass(window); |
| 191 |
| 192 if (window == root_) { |
| 193 // We are the top window. |
| 194 |
| 195 DCHECK(GetProp(window, kFocusManagerKey)); |
| 196 |
| 197 // Make sure this is called on the window that was set with the |
| 198 // FocusManager. |
| 199 RemoveProp(window, kFocusManagerKey); |
| 200 |
| 201 delete this; |
| 202 } |
| 203 return true; |
| 204 } |
| 205 |
| 46 bool FocusManager::OnKeyDown(HWND window, UINT message, WPARAM wparam, | 206 bool FocusManager::OnKeyDown(HWND window, UINT message, WPARAM wparam, |
| 47 LPARAM lparam) { | 207 LPARAM lparam) { |
| 48 DCHECK((message == WM_KEYDOWN) || (message == WM_SYSKEYDOWN)); | 208 DCHECK((message == WM_KEYDOWN) || (message == WM_SYSKEYDOWN)); |
| 49 HWND hwnd = widget_->GetNativeView(); | |
| 50 | 209 |
| 51 if (!IsWindowVisible(hwnd)) { | 210 if (!IsWindowVisible(root_)) { |
| 52 // We got a message for a hidden window. Because WidgetWin::Close hides the | 211 // We got a message for a hidden window. Because WidgetWin::Close hides the |
| 53 // window, then destroys it, it it possible to get a message after we've | 212 // window, then destroys it, it it possible to get a message after we've |
| 54 // hidden the window. If we allow the message to be dispatched chances are | 213 // hidden the window. If we allow the message to be dispatched chances are |
| 55 // we'll crash in some weird place. By returning false we make sure the | 214 // we'll crash in some weird place. By returning false we make sure the |
| 56 // message isn't dispatched. | 215 // message isn't dispatched. |
| 57 return false; | 216 return false; |
| 58 } | 217 } |
| 59 | 218 |
| 60 // First give the registered keystroke handlers a chance a processing | 219 // First give the registered keystroke handlers a chance a processing |
| 61 // the message | 220 // the message |
| (...skipping 17 matching lines...) Expand all Loading... |
| 79 virtual_key_code, repeat_count, flags); | 238 virtual_key_code, repeat_count, flags); |
| 80 | 239 |
| 81 // If the focused view wants to process the key event as is, let it be. | 240 // If the focused view wants to process the key event as is, let it be. |
| 82 if (focused_view_ && focused_view_->SkipDefaultKeyEventProcessing(key_event)) | 241 if (focused_view_ && focused_view_->SkipDefaultKeyEventProcessing(key_event)) |
| 83 return true; | 242 return true; |
| 84 | 243 |
| 85 // Intercept Tab related messages for focus traversal. | 244 // Intercept Tab related messages for focus traversal. |
| 86 // Note that we don't do focus traversal if the root window is not part of the | 245 // Note that we don't do focus traversal if the root window is not part of the |
| 87 // active window hierarchy as this would mean we have no focused view and | 246 // active window hierarchy as this would mean we have no focused view and |
| 88 // would focus the first focusable view. | 247 // would focus the first focusable view. |
| 89 HWND top_window = widget_->GetNativeView(); | |
| 90 HWND active_window = ::GetActiveWindow(); | 248 HWND active_window = ::GetActiveWindow(); |
| 91 if ((active_window == top_window || ::IsChild(active_window, top_window)) && | 249 if ((active_window == root_ || ::IsChild(active_window, root_)) && |
| 92 IsTabTraversalKeyEvent(key_event)) { | 250 IsTabTraversalKeyEvent(key_event)) { |
| 93 AdvanceFocus(win_util::IsShiftPressed()); | 251 AdvanceFocus(win_util::IsShiftPressed()); |
| 94 return false; | 252 return false; |
| 95 } | 253 } |
| 96 | 254 |
| 97 // Intercept arrow key messages to switch between grouped views. | 255 // Intercept arrow key messages to switch between grouped views. |
| 98 if (focused_view_ && focused_view_->GetGroup() != -1 && | 256 if (focused_view_ && focused_view_->GetGroup() != -1 && |
| 99 (virtual_key_code == VK_UP || virtual_key_code == VK_DOWN || | 257 (virtual_key_code == VK_UP || virtual_key_code == VK_DOWN || |
| 100 virtual_key_code == VK_LEFT || virtual_key_code == VK_RIGHT)) { | 258 virtual_key_code == VK_LEFT || virtual_key_code == VK_RIGHT)) { |
| 101 bool next = (virtual_key_code == VK_RIGHT || virtual_key_code == VK_DOWN); | 259 bool next = (virtual_key_code == VK_RIGHT || virtual_key_code == VK_DOWN); |
| 102 std::vector<View*> views; | 260 std::vector<View*> views; |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 159 bool FocusManager::ContainsView(View* view) { | 317 bool FocusManager::ContainsView(View* view) { |
| 160 DCHECK(view); | 318 DCHECK(view); |
| 161 RootView* root_view = view->GetRootView(); | 319 RootView* root_view = view->GetRootView(); |
| 162 if (!root_view) | 320 if (!root_view) |
| 163 return false; | 321 return false; |
| 164 | 322 |
| 165 Widget* widget = root_view->GetWidget(); | 323 Widget* widget = root_view->GetWidget(); |
| 166 if (!widget) | 324 if (!widget) |
| 167 return false; | 325 return false; |
| 168 | 326 |
| 169 gfx::NativeView top_window = widget_->GetNativeView(); | |
| 170 gfx::NativeView window = widget->GetNativeView(); | 327 gfx::NativeView window = widget->GetNativeView(); |
| 171 while (window) { | 328 while (window) { |
| 172 if (window == top_window) | 329 if (window == root_) |
| 173 return true; | 330 return true; |
| 174 #if defined(OS_WIN) | 331 #if defined(OS_WIN) |
| 175 window = ::GetParent(window); | 332 window = ::GetParent(window); |
| 176 #else | 333 #else |
| 177 window = gtk_widget_get_parent(window); | 334 window = gtk_widget_get_parent(window); |
| 178 #endif | 335 #endif |
| 179 } | 336 } |
| 180 return false; | 337 return false; |
| 181 } | 338 } |
| 182 | 339 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 213 focus_traversable = original_starting_view->GetRootView(); | 370 focus_traversable = original_starting_view->GetRootView(); |
| 214 starting_view = original_starting_view; | 371 starting_view = original_starting_view; |
| 215 } | 372 } |
| 216 } else { | 373 } else { |
| 217 // When you are going back, starting view's FocusTraversable should not be | 374 // When you are going back, starting view's FocusTraversable should not be |
| 218 // used. | 375 // used. |
| 219 focus_traversable = original_starting_view->GetRootView(); | 376 focus_traversable = original_starting_view->GetRootView(); |
| 220 starting_view = original_starting_view; | 377 starting_view = original_starting_view; |
| 221 } | 378 } |
| 222 } else { | 379 } else { |
| 223 focus_traversable = widget_->GetRootView(); | 380 focus_traversable = top_root_view_; |
| 224 } | 381 } |
| 225 | 382 |
| 226 // Traverse the FocusTraversable tree down to find the focusable view. | 383 // Traverse the FocusTraversable tree down to find the focusable view. |
| 227 View* v = FindFocusableView(focus_traversable, starting_view, reverse); | 384 View* v = FindFocusableView(focus_traversable, starting_view, reverse); |
| 228 if (v) { | 385 if (v) { |
| 229 return v; | 386 return v; |
| 230 } else { | 387 } else { |
| 231 // Let's go up in the FocusTraversable tree. | 388 // Let's go up in the FocusTraversable tree. |
| 232 FocusTraversable* parent_focus_traversable = | 389 FocusTraversable* parent_focus_traversable = |
| 233 focus_traversable->GetFocusTraversableParent(); | 390 focus_traversable->GetFocusTraversableParent(); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 293 if (view) { | 450 if (view) { |
| 294 view->SchedulePaint(); | 451 view->SchedulePaint(); |
| 295 view->Focus(); | 452 view->Focus(); |
| 296 view->DidGainFocus(); | 453 view->DidGainFocus(); |
| 297 } | 454 } |
| 298 } | 455 } |
| 299 } | 456 } |
| 300 | 457 |
| 301 void FocusManager::ClearFocus() { | 458 void FocusManager::ClearFocus() { |
| 302 SetFocusedView(NULL); | 459 SetFocusedView(NULL); |
| 303 ClearNativeFocus(); | 460 ClearHWNDFocus(); |
| 304 } | 461 } |
| 305 | 462 |
| 463 void FocusManager::ClearHWNDFocus() { |
| 464 // Keep the top root window focused so we get keyboard events. |
| 465 ignore_set_focus_msg_ = true; |
| 466 #if defined(OS_WIN) |
| 467 ::SetFocus(root_); |
| 468 #else |
| 469 NOTIMPLEMENTED(); |
| 470 #endif |
| 471 ignore_set_focus_msg_ = false; |
| 472 } |
| 473 |
| 474 #if defined(OS_WIN) |
| 475 void FocusManager::FocusHWND(HWND hwnd) { |
| 476 ignore_set_focus_msg_ = true; |
| 477 // Only reset focus if hwnd is not already focused. |
| 478 if (hwnd && ::GetFocus() != hwnd) |
| 479 ::SetFocus(hwnd); |
| 480 ignore_set_focus_msg_ = false; |
| 481 } |
| 482 #endif |
| 483 |
| 306 void FocusManager::StoreFocusedView() { | 484 void FocusManager::StoreFocusedView() { |
| 307 ViewStorage* view_storage = ViewStorage::GetSharedInstance(); | 485 ViewStorage* view_storage = ViewStorage::GetSharedInstance(); |
| 308 if (!view_storage) { | 486 if (!view_storage) { |
| 309 // This should never happen but bug 981648 seems to indicate it could. | 487 // This should never happen but bug 981648 seems to indicate it could. |
| 310 NOTREACHED(); | 488 NOTREACHED(); |
| 311 return; | 489 return; |
| 312 } | 490 } |
| 313 | 491 |
| 314 // TODO (jcampan): when a TabContents containing a popup is closed, the focus | 492 // TODO (jcampan): when a TabContents containing a popup is closed, the focus |
| 315 // is stored twice causing an assert. We should find a better alternative than | 493 // is stored twice causing an assert. We should find a better alternative than |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 350 void FocusManager::ClearStoredFocusedView() { | 528 void FocusManager::ClearStoredFocusedView() { |
| 351 ViewStorage* view_storage = ViewStorage::GetSharedInstance(); | 529 ViewStorage* view_storage = ViewStorage::GetSharedInstance(); |
| 352 if (!view_storage) { | 530 if (!view_storage) { |
| 353 // This should never happen but bug 981648 seems to indicate it could. | 531 // This should never happen but bug 981648 seems to indicate it could. |
| 354 NOTREACHED(); | 532 NOTREACHED(); |
| 355 return; | 533 return; |
| 356 } | 534 } |
| 357 view_storage->RemoveView(stored_focused_view_storage_id_); | 535 view_storage->RemoveView(stored_focused_view_storage_id_); |
| 358 } | 536 } |
| 359 | 537 |
| 538 FocusManager* FocusManager::GetParentFocusManager() const { |
| 539 #if defined(OS_WIN) |
| 540 HWND parent = ::GetParent(root_); |
| 541 #else |
| 542 GtkWidget* parent = gtk_widget_get_parent(root_); |
| 543 #endif |
| 544 // If we are a top window, we don't have a parent FocusManager. |
| 545 if (!parent) |
| 546 return NULL; |
| 547 |
| 548 return GetFocusManager(parent); |
| 549 } |
| 550 |
| 360 // Find the next (previous if reverse is true) focusable view for the specified | 551 // Find the next (previous if reverse is true) focusable view for the specified |
| 361 // FocusTraversable, starting at the specified view, traversing down the | 552 // FocusTraversable, starting at the specified view, traversing down the |
| 362 // FocusTraversable hierarchy. | 553 // FocusTraversable hierarchy. |
| 363 View* FocusManager::FindFocusableView(FocusTraversable* focus_traversable, | 554 View* FocusManager::FindFocusableView(FocusTraversable* focus_traversable, |
| 364 View* starting_view, | 555 View* starting_view, |
| 365 bool reverse) { | 556 bool reverse) { |
| 366 FocusTraversable* new_focus_traversable = NULL; | 557 FocusTraversable* new_focus_traversable = NULL; |
| 367 View* new_starting_view = NULL; | 558 View* new_starting_view = NULL; |
| 368 View* v = focus_traversable->FindNextFocusableView(starting_view, | 559 View* v = focus_traversable->FindNextFocusableView(starting_view, |
| 369 reverse, | 560 reverse, |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 431 // We have to copy the target list here, because an AcceleratorPressed | 622 // We have to copy the target list here, because an AcceleratorPressed |
| 432 // event handler may modify the list. | 623 // event handler may modify the list. |
| 433 AcceleratorTargetList targets(map_iter->second); | 624 AcceleratorTargetList targets(map_iter->second); |
| 434 for (AcceleratorTargetList::iterator iter = targets.begin(); | 625 for (AcceleratorTargetList::iterator iter = targets.begin(); |
| 435 iter != targets.end(); ++iter) { | 626 iter != targets.end(); ++iter) { |
| 436 if ((*iter)->AcceleratorPressed(accelerator)) | 627 if ((*iter)->AcceleratorPressed(accelerator)) |
| 437 return true; | 628 return true; |
| 438 } | 629 } |
| 439 } | 630 } |
| 440 | 631 |
| 632 // When dealing with child windows that have their own FocusManager (such |
| 633 // as ConstrainedWindow), we still want the parent FocusManager to process |
| 634 // the accelerator if the child window did not process it. |
| 635 FocusManager* parent_focus_manager = GetParentFocusManager(); |
| 636 if (parent_focus_manager) |
| 637 return parent_focus_manager->ProcessAccelerator(accelerator); |
| 638 |
| 441 return false; | 639 return false; |
| 442 } | 640 } |
| 443 | 641 |
| 444 AcceleratorTarget* FocusManager::GetCurrentTargetForAccelerator( | 642 AcceleratorTarget* FocusManager::GetCurrentTargetForAccelerator( |
| 445 const views::Accelerator& accelerator) const { | 643 const views::Accelerator& accelerator) const { |
| 446 AcceleratorMap::const_iterator map_iter = accelerators_.find(accelerator); | 644 AcceleratorMap::const_iterator map_iter = accelerators_.find(accelerator); |
| 447 if (map_iter == accelerators_.end() || map_iter->second.empty()) | 645 if (map_iter == accelerators_.end() || map_iter->second.empty()) |
| 448 return NULL; | 646 return NULL; |
| 449 return map_iter->second.front(); | 647 return map_iter->second.front(); |
| 450 } | 648 } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 494 std::find(focus_change_listeners_.begin(), focus_change_listeners_.end(), | 692 std::find(focus_change_listeners_.begin(), focus_change_listeners_.end(), |
| 495 listener); | 693 listener); |
| 496 if (place == focus_change_listeners_.end()) { | 694 if (place == focus_change_listeners_.end()) { |
| 497 NOTREACHED() << "Removing a listener that isn't registered."; | 695 NOTREACHED() << "Removing a listener that isn't registered."; |
| 498 return; | 696 return; |
| 499 } | 697 } |
| 500 focus_change_listeners_.erase(place); | 698 focus_change_listeners_.erase(place); |
| 501 } | 699 } |
| 502 | 700 |
| 503 } // namespace views | 701 } // namespace views |
| OLD | NEW |