Wine and X

Notes published the
4 - 5 minutes to read, 1042 words
Categories: linux windows
Keywords: linux windows wine

WINE is a fantastic program for running old games developed for Windows.

Unfortunately, some games (especially the older ones) change the resolution of the desktop (sometimes even the refresh rate), and sometimes it is not easy to reset those settings to their original value.

Changing the resolution from 800x600 to something like 1600x900 can be hard because many elements of the menu and Windows might not appear on the screen.

There are multiple workarounds, but no silver bullet.

Change the game settings

Some games are configurable and it is possible to set the desired screen resolution.

But this is not always possible, even if, the game might not support the current resolution.

Emulate a virtual desktop

The most simple workaround is to emulate a virtual desktop.

Setting the size of the virtual desktop big enough might be the easiest workaround (advantage: alt+tab will work too). With explorer, any application can have it’s separate virtual desktop:

wine explorer "/desktop=app,1024x768" "C:/Program Files/Install dir/application.exe"

Unfortunately, this method does not always work for two reasons.

The first reason is that some programs, even if started on a virtual desktop, still manage to change the screen resolution.

The second reason is that some desktop environments, like Cinnamon (the default desktop environment on Linux Mint) seems to have issues with this feature of WINE.

A new "virtual" desktop

There is a second method. Create a new "virtual" desktop, start the program inside it, and throw everything away when the program finishes.

It is actually easy when using Xorg (I have currently no experience with Wayland): just start a second X server, and start the game in that session!

The nice thing about this approach is that it does not depend on your desktop environment, and that it "isolates" your game session from other programs (thus no notification, Alt+Tab for switching programs, …​ unless those are desired features)

There are three, more or less equivalent ways to do it

Start X directly

export DISPLAY=:3;
X "$DISPLAY" -ac &
export WINEPREFIX="...";
cd "${WINEPREFIX}/Program Files/Install dir/";
wine application.exe;
kill %1;

Note the usage of kill %1 for killing the temporary X session after the program finishes.

Use xinit

export DISPLAY=:3;
export WINEPREFIX="...";
cd "${WINEPREFIX}/Program Files/Install dir/";
xinit wine application.exe -- "$DISPLAY";

The main advantage is that we do not need to kill anything by hand anymore

And the last one is to use startx

export WINEPREFIX="...";
cd "${WINEPREFIX}/Program Files/Install dir/";
startx wine application.exe;

In this case, we do not even need to define DISPLAY, startx will do the job for us.

Thus of the three approaches, the one with startx seems the easiest to use, and I’ll continue my notes with that.

Note that startx does not support parameter with spaces. As far as I could see (startx, at least on Debian, is a shell script), it is still the case.

The easiest way to use startx is to move all relevant commands of the program we are interested to execute in a separate script. This way, parameters with spaces won’t be an issue:

printf '#!/bin/sh
export WINEPREFIX="...";
wine "C:/Program Files/Install dir/application.exe";
' > script.sh
chmod +x script.sh

startx ./script.sh

Unfortunately starting a separate X also has some drawbacks.

The first is that sometimes a windows program is just a launcher, and it executes (detached) the reals program.

Thus the wine command finishes, the X instance is killed, and the program are not usable.

There are two ways to overcome this issue.

The first is, if possible, to find out the "real" program and execute it directly.

If this is not possible, the other workaround is to wait until all Windows programs stop running:

printf '#!/bin/sh
export WINEPREFIX="...";
wineserver -p0;
wine "C:/Program Files/Install dir/application.exe"
wineserver -w;
' > script.sh
chmod +x script.sh

startx script.sh

When wine is executed the first time, some "services" are started and monitored in the background. With wineserver -w it is possible to wait until all wine processes are done with the execution. For performance reasons (for example in case multiple executables are executed one after the other), the background processes are not stopped immediately but are still executed for some time. Executing wineserver -p0 tells wine to stop those services as soon as possible. Nevertheless, with some programs (those slow at shutting down even if the GUI is closed immediately) it might seem to introduce a big lag.

Note 📝
You can use Ctrl+Alt+F7 to switch back to your first graphical session (at least on most if not all Debian-based systems)

The second drawback is (at least for me) the biggest one.

Monitor settings are not duplicated.

If you have configured from your desktop environment multiple monitors, touch to click on the trackpad, or something else…​ all those settings will generally not be available to the next X instance.

If you have, for example, a laptop, the internal monitor is turned off and you are only working/playing on the external monitor, chances are that the new X instance will render the content to the internal monitor.

I’ve currently found no way to export the settings of the actual running environment in a format that can be used by X directly.

I would have expected that the desktop environment (KDE, GNOME, Mate, …​.) would offer such an option, or X itself, but could not find anything.

One could hardcode the desired settings in /etc/xorg.conf.d, but why should I duplicate what I’ve configured in my desktop environment?

If the default configuration is "good enough", then starting a new X instance is a trivial task.

Otherwise, as I know no way to programmatically recreate the current environment for a new X instance, there is no silver bullet.

export settings


Do you want to share your opinion? Or is there an error, some parts that are not clear enough?

You can contact me anytime.