OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "chrome/browser/extensions/global_shortcut_listener_x11.h" | 5 #include "chrome/browser/extensions/global_shortcut_listener_x11.h" |
6 | 6 |
7 #include "content/public/browser/browser_thread.h" | 7 #include "content/public/browser/browser_thread.h" |
8 #include "ui/base/accelerators/accelerator.h" | 8 #include "ui/base/accelerators/accelerator.h" |
9 #include "ui/events/keycodes/keyboard_code_conversion_x.h" | 9 #include "ui/events/keycodes/keyboard_code_conversion_x.h" |
| 10 #include "ui/events/platform/x11/x11_event_source.h" |
10 #include "ui/gfx/x/x11_error_tracker.h" | 11 #include "ui/gfx/x/x11_error_tracker.h" |
11 #include "ui/gfx/x/x11_types.h" | 12 #include "ui/gfx/x/x11_types.h" |
12 | 13 |
13 #if defined(TOOLKIT_GTK) | |
14 #include <gdk/gdkx.h> | |
15 #else | |
16 #include "ui/events/platform/x11/x11_event_source.h" | |
17 #endif | |
18 | |
19 using content::BrowserThread; | 14 using content::BrowserThread; |
20 | 15 |
21 namespace { | 16 namespace { |
22 | 17 |
23 // The modifiers masks used for grabing keys. Due to XGrabKey only working on | 18 // The modifiers masks used for grabing keys. Due to XGrabKey only working on |
24 // exact modifiers, we need to grab all key combination including zero or more | 19 // exact modifiers, we need to grab all key combination including zero or more |
25 // of the following: Num lock, Caps lock and Scroll lock. So that we can make | 20 // of the following: Num lock, Caps lock and Scroll lock. So that we can make |
26 // sure the behavior of global shortcuts is consistent on all platforms. | 21 // sure the behavior of global shortcuts is consistent on all platforms. |
27 const unsigned int kModifiersMasks[] = { | 22 const unsigned int kModifiersMasks[] = { |
28 0, // No additional modifier. | 23 0, // No additional modifier. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 | 60 |
66 GlobalShortcutListenerX11::~GlobalShortcutListenerX11() { | 61 GlobalShortcutListenerX11::~GlobalShortcutListenerX11() { |
67 if (is_listening_) | 62 if (is_listening_) |
68 StopListening(); | 63 StopListening(); |
69 } | 64 } |
70 | 65 |
71 void GlobalShortcutListenerX11::StartListening() { | 66 void GlobalShortcutListenerX11::StartListening() { |
72 DCHECK(!is_listening_); // Don't start twice. | 67 DCHECK(!is_listening_); // Don't start twice. |
73 DCHECK(!registered_hot_keys_.empty()); // Also don't start if no hotkey is | 68 DCHECK(!registered_hot_keys_.empty()); // Also don't start if no hotkey is |
74 // registered. | 69 // registered. |
75 #if defined(TOOLKIT_GTK) | 70 |
76 gdk_window_add_filter(gdk_get_default_root_window(), | |
77 &GlobalShortcutListenerX11::OnXEventThunk, | |
78 this); | |
79 #else | |
80 ui::X11EventSource::GetInstance()->AddPlatformEventDispatcher(this); | 71 ui::X11EventSource::GetInstance()->AddPlatformEventDispatcher(this); |
81 #endif | |
82 | 72 |
83 is_listening_ = true; | 73 is_listening_ = true; |
84 } | 74 } |
85 | 75 |
86 void GlobalShortcutListenerX11::StopListening() { | 76 void GlobalShortcutListenerX11::StopListening() { |
87 DCHECK(is_listening_); // No point if we are not already listening. | 77 DCHECK(is_listening_); // No point if we are not already listening. |
88 DCHECK(registered_hot_keys_.empty()); // Make sure the set is clean before | 78 DCHECK(registered_hot_keys_.empty()); // Make sure the set is clean before |
89 // ending. | 79 // ending. |
90 | 80 |
91 #if defined(TOOLKIT_GTK) | |
92 gdk_window_remove_filter(NULL, | |
93 &GlobalShortcutListenerX11::OnXEventThunk, | |
94 this); | |
95 #else | |
96 ui::X11EventSource::GetInstance()->RemovePlatformEventDispatcher(this); | 81 ui::X11EventSource::GetInstance()->RemovePlatformEventDispatcher(this); |
97 #endif | |
98 | 82 |
99 is_listening_ = false; | 83 is_listening_ = false; |
100 } | 84 } |
101 | 85 |
102 #if !defined(TOOLKIT_GTK) | |
103 bool GlobalShortcutListenerX11::CanDispatchEvent( | 86 bool GlobalShortcutListenerX11::CanDispatchEvent( |
104 const ui::PlatformEvent& event) { | 87 const ui::PlatformEvent& event) { |
105 return event->type == KeyPress; | 88 return event->type == KeyPress; |
106 } | 89 } |
107 | 90 |
108 uint32_t GlobalShortcutListenerX11::DispatchEvent( | 91 uint32_t GlobalShortcutListenerX11::DispatchEvent( |
109 const ui::PlatformEvent& event) { | 92 const ui::PlatformEvent& event) { |
110 CHECK_EQ(KeyPress, event->type); | 93 CHECK_EQ(KeyPress, event->type); |
111 OnXKeyPressEvent(event); | 94 OnXKeyPressEvent(event); |
112 | 95 |
113 return ui::POST_DISPATCH_NONE; | 96 return ui::POST_DISPATCH_NONE; |
114 } | 97 } |
115 #endif | |
116 | 98 |
117 bool GlobalShortcutListenerX11::RegisterAcceleratorImpl( | 99 bool GlobalShortcutListenerX11::RegisterAcceleratorImpl( |
118 const ui::Accelerator& accelerator) { | 100 const ui::Accelerator& accelerator) { |
119 DCHECK(registered_hot_keys_.find(accelerator) == registered_hot_keys_.end()); | 101 DCHECK(registered_hot_keys_.find(accelerator) == registered_hot_keys_.end()); |
120 | 102 |
121 int modifiers = GetNativeModifiers(accelerator); | 103 int modifiers = GetNativeModifiers(accelerator); |
122 KeyCode keycode = XKeysymToKeycode(x_display_, | 104 KeyCode keycode = XKeysymToKeycode(x_display_, |
123 XKeysymForWindowsKeyCode(accelerator.key_code(), false)); | 105 XKeysymForWindowsKeyCode(accelerator.key_code(), false)); |
124 gfx::X11ErrorTracker err_tracker; | 106 gfx::X11ErrorTracker err_tracker; |
125 | 107 |
(...skipping 27 matching lines...) Expand all Loading... |
153 KeyCode keycode = XKeysymToKeycode(x_display_, | 135 KeyCode keycode = XKeysymToKeycode(x_display_, |
154 XKeysymForWindowsKeyCode(accelerator.key_code(), false)); | 136 XKeysymForWindowsKeyCode(accelerator.key_code(), false)); |
155 | 137 |
156 for (size_t i = 0; i < arraysize(kModifiersMasks); ++i) { | 138 for (size_t i = 0; i < arraysize(kModifiersMasks); ++i) { |
157 XUngrabKey(x_display_, keycode, modifiers | kModifiersMasks[i], | 139 XUngrabKey(x_display_, keycode, modifiers | kModifiersMasks[i], |
158 x_root_window_); | 140 x_root_window_); |
159 } | 141 } |
160 registered_hot_keys_.erase(accelerator); | 142 registered_hot_keys_.erase(accelerator); |
161 } | 143 } |
162 | 144 |
163 #if defined(TOOLKIT_GTK) | |
164 GdkFilterReturn GlobalShortcutListenerX11::OnXEvent(GdkXEvent* gdk_x_event, | |
165 GdkEvent* gdk_event) { | |
166 XEvent* x_event = static_cast<XEvent*>(gdk_x_event); | |
167 if (x_event->type == KeyPress) | |
168 OnXKeyPressEvent(x_event); | |
169 | |
170 return GDK_FILTER_CONTINUE; | |
171 } | |
172 #endif | |
173 | |
174 void GlobalShortcutListenerX11::OnXKeyPressEvent(::XEvent* x_event) { | 145 void GlobalShortcutListenerX11::OnXKeyPressEvent(::XEvent* x_event) { |
175 DCHECK(x_event->type == KeyPress); | 146 DCHECK(x_event->type == KeyPress); |
176 int modifiers = 0; | 147 int modifiers = 0; |
177 modifiers |= (x_event->xkey.state & ShiftMask) ? ui::EF_SHIFT_DOWN : 0; | 148 modifiers |= (x_event->xkey.state & ShiftMask) ? ui::EF_SHIFT_DOWN : 0; |
178 modifiers |= (x_event->xkey.state & ControlMask) ? ui::EF_CONTROL_DOWN : 0; | 149 modifiers |= (x_event->xkey.state & ControlMask) ? ui::EF_CONTROL_DOWN : 0; |
179 modifiers |= (x_event->xkey.state & Mod1Mask) ? ui::EF_ALT_DOWN : 0; | 150 modifiers |= (x_event->xkey.state & Mod1Mask) ? ui::EF_ALT_DOWN : 0; |
180 | 151 |
181 ui::Accelerator accelerator( | 152 ui::Accelerator accelerator( |
182 ui::KeyboardCodeFromXKeyEvent(x_event), modifiers); | 153 ui::KeyboardCodeFromXKeyEvent(x_event), modifiers); |
183 if (registered_hot_keys_.find(accelerator) != registered_hot_keys_.end()) | 154 if (registered_hot_keys_.find(accelerator) != registered_hot_keys_.end()) |
184 NotifyKeyPressed(accelerator); | 155 NotifyKeyPressed(accelerator); |
185 } | 156 } |
186 | 157 |
187 } // namespace extensions | 158 } // namespace extensions |
OLD | NEW |