Unfortunately, you'll have to hardcode such a keyboard shortcut. Screenlockers always grab control of the keyboard, meaning they are the only running X client that get the keypresses. If they didn't do that, it would mean that other applications would receive keypresses which is the exact thing you wouldn't want to happen with a keylocker. The grabbing happens with the XGrabKeyboard
function that is implemented in Xlib (which is the library that slock uses). In general, Xlib is pretty well-documented and you probably even have manpages installed for it if you're interested - for example man XGrabKeyboard
. The other manpages are similarly prefixed with "X" for various other library functions.
As far as I understand, you're worried that setuid
messes up your script, right? If so, my first instinct would be to fork()
slock on startup and probably use pipes to communicate between parent and child. Looking at the source code, you could probably fork on line 340 or so (before the setuid
and set up a pipe. Once you have programmed your shortcut, you can use the pipe to communicate between parent and child. Essentially all you would have to do is send a message that lets the child, resp. parent know when to execute your own script. Pipes are fairly easy in C, so they are suitable if you don't want to fiddle with the implementation too much. Here's a full pipe example taken from this site:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main(void)
{
int fd[2], nbytes;
pid_t childpid;
char string[] = "Hello, world!\n";
char readbuffer[80];
pipe(fd);
if((childpid = fork()) == -1)
{
perror("fork");
exit(1);
}
if(childpid == 0)
{
/* Child process closes up input side of pipe */
close(fd[0]);
/* Send "string" through the output side of pipe */
write(fd[1], string, (strlen(string)+1));
exit(0);
}
else
{
/* Parent process closes up output side of pipe */
close(fd[1]);
/* Read in a string from the pipe */
nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
printf("Received string: %s", readbuffer);
}
return(0);
}
evtest
is still able to read events from/dev/input/event...
while slock is running.