我目前正在开始设置 stumpwm,我想将一个特定的窗口分配给一个特定的组。到目前为止,我有这个:
(define-frame-preference "Spotify"
(0 t t :class "Spotify")
)
所以本质上,我希望这会将 Spotify 类的窗口设置为 Spotify 组,但这不会发生。
有人可以帮我吗?谢谢!
我目前正在开始设置 stumpwm,我想将一个特定的窗口分配给一个特定的组。到目前为止,我有这个:
(define-frame-preference "Spotify"
(0 t t :class "Spotify")
)
所以本质上,我希望这会将 Spotify 类的窗口设置为 Spotify 组,但这不会发生。
有人可以帮我吗?谢谢!
因此,正如 coredump 所指出的那样,Spotify 窗口的定义方式似乎存在问题。作为替代方案,幸运的是,有很多方法可以通过第三方客户端(ArchWiki)控制 spotify
就个人而言,我发现您可以通过 Emacs 上的 Ivy 控制 Spotify,这要归功于 Ivy Spotify这个项目,这可能就是我将使用的。
X11 窗口和 Linux 进程之间的关系很微妙:事情是异步的,你启动一个进程,一段时间后零,一个或多个窗口被创建。您必须使用回调,没有简单的方法可以创建一个进程并同步返回其所有窗口。
有些进程可以很好地_NET_WM_PID
在 Windows 上设置属性(看起来像“Spotify”应用程序那样)。您可以按如下方式检索此属性:
(first (xlib:get-property (window-xwin w) :_net_wm_pid))
考虑到 Spotify 未能足够早地设置类属性(参见评论和其他答案),放置规则在这里无济于事。但是您可以使用自定义钩子:
STUMPWM-USER> (let ((out *standard-output*))
(push (lambda (&rest args) (print args out))
*new-window-hook*))
(#<CLOSURE (LAMBDA (&REST ARGS)) {101A92388B}>)
请注意我如何首先评估*standard-output*
以将其词法绑定到out
,以便该函数在打印信息时可以将其用作流。这是因为钩子可能在另一个线程中运行,其中标准输出的动态绑定可能不是我想要的(在我的例子中,这确保在 Slime REPL 中完成调试)。
例如xclock
,当我开始时,REPL 中会打印以下内容:
(#S(TILE-WINDOW "xclock" #x380000A))
所以我可以改变钩子,以便 if 做其他事情。这有点实验性,但例如,您可以临时修改*new-window-hook*
以对特定窗口事件做出反应:
(in-package :stumpwm-user)
(let ((process (sb-ext:run-program "xclock" () :search t :wait nil))
(hook))
(sb-ext:process-kill process sb-unix:sigstop)
(flet ((hook (w)
(when (find
(sb-ext:process-pid process)
(xlib:get-property (window-xwin w) :_net_wm_pid))
(move-window-to-group w (add-group (current-screen) "XCLOCK"))
(setf *new-window-hook* (remove hook *new-window-hook*)))))
(setf hook #'hook)
(push #'hook *new-window-hook*))
(sb-ext:process-kill process sb-unix:sigcont))
基本上:创建一个进程,停止它以最小化竞争条件,定义一个检查客户端中关联的 PID 是否与进程之一匹配的钩子,执行一些规则,然后从钩子列表中删除钩子。这是脆弱的,因为如果钩子从未运行,它会保留在列表中,如果出现错误,它也会保留在列表中。在表达式的末尾,添加了钩子并且进程恢复执行。