Initial commit.

This commit is contained in:
Jonas Kvinge
2018-02-27 18:06:05 +01:00
parent 85d9664df7
commit b2b1ba7abe
1393 changed files with 177311 additions and 1 deletions

View File

@@ -0,0 +1,40 @@
/*
* Strawberry Music Player
* This file was part of Clementine.
* Copyright 2010, David Sansome <me@davidsansome.com>
*
* 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 "globalshortcutbackend.h"
#include "globalshortcuts.h"
GlobalShortcutBackend::GlobalShortcutBackend(GlobalShortcuts *parent)
: QObject(parent), manager_(parent), active_(false) {}
bool GlobalShortcutBackend::Register() {
bool ret = DoRegister();
if (ret) active_ = true;
return ret;
}
void GlobalShortcutBackend::Unregister() {
DoUnregister();
active_ = false;
}

View File

@@ -0,0 +1,54 @@
/*
* Strawberry Music Player
* This file was part of Clementine.
* Copyright 2010, David Sansome <me@davidsansome.com>
*
* 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 GLOBALSHORTCUTBACKEND_H
#define GLOBALSHORTCUTBACKEND_H
#include "config.h"
#include <QObject>
class GlobalShortcuts;
class GlobalShortcutBackend : public QObject {
Q_OBJECT
public:
explicit GlobalShortcutBackend(GlobalShortcuts *parent = nullptr);
virtual ~GlobalShortcutBackend() {}
bool is_active() const { return active_; }
bool Register();
void Unregister();
signals:
void RegisterFinished(bool success);
protected:
virtual bool DoRegister() = 0;
virtual void DoUnregister() = 0;
GlobalShortcuts* manager_;
bool active_;
};
#endif // GLOBALSHORTCUTBACKEND_H

View File

@@ -0,0 +1,99 @@
/*
* Strawberry Music Player
* This file was part of Clementine.
* Copyright 2010, David Sansome <me@davidsansome.com>
*
* 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 "globalshortcutgrabber.h"
#include "ui_globalshortcutgrabber.h"
#include <QtDebug>
#include <QKeyEvent>
GlobalShortcutGrabber::GlobalShortcutGrabber(QWidget *parent)
: QDialog(parent), ui_(new Ui::GlobalShortcutGrabber) {
ui_->setupUi(this);
modifier_keys_ << Qt::Key_Shift << Qt::Key_Control << Qt::Key_Meta << Qt::Key_Alt << Qt::Key_AltGr;
}
GlobalShortcutGrabber::~GlobalShortcutGrabber() {
delete ui_;
}
QKeySequence GlobalShortcutGrabber::GetKey(const QString &name) {
ui_->label->setText(tr("Press a key combination to use for %1...").arg(name));
ui_->combo->clear();
ret_ = QKeySequence();
if (exec() == QDialog::Rejected) return QKeySequence();
return ret_;
}
void GlobalShortcutGrabber::showEvent(QShowEvent *e) {
grabKeyboard();
QDialog::showEvent(e);
}
void GlobalShortcutGrabber::hideEvent(QHideEvent *e) {
releaseKeyboard();
QDialog::hideEvent(e);
}
void GlobalShortcutGrabber::grabKeyboard() {
#ifdef Q_OS_DARWIN
SetupMacEventHandler();
#endif
QDialog::grabKeyboard();
}
void GlobalShortcutGrabber::releaseKeyboard() {
#ifdef Q_OS_DARWIN
TeardownMacEventHandler();
#endif
QDialog::releaseKeyboard();
}
bool GlobalShortcutGrabber::event(QEvent *e) {
if (e->type() == QEvent::ShortcutOverride) {
QKeyEvent *ke = static_cast<QKeyEvent*>(e);
if (modifier_keys_.contains(ke->key()))
ret_ = QKeySequence(ke->modifiers());
else
ret_ = QKeySequence(ke->modifiers() | ke->key());
UpdateText();
if (!modifier_keys_.contains(ke->key())) accept();
return true;
}
return QDialog::event(e);
}
void GlobalShortcutGrabber::UpdateText() {
ui_->combo->setText("<b>" + ret_.toString(QKeySequence::NativeText) + "</b>");
}

View File

@@ -0,0 +1,67 @@
/*
* Strawberry Music Player
* This file was part of Clementine.
* Copyright 2010, David Sansome <me@davidsansome.com>
*
* 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 GLOBALSHORTCUTGRABBER_H
#define GLOBALSHORTCUTGRABBER_H
#include "config.h"
#include <QDialog>
class MacMonitorWrapper;
class Ui_GlobalShortcutGrabber;
#ifdef __OBJC__
@class NSEvent;
#else
class NSEvent;
#endif
class GlobalShortcutGrabber : public QDialog {
Q_OBJECT
public:
GlobalShortcutGrabber(QWidget *parent = nullptr);
~GlobalShortcutGrabber();
QKeySequence GetKey(const QString& name);
protected:
bool event(QEvent *);
void showEvent(QShowEvent *);
void hideEvent(QHideEvent *);
void grabKeyboard();
void releaseKeyboard();
private:
void UpdateText();
void SetupMacEventHandler();
void TeardownMacEventHandler();
bool HandleMacEvent(NSEvent*);
Ui_GlobalShortcutGrabber *ui_;
QKeySequence ret_;
QList<int> modifier_keys_;
MacMonitorWrapper *wrapper_;
};
#endif // GLOBALSHORTCUTGRABBER_H

View File

@@ -0,0 +1,62 @@
/*
* Strawberry Music Player
* This file was part of Clementine.
* Copyright 2011, David Sansome <me@davidsansome.com>
*
* 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 "globalshortcutgrabber.h"
#import <AppKit/NSEvent.h>
#import <AppKit/NSGraphics.h>
#import <AppKit/NSViewController.h>
#import <QuartzCore/CALayer.h>
#include <QKeySequence>
#import "core/mac_utilities.h"
class MacMonitorWrapper {
public:
explicit MacMonitorWrapper(id monitor) : local_monitor_(monitor) {}
~MacMonitorWrapper() { [NSEvent removeMonitor:local_monitor_]; }
private:
id local_monitor_;
Q_DISABLE_COPY(MacMonitorWrapper);
};
bool GlobalShortcutGrabber::HandleMacEvent(NSEvent* event) {
ret_ = mac::KeySequenceFromNSEvent(event);
UpdateText();
if ([[event charactersIgnoringModifiers] length] != 0) {
accept();
return true;
}
return ret_ == QKeySequence(Qt::Key_Escape);
}
void GlobalShortcutGrabber::SetupMacEventHandler() {
id monitor = [NSEvent addLocalMonitorForEventsMatchingMask: NSKeyDownMask handler:^(NSEvent* event) {
return HandleMacEvent(event) ? event : nil;
}];
wrapper_ = new MacMonitorWrapper(monitor);
}
void GlobalShortcutGrabber::TeardownMacEventHandler() { delete wrapper_; }

View File

@@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>GlobalShortcutGrabber</class>
<widget class="QDialog" name="GlobalShortcutGrabber">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>418</width>
<height>110</height>
</rect>
</property>
<property name="windowTitle">
<string>Press a key</string>
</property>
<property name="windowIcon">
<iconset resource="../../data/data.qrc">
<normaloff>:/icons/64x64/strawberry.png</normaloff>:/icons/64x64/strawberry.png</iconset>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Press a key combination to use for %1...</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="combo">
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../../data/data.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>GlobalShortcutGrabber</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>GlobalShortcutGrabber</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -0,0 +1,151 @@
/*
* Strawberry Music Player
* This file was part of Clementine.
* Copyright 2010, David Sansome <me@davidsansome.com>
*
* 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 "globalshortcuts.h"
#include "gnomeglobalshortcutbackend.h"
#include "macglobalshortcutbackend.h"
#include "qxtglobalshortcutbackend.h"
#include "settings/shortcutssettingspage.h"
#include "core/mac_startup.h"
#include <QAction>
#include <QShortcut>
#include <QSignalMapper>
#include <QtDebug>
#ifdef QT_DBUS_LIB
#include <QtDBus>
#endif
GlobalShortcuts::GlobalShortcuts(QWidget* parent)
: QWidget(parent),
gnome_backend_(nullptr),
system_backend_(nullptr),
use_gnome_(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("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()));
// Create backends - these do the actual shortcut registration
gnome_backend_ = new GnomeGlobalShortcutBackend(this);
#ifndef Q_OS_DARWIN
system_backend_ = new QxtGlobalShortcutBackend(this);
#else
system_backend_ = new MacGlobalShortcutBackend(this);
#endif
ReloadSettings();
}
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) {
Shortcut shortcut;
shortcut.action = new QAction(name, this);
QKeySequence key_sequence = QKeySequence::fromString(settings_.value(id, default_key.toString()).toString());
shortcut.action->setShortcut(key_sequence);
shortcut.id = id;
shortcut.default_key = default_key;
// 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);
shortcuts_[id] = shortcut;
return shortcut;
}
bool GlobalShortcuts::IsGsdAvailable() const {
#ifdef QT_DBUS_LIB
return QDBusConnection::sessionBus().interface()->isServiceRegistered(
GnomeGlobalShortcutBackend::kGsdService);
#else // QT_DBUS_LIB
return false;
#endif
}
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_gnome_ = settings_.value("use_gnome", true).toBool();
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();
}
bool GlobalShortcuts::IsMacAccessibilityEnabled() const {
#ifdef Q_OS_MAC
return static_cast<MacGlobalShortcutBackend*>(system_backend_)->IsAccessibilityEnabled();
#else
return true;
#endif
}
void GlobalShortcuts::ShowMacAccessibilityDialog() {
#ifdef Q_OS_MAC
static_cast<MacGlobalShortcutBackend*>(system_backend_)->ShowAccessibilityDialog();
#endif
}

View File

@@ -0,0 +1,97 @@
/*
* Strawberry Music Player
* This file was part of Clementine.
* Copyright 2010, David Sansome <me@davidsansome.com>
*
* 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 GLOBALSHORTCUTS_H
#define GLOBALSHORTCUTS_H
#include "config.h"
#include <QKeySequence>
#include <QMap>
#include <QSettings>
#include <QWidget>
class QAction;
class QShortcut;
class GlobalShortcutBackend;
class QSignalMapper;
class GlobalShortcuts : public QWidget {
Q_OBJECT
public:
explicit GlobalShortcuts(QWidget* parent = nullptr);
struct Shortcut {
QString id;
QKeySequence default_key;
QAction *action;
QShortcut *shortcut;
};
QMap<QString, Shortcut> shortcuts() const { return shortcuts_; }
bool IsGsdAvailable() const;
bool IsMacAccessibilityEnabled() const;
public slots:
void ReloadSettings();
void ShowMacAccessibilityDialog();
void Unregister();
void Register();
signals:
void Play();
void Pause();
void PlayPause();
void Stop();
void StopAfter();
void Next();
void Previous();
void IncVolume();
void DecVolume();
void Mute();
void SeekForward();
void SeekBackward();
void ShowHide();
void ShowOSD();
void TogglePrettyOSD();
void CycleShuffleMode();
void CycleRepeatMode();
void RemoveCurrentSong();
private:
void AddShortcut(const QString &id, const QString &name, const char *signal, const QKeySequence &default_key = QKeySequence(0));
Shortcut AddShortcut(const QString &id, const QString &name, const QKeySequence &default_key);
private:
GlobalShortcutBackend *gnome_backend_;
GlobalShortcutBackend *system_backend_;
QMap<QString, Shortcut> shortcuts_;
QSettings settings_;
bool use_gnome_;
QSignalMapper *rating_signals_mapper_;
};
#endif

View File

@@ -0,0 +1,113 @@
/*
* Strawberry Music Player
* This file was part of Clementine.
* Copyright 2010, David Sansome <me@davidsansome.com>
*
* 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 "gnomeglobalshortcutbackend.h"
#include "globalshortcuts.h"
#include "core/closure.h"
#include "core/logging.h"
#ifdef QT_DBUS_LIB
#include "dbus/gnomesettingsdaemon.h"
#endif
#include <QAction>
#include <QCoreApplication>
#include <QDateTime>
#include <QtDebug>
#ifdef QT_DBUS_LIB
#include <QtDBus>
#endif
const char *GnomeGlobalShortcutBackend::kGsdService = "org.gnome.SettingsDaemon";
const char *GnomeGlobalShortcutBackend::kGsdPath = "/org/gnome/SettingsDaemon/MediaKeys";
const char *GnomeGlobalShortcutBackend::kGsdInterface = "org.gnome.SettingsDaemon.MediaKeys";
GnomeGlobalShortcutBackend::GnomeGlobalShortcutBackend(GlobalShortcuts *parent)
: GlobalShortcutBackend(parent),
interface_(nullptr),
is_connected_(false) {}
bool GnomeGlobalShortcutBackend::DoRegister() {
#ifdef QT_DBUS_LIB
qLog(Debug) << "registering";
// Check if the GSD service is available
if (!QDBusConnection::sessionBus().interface()->isServiceRegistered(kGsdService)) {
qLog(Warning) << "gnome settings daemon not registered";
return false;
}
if (!interface_) {
interface_ = new OrgGnomeSettingsDaemonMediaKeysInterface(kGsdService, kGsdPath, QDBusConnection::sessionBus(), this);
}
QDBusPendingReply<> reply = interface_->GrabMediaPlayerKeys(QCoreApplication::applicationName(), QDateTime::currentDateTime().toTime_t());
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
NewClosure(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(RegisterFinished(QDBusPendingCallWatcher*)), watcher);
return true;
#else // QT_DBUS_LIB
qLog(Warning) << "dbus not available";
return false;
#endif
}
void GnomeGlobalShortcutBackend::RegisterFinished(QDBusPendingCallWatcher *watcher) {
#ifdef QT_DBUS_LIB
QDBusMessage reply = watcher->reply();
watcher->deleteLater();
if (reply.type() == QDBusMessage::ErrorMessage) {
qLog(Warning) << "Failed to grab media keys" << reply.errorName() <<reply.errorMessage();
return;
}
connect(interface_, SIGNAL(MediaPlayerKeyPressed(QString, QString)), this, SLOT(GnomeMediaKeyPressed(QString, QString)));
is_connected_ = true;
qLog(Debug) << "registered";
#endif // QT_DBUS_LIB
}
void GnomeGlobalShortcutBackend::DoUnregister() {
qLog(Debug) << "unregister";
#ifdef QT_DBUS_LIB
// Check if the GSD service is available
if (!QDBusConnection::sessionBus().interface()->isServiceRegistered(kGsdService))
return;
if (!interface_ || !is_connected_) return;
is_connected_ = false;
interface_->ReleaseMediaPlayerKeys(QCoreApplication::applicationName());
disconnect(interface_, SIGNAL(MediaPlayerKeyPressed(QString,QString)), this, SLOT(GnomeMediaKeyPressed(QString,QString)));
#endif
}
void GnomeGlobalShortcutBackend::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

@@ -0,0 +1,58 @@
/*
* Strawberry Music Player
* This file was part of Clementine.
* Copyright 2010, David Sansome <me@davidsansome.com>
*
* 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 GNOMEGLOBALSHORTCUTBACKEND_H
#define GNOMEGLOBALSHORTCUTBACKEND_H
#include "config.h"
#include "globalshortcutbackend.h"
class OrgGnomeSettingsDaemonMediaKeysInterface;
class QDBusPendingCallWatcher;
class GnomeGlobalShortcutBackend : public GlobalShortcutBackend {
Q_OBJECT
public:
explicit GnomeGlobalShortcutBackend(GlobalShortcuts *parent);
static const char *kGsdService;
static const char *kGsdPath;
static const char *kGsdInterface;
protected:
bool RegisterInNewThread() const { return true; }
bool DoRegister();
void DoUnregister();
private slots:
void RegisterFinished(QDBusPendingCallWatcher *watcher);
void GnomeMediaKeyPressed(const QString& application, const QString& key);
private:
OrgGnomeSettingsDaemonMediaKeysInterface *interface_;
bool is_connected_;
};
#endif // GNOMEGLOBALSHORTCUTBACKEND_H

View File

@@ -0,0 +1,62 @@
/*
* Strawberry Music Player
* This file was part of Clementine.
* Copyright 2010, David Sansome <me@davidsansome.com>
*
* 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 MACGLOBALSHORTCUTBACKEND_H
#define MACGLOBALSHORTCUTBACKEND_H
#include "config.h"
#include <memory>
#include "globalshortcutbackend.h"
#include <QKeySequence>
#include <QMap>
class MacGlobalShortcutBackendPrivate;
class QAction;
class MacGlobalShortcutBackend : public GlobalShortcutBackend {
Q_OBJECT
public:
explicit MacGlobalShortcutBackend(GlobalShortcuts* parent);
virtual ~MacGlobalShortcutBackend();
bool IsAccessibilityEnabled() const;
void ShowAccessibilityDialog();
void MacMediaKeyPressed(int key);
protected:
bool DoRegister();
void DoUnregister();
private:
bool KeyPressed(const QKeySequence &sequence);
QMap<QKeySequence, QAction*> shortcuts_;
friend class MacGlobalShortcutBackendPrivate;
std::unique_ptr<MacGlobalShortcutBackendPrivate> p_;
};
#endif // MACGLOBALSHORTCUTBACKEND_H

View File

@@ -0,0 +1,163 @@
/*
* Strawberry Music Player
* This file was part of Clementine.
* Copyright 2010, David Sansome <me@davidsansome.com>
*
* 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 "macglobalshortcutbackend.h"
#include <boost/noncopyable.hpp>
#include <AppKit/NSEvent.h>
#include <AppKit/NSWorkspace.h>
#include <Foundation/NSString.h>
#include <IOKit/hidsystem/ev_keymap.h>
#include <QAction>
#include <QList>
#include <QMessageBox>
#include <QPushButton>
#include <QtDebug>
#include "config.h"
#include "core/globalshortcuts.h"
#include "core/logging.h"
#include "core/mac_startup.h"
#include "core/utilities.h"
#import "core/mac_utilities.h"
#import "mac/SBSystemPreferences.h"
class MacGlobalShortcutBackendPrivate : boost::noncopyable {
public:
explicit MacGlobalShortcutBackendPrivate(MacGlobalShortcutBackend* backend)
: global_monitor_(nil), local_monitor_(nil), backend_(backend) {}
bool Register() {
global_monitor_ = [NSEvent addGlobalMonitorForEventsMatchingMask:NSKeyDownMask
handler:^(NSEvent* event) {
HandleKeyEvent(event);
}];
local_monitor_ = [NSEvent addLocalMonitorForEventsMatchingMask:NSKeyDownMask
handler:^(NSEvent* event) {
// Filter event if we handle it as a global shortcut.
return HandleKeyEvent(event) ? nil : event;
}];
return true;
}
void Unregister() {
[NSEvent removeMonitor:global_monitor_];
[NSEvent removeMonitor:local_monitor_];
}
private:
bool HandleKeyEvent(NSEvent* event) {
QKeySequence sequence = mac::KeySequenceFromNSEvent(event);
return backend_->KeyPressed(sequence);
}
id global_monitor_;
id local_monitor_;
MacGlobalShortcutBackend* backend_;
};
MacGlobalShortcutBackend::MacGlobalShortcutBackend(GlobalShortcuts* parent)
: GlobalShortcutBackend(parent),
p_(new MacGlobalShortcutBackendPrivate(this)) {}
MacGlobalShortcutBackend::~MacGlobalShortcutBackend() {}
bool MacGlobalShortcutBackend::DoRegister() {
// Always enable media keys.
mac::SetShortcutHandler(this);
for (const GlobalShortcuts::Shortcut& shortcut :
manager_->shortcuts().values()) {
shortcuts_[shortcut.action->shortcut()] = shortcut.action;
}
}
return p_->Register();
}
void MacGlobalShortcutBackend::DoUnregister() {
p_->Unregister();
shortcuts_.clear();
}
void MacGlobalShortcutBackend::MacMediaKeyPressed(int key) {
switch (key) {
case NX_KEYTYPE_PLAY:
KeyPressed(Qt::Key_MediaPlay);
break;
case NX_KEYTYPE_FAST:
KeyPressed(Qt::Key_MediaNext);
break;
case NX_KEYTYPE_REWIND:
KeyPressed(Qt::Key_MediaPrevious);
break;
}
}
bool MacGlobalShortcutBackend::KeyPressed(const QKeySequence& sequence) {
if (sequence.isEmpty()) {
return false;
}
QAction* action = shortcuts_[sequence];
if (action) {
action->trigger();
return true;
}
return false;
}
bool MacGlobalShortcutBackend::IsAccessibilityEnabled() const {
return AXAPIEnabled();
}
void MacGlobalShortcutBackend::ShowAccessibilityDialog() {
NSArray* paths = NSSearchPathForDirectoriesInDomains(
NSPreferencePanesDirectory, NSSystemDomainMask, YES);
if ([paths count] == 1) {
SBSystemPreferencesApplication* system_prefs = [SBApplication
applicationWithBundleIdentifier:@"com.apple.systempreferences"];
[system_prefs activate];
SBElementArray* panes = [system_prefs panes];
SBSystemPreferencesPane* security_pane = nil;
for (SBSystemPreferencesPane* pane : panes) {
if ([[pane id] isEqualToString:@"com.apple.preference.security"]) {
security_pane = pane;
break;
}
}
}
[system_prefs setCurrentPane:security_pane];
SBElementArray* anchors = [security_pane anchors];
for (SBSystemPreferencesAnchor* anchor : anchors) {
if ([[anchor name] isEqualToString:@"Privacy_Accessibility"]) {
[anchor reveal];
}
}
}
}
}

View File

@@ -0,0 +1,61 @@
/*
* Strawberry Music Player
* This file was part of Clementine.
* Copyright 2010, David Sansome <me@davidsansome.com>
*
* 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 "globalshortcuts.h"
#include "qxtglobalshortcutbackend.h"
#include "qxtglobalshortcut.h"
#include "core/logging.h"
#include <QAction>
#include <QtDebug>
QxtGlobalShortcutBackend::QxtGlobalShortcutBackend(GlobalShortcuts* parent) : GlobalShortcutBackend(parent) {}
bool QxtGlobalShortcutBackend::DoRegister() {
qLog(Debug) << "registering";
for (const GlobalShortcuts::Shortcut& shortcut : manager_->shortcuts().values()) {
AddShortcut(shortcut.action);
}
return true;
}
void QxtGlobalShortcutBackend::AddShortcut(QAction *action) {
if (action->shortcut().isEmpty()) return;
QxtGlobalShortcut *shortcut = new QxtGlobalShortcut(action->shortcut(), this);
connect(shortcut, SIGNAL(activated()), action, SLOT(trigger()));
shortcuts_ << shortcut;
}
void QxtGlobalShortcutBackend::DoUnregister() {
qLog(Debug) << "unregistering";
qDeleteAll(shortcuts_);
shortcuts_.clear();
}

View File

@@ -0,0 +1,44 @@
/*
* Strawberry Music Player
* This file was part of Clementine.
* Copyright 2010, David Sansome <me@davidsansome.com>
*
* 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 QXTGLOBALSHORTCUTBACKEND_H
#define QXTGLOBALSHORTCUTBACKEND_H
#include "config.h"
#include "globalshortcutbackend.h"
class QxtGlobalShortcut;
class QxtGlobalShortcutBackend : public GlobalShortcutBackend {
public:
explicit QxtGlobalShortcutBackend(GlobalShortcuts *parent = nullptr);
protected:
bool DoRegister();
void DoUnregister();
private:
void AddShortcut(QAction *action);
QList<QxtGlobalShortcut *> shortcuts_;
};
#endif // QXTGLOBALSHORTCUTBACKEND_H