如何使用Go为X11 / Wayland的多个屏幕添加背景图像?

4

我在Go中为窗口管理器制作了一个自定义壁纸设置器。目前我使用github.com/xyproto/wallutils项目,该项目又依赖于feh

对于一个屏幕,我可以使用其尺寸创建精确大小的图像,并且一切正常,但是如果连接到计算机的多个具有不同尺寸的屏幕,则此方法无法工作。

对于精确的图像,我使用 feh的“填充”选项,这仅适用于其中一个监视器。

我想做的是为每个屏幕创建正确尺寸的图像,并将它们作为背景图像发送到相应的X11或Wayland屏幕。我如何在Go中实现这一点?


你声称已经有了单个显示器的工作代码,那问题出在哪里呢?是因为你不知道如何检测可用的显示器及其信息吗? - icza
1
我喜欢 ChatGPT 自信地建议使用包 "xgraphics/window" 通过 screens, err := window.Screens() 获取屏幕。但是,就我所知,"xgraphics/window" 并不存在! - VonC
@icza,我在问题中添加了一个解释,为什么当前基于feh的方法仅适用于一个监视器。 - dimus
请分享更多细节,例如您尝试解决问题的方法。 - Nico Haase
@NicoHaase,目前我使用来自wallutils的feh绑定来为单个显示器提供服务。https://codeberg.org/dimus/muro/src/commit/e5876d787c0fb6f683548404c7c5a917deccae30/pkg/muro.go#L171然而,这种方法不允许将图像单独发送到每个显示器。 - dimus
2
请按照惯例通过编辑问题来添加所有澄清信息。 - Nico Haase
2个回答

3

需求:

  • 向不同的监视器发送不同的壁纸
  • 从 Go 中调用
  • 在下面使用 feh

muro 和 wallutils

wallutils 指定了一个 WM 接口,其中提供了 SetWallpaper 方法等功能。对于许多不同的窗口管理器,都有相应的此接口实现。

Go 包 muro 反过来使用了 wallutils。基于标志 WithAnyWindowManager,它将使用 wallutils 的 SetWallpaperCustom 方法,该方法根据检测到的窗口管理器选择具体的 SetWallpaper 实现,或者直接调用 feh 变量的 SetWallpaper

wallutils 和 feh

特定的显示模式取决于如何调用,但是 wallutils feh.go 中的 SetWallpaper 基本上会按照以下方式在您的情况下调用 feh

    feh --bg-fill <image file name>

两个注意事项:

  • 这里的feh将所有屏幕的壁纸设置为完全相同的图像
  • 因此,不直接支持使用不同的图像

此外,wallutils的自述文件明确说明:

为每个监视器设置壁纸

目前尚不支持为每个监视器设置壁纸。

请参见https://github.com/xyproto/wallutils#setting-a-wallpaper-per-monitor

可能的解决方案

由于您可以确定监视器和分辨率,因此我们专注于在使用feh的情况下以正确的顺序发送预定义的图像作为背景图像到适当的屏幕。

feh本身支持为每个监视器设置不同的壁纸。只需使用具有不同分辨率的不同图像调用feh即可。顺序保证与通过调用xrandr --listmonitors确定的顺序相同。

确定顺序并将其视为已知后,最简单的 GO 程序可能如下所示(还可以参见 wallutil 的实用函数 run):
package main

import (
    "os/exec"
)

func main() {
    args := []string{"--bg-fill", "1.png", "2.png"}
    cmd := exec.Command("feh", args...)
    if _, err := cmd.CombinedOutput(); err != nil {
        panic(err)
    }
}

(在 FluxBox 窗口管理器下测试过)

只要提供的窗口管理器与 go 目录中准备好的两个图像配合使用,这就是最简单的情况。当然,也可以通过编程方式确定屏幕并动态调整对 feh 的调用。

由于 feh 并不适用于每个环境,wallutils 为许多窗口管理器环境(Cinnamon、Deepin、Gnome、Mate、Pekwm、Plasma、Sway、Weston、Xfce4)提供了其 WM 接口的具体实现。这当然非常酷。但是,如果您想为 wallutils 创建 MR,则可能至少需要在所有支持它的变体中这样做。


1
它在Qtile窗口管理器中也对我有效,谢谢!如果他们决定在wallutils中添加这个功能,我会把你的答案传给开发人员。 - dimus
1
我是wallutils的开发者,非常希望增加这个功能,只是还没有完成。感谢您使用wallutils. :) - Alexander
感谢您提供如此出色的库。 :-) - Stephan Schlecht

0

谢谢您提供的链接,@VonC,wallutils还提供有关显示器数量和其尺寸的信息 https://github.com/xyproto/wallutils/blob/main/backend.go#L37,对我来说缺少的是根据每个显示器的尺寸发送图像到它们的背景的能力。 - dimus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接