Skip to content

Instantly share code, notes, and snippets.

@bharadwaj-raju
Last active July 26, 2022 08:39
Show Gist options
  • Save bharadwaj-raju/46ef4c76e4e72ae618f83a22bfde09bf to your computer and use it in GitHub Desktop.
Save bharadwaj-raju/46ef4c76e4e72ae618f83a22bfde09bf to your computer and use it in GitHub Desktop.
# coding: utf-8
# Licensed under the MIT License
# Copyright © 2016 Bharadwaj Raju <[email protected]>
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"), to deal in the Software without
# restriction, including without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to permit persons
# to whom the Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import os
import sys
import subprocess as sp
import tempfile
import shutil
try:
import configparser
except ImportError:
import ConfigParser as configparser
import traceback
import ctypes
def set(image):
''' Set the desktop wallpaper to 'image'. '''
desktop_env = get_desktop_environment()
if desktop_env in ['gnome', 'unity', 'cinnamon', 'pantheon', 'mate']:
uri = 'file://%s' % image
SCHEMA = 'org.gnome.desktop.background'
KEY = 'picture-uri'
if desktop_env == 'mate':
uri = image
SCHEMA = 'org.mate.background'
KEY = 'picture-filename'
try:
from gi.repository import Gio
gsettings = Gio.Settings.new(SCHEMA)
gsettings.set_string(KEY, uri)
except ImportError:
try:
gsettings_proc = sp.Popen(['gsettings', 'set', SCHEMA, KEY, uri])
except: # MATE < 1.6
sp.Popen(['mateconftool-2','-t','string','--set','/desktop/mate/background/picture_filename','%s' % image], stdout=sp.PIPE)
finally:
gsettings_proc.communicate()
if gsettings_proc.returncode != 0:
sp.Popen(['mateconftool-2','-t','string','--set','/desktop/mate/background/picture_filename','%s' % image])
elif desktop_env == 'gnome2':
args = ['gconftool-2','-t','string','--set','/desktop/gnome/background/picture_filename', '%s' % image]
sp.Popen(args)
elif desktop_env == 'kde':
# Probably only works in 5+
sp.Popen(['''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", "file:///%s")
}}'
''' % image], shell=True)
elif desktop_env in ['kde3', 'trinity']:
args = 'dcop kdesktop KBackgroundIface setWallpaper 0 "%s" 6' % image
sp.Popen(args,shell=True)
elif desktop_env=='xfce4':
# XFCE4's image property is not image-path but last-image (What?)
list_of_properties = sp.check_output(['bash -c "xfconf-query -R -l -c xfce4-desktop -p /backdrop"'], shell=True)
list_of_properties = list_of_properties.decode('utf-8')
for i in list_of_properties.split('\n'):
if i.endswith('last-image'):
# The property given is a background property
sp.Popen(
['xfconf-query -c xfce4-desktop -p %s -s "%s"' % (i, image)],
shell=True)
sp.Popen(['xfdesktop --reload'], shell=True)
elif desktop_env=='razor-qt':
desktop_conf = configparser.ConfigParser()
# Development version
desktop_conf_file = os.path.join(get_config_dir('razor')[0], 'desktop.conf')
if os.path.isfile(desktop_conf_file):
config_option = r'screens\1\desktops\1\wallpaper'
else:
desktop_conf_file = os.path.join(os.path.expanduser('~'),'.razor/desktop.conf')
config_option = r'desktops\1\wallpaper'
desktop_conf.read(os.path.join(desktop_conf_file))
try:
if desktop_conf.has_option('razor',config_option): # only replacing a value
desktop_conf.set('razor',config_option,image)
with codecs.open(desktop_conf_file, 'w', encoding='utf-8', errors='replace') as f:
desktop_conf.write(f)
except:
pass
elif desktop_env in ['fluxbox','jwm','openbox','afterstep', 'i3']:
try:
args = ['feh','--bg-scale', image]
sp.Popen(args)
except:
sys.stderr.write('Error: Failed to set wallpaper with feh!')
sys.stderr.write('Please make sre that You have feh installed.')
elif desktop_env == 'icewm':
args = ['icewmbg', image]
sp.Popen(args)
elif desktop_env == 'blackbox':
args = ['bsetbg', '-full', image]
sp.Popen(args)
elif desktop_env == 'lxde':
args = 'pcmanfm --set-wallpaper %s --wallpaper-mode=scaled' % image
sp.Popen(args, shell=True)
elif desktop_env == 'lxqt':
args = 'pcmanfm-qt --set-wallpaper %s --wallpaper-mode=scaled' % image
sp.Popen(args, shell=True)
elif desktop_env == 'windowmaker':
args = 'wmsetbg -s -u %s' % image
sp.Popen(args, shell=True)
elif desktop_env == 'enlightenment':
args = 'enlightenment_remote -desktop-bg-add 0 0 0 0 %s' % image
sp.Popen(args, shell=True)
elif desktop_env == 'awesome':
with sp.Popen("awesome-client", stdin=sp.PIPE) as awesome_client:
command = 'local gears = require("gears"); for s = 1, screen.count() do gears.wallpaper.maximized("%s", s, true); end;' % image
awesome_client.communicate(input=bytes(command, 'UTF-8'))
elif desktop_env == 'windows':
WINDOWS_SCRIPT = '''reg add "HKEY_CURRENT_USER\Control Panel\Desktop" /v Wallpaper /t REG_SZ /d %s /f
rundll32.exe user32.dll,UpdatePerUserSystemParameters
''' % image
windows_script_file = os.path.join(tempfile.gettempdir(), 'wallscript.bat')
with open(windows_script_file, 'w') as f:
f.write(WINDOWS_SCRIPT)
sp.Popen([windows_script_file], shell=True)
# Sometimes the method above works
# and sometimes the one below
SPI_SETDESKWALLPAPER = 20
ctypes.windll.user32.SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0, image , 0)
elif desktop_env == 'mac':
try:
from appscript import app, mactypes
app('Finder').desktop_picture.set(mactypes.File(image))
except ImportError:
OSX_SCRIPT = '''tell application "System Events"
set desktopCount to count of desktops
repeat with desktopNumber from 1 to desktopCount
tell desktop desktopNumber
set picture to POSIX file "%s"
end tell
end repeat
end tell''' % image
sp.Popen(['osascript', OSX_SCRIPT])
else:
try:
sp.Popen(['feh', '--bg-scale', image])
# feh is nearly a catch-all for Linux WMs
except:
pass
def get_desktop_environment():
''' Get desktop environment or OS. '''
if sys.platform in ['win32', 'cygwin']:
return 'windows'
elif sys.platform == 'darwin':
return 'mac'
else:
desktop_session = os.environ.get('XDG_CURRENT_DESKTOP') or os.environ.get('DESKTOP_SESSION')
if desktop_session is not None:
desktop_session = desktop_session.lower()
# Fix for X-Cinnamon etc
if desktop_session.startswith('x-'):
desktop_session = desktop_session.replace('x-', '')
if desktop_session in ['gnome','unity', 'cinnamon', 'mate',
'xfce4', 'lxde', 'fluxbox',
'blackbox', 'openbox', 'icewm', 'jwm',
'afterstep','trinity', 'kde', 'pantheon',
'i3', 'lxqt', 'awesome', 'enlightenment']:
return desktop_session
#-- Special cases --#
# Canonical sets environment var to Lubuntu rather than
# LXDE if using LXDE.
# There is no guarantee that they will not do the same
# with the other desktop environments.
elif 'xfce' in desktop_session:
return 'xfce4'
elif desktop_session.startswith('ubuntu'):
return 'unity'
elif desktop_session.startswith('xubuntu'):
return 'xfce4'
elif desktop_session.startswith('lubuntu'):
return 'lxde'
elif desktop_session.startswith('kubuntu'):
return 'kde'
elif desktop_session.startswith('razor'):
return 'razor-qt'
elif desktop_session.startswith('wmaker'):
return 'windowmaker'
if os.environ.get('KDE_FULL_SESSION') == 'true':
return 'kde'
elif os.environ.get('GNOME_DESKTOP_SESSION_ID'):
if not 'deprecated' in os.environ.get('GNOME_DESKTOP_SESSION_ID'):
return 'gnome2'
elif is_running('xfce-mcs-manage'):
return 'xfce4'
elif is_running('ksmserver'):
return 'kde'
return 'unknown'
def is_running(process):
''' Check if 'process' is running. '''
if os.name == 'nt':
process_list = get_cmd_out(['tasklist', '/v'])
return process in process_list
else:
process_list = get_cmd_out('ps axw | awk \'{print $5}\'')
for i in process_list.split('\n'):
# 'COMMAND' is the column heading
# [*] indicates kernel-level processes like \
# kthreadd, which manages threads in the Linux kernel
if not i == 'COMMAND' or i.startswith('['):
if i == process:
return True
elif os.path.basename(i) == process:
# check i without executable path
# for example, if 'process' arguments is 'sshd'
# and '/usr/bin/sshd' is listed in ps, return True
return True
return False # finally
def get_cmd_out(command):
if type(command) == list:
return sp.check_output(command).decode('utf-8').rstrip('\n')
else:
return sp.check_output(command, shell=True).decode('utf-8').rstrip('\n')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment