mirror of
https://github.com/dylanaraps/pywal.git
synced 2025-05-29 06:07:35 +02:00
180 lines
5.0 KiB
Python
180 lines
5.0 KiB
Python
"""Set the wallpaper."""
|
|
import ctypes
|
|
import logging
|
|
import os
|
|
import re
|
|
import shutil
|
|
import subprocess
|
|
import urllib.parse
|
|
|
|
from .settings import CACHE_DIR, HOME, OS
|
|
from . import util
|
|
|
|
|
|
def get_desktop_env():
|
|
"""Identify the current running desktop environment."""
|
|
desktop = os.environ.get("XDG_CURRENT_DESKTOP")
|
|
if desktop:
|
|
return desktop
|
|
|
|
desktop = os.environ.get("DESKTOP_SESSION")
|
|
if desktop:
|
|
return desktop
|
|
|
|
desktop = os.environ.get("GNOME_DESKTOP_SESSION_ID")
|
|
if desktop:
|
|
return "GNOME"
|
|
|
|
desktop = os.environ.get("MATE_DESKTOP_SESSION_ID")
|
|
if desktop:
|
|
return "MATE"
|
|
|
|
desktop = os.environ.get("SWAYSOCK")
|
|
if desktop:
|
|
return "SWAY"
|
|
|
|
desktop = os.environ.get("DESKTOP_STARTUP_ID")
|
|
if desktop and "awesome" in desktop:
|
|
return "AWESOME"
|
|
|
|
return None
|
|
|
|
|
|
def xfconf(img):
|
|
"""Call xfconf to set the wallpaper on XFCE."""
|
|
xfconf_re = re.compile(
|
|
r"^/backdrop/screen\d/monitor(?:0|\w*)/"
|
|
r"(?:(?:image-path|last-image)|workspace\d/last-image)$",
|
|
flags=re.M
|
|
)
|
|
xfconf_data = subprocess.check_output(
|
|
["xfconf-query", "--channel", "xfce4-desktop", "--list"],
|
|
stderr=subprocess.DEVNULL
|
|
).decode('utf8')
|
|
paths = xfconf_re.findall(xfconf_data)
|
|
for path in paths:
|
|
util.disown(["xfconf-query", "--channel", "xfce4-desktop",
|
|
"--property", path, "--set", img])
|
|
|
|
|
|
def set_wm_wallpaper(img):
|
|
"""Set the wallpaper for non desktop environments."""
|
|
if shutil.which("feh"):
|
|
util.disown(["feh", "--bg-fill", img])
|
|
|
|
elif shutil.which("nitrogen"):
|
|
util.disown(["nitrogen", "--set-zoom-fill", img])
|
|
|
|
elif shutil.which("bgs"):
|
|
util.disown(["bgs", "-z", img])
|
|
|
|
elif shutil.which("hsetroot"):
|
|
util.disown(["hsetroot", "-fill", img])
|
|
|
|
elif shutil.which("habak"):
|
|
util.disown(["habak", "-mS", img])
|
|
|
|
elif shutil.which("display"):
|
|
util.disown(["display", "-backdrop", "-window", "root", img])
|
|
|
|
else:
|
|
logging.error("No wallpaper setter found.")
|
|
return
|
|
|
|
|
|
def set_desktop_wallpaper(desktop, img):
|
|
"""Set the wallpaper for the desktop environment."""
|
|
desktop = str(desktop).lower()
|
|
|
|
if "xfce" in desktop or "xubuntu" in desktop:
|
|
xfconf(img)
|
|
|
|
elif "muffin" in desktop or "cinnamon" in desktop:
|
|
util.disown(["gsettings", "set",
|
|
"org.cinnamon.desktop.background",
|
|
"picture-uri", "file://" + urllib.parse.quote(img)])
|
|
|
|
elif "gnome" in desktop or "unity" in desktop:
|
|
util.disown(["gsettings", "set",
|
|
"org.gnome.desktop.background",
|
|
"picture-uri", "file://" + urllib.parse.quote(img)])
|
|
|
|
elif "mate" in desktop:
|
|
util.disown(["gsettings", "set", "org.mate.background",
|
|
"picture-filename", img])
|
|
|
|
elif "sway" in desktop:
|
|
util.disown(["swaymsg", "output", "*", "bg", img, "fill"])
|
|
|
|
elif "awesome" in desktop:
|
|
util.disown(["awesome-client",
|
|
"require('gears').wallpaper.maximized('{img}')"
|
|
.format(**locals())])
|
|
|
|
else:
|
|
set_wm_wallpaper(img)
|
|
|
|
|
|
def set_mac_wallpaper(img):
|
|
"""Set the wallpaper on macOS."""
|
|
db_file = "Library/Application Support/Dock/desktoppicture.db"
|
|
db_path = os.path.join(HOME, db_file)
|
|
img_dir, _ = os.path.split(img)
|
|
|
|
# Clear the existing picture data and write the image paths
|
|
sql = "delete from data; "
|
|
sql += "insert into data values(\"%s\"); " % img_dir
|
|
sql += "insert into data values(\"%s\"); " % img
|
|
|
|
# Set all monitors/workspaces to the selected image
|
|
sql += "update preferences set data_id=2 where key=1 or key=2 or key=3; "
|
|
sql += "update preferences set data_id=1 where key=10 or key=20 or key=30;"
|
|
|
|
subprocess.call(["sqlite3", db_path, sql])
|
|
|
|
# Kill the dock to fix issues with cached wallpapers.
|
|
# macOS caches wallpapers and if a wallpaper is set that shares
|
|
# the filename with a cached wallpaper, the cached wallpaper is
|
|
# used instead.
|
|
subprocess.call(["killall", "Dock"])
|
|
|
|
|
|
def set_win_wallpaper(img):
|
|
"""Set the wallpaper on Windows."""
|
|
# There's a different command depending on the architecture
|
|
# of Windows. We check the PROGRAMFILES envar since using
|
|
# platform is unreliable.
|
|
if "x86" in os.environ["PROGRAMFILES"]:
|
|
ctypes.windll.user32.SystemParametersInfoW(20, 0, img, 3)
|
|
else:
|
|
ctypes.windll.user32.SystemParametersInfoA(20, 0, img, 3)
|
|
|
|
|
|
def change(img):
|
|
"""Set the wallpaper."""
|
|
if not os.path.isfile(img):
|
|
return
|
|
|
|
desktop = get_desktop_env()
|
|
|
|
if OS == "Darwin":
|
|
set_mac_wallpaper(img)
|
|
|
|
elif OS == "Windows":
|
|
set_win_wallpaper(img)
|
|
|
|
else:
|
|
set_desktop_wallpaper(desktop, img)
|
|
|
|
logging.info("Set the new wallpaper.")
|
|
|
|
|
|
def get(cache_dir=CACHE_DIR):
|
|
"""Get the current wallpaper."""
|
|
current_wall = os.path.join(cache_dir, "wal")
|
|
|
|
if os.path.isfile(current_wall):
|
|
return util.read_file(current_wall)[0]
|
|
|
|
return "None"
|