How to force an application window to be automatically maximized after starting the application?

I tried to use Docky, then I removed it and after that my browser (Chromium) can’t be opened in maximum height, every time I should maximize it myself. (XFCE desktop)

Asked By: R S

||

How to startup an application (any) maximized

Starting an application via the script below, you can force any application* to startup maximized. If you either replace the main command in (a copy of-) your .desktop file by the command to run the script (see further below how to do that) or add it as a quicklist shortcut, you can achieve exactly what you want.

(* Some applications have a fixed, unchangeable windowsize, some windows open a new tab in a possibly already opened window)

About the script

The script runs with the command:

python3 /path/to/script <application>

The script:

  • first runs the command to open the application
  • to prevent timing issues, it then waits for the application’s (new) window to appear (by finding a match between its pid and the id of the corresponding window) in the output of the wmctrl -lp -command (for only 15 seconds, to prevent an infinite loop)
  • Once the window appears, it maximizes the window with the command:

    xdotool windowsize <window_id> 100% 100%
    

The code

#!/usr/bin/env python3
import subprocess
import getpass
import time
import sys

app = sys.argv[1]

user = getpass.getuser()
get = lambda x: subprocess.check_output(x).decode("utf-8")
ws1 = get(["wmctrl", "-lp"]); t = 0
subprocess.Popen(app)
while t < 30:      
    ws2 = [(w.split()[2], w.split()[0]) for w in get(["wmctrl", "-lp"]).splitlines() if not w in ws1]
    procs = sum([[(w[1], p) for p in get(["ps", "-u", user]).splitlines() 
              if app[:15].lower() in p.lower() and w[0] in p] for w in ws2], [])
    if len(procs) > 0:
        subprocess.call(["xdotool", "windowsize", "-sync", procs[0][0] , "100%", "100%"])
        break
    time.sleep(0.5)
    t = t+1

How to use

  1. The script needs both wmctrl and xdotool

    sudo apt-get install wmctrl xdotool
    
  2. Copy the script above into an empty file, save it as run_maximized.py

  3. Now edit your .desktop file:

    • Copy the global .desktop file locally:

      cp /usr/share/applications/chromium-browser.desktop ~/.local/share/applications
      

XFCE version:

  1. open the file with gedit:

    gedit ~/.local/share/applications/chromium-browser.desktop
    

    Browse to the line:

    Exec=chromium-browser %U
    

    (which is the first line, starting with Exec=

    Change it into:

    Exec=python3 /path/to/script.py chromium-browser
    

    where you need to replace /path/to/script.py by the actual path.

  2. Log out and back in. From now on, your Chromium launcher will open Chromium maximized.

Unity version:

  1. open the file with gedit:

    gedit ~/.local/share/applications/chromium-browser.desktop
    

    Browse to the line:

    Actions=NewWindow;Incognito;TempProfile;
    

    Change it into:

    Actions=NewWindow;Incognito;TempProfile;divider1;Open maximized;
    

    The add to the very bottom of the file the section below:

    [Desktop Action Open maximized]
    Name=Open maximized
    Exec=python3 /path/to/script.py chromium-browser
    OnlyShowIn=Unity;
    
    [Desktop Action divider1]
    Name=.....................................
    OnlyShowIn=Unity;
    

    where you need to replace /path/to/script.py by the actual path.

  2. Log out and back in. From now on, your Chromium launcher looks like:

    enter image description here

Important note

In a .desktop file, you must use absolute paths; ~ won’t work for example. This counts for .desktop files in /usr/share/applications, ~/.local/share/applications as well as commands in Startup Applications (which are actually called by .desktop files in ~/.config/autostart).

Answered By: Jacob Vlijm

It’s not 100% foolproof, but a much simpler approach is to modify the Exec= line in an existing .desktop file and run xdotool search --sync there directly. This waits for the window to be mapped, and avoids hard-coded delays. Not to disparage the hard work Jacob put into that Python script, but it does seem exorbitant for what is essentially a one-liner in the shell.

Here’s an example, using Alacarte (a GUI editor for the system menus):

Exec=sh -c 'alacarte & xdotool search --sync --onlyvisible --class alacarte windowsize 100%% 100%%'

Note the & which—critically—puts the application in the background. Also note that % must be escaped as %% within the Exec key.

By "not 100% foolproof" I mean the process of editing .desktop files by hand is very typo-prone, and you’re unlikely to get a good error message from anywhere if you mess something up. You’ll usually just get… nothing. The utility dex (available in the "universe" repository) can run a .desktop file directly from the shell and its -v option may help with debugging.

It is possible to edit the .desktop file directly in /usr/share/applications (as root), but it’s probably best to use Alacarte or MenuLibre to create one in ~/.local/share/applications, so your changes aren’t overwritten by future package update. Both should be available from the "universe" repository on Ubuntu and derivatives.

Lastly, if you edit the .desktop file by hand, run update-desktop-database in the containing directory to update the cache, otherwise it may seem like nothing happened.

Answered By: TheDudeAbides