Add new global shortcut system backend for X11 and Windows

- Remove qxt
- Also create an option for enabled/disabling shortcuts through X11.
This commit is contained in:
Jonas Kvinge
2019-01-01 20:07:29 +01:00
parent 2a54cb17e7
commit cef334c210
40 changed files with 1283 additions and 2345 deletions

View File

@@ -0,0 +1,76 @@
/*
* Strawberry Music Player
* Copyright 2018, Jonas Kvinge <jonas@jkvinge.net>
*
* Strawberry is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Strawberry is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <QtGlobal>
#include <QObject>
#include <QAbstractEventDispatcher>
#include <QByteArray>
#include <qt_windows.h>
#include "core/logging.h"
#include "globalshortcuts.h"
#include "globalshortcutbackend.h"
#include "globalshortcut.h"
#include "keymapper_win.h"
quint32 GlobalShortcut::nativeModifiers(Qt::KeyboardModifiers qt_mods) {
quint32 native_mods = 0;
if (qt_mods & Qt::ShiftModifier) native_mods |= MOD_SHIFT;
if (qt_mods & Qt::ControlModifier) native_mods |= MOD_CONTROL;
if (qt_mods & Qt::AltModifier) native_mods |= MOD_ALT;
if (qt_mods & Qt::MetaModifier) native_mods |= MOD_WIN;
return native_mods;
}
quint32 GlobalShortcut::nativeKeycode(Qt::Key qt_key) {
quint32 key_code = 0;
if (KeyMapperWin::keymapper_win_.contains(qt_key)) {
key_code = KeyMapperWin::keymapper_win_.value(qt_key);
}
return key_code;
}
bool GlobalShortcut::registerShortcut(quint32 native_key, quint32 native_mods) {
return RegisterHotKey(0, native_mods ^ native_key, native_mods, native_key);
}
bool GlobalShortcut::unregisterShortcut(quint32 native_key, quint32 native_mods) {
return UnregisterHotKey(0, native_mods ^ native_key);
}
bool GlobalShortcut::nativeEventFilter(const QByteArray &eventtype, void *message, long *result) {
Q_UNUSED(eventtype);
Q_UNUSED(result);
MSG *msg = static_cast<MSG*>(message);
if (msg->message != WM_HOTKEY) return false;
quint32 key_code = HIWORD(msg->lParam);
quint32 modifiers = LOWORD(msg->lParam);
activateShortcut(key_code, modifiers);
return true;
}

View File

@@ -0,0 +1,112 @@
/*
* Strawberry Music Player
* Copyright 2018, Jonas Kvinge <jonas@jkvinge.net>
*
* Strawberry is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Strawberry is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "config.h"
#include <QtGlobal>
#include <QApplication>
#include <QObject>
#include <QAbstractEventDispatcher>
#include <QDataStream>
#include <QVector>
#include <QByteArray>
#include <QX11Info>
#include <QKeySequence>
#include <QtAlgorithms>
#include "core/logging.h"
#include "globalshortcuts.h"
#include "globalshortcutbackend.h"
#include "globalshortcut.h"
#include "keymapper_x11.h"
#include <X11/X.h>
#include <X11/Xlib.h>
#include <xcb/xcb.h>
#include <xcb/xproto.h>
const QVector<quint32> GlobalShortcut::mask_modifiers_ = QVector<quint32>() << 0 << Mod2Mask << LockMask << (Mod2Mask | LockMask);
quint32 GlobalShortcut::nativeModifiers(Qt::KeyboardModifiers qt_mods) {
quint32 native_mods = 0;
if (qt_mods & Qt::ShiftModifier) native_mods |= ShiftMask;
if (qt_mods & Qt::ControlModifier) native_mods |= ControlMask;
if (qt_mods & Qt::AltModifier) native_mods |= Mod1Mask;
if (qt_mods & Qt::MetaModifier) native_mods |= Mod4Mask;
return native_mods;
}
quint32 GlobalShortcut::nativeKeycode(Qt::Key key) {
if (!QX11Info::display()) return 0;
quint32 keysym = 0;
if (KeyMapperX11::keymapper_x11_.contains(key)) {
keysym = KeyMapperX11::keymapper_x11_.value(key);
}
else {
keysym = XStringToKeysym(QKeySequence(key).toString().toLatin1().data());
if (keysym == NoSymbol) return 0;
}
return XKeysymToKeycode(QX11Info::display(), keysym);
}
bool GlobalShortcut::registerShortcut(quint32 native_key, quint32 native_mods) {
if (!QX11Info::display()) return false;
for (quint32 mask_mods : mask_modifiers_) {
//xcb_grab_key(QX11Info::connection(), 1, QX11Info::appRootWindow(), (native_mods | mask_mods), native_key, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC);
XGrabKey(QX11Info::display(), native_key, (native_mods | mask_mods), QX11Info::appRootWindow(), True, GrabModeAsync, GrabModeAsync);
}
return true;
}
bool GlobalShortcut::unregisterShortcut(quint32 native_key, quint32 native_mods) {
if (!QX11Info::display()) return false;
for (quint32 mask_mods : mask_modifiers_) {
XUngrabKey(QX11Info::display(), native_key, native_mods | mask_mods, QX11Info::appRootWindow());
}
return true;
}
bool GlobalShortcut::nativeEventFilter(const QByteArray &eventtype, void *message, long *result) {
Q_UNUSED(eventtype);
Q_UNUSED(result);
xcb_generic_event_t *event = static_cast<xcb_generic_event_t *>(message);
if ((event->response_type & 127) != XCB_KEY_PRESS) return false;
xcb_key_press_event_t *key_press_event = static_cast<xcb_key_press_event_t *>(message);
if (!key_press_event) return false;
quint32 keycode = key_press_event->detail;
unsigned int keystate = 0;
if (key_press_event->state & XCB_MOD_MASK_1) keystate |= Mod1Mask;
if (key_press_event->state & XCB_MOD_MASK_CONTROL) keystate |= ControlMask;
if (key_press_event->state & XCB_MOD_MASK_4) keystate |= Mod4Mask;
if (key_press_event->state & XCB_MOD_MASK_SHIFT) keystate |= ShiftMask;
activateShortcut(keycode, keystate & (ShiftMask | ControlMask | Mod1Mask | Mod4Mask));
return false;
}

View File

@@ -0,0 +1,145 @@
/*
* Strawberry Music Player
* Copyright 2018, Jonas Kvinge <jonas@jkvinge.net>
*
* Strawberry is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Strawberry is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "config.h"
#include <QtGlobal>
#include <QObject>
#include <QApplication>
#include <QAbstractEventDispatcher>
#include <QPair>
#include <QHash>
#include <QtDebug>
#include "core/logging.h"
#include "globalshortcutbackend.h"
#include "globalshortcut.h"
GlobalShortcut *GlobalShortcut::initialized_ = nullptr;
QHash<QPair<quint32, quint32>, GlobalShortcut*> GlobalShortcut::internal_shortcuts_;
GlobalShortcut::GlobalShortcut(QObject *parent) : QObject(parent),
qt_key_(Qt::Key(0)),
qt_mods_(Qt::NoModifier),
native_key_(0),
native_mods_(0) {
Q_ASSERT(!initialized_);
QAbstractEventDispatcher::instance()->installNativeEventFilter(this);
initialized_ = this;
}
GlobalShortcut::GlobalShortcut(QKeySequence shortcut, GlobalShortcutBackend *backend, QObject *parent) : QObject(parent),
backend_(backend),
shortcut_(shortcut),
qt_key_(Qt::Key(0)),
qt_mods_(Qt::NoModifier),
native_key_(0),
native_mods_(0) {
Q_ASSERT(initialized_);
setShortcut(shortcut);
}
GlobalShortcut::~GlobalShortcut() {
if (this == initialized_) {
QAbstractEventDispatcher::instance()->removeNativeEventFilter(this);
initialized_ = nullptr;
}
else {
unsetShortcut();
}
}
bool GlobalShortcut::setShortcut(const QKeySequence &shortcut) {
Q_ASSERT(initialized_);
if (shortcut.isEmpty()) return false;
shortcut_ = shortcut;
Qt::KeyboardModifiers all_mods = Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier;
qt_key_ = Qt::Key((shortcut[0] ^ all_mods) & shortcut[0]);
qt_mods_ = Qt::KeyboardModifiers(shortcut[0] & all_mods);
native_key_ = nativeKeycode(qt_key_);
if (native_key_ == 0) return false;
native_mods_ = nativeModifiers(qt_mods_);
bool result = registerShortcut(native_key_, native_mods_);
if (result) {
internal_shortcuts_.insert(qMakePair(native_key_, native_mods_), this);
}
else {
qLog(Error) << "Failed to register shortcut" << shortcut_.toString();
}
qLog(Info) << "Registered shortcut" << shortcut_.toString();
return result;
}
bool GlobalShortcut::unsetShortcut() {
Q_ASSERT(initialized_);
QPair<quint32, quint32> hash = qMakePair(native_key_, native_mods_);
if (internal_shortcuts_.contains(hash)) {
GlobalShortcut *gshortcut = internal_shortcuts_.value(hash);
if (gshortcut != this) return false;
}
bool result = unregisterShortcut(native_key_, native_mods_);
if (result) {
if (internal_shortcuts_.contains(hash)) {
internal_shortcuts_.remove(hash);
}
qLog(Info) << "Unregister shortcut" << shortcut_.toString();
}
else {
qLog(Error) << "Failed to unregister shortcut:" << shortcut_.toString();
}
qt_key_ = Qt::Key(0);
qt_mods_ = Qt::KeyboardModifiers(0);
native_key_ = 0;
native_mods_ = 0;
return result;
}
void GlobalShortcut::activateShortcut(quint32 native_key, quint32 native_mod) {
Q_ASSERT(initialized_);
QPair<quint32, quint32> hash = qMakePair(native_key, native_mod);
if (!internal_shortcuts_.contains(hash)) return;
GlobalShortcut *gshortcut = internal_shortcuts_.value(hash);
if (gshortcut && gshortcut != initialized_) {
emit gshortcut->activated();
}
}

View File

@@ -0,0 +1,80 @@
/*
* Strawberry Music Player
* Copyright 2018, Jonas Kvinge <jonas@jkvinge.net>
*
* Strawberry is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Strawberry is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef GLOBALSHORTCUT_H
#define GLOBALSHORTCUT_H
#include "config.h"
#include <stdbool.h>
#include <QtGlobal>
#include <QObject>
#include <QAbstractNativeEventFilter>
#include <QKeySequence>
#include <QPair>
#include <QVector>
#include <QHash>
#include <QByteArray>
class GlobalShortcutBackend;
class GlobalShortcut : public QObject, QAbstractNativeEventFilter {
Q_OBJECT
public:
explicit GlobalShortcut(QObject *parent = nullptr);
explicit GlobalShortcut(QKeySequence shortcut, GlobalShortcutBackend *backend, QObject *parent = nullptr);
~GlobalShortcut();
GlobalShortcutBackend *backend() const { return backend_; }
QKeySequence shortcut() const { return shortcut_; }
bool setShortcut(const QKeySequence &shortcut);
bool unsetShortcut();
signals:
void activated();
private:
void activateShortcut(quint32 native_key, quint32 native_mods);
quint32 nativeModifiers(Qt::KeyboardModifiers qt_mods);
quint32 nativeKeycode(Qt::Key qt_keycode);
bool registerShortcut(quint32 native_key, quint32 native_mods);
bool unregisterShortcut(quint32 native_key, quint32 native_mods);
bool nativeEventFilter(const QByteArray &eventtype, void *message, long *result);
static GlobalShortcut *initialized_;
static QHash<QPair<quint32, quint32>, GlobalShortcut*> internal_shortcuts_;
static const QVector<quint32> mask_modifiers_;
GlobalShortcutBackend *backend_;
QKeySequence shortcut_;
Qt::Key qt_key_;
Qt::KeyboardModifiers qt_mods_;
quint32 native_key_;
quint32 native_mods_;
};
#endif // GLOBALSHORTCUT_H

View File

@@ -20,45 +20,41 @@
#include "config.h"
#ifdef HAVE_DBUS
# include <dbus/gnomesettingsdaemon.h>
#endif
#include <dbus/gnomesettingsdaemon.h>
#include <QAction>
#include <QObject>
#include <QCoreApplication>
#include <QDateTime>
#include <QMap>
#include <QtDebug>
#ifdef HAVE_DBUS
# include <QCoreApplication>
# include <QDBusConnectionInterface>
# include <QDBusMessage>
# include <QDBusPendingCall>
# include <QDBusPendingReply>
#endif
#include <QDBusConnection>
#include <QDBusMessage>
#include <QDBusPendingCallWatcher>
#include <QDBusPendingReply>
#include "core/closure.h"
#include "core/logging.h"
#include "globalshortcuts.h"
#include "globalshortcuts/globalshortcutbackend.h"
#include "gnomeglobalshortcutbackend.h"
#include "globalshortcutbackend.h"
#include "globalshortcutbackend-dbus.h"
const char *GnomeGlobalShortcutBackend::kGsdService = "org.gnome.SettingsDaemon";
const char *GnomeGlobalShortcutBackend::kGsdPath = "/org/gnome/SettingsDaemon/MediaKeys";
const char *GnomeGlobalShortcutBackend::kGsdInterface = "org.gnome.SettingsDaemon.MediaKeys";
const char *GlobalShortcutBackendDBus::kGsdService = "org.gnome.SettingsDaemon";
const char *GlobalShortcutBackendDBus::kGsdPath = "/org/gnome/SettingsDaemon/MediaKeys";
const char *GlobalShortcutBackendDBus::kGsdInterface = "org.gnome.SettingsDaemon.MediaKeys";
GnomeGlobalShortcutBackend::GnomeGlobalShortcutBackend(GlobalShortcuts *parent)
GlobalShortcutBackendDBus::GlobalShortcutBackendDBus(GlobalShortcuts *parent)
: GlobalShortcutBackend(parent),
interface_(nullptr),
is_connected_(false) {}
bool GnomeGlobalShortcutBackend::DoRegister() {
GlobalShortcutBackendDBus::~GlobalShortcutBackendDBus(){}
bool GlobalShortcutBackendDBus::DoRegister() {
qLog(Debug) << "Registering";
#ifdef HAVE_DBUS
qLog(Debug) << "registering";
// Check if the GSD service is available
if (!QDBusConnection::sessionBus().interface()->isServiceRegistered(kGsdService)) {
qLog(Warning) << "gnome settings daemon not registered";
qLog(Warning) << "Gnome settings daemon not registered";
return false;
}
@@ -72,16 +68,11 @@ bool GnomeGlobalShortcutBackend::DoRegister() {
NewClosure(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(RegisterFinished(QDBusPendingCallWatcher*)), watcher);
return true;
#else
qLog(Warning) << "dbus not available";
return false;
#endif
}
void GnomeGlobalShortcutBackend::RegisterFinished(QDBusPendingCallWatcher *watcher) {
void GlobalShortcutBackendDBus::RegisterFinished(QDBusPendingCallWatcher *watcher) {
#ifdef HAVE_DBUS
QDBusMessage reply = watcher->reply();
watcher->deleteLater();
@@ -93,16 +84,14 @@ void GnomeGlobalShortcutBackend::RegisterFinished(QDBusPendingCallWatcher *watch
connect(interface_, SIGNAL(MediaPlayerKeyPressed(QString, QString)), this, SLOT(GnomeMediaKeyPressed(QString, QString)));
is_connected_ = true;
qLog(Debug) << "registered";
#endif
qLog(Debug) << "Registered";
}
void GnomeGlobalShortcutBackend::DoUnregister() {
void GlobalShortcutBackendDBus::DoUnregister() {
qLog(Debug) << "unregister";
qLog(Debug) << "Unregister";
#ifdef HAVE_DBUS
// Check if the GSD service is available
if (!QDBusConnection::sessionBus().interface()->isServiceRegistered(kGsdService))
return;
@@ -112,14 +101,12 @@ void GnomeGlobalShortcutBackend::DoUnregister() {
interface_->ReleaseMediaPlayerKeys(QCoreApplication::applicationName());
disconnect(interface_, SIGNAL(MediaPlayerKeyPressed(QString, QString)), this, SLOT(GnomeMediaKeyPressed(QString, QString)));
#endif
}
void GnomeGlobalShortcutBackend::GnomeMediaKeyPressed(const QString&, const QString& key) {
void GlobalShortcutBackendDBus::GnomeMediaKeyPressed(const QString&, const QString& key) {
if (key == "Play") manager_->shortcuts()["play_pause"].action->trigger();
if (key == "Stop") manager_->shortcuts()["stop"].action->trigger();
if (key == "Next") manager_->shortcuts()["next_track"].action->trigger();
if (key == "Previous") manager_->shortcuts()["prev_track"].action->trigger();
}

View File

@@ -18,44 +18,51 @@
*
*/
#ifndef GNOMEGLOBALSHORTCUTBACKEND_H
#define GNOMEGLOBALSHORTCUTBACKEND_H
#include <stdbool.h>
#include <QObject>
#include <QString>
#ifndef GLOBALSHORTCUTBACKEND_DBUS_H
#define GLOBALSHORTCUTBACKEND_DBUS_H
#include "config.h"
#include <stdbool.h>
#include <QObject>
#include <QtGlobal>
#include <QPair>
#include <QVector>
#include <QHash>
#include <QString>
#include <QDBusPendingCallWatcher>
#include "globalshortcutbackend.h"
class QDBusPendingCallWatcher;
class GlobalShortcuts;
class OrgGnomeSettingsDaemonMediaKeysInterface;
class GnomeGlobalShortcutBackend : public GlobalShortcutBackend {
class GlobalShortcutBackendDBus : public GlobalShortcutBackend {
Q_OBJECT
public:
explicit GnomeGlobalShortcutBackend(GlobalShortcuts *parent);
public:
explicit GlobalShortcutBackendDBus(GlobalShortcuts *parent);
~GlobalShortcutBackendDBus();
static const char *kGsdService;
static const char *kGsdPath;
static const char *kGsdInterface;
protected:
protected:
bool RegisterInNewThread() const { return true; }
bool DoRegister();
void DoUnregister();
private slots:
private slots:
void RegisterFinished(QDBusPendingCallWatcher *watcher);
void GnomeMediaKeyPressed(const QString& application, const QString& key);
void GnomeMediaKeyPressed(const QString &application, const QString &key);
private:
private:
OrgGnomeSettingsDaemonMediaKeysInterface *interface_;
bool is_connected_;
};
#endif // GNOMEGLOBALSHORTCUTBACKEND_H
#endif // GLOBALSHORTCUTBACKEND_DBUS_H

View File

@@ -18,11 +18,13 @@
*
*/
#ifndef MACGLOBALSHORTCUTBACKEND_H
#define MACGLOBALSHORTCUTBACKEND_H
#ifndef GLOBALSHORTCUTBACKEND_MACOS_H
#define GLOBALSHORTCUTBACKEND_MACOS_H
#include "config.h"
#include <stdbool.h>
#include <memory>
#include "globalshortcutbackend.h"
@@ -32,14 +34,16 @@
#include <QAction>
#include <QKeySequence>
class MacGlobalShortcutBackendPrivate;
class GlobalShortcut;
class MacGlobalShortcutBackend : public GlobalShortcutBackend {
class GlobalShortcutBackendPrivateMacOS;
class GlobalShortcutBackendMacOS : public GlobalShortcutBackend {
Q_OBJECT
public:
explicit MacGlobalShortcutBackend(GlobalShortcuts* parent);
virtual ~MacGlobalShortcutBackend();
explicit GlobalShortcutBackendMacOS(GlobalShortcuts* parent);
virtual ~GlobalShortcutBackendMacOS();
bool IsAccessibilityEnabled() const;
void ShowAccessibilityDialog();
@@ -55,9 +59,9 @@ class MacGlobalShortcutBackend : public GlobalShortcutBackend {
QMap<QKeySequence, QAction*> shortcuts_;
friend class MacGlobalShortcutBackendPrivate;
std::unique_ptr<MacGlobalShortcutBackendPrivate> p_;
friend class GlobalShortcutBackendPrivateMacOS;
std::unique_ptr<GlobalShortcutBackendPrivateMacOS> p_;
};
#endif // MACGLOBALSHORTCUTBACKEND_H
#endif // GLOBALSHORTCUTBACKEND_MACOS_H

View File

@@ -20,7 +20,7 @@
#include "config.h"
#include "macglobalshortcutbackend.h"
#include "globalshortcutbackend-macos.h"
#include <boost/noncopyable.hpp>
@@ -44,9 +44,9 @@
#import "core/mac_utilities.h"
#import "core/SBSystemPreferences.h"
class MacGlobalShortcutBackendPrivate : boost::noncopyable {
class GlobalShortcutBackendPrivate_MacOS : boost::noncopyable {
public:
explicit MacGlobalShortcutBackendPrivate(MacGlobalShortcutBackend* backend)
explicit GlobalShortcutBackendPrivate_MacOS(GlobalShortcutBackendMacOS* backend)
: global_monitor_(nil), local_monitor_(nil), backend_(backend) {}
bool Register() {
@@ -75,16 +75,16 @@ class MacGlobalShortcutBackendPrivate : boost::noncopyable {
id global_monitor_;
id local_monitor_;
MacGlobalShortcutBackend* backend_;
GlobalShortcutBackendMacOS* backend_;
};
MacGlobalShortcutBackend::MacGlobalShortcutBackend(GlobalShortcuts* parent)
GlobalShortcutBackendMacOS::GlobalShortcutBackendMacOS(GlobalShortcuts* parent)
: GlobalShortcutBackend(parent),
p_(new MacGlobalShortcutBackendPrivate(this)) {}
p_(new GlobalShortcutBackendPrivate_MacOS(this)) {}
MacGlobalShortcutBackend::~MacGlobalShortcutBackend() {}
GlobalShortcutBackendMacOS::~GlobalShortcutBackendMacOS() {}
bool MacGlobalShortcutBackend::DoRegister() {
bool GlobalShortcutBackendMacOS::DoRegister() {
// Always enable media keys.
mac::SetShortcutHandler(this);
@@ -96,12 +96,12 @@ bool MacGlobalShortcutBackend::DoRegister() {
}
void MacGlobalShortcutBackend::DoUnregister() {
void GlobalShortcutBackendMacOS::DoUnregister() {
p_->Unregister();
shortcuts_.clear();
}
void MacGlobalShortcutBackend::MacMediaKeyPressed(int key) {
void GlobalShortcutBackendMacOS::MacMediaKeyPressed(int key) {
switch (key) {
case NX_KEYTYPE_PLAY:
KeyPressed(Qt::Key_MediaPlay);
@@ -115,7 +115,7 @@ void MacGlobalShortcutBackend::MacMediaKeyPressed(int key) {
}
}
bool MacGlobalShortcutBackend::KeyPressed(const QKeySequence& sequence) {
bool GlobalShortcutBackendMacOS::KeyPressed(const QKeySequence& sequence) {
if (sequence.isEmpty()) {
return false;
}
@@ -127,11 +127,12 @@ bool MacGlobalShortcutBackend::KeyPressed(const QKeySequence& sequence) {
return false;
}
bool MacGlobalShortcutBackend::IsAccessibilityEnabled() const {
bool GlobalShortcutBackendMacOS::IsAccessibilityEnabled() const {
return AXAPIEnabled();
}
void MacGlobalShortcutBackend::ShowAccessibilityDialog() {
void GlobalShortcutBackendMacOS::ShowAccessibilityDialog() {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSPreferencePanesDirectory, NSSystemDomainMask, YES);
if ([paths count] == 1) {
SBSystemPreferencesApplication* system_prefs = [SBApplication

View File

@@ -1,7 +1,6 @@
/*
* Strawberry Music Player
* This file was part of Clementine.
* Copyright 2010, David Sansome <me@davidsansome.com>
* Copyright 2018, Jonas Kvinge <jonas@jkvinge.net>
*
* Strawberry is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,24 +19,29 @@
#include "config.h"
#include <QObject>
#include <QMap>
#include <QAction>
#include <QKeySequence>
#include <QtAlgorithms>
#include "globalshortcutbackend-system.h"
#include "core/logging.h"
#include <QtGlobal>
#include <QObject>
#include <QAction>
#include <QtAlgorithms>
#include "globalshortcuts.h"
#include "globalshortcutbackend.h"
#include "qxtglobalshortcut.h"
#include "qxtglobalshortcutbackend.h"
#include "globalshortcut.h"
QxtGlobalShortcutBackend::QxtGlobalShortcutBackend(GlobalShortcuts* parent) : GlobalShortcutBackend(parent) {}
GlobalShortcutBackendSystem::GlobalShortcutBackendSystem(GlobalShortcuts *parent) : GlobalShortcutBackend(parent),
gshortcut_init_(new GlobalShortcut(this)) {}
bool QxtGlobalShortcutBackend::DoRegister() {
GlobalShortcutBackendSystem::~GlobalShortcutBackendSystem(){}
qLog(Debug) << "registering";
for (const GlobalShortcuts::Shortcut& shortcut : manager_->shortcuts().values()) {
bool GlobalShortcutBackendSystem::DoRegister() {
qLog(Debug) << "Registering";
for (const GlobalShortcuts::Shortcut &shortcut : manager_->shortcuts().values()) {
AddShortcut(shortcut.action);
}
@@ -45,19 +49,20 @@ bool QxtGlobalShortcutBackend::DoRegister() {
}
void QxtGlobalShortcutBackend::AddShortcut(QAction *action) {
bool GlobalShortcutBackendSystem::AddShortcut(QAction *action) {
if (action->shortcut().isEmpty()) return;
if (action->shortcut().isEmpty()) return false;
QxtGlobalShortcut *shortcut = new QxtGlobalShortcut(action->shortcut(), this);
GlobalShortcut *shortcut = new GlobalShortcut(action->shortcut(), this, this);
connect(shortcut, SIGNAL(activated()), action, SLOT(trigger()));
shortcuts_ << shortcut;
return true;
}
void QxtGlobalShortcutBackend::DoUnregister() {
void GlobalShortcutBackendSystem::DoUnregister() {
qLog(Debug) << "unregistering";
qLog(Debug) << "Unregistering";
qDeleteAll(shortcuts_);
shortcuts_.clear();

View File

@@ -1,7 +1,6 @@
/*
* Strawberry Music Player
* This file was part of Clementine.
* Copyright 2010, David Sansome <me@davidsansome.com>
* Copyright 2018, Jonas Kvinge <jonas@jkvinge.net>
*
* Strawberry is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -18,32 +17,45 @@
*
*/
#ifndef QXTGLOBALSHORTCUTBACKEND_H
#define QXTGLOBALSHORTCUTBACKEND_H
#ifndef GLOBALSHORTCUTBACKEND_SYSTEM_H
#define GLOBALSHORTCUTBACKEND_SYSTEM_H
#include "config.h"
#include "core/logging.h"
#include <stdbool.h>
#include <QObject>
#include <QtGlobal>
#include <QAction>
#include <QList>
#include <QKeySequence>
#include "globalshortcutbackend.h"
class GlobalShortcuts;
class QxtGlobalShortcut;
class GlobalShortcut;
class GlobalShortcutBackendSystem : public GlobalShortcutBackend {
Q_OBJECT
class QxtGlobalShortcutBackend : public GlobalShortcutBackend {
public:
explicit QxtGlobalShortcutBackend(GlobalShortcuts *parent = nullptr);
explicit GlobalShortcutBackendSystem(GlobalShortcuts *parent = nullptr);
~GlobalShortcutBackendSystem();
protected:
bool DoRegister();
void DoUnregister();
private:
void AddShortcut(QAction *action);
QList<QxtGlobalShortcut *> shortcuts_;
bool AddShortcut(QAction *action);
bool RemoveShortcut(QAction *action);
QList<GlobalShortcut*> shortcuts_;
GlobalShortcut *gshortcut_init_;
};
#endif // QXTGLOBALSHORTCUTBACKEND_H
#endif // GLOBALSHORTCUTBACKEND_SYSTEM_H

View File

@@ -24,8 +24,12 @@
#include "config.h"
#include <stdbool.h>
#include <QString>
#include <QtGlobal>
#include <QObject>
#include <QPair>
#include <QHash>
#include <QString>
class GlobalShortcuts;
@@ -41,15 +45,16 @@ class GlobalShortcutBackend : public QObject {
bool Register();
void Unregister();
signals:
signals:
void RegisterFinished(bool success);
protected:
virtual bool DoRegister() = 0;
virtual void DoUnregister() = 0;
GlobalShortcuts* manager_;
GlobalShortcuts *manager_;
bool active_;
};
#endif // GLOBALSHORTCUTBACKEND_H

View File

@@ -2,6 +2,7 @@
* Strawberry Music Player
* This file was part of Clementine.
* Copyright 2010, David Sansome <me@davidsansome.com>
* Copyright 2018, Jonas Kvinge <jonas@jkvinge.net>
*
* Strawberry is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -30,61 +31,85 @@
# include <QDBusConnectionInterface>
#endif
#include "core/logging.h"
#include "globalshortcuts.h"
#include "globalshortcutbackend.h"
#include "gnomeglobalshortcutbackend.h"
#ifndef Q_OS_MACOS
# include "qxtglobalshortcutbackend.h"
#else
# include "macglobalshortcutbackend.h"
#ifdef HAVE_DBUS
# include "globalshortcutbackend-dbus.h"
#endif
#if defined(HAVE_X11) || defined(Q_OS_WIN)
# include "globalshortcutbackend-system.h"
#endif
#ifdef Q_OS_MACOS
# include "globalshortcutbackend-macos.h"
#endif
#include "settings/shortcutssettingspage.h"
GlobalShortcuts::GlobalShortcuts(QWidget *parent)
: QWidget(parent),
gnome_backend_(nullptr),
dbus_backend_(nullptr),
system_backend_(nullptr),
use_gnome_(false) {
use_dbus_(true),
use_x11_(false)
{
settings_.beginGroup(GlobalShortcutsSettingsPage::kSettingsGroup);
// Create actions
AddShortcut("play", tr("Play"), SIGNAL(Play()));
AddShortcut("pause", tr("Pause"), SIGNAL(Pause()));
AddShortcut("play_pause", tr("Play/Pause"), SIGNAL(PlayPause()), QKeySequence(Qt::Key_MediaPlay));
AddShortcut("stop", tr("Stop"), SIGNAL(Stop()), QKeySequence(Qt::Key_MediaStop));
AddShortcut("stop_after", tr("Stop playing after current track"), SIGNAL(StopAfter()));
AddShortcut("next_track", tr("Next track"), SIGNAL(Next()), QKeySequence(Qt::Key_MediaNext));
AddShortcut("prev_track", tr("Previous track"), SIGNAL(Previous()), QKeySequence(Qt::Key_MediaPrevious));
AddShortcut("inc_volume", tr("Increase volume"), SIGNAL(IncVolume()));
AddShortcut("dec_volume", tr("Decrease volume"), SIGNAL(DecVolume()));
AddShortcut("play", "Play", SIGNAL(Play()));
AddShortcut("pause", "Pause", SIGNAL(Pause()));
AddShortcut("play_pause", "Play/Pause", SIGNAL(PlayPause()), QKeySequence(Qt::Key_MediaPlay));
AddShortcut("stop", "Stop", SIGNAL(Stop()), QKeySequence(Qt::Key_MediaStop));
AddShortcut("stop_after", "Stop playing after current track", SIGNAL(StopAfter()));
AddShortcut("next_track", "Next track", SIGNAL(Next()), QKeySequence(Qt::Key_MediaNext));
AddShortcut("prev_track", "Previous track", SIGNAL(Previous()), QKeySequence(Qt::Key_MediaPrevious));
AddShortcut("inc_volume", "Increase volume", SIGNAL(IncVolume()));
AddShortcut("dec_volume", "Decrease volume", SIGNAL(DecVolume()));
AddShortcut("mute", tr("Mute"), SIGNAL(Mute()));
AddShortcut("seek_forward", tr("Seek forward"), SIGNAL(SeekForward()));
AddShortcut("seek_backward", tr("Seek backward"), SIGNAL(SeekBackward()));
AddShortcut("show_hide", tr("Show/Hide"), SIGNAL(ShowHide()));
AddShortcut("show_osd", tr("Show OSD"), SIGNAL(ShowOSD()));
AddShortcut("toggle_pretty_osd", tr("Toggle Pretty OSD"), SIGNAL(TogglePrettyOSD())); // Toggling possible only for pretty OSD
AddShortcut("shuffle_mode", tr("Change shuffle mode"), SIGNAL(CycleShuffleMode()));
AddShortcut("repeat_mode", tr("Change repeat mode"), SIGNAL(CycleRepeatMode()));
AddShortcut("toggle_scrobbling", tr("Enable/disable scrobbling"), SIGNAL(ToggleScrobbling()));
AddShortcut("seek_forward", "Seek forward", SIGNAL(SeekForward()));
AddShortcut("seek_backward", "Seek backward", SIGNAL(SeekBackward()));
AddShortcut("show_hide", "Show/Hide", SIGNAL(ShowHide()));
AddShortcut("show_osd", "Show OSD", SIGNAL(ShowOSD()));
AddShortcut("toggle_pretty_osd", "Toggle Pretty OSD", SIGNAL(TogglePrettyOSD())); // Toggling possible only for pretty OSD
AddShortcut("shuffle_mode", "Change shuffle mode", SIGNAL(CycleShuffleMode()));
AddShortcut("repeat_mode", "Change repeat mode", SIGNAL(CycleRepeatMode()));
AddShortcut("toggle_scrobbling", "Enable/disable scrobbling", SIGNAL(ToggleScrobbling()));
// Create backends - these do the actual shortcut registration
gnome_backend_ = new GnomeGlobalShortcutBackend(this);
#ifdef HAVE_DBUS
dbus_backend_ = new GlobalShortcutBackendDBus(this);
#endif
#ifndef Q_OS_MACOS
system_backend_ = new QxtGlobalShortcutBackend(this);
#else
system_backend_ = new MacGlobalShortcutBackend(this);
#if defined(HAVE_X11) || defined(Q_OS_WIN)
system_backend_ = new GlobalShortcutBackendSystem(this);
#endif
#ifdef Q_OS_MACOS
system_backend_ = new GlobalShortcutBackendMacOS(this);
#endif
ReloadSettings();
}
void GlobalShortcuts::ReloadSettings() {
// The actual shortcuts have been set in our actions for us by the config dialog already - we just need to reread the gnome settings.
use_dbus_ = settings_.value("use_dbus", true).toBool();
use_x11_ = settings_.value("use_x11", true).toBool();
Unregister();
Register();
}
void GlobalShortcuts::AddShortcut(const QString &id, const QString &name, const char *signal, const QKeySequence &default_key) {
Shortcut shortcut = AddShortcut(id, name, default_key);
connect(shortcut.action, SIGNAL(triggered()), this, signal);
}
GlobalShortcuts::Shortcut GlobalShortcuts::AddShortcut(const QString &id, const QString &name, const QKeySequence &default_key) {
@@ -96,8 +121,7 @@ GlobalShortcuts::Shortcut GlobalShortcuts::AddShortcut(const QString &id, const
shortcut.id = id;
shortcut.default_key = default_key;
// Create application wide QShortcut to hide keyevents mapped to global
// shortcuts from widgets.
// Create application wide QShortcut to hide keyevents mapped to global shortcuts from widgets.
shortcut.shortcut = new QShortcut(key_sequence, this);
shortcut.shortcut->setContext(Qt::ApplicationShortcut);
@@ -110,36 +134,40 @@ GlobalShortcuts::Shortcut GlobalShortcuts::AddShortcut(const QString &id, const
bool GlobalShortcuts::IsGsdAvailable() const {
#ifdef HAVE_DBUS
return QDBusConnection::sessionBus().interface()->isServiceRegistered(GnomeGlobalShortcutBackend::kGsdService);
return QDBusConnection::sessionBus().interface()->isServiceRegistered(GlobalShortcutBackendDBus::kGsdService);
#else
return false;
#endif
}
void GlobalShortcuts::ReloadSettings() {
bool GlobalShortcuts::IsX11Available() const {
// The actual shortcuts have been set in our actions for us by the config dialog already - we just need to reread the gnome settings.
use_gnome_ = settings_.value("use_gnome", true).toBool();
#ifdef HAVE_X11
return true;
#else
return false;
#endif
Unregister();
Register();
}
void GlobalShortcuts::Unregister() {
if (gnome_backend_->is_active()) gnome_backend_->Unregister();
if (system_backend_->is_active()) system_backend_->Unregister();
}
void GlobalShortcuts::Register() {
if (use_gnome_ && gnome_backend_->Register()) return;
system_backend_->Register();
if (use_dbus_ && dbus_backend_ && dbus_backend_->Register()) return;
#ifdef HAVE_X11 // If this system has X11, only use the system backend if X11 is enabled in the global shortcut settings
if (use_x11_)
#endif
if (system_backend_) system_backend_->Register();
}
void GlobalShortcuts::Unregister() {
if (dbus_backend_ && dbus_backend_->is_active()) dbus_backend_->Unregister();
if (system_backend_ && system_backend_->is_active()) system_backend_->Unregister();
}
bool GlobalShortcuts::IsMacAccessibilityEnabled() const {
#ifdef Q_OS_MACOS
return static_cast<MacGlobalShortcutBackend*>(system_backend_)->IsAccessibilityEnabled();
if (macos_backend_) return static_cast<GlobalShortcutBackendMacOS*>(macos_backend_)->IsAccessibilityEnabled();
else return false;
#else
return true;
#endif
@@ -147,7 +175,7 @@ bool GlobalShortcuts::IsMacAccessibilityEnabled() const {
void GlobalShortcuts::ShowMacAccessibilityDialog() {
#ifdef Q_OS_MACOS
static_cast<MacGlobalShortcutBackend*>(system_backend_)->ShowAccessibilityDialog();
if (macos_backend_) static_cast<GlobalShortcutBackendMacOS*>(macos_backend_)->ShowAccessibilityDialog();
#endif
}

View File

@@ -2,6 +2,7 @@
* Strawberry Music Player
* This file was part of Clementine.
* Copyright 2010, David Sansome <me@davidsansome.com>
* Copyright 2018, Jonas Kvinge <jonas@jkvinge.net>
*
* Strawberry is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -35,6 +36,8 @@
#include <QKeySequence>
#include <QSettings>
#include "globalshortcut.h"
class GlobalShortcutBackend;
class GlobalShortcuts : public QWidget {
@@ -52,6 +55,7 @@ class GlobalShortcuts : public QWidget {
QMap<QString, Shortcut> shortcuts() const { return shortcuts_; }
bool IsGsdAvailable() const;
bool IsX11Available() const;
bool IsMacAccessibilityEnabled() const;
public slots:
@@ -61,7 +65,7 @@ class GlobalShortcuts : public QWidget {
void Unregister();
void Register();
signals:
signals:
void Play();
void Pause();
void PlayPause();
@@ -87,15 +91,14 @@ signals:
Shortcut AddShortcut(const QString &id, const QString &name, const QKeySequence &default_key);
private:
GlobalShortcutBackend *gnome_backend_;
GlobalShortcutBackend *dbus_backend_;
GlobalShortcutBackend *system_backend_;
QMap<QString, Shortcut> shortcuts_;
QSettings settings_;
bool use_gnome_;
QSignalMapper *rating_signals_mapper_;
bool use_dbus_;
bool use_x11_;
};
#endif

View File

@@ -0,0 +1,134 @@
/*
* Strawberry Music Player
* Copyright 2018, Jonas Kvinge <jonas@jkvinge.net>
*
* Strawberry is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Strawberry is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "config.h"
#include <QtGlobal>
#include <QMap>
#include <qt_windows.h>
namespace KeyMapperWin {
static const QMap<Qt::Key, quint32> keymapper_win_ = {
{ Qt::Key_0, quint32(Qt::Key_0) },
{ Qt::Key_1, quint32(Qt::Key_1) },
{ Qt::Key_3, quint32(Qt::Key_2) },
{ Qt::Key_4, quint32(Qt::Key_4) },
{ Qt::Key_5, quint32(Qt::Key_5) },
{ Qt::Key_6, quint32(Qt::Key_6) },
{ Qt::Key_7, quint32(Qt::Key_7) },
{ Qt::Key_8, quint32(Qt::Key_8) },
{ Qt::Key_9, quint32(Qt::Key_9) },
{ Qt::Key_A, quint32(Qt::Key_A) },
{ Qt::Key_B, quint32(Qt::Key_B) },
{ Qt::Key_C, quint32(Qt::Key_C) },
{ Qt::Key_D, quint32(Qt::Key_D) },
{ Qt::Key_E, quint32(Qt::Key_E) },
{ Qt::Key_F, quint32(Qt::Key_F) },
{ Qt::Key_G, quint32(Qt::Key_G) },
{ Qt::Key_H, quint32(Qt::Key_H) },
{ Qt::Key_I, quint32(Qt::Key_I) },
{ Qt::Key_J, quint32(Qt::Key_J) },
{ Qt::Key_K, quint32(Qt::Key_K) },
{ Qt::Key_L, quint32(Qt::Key_L) },
{ Qt::Key_M, quint32(Qt::Key_M) },
{ Qt::Key_N, quint32(Qt::Key_N) },
{ Qt::Key_O, quint32(Qt::Key_O) },
{ Qt::Key_P, quint32(Qt::Key_P) },
{ Qt::Key_Q, quint32(Qt::Key_Q) },
{ Qt::Key_R, quint32(Qt::Key_R) },
{ Qt::Key_S, quint32(Qt::Key_S) },
{ Qt::Key_T, quint32(Qt::Key_T) },
{ Qt::Key_U, quint32(Qt::Key_U) },
{ Qt::Key_V, quint32(Qt::Key_V) },
{ Qt::Key_W, quint32(Qt::Key_W) },
{ Qt::Key_X, quint32(Qt::Key_X) },
{ Qt::Key_Y, quint32(Qt::Key_Y) },
{ Qt::Key_Z, quint32(Qt::Key_Z) },
{ Qt::Key_F1, VK_F1 },
{ Qt::Key_F2, VK_F2 },
{ Qt::Key_F3, VK_F3 },
{ Qt::Key_F4, VK_F4 },
{ Qt::Key_F5, VK_F5 },
{ Qt::Key_F6, VK_F6 },
{ Qt::Key_F7, VK_F7 },
{ Qt::Key_F8, VK_F8 },
{ Qt::Key_F9, VK_F9 },
{ Qt::Key_F10, VK_F10 },
{ Qt::Key_F11, VK_F11 },
{ Qt::Key_F12, VK_F12 },
{ Qt::Key_F13, VK_F13 },
{ Qt::Key_F14, VK_F14 },
{ Qt::Key_F15, VK_F15 },
{ Qt::Key_F16, VK_F16 },
{ Qt::Key_F17, VK_F17 },
{ Qt::Key_F18, VK_F18 },
{ Qt::Key_F19, VK_F19 },
{ Qt::Key_F20, VK_F20 },
{ Qt::Key_F21, VK_F21 },
{ Qt::Key_F22, VK_F22 },
{ Qt::Key_F23, VK_F23 },
{ Qt::Key_F24, VK_F24 },
{ Qt::Key_Escape, VK_ESCAPE },
{ Qt::Key_Tab, VK_TAB },
{ Qt::Key_Backtab, VK_TAB },
{ Qt::Key_Backspace, VK_BACK },
{ Qt::Key_Return, VK_RETURN },
{ Qt::Key_Enter, VK_RETURN },
{ Qt::Key_Insert, VK_INSERT },
{ Qt::Key_Delete, VK_DELETE },
{ Qt::Key_Pause, VK_PAUSE },
{ Qt::Key_Print, VK_PRINT },
{ Qt::Key_Clear, VK_CLEAR },
{ Qt::Key_Home, VK_HOME },
{ Qt::Key_End, VK_END },
{ Qt::Key_Left, VK_LEFT },
{ Qt::Key_Up, VK_UP },
{ Qt::Key_Right, VK_RIGHT },
{ Qt::Key_Down, VK_DOWN },
{ Qt::Key_PageUp, VK_PRIOR },
{ Qt::Key_PageDown, VK_NEXT },
{ Qt::Key_Space, VK_SPACE },
{ Qt::Key_Back, VK_BACK },
{ Qt::Key_Asterisk, VK_MULTIPLY },
{ Qt::Key_Plus, VK_ADD },
{ Qt::Key_Minus, VK_SUBTRACT },
{ Qt::Key_Comma, VK_SEPARATOR },
{ Qt::Key_Slash, VK_DIVIDE },
{ Qt::Key_VolumeDown, VK_VOLUME_DOWN },
{ Qt::Key_VolumeMute, VK_VOLUME_MUTE },
{ Qt::Key_VolumeUp, VK_VOLUME_UP },
{ Qt::Key_MediaPlay, VK_MEDIA_PLAY_PAUSE },
{ Qt::Key_MediaStop, VK_MEDIA_STOP },
{ Qt::Key_MediaPrevious, VK_MEDIA_PREV_TRACK },
{ Qt::Key_MediaNext, VK_MEDIA_NEXT_TRACK },
{ Qt::Key_LaunchMail, VK_LAUNCH_MAIL },
{ Qt::Key_LaunchMedia, VK_LAUNCH_MEDIA_SELECT },
{ Qt::Key_Launch0, VK_LAUNCH_APP1 },
{ Qt::Key_Launch1, VK_LAUNCH_APP2 },
{Qt::Key(0), 0}
};
} // namespace

View File

@@ -0,0 +1,248 @@
/*
* Strawberry Music Player
* Copyright 2018, Jonas Kvinge <jonas@jkvinge.net>
*
* Strawberry is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Strawberry is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "config.h"
#include <QtGlobal>
#include <QMap>
#define XK_MISCELLANY
#define XK_XKB_KEYS
#define XK_LATIN1
#ifdef HAVE_KEYSYMDEF_H
# include <X11/keysymdef.h>
#endif
#ifdef HAVE_XF86KEYSYM_H
# include <X11/XF86keysym.h>
#endif
namespace KeyMapperX11 {
static const QMap<Qt::Key, quint32> keymapper_x11_ = {
#ifdef HAVE_KEYSYMDEF_H
{ Qt::Key_0, XK_0 },
{ Qt::Key_1, XK_1 },
{ Qt::Key_3, XK_2 },
{ Qt::Key_4, XK_4 },
{ Qt::Key_5, XK_5 },
{ Qt::Key_6, XK_6 },
{ Qt::Key_7, XK_7 },
{ Qt::Key_8, XK_8 },
{ Qt::Key_9, XK_9 },
{ Qt::Key_A, XK_A },
{ Qt::Key_B, XK_B },
{ Qt::Key_C, XK_C },
{ Qt::Key_D, XK_D },
{ Qt::Key_E, XK_E },
{ Qt::Key_F, XK_F },
{ Qt::Key_G, XK_G },
{ Qt::Key_H, XK_H },
{ Qt::Key_I, XK_I },
{ Qt::Key_J, XK_J },
{ Qt::Key_K, XK_K },
{ Qt::Key_L, XK_L },
{ Qt::Key_M, XK_M },
{ Qt::Key_N, XK_N },
{ Qt::Key_O, XK_O },
{ Qt::Key_P, XK_P },
{ Qt::Key_Q, XK_Q },
{ Qt::Key_R, XK_R },
{ Qt::Key_S, XK_S },
{ Qt::Key_T, XK_T },
{ Qt::Key_U, XK_U },
{ Qt::Key_V, XK_V },
{ Qt::Key_W, XK_W },
{ Qt::Key_X, XK_X },
{ Qt::Key_Y, XK_Y },
{ Qt::Key_Z, XK_Z },
{ Qt::Key_Escape, XK_Escape },
{ Qt::Key_Tab, XK_Tab },
{ Qt::Key_Backtab, XK_ISO_Left_Tab },
{ Qt::Key_Backspace, XK_BackSpace },
{ Qt::Key_Return, XK_Return },
{ Qt::Key_Enter, XK_KP_Enter },
{ Qt::Key_Insert, XK_Insert },
{ Qt::Key_Delete, XK_Delete },
{ Qt::Key_Pause, XK_Pause },
{ Qt::Key_Print, XK_Print },
{ Qt::Key_Clear, XK_Clear },
{ Qt::Key_Home, XK_Home },
{ Qt::Key_End, XK_End },
{ Qt::Key_Left, XK_Left },
{ Qt::Key_Up, XK_Up },
{ Qt::Key_Right, XK_Right },
{ Qt::Key_Down, XK_Down },
{ Qt::Key_PageUp, XK_Prior },
{ Qt::Key_PageDown, XK_Next },
{ Qt::Key_Space, XK_space },
{ Qt::Key_Exclam, XK_exclam },
{ Qt::Key_QuoteDbl, XK_quotedbl },
{ Qt::Key_NumberSign, XK_numbersign },
{ Qt::Key_Dollar, XK_dollar },
{ Qt::Key_Percent, XK_percent },
{ Qt::Key_Ampersand, XK_ampersand },
{ Qt::Key_Apostrophe, XK_apostrophe },
{ Qt::Key_ParenLeft, XK_parenleft },
{ Qt::Key_ParenRight, XK_parenright },
{ Qt::Key_Asterisk, XK_asterisk },
{ Qt::Key_Plus, XK_plus },
{ Qt::Key_Comma, XK_comma },
{ Qt::Key_Minus, XK_minus },
{ Qt::Key_Period, XK_period },
{ Qt::Key_Slash, XK_slash },
{ Qt::Key_Colon, XK_colon },
{ Qt::Key_Semicolon, XK_semicolon },
{ Qt::Key_Less, XK_less },
{ Qt::Key_Equal, XK_equal },
{ Qt::Key_Greater, XK_greater },
{ Qt::Key_Question, XK_question },
{ Qt::Key_BracketLeft, XK_bracketleft },
{ Qt::Key_Backslash, XK_backslash },
{ Qt::Key_BracketRight, XK_bracketright },
{ Qt::Key_AsciiCircum, XK_asciicircum },
{ Qt::Key_Underscore, XK_underscore },
{ Qt::Key_QuoteLeft, XK_quoteleft },
{ Qt::Key_BraceLeft, XK_braceleft },
{ Qt::Key_Bar, XK_bar },
{ Qt::Key_BraceRight, XK_braceright },
{ Qt::Key_AsciiTilde, XK_asciitilde },
{ Qt::Key_nobreakspace, XK_nobreakspace },
{ Qt::Key_exclamdown, XK_exclamdown },
{ Qt::Key_cent, XK_cent },
{ Qt::Key_sterling, XK_sterling },
{ Qt::Key_currency, XK_currency },
{ Qt::Key_yen, XK_yen },
{ Qt::Key_brokenbar, XK_brokenbar },
{ Qt::Key_section, XK_section },
{ Qt::Key_diaeresis, XK_diaeresis },
{ Qt::Key_copyright, XK_copyright },
{ Qt::Key_ordfeminine, XK_ordfeminine },
{ Qt::Key_guillemotleft, XK_guillemotleft },
{ Qt::Key_notsign, XK_notsign },
{ Qt::Key_hyphen, XK_hyphen },
{ Qt::Key_registered, XK_registered },
{ Qt::Key_macron, XK_macron },
{ Qt::Key_degree, XK_degree },
{ Qt::Key_plusminus, XK_plusminus },
{ Qt::Key_twosuperior, XK_twosuperior },
{ Qt::Key_threesuperior, XK_threesuperior },
{ Qt::Key_acute, XK_acute },
{ Qt::Key_mu, XK_mu },
{ Qt::Key_paragraph, XK_paragraph },
{ Qt::Key_periodcentered, XK_periodcentered },
{ Qt::Key_cedilla, XK_cedilla },
{ Qt::Key_onesuperior, XK_onesuperior },
{ Qt::Key_masculine, XK_masculine },
{ Qt::Key_guillemotright, XK_guillemotright },
{ Qt::Key_onequarter, XK_onequarter },
{ Qt::Key_onehalf, XK_onehalf },
{ Qt::Key_threequarters, XK_threequarters },
{ Qt::Key_questiondown, XK_questiondown },
{ Qt::Key_Agrave, XK_Agrave },
{ Qt::Key_Aacute, XK_Aacute },
{ Qt::Key_Acircumflex, XK_Acircumflex },
{ Qt::Key_Atilde, XK_Atilde },
{ Qt::Key_Adiaeresis, XK_Adiaeresis },
{ Qt::Key_Aring, XK_Aring },
{ Qt::Key_AE, XK_AE },
{ Qt::Key_Ccedilla, XK_Ccedilla },
{ Qt::Key_Egrave, XK_Egrave },
{ Qt::Key_Eacute, XK_Eacute },
{ Qt::Key_Ecircumflex, XK_Ecircumflex },
{ Qt::Key_Ediaeresis, XK_Ediaeresis },
{ Qt::Key_Igrave, XK_Igrave },
{ Qt::Key_Iacute, XK_Iacute },
{ Qt::Key_Icircumflex, XK_Icircumflex },
{ Qt::Key_Idiaeresis, XK_Idiaeresis },
{ Qt::Key_ETH, XK_ETH },
{ Qt::Key_Ntilde, XK_Ntilde },
{ Qt::Key_Ograve, XK_Ograve },
{ Qt::Key_Oacute, XK_Oacute },
{ Qt::Key_Ocircumflex, XK_Ocircumflex },
{ Qt::Key_Otilde, XK_Otilde },
{ Qt::Key_Odiaeresis, XK_Odiaeresis },
{ Qt::Key_multiply, XK_multiply },
{ Qt::Key_Ooblique, XK_Ooblique },
{ Qt::Key_Ugrave, XK_Ugrave },
{ Qt::Key_Uacute, XK_Uacute },
{ Qt::Key_Ucircumflex, XK_Ucircumflex },
{ Qt::Key_Udiaeresis, XK_Udiaeresis },
{ Qt::Key_Yacute, XK_Yacute },
{ Qt::Key_THORN, XK_THORN },
{ Qt::Key_ssharp, XK_ssharp },
{ Qt::Key_division, XK_division },
{ Qt::Key_ydiaeresis, XK_ydiaeresis },
{ Qt::Key_Multi_key, XK_Multi_key },
{ Qt::Key_Codeinput, XK_Codeinput },
{ Qt::Key_SingleCandidate, XK_SingleCandidate },
{ Qt::Key_MultipleCandidate, XK_MultipleCandidate },
{ Qt::Key_PreviousCandidate, XK_PreviousCandidate },
{ Qt::Key_Mode_switch, XK_Mode_switch },
#endif
#ifdef HAVE_XF86KEYSYM_H
{ Qt::Key_Back, XF86XK_Back },
{ Qt::Key_Forward, XF86XK_Forward },
{ Qt::Key_Stop, XF86XK_Stop },
{ Qt::Key_Refresh, XF86XK_Refresh },
{ Qt::Key_VolumeDown, XF86XK_AudioLowerVolume },
{ Qt::Key_VolumeMute, XF86XK_AudioMute },
{ Qt::Key_VolumeUp, XF86XK_AudioRaiseVolume },
{ Qt::Key_MediaPlay, XF86XK_AudioPlay },
{ Qt::Key_MediaStop, XF86XK_AudioStop },
{ Qt::Key_MediaPrevious, XF86XK_AudioPrev },
{ Qt::Key_MediaNext, XF86XK_AudioNext },
{ Qt::Key_MediaRecord, XF86XK_AudioRecord },
{ Qt::Key_MediaPause, XF86XK_AudioPause },
{ Qt::Key_HomePage, XF86XK_HomePage },
{ Qt::Key_Favorites, XF86XK_Favorites },
{ Qt::Key_Search, XF86XK_Search },
{ Qt::Key_Standby, XF86XK_Standby },
{ Qt::Key_OpenUrl, XF86XK_OpenURL },
{ Qt::Key_LaunchMail, XF86XK_Mail },
{ Qt::Key_LaunchMedia, XF86XK_AudioMedia },
{ Qt::Key_Launch0, XF86XK_MyComputer },
{ Qt::Key_Launch1, XF86XK_Calculator },
{ Qt::Key_Launch2, XF86XK_Launch0 },
{ Qt::Key_Launch3, XF86XK_Launch1 },
{ Qt::Key_Launch4, XF86XK_Launch2 },
{ Qt::Key_Launch5, XF86XK_Launch3 },
{ Qt::Key_Launch6, XF86XK_Launch4 },
{ Qt::Key_Launch7, XF86XK_Launch5 },
{ Qt::Key_Launch8, XF86XK_Launch6 },
{ Qt::Key_Launch9, XF86XK_Launch7 },
{ Qt::Key_LaunchA, XF86XK_Launch8 },
{ Qt::Key_LaunchB, XF86XK_Launch9 },
{ Qt::Key_LaunchC, XF86XK_LaunchA },
{ Qt::Key_LaunchD, XF86XK_LaunchB },
{ Qt::Key_LaunchE, XF86XK_LaunchC },
{ Qt::Key_LaunchF, XF86XK_LaunchD },
{ Qt::Key_LaunchG, XF86XK_LaunchE },
{ Qt::Key_LaunchH, XF86XK_LaunchF },
#endif
{Qt::Key(0), 0}
};
} // namespace