Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / ui / gtk / extensions / extension_keybinding_registry_gtk.cc
blob9be5f3e7d61376061d7e4c956c38300d2035f5de
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
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/gtk/extensions/extension_keybinding_registry_gtk.h"
7 #include <gtk/gtk.h>
9 #include "chrome/browser/extensions/api/commands/command_service.h"
10 #include "chrome/browser/extensions/extension_service.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "extensions/common/extension.h"
13 #include "ui/base/accelerators/platform_accelerator_gtk.h"
15 // static
16 void extensions::ExtensionKeybindingRegistry::SetShortcutHandlingSuspended(
17 bool suspended) {
18 ExtensionKeybindingRegistryGtk::set_shortcut_handling_suspended(suspended);
21 bool ExtensionKeybindingRegistryGtk::shortcut_handling_suspended_ = false;
23 ExtensionKeybindingRegistryGtk::ExtensionKeybindingRegistryGtk(
24 Profile* profile,
25 gfx::NativeWindow window,
26 ExtensionFilter extension_filter,
27 Delegate* delegate)
28 : ExtensionKeybindingRegistry(profile, extension_filter, delegate),
29 profile_(profile),
30 window_(window),
31 accel_group_(NULL) {
32 Init();
35 ExtensionKeybindingRegistryGtk::~ExtensionKeybindingRegistryGtk() {
36 if (accel_group_) {
37 gtk_accel_group_disconnect(accel_group_,
38 NULL); // Remove all closures.
39 event_targets_.clear();
41 gtk_window_remove_accel_group(window_, accel_group_);
42 g_object_unref(accel_group_);
43 accel_group_ = NULL;
47 gboolean ExtensionKeybindingRegistryGtk::HasPriorityHandler(
48 const GdkEventKey* event) const {
49 if (shortcut_handling_suspended_)
50 return FALSE;
52 ui::Accelerator accelerator = ui::AcceleratorForGdkKeyCodeAndModifier(
53 event->keyval, static_cast<GdkModifierType>(event->state));
55 return event_targets_.find(accelerator) != event_targets_.end();
58 void ExtensionKeybindingRegistryGtk::AddExtensionKeybinding(
59 const extensions::Extension* extension,
60 const std::string& command_name) {
61 extensions::CommandService* command_service =
62 extensions::CommandService::Get(profile_);
63 extensions::CommandMap commands;
64 command_service->GetNamedCommands(
65 extension->id(),
66 extensions::CommandService::ACTIVE_ONLY,
67 extensions::CommandService::REGULAR,
68 &commands);
70 for (extensions::CommandMap::const_iterator iter = commands.begin();
71 iter != commands.end(); ++iter) {
72 if (!command_name.empty() && (iter->second.command_name() != command_name))
73 continue;
75 ui::Accelerator accelerator(iter->second.accelerator());
76 event_targets_[accelerator].push_back(
77 std::make_pair(extension->id(), iter->second.command_name()));
79 // Shortcuts except media keys have only one target in the list. See comment
80 // about |event_targets_|.
81 if (!extensions::CommandService::IsMediaKey(iter->second.accelerator()))
82 DCHECK_EQ(1u, event_targets_[accelerator].size());
84 if (!accel_group_) {
85 accel_group_ = gtk_accel_group_new();
86 gtk_window_add_accel_group(window_, accel_group_);
89 gtk_accel_group_connect(
90 accel_group_,
91 ui::GetGdkKeyCodeForAccelerator(accelerator),
92 ui::GetGdkModifierForAccelerator(accelerator),
93 GtkAccelFlags(0),
94 g_cclosure_new(G_CALLBACK(OnGtkAcceleratorThunk), this, NULL));
97 // Unlike on Windows, we need to explicitly add the browser action and page
98 // action to the event_targets_, even though we don't register them as
99 // handlers. See http://crbug.com/124873.
100 extensions::Command browser_action;
101 if (command_service->GetBrowserActionCommand(
102 extension->id(),
103 extensions::CommandService::ACTIVE_ONLY,
104 &browser_action,
105 NULL)) {
106 ui::Accelerator accelerator(browser_action.accelerator());
107 event_targets_[accelerator].push_back(
108 std::make_pair(extension->id(), browser_action.command_name()));
109 // We should have only one target. See comment about |event_targets_|.
110 DCHECK_EQ(1u, event_targets_[accelerator].size());
113 // Add the Page Action (if any).
114 extensions::Command page_action;
115 if (command_service->GetPageActionCommand(
116 extension->id(),
117 extensions::CommandService::ACTIVE_ONLY,
118 &page_action,
119 NULL)) {
120 ui::Accelerator accelerator(page_action.accelerator());
121 event_targets_[accelerator].push_back(
122 std::make_pair(extension->id(), page_action.command_name()));
123 // We should have only one target. See comment about |event_targets_|.
124 DCHECK_EQ(1u, event_targets_[accelerator].size());
127 // Add the Script Badge (if any).
128 extensions::Command script_badge;
129 if (command_service->GetScriptBadgeCommand(
130 extension->id(),
131 extensions::CommandService::ACTIVE_ONLY,
132 &script_badge,
133 NULL)) {
134 ui::Accelerator accelerator(script_badge.accelerator());
135 event_targets_[accelerator].push_back(
136 std::make_pair(extension->id(), script_badge.command_name()));
137 // We should have only one target. See comment about |event_targets_|.
138 DCHECK_EQ(1u, event_targets_[accelerator].size());
142 void ExtensionKeybindingRegistryGtk::RemoveExtensionKeybindingImpl(
143 const ui::Accelerator& accelerator,
144 const std::string& command_name) {
145 // On GTK, unlike Windows, the Event Targets contain all events but we must
146 // only unregister the ones we registered targets for.
147 if (!ShouldIgnoreCommand(command_name)) {
148 gtk_accel_group_disconnect_key(
149 accel_group_,
150 ui::GetGdkKeyCodeForAccelerator(accelerator),
151 ui::GetGdkModifierForAccelerator(accelerator));
155 gboolean ExtensionKeybindingRegistryGtk::OnGtkAccelerator(
156 GtkAccelGroup* group,
157 GObject* acceleratable,
158 guint keyval,
159 GdkModifierType modifier) {
160 ui::Accelerator accelerator = ui::AcceleratorForGdkKeyCodeAndModifier(
161 keyval, modifier);
163 return ExtensionKeybindingRegistry::NotifyEventTargets(accelerator);