Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(246)

Side by Side Diff: chrome/browser/extensions/global_shortcut_listener_win.cc

Issue 23812010: Implement first part of supporting global extension commands. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: gclient sync Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2013 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/extensions/global_shortcut_listener_win.h"
6
7 #include "base/win/win_util.h"
8 #include "content/public/browser/browser_thread.h"
9 #include "ui/base/accelerators/accelerator.h"
10 #include "ui/events/event_constants.h"
11 #include "ui/events/keycodes/keyboard_code_conversion_win.h"
12
13 using content::BrowserThread;
14
15 namespace {
16
17 static base::LazyInstance<extensions::GlobalShortcutListenerWin> instance =
18 LAZY_INSTANCE_INITIALIZER;
19
20 } // namespace
21
22 namespace extensions {
23
24 // static
25 GlobalShortcutListener* GlobalShortcutListener::GetInstance() {
26 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
27 return instance.Pointer();
28 }
29
30 GlobalShortcutListenerWin::GlobalShortcutListenerWin()
31 : is_listening_(false) {
32 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
33 }
34
35 GlobalShortcutListenerWin::~GlobalShortcutListenerWin() {
36 if (is_listening_)
37 StopListening();
38 }
39
40 void GlobalShortcutListenerWin::StartListening() {
41 DCHECK(!is_listening_); // Don't start twice.
42 DCHECK(!hotkey_ids_.empty()); // Also don't start if no hotkey is registered.
43 gfx::SingletonHwnd::GetInstance()->AddObserver(this);
44 is_listening_ = true;
45 }
46
47 void GlobalShortcutListenerWin::StopListening() {
48 DCHECK(is_listening_); // No point if we are not already listening.
49 DCHECK(hotkey_ids_.empty()); // Make sure the map is clean before ending.
50 gfx::SingletonHwnd::GetInstance()->RemoveObserver(this);
51 is_listening_ = false;
52 }
53
54 void GlobalShortcutListenerWin::OnWndProc(HWND hwnd,
55 UINT message,
56 WPARAM wparam,
57 LPARAM lparam) {
58 if (message != WM_HOTKEY)
59 return;
60
61 int key_code = HIWORD(lparam);
62 int modifiers = 0;
63 modifiers |= (LOWORD(lparam) & MOD_SHIFT) ? ui::EF_SHIFT_DOWN : 0;
64 modifiers |= (LOWORD(lparam) & MOD_ALT) ? ui::EF_ALT_DOWN : 0;
65 modifiers |= (LOWORD(lparam) & MOD_CONTROL) ? ui::EF_CONTROL_DOWN : 0;
66 ui::Accelerator accelerator(
67 ui::KeyboardCodeForWindowsKeyCode(key_code), modifiers);
68
69 instance.Get().NotifyKeyPressed(accelerator);
70 }
71
72 void GlobalShortcutListenerWin::RegisterAccelerator(
73 const ui::Accelerator& accelerator,
74 GlobalShortcutListener::Observer* observer) {
75 int modifiers = 0;
76 modifiers |= accelerator.IsShiftDown() ? MOD_SHIFT : 0;
77 modifiers |= accelerator.IsCtrlDown() ? MOD_CONTROL : 0;
78 modifiers |= accelerator.IsAltDown() ? MOD_ALT : 0;
79 static int hotkey_id = 0;
80 bool success = !!RegisterHotKey(
81 gfx::SingletonHwnd::GetInstance()->hwnd(),
82 hotkey_id,
83 modifiers,
84 accelerator.key_code());
85
86 if (!success) {
87 // Most likely error: 1409 (Hotkey already registered).
88 LOG(ERROR) << "RegisterHotKey failed, error: " << GetLastError();
89 return;
90 }
91
92 hotkey_ids_[accelerator] = hotkey_id++;
93 GlobalShortcutListener::RegisterAccelerator(accelerator, observer);
94 }
95
96 void GlobalShortcutListenerWin::UnregisterAccelerator(
97 const ui::Accelerator& accelerator,
98 GlobalShortcutListener::Observer* observer) {
99 // We may get asked to unregister something that we couldn't register (for
100 // example if the shortcut was already taken by another app), so we
101 // need to handle that gracefully.
102 HotkeyIdMap::iterator it = hotkey_ids_.find(accelerator);
103 if (it == hotkey_ids_.end())
104 return;
105
106 UnregisterHotKey(gfx::SingletonHwnd::GetInstance()->hwnd(), it->second);
107 hotkey_ids_.erase(it);
108
109 GlobalShortcutListener::UnregisterAccelerator(accelerator, observer);
110 }
111
112 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698