I want to make a "to-do" list my wallpaper. I was hoping to be able to write a text file, save it, and have the background be updated each time I edit file. Is this possible?
Asked
Active
Viewed 3,723 times
7
-
To my knowledge,this is not an existing functionality, but it may be something that can be scripted. – MGodby Dec 04 '14 at 20:48
2 Answers
11
The script below watches a textfile that you can edit. If the file is changed, it will create a new layer over your wallpaper with the text of the file.
Options
you can define:
- text size
- text color
- number of columns
- (max) number of lines per column
- border width (around the text blocks)
How to use
The script uses Imagemagick, you might have to install it first:
sudo apt-get install imagemagick
Then:
- Copy the script below into an empty file and save it as
walltext.py
. - Edit, if you want specific settings, the options in the head section of the script.
- Into the same folder, copy the wallpaper of your choice , name it (exactly)
original.jpg
N.B.- It is important that the proportions of your wallpaper match the proportions of your screen's resolution, else the text will not be positioned properly. - In the same folder, create an empty textfile named (exactly) notes.txt. This is the file to make your todolist or whatever you'd like to have on your screen.
Run the script by the command:
python3 /path/to/walltext.py
Now start editing your text file. Every five seconds, the wallpaper is updated if needed (after you saved the changes):
Examples
1 column, max 30 lines per column
2 columns, max 20 lines per column
3 columns, max 10 lines per column
The script
#!/usr/bin/env python3
import subprocess
import os
import time
curr_dir = os.path.dirname(os.path.realpath(__file__))
curr_wall = curr_dir+"/"+"original.jpg"
notes = curr_dir+"/"+"notes.txt"
#--
text_color = "white" # text color
size = "20" # text size (real size depends on the scale factor of your wallpaper)
border = 120 # space around your text blocks
columns = 2 # (max) number of columns
n_lines = 10 # (max) number of lines per column
#--
def run_command(cmd):
subprocess.call(["/bin/bash", "-c", cmd])
def get_value(cmd):
return subprocess.check_output(["/bin/bash", "-c", cmd]).decode("utf-8").strip()
def read_text(file):
with open(file) as src:
return [l.strip() for l in src.readlines()]
def slice_lines(lines, n_lines, columns):
markers = [i for i in range(len(lines)) if i % n_lines == 0]
last = len(lines); markers = markers+[last] if markers[-1] != last else markers
textblocks = [lines[markers[i]:markers[i+1]] for i in range(len(markers)-1)]
filled_blocks = len(textblocks)
if filled_blocks < columns:
for n in range(columns - filled_blocks):
textblocks.insert(len(textblocks), [])
for i in range(columns):
textblocks[i] = ("\n").join(textblocks[i])
return textblocks[:columns]
def create_section(psize, text, layer):
run_command("convert -background none -fill "+text_color+" -border "+str(border)+\
" -bordercolor none -pointsize "+size+" -size "+psize+\
" caption:"+'"'+text+'" '+layer)
def combine_sections(layers):
run_command("convert "+image_1+" "+image_2+" "+"+append "+span_image)
pass
def set_overlay():
boxes = slice_lines(read_text(notes), n_lines, columns)
resolution = get_value('identify -format "%wx%h" '+curr_wall).split("x")
w = str(int(int(resolution[0])/columns)-2*border)
h = str(int(resolution[1])-2*border)
layers = []
for i in range(len(boxes)):
layer = curr_dir+"/"+"layer_"+str(i+1)+".png"
create_section(w+"x"+h, boxes[i], layer)
layers.append(layer)
run_command("convert "+(" ").join(layers)+" "+"+append "+curr_dir+"/"+"layer_span.png")
wall_img = curr_dir+"/"+"walltext.jpg"
run_command("convert "+curr_wall+" "+curr_dir+"/"+"layer_span.png"+" -background None -layers merge "+wall_img)
run_command("gsettings set org.gnome.desktop.background picture-uri file:///"+wall_img)
for img in [img for img in os.listdir(curr_dir) if img.startswith("layer_")]:
os.remove(curr_dir+"/"+img)
while True:
text_1 = read_text(notes)
time.sleep(5)
text_2 = read_text(notes)
if text_2 != text_1:
set_overlay()
Notes
- More options can be added to the script, more info on Imagemagick's options can be found here.

