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 3


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?)


This does what you're looking for!



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

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

# 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:
            has_been_spawned = True
            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
                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

# send notification that everything is ready
run_command_in_background(["notify-send", "Hola we", "apps/workspaces are set up"])

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.