Startup script for my Linux desktop

bad
setup
Debian
tools
Published

February 24, 2023

Modified

March 11, 2023

Introduction

This is my startup.sh script, to open various apps and webpages when I log in to my Linux PC, and arrange them on my workspaces.

Testing and debugging this script is a bit annoying. My previous approach was to make fixes to the script, close everything, exit my desktop session, then log in again and see what happens. Another possibility is to copy-paste lines out of the script into the terminal.

Now I’m going to try developing the script as a Jupyter notebook with the Bash kernel. I will also generate the shell script from the notebook.

I’ve included a couple of “appendices”, with lists of the tools and scripts I am using.

Workspaces and Apps

I use two monitors:

  1. Left monitor, doesn’t switch workspaces, for apps that I want always to hand.
  2. Right monitor, widescreen, does switch between workspaces, for work.

Apps on left monitor:

  1. Gnome Pomodoro - timer
  2. Trello - tasks planner
  3. ChatGPT - AI assistant
  4. Miniflux - blog reader
  5. Anki - learning with flashcards
  6. Swatch - my system monitor script

I am currently using these workspaces:

  1. Entertainment
    • playing music
    • watching movies
    • xterm with GNU screen
  2. Chat and Social
    • Discord
    • Slack
  3. Miscellaneous
    • sysadmin
    • random stuff
  4. AI Study
    • Jupyter notebook
    • Quarto blog
    • xterm with GNU screen

I can add extra workspaces as needed when I work on other projects.

The startup script

#!/bin/bash
# usage: source from ~/.xsessionrc
# set Right Alt to be the compose key, so I can type — em-dashes and such!
setxkbmap -option compose:ralt
sleep 1
gnome-dark
connects &
wmctrl -s 0

Common apps on the left monitor

chrome_profile Sam --new-window \
"https://trello.com/b/dnuAgKw1/ai" \
"https://trello.com/b/y16reUe3/misc" \
"https://chat.openai.com/chat" \
&
gnome-pomodoro &
barrier &
anki &
swatch &
# flameshot &
# miniflux &
# chatgpt &
# Sleep for a bit, and try to get out of the Activities Overview
sleep 5; xdotool key 'Super'; sleep 1 ; xdotool key 'Escape'
wmctrl -r Trello -e 0,960,0,960,1080
wmctrl -r pomodoro -e 0,0,0,400,400
wmctrl -r Barrier -e 0,400,0,400,400
wmctrl -r Anki -e 0,0,0,960,1080
xdotool search --name swatch windowmove 600 100

for app in Trello pomodoro Anki swatch Trello Miniflux; do
    wmctrl -r "$app" -b add,sticky
done
wmctrl -r pomodoro -b add,above
wmctrl -r swatch -b add,above

for app in barrier; do wmctrl -c $app; done
for app in swatch pomodoro; do xdotool search --name $app windowminimize %@; done
Opening in existing browser session.
libva error: vaGetDriverNameByIndex() failed with unknown libva error, driver_name = (null)
[1]+  Done                    chrome_profile Sam --new-window "https://trello.com/b/dnuAgKw1/ai" "https://trello.com/b/y16reUe3/misc" "https://chat.openai.com/chat" "https://chat.openai.com/chat" "https://miniflux.ucm.dev/unread" "https://www.youtube.com/playlist?list=PLqkzs79RU9yUrYAN083Jbiza9DMqQE1dq"
gnome-pomodoro --start

Apps on Workspace 1: Entertainment

chrome --new-window \
'https://sigmoid.social/' \
'https://www.facebook.com/' \
'https://www.twitter.com/' \
'https://www.linkedin.com/' \
'https://www.reddit.com/' \
"https://miniflux.ucm.dev/unread" \
"https://news.ycombinator.com/best" \
"https://chat.openai.com/chat" \
&
sleep 2
wmctrl -r "Sigmoid Social" -e 0,1920,0,1720,1440
chrome --new-window \
"https://www.youtube.com/playlist?list=PLqkzs79RU9yUrYAN083Jbiza9DMqQE1dq" \
'https://www.netflix.com/browse' \
'https://www.disneyplus.com/' \
'https://primevideo.com/' \
'https://www.youtube.com/' \
&
sleep 2
wmctrl -r "my music" -e 0,3640,0,1720,1440

Apps on Workspace 2: Miscellaneous

sleep 2
wmctrl -s 1
chrome_profile Sam --new-window & sleep 1 ; xtile -w `xactivewindow` /2 1 1
sleep 2
nautilus ~/plan.dev & sleep 1; wmctrl -r plan.dev -e 0,3640,0,400,400
sw misc sh
xterm -e "stty -ixon; xtile /2+1 1 1 ; sxw misc sh ; exec $SHELL" & sleep 2
sstuff misc sh "^L"

Apps on Workspace 3: Chat and Social

sleep 2
wmctrl -s 2
slack & # --startup &
discord & # --start-minimized &
chrome_profile Sam --new-window & sleep 1 ; xtile -w `xactivewindow` /2 1 1
sleep 5
wmctrl -r Slack -e 0,1920,0,1720,1440
wmctrl -r Discord -e 0,3640,0,1720,1440

