I am using a large 4K monitor with multiple work spaces each having multiple applications. When rebooting Ubuntu 18.04, the locations of the application windows are lost and it takes me several minutes to reconfigure them. How can I save and recover the window positions within the work spaces?
3 Answers
The Gnome Extension "Auto Move Windows" will move applications to a specified workspace when they are opened. The location of the application windows within the workspace are also remembered. See, https://extensions.gnome.org/extension/16/auto-move-windows/
Note that there are solutions for prior versions of Ubuntu (w/ Unity) that use scripts. However, Ubuntu switched back to using Gnome in 18.04. (e.g., Saving and restoring window positions and How can I start up an application with a pre-defined window size and position?)

- 99,918

- 783
- 8
- 19
This does what you're looking for!
https://github.com/johannesjo/gnome-shell-extension-window-session-manager

- 121
- 3
I just wrote this python script to open different applications and move them to specific workplaces on boot up. It works for me on Ubuntu 20. Only dependency besides python is wmctrl
(which might be installed by default on Ubuntu?). Have it run on startup - I put it in Startup Applications with python3 /path/to/script.py
in the Command field.
There are probably optimizations to make here but leaving it to be used/changed by anyone struggling with this. If using the script as is, change the apps
list to hold the programs you want. Only change the first 3 elements of each tuple in list - first is command to launch the program from a terminal, second is workspace number, third is string to identify program in output from wmctrl -l
- e.g. with line 0x02200005 8 fiona New Tab - Google Chrome
in wmctrl
output, search term could be Google Chrome
.
import subprocess
import time
import datetime
def run_command_in_background(command):
# command is list of strings
subprocess.Popen(command)
def get_wmctrl_lines():
return subprocess.run(["wmctrl", "-l"], capture_output=True, text=True).stdout.splitlines()
finito_ids = set()
def get_running_app_window_id_desktop_nb(search_term):
for line in get_wmctrl_lines():
if search_term in line.lower():
split = line.split()
window_id = split[0]
if window_id not in finito_ids:
return split[0], int(split[1])
return None, None
def move_window_to_desktop(window_id, desktop_number):
# desktop = workspace??
run_command_in_background(["wmctrl", "-i", "-r", str(window_id), "-t", str(desktop_number)])
apps = [
# app_command, desktop_nb, search_term, should_be_full_screen, has_been_spawned, has_been_formatted
(["vivaldi"],2,"vivaldi",False,False,False),
(["terminator"],3,"/bin/bash",True,False,False),
(["terminator"],4,"/bin/bash",True,False,False),
(["terminator"],5,"/bin/bash",True,False,False),
(["snap","run","spotify"],6,"spotify",False,False,False),
(["google-chrome"],8,"chrome",False,False,False),
]
move apps
while False in [a[-1] for a in apps]:
new_apps = []
for app in apps:
app_command, desktop_nb, search_term, should_be_full_screen, has_been_spawned, has_been_formatted = app
if not has_been_spawned:
run_command_in_background(app_command)
has_been_spawned = True
else:
app_window_id, current_desktop_nb = get_running_app_window_id_desktop_nb(search_term)
if app_window_id is not None:
run_command_in_background(["wmctrl", "-i", "-r", app_window_id, "-t", str(desktop_nb)])
if should_be_full_screen:
run_command_in_background(["wmctrl", "-i", "-r", app_window_id, "-b", "toggle,fullscreen"])
has_been_formatted = True
finito_ids.add(app_window_id)
else:
print("app %s still not running" % search_term)
new_apps.append((app_command, desktop_nb, search_term, should_be_full_screen, has_been_spawned, has_been_formatted))
apps = new_apps
time.sleep(1)
send notification that everything is ready
run_command_in_background(["notify-send", "Hola we", "apps/workspaces are set up"])

- 205