使用 systemd 自动启动 gtk 应用程序

使用 systemd 自动启动 gtk 应用程序

我正在编写一个小守护进程,用于记录活动窗口的名称。相关部分如下:

import wnck
import gtk

from plugins import IReporter


class ActiveWindowNameReporter(IReporter):

    export_as = 'active_window_name'

    def report(self):
        name = None

        screen = wnck.screen_get_default()
        screen.force_update()
        while gtk.events_pending():
                gtk.main_iteration()

        if screen:
            active_window = screen.get_active_window()

            if active_window:
                name = active_window.get_name()

        return name

我为此编写了一个简单的 systemd 用户服务文件:

[Unit]
Description=Activity Monitor Service

[Service]
ExecStart=/usr/bin/python /home/me/Projects/monitor/monitor.py

[Install]
WantedBy=graphical.target

但是,运行服务失败。在 journalctl -r 中我可以看到:

Unit actor.service entered failed state.
actor.service: main process exited, code=exited, status=1/FAILURE
ImportError: could not import gtk
import wnck
File "/home/me/Projects/monitor/reporters/active_window_name.py", line 1, in <mod
from reporters import *
File "/home/me/Projects/monitor/monitor.py", line 16, in <module>
Traceback (most recent call last):
detected unhandled Python exception in '/home/tbabej/Projects/actor/actor.py'      
Started Activity Monitor Service.                                                  
Starting Activity Monitor Service...

好像是因为会话不可用导致 gtk 模块导入失败?但是在脚本中设置 XDG_SESSION_ID 变量没有帮助。

答案1

系统服务不能也不应该与用户会话交互。Unix 上始终只有一个图形会话的假设从未成立(X11 从一开始就是多用户的),甚至在 Windows 上也不正确(NT 4.0 引入终端服务之后,XP 添加了快速用户切换)。

换句话说,系统服务不知道X11 显示它应该使用;没有权利证书即使你进行了硬编码:0(只有会话的所有者知道正确的 $XAUTHORITY 值 - 成为 root 并不赋予任何魔法力量);并且通常会自动启动会出现任何 X11 显示,即使你进行了硬编码/home/me/.Xauthority

这意味着必须启动像你这样的脚本里面图形会话——通过~/.config/autostart/*.desktop(XDG 自动启动规范),或者通过~/.xprofile(常规 shell 脚本)。

# ~/.config/autostart/monitor.desktop

[桌面条目]
名称=活动监视器
类型=应用程序
执行=nm-applet

相关内容