Is there any way to have a different background for each workspace without using CCSM? I've read a few horror stories and would rather avoid it if possible. I'm using Raring Ringtail (13.04)
-
@cipricus Do you have a fixed number of workspaces or should the solution handle a variable number of workspaces? Unity or Xubuntu? (both can be done).– Jacob VlijmDec 12, 2014 at 17:08
-
@JacobVlijm: personally I need 2, but 4 would be what many prefer I think. Unity is the assumed environment if not specified otherwise. Give an answer as large as possible and I will give you even a bigger bounty if the case. But mind that its without CCSM for the reason mentioned in the question: so, the alternative shouldn't be as risky as that.– user47206Dec 12, 2014 at 19:37
-
@JacobVlijm - see why without CCSM; I would prefer an answer that would not be too complicated. The question is 'simple'. :)– user47206Dec 12, 2014 at 20:10
1 Answer
Having different wallpapers on different workspaces without using ccsm
The script below does not use compiz settings manager, but it assumes:
python3
is installed (if not let me know)wmctrl
is installed (to fetch the data on the workspaces). You might need to install it: sudo apt-get install wmctrl
It works no matter the number of workspaces; it calculates the number of columns of the workspaces and the row of the current workspace, and sets the user defined wallpaper for that (current) workspace.
After the script is started, just switch to the different workspaces and set the wallpaper in the "normal" (GUI) way. The script keeps track of the wallpaper(s) per workspace in a small file it creates. That should not cause any lag in performance, since the file is only read when the script initiates, or when the wallpapers per workspace are changed by the user.
The script
#!/usr/bin/env python3
import subprocess
import time
import os
key1 = "gsettings set org.gnome.desktop.background picture-uri "
key2 = "gsettings get org.gnome.desktop.background picture-uri"
def write_wspaces(file, current):
with open(file, "wt") as wt:
wt.write(current)
def read_wspaces(file):
with open(file) as src:
return src.read().strip()
def get_info(command):
return subprocess.check_output(["/bin/bash", "-c", command]).decode("utf-8")
def get_currwallpaper():
return get_info(key2).replace("file://", "").strip()
# get resolution
output = get_info("xrandr").split(); idf = output.index("current")
res = (int(output[idf+1]), int(output[idf+3].replace(",", "")))
def calculate_geometry():
# get viewport data
vp = get_info("wmctrl -d").split(" ")
span = vp[4].split("x"), vp[7].split(",")
# calculate number of (horizontal) viewports
n_vps_hor = int(int(span[0][0])/int(res[0]))
n_vps_vert = int(int(span[0][2])/int(res[1]))
n_wspaces = int(n_vps_hor)*int(n_vps_vert)
# calculate current viewport
curr_vp_hor = int((int(span[1][0])/int(res[0]))+1)
curr_vp_vert = int((int(span[1][3])/int(res[1]))+1)
return ((curr_vp_vert-1)*n_vps_hor)+curr_vp_hor, n_wspaces
home = os.environ["HOME"]
wspaces = home+"/"+".config/wall_wspaces"
if not os.path.exists(wspaces):
os.makedirs(wspaces)
if not os.path.exists(wspaces+"/wspaces.txt"):
current = get_currwallpaper().replace("'", "")
writelist = []; [writelist.append(current) for i in range(calculate_geometry()[1])]
write_wspaces(wspaces+"/wspaces.txt", str(writelist))
wall_list = eval(read_wspaces(wspaces+"/wspaces.txt"))
while True:
curr_vp1 = calculate_geometry()[0]; currwallpaper1 = get_currwallpaper()
time.sleep(2)
curr_vp2 = calculate_geometry()[0]; currwallpaper2 = get_currwallpaper()
if curr_vp1 != curr_vp2:
command = key1+"file://"+str(wall_list[curr_vp2-1])
subprocess.Popen(["/bin/bash", "-c", command])
elif currwallpaper1 != currwallpaper2:
wall_list = eval(read_wspaces(wspaces+"/wspaces.txt"))
wall_list[int(curr_vp2)-1] = currwallpaper2
write_wspaces(wspaces+"/wspaces.txt", str(wall_list))
else:
pass
How to use
Simply copy the script into an empty file, save it as workspace_walls.py
and run it by the command:
python3 /path/to/workspace_walls.py
If it works as you like it to, add it to your startup applications: Dash > Startup Applications > Add
Edit:
Below a completely rewritten version of the script, to the model of this one.
The script (with a few minor differences) + GUI is also available as ppa
:
sudo add-apt-repository ppa:vlijm/wswitcher
sudo apt-get update
sudo apt-get install wswitcher
#!/usr/bin/env python3
import subprocess
import os
import time
workspace_data = os.environ["HOME"]+"/.wallpaper_data_"
key = [
"gsettings get ",
"gsettings set ",
"org.gnome.desktop.background picture-uri",
]
def getwall():
return subprocess.check_output(
["/bin/bash", "-c", key[0]+key[2]]
).decode("utf-8").strip()
def get_res():
# get resolution
xr = subprocess.check_output(["xrandr"]).decode("utf-8").split()
pos = xr.index("current")
return [int(xr[pos+1]), int(xr[pos+3].replace(",", "") )]
def current():
# get the current viewport
res = get_res()
vp_data = subprocess.check_output(
["wmctrl", "-d"]
).decode("utf-8").split()
dt = [int(n) for n in vp_data[3].split("x")]
cols = int(dt[0]/res[0])
curr_vpdata = [int(n) for n in vp_data[5].split(",")]
curr_col = int(curr_vpdata[0]/res[0])+1
curr_row = int(curr_vpdata[1]/res[1])
return str(curr_col+curr_row*cols)
curr_ws1 = current()
currwall1 = getwall()
while True:
time.sleep(1)
currwall2 = getwall()
# print(currwall2)
curr_ws2 = current()
datafile = workspace_data+curr_ws2
if curr_ws2 == curr_ws1:
if currwall2 != currwall1:
open(datafile, "wt").write(currwall2)
else:
if not os.path.exists(datafile):
open(datafile, "wt").write(currwall2)
else:
curr_set = open(datafile).read()
command = key[1]+key[2]+' "'+str(curr_set)+'"'
subprocess.Popen(["/bin/bash", "-c", command])
curr_ws1 = curr_ws2
currwall1 = getwall()
Budgie now supported
Added support for Budgie on July 21, 2017 for Zesty, when installed from the ppa (see above)
-
I have run it with 2 and 4 workspaces and I think it works as intended. only that what it does is that it changes the wallpaper each time when I click/select a workspace to the WP designated by the script to that WS, which leads to that typical lag normal when a wallpaper is set for the first time.. that is, all WS have the same WP, namely the one that is set by the script to the last selected WS, until a new WS is selected.when I use hotcorner to show WS they all have the same WP, which is changed (for all) when I select a new WS.– user47206Dec 12, 2014 at 22:38
-
1@cipricus that is true, I am not sure if the ccsm version is different? (never used that) Dec 12, 2014 at 22:39
-
we'll see about that. maybe i will give ccsm a try although i have avoided touching that thing till now :) the bounty needs 16 hours to be granted. that lag is a problem especially with conky, the transition is not smooth– user47206Dec 12, 2014 at 22:43
-
ccsm is a nasty piece!! unity crashed and all that! conky, plank, logout, all wrong– user47206Dec 12, 2014 at 23:03
-
1@cipricus simplified use of the script; simply run it and set wallpapers via GUI per workspace as usual (no more list editing in the script) Dec 13, 2014 at 13:23