2018-02-27 18:06:05 +01:00
/*
* Strawberry Music Player
* This file was part of Clementine .
* Copyright 2010 , David Sansome < me @ davidsansome . com >
2021-03-20 21:14:47 +01:00
* Copyright 2018 - 2021 , Jonas Kvinge < jonas @ jkvinge . net >
2018-02-27 18:06:05 +01:00
*
* 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/>.
2018-08-09 18:39:44 +02:00
*
2018-02-27 18:06:05 +01:00
*/
# include "config.h"
2021-01-30 14:28:03 +01:00
# include <functional>
2021-05-12 20:08:06 +02:00
# include <QApplication>
2018-05-01 00:41:33 +02:00
# include <QWidget>
# include <QVariant>
# include <QString>
2018-02-27 18:06:05 +01:00
# include <QAction>
# include <QShortcut>
2018-05-01 00:41:33 +02:00
# include <QKeySequence>
2018-07-03 19:48:08 +02:00
# ifdef HAVE_DBUS
2018-05-01 00:41:33 +02:00
# include <QDBusConnectionInterface>
2018-02-27 18:06:05 +01:00
# endif
2021-01-26 19:13:29 +01:00
# include "globalshortcutsmanager.h"
# include "globalshortcutsbackend.h"
2019-01-01 20:07:29 +01:00
# ifdef HAVE_DBUS
2021-01-26 19:13:29 +01:00
# include "globalshortcutsbackend-gsd.h"
# include "globalshortcutsbackend-kde.h"
2019-01-01 20:07:29 +01:00
# endif
2021-05-12 20:08:06 +02:00
# if (defined(HAVE_X11) && defined(HAVE_QPA_QPLATFORMNATIVEINTERFACE_H)) || defined(Q_OS_WIN)
2021-01-26 19:13:29 +01:00
# include "globalshortcutsbackend-system.h"
2018-07-01 22:26:46 +02:00
# endif
2019-01-01 20:07:29 +01:00
# ifdef Q_OS_MACOS
2021-01-26 19:13:29 +01:00
# include "globalshortcutsbackend-macos.h"
2019-01-01 20:07:29 +01:00
# endif
2021-01-26 19:13:29 +01:00
# include "settings/globalshortcutssettingspage.h"
2018-05-01 00:41:33 +02:00
2021-01-26 19:13:29 +01:00
GlobalShortcutsManager : : GlobalShortcutsManager ( QWidget * parent )
2018-02-27 18:06:05 +01:00
: QWidget ( parent ) ,
2020-10-31 02:08:19 +01:00
gsd_backend_ ( nullptr ) ,
kde_backend_ ( nullptr ) ,
2018-02-27 18:06:05 +01:00
system_backend_ ( nullptr ) ,
2019-01-25 21:36:28 +01:00
use_gsd_ ( true ) ,
2020-10-31 02:08:19 +01:00
use_kde_ ( true ) ,
2019-01-01 20:07:29 +01:00
use_x11_ ( false )
{
2018-02-27 18:06:05 +01:00
settings_ . beginGroup ( GlobalShortcutsSettingsPage : : kSettingsGroup ) ;
// Create actions
2021-01-30 14:28:03 +01:00
AddShortcut ( " play " , " Play " , std : : bind ( & GlobalShortcutsManager : : Play , this ) ) ;
AddShortcut ( " pause " , " Pause " , std : : bind ( & GlobalShortcutsManager : : Pause , this ) ) ;
AddShortcut ( " play_pause " , " Play/Pause " , std : : bind ( & GlobalShortcutsManager : : PlayPause , this ) , QKeySequence ( Qt : : Key_MediaPlay ) ) ;
AddShortcut ( " stop " , " Stop " , std : : bind ( & GlobalShortcutsManager : : Stop , this ) , QKeySequence ( Qt : : Key_MediaStop ) ) ;
AddShortcut ( " stop_after " , " Stop playing after current track " , std : : bind ( & GlobalShortcutsManager : : StopAfter , this ) ) ;
AddShortcut ( " next_track " , " Next track " , std : : bind ( & GlobalShortcutsManager : : Next , this ) , QKeySequence ( Qt : : Key_MediaNext ) ) ;
AddShortcut ( " prev_track " , " Previous track " , std : : bind ( & GlobalShortcutsManager : : Previous , this ) , QKeySequence ( Qt : : Key_MediaPrevious ) ) ;
AddShortcut ( " inc_volume " , " Increase volume " , std : : bind ( & GlobalShortcutsManager : : IncVolume , this ) ) ;
AddShortcut ( " dec_volume " , " Decrease volume " , std : : bind ( & GlobalShortcutsManager : : DecVolume , this ) ) ;
AddShortcut ( " mute " , tr ( " Mute " ) , std : : bind ( & GlobalShortcutsManager : : Mute , this ) ) ;
AddShortcut ( " seek_forward " , " Seek forward " , std : : bind ( & GlobalShortcutsManager : : SeekForward , this ) ) ;
AddShortcut ( " seek_backward " , " Seek backward " , std : : bind ( & GlobalShortcutsManager : : SeekBackward , this ) ) ;
AddShortcut ( " show_hide " , " Show/Hide " , std : : bind ( & GlobalShortcutsManager : : ShowHide , this ) ) ;
AddShortcut ( " show_osd " , " Show OSD " , std : : bind ( & GlobalShortcutsManager : : ShowOSD , this ) ) ;
AddShortcut ( " toggle_pretty_osd " , " Toggle Pretty OSD " , std : : bind ( & GlobalShortcutsManager : : TogglePrettyOSD , this ) ) ; // Toggling possible only for pretty OSD
AddShortcut ( " shuffle_mode " , " Change shuffle mode " , std : : bind ( & GlobalShortcutsManager : : CycleShuffleMode , this ) ) ;
AddShortcut ( " repeat_mode " , " Change repeat mode " , std : : bind ( & GlobalShortcutsManager : : CycleRepeatMode , this ) ) ;
AddShortcut ( " toggle_scrobbling " , " Enable/disable scrobbling " , std : : bind ( & GlobalShortcutsManager : : ToggleScrobbling , this ) ) ;
AddShortcut ( " love " , " Love " , std : : bind ( & GlobalShortcutsManager : : Love , this ) ) ;
2018-02-27 18:06:05 +01:00
// Create backends - these do the actual shortcut registration
2019-01-01 20:07:29 +01:00
# ifdef HAVE_DBUS
2021-01-26 19:13:29 +01:00
gsd_backend_ = new GlobalShortcutsBackendGSD ( this ) ;
kde_backend_ = new GlobalShortcutsBackendKDE ( this ) ;
2019-01-01 20:07:29 +01:00
# endif
2018-02-27 18:06:05 +01:00
2019-01-01 20:07:29 +01:00
# ifdef Q_OS_MACOS
2019-02-23 01:10:45 +01:00
if ( ! system_backend_ )
2021-01-26 19:13:29 +01:00
system_backend_ = new GlobalShortcutsBackendMacOS ( this ) ;
2019-02-23 01:10:45 +01:00
# endif
# if defined(Q_OS_WIN)
if ( ! system_backend_ )
2021-01-26 19:13:29 +01:00
system_backend_ = new GlobalShortcutsBackendSystem ( this ) ;
2019-02-23 01:10:45 +01:00
# endif
2021-05-12 20:08:06 +02:00
# if defined(HAVE_X11) && defined(HAVE_QPA_QPLATFORMNATIVEINTERFACE_H)
2019-02-23 01:10:45 +01:00
if ( ! system_backend_ & & IsX11Available ( ) )
2021-01-26 19:13:29 +01:00
system_backend_ = new GlobalShortcutsBackendSystem ( this ) ;
2018-02-27 18:06:05 +01:00
# endif
ReloadSettings ( ) ;
}
2021-01-26 19:13:29 +01:00
void GlobalShortcutsManager : : ReloadSettings ( ) {
2019-01-01 20:07:29 +01:00
// The actual shortcuts have been set in our actions for us by the config dialog already - we just need to reread the gnome settings.
2019-01-25 21:36:28 +01:00
use_gsd_ = settings_ . value ( " use_gsd " , true ) . toBool ( ) ;
2020-10-31 02:08:19 +01:00
use_kde_ = settings_ . value ( " use_kde " , true ) . toBool ( ) ;
2019-02-23 01:10:45 +01:00
use_x11_ = settings_ . value ( " use_x11 " , false ) . toBool ( ) ;
2019-01-01 20:07:29 +01:00
Unregister ( ) ;
Register ( ) ;
}
2021-01-30 14:28:03 +01:00
void GlobalShortcutsManager : : AddShortcut ( const QString & id , const QString & name , std : : function < void ( ) > signal , const QKeySequence & default_key ) {
2018-02-27 18:06:05 +01:00
Shortcut shortcut = AddShortcut ( id , name , default_key ) ;
2021-01-30 14:28:03 +01:00
QObject : : connect ( shortcut . action , & QAction : : triggered , this , signal ) ;
2019-01-01 20:07:29 +01:00
2018-02-27 18:06:05 +01:00
}
2021-01-26 19:13:29 +01:00
GlobalShortcutsManager : : Shortcut GlobalShortcutsManager : : AddShortcut ( const QString & id , const QString & name , const QKeySequence & default_key ) {
2018-02-27 18:06:05 +01:00
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 ;
2019-01-01 20:07:29 +01:00
// Create application wide QShortcut to hide keyevents mapped to global shortcuts from widgets.
2018-02-27 18:06:05 +01:00
shortcut . shortcut = new QShortcut ( key_sequence , this ) ;
shortcut . shortcut - > setContext ( Qt : : ApplicationShortcut ) ;
shortcuts_ [ id ] = shortcut ;
return shortcut ;
}
2021-01-26 19:13:29 +01:00
bool GlobalShortcutsManager : : IsGsdAvailable ( ) const {
2018-02-27 18:06:05 +01:00
2018-07-03 19:48:08 +02:00
# ifdef HAVE_DBUS
2021-01-26 19:13:29 +01:00
return QDBusConnection : : sessionBus ( ) . interface ( ) - > isServiceRegistered ( GlobalShortcutsBackendGSD : : kGsdService ) | | QDBusConnection : : sessionBus ( ) . interface ( ) - > isServiceRegistered ( GlobalShortcutsBackendGSD : : kGsdService2 ) ;
2018-07-03 19:48:08 +02:00
# else
2018-02-27 18:06:05 +01:00
return false ;
# endif
}
2021-01-26 19:13:29 +01:00
bool GlobalShortcutsManager : : IsKdeAvailable ( ) const {
2020-10-31 02:08:19 +01:00
# ifdef HAVE_DBUS
2021-01-26 19:13:29 +01:00
return QDBusConnection : : sessionBus ( ) . interface ( ) - > isServiceRegistered ( GlobalShortcutsBackendKDE : : kKdeService ) ;
2020-10-31 02:08:19 +01:00
# else
return false ;
# endif
}
2021-01-26 19:13:29 +01:00
bool GlobalShortcutsManager : : IsX11Available ( ) const {
2018-02-27 18:06:05 +01:00
2021-05-12 20:08:06 +02:00
return QApplication : : platformName ( ) = = " xcb " ;
2018-02-27 18:06:05 +01:00
}
2021-01-26 19:13:29 +01:00
void GlobalShortcutsManager : : Register ( ) {
2020-10-31 02:08:19 +01:00
if ( use_gsd_ & & gsd_backend_ & & gsd_backend_ - > Register ( ) ) return ;
if ( use_kde_ & & kde_backend_ & & kde_backend_ - > Register ( ) ) return ;
2021-05-12 20:08:06 +02:00
# if defined(HAVE_X11) && defined(HAVE_QPA_QPLATFORMNATIVEINTERFACE_H) // If this system has X11, only use the system backend if X11 is enabled in the global shortcut settings
2019-02-23 01:10:45 +01:00
if ( use_x11_ ) {
# endif
if ( system_backend_ )
system_backend_ - > Register ( ) ;
2021-05-12 20:08:06 +02:00
# if defined(HAVE_X11) && defined(HAVE_QPA_QPLATFORMNATIVEINTERFACE_H)
2019-02-23 01:10:45 +01:00
}
2019-01-01 20:07:29 +01:00
# endif
2020-10-31 02:08:19 +01:00
2018-02-27 18:06:05 +01:00
}
2021-01-26 19:13:29 +01:00
void GlobalShortcutsManager : : Unregister ( ) {
2020-10-31 02:08:19 +01:00
if ( gsd_backend_ & & gsd_backend_ - > is_active ( ) ) gsd_backend_ - > Unregister ( ) ;
if ( kde_backend_ & & kde_backend_ - > is_active ( ) ) kde_backend_ - > Unregister ( ) ;
2019-01-01 20:07:29 +01:00
if ( system_backend_ & & system_backend_ - > is_active ( ) ) system_backend_ - > Unregister ( ) ;
2020-10-31 02:08:19 +01:00
2018-02-27 18:06:05 +01:00
}
2021-01-26 19:13:29 +01:00
bool GlobalShortcutsManager : : IsMacAccessibilityEnabled ( ) const {
2018-06-28 01:15:32 +02:00
# ifdef Q_OS_MACOS
2021-01-26 19:13:29 +01:00
if ( system_backend_ ) return qobject_cast < GlobalShortcutsBackendMacOS * > ( system_backend_ ) - > IsAccessibilityEnabled ( ) ;
2019-01-01 20:07:29 +01:00
else return false ;
2018-02-27 18:06:05 +01:00
# else
return true ;
# endif
}
2021-01-26 19:13:29 +01:00
void GlobalShortcutsManager : : ShowMacAccessibilityDialog ( ) {
2018-06-28 01:15:32 +02:00
# ifdef Q_OS_MACOS
2021-01-26 19:13:29 +01:00
if ( system_backend_ ) qobject_cast < GlobalShortcutsBackendMacOS * > ( system_backend_ ) - > ShowAccessibilityDialog ( ) ;
2018-02-27 18:06:05 +01:00
# endif
}