| 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/keyboard_codes.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 #include "base/win_util.h" | |
| 24 #endif | |
| 25 | |
| 26 namespace views { | 23 namespace views { |
| 27 | 24 |
| 28 // FocusManager ----------------------------------------------------- | 25 // FocusManager ----------------------------------------------------- |
| 29 | 26 |
| 30 FocusManager::FocusManager(Widget* widget) | 27 FocusManager::FocusManager(Widget* widget) |
| 31 : widget_(widget), | 28 : widget_(widget), |
| 32 focused_view_(NULL) { | 29 focused_view_(NULL) { |
| 33 DCHECK(widget_); | 30 DCHECK(widget_); |
| 34 stored_focused_view_storage_id_ = | 31 stored_focused_view_storage_id_ = |
| 35 ViewStorage::GetSharedInstance()->CreateStorageID(); | 32 ViewStorage::GetSharedInstance()->CreateStorageID(); |
| 36 } | 33 } |
| 37 | 34 |
| 38 FocusManager::~FocusManager() { | 35 FocusManager::~FocusManager() { |
| 39 // If there are still registered FocusChange listeners, chances are they were | 36 // If there are still registered FocusChange listeners, chances are they were |
| 40 // leaked so warn about them. | 37 // leaked so warn about them. |
| 41 DCHECK(focus_change_listeners_.empty()); | 38 DCHECK(focus_change_listeners_.empty()); |
| 42 } | 39 } |
| 43 | 40 |
| 44 #if defined(OS_WIN) | 41 bool FocusManager::OnKeyEvent(const KeyEvent& event) { |
| 45 // Message handlers. | |
| 46 bool FocusManager::OnKeyDown(HWND window, UINT message, WPARAM wparam, | |
| 47 LPARAM lparam) { | |
| 48 DCHECK((message == WM_KEYDOWN) || (message == WM_SYSKEYDOWN)); | |
| 49 HWND hwnd = widget_->GetNativeView(); | |
| 50 | |
| 51 if (!IsWindowVisible(hwnd)) { | |
| 52 // 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 | |
| 54 // 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 | |
| 56 // message isn't dispatched. | |
| 57 return false; | |
| 58 } | |
| 59 | |
| 60 int virtual_key_code = static_cast<int>(wparam); | |
| 61 int repeat_count = LOWORD(lparam); | |
| 62 int flags = HIWORD(lparam); | |
| 63 KeyEvent key_event(Event::ET_KEY_PRESSED, | |
| 64 virtual_key_code, repeat_count, flags); | |
| 65 | |
| 66 // If the focused view wants to process the key event as is, let it be. | 42 // If the focused view wants to process the key event as is, let it be. |
| 67 if (focused_view_ && focused_view_->SkipDefaultKeyEventProcessing(key_event)) | 43 if (focused_view_ && focused_view_->SkipDefaultKeyEventProcessing(event)) |
| 68 return true; | 44 return true; |
| 69 | 45 |
| 70 // Intercept Tab related messages for focus traversal. | 46 // Intercept Tab related messages for focus traversal. |
| 71 // Note that we don't do focus traversal if the root window is not part of the | 47 // Note that we don't do focus traversal if the root window is not part of the |
| 72 // active window hierarchy as this would mean we have no focused view and | 48 // active window hierarchy as this would mean we have no focused view and |
| 73 // would focus the first focusable view. | 49 // would focus the first focusable view. |
| 50 #if defined(OS_WIN) |
| 74 HWND top_window = widget_->GetNativeView(); | 51 HWND top_window = widget_->GetNativeView(); |
| 75 HWND active_window = ::GetActiveWindow(); | 52 HWND active_window = ::GetActiveWindow(); |
| 76 if ((active_window == top_window || ::IsChild(active_window, top_window)) && | 53 if ((active_window == top_window || ::IsChild(active_window, top_window)) && |
| 77 IsTabTraversalKeyEvent(key_event)) { | 54 IsTabTraversalKeyEvent(event)) { |
| 78 AdvanceFocus(win_util::IsShiftPressed()); | 55 AdvanceFocus(event.IsShiftDown()); |
| 79 return false; | 56 return false; |
| 80 } | 57 } |
| 58 #else |
| 59 if (IsTabTraversalKeyEvent(event)) { |
| 60 AdvanceFocus(event.IsShiftDown()); |
| 61 return false; |
| 62 } |
| 63 #endif |
| 81 | 64 |
| 82 // Intercept arrow key messages to switch between grouped views. | 65 // Intercept arrow key messages to switch between grouped views. |
| 66 int key_code = event.GetCharacter(); |
| 83 if (focused_view_ && focused_view_->GetGroup() != -1 && | 67 if (focused_view_ && focused_view_->GetGroup() != -1 && |
| 84 (virtual_key_code == VK_UP || virtual_key_code == VK_DOWN || | 68 (key_code == base::VKEY_UP || key_code == base::VKEY_DOWN || |
| 85 virtual_key_code == VK_LEFT || virtual_key_code == VK_RIGHT)) { | 69 key_code == base::VKEY_LEFT || key_code == base::VKEY_RIGHT)) { |
| 86 bool next = (virtual_key_code == VK_RIGHT || virtual_key_code == VK_DOWN); | 70 bool next = (key_code == base::VKEY_RIGHT || key_code == base::VKEY_DOWN); |
| 87 std::vector<View*> views; | 71 std::vector<View*> views; |
| 88 focused_view_->GetParent()->GetViewsWithGroup(focused_view_->GetGroup(), | 72 focused_view_->GetParent()->GetViewsWithGroup(focused_view_->GetGroup(), |
| 89 &views); | 73 &views); |
| 90 std::vector<View*>::const_iterator iter = std::find(views.begin(), | 74 std::vector<View*>::const_iterator iter = std::find(views.begin(), |
| 91 views.end(), | 75 views.end(), |
| 92 focused_view_); | 76 focused_view_); |
| 93 DCHECK(iter != views.end()); | 77 DCHECK(iter != views.end()); |
| 94 int index = static_cast<int>(iter - views.begin()); | 78 int index = static_cast<int>(iter - views.begin()); |
| 95 index += next ? 1 : -1; | 79 index += next ? 1 : -1; |
| 96 if (index < 0) { | 80 if (index < 0) { |
| 97 index = static_cast<int>(views.size()) - 1; | 81 index = static_cast<int>(views.size()) - 1; |
| 98 } else if (index >= static_cast<int>(views.size())) { | 82 } else if (index >= static_cast<int>(views.size())) { |
| 99 index = 0; | 83 index = 0; |
| 100 } | 84 } |
| 101 views[index]->RequestFocus(); | 85 views[index]->RequestFocus(); |
| 102 return false; | 86 return false; |
| 103 } | 87 } |
| 104 | 88 |
| 105 // Process keyboard accelerators. | 89 // Process keyboard accelerators. |
| 106 // We process accelerators here as we have no way of knowing if a HWND has | 90 // If the key combination matches an accelerator, the accelerator is |
| 107 // really processed a key event. If the key combination matches an | 91 // triggered, otherwise the key event is proceed as usual. |
| 108 // accelerator, the accelerator is triggered, otherwise we forward the | 92 Accelerator accelerator(event.GetCharacter(), |
| 109 // event to the HWND. | 93 event.IsShiftDown(), |
| 110 Accelerator accelerator(Accelerator(static_cast<int>(virtual_key_code), | 94 event.IsControlDown(), |
| 111 win_util::IsShiftPressed(), | 95 event.IsAltDown()); |
| 112 win_util::IsCtrlPressed(), | |
| 113 win_util::IsAltPressed())); | |
| 114 if (ProcessAccelerator(accelerator)) { | 96 if (ProcessAccelerator(accelerator)) { |
| 115 // If a shortcut was activated for this keydown message, do not propagate | 97 // If a shortcut was activated for this keydown message, do not propagate |
| 116 // the message further. | 98 // the event further. |
| 117 return false; | 99 return false; |
| 118 } | 100 } |
| 119 return true; | 101 return true; |
| 120 } | 102 } |
| 121 #endif | |
| 122 | 103 |
| 123 void FocusManager::ValidateFocusedView() { | 104 void FocusManager::ValidateFocusedView() { |
| 124 if (focused_view_) { | 105 if (focused_view_) { |
| 125 if (!ContainsView(focused_view_)) | 106 if (!ContainsView(focused_view_)) |
| 126 ClearFocus(); | 107 ClearFocus(); |
| 127 } | 108 } |
| 128 } | 109 } |
| 129 | 110 |
| 130 // Tests whether a view is valid, whether it still belongs to the window | 111 // Tests whether a view is valid, whether it still belongs to the window |
| 131 // hierarchy of the FocusManager. | 112 // hierarchy of the FocusManager. |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 403 if (map_iter != accelerators_.end()) { | 384 if (map_iter != accelerators_.end()) { |
| 404 // We have to copy the target list here, because an AcceleratorPressed | 385 // We have to copy the target list here, because an AcceleratorPressed |
| 405 // event handler may modify the list. | 386 // event handler may modify the list. |
| 406 AcceleratorTargetList targets(map_iter->second); | 387 AcceleratorTargetList targets(map_iter->second); |
| 407 for (AcceleratorTargetList::iterator iter = targets.begin(); | 388 for (AcceleratorTargetList::iterator iter = targets.begin(); |
| 408 iter != targets.end(); ++iter) { | 389 iter != targets.end(); ++iter) { |
| 409 if ((*iter)->AcceleratorPressed(accelerator)) | 390 if ((*iter)->AcceleratorPressed(accelerator)) |
| 410 return true; | 391 return true; |
| 411 } | 392 } |
| 412 } | 393 } |
| 413 | |
| 414 return false; | 394 return false; |
| 415 } | 395 } |
| 416 | 396 |
| 417 AcceleratorTarget* FocusManager::GetCurrentTargetForAccelerator( | 397 AcceleratorTarget* FocusManager::GetCurrentTargetForAccelerator( |
| 418 const views::Accelerator& accelerator) const { | 398 const views::Accelerator& accelerator) const { |
| 419 AcceleratorMap::const_iterator map_iter = accelerators_.find(accelerator); | 399 AcceleratorMap::const_iterator map_iter = accelerators_.find(accelerator); |
| 420 if (map_iter == accelerators_.end() || map_iter->second.empty()) | 400 if (map_iter == accelerators_.end() || map_iter->second.empty()) |
| 421 return NULL; | 401 return NULL; |
| 422 return map_iter->second.front(); | 402 return map_iter->second.front(); |
| 423 } | 403 } |
| 424 | 404 |
| 425 // static | 405 // static |
| 426 bool FocusManager::IsTabTraversalKeyEvent(const KeyEvent& key_event) { | 406 bool FocusManager::IsTabTraversalKeyEvent(const KeyEvent& key_event) { |
| 427 #if defined(OS_WIN) | 407 return key_event.GetCharacter() == base::VKEY_TAB && |
| 428 return key_event.GetCharacter() == VK_TAB && !win_util::IsCtrlPressed(); | 408 !key_event.IsControlDown(); |
| 429 #else | |
| 430 NOTIMPLEMENTED(); | |
| 431 return false; | |
| 432 #endif | |
| 433 } | 409 } |
| 434 | 410 |
| 435 void FocusManager::ViewRemoved(View* parent, View* removed) { | 411 void FocusManager::ViewRemoved(View* parent, View* removed) { |
| 436 if (focused_view_ && focused_view_ == removed) | 412 if (focused_view_ && focused_view_ == removed) |
| 437 ClearFocus(); | 413 ClearFocus(); |
| 438 } | 414 } |
| 439 | 415 |
| 440 void FocusManager::AddFocusChangeListener(FocusChangeListener* listener) { | 416 void FocusManager::AddFocusChangeListener(FocusChangeListener* listener) { |
| 441 DCHECK(std::find(focus_change_listeners_.begin(), | 417 DCHECK(std::find(focus_change_listeners_.begin(), |
| 442 focus_change_listeners_.end(), listener) == | 418 focus_change_listeners_.end(), listener) == |
| 443 focus_change_listeners_.end()) << "Adding a listener twice."; | 419 focus_change_listeners_.end()) << "Adding a listener twice."; |
| 444 focus_change_listeners_.push_back(listener); | 420 focus_change_listeners_.push_back(listener); |
| 445 } | 421 } |
| 446 | 422 |
| 447 void FocusManager::RemoveFocusChangeListener(FocusChangeListener* listener) { | 423 void FocusManager::RemoveFocusChangeListener(FocusChangeListener* listener) { |
| 448 FocusChangeListenerList::iterator place = | 424 FocusChangeListenerList::iterator place = |
| 449 std::find(focus_change_listeners_.begin(), focus_change_listeners_.end(), | 425 std::find(focus_change_listeners_.begin(), focus_change_listeners_.end(), |
| 450 listener); | 426 listener); |
| 451 if (place == focus_change_listeners_.end()) { | 427 if (place == focus_change_listeners_.end()) { |
| 452 NOTREACHED() << "Removing a listener that isn't registered."; | 428 NOTREACHED() << "Removing a listener that isn't registered."; |
| 453 return; | 429 return; |
| 454 } | 430 } |
| 455 focus_change_listeners_.erase(place); | 431 focus_change_listeners_.erase(place); |
| 456 } | 432 } |
| 457 | 433 |
| 458 } // namespace views | 434 } // namespace views |
| OLD | NEW |