I am writing a screen locking utility in Red Hat Enterprise Linux 7.6 and QT Creator in C++. The user is not supposed to be able to use any keyboard shortcuts while on the lockscreen.
So far I have been able to stop all keyboard shortcuts while debugging in QT Creator by using the following scripts (using execute()
in QT) to disable and then reenable shortcuts before displaying the login page that is locked:
#! /usr/bin/bash
shortcuts=$(gsettings list-keys org.gnome.desktop.wm.keybindings);
for x in $shortcuts; do
echo "Disabling $x";
gsettings set org.gnome.desktop.wm.keybindings $x [];
done
The problem arises when I try to execute this script inside my compiled QT program called using its PATH
alias from a systemd
service. The service starts properly and runs the program, and looking at the journalctl
logs I can see that the echo "Disabling...
command is being executed, but I am still able to use keyboard shortcuts (by pressing ALT+F1
I can go into applications->system tools->settings->devices
and see that nothing has been disabled.
My testService.service that I wrote looks like this (don’t mind all the commenting as I was doing some experimenting with run types
):
[Unit]
Description=testing screenlocker service
After=graphical.target
[Service]
#Type=simple
Type=exec
Environment="DISPLAY=:0"
#ExecStartPre=/home/user/Desktop/ScreenLocker/Source/disableShortcuts.sh
ExecStart=/home/user/Desktop/ScreenLocker/Source/build-ScreenLocker-Desktop_Qt_5_3_0_GCC_64bit-Debug/Screenlocker
TimeoutStartSec=0
[Install]
WantedBy=default.target
I am not sure what privelege or setting is keeping this system service from modifying the keymap for the user.
The QT Creator Code
main.cpp:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// set current directory to build directory so QT looks for resources in the right spot
// (before it would look in the directory above where PWD was and would have issues
QDir::setCurrent(QCoreApplication::applicationDirPath());
// Disabling keyboard shortcuts
QString qstr = QApplication::applicationDirPath();
QDir qdir = QDir(qstr);
qdir.cdUp();
QString qstrpath = qdir.absoluteFilePath("disableShortcuts.sh");
qstrpath = QDir::toNativeSeparators(qstrpath);
system(qPrintable(qstrpath));
...
mainwindow.cpp , where the logic on the button is stored to reset the shortcuts:
void MainWindow::handleButton(){
QString usr = getUsername();
QString pswd = getPassword();
QCloseEvent *event;
if(usr == "Ray" && pswd == "Theon"){
// Reenabling keyboard shortcuts
QString qstr = QApplication::applicationDirPath();
QDir qdir = QDir(qstr);
qdir.cdUp();
QString qstrpath = qdir.absoluteFilePath("resetShortcuts.sh");
qstrpath = QDir::toNativeSeparators(qstrpath);
system(qPrintable(qstrpath));
setStyleSheet("background-color: blue");
event->setAccepted(true);
this->close();
}
}
...
Things I have tried:
- using
ExecStartPre
/ExecStopPost
to run the disableShortcuts.sh and resetShortcuts.sh before and after the screenlocker respectively. I gave this the old college try and couldn’t figure it out – if it turns out that it is impossible to do this purely in QT/bash then i’ll revisit this. - using
simple
andoneshot
in thetype
settings of the .service file in an attempt to keep other services from not preempting the execution oftestService.service
( you can see in the logs that it gets preempted by the scheduler quite a bit but it does run) - changed the permissions of the bash scripts to 777 so that they won’t have any issue with execution permissions by anything/anyone trying to execute them