Gostaria de executar uma tela se a sessão do Gnome estiver bloqueada e desbloqueada. Existe uma maneira de interceptar isso e executar determinadas ações quando a área de trabalho está bloqueada ou desbloqueada?
Gostaria de executar uma tela se a sessão do Gnome estiver bloqueada e desbloqueada. Existe uma maneira de interceptar isso e executar determinadas ações quando a área de trabalho está bloqueada ou desbloqueada?
Respostas:
O Gnome-screensaver emite alguns sinais no dbus quando algo acontece.
Aqui a documentação (com alguns exemplos).
Você pode escrever um script que seja executado:
dbus-monitor --session "type='signal',interface='org.gnome.ScreenSaver'"
e isso faz o que você precisa a qualquer momento, dbus-monitor
imprime uma linha sobre a tela ser bloqueada / desbloqueada.
Aqui está um comando bash para fazer o que você precisa:
dbus-monitor --session "type='signal',interface='org.gnome.ScreenSaver'" |
while read x; do
case "$x" in
*"boolean true"*) echo SCREEN_LOCKED;;
*"boolean false"*) echo SCREEN_UNLOCKED;;
esac
done
Basta substituir echo SCREEN_LOCKED
e echo SCREEN_UNLOCKED
com o que você precisa.
gnome-screensaver-command
já está lá. Passando -a
para gnome-screensaver-command
você bloqueia a tela, enquanto a desbloqueia -d
. De qualquer forma, a maioria dos aplicativos gnome usa o dbus extensivamente, para que você possa fazer muitas coisas incríveis com ele.
No ubuntu 14.04, o evento DBus para desbloqueio de bloqueio de tela foi alterado e o novo script para ligação aos eventos de bloqueio e desbloqueio de tela se parece com o seguinte
dbus-monitor --session "type='signal',interface='com.ubuntu.Upstart0_6'" | \
(
while true; do
read X
if echo $X | grep "desktop-lock" &> /dev/null; then
SCREEN_LOCKED;
elif echo $X | grep "desktop-unlock" &> /dev/null; then
SCREEN_UNLOCKED;
fi
done
)
Hoje em dia, acho melhor ouvir as LockedHint
mensagens do que proteger as telas. Dessa forma, você não está vinculado a uma implementação de proteção de tela.
Aqui está um script simples para fazer isso:
gdbus monitor -y -d org.freedesktop.login1 | grep LockedHint
Dá isto:
/org/freedesktop/login1/session/_32: org.freedesktop.DBus.Properties.PropertiesChanged ('org.freedesktop.login1.Session', {'LockedHint': <true>}, @as [])
/org/freedesktop/login1/session/_32: org.freedesktop.DBus.Properties.PropertiesChanged ('org.freedesktop.login1.Session', {'LockedHint': <false>}, @as [])
Ubuntu 16.04: a solução do ozma não funcionou para mim, mas esta funcionou:
dbus-monitor --session "type=signal,interface=com.canonical.Unity.Session,member=Unlocked" |
while read MSG; do
LOCK_STAT=`echo $MSG | awk '{print $NF}'`
if [[ "$LOCK_STAT" == "member=Unlocked" ]]; then
echo "was unlocked"
fi
done
Expandindo a resposta já dada.
Se você tentar executar um script a partir de uma sessão screen
ou tmux
, precisará encontrar o correto $DBUS_SESSION_BUS_ADDRESS
primeiro e passá-lo como argumento para, em dbus-monitor
vez de --session
. Além disso, se você o estiver executando como um daemon, verifique se apenas uma instância está sendo executada por vez (por exemplo, com um arquivo de bloqueio) e se o script é limpo por si próprio trap
. O exemplo a seguir funcionará como um daemon na maioria dos ambientes atuais do Gnome (testado no Ubuntu GNOME 16.04):
#!/bin/bash
set -o nounset # good practice, exit if unset variable used
pidfile=/tmp/lastauth.pid # lock file path
logfile=/tmp/lastauth.log # log file path
cleanup() { # when cleaning up:
rm -f $pidfile # * remove the lock file
trap - INT TERM EXIT # * reset kernel signal catching
exit # * stop the daemon
}
log() { # simple logging format example
echo $(date +%Y-%m-%d\ %X) -- $USER -- "$@" >> $logfile
}
if [ -e "$pidfile" ]; then # if lock file exists, exit
log $0 already running...
exit
fi
trap cleanup INT TERM EXIT # call cleanup() if e.g. killed
log daemon started...
echo $$ > $pidfile # create lock file with own PID inside
# usually `dbus-daemon` address can be guessed (`-s` returns 1st PID found)
export $(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$(pidof -s dbus-daemon)/environ)
expr='type=signal,interface=org.gnome.ScreenSaver' # DBus watch expression here
dbus-monitor --address $DBUS_SESSION_BUS_ADDRESS "$expr" | \
while read line; do
case "$line" in
*"boolean true"*) log session locked;;
*"boolean false"*) log session unlocked;;
esac
done
cleanup # let's not leave orphaned lock file when the loop ends (e.g. dbus dies)
Se isso não funcionar para você, provavelmente é porque:
Se você estiver no Kubuntu ou estiver usando o KDE / Plasma como seu ambiente de área de trabalho, terá que ouvir a interface org.freedesktop.ScreenSaver
, para que o script para ouvir esse evento fique assim:
dbus-monitor --session "type='signal',interface='org.freedesktop.ScreenSaver'" |
while read x; do
case "$x" in
*"boolean true"*) echo SCREEN_LOCKED;;
*"boolean false"*) echo SCREEN_UNLOCKED;;
esac
done
Personalization>Notifications>Notifications>Screensaver
.
upstart
suporte a tarefasdesktop-lock
e desktop-unlock
eventos da sessão em start on
estrofe. Basta criar um trabalho .conf para seu usuário com acionadores e comandos relevantes para chamar no exemplo $XDG_CONFIG_HOME/upstart/
ou $HOME/.config/upstart
abaixo, como abaixo:
description "some job description"
start on desktop-lock
script
/path/to/your/executable
end script
isto é o que funcionou para mim no ubuntu 16.04
dbus-monitor --session "type=signal,interface=org.gnome.ScreenSaver" |
while read MSG; do
LOCK_STAT=`echo $MSG | grep boolean | awk '{print $2}'`
if [[ "$LOCK_STAT" == "true" ]]; then
echo "was locked"
else
echo "was un-locked"
fi
done