OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "chrome/browser/ui/gtk/extensions/extension_keybinding_registry_gtk.h" | |
6 | |
7 #include <gtk/gtk.h> | |
8 | |
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" | |
14 | |
15 // static | |
16 void extensions::ExtensionKeybindingRegistry::SetShortcutHandlingSuspended( | |
17 bool suspended) { | |
18 ExtensionKeybindingRegistryGtk::set_shortcut_handling_suspended(suspended); | |
19 } | |
20 | |
21 bool ExtensionKeybindingRegistryGtk::shortcut_handling_suspended_ = false; | |
22 | |
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(); | |
33 } | |
34 | |
35 ExtensionKeybindingRegistryGtk::~ExtensionKeybindingRegistryGtk() { | |
36 if (accel_group_) { | |
37 gtk_accel_group_disconnect(accel_group_, | |
38 NULL); // Remove all closures. | |
39 | |
40 gtk_window_remove_accel_group(window_, accel_group_); | |
41 g_object_unref(accel_group_); | |
42 accel_group_ = NULL; | |
43 } | |
44 } | |
45 | |
46 gboolean ExtensionKeybindingRegistryGtk::HasPriorityHandler( | |
47 const GdkEventKey* event) const { | |
48 if (shortcut_handling_suspended_) | |
49 return FALSE; | |
50 | |
51 ui::Accelerator accelerator = ui::AcceleratorForGdkKeyCodeAndModifier( | |
52 event->keyval, static_cast<GdkModifierType>(event->state)); | |
53 | |
54 return IsAcceleratorRegistered(accelerator); | |
55 } | |
56 | |
57 void ExtensionKeybindingRegistryGtk::AddExtensionKeybinding( | |
58 const extensions::Extension* extension, | |
59 const std::string& command_name) { | |
60 extensions::CommandService* command_service = | |
61 extensions::CommandService::Get(profile_); | |
62 extensions::CommandMap commands; | |
63 command_service->GetNamedCommands( | |
64 extension->id(), | |
65 extensions::CommandService::ACTIVE_ONLY, | |
66 extensions::CommandService::REGULAR, | |
67 &commands); | |
68 | |
69 for (extensions::CommandMap::const_iterator iter = commands.begin(); | |
70 iter != commands.end(); ++iter) { | |
71 if (!command_name.empty() && (iter->second.command_name() != command_name)) | |
72 continue; | |
73 | |
74 ui::Accelerator accelerator(iter->second.accelerator()); | |
75 AddEventTarget(accelerator, extension->id(), iter->second.command_name()); | |
76 | |
77 if (!accel_group_) { | |
78 accel_group_ = gtk_accel_group_new(); | |
79 gtk_window_add_accel_group(window_, accel_group_); | |
80 } | |
81 | |
82 gtk_accel_group_connect( | |
83 accel_group_, | |
84 ui::GetGdkKeyCodeForAccelerator(accelerator), | |
85 ui::GetGdkModifierForAccelerator(accelerator), | |
86 GtkAccelFlags(0), | |
87 g_cclosure_new(G_CALLBACK(OnGtkAcceleratorThunk), this, NULL)); | |
88 } | |
89 | |
90 // Unlike on Windows, we need to explicitly add the browser action and page | |
91 // action to the event_targets_, even though we don't register them as | |
92 // handlers. See http://crbug.com/124873. | |
93 extensions::Command browser_action; | |
94 if (command_service->GetBrowserActionCommand( | |
95 extension->id(), | |
96 extensions::CommandService::ACTIVE_ONLY, | |
97 &browser_action, | |
98 NULL)) { | |
99 AddEventTarget(browser_action.accelerator(), | |
100 extension->id(), | |
101 browser_action.command_name()); | |
102 } | |
103 | |
104 // Add the Page Action (if any). | |
105 extensions::Command page_action; | |
106 if (command_service->GetPageActionCommand( | |
107 extension->id(), | |
108 extensions::CommandService::ACTIVE_ONLY, | |
109 &page_action, | |
110 NULL)) { | |
111 AddEventTarget( | |
112 page_action.accelerator(), extension->id(), page_action.command_name()); | |
113 } | |
114 } | |
115 | |
116 void ExtensionKeybindingRegistryGtk::RemoveExtensionKeybindingImpl( | |
117 const ui::Accelerator& accelerator, | |
118 const std::string& command_name) { | |
119 // On GTK, unlike Windows, the Event Targets contain all events but we must | |
120 // only unregister the ones we registered targets for. | |
121 if (!ShouldIgnoreCommand(command_name)) { | |
122 gtk_accel_group_disconnect_key( | |
123 accel_group_, | |
124 ui::GetGdkKeyCodeForAccelerator(accelerator), | |
125 ui::GetGdkModifierForAccelerator(accelerator)); | |
126 } | |
127 } | |
128 | |
129 gboolean ExtensionKeybindingRegistryGtk::OnGtkAccelerator( | |
130 GtkAccelGroup* group, | |
131 GObject* acceleratable, | |
132 guint keyval, | |
133 GdkModifierType modifier) { | |
134 ui::Accelerator accelerator = ui::AcceleratorForGdkKeyCodeAndModifier( | |
135 keyval, modifier); | |
136 | |
137 return ExtensionKeybindingRegistry::NotifyEventTargets(accelerator); | |
138 } | |
OLD | NEW |