首页 > 解决方案 > 有没有一种通用的方法可以在 linux 上设置壁纸?

问题描述

我正在构建一个程序,该程序会定期使用从 reddit 中获取的墙纸更改您的墙纸。它目前支持 Windows,但我希望它也可以在 Linux 上运行。该程序是用Java开发的。

问题是每个 DE 都有其独特的壁纸更换方式:XFCECinnamonGNOME ecc ...

我想找到一种简单的通用方法来做到这一点。到目前为止,这是我的代码(它使用 XFCE 解决方案,因为我的机器在 XFCE 上运行):

public static void setWallpaper(String wallpaperPath) { 
    String s = "xfconf-query -c xfce4-desktop -p /backdrop/screen0/monitorVGA-1/workspace0/last-image -s \"" + wallpaperPath + "\"";
    ProcessBuilder processBuilder = new ProcessBuilder().command("bash", "-c", s);
    Process process = processBuilder.start();
}

我已经尝试过,xwallpaper但它不起作用,没有变化,没有输出,没有错误。

标签: javalinuxgnomewallpaperkde

解决方案


这是我找到的最好的解决方案,但我敢打赌它可以改进。我$XDG_CURRENT_DESKTOP先扫描然后再扫描$GDM_SESSION(显然 xdg 并不总是作为环境变量存在)。然后我根据我找到的环境采取行动并设置壁纸。

public static void main(String[] args) {
        String wpPath = "/path/to/file";
        String os = System.getProperty("os.name");
        switch (os) {
            case "Windows 10":
                System.out.println("WINODWS DETECTED");
                break;
            case "Linux":
                String de = identifyDE();
                if (de == null) {
                    System.out.println("Couldn't identify your Desktop Environment"); // log Severe
                    break;
                }

                switch (de) {
                    case "xfce":
                        executeProcess("xfconf-query -c xfce4-desktop -p /backdrop/screen0/monitorVGA-1/workspace0/last-image -s \"" + wpPath + "\"");
                        break;
                    case "gnome":
                        executeProcess("gsettings set org.gnome.desktop.background draw-background false && gsettings set org.gnome.desktop.background picture-uri \"file://" + wpPath + "\" && gsettings set org.gnome.desktop.background draw-background true");
                        break;
                    case "kde":
                        executeProcess("qdbus org.kde.plasmashell /PlasmaShell org.kde.PlasmaShell.evaluateScript 'var allDesktops = desktops();print (allDesktops);for (i=0;i<allDesktops.length;i++) {d = allDesktops[i];d.wallpaperPlugin = \"org.kde.image\";d.currentConfigGroup = Array(\"Wallpaper\", \"org.kde.image\", \"General\");d.writeConfig(\"Image\", \"" + wpPath + "\")}'");
                        break;
                    case "unity":
                        executeProcess("gsettings set org.gnome.desktop.background picture-uri \"file://" + wpPath + "\"");
                        break;
                    case "cinnamon":
                        executeProcess("gsettings set org.cinnamon.desktop.background picture-uri  \"file://" + wpPath + "\"");
                        break;
                    default:
                        System.out.println("Can't recognize DE: " + de);
                }


                break;
            default:
                System.out.println("Can't recognize OS: " + os);
        }
    }

public static String identifyDE() {
        String de;
        de = System.getenv("XDG_CURRENT_DESKTOP").toLowerCase();

        if (de.contains("xfce")) {
            return "xfce";
        } else if (de.contains("kde")) {
            return "kde";
        } else if (de.contains("unity")) {
            return "unity";
        } else if (de.contains("gnome")) {
            return "gnome";
        } else if (de.contains("cinnamon")) {
            return "cinnamon";
        } else if (de.contains("mate")) {
            return "mate";
        } else if (de.contains("deepin")) {
            return "deepin";
        } else if (de.contains("budgie")) {
            return "budgie";
        } else if (de.contains("lxqt")) {
            return "lxqt";
        } else {
            System.out.println("Not identifiable with: echo $XDG_CURRENT_DESKTOP: " + de);
        }

        de = System.getenv("GDM_SESSION").toLowerCase();

        if (de.contains("xfce")) {
            return "xfce";
        } else if (de.contains("kde")) {
            return "kde";
        } else if (de.contains("unity")) {
            return "unity";
        } else if (de.contains("gnome")) {
            return "gnome";
        } else if (de.contains("cinnamon")) {
            return "cinnamon";
        }  else if (de.contains("mate")) {
            return "mate";
        } else if (de.contains("deepin")) {
            return "deepin";
        } else if (de.contains("budgie")) {
            return "budgie";
        } else if (de.contains("lxqt")) {
            return "lxqt";
        } else {
            System.out.println("Not identifiable with: echo $GDM_SESSION: " + de);
        }

        return null;
    }

public static String executeProcess(String s) {
        ProcessBuilder pb = new ProcessBuilder("bash", "-c", s);
        pb.redirectErrorStream(true);
        Process p = null;
        try {
            p = pb.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
        BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));

        StringBuilder res = new StringBuilder();
        String line;

        try {
            while ((line = reader.readLine()) != null) {
                res.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }


        return res.toString();
    }

这段代码确实需要进一步测试,因为目前它仅在 manjaro XFCE 和 manjaro KDE 上进行了测试,我什至不确定其中的一些名称(deepin 的 XDG_CURRENT_DESKTOP 包含“deepin”还是“dde”?)。但是我认为这是一个很好的解决方案(或一个骨干),所以无论如何我都会发布这个。

资料来源:


推荐阅读