Update GlobalShortcut API design.

* Rename Shortcut API to GlobalShortcut for better suite.
* Implement the new design interfaces.
* Put the chromium related source code to the same directory as in chrome.
This commit is contained in:
Haojian Wu 2014-07-31 12:22:29 +08:00
parent b2217474c1
commit 035679057e
16 changed files with 288 additions and 302 deletions

View file

@ -19,12 +19,12 @@
'atom/browser/api/lib/auto-updater.coffee',
'atom/browser/api/lib/browser-window.coffee',
'atom/browser/api/lib/dialog.coffee',
'atom/browser/api/lib/global-shortcut.coffee',
'atom/browser/api/lib/ipc.coffee',
'atom/browser/api/lib/menu.coffee',
'atom/browser/api/lib/menu-item.coffee',
'atom/browser/api/lib/power-monitor.coffee',
'atom/browser/api/lib/protocol.coffee',
'atom/browser/api/lib/shortcut.coffee',
'atom/browser/api/lib/tray.coffee',
'atom/browser/api/lib/web-contents.coffee',
'atom/browser/lib/init.coffee',
@ -53,6 +53,8 @@
'atom/browser/api/atom_api_auto_updater.cc',
'atom/browser/api/atom_api_auto_updater.h',
'atom/browser/api/atom_api_dialog.cc',
'atom/browser/api/atom_api_global_shortcut.cc',
'atom/browser/api/atom_api_global_shortcut.h',
'atom/browser/api/atom_api_menu.cc',
'atom/browser/api/atom_api_menu.h',
'atom/browser/api/atom_api_menu_views.cc',
@ -63,8 +65,6 @@
'atom/browser/api/atom_api_power_monitor.h',
'atom/browser/api/atom_api_protocol.cc',
'atom/browser/api/atom_api_protocol.h',
'atom/browser/api/atom_api_shortcut.cc',
'atom/browser/api/atom_api_shortcut.h',
'atom/browser/api/atom_api_tray.cc',
'atom/browser/api/atom_api_tray.h',
'atom/browser/api/atom_api_web_contents.cc',
@ -226,6 +226,14 @@
'atom/renderer/atom_render_view_observer.h',
'atom/renderer/atom_renderer_client.cc',
'atom/renderer/atom_renderer_client.h',
'chromium_src/chrome/browser/extensions/global_shortcut_listener.cc',
'chromium_src/chrome/browser/extensions/global_shortcut_listener.h',
'chromium_src/chrome/browser/extensions/global_shortcut_listener_mac.mm',
'chromium_src/chrome/browser/extensions/global_shortcut_listener_mac.h',
'chromium_src/chrome/browser/extensions/global_shortcut_listener_x11.cc',
'chromium_src/chrome/browser/extensions/global_shortcut_listener_x11.h',
'chromium_src/chrome/browser/extensions/global_shortcut_listener_win.cc',
'chromium_src/chrome/browser/extensions/global_shortcut_listener_win.h',
'chromium_src/chrome/browser/ui/libgtk2ui/app_indicator_icon_menu.cc',
'chromium_src/chrome/browser/ui/libgtk2ui/app_indicator_icon_menu.h',
'chromium_src/chrome/browser/ui/libgtk2ui/gtk2_status_icon.cc',
@ -234,14 +242,6 @@
'chromium_src/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.h',
'chromium_src/chrome/browser/ui/views/status_icons/status_tray_state_changer_win.cc',
'chromium_src/chrome/browser/ui/views/status_icons/status_tray_state_changer_win.h',
'chromium_src/chrome/browser/ui/shortcut/global_shortcut_listener.cc',
'chromium_src/chrome/browser/ui/shortcut/global_shortcut_listener.h',
'chromium_src/chrome/browser/ui/shortcut/global_shortcut_listener_mac.mm',
'chromium_src/chrome/browser/ui/shortcut/global_shortcut_listener_mac.h',
'chromium_src/chrome/browser/ui/shortcut/global_shortcut_listener_x11.cc',
'chromium_src/chrome/browser/ui/shortcut/global_shortcut_listener_x11.h',
'chromium_src/chrome/browser/ui/shortcut/global_shortcut_listener_win.cc',
'chromium_src/chrome/browser/ui/shortcut/global_shortcut_listener_win.h',
'<@(native_mate_files)',
],
'framework_sources': [

View file

@ -0,0 +1,123 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_global_shortcut.h"
#include <string>
#include "atom/browser/ui/accelerator_util.h"
#include "atom/common/native_mate_converters/function_converter.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"
using extensions::GlobalShortcutListener;
namespace atom {
namespace api {
GlobalShortcut::GlobalShortcut() {
}
GlobalShortcut::~GlobalShortcut() {
UnregisterAll();
}
void GlobalShortcut::OnKeyPressed(const ui::Accelerator& accelerator) {
if (accelerator_callback_map_.find(accelerator) ==
accelerator_callback_map_.end()) {
// This should never occur, because if it does, GlobalGlobalShortcutListener
// notifes us with wrong accelerator.
NOTREACHED();
return;
}
accelerator_callback_map_[accelerator].Run();
}
bool GlobalShortcut::Register(const std::string& keycode,
const base::Closure& callback) {
ui::Accelerator accelerator;
if (!accelerator_util::StringToAccelerator(keycode, &accelerator)) {
LOG(ERROR) << keycode << " is invalid.";
return false;
}
if (!GlobalShortcutListener::GetInstance()->RegisterAccelerator(
accelerator, this)) {
return false;
}
accelerator_callback_map_[accelerator] = callback;
return true;
}
void GlobalShortcut::Unregister(const std::string& keycode) {
ui::Accelerator accelerator;
if (!accelerator_util::StringToAccelerator(keycode, &accelerator)) {
LOG(ERROR) << "The keycode: " << keycode << " is invalid.";
return;
}
if (accelerator_callback_map_.find(accelerator) ==
accelerator_callback_map_.end()) {
LOG(ERROR) << "The keycode: " << keycode << " isn't registered yet!";
return;
}
accelerator_callback_map_.erase(accelerator);
GlobalShortcutListener::GetInstance()->UnregisterAccelerator(
accelerator, this);
}
void GlobalShortcut::UnregisterAll() {
accelerator_callback_map_.clear();
GlobalShortcutListener::GetInstance()->UnregisterAccelerators(this);
}
bool GlobalShortcut::IsRegistered(const std::string& keycode) {
ui::Accelerator accelerator;
if (!accelerator_util::StringToAccelerator(keycode, &accelerator)) {
LOG(ERROR) << "The keycode: " << keycode << " is invalid.";
return false;
}
return accelerator_callback_map_.find(accelerator) !=
accelerator_callback_map_.end();
}
// static
mate::ObjectTemplateBuilder GlobalShortcut::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return mate::ObjectTemplateBuilder(isolate)
.SetMethod("register",
base::Bind(&GlobalShortcut::Register,
base::Unretained(this)))
.SetMethod("isRegistered",
base::Bind(&GlobalShortcut::IsRegistered,
base::Unretained(this)))
.SetMethod("unregister",
base::Bind(&GlobalShortcut::Unregister,
base::Unretained(this)))
.SetMethod("unregisterAll",
base::Bind(&GlobalShortcut::UnregisterAll,
base::Unretained(this)));
}
// static
mate::Handle<GlobalShortcut> GlobalShortcut::Create(v8::Isolate* isolate) {
return CreateHandle(isolate, new GlobalShortcut);
}
} // namespace api
} // namespace atom
namespace {
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
v8::Handle<v8::Context> context, void* priv) {
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.Set("globalShortcut", atom::api::GlobalShortcut::Create(isolate));
}
} // namespace
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_global_shortcut, Initialize)

