| 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 |