You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
106 lines
4.5 KiB
106 lines
4.5 KiB
/******************************************************************** |
|
KSld - the KDE Screenlocker Daemon |
|
This file is part of the KDE project. |
|
|
|
Copyright (C) 2015 Martin Gräßlin <mgraesslin@kde.org> |
|
|
|
This program 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 2 of the License, or |
|
(at your option) any later version. |
|
|
|
This program 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 this program. If not, see <http://www.gnu.org/licenses/>. |
|
*********************************************************************/ |
|
#ifndef GLOBALACCEL_H |
|
#define GLOBALACCEL_H |
|
|
|
#include <KGlobalShortcutInfo> |
|
|
|
#include <QObject> |
|
#include <QMap> |
|
|
|
class QDBusPendingCallWatcher; |
|
|
|
struct xcb_key_press_event_t; |
|
typedef struct _XCBKeySymbols xcb_key_symbols_t; |
|
|
|
/** |
|
* @short Interaction with KGlobalAccel. |
|
* |
|
* While the screen is locked, we want a few white listed global shortcuts to activate. |
|
* While the screen is locked KGlobalAcceld is not functional as the screen locker holds an |
|
* active X11 key grab and KGlobalAcceld does not get the key events. This prevents useful keys, |
|
* like volume control to no longer function. |
|
* |
|
* This class circumvents the problem by interacting with KGlobalAccel when the screen is locked |
|
* to still allow a few white listed shortcuts (like volume control) to function. |
|
* |
|
* As the screen is locked we can operate on a few assumptions which simplifies the interaction: |
|
* shortcuts won't change. The user cannot interact with the system thus the global shortcut won't |
|
* change while the screen is locked. This allows us to fetch the allowed shortcut information from |
|
* KGlobalAcceld when the screen gets locked and keep these information around till the screen is |
|
* unlocked. We do not need to update the information while the screen is locked. |
|
* |
|
* As the information is fetched in an async way from KGlobalAcceld there is a short time window |
|
* when the screen is locked, but the shortcut information is not fetched. This is considered a |
|
* not relevant corner case as we can assume that right when the screen locks (due to e.g. idle) |
|
* no user is in front of the system and is not able to press the shortcut or that the user directly |
|
* wants to cancel the lock screen again (grace time). |
|
* |
|
* Components are just registered by name in KGlobalAccel. This would in theory allow a malicious |
|
* application to register under a white listed name with white listed shortcuts and bind enough |
|
* shortcuts to turn this functionality into a key grabber to read the users password. To prevent such |
|
* attacks the shortcuts which can be invoked are restricted: the triggered key may not be a single |
|
* key in alphanumeric area with or without the shift keys. If a global shortcut contains an |
|
* alphanumeric key it will only be handled if also an additional modifier like Alt of Meta is pressed. |
|
**/ |
|
class GlobalAccel : public QObject |
|
{ |
|
Q_OBJECT |
|
public: |
|
GlobalAccel(QObject *parent = nullptr); |
|
|
|
/** |
|
* Starts interacting with KGlobalAccel and fetches the up-to-date shortcut information. |
|
**/ |
|
void prepare(); |
|
/** |
|
* Discards all knowing shortcut information. |
|
**/ |
|
void release(); |
|
|
|
/** |
|
* Checks whether a global shortcut is triggered for the given @p event. |
|
* If there is a global shortcut it gets invoked and @c true is returned. |
|
* If there is no matching global shortcut @c false is returned. |
|
**/ |
|
bool checkKeyPress(xcb_key_press_event_t *event); |
|
|
|
private: |
|
void components(QDBusPendingCallWatcher *watcher); |
|
/** |
|
* Recursion check: for each DBus call to KGlobalAccel this counter is |
|
* increased, on each reply decreased. As long as we have running DBus |
|
* calls, we do not enter prepare again. |
|
* |
|
* This ensures that if the screen gets locked, unlocked, locked in a short |
|
* time while we are still fetching information from KGlobalAccel we do not |
|
* enter an incorrect state. |
|
**/ |
|
uint m_updatingInformation = 0; |
|
/** |
|
* The shortcuts which got fetched from KGlobalAccel and can be operated on. |
|
* The key of contains the component DBus object path, the value the list of |
|
* allowed shortcuts. |
|
**/ |
|
QMap<QString, QList<KGlobalShortcutInfo>> m_shortcuts; |
|
xcb_key_symbols_t *m_keySymbols = nullptr; |
|
}; |
|
|
|
#endif
|
|
|