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

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: No change, just reuploading (last attempt was incomplete) 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 if (hotkey_id == 0) {
81 // Ensure that the window has been created before calling RegisterHotKey
Yoyo Zhou 2013/10/03 22:08:50 Which window is this?
Finnur 2013/10/04 17:57:02 The singleton-hwnd, but this code is now redundant
82 // because otherwise we'd be calling RegisterHotkey on a NULL window, which
83 // causes problems when unregistering (after the window has been created).
84 gfx::SingletonHwnd::GetInstance()->Init();
85 }
86
87 bool success = !!RegisterHotKey(
88 gfx::SingletonHwnd::GetInstance()->hwnd(),
89 hotkey_id,
90 modifiers,
91 accelerator.key_code());
92
93 if (!success) {
94 // Most likely error: 1409 (Hotkey already registered).
95 LOG(ERROR) << "RegisterHotKey failed, error: " << GetLastError();
96 return;
97 }
98
99 hotkey_ids_[accelerator] = hotkey_id++;
100 GlobalShortcutListener::RegisterAccelerator(accelerator, observer);
101 }
102
103 void GlobalShortcutListenerWin::UnregisterAccelerator(
104 const ui::Accelerator& accelerator,
105 GlobalShortcutListener::Observer* observer) {
106 // We may get asked to unregister something that we couldn't register (for
107 // example if the shortcut was already taken by another app), so we
108 // need to handle that gracefully.
109 HotkeyIdMap::iterator it = hotkey_ids_.find(accelerator);
110 if (it == hotkey_ids_.end())
111 return;
112
113 UnregisterHotKey(gfx::SingletonHwnd::GetInstance()->hwnd(), it->second);
114 hotkey_ids_.erase(it);
115
116 GlobalShortcutListener::UnregisterAccelerator(accelerator, observer);
117 }
118
119 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698