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

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

Issue 159046: Implementing accelerators for Linux toolkit_views (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 4 months 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 | « views/focus/focus_manager.h ('k') | views/focus/focus_manager_unittest.cc » ('j') | 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 "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
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
OLDNEW
« no previous file with comments | « views/focus/focus_manager.h ('k') | views/focus/focus_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698