Jacob Vlijm
- 83,767
-
This is perfect for what I need, except one thing: Can I make it so that it does this over my current background? i.e. instead of bg_color = "white" somehow make it overlay? I'll mark as solved either way. Thanks so much! – GuyfromAmsterdam Dec 04 '14 at 23:09
-
Thanks again! It seems to work pretty well, however, if I add an apostrophe (but not a quotation mark) it doesn't seem to recognise that sentence, and will refuse to write it. Like this: http://i.imgur.com/NqoU2X3.gif – GuyfromAmsterdam Dec 04 '14 at 23:41
-
also, is there a way to change alignment/ make two columns? Lot's of questions, but this is fantastic! – GuyfromAmsterdam Dec 04 '14 at 23:51
-
-
@GuyfromAmsterdam the ' is easy to fix, I will update my answer later this morning. – Jacob Vlijm Dec 05 '14 at 07:04
-
thanks! it also seems to not work on startup (i.e. adding python3 /desitnationfile to startup applications). Thanks again for being so helpful! – GuyfromAmsterdam Dec 05 '14 at 07:50
-
-
-
@GuyfromAmsterdam and your command =
python3 /home/joop/Documents/ubuntu/walltext.py
? – Jacob Vlijm Dec 05 '14 at 07:56 -
@GuyfromAmsterdam fixed the quote issue, will add the overlay and column (free to set any number of columns) function after the weekend. About the startup applications: It must be a typo, is your command
python3 /home/joop/Documents/ubuntu/walltext.py
(Don't forget thepython3
unless you made it executable)? Isn't the file located in a subfolder? – Jacob Vlijm Dec 05 '14 at 09:52 -
I had the command right, but I got it to work through making it executable, and setting the file itself as what's being opened by the startup applications! – GuyfromAmsterdam Dec 05 '14 at 12:27
-
-
It's perfect. Thank you so much. I had some issues with resizing the image but once that worked out the text was perfectly sized too. Thanks again! – GuyfromAmsterdam Dec 08 '14 at 21:00
-
this is great, @JacobVlijm can you make this script available on github with a license , please ? – Jul 07 '16 at 09:12
-
@ALJIMohamed thanks a lot! I think I will :) I might smoothen it a bit to make it easyer to use. Thatnks for the suggestion! – Jacob Vlijm Jul 07 '16 at 09:18
-
-
-1
I've modified the code above to put random quotes on the wallpaper every hour. Enjoy :) http://forraskod.blogspot.hu/2016/01/linux-hatterkep-veletlenszeru.html
#!/usr/bin/env python3
import subprocess
import os
import time
import random
curr_dir = os.path.dirname(os.path.realpath(__file__))
curr_wall = curr_dir+"/"+"original.jpg"
notes = curr_dir+"/"+"notes.txt"
#--
text_color = "white" # text color
size = "80" # text size (real size depends on the scale factor of your wallpaper)
border = 480 # space around your text blocks
columns = 1 # (max) number of columns
n_lines = 3 # (max) number of lines per column
#--
def run_command(cmd):
subprocess.call(["/bin/bash", "-c", cmd])
def get_value(cmd):
return subprocess.check_output(["/bin/bash", "-c", cmd]).decode("utf-8").strip()
def read_text(file):
with open(file) as src:
return [l.strip() for l in src.readlines()]
def slice_lines(lines, n_lines, columns):
markers = [i for i in range(len(lines)) if i % n_lines == 0]
last = len(lines); markers = markers+[last] if markers[-1] != last else markers
textblocks = [lines[markers[i]:markers[i+1]] for i in range(len(markers)-1)]
filled_blocks = len(textblocks)
if filled_blocks < columns:
for n in range(columns - filled_blocks):
textblocks.insert(len(textblocks), [])
for i in range(columns):
textblocks[i] = ("\n").join(textblocks[i])
return textblocks[:columns]
def create_section(psize, text, layer):
run_command("convert -background none -fill "+text_color+" -border "+str(border)+\
" -bordercolor none -pointsize "+size+" -size "+psize+\
" caption:"+'"'+text+'" '+layer)
def combine_sections(layers):
run_command("convert "+image_1+" "+image_2+" "+"+append "+span_image)
pass
def set_overlay(): # Read the file "notes" as specified above, display text in columns
boxes = slice_lines(read_text(notes), n_lines, columns)
resolution = get_value('identify -format "%wx%h" '+curr_wall).split("x")
w = str(int(int(resolution[0])/columns)-2*border)
h = str(int(resolution[1])-2*border)
layers = []
for i in range(len(boxes)):
layer = curr_dir+"/"+"layer_"+str(i+1)+".png"
create_section(w+"x"+h, boxes[i], layer)
layers.append(layer)
run_command("convert "+(" ").join(layers)+" "+"+append "+curr_dir+"/"+"layer_span.png")
wall_img = curr_dir+"/"+"walltext.jpg"
run_command("convert "+curr_wall+" "+curr_dir+"/"+"layer_span.png"+" -background None -layers merge "+wall_img)
run_command("gsettings set org.gnome.desktop.background picture-uri file:///"+wall_img)
for img in [img for img in os.listdir(curr_dir) if img.startswith("layer_")]:
os.remove(curr_dir+"/"+img)
def set_single_overlay(): # DEFAULT, read 1 line from "notes" file as specified above
resolution = get_value('identify -format "%wx%h" '+curr_wall).split("x")
w = str(int(int(resolution[0])/columns)-2*border)
h = str(int(resolution[1])-2*border)
layers = []
layer = curr_dir+"/"+"layer_1.png"
#print(w)
#print(h)
create_section(w+"x"+h, text_1, layer)
layers.append(layer)
run_command("convert "+(" ").join(layers)+" "+"+append "+curr_dir+"/"+"layer_span.png")
wall_img = curr_dir+"/"+"walltext.jpg"
run_command("convert "+curr_wall+" "+curr_dir+"/"+"layer_span.png"+" -background None -layers merge "+wall_img)
run_command("gsettings set org.gnome.desktop.background picture-uri file:///"+wall_img)
for img in [img for img in os.listdir(curr_dir) if img.startswith("layer_")]:
os.remove(curr_dir+"/"+img)
print("Walltext started.")
print (curr_wall)
print (notes)
while True:
text_1 = random.choice(open(notes).readlines())
print(text_1)
set_single_overlay()
time.sleep(3600)
# text_2 = read_text(notes)
# if text_2 != text_1:
# set_overlay()
-
1While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review – Pilot6 Jan 24 '16 at 22:19
-