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

Side by Side Diff: ui/base/accelerators/accelerator_manager.cc

Issue 9402018: Experimental Extension Keybinding (first cut). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 10 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "ui/base/accelerators/accelerator_manager.h" 5 #include "ui/base/accelerators/accelerator_manager.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 10
11 namespace ui { 11 namespace ui {
12 12
13 AcceleratorManager::AcceleratorManager() : last_event_type_(ET_KEY_PRESSED) { 13 AcceleratorManager::AcceleratorManager() : last_event_type_(ET_KEY_PRESSED) {
14 } 14 }
15 15
16 AcceleratorManager::~AcceleratorManager() { 16 AcceleratorManager::~AcceleratorManager() {
17 } 17 }
18 18
19 void AcceleratorManager::Register(const Accelerator& accelerator, 19 void AcceleratorManager::Register(const Accelerator& accelerator,
20 bool priority,
20 AcceleratorTarget* target) { 21 AcceleratorTarget* target) {
21 AcceleratorTargetList& targets = accelerators_[accelerator]; 22 AcceleratorTargetList& targets = accelerators_[accelerator].second;
22 DCHECK(std::find(targets.begin(), targets.end(), target) == targets.end()) 23 DCHECK(std::find(targets.begin(), targets.end(), target) == targets.end())
23 << "Registering the same target multiple times"; 24 << "Registering the same target multiple times";
24 targets.push_front(target); 25
26 // All priority accelerators go to the front of the line.
27 if (priority) {
28 DCHECK(!accelerators_[accelerator].first)
29 << "Only one _priority_ handler can be registered";
30 targets.push_front(target);
31 // Mark that we have a priority accelerator at the front.
32 accelerators_[accelerator].first = true;
33 return;
34 }
35
36 // We are registering a normal priority handler. If no priority accelerator
37 // handler has been registered before us, just add the new handler to the
38 // front. Otherwise, register it after the first (only) priority handler.
39 if (!accelerators_[accelerator].first)
40 targets.push_front(target);
41 else
42 targets.insert(++targets.begin(), target);
25 } 43 }
26 44
27 void AcceleratorManager::Unregister(const Accelerator& accelerator, 45 void AcceleratorManager::Unregister(const Accelerator& accelerator,
28 AcceleratorTarget* target) { 46 AcceleratorTarget* target) {
29 AcceleratorMap::iterator map_iter = accelerators_.find(accelerator); 47 AcceleratorMap::iterator map_iter = accelerators_.find(accelerator);
30 if (map_iter == accelerators_.end()) { 48 if (map_iter == accelerators_.end()) {
31 NOTREACHED() << "Unregistering non-existing accelerator"; 49 NOTREACHED() << "Unregistering non-existing accelerator";
32 return; 50 return;
33 } 51 }
34 52
35 AcceleratorTargetList* targets = &map_iter->second; 53 AcceleratorTargetList* targets = &map_iter->second.second;
36 AcceleratorTargetList::iterator target_iter = 54 AcceleratorTargetList::iterator target_iter =
37 std::find(targets->begin(), targets->end(), target); 55 std::find(targets->begin(), targets->end(), target);
38 if (target_iter == targets->end()) { 56 if (target_iter == targets->end()) {
39 NOTREACHED() << "Unregistering accelerator for wrong target"; 57 NOTREACHED() << "Unregistering accelerator for wrong target";
40 return; 58 return;
41 } 59 }
42 60
61 // Check to see if we have a priority handler and whether we are removing it.
62 if (accelerators_[accelerator].first && target_iter == targets->begin()) {
63 // We've are taking the priority accelerator away, flip the priority flag.
64 accelerators_[accelerator].first = false;
65 }
66
43 targets->erase(target_iter); 67 targets->erase(target_iter);
44 } 68 }
45 69
46 void AcceleratorManager::UnregisterAll(AcceleratorTarget* target) { 70 void AcceleratorManager::UnregisterAll(AcceleratorTarget* target) {
47 for (AcceleratorMap::iterator map_iter = accelerators_.begin(); 71 for (AcceleratorMap::iterator map_iter = accelerators_.begin();
48 map_iter != accelerators_.end(); ++map_iter) { 72 map_iter != accelerators_.end(); ++map_iter) {
49 AcceleratorTargetList* targets = &map_iter->second; 73 AcceleratorTargetList* targets = &map_iter->second.second;
50 targets->remove(target); 74 targets->remove(target);
51 } 75 }
52 } 76 }
53 77
54 bool AcceleratorManager::Process(const Accelerator& accelerator) { 78 bool AcceleratorManager::Process(const Accelerator& accelerator) {
55 bool result = false; 79 bool result = false;
56 AcceleratorMap::iterator map_iter = accelerators_.find(accelerator); 80 AcceleratorMap::iterator map_iter = accelerators_.find(accelerator);
57 if (map_iter != accelerators_.end() && ShouldHandle(accelerator)) { 81 if (map_iter != accelerators_.end() && ShouldHandle(accelerator)) {
58 // We have to copy the target list here, because an AcceleratorPressed 82 // We have to copy the target list here, because an AcceleratorPressed
59 // event handler may modify the list. 83 // event handler may modify the list.
60 AcceleratorTargetList targets(map_iter->second); 84 AcceleratorTargetList targets(map_iter->second.second);
61 for (AcceleratorTargetList::iterator iter = targets.begin(); 85 for (AcceleratorTargetList::iterator iter = targets.begin();
62 iter != targets.end(); ++iter) { 86 iter != targets.end(); ++iter) {
63 if ((*iter)->CanHandleAccelerators() && 87 if ((*iter)->CanHandleAccelerators() &&
64 (*iter)->AcceleratorPressed(accelerator)) { 88 (*iter)->AcceleratorPressed(accelerator)) {
65 result = true; 89 result = true;
66 break; 90 break;
67 } 91 }
68 } 92 }
69 } 93 }
70 last_event_type_ = accelerator.type(); 94 last_event_type_ = accelerator.type();
71 return result; 95 return result;
72 } 96 }
73 97
74 AcceleratorTarget* AcceleratorManager::GetCurrentTarget( 98 AcceleratorTarget* AcceleratorManager::GetCurrentTarget(
75 const Accelerator& accelerator) const { 99 const Accelerator& accelerator) const {
76 AcceleratorMap::const_iterator map_iter = accelerators_.find(accelerator); 100 AcceleratorMap::const_iterator map_iter = accelerators_.find(accelerator);
77 if (map_iter == accelerators_.end() || map_iter->second.empty()) 101 if (map_iter == accelerators_.end() || map_iter->second.second.empty())
78 return NULL; 102 return NULL;
79 return map_iter->second.front(); 103 return map_iter->second.second.front();
104 }
105
106 bool AcceleratorManager::HasPriorityHandler(
107 const Accelerator& accelerator) const {
108 AcceleratorMap::const_iterator map_iter = accelerators_.find(accelerator);
109 if (map_iter == accelerators_.end() || map_iter->second.second.empty())
110 return false;
111
112 // Check if we have a priority handler. If not, there's no more work needed.
113 if (!map_iter->second.first)
114 return false;
115
116 // If the priority handler says it cannot handle the accelerator, we must not
117 // count it as one.
sadrul 2012/02/21 16:17:28 In this case, does it make sense to have multiple
Finnur 2012/02/21 21:58:21 Right now, we DCHECK if there is more than one. In
118 return map_iter->second.second.front()->CanHandleAccelerators();
80 } 119 }
81 120
82 bool AcceleratorManager::ShouldHandle(const Accelerator& accelerator) const { 121 bool AcceleratorManager::ShouldHandle(const Accelerator& accelerator) const {
83 if (accelerator.type() != ET_KEY_RELEASED && 122 if (accelerator.type() != ET_KEY_RELEASED &&
84 accelerator.type() != ET_TRANSLATED_KEY_RELEASE) { 123 accelerator.type() != ET_TRANSLATED_KEY_RELEASE) {
85 return true; 124 return true;
86 } 125 }
87 // This check is necessary e.g. not to process the Shift+Alt+ET_KEY_RELEASED 126 // This check is necessary e.g. not to process the Shift+Alt+ET_KEY_RELEASED
88 // Accelerator for Chrome OS (see ash/accelerators/accelerator_controller.cc) 127 // Accelerator for Chrome OS (see ash/accelerators/accelerator_controller.cc)
89 // when Shift+Alt+Tab is pressed and then Tab is released. 128 // when Shift+Alt+Tab is pressed and then Tab is released.
90 if (last_event_type_ == ET_KEY_PRESSED || 129 if (last_event_type_ == ET_KEY_PRESSED ||
91 last_event_type_ == ET_TRANSLATED_KEY_PRESS) { 130 last_event_type_ == ET_TRANSLATED_KEY_PRESS) {
92 return true; 131 return true;
93 } 132 }
94 return false; 133 return false;
95 } 134 }
96 135
97 } // namespace ui 136 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698