Apps on Workspace 4: AI Study

sleep 2
wmctrl -s 3
cd ~/ai

zotero &

. ~/my/ai.env

xterm -e "stty -ixon; xtile /3+2 1 1 ; s ai ; exec $SHELL" & sleep 2

sw ai jup
sw ai quarto
sw ai sh

#       xterm -e "stty -ixon; xtile /3+2 1 1 ; sxw ai sh ; exec $SHELL" & sleep 2
sstuff ai sh "^L"

chrome_profile Sam --new-window \
"https://forums.fast.ai/c/part-2-2022/57" \
"https://walkwithfastai.com/revisited/" \
&
sleep 1 ; xtile -w `xactivewindow` 1 1 0

sst ai jup jup ; sleep 2 ; xtile -w `xactivewindow` /3 1 1
sst ai quarto quarto preview blog --no-browser --port 4242

chrome --new-window "http://localhost:4242" & sleep 1 ; xtile -w `xactivewindow` /3+1 1 1

screen -S ai -X shelltitle sh
sleep 2
xdotool search --name zotero windowminimize %@

Exporting the shell script

I might put this in a separate script or tool later; as it is, I can run it from the notebook.

# __END__
cd ~/ai/blog/posts/startup
jupyter nbconvert --no-prompt --to script startup.ipynb --stdout \
--TemplateExporter.exclude_raw=True |
sed -n '/^# __END__/q; p' > startup.sh
chmod +x startup.sh
[NbConvertApp] Converting notebook startup.ipynb to script
mv -v ./startup.sh ~/local/x/startup.sh
renamed './startup.sh' -> '/home/sam/local/x/startup.sh'

Logging out to test the script

This notebook can helpfully kill itself, an unusual characteristic for a notebook!

close_all() {
        while wmctrl -c "$1"; do sleep 0.2; done
}
close_all Anki
close_all 'Google Chrome'
sleep 5
killall screen Xorg

Conclusion

In this blog post, I’ve shared my startup.sh script for my Linux desktop, which opens various apps and webpages when I log in and arranges them on my workspaces. I’ve also explained how I test and debug the script, and shown how I am developing it as a Jupyter notebook with the Bash kernel. By exporting the shell script from the notebook, I can easily run it whenever I need to. I hope that this script is useful as an example to others who want to automate their desktop environment and increase their productivity; or at least a little interesting.

I like this script in that helps me keep my workspaces organized right away when I log in. However, I spend too much time tweaking it, which can eat up valuable time that could be spent on actual work.

To be honest, I think it was fairly bonkers of me to go to this level of effort to set up my windows just so at startup. You probably shouldn’t imitate such bizarre nerdish behaviour!

Thanks for reading.

Appendix 1: tools and programs that I use here

  • Jupyter notebook with the Bash kernel for developing and testing my startup script
  • Bash shell scripting language
  • Gnome desktop environment
  • Xorg display server
  • setxkbmap allows to change the keyboard layout and options
  • wmctrl for controlling windows on your desktop
  • xdotool for simulating keyboard and mouse input, and controlling windows
  • Chrome web browser
  • Trello for task planning
  • ChatGPT for an AI assistant
  • Miniflux for a blog reader
  • Anki for learning with flashcards
  • Perl programming language for the xtile script
  • Screen for creating and managing terminal sessions
  • Slack for team communication
  • Discord for voice and text chat
  • Nautilus file manager
  • Zotero for reference management
  • Gnome Pomodoro for timing my work and taking breaks
  • xterm for a command line with a nice bitmap font (misc fixed 6x13)
  • ssh for connecting to remote servers using the command-line interface.
  • Barrier for sharing a keyboard and mouse across multiple computers as a software KVM switch.

Appendix 2: scripts that I wrote and used here

  • gnome-dark: A Bash script that sets the Gnome desktop environment to use the Adwaita-dark theme and a dark color scheme.
  • gnome-light: A Bash script that sets the Gnome desktop environment to use the Adwaita theme and a light color scheme.
  • connects: A Bash script that connects to several remote hosts using the connect command and runs them in the background.
  • connect: A Bash script that uses ssh to connect to remote servers specified as command-line arguments, with some connection options set.
  • chrome_profile: A Bash script that launches Google Chrome with a specific profile.
  • chrome_profile_key: A Bash script that returns the key for a specific Chrome profile.
  • chrome_profiles_list: A Bash script that lists all Chrome profiles and their keys.
  • swatch: A Bash script that launches a terminal window and displays system information using the watch command and other tools.
  • xtile: A Perl script that tiles a window on a specific screen, with options for the window size and position.
  • s: A Bash script that launches the screen command with some default options, and any additional arguments.
  • sw: A Bash script that creates a new screen and window, with an optional directory.
  • sxw: A Bash script that attaches to a specific screen window using the screen command.
  • sstuff: A Bash script that sends keystrokes to a specific screen window using the screen command.