88def set_background (file_path ):
99 de = get_desktop_environment ()
1010
11- if de in ["gnome" , "unity" , "cinnamon" , "pantheon" , "gnome-classic" ]:
12- # Because of a bug and stupid design of gsettings, see http://askubuntu.com/a/418521/388226
13- if de == "unity" :
14- subprocess .call (["gsettings" , "set" , "org.gnome.desktop.background" , "draw-background" , "false" ])
15- subprocess .call (["gsettings" , "set" , "org.gnome.desktop.background" , "picture-uri" , "file://" + file_path ])
16- subprocess .call (["gsettings" , "set" , "org.gnome.desktop.background" , "picture-options" , "scaled" ])
17- subprocess .call (["gsettings" , "set" , "org.gnome.desktop.background" , "primary-color" , "#000000" ])
18- if de == "unity" :
19- subprocess .call (["gsettings" , "set" , "org.gnome.desktop.background" , "draw-background" , "true" ])
20- elif de == "mate" :
21- subprocess .call (["gsettings" , "set" , "org.mate.background" , "picture-filename" , file_path ])
22- elif de == 'i3' :
23- subprocess .call (['feh' ,'--bg-max' ,file_path ])
24- elif de == "xfce4" :
25- # Xfce4 displays to change the background of
26- displays = subprocess .getoutput ('xfconf-query --channel xfce4-desktop --list | grep last-image' ).split ()
27-
28- for display in displays :
29- subprocess .call (["xfconf-query" , "--channel" , "xfce4-desktop" , "--property" , display , "--set" , file_path ])
30- elif de == "lxde" :
31- subprocess .call (["pcmanfm" , "--set-wallpaper" , file_path , "--wallpaper-mode=fit" , ])
32- elif de == "mac" :
11+ if de == "mac" :
3312 subprocess .call (["osascript" , "-e" ,
3413 'tell application "System Events"\n '
3514 'set theDesktops to a reference to every desktop\n '
3615 'repeat with aDesktop in theDesktops\n '
3716 'set the picture of aDesktop to \" ' + file_path + '"\n end repeat\n end tell' ])
38- elif de == "kde" :
39- if plasma_version () > LooseVersion ("5.7" ):
40- ''' Command per https://github.com/boramalper/himawaripy/issues/57
41-
42- Sets 'FillMode' to 1, which is "Scaled, Keep Proportions"
43- Forces 'Color' to black, which sets the background colour.
44- '''
45- script = 'var a = desktops();' \
46- 'for (i = 0; i < a.length; i++) {{' \
47- 'd = a[i];d.wallpaperPlugin = "org.kde.image";' \
48- 'd.currentConfigGroup = Array("Wallpaper", "org.kde.image", "General");' \
49- 'd.writeConfig("Image", "file://{}");' \
50- 'd.writeConfig("FillMode", 1);' \
51- 'd.writeConfig("Color", "#000");' \
52- '}}'
53- try :
54- subprocess .check_output (["qdbus" , "org.kde.plasmashell" , "/PlasmaShell" ,
55- "org.kde.PlasmaShell.evaluateScript" , script .format (file_path )])
56- except subprocess .CalledProcessError as e :
57- if "Widgets are locked" in e .output .decode ("utf-8" ):
58- print ("Cannot change the wallpaper while widgets are locked! (unlock the widgets)" )
59- else :
60- raise e
17+ else : # Linux
18+ # gsettings requires it.
19+ fetch_envvar ("DBUS_SESSION_BUS_ADDRESS" )
20+ # feh and nitrogen (might) require it.
21+ fetch_envvar ("DISPLAY" )
22+
23+ if de in ["gnome" , "unity" , "cinnamon" , "pantheon" , "gnome-classic" ]:
24+ # Because of a bug and stupid design of gsettings, see http://askubuntu.com/a/418521/388226
25+ if de == "unity" :
26+ subprocess .call (["gsettings" , "set" , "org.gnome.desktop.background" , "draw-background" , "false" ])
27+ subprocess .call (["gsettings" , "set" , "org.gnome.desktop.background" , "picture-uri" , "file://" + file_path ])
28+ subprocess .call (["gsettings" , "set" , "org.gnome.desktop.background" , "picture-options" , "scaled" ])
29+ subprocess .call (["gsettings" , "set" , "org.gnome.desktop.background" , "primary-color" , "#000000" ])
30+ if de == "unity" :
31+ assert os .system ('bash -c "gsettings set org.gnome.desktop.background draw-background true"' ) == 0
32+ elif de == "mate" :
33+ subprocess .call (["gsettings" , "set" , "org.mate.background" , "picture-filename" , file_path ])
34+ elif de == 'i3' :
35+ subprocess .call (['feh' , '--bg-max' , file_path ])
36+ elif de == "xfce4" :
37+ # Xfce4 displays to change the background of
38+ displays = subprocess .getoutput ('xfconf-query --channel xfce4-desktop --list | grep last-image' ).split ()
39+
40+ for display in displays :
41+ subprocess .call (["xfconf-query" , "--channel" , "xfce4-desktop" , "--property" , display , "--set" , file_path ])
42+ elif de == "lxde" :
43+ subprocess .call (["pcmanfm" , "--set-wallpaper" , file_path , "--wallpaper-mode=fit" , ])
44+ elif de == "kde" :
45+ if plasma_version () > LooseVersion ("5.7" ):
46+ ''' Command per https://github.com/boramalper/himawaripy/issues/57
47+
48+ Sets 'FillMode' to 1, which is "Scaled, Keep Proportions"
49+ Forces 'Color' to black, which sets the background colour.
50+ '''
51+ script = 'var a = desktops();' \
52+ 'for (i = 0; i < a.length; i++) {{' \
53+ 'd = a[i];d.wallpaperPlugin = "org.kde.image";' \
54+ 'd.currentConfigGroup = Array("Wallpaper", "org.kde.image", "General");' \
55+ 'd.writeConfig("Image", "file://{}");' \
56+ 'd.writeConfig("FillMode", 1);' \
57+ 'd.writeConfig("Color", "#000");' \
58+ '}}'
59+ try :
60+ subprocess .check_output (["qdbus" , "org.kde.plasmashell" , "/PlasmaShell" ,
61+ "org.kde.PlasmaShell.evaluateScript" , script .format (file_path )])
62+ except subprocess .CalledProcessError as e :
63+ if "Widgets are locked" in e .output .decode ("utf-8" ):
64+ print ("Cannot change the wallpaper while widgets are locked! (unlock the widgets)" )
65+ else :
66+ raise e
67+ else :
68+ print ("Couldn't detect plasmashell 5.7 or higher." )
69+ elif has_program ("feh" ):
70+ print ("Couldn't detect your desktop environment ('{}'), but you have "
71+ "'feh' installed so we will use it..." .format (de ))
72+ subprocess .call (["feh" , "--bg-max" , file_path ])
73+ elif has_program ("nitrogen" ):
74+ print ("Couldn't detect your desktop environment ('{}'), but you have "
75+ "'nitrogen' installed so we will use it..." .format (de ))
76+ subprocess .call (["nitrogen" , "--restore" ])
6177 else :
62- print ("Couldn't detect plasmashell 5.7 or higher." )
63- elif has_program ("feh" ):
64- print ("Couldn't detect your desktop environment ('{}'), but you have "
65- "'feh' installed so we will use it..." .format (de ))
66- os .environ ['DISPLAY' ] = ':0'
67- subprocess .call (["feh" , "--bg-max" , file_path ])
68- elif has_program ("nitrogen" ):
69- print ("Couldn't detect your desktop environment ('{}'), but you have "
70- "'nitrogen' installed so we will use it..." .format (de ))
71- os .environ ["DISPLAY" ] = ':0'
72- subprocess .call (["nitrogen" , "--restore" ])
73- else :
74- return False
78+ return False
7579
7680 return True
7781
@@ -87,8 +91,11 @@ def get_desktop_environment():
8791 elif sys .platform == "darwin" :
8892 return "mac"
8993 else : # Most likely either a POSIX system or something not much common
94+ fetch_envvar ("DESKTOP_SESSION" )
9095 desktop_session = os .environ .get ("DESKTOP_SESSION" )
91- if desktop_session is not None : # Easier to match if we don't have to deal with caracter cases
96+
97+ if desktop_session is not None :
98+ # Easier to match if we don't have to deal with character cases
9299 desktop_session = desktop_session .lower ()
93100 if desktop_session in ["gnome" , "unity" , "cinnamon" , "mate" , "xfce4" , "lxde" , "fluxbox" ,
94101 "blackbox" , "openbox" , "icewm" , "jwm" , "afterstep" , "trinity" , "kde" , "pantheon" ,
@@ -111,6 +118,10 @@ def get_desktop_environment():
111118 return "windowmaker"
112119 elif desktop_session .startswith ("peppermint" ):
113120 return "gnome"
121+
122+ fetch_envvar ("KDE_FULL_SESSION" )
123+ fetch_envvar ("GNOME_DESKTOP_SESSION_ID" )
124+
114125 if os .environ .get ('KDE_FULL_SESSION' ) == 'true' :
115126 return "kde"
116127 elif os .environ .get ('GNOME_DESKTOP_SESSION_ID' ):
@@ -122,18 +133,19 @@ def get_desktop_environment():
122133 elif is_running ("ksmserver" ):
123134 return "kde"
124135
125- # We couldn't detect it so far, so let's try one last time
126- current_desktop = os .environ .get ("XDG_CURRENT_DESKTOP" )
127- if current_desktop :
128- current_desktop = current_desktop .lower ()
129- if current_desktop in ["gnome" , "unity" , "kde" , "gnome-classic" , "mate" ]:
130- return current_desktop
136+ # We couldn't detect it so far, so let's try one last time
137+ fetch_envvar ("XDG_CURRENT_DESKTOP" )
138+ current_desktop = os .environ .get ("XDG_CURRENT_DESKTOP" )
139+ if current_desktop :
140+ current_desktop = current_desktop .lower ()
141+ if current_desktop in ["gnome" , "unity" , "kde" , "gnome-classic" , "mate" ]:
142+ return current_desktop
131143
132- # Special Cases
133- elif current_desktop == "xfce" :
134- return "xfce4"
135- elif current_desktop == "x-cinnamon" :
136- return "cinnamon"
144+ # Special Cases
145+ elif current_desktop == "xfce" :
146+ return "xfce4"
147+ elif current_desktop == "x-cinnamon" :
148+ return "cinnamon"
137149
138150 return "unknown"
139151
@@ -162,3 +174,30 @@ def is_running(process):
162174 return True
163175 except subprocess .CalledProcessError :
164176 return False
177+
178+
179+ def fetch_envvar (varname ):
180+ """
181+ When himawaripy is called by cron or an init, the environment variables that
182+ are available to us is severely limited, causing problems with some
183+ processes we call (such as gsetings [due to lack of
184+ $DBUS_SESSION_BUS_ADDRESS for instance]).
185+
186+ To try fix this issue as much as we can, without resorting to additional
187+ shell scripts, we try fetching values of the environment variables we are
188+ interested in (before we access them!) from another process. pulseauido
189+ seemed to me a good choice, for it's available virtually on all desktop
190+ installations (regardless of DE), and seem to have all the environment
191+ variables that we are (potentially) interested in (*e.g.* gdm does NOT have
192+ $DISPLAY whereas pulseaudio do!)
193+ """
194+
195+ if varname in os .environ :
196+ return
197+
198+ val = os .popen ('bash -c "grep -z ^{}= /proc/$(pgrep -n pulseaudio)/environ | cut -d= -f2-"' .format (varname )).read ().strip ("\0 \n " )
199+ if val :
200+ print ("Fetched env. var. {} as `{}`" .format (varname , val ))
201+ os .environ [varname ] = val
202+ else :
203+ print ("Could NOT retrieve env. var. {}" .format (varname ))
0 commit comments