Using commands to resize programs in Linux
Neither Linux nor Windows remembers the window size and position for applications.
A minority of programs retain their dimensions and position upon exit. For the rest, it feels as if a mischievous spirit is deciding randomly: “Where should we put it this time?”
It is disappointing that such a basic and important feature is still largely ignored by developers of both operating systems. As a result, we must rely on separate tools to address this issue while less significant concerns are prioritized.
In this article, we will explore options to modify window sizes and positions using commands and scripts.
Geometry
Occasionally, Linux applications support setting geometry, which more than solves this problem, but only for those specific apps.
Geometry is a special string containing four numbers:
- Window width
- Window height
- Starting position in pixels from left screen border
- Starting position in pixels from top screen border
We can append this special geometry string to some programs when we start them from command line. This functionality must be implemented by the developer within the app.
There are also programs that can set any graphical window’s parameters through special commands. The following article explains both methods in detail.
The first two parameters determine window’s size vertically and horizontally, while the other two specify where the top-left corner of the application is on our monitor. Here’s an example:
1200x600+20+0
Assuming we have a 1080p monitor, its exact resolution is 1920x1080. Here, the program window is being set to 1200 pixels wide and 600 pixels high. It will occupy a considerable amount of space on our monitor.
The third number indicates that we want our program to be 20 pixels from the left border of our monitor. The last number means it will start at pixel 0 from the top. In other words, there will be no space between our program’s top border and the monitor’s top border.
Notice the two pluses at the end. We can either put ‘+’ or ‘-‘ in front of each of the last two numbers. Plus means ‘pixels from the left edge of the screen’, while minus means ‘pixels from the right edge of the screen’.
Sometimes it is more convenient to align our windows from the right side, so it is great that we have this flexibility.
Of course, pixels then align towards the left side, just like when we get an order to move our piece of furniture 20 cm from the right wall; we move it to the left instead of trying to demolish the wall and put it inside.
Without the option to align from the right side with minuses, if we wanted to set it 20 pixels from the right, we’d have to calculate each time: current monitor resolution - (window width + 20px). It would be very cumbersome to do this.
Not all window managers on Linux support geometry, so make sure that the one in your distribution does before starting to tinker with it. Fortunately, all the popular ones (and many less popular ones) do, so it is likely that yours does too.
Another thing to consider is that some window managers have different window ‘states’. For example, in i3, windows can be either floating or tiling. Geometry only works for floating windows. However, if you’re using a tiling window manager, you are likely doing so intentionally and already know about this distinction.
As mentioned at the beginning of this article, some programs support setting geometry at startup. In those cases, the magic formula almost always looks like this shell command:
It is super useful for multi-monitor setups. Sometimes, we want to start the player on monitor one. Tutorials, we might want to watch on monitor 2, a TV show on our TV, which is set up as monitor 3.
We can have different commands to start the same player in these different contexts, which is more powerful than system-wide memory of last known window state (which nevertheless needs to be implemented).
Getting window geometry
Finding out exact position and dimensions of our window does not require print-screening entire desktop and then probing it in an image editor.
It’s very simple. We just resize the window to our liking, position it where we want on our screen and run a command to find out its dimensions.
For that, a program called xwininfo is needed. It has many more uses than just geometry, but since right now it is all we need, we enter this command into our console:
This is super useful for multi-monitor setups. Sometimes, we want to start the player on monitor one. For tutorials, we might want to watch on monitor two, and a TV show on our TV, which is set up as monitor three.
We can have different commands to start the same player in these different contexts, which is much more powerful than system-wide memory of the last known window state (which still needs to be implemented).
Introduction to wmctrl
Many people who work on their computers have a small set of programs they run each time they start working. For entertainment, they often use a different set of programs.
Some applications need to have different window properties during work than during leisure. For example, a terminal emulator window could be smaller during leisure time to give more screen space to the internet browser, but larger during work hours when Vim or Kakoune needs to be run inside it.
With Linux, the sky is the limit, and we can create extremely convenient shortcuts to instantly get the desktop setup we want.
The tool that makes this possible is wmctrl. It is a simple, lightning-fast application that looks for specified windows on our desktop and gives them various behavior commands, like maximizing, changing geometry, closing, and even changing the title.
First, we need to install it using our Linux distro’s package manager of choice. In the case of Ubuntu/Mint, the command is:
Let’s start by changing the geometry of a single window. We’ll need to provide wmctrl with some identification so it knows which window we want to modify. The previously used xwininfo command can also be used here.
Type this in your console window:
…and then click on the window you want. You should get the window title in your console.
The command may look complicated if you don’t understand regex and piping, but in reality, it’s simple. It filters the output of xwininfo to get the line where the title resides and then extracts it from inside the brackets so that the full title is the only thing displayed.
It is easier and faster to go these extra two piping steps to get just what we want. Additionally, we can point a bash variable to it or save it to a file for future use.
The full command may not work in some edge cases (like a browser with a focused tab containing brackets in the page title). If it doesn’t work for you, just write xwininfo in your console, and the title will be inside brackets next to the Window id number.
Write down that title. Now, let’s look at wmctrl syntax for changing window geometry:
One last obstacle: wmctrl does not accept geometry in its standard format. You have to take those four numbers and rearrange them to fit wmctrl’s standard, which is:
GRAVITY,PX_FROM_LEFT,PX_FROM_TOP,WIDTH,HEIGHT
As you can see, wmctrl takes another item right at the beginning.
That first number is gravity, which specifies the alignment or source of reference for the moved window. You most likely don’t need to understand what it is and can always set it to 0. Just remember to include it. You can safely skip the next section describing how it works.
Gravity details
We don’t use pluses and minuses to specify if the window should move “to the right from the left side of the screen” or “to the left from the right side of the screen.”
Instead, we use a compass-like reference point. The screen has four cardinal directions (north, south, east, west) and four intercardinal directions (northeast, northwest, etc.).
A value of 0 refers to the system default, typically north-west, meaning alignment from the top-left corner of the screen. A gravity value of 3 (north-east) aligns the window from the top-right corner, similar to using negative numbers when setting geometry.
Below are the codes for all 8 gravity directions. Note that many window managers do not support this feature and will default to the system setting regardless of the value provided.
NorthWest (1), North (2), NorthEast (3), West (4), Center (5), East (6), SouthWest (7), South (8), SouthEast (9) and Static (10)
Wmctrl traps
Read this part if your wmctrl command does nothing, or if you intend to use it often and want to know some caveats in advance.
Let’s look at an example of a wmctrl command:
The program first generates a list of currently existing windows, finds the first title that contains a string specified within brackets, and then sets it to gravity 0, position from the left 30px, position from the top 20px, window width 800px, and window height 1080px.
Because only the first found item gets adjusted, if we have a few windows which are really one program, only one of them will be done, and each next command given will still reposition just that one window.
Another potential issue is that windows can have surprising titles sometimes. Browsers troll the most if we seek inside the window title.
A website we are visiting might have a “Sublime Text registered version cost” title, which could result in your Firefox having a “Sublime Text registered version cost - Mozilla Firefox” title whenever that particular tab is focused.
If those 3 conditions were met:
- The title we order wmctrl to search for is ‘Sublime Text’
- The browser is higher in wmctrl’s item search order than Sublime Text (and so would be checked first)
- The title of the currently focused Firefox tab includes a string ‘Sublime Text’
…then wmctrl would adjust Firefox’s parameters instead of Sublime Text’s.
There are multiple ways to solve that problem:
-
Use wmctrl with ‘-x’ to search WM_CLASS instead of the title, and that you can find with the ‘xprop grep WM_CLASS’ command (followed by clicking a desired application window, just like with xwininfo). - Use it with the ‘-F’ option to match the exact string to the letter, instead of looking for the string inside the app title (‘Sublime Text’ only matches if the application title is ‘Sublime Text’, it will fail if it is ‘How much does Sublime Text cost - Mozilla Firefox’).
- Change conflicting application titles right before searching (for example: ‘wmctrl -r “ - Mozilla Firefox” -N Firefox’ and Sublime Text resizing wmctrl command right after).
If you are playing title guessing games in your scripts, it is generally a good idea to set application titles to some unique strings that are not likely to get falsely matched (for example: ‘:.:BROWSER:.:’, ‘:.:EDITOR:.:’, ‘:.:MP3PLAYER:.:’…) in all applications that give an option to change their titles. Many do, many don’t ;)
If you can’t, it is good practice to order your resizing commands starting from applications most likely to cause conflicts (i.e., those whose names dynamically change based on file opened, website visited, etc.), through less likely to do so, with the ones which never will (due to constant unique name) at the bottom. For the last ones, the order doesn’t matter.
For each that can cause problems, follow the line in which you resize with the line that changes that same program’s name (the mentioned ‘-N’, you can see it below in an example file). This will ensure that the application won’t cause any conflicts.
Don’t worry if you have to do a lot of title renaming - both repositioning and renaming are trivial operations from your processor’s point of view. You will never see any performance hit, no matter how old your computer is and how many windows you shuffle around.
Again, many apps offer an option to set a permanent app title and your fixing attempts should start there. Some even allow having different titles when starting them with different profiles. A fantastic terminal emulator called Tilix is a good example.
Creating a script file to resize multiple windows
Each wmctrl command only changes one window, so we need to invoke as many commands as windows we need changed.
To contain all these instructions, we will use a bash script. Traditionally, in its first line we need to point to the interpreter. Most often, the line you need is:
Then, in each line a separate wmctrl command. No need for a colon, semicolon, or any other sign by line end. Just one command in each line.
The quickest way to write such a script is to set up exactly the desktop layout we want. Align everything so it looks perfect. Then, use the mentioned xwininfo commands to get each window’s geometry and title. Write everything down.
Next, write wmctrl commands. Remember to convert geometry strings (WIDTHxHEIGHT+FROMLEFT+FROMTOP) to the format that wmctrl accepts (0,FROMLEFT,FROMTOP,WIDTH,HEIGHT) in each command.
A complete example winresize.sh file looks like this:
Don’t forget to order them from most conflicting to least conflicting and follow each problematic application with another wmctrl command that renames it. Above, you see me doing it with Firefox.
Making convenient shortcuts for resizing
The final step is to set up a way to execute our new script at will. Below are the main 3 categories of options we have.
- Create a bash alias for execution of that file (in file ~/.bash_aliases add line: resizer=’/path/to/script.sh’), source that file (or restart the system if you don’t know how) and then execute it from console by writing ‘resizer’
- Set up a system-wide keyboard shortcut for that script (different for every window manager, in i3 it’s as simple as adding this line: ‘bindsym F9 exec /path/to/script.sh’)
- Create a mouse gesture to execute a script (easily achieved with easystroke, choosing ‘command’ option and then in command just pasting /full/path/to/our/script.sh
And voila! We now can reshape all our desktop with something as simple as a single command, pressing of a key, or a mouse gesture. We can create as many of those files and shortcuts as we want.
Final note
These techniques open up numerous possibilities for customizing your Linux desktop experience. While they may seem simple, they demonstrate the flexibility and power of the command line in solving everyday computing challenges.
As you continue to work with Linux, you’ll likely find more creative ways to apply these skills, whether for personal productivity or larger-scale system management tasks.