View file

@ -0,0 +1,54 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_API_ATOM_API_GLOBAL_SHORTCUT_H_
#define ATOM_BROWSER_API_ATOM_API_GLOBAL_SHORTCUT_H_
#include <map>
#include <string>
#include "base/callback.h"
#include "chrome/browser/extensions/global_shortcut_listener.h"
#include "native_mate/wrappable.h"
#include "native_mate/handle.h"
#include "ui/base/accelerators/accelerator.h"
namespace atom {
namespace api {
class GlobalShortcut : public extensions::GlobalShortcutListener::Observer,
public mate::Wrappable {
public:
static mate::Handle<GlobalShortcut> Create(v8::Isolate* isolate);
protected:
GlobalShortcut();
virtual ~GlobalShortcut();
// mate::Wrappable implementations:
virtual mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) OVERRIDE;
private:
typedef std::map<ui::Accelerator, base::Closure> AcceleratorCallbackMap;
bool Register(const std::string& keycode, const base::Closure& callback);
bool IsRegistered(const std::string& keycode);
void Unregister(const std::string& keycode);
void UnregisterAll();
// GlobalShortcutListener::Observer implementation.
virtual void OnKeyPressed(const ui::Accelerator& accelerator) OVERRIDE;
AcceleratorCallbackMap accelerator_callback_map_;
DISALLOW_COPY_AND_ASSIGN(GlobalShortcut);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_GLOBAL_SHORTCUT_H_

View file

@ -1,110 +0,0 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_shortcut.h"
#include <string>
#include <vector>
#include "atom/browser/ui/accelerator_util.h"
#include "base/values.h"
#include "native_mate/constructor.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"
namespace atom {
namespace api {
Shortcut::Shortcut(const std::string& key) {
is_key_valid_ = accelerator_util::StringToAccelerator(key, &accelerator_);
}
Shortcut::~Shortcut() {
Unregister();
}
// static
mate::Wrappable* Shortcut::Create(const std::string& key) {
return new Shortcut(key);
}
void Shortcut::OnActive() {
Emit("active");
}
void Shortcut::OnFailed(const std::string& error_msg) {
base::ListValue args;
args.AppendString(error_msg);
Emit("failed", args);
}
void Shortcut::SetKey(const std::string& key) {
// We need to unregister the previous key before set new key eachtime.
Unregister();
is_key_valid_ = accelerator_util::StringToAccelerator(key, &accelerator_);
}
void Shortcut::OnKeyPressed(const ui::Accelerator& accelerator) {
if (accelerator != accelerator_) {
// This should never occur, because if it does, GlobalShortcutListener
// notifes us with wrong accelerator.
NOTREACHED();
return;
}
OnActive();
}
void Shortcut::Register() {
if (!is_key_valid_) {
OnFailed("Shortcut is invalid.");
return;
}
if (!GlobalShortcutListener::GetInstance()->RegisterAccelerator(
accelerator_, this))
OnFailed("Fail to register the shortcut.");
}
void Shortcut::Unregister() {
GlobalShortcutListener::GetInstance()->UnregisterAccelerator(
accelerator_, this);
}
bool Shortcut::IsRegistered() {
return GlobalShortcutListener::GetInstance()->IsAcceleratorRegistered(
accelerator_);
}
// static
void Shortcut::BuildPrototype(v8::Isolate* isolate,
v8::Handle<v8::ObjectTemplate> prototype) {
mate::ObjectTemplateBuilder(isolate, prototype)
.SetMethod("setKey", &Shortcut::SetKey)
.SetMethod("register", &Shortcut::Register)
.SetMethod("unregister", &Shortcut::Unregister)
.SetMethod("isRegistered", &Shortcut::IsRegistered);
}
} // namespace api
} // namespace atom
namespace {
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
v8::Handle<v8::Context> context, void* priv) {
using atom::api::Shortcut;
v8::Isolate* isolate = context->GetIsolate();
v8::Handle<v8::Function> constructor = mate::CreateConstructor<Shortcut>(
isolate, "Shortcut", base::Bind(&Shortcut::Create));
mate::Dictionary dict(isolate, exports);
dict.Set("Shortcut", static_cast<v8::Handle<v8::Value>>(constructor));
}
} // namespace
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_shortcut, Initialize)

