summaryrefslogtreecommitdiffstats
path: root/ui/base
diff options
context:
space:
mode:
authorfinnur@chromium.org <finnur@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-23 13:00:55 +0000
committerfinnur@chromium.org <finnur@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-23 13:00:55 +0000
commitf553247ebf96528afde64b205cc4fb8733fb08ce (patch)
tree025fa9618eb4bec03f93e58a35fbf2b97dfa5a76 /ui/base
parent92e713a7e3b2b5a2458876f81a053d0c6b7ce5fd (diff)
downloadchromium_src-f553247ebf96528afde64b205cc4fb8733fb08ce.zip
chromium_src-f553247ebf96528afde64b205cc4fb8733fb08ce.tar.gz
chromium_src-f553247ebf96528afde64b205cc4fb8733fb08ce.tar.bz2
Experimental Extension Keybinding (first cut).
Implemented in this cut: - End-to-end extension keybinding -- in one dimension, that is -- no UI, just basic functionality, such as: - Manifest changes to specify keybinding. - A simple parser to parse the keybinding from the manifest. - An Extension Keybinding Registry object. - The ability to open browser action popups, page action popups and send named events to the Extension. Not implemented: - All non-Windows specific code. - Install-success-bubble UI changes (that notify the user of new keybinding -- or of keybinding conflict) - A UI to show all keybindings and keybinding conflicts, allowing user to reconfigure keybindings. BUG=27702 TEST=This is tested by an automated test and requires an extension to test manually (one that registers keybinding shortcuts). Review URL: https://chromiumcodereview.appspot.com/9402018 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@123228 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/base')
-rw-r--r--ui/base/accelerators/accelerator_manager.cc53
-rw-r--r--ui/base/accelerators/accelerator_manager.h26
2 files changed, 70 insertions, 9 deletions
diff --git a/ui/base/accelerators/accelerator_manager.cc b/ui/base/accelerators/accelerator_manager.cc
index d2d70c9..034593d 100644
--- a/ui/base/accelerators/accelerator_manager.cc
+++ b/ui/base/accelerators/accelerator_manager.cc
@@ -17,11 +17,29 @@ AcceleratorManager::~AcceleratorManager() {
}
void AcceleratorManager::Register(const Accelerator& accelerator,
+ HandlerPriority priority,
AcceleratorTarget* target) {
- AcceleratorTargetList& targets = accelerators_[accelerator];
+ AcceleratorTargetList& targets = accelerators_[accelerator].second;
DCHECK(std::find(targets.begin(), targets.end(), target) == targets.end())
<< "Registering the same target multiple times";
- targets.push_front(target);
+
+ // All priority accelerators go to the front of the line.
+ if (priority) {
+ DCHECK(!accelerators_[accelerator].first)
+ << "Only one _priority_ handler can be registered";
+ targets.push_front(target);
+ // Mark that we have a priority accelerator at the front.
+ accelerators_[accelerator].first = true;
+ return;
+ }
+
+ // We are registering a normal priority handler. If no priority accelerator
+ // handler has been registered before us, just add the new handler to the
+ // front. Otherwise, register it after the first (only) priority handler.
+ if (!accelerators_[accelerator].first)
+ targets.push_front(target);
+ else
+ targets.insert(++targets.begin(), target);
}
void AcceleratorManager::Unregister(const Accelerator& accelerator,
@@ -32,7 +50,7 @@ void AcceleratorManager::Unregister(const Accelerator& accelerator,
return;
}
- AcceleratorTargetList* targets = &map_iter->second;
+ AcceleratorTargetList* targets = &map_iter->second.second;
AcceleratorTargetList::iterator target_iter =
std::find(targets->begin(), targets->end(), target);
if (target_iter == targets->end()) {
@@ -40,13 +58,19 @@ void AcceleratorManager::Unregister(const Accelerator& accelerator,
return;
}
+ // Check to see if we have a priority handler and whether we are removing it.
+ if (accelerators_[accelerator].first && target_iter == targets->begin()) {
+ // We've are taking the priority accelerator away, flip the priority flag.
+ accelerators_[accelerator].first = false;
+ }
+
targets->erase(target_iter);
}
void AcceleratorManager::UnregisterAll(AcceleratorTarget* target) {
for (AcceleratorMap::iterator map_iter = accelerators_.begin();
map_iter != accelerators_.end(); ++map_iter) {
- AcceleratorTargetList* targets = &map_iter->second;
+ AcceleratorTargetList* targets = &map_iter->second.second;
targets->remove(target);
}
}
@@ -57,7 +81,7 @@ bool AcceleratorManager::Process(const Accelerator& accelerator) {
if (map_iter != accelerators_.end() && ShouldHandle(accelerator)) {
// We have to copy the target list here, because an AcceleratorPressed
// event handler may modify the list.
- AcceleratorTargetList targets(map_iter->second);
+ AcceleratorTargetList targets(map_iter->second.second);
for (AcceleratorTargetList::iterator iter = targets.begin();
iter != targets.end(); ++iter) {
if ((*iter)->CanHandleAccelerators() &&
@@ -74,9 +98,24 @@ bool AcceleratorManager::Process(const Accelerator& accelerator) {
AcceleratorTarget* AcceleratorManager::GetCurrentTarget(
const Accelerator& accelerator) const {
AcceleratorMap::const_iterator map_iter = accelerators_.find(accelerator);
- if (map_iter == accelerators_.end() || map_iter->second.empty())
+ if (map_iter == accelerators_.end() || map_iter->second.second.empty())
return NULL;
- return map_iter->second.front();
+ return map_iter->second.second.front();
+}
+
+bool AcceleratorManager::HasPriorityHandler(
+ const Accelerator& accelerator) const {
+ AcceleratorMap::const_iterator map_iter = accelerators_.find(accelerator);
+ if (map_iter == accelerators_.end() || map_iter->second.second.empty())
+ return false;
+
+ // Check if we have a priority handler. If not, there's no more work needed.
+ if (!map_iter->second.first)
+ return false;
+
+ // If the priority handler says it cannot handle the accelerator, we must not
+ // count it as one.
+ return map_iter->second.second.front()->CanHandleAccelerators();
}
bool AcceleratorManager::ShouldHandle(const Accelerator& accelerator) const {
diff --git a/ui/base/accelerators/accelerator_manager.h b/ui/base/accelerators/accelerator_manager.h
index c54ea1d..7164acb 100644
--- a/ui/base/accelerators/accelerator_manager.h
+++ b/ui/base/accelerators/accelerator_manager.h
@@ -8,6 +8,7 @@
#include <list>
#include <map>
+#include <utility>
#include "base/basictypes.h"
#include "ui/base/accelerators/accelerator.h"
@@ -19,19 +20,34 @@ namespace ui {
// The AcceleratorManger is used to handle keyboard accelerators.
class UI_EXPORT AcceleratorManager {
public:
+ enum HandlerPriority {
+ kNormalPriority,
+ kHighPriority,
+ };
+
AcceleratorManager();
~AcceleratorManager();
// Register a keyboard accelerator for the specified target. If multiple
// targets are registered for an accelerator, a target registered later has
// higher priority.
+ // |accelerator| is the accelerator to register.
+ // |priority| denotes the priority of the handler.
+ // NOTE: In almost all cases, you should specify kPriorityNormal for this
+ // parameter. Setting it to kPriorityHigh prevents Chrome from sending the
+ // shortcut to the webpage if the renderer has focus, which is not desirable
+ // except for very isolated cases.
+ // |target| is the AcceleratorTarget that handles the event once the
+ // accelerator is pressed.
// Note that we are currently limited to accelerators that are either:
// - a key combination including Ctrl or Alt
// - the escape key
// - the enter key
// - any F key (F1, F2, F3 ...)
// - any browser specific keys (as available on special keyboards)
- void Register(const Accelerator& accelerator, AcceleratorTarget* target);
+ void Register(const Accelerator& accelerator,
+ HandlerPriority priority,
+ AcceleratorTarget* target);
// Unregister the specified keyboard accelerator for the specified target.
void Unregister(const Accelerator& accelerator, AcceleratorTarget* target);
@@ -52,12 +68,18 @@ class UI_EXPORT AcceleratorManager {
// accelerator.
AcceleratorTarget* GetCurrentTarget(const Accelerator& accelertor) const;
+ // Whether the given |accelerator| has a priority handler associated with it.
+ bool HasPriorityHandler(const Accelerator& accelerator) const;
+
private:
bool ShouldHandle(const Accelerator& accelerator) const;
// The accelerators and associated targets.
typedef std::list<AcceleratorTarget*> AcceleratorTargetList;
- typedef std::map<Accelerator, AcceleratorTargetList> AcceleratorMap;
+ // This construct pairs together a |bool| (denoting whether the list contains
+ // a priority_handler at the front) with the list of AcceleratorTargets.
+ typedef std::pair<bool, AcceleratorTargetList> AcceleratorTargets;
+ typedef std::map<Accelerator, AcceleratorTargets> AcceleratorMap;
AcceleratorMap accelerators_;
// An event passed to Process() last time.