有没有一种通用的方法可以在 linux 上设置壁纸?
Posted
技术标签:
【中文标题】有没有一种通用的方法可以在 linux 上设置壁纸?【英文标题】:Is there an universal way to set a wallpaper on linux? 【发布时间】:2021-10-15 17:32:57 【问题描述】:我正在构建一个程序,该程序会使用从 reddit 中获取的壁纸定期更改您的壁纸。它目前支持 Windows,但我希望它也可以在 Linux 上运行。该程序是用Java开发的。
问题在于每个 DE 都有其独特的壁纸更换方式:XFCE、Cinnamon、GNOME 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
,但它不起作用,没有变化,没有输出,没有错误。
【问题讨论】:
问题在于每个 DE 都有其独特的壁纸更换方式: 是的,因此您可能需要为每个 DE 开发启发式方法。您需要每个脚本和检测每个脚本的方法。uname -a
可能会为您服务。一旦你测试了这些,ProcessBuilder
应该会为你做。
没有通用的方法。有多种特定于操作系统的方法……最简单的方法是运行(特定于系统的)命令来执行此操作。但这将取决于已经安装的相关应用程序。问题:您为什么要在 Java 桌面应用程序中执行此操作?当然,这不是应用程序关心的问题。
@StephenC “Java 桌面应用程序”是什么意思? (抱歉我的无知,但我对开发有点陌生)
以及用 Java 编写的应用程序,旨在运行或从用户的“桌面”运行。
@StephenC 这是我的一个项目,壁纸会定期更换。我还需要一种在 linux 上更改壁纸的方法,所以我需要以某种方式实现这个东西
【参考方案1】:
这是我找到的最佳解决方案,但我敢打赌它可以改进。我先扫描$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”?) .不过我认为这是一个很好的解决方案(或一个骨干),所以我还是发布了这个。
来源:
XDG_CURRENT_DESKTOP and GDM_SESSION KDE GNOME Unity Mint【讨论】:
出于好奇:为什么要执行echo $GDM_SESSION
而不仅仅是System.getenv("GDM_SESSION")
?
我只是忘记了它的存在,我会更新答案,因为System.getenv("GDM_SESSION")
它更干净了
是的......这是唯一可行的方法。请注意,它仅适用于您为其实施的一组环境。这就是这种方法的问题。以上是关于有没有一种通用的方法可以在 linux 上设置壁纸?的主要内容,如果未能解决你的问题,请参考以下文章