View file

@ -1,67 +0,0 @@
// Copyright (c) 2014 GitHub, Inc. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_API_ATOM_API_SHORTCUT_H_
#define ATOM_BROWSER_API_ATOM_API_SHORTCUT_H_
#include <string>
#include <vector>
#include "atom/browser/api/event_emitter.h"
#include "chrome/browser/ui/shortcut/global_shortcut_listener.h"
#include "ui/base/accelerators/accelerator.h"
namespace mate {
class Dictionary;
}
namespace atom {
class Shortcut;
namespace api {
class Menu;
class Shortcut : public mate::EventEmitter,
public GlobalShortcutListener::Observer {
public:
static mate::Wrappable* Create(const std::string& key);
static void BuildPrototype(v8::Isolate* isolate,
v8::Handle<v8::ObjectTemplate> prototype);
protected:
explicit Shortcut(const std::string& key);
virtual ~Shortcut();
const ui::Accelerator& GetAccelerator() const {
return accelerator_;
}
void OnActive();
void OnFailed(const std::string& error_msg);
// GlobalShortcutListener::Observer implementation.
virtual void OnKeyPressed(const ui::Accelerator& accelerator) OVERRIDE;
void SetKey(const std::string& key);
void Register();
void Unregister();
bool IsRegistered();
private:
bool is_key_valid_;
ui::Accelerator accelerator_;
DISALLOW_COPY_AND_ASSIGN(Shortcut);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_SHORTCUT_H_

View file

@ -0,0 +1,5 @@
bindings = process.atomBinding 'global_shortcut'
globalShortcut = bindings.globalShortcut
module.exports = globalShortcut

View file

@ -1,7 +0,0 @@
EventEmitter = require('events').EventEmitter
bindings = process.atomBinding 'shortcut'
Shortcut = bindings.Shortcut
Shortcut::__proto__ = EventEmitter.prototype
module.exports = Shortcut

View file

@ -65,7 +65,7 @@ REFERENCE_MODULE(atom_browser_dialog);
REFERENCE_MODULE(atom_browser_menu);
REFERENCE_MODULE(atom_browser_power_monitor);
REFERENCE_MODULE(atom_browser_protocol);
REFERENCE_MODULE(atom_browser_shortcut);
REFERENCE_MODULE(atom_browser_global_shortcut);
REFERENCE_MODULE(atom_browser_tray);
REFERENCE_MODULE(atom_browser_window);
REFERENCE_MODULE(atom_common_clipboard);

View file

@ -1,18 +1,16 @@
// Copyright (c) 2014 The Chromium Authors. All rights reserved.
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/extensions/global_shortcut_listener.h"
#include "base/logging.h"
#include "chrome/browser/ui/shortcut/global_shortcut_listener.h"
#include "content/public/browser/browser_thread.h"
#include "ui/base/accelerators/accelerator.h"
using content::BrowserThread;
namespace atom {
namespace api {
namespace extensions {
GlobalShortcutListener::GlobalShortcutListener()
: shortcut_handling_suspended_(false) {
@ -21,6 +19,7 @@ GlobalShortcutListener::GlobalShortcutListener()
GlobalShortcutListener::~GlobalShortcutListener() {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK(accelerator_map_.empty()); // Make sure we've cleaned up.
}
bool GlobalShortcutListener::RegisterAccelerator(
@ -55,8 +54,8 @@ void GlobalShortcutListener::UnregisterAccelerator(
return;
AcceleratorMap::iterator it = accelerator_map_.find(accelerator);
if (it == accelerator_map_.end())
return;
// We should never get asked to unregister something that we didn't register.
DCHECK(it != accelerator_map_.end());
// The caller should call this function with the right observer.
DCHECK(it->second == observer);
@ -120,6 +119,4 @@ void GlobalShortcutListener::NotifyKeyPressed(
iter->second->OnKeyPressed(accelerator);
}
} // namespace api
} // namespace atom
} // namespace extensions

View file

@ -1,9 +1,9 @@
// Copyright (c) 2014 The Chromium Authors. All rights reserved.
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_SHORTCUT_GLOBAL_SHORTCUT_LISTENER_H_
#define CHROME_BROWSER_UI_SHORTCUT_GLOBAL_SHORTCUT_LISTENER_H_
#ifndef CHROME_BROWSER_EXTENSIONS_GLOBAL_SHORTCUT_LISTENER_H_
#define CHROME_BROWSER_EXTENSIONS_GLOBAL_SHORTCUT_LISTENER_H_
#include <map>
@ -14,9 +14,7 @@ namespace ui {
class Accelerator;
}
namespace atom {
namespace api {
namespace extensions {
// Platform-neutral implementation of a class that keeps track of observers and
// monitors keystrokes. It relays messages to the appropriate observer when a
@ -61,9 +59,6 @@ class GlobalShortcutListener {
// Returns whether shortcut handling is currently suspended.
bool IsShortcutHandlingSuspended() const;
// Returen whether accelerator is registered.
virtual bool IsAcceleratorRegistered(const ui::Accelerator& accelerator) = 0;
protected:
GlobalShortcutListener();
@ -99,7 +94,6 @@ class GlobalShortcutListener {
DISALLOW_COPY_AND_ASSIGN(GlobalShortcutListener);
};
} // namespace api
} // namespace extensions
} // namespace atom
#endif // CHROME_BROWSER_UI_SHORTCUT_GLOBAL_SHORTCUT_LISTENER_H_
#endif // CHROME_BROWSER_EXTENSIONS_GLOBAL_SHORTCUT_LISTENER_H_

View file

@ -1,11 +1,11 @@
// Copyright (c) 2014 The Chromium Authors. All rights reserved.
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_SHORTCUT_GLOBAL_SHORTCUT_LISTENER_MAC_H_
#define CHROME_BROWSER_UI_SHORTCUT_GLOBAL_SHORTCUT_LISTENER_MAC_H_
#ifndef CHROME_BROWSER_EXTENSIONS_GLOBAL_SHORTCUT_LISTENER_MAC_H_
#define CHROME_BROWSER_EXTENSIONS_GLOBAL_SHORTCUT_LISTENER_MAC_H_
#include "chrome/browser/ui/shortcut/global_shortcut_listener.h"
#include "chrome/browser/extensions/global_shortcut_listener.h"
#include <Carbon/Carbon.h>
#include <CoreFoundation/CoreFoundation.h>
@ -14,9 +14,7 @@
#include "base/mac/scoped_nsobject.h"
namespace atom {
namespace api {
namespace extensions {
// Mac-specific implementation of the GlobalShortcutListener class that
// listens for global shortcuts. Handles basic keyboard intercepting and
@ -32,7 +30,6 @@ class GlobalShortcutListenerMac : public GlobalShortcutListener {
GlobalShortcutListenerMac();
virtual ~GlobalShortcutListenerMac();
virtual bool IsAcceleratorRegistered(const ui::Accelerator& accelerator) OVERRIDE;
private:
typedef int KeyId;
typedef std::map<ui::Accelerator, KeyId> AcceleratorIdMap;
@ -104,8 +101,6 @@ class GlobalShortcutListenerMac : public GlobalShortcutListener {
DISALLOW_COPY_AND_ASSIGN(GlobalShortcutListenerMac);
};
} // namespace api
} // namespace extensions
} // namespace atom
#endif // CHROME_BROWSER_UI_SHORTCUT_GLOBAL_SHORTCUT_LISTENER_MAC_H_
#endif // CHROME_BROWSER_EXTENSIONS_GLOBAL_SHORTCUT_LISTENER_MAC_H_

View file

@ -1,8 +1,8 @@
// Copyright (c) 2014 The Chromium Authors. All rights reserved.
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/shortcut/global_shortcut_listener_mac.h"
#include "chrome/browser/extensions/global_shortcut_listener_mac.h"
#include <ApplicationServices/ApplicationServices.h>
#import <Cocoa/Cocoa.h>
@ -15,7 +15,7 @@
#import "ui/events/keycodes/keyboard_code_conversion_mac.h"
using content::BrowserThread;
using atom::api::GlobalShortcutListenerMac;
using extensions::GlobalShortcutListenerMac;
namespace {
@ -48,9 +48,7 @@ bool IsMediaKey(const ui::Accelerator& accelerator) {
} // namespace
namespace atom {
namespace api {
namespace extensions {
// static
GlobalShortcutListener* GlobalShortcutListener::GetInstance() {
@ -86,11 +84,6 @@ GlobalShortcutListenerMac::~GlobalShortcutListenerMac() {
StopWatchingHotKeys();
}
bool GlobalShortcutListenerMac::IsAcceleratorRegistered(
const ui::Accelerator& accelerator) {
return accelerator_ids_.find(accelerator) != accelerator_ids_.end();
}
void GlobalShortcutListenerMac::StartListening() {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@ -387,6 +380,4 @@ OSStatus GlobalShortcutListenerMac::HotKeyHandler(
return noErr;
}
} // namespace api
} // namespace atom
} // namespace extensions

View file

@ -1,8 +1,8 @@
// Copyright (c) 2014 The Chromium Authors. All rights reserved.
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/shortcut/global_shortcut_listener_win.h"
#include "chrome/browser/extensions/global_shortcut_listener_win.h"
#include "base/win/win_util.h"
#include "content/public/browser/browser_thread.h"
@ -12,9 +12,7 @@
using content::BrowserThread;
namespace atom {
namespace api {
namespace extensions {
// static
GlobalShortcutListener* GlobalShortcutListener::GetInstance() {
@ -34,11 +32,6 @@ GlobalShortcutListenerWin::~GlobalShortcutListenerWin() {
StopListening();
}
bool GlobalShortcutListenerWin::IsAcceleratorRegistered(
const ui::Accelerator& accelerator) {
return hotkey_ids_.find(accelerator) != hotkey_ids_.end();
}
void GlobalShortcutListenerWin::StartListening() {
DCHECK(!is_listening_); // Don't start twice.
DCHECK(!hotkey_ids_.empty()); // Also don't start if no hotkey is registered.
@ -80,7 +73,6 @@ bool GlobalShortcutListenerWin::RegisterAcceleratorImpl(
modifiers |= accelerator.IsCtrlDown() ? MOD_CONTROL : 0;
modifiers |= accelerator.IsAltDown() ? MOD_ALT : 0;
static int hotkey_id = 0;
//bool success = false;
bool success = !!RegisterHotKey(
gfx::SingletonHwnd::GetInstance()->hwnd(),
hotkey_id,
@ -101,8 +93,6 @@ void GlobalShortcutListenerWin::UnregisterAcceleratorImpl(
HotkeyIdMap::iterator it = hotkey_ids_.find(accelerator);
DCHECK(it != hotkey_ids_.end());
//bool success = false;
gfx::SingletonHwnd::GetInstance();
bool success = !!UnregisterHotKey(
gfx::SingletonHwnd::GetInstance()->hwnd(), it->second);
// This call should always succeed, as long as we pass in the right HWND and
@ -112,6 +102,4 @@ void GlobalShortcutListenerWin::UnregisterAcceleratorImpl(
hotkey_ids_.erase(it);
}
} // namespace api
} // namespace atom
} // namespace extensions

View file

@ -1,18 +1,16 @@
// Copyright (c) 2014 The Chromium Authors. All rights reserved.
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_SHORTCUT_GLOBAL_SHORTCUT_LISTENER_WIN_H_
#define CHROME_BROWSER_UI_SHORTCUT_GLOBAL_SHORTCUT_LISTENER_WIN_H_
#ifndef CHROME_BROWSER_EXTENSIONS_GLOBAL_SHORTCUT_LISTENER_WIN_H_
#define CHROME_BROWSER_EXTENSIONS_GLOBAL_SHORTCUT_LISTENER_WIN_H_
#include <windows.h>
#include "chrome/browser/ui/shortcut/global_shortcut_listener.h"
#include "chrome/browser/extensions/global_shortcut_listener.h"
#include "ui/gfx/win/singleton_hwnd.h"
namespace atom {
namespace api {
namespace extensions {
// Windows-specific implementation of the GlobalShortcutListener class that
// listens for global shortcuts. Handles setting up a keyboard hook and
@ -23,9 +21,6 @@ class GlobalShortcutListenerWin : public GlobalShortcutListener,
GlobalShortcutListenerWin();
virtual ~GlobalShortcutListenerWin();
virtual bool IsAcceleratorRegistered(
const ui::Accelerator& accelerator) OVERRIDE;
private:
// The implementation of our Window Proc, called by SingletonHwnd.
virtual void OnWndProc(HWND hwnd,
@ -51,8 +46,6 @@ class GlobalShortcutListenerWin : public GlobalShortcutListener,
DISALLOW_COPY_AND_ASSIGN(GlobalShortcutListenerWin);
};
} // namespace api
} // namespace extensions
} // namespace atom
#endif // CHROME_BROWSER_UI_SHORTCUT_GLOBAL_SHORTCUT_LISTENER_WIN_H_
#endif // CHROME_BROWSER_EXTENSIONS_GLOBAL_SHORTCUT_LISTENER_WIN_H_

View file

@ -1,16 +1,21 @@
// Copyright 2014 The Chromium Authors. All rights reserved.
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/shortcut/global_shortcut_listener_x11.h"
#include "chrome/browser/extensions/global_shortcut_listener_x11.h"
#include "base/message_loop/message_pump_x11.h"
#include "content/public/browser/browser_thread.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/events/keycodes/keyboard_code_conversion_x.h"
#include "ui/gfx/x/x11_error_tracker.h"
#include "ui/gfx/x/x11_types.h"
#if defined(TOOLKIT_GTK)
#include <gdk/gdkx.h>
#else
#include "base/message_loop/message_pump_x11.h"
#endif
using content::BrowserThread;
namespace {
@ -41,9 +46,7 @@ int GetNativeModifiers(const ui::Accelerator& accelerator) {
} // namespace
namespace atom {
namespace api {
namespace extensions {
// static
GlobalShortcutListener* GlobalShortcutListener::GetInstance() {
@ -65,16 +68,17 @@ GlobalShortcutListenerX11::~GlobalShortcutListenerX11() {
StopListening();
}
bool GlobalShortcutListenerX11::IsAcceleratorRegistered(
const ui::Accelerator& accelerator) {
return registered_hot_keys_.find(accelerator) != registered_hot_keys_.end();
}
void GlobalShortcutListenerX11::StartListening() {
DCHECK(!is_listening_); // Don't start twice.
DCHECK(!registered_hot_keys_.empty()); // Also don't start if no hotkey is
// registered.
#if defined(TOOLKIT_GTK)
gdk_window_add_filter(gdk_get_default_root_window(),
&GlobalShortcutListenerX11::OnXEventThunk,
this);
#else
base::MessagePumpX11::Current()->AddDispatcherForRootWindow(this);
#endif
is_listening_ = true;
}
@ -84,17 +88,25 @@ void GlobalShortcutListenerX11::StopListening() {
DCHECK(registered_hot_keys_.empty()); // Make sure the set is clean before
// ending.
#if defined(TOOLKIT_GTK)
gdk_window_remove_filter(NULL,
&GlobalShortcutListenerX11::OnXEventThunk,
this);
#else
base::MessagePumpX11::Current()->RemoveDispatcherForRootWindow(this);
#endif
is_listening_ = false;
}
#if !defined(TOOLKIT_GTK)
uint32_t GlobalShortcutListenerX11::Dispatch(const base::NativeEvent& event) {
if (event->type == KeyPress)
OnXKeyPressEvent(event);
return POST_DISPATCH_NONE;
}
#endif
bool GlobalShortcutListenerX11::RegisterAcceleratorImpl(
const ui::Accelerator& accelerator) {
@ -142,6 +154,17 @@ void GlobalShortcutListenerX11::UnregisterAcceleratorImpl(
registered_hot_keys_.erase(accelerator);
}
#if defined(TOOLKIT_GTK)
GdkFilterReturn GlobalShortcutListenerX11::OnXEvent(GdkXEvent* gdk_x_event,
GdkEvent* gdk_event) {
XEvent* x_event = static_cast<XEvent*>(gdk_x_event);
if (x_event->type == KeyPress)
OnXKeyPressEvent(x_event);
return GDK_FILTER_CONTINUE;
}
#endif
void GlobalShortcutListenerX11::OnXKeyPressEvent(::XEvent* x_event) {
DCHECK(x_event->type == KeyPress);
int modifiers = 0;
@ -155,6 +178,4 @@ void GlobalShortcutListenerX11::OnXKeyPressEvent(::XEvent* x_event) {
NotifyKeyPressed(accelerator);
}
} // namespace api
} // namespace atom
} // namespace extensions

View file

@ -1,35 +1,40 @@
// Copyright 2014 The Chromium Authors. All rights reserved.
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_SHORTCUT_GLOBAL_SHORTCUT_LISTENER_X11_H_
#define CHROME_BROWSER_UI_SHORTCUT_GLOBAL_SHORTCUT_LISTENER_X11_H_
#ifndef CHROME_BROWSER_EXTENSIONS_GLOBAL_SHORTCUT_LISTENER_X11_H_
#define CHROME_BROWSER_EXTENSIONS_GLOBAL_SHORTCUT_LISTENER_X11_H_
#include <X11/Xlib.h>
#include <set>
#include "base/message_loop/message_pump_dispatcher.h"
#include "chrome/browser/ui/shortcut/global_shortcut_listener.h"
#include "chrome/browser/extensions/global_shortcut_listener.h"
namespace atom {
#if defined(TOOLKIT_GTK)
#include <gtk/gtk.h>
#include "ui/base/gtk/gtk_signal.h"
#endif // defined(TOOLKIT_GTK)
namespace api {
namespace extensions {
// X11-specific implementation of the GlobalShortcutListener class that
// listens for global shortcuts. Handles basic keyboard intercepting and
// forwards its output to the base class for processing.
class GlobalShortcutListenerX11
: public base::MessagePumpDispatcher,
:
#if !defined(TOOLKIT_GTK)
public base::MessagePumpDispatcher,
#endif
public GlobalShortcutListener {
public:
GlobalShortcutListenerX11();
virtual ~GlobalShortcutListenerX11();
#if !defined(TOOLKIT_GTK)
// base::MessagePumpDispatcher implementation.
virtual uint32_t Dispatch(const base::NativeEvent& event) OVERRIDE;
virtual bool IsAcceleratorRegistered(
const ui::Accelerator& accelerator) OVERRIDE;
#endif
private:
// GlobalShortcutListener implementation.
@ -40,6 +45,12 @@ class GlobalShortcutListenerX11
virtual void UnregisterAcceleratorImpl(
const ui::Accelerator& accelerator) OVERRIDE;
#if defined(TOOLKIT_GTK)
// Callback for XEvents of the default root window.
CHROMEG_CALLBACK_1(GlobalShortcutListenerX11, GdkFilterReturn,
OnXEvent, GdkXEvent*, GdkEvent*);
#endif
// Invoked when a global shortcut is pressed.
void OnXKeyPressEvent(::XEvent* x_event);
@ -57,8 +68,6 @@ class GlobalShortcutListenerX11
DISALLOW_COPY_AND_ASSIGN(GlobalShortcutListenerX11);
};
} // namespace api
} // namespace extensions
} // namespace atom
#endif // CHROME_BROWSER_UI_SHORTCUT_GLOBAL_SHORTCUT_LISTENER_X11_H_
#endif // CHROME_BROWSER_EXTENSIONS_GLOBAL_SHORTCUT_LISTENER_X11_H_