In the bad old days, every computer had a monitor, a keyboard, a mouse, and that was it. These days, computers have all kinds of extra peripherals, like screens that can dim, audio outputs that can change their volume, and keyboards with buttons to control all those things. On a modern Linux kernel, getting those things working can be a hassle, and if they need to work together (say, dimming the screen when battery gets low) it’s even more complex.
Luckily, modern desktop environments handle all this stuff out-of-the-box, and GNOME 3 is one of the more widely-available and best-supported options. Its default configuration is simple and easy for new users to get started with, while its modularity and extensibility allow power-users quite a bit of customisation.
Unluckily, as flexible and extensible as it is, GNOME 3’s desktop environment is not quite as graceful at dealing with many windows as a good tiling window-manager like i3. And the GNOME Shell front-end is fairly tightly linked with the hardware-management backend. It would be lovely if there were a GNOME component that allowed the hardware-management to run independently of GNOME Shell, so I could use it with a different window-manager.
It turns out there is. There’s a thing called GNOME Flashback, which makes the modern GNOME 3 infrastructure available without the GNOME 3 interface, so that people who preferred the old GNOME 2 interface can keep using it, or at least something resembling it. Because GNOME 2 allowed custom window-managers, so does GNOME Flashback, which means we can use it with i3.
I’m using GNOME 3.38 on Debian 10 (“bullseye”). Your mileage may vary with other versions and other distros.
We’re going to need the GNOME Flashback package, and of course i3.
$ sudo apt-get install gnome-session-flashback i3
To create a session with all the required GNOME background services,
the easiest thing is to use gnome-session
.
We’ll create a session that includes i3 and the GNOME Flashback goodies,
by copying and customising
the standard Metacity-based GNOME session.
To copy the files:
$ mkdir -p \
~/.config/systemd/user/gnome-session@gnome-flashback-i3.target.d/ \
~/.config/gnome-session/sessions/
$ cp \
/usr/lib/systemd/user/gnome-session@gnome-flashback-metacity.target.d/session.conf \
~/.config/systemd/user/gnome-session@gnome-flashback-i3.target.d/session.conf
$ cp \
/usr/share/gnome-session/sessions/gnome-flashback-metacity.session \
~/.config/gnome-session/sessions/gnome-flashback-i3.session
To do the customisation,
open up the gnome-flashback-i3.session
file in an editor,
and on the RequiredComponents line,
change “metacity” to “i3”.
You can make other modifications to the session file,
but note that RequiredComponents
aren’t executables,
they’re the names of .desktop
files in /usr/share/applications
(amongst other places).
GNOME Flashback also tries to create a custom window to manage desktop icons. Desktop icons aren’t very useful for a tiling window manager like i3, but more annoyingly, i3 doesn’t seem to understand that the desktop window should be behind all other windows, and tries to manage it as another application window. To disable the custom desktop functionality:
dconf write /org/gnome/gnome-flashback/desktop false
…tells GNOME Flashback to not create a custom desktop window, while:
dconf write /org/gnome/gnome-flashback/root-background true
…tells it to draw the desktop image (“wallpaper”) on the root window, just like in previous versions.
Modern versions of GNOME Terminal
will also use client-side decorations
if $XDG_CURRENT_DESKTOP
contains “GNOME”.
Client-side decorations can be nice in regular GNOME,
but they’re kind of a waste of space with i3.
I haven’t figured out how to prevent that environment variable from being set,
but there is an override:
dconf write /org/gnome/terminal/legacy/headerbar false
Adding a new session type to GDM’s list of sessions
would require editing system-wide files,
but luckily we don’t actually need to do that.
If you have a file named .xsession
in your home directory,
GDM will include a session named “System X11 Default”
that will execute that file as a shell script.
Luckily,
GNOME Flashback already includes such a shell script,
which we can copy and customise.
Copy the file
/usr/libexec/gnome-flashback-metacity
to ~/.xsession
then open it up in an editor,
and change “metacity” to “i3”.
When gnome-session
starts a session component,
it typically expects the component to notify it via DBus
that the component has started correctly.
i3 knows nothing of DBus,
so gnome-session
will launch i3
and wait forever for something to happen.
Instead,
teach i3 to notify gnome-session
that it has started
by putting the following lines at the end of ~/.config/i3/config
:
exec --no-startup-id dbus-send \
--session \
--print-reply=literal \
--dest=org.gnome.SessionManager \
"/org/gnome/SessionManager" \
org.gnome.SessionManager.RegisterClient \
"string:i3" \
"string:$DESKTOP_AUTOSTART_ID"
Also,
to log out of an i3-based session,
you run
(directly, or via a keybinding)
i3-msg exit
to tell i3 to exit.
However,
under gnome-session,
that doesn’t actually log you out:
gnome-session might restart i3,
or it might just let it exit,
leaving all your applications still running,
with no way to manually exit them.
Instead,
you should bind your usual logout key to run gnome-session-quit
,
which will pop up the traditional confirmation dialog,
and which works as you’d expect.
The GNOME Panel is redundant with the i3 bar, but some GNOME functionality is only available via panel applets, and not via standard notification area icons. As a result, you probably should disable the bar in your i3 configuration, and stick with the Panel.
Log out, log back in (and make sure to pick “System X11 Default” as your session) and you should be in i3 with all the GNOME services available.
For some reason,
my GNOME+i3 session never seems
to route the X11 bell through PulseAudio,
and instead it always stays as a grating beep.
I’m not sure why,
but you might be able to work around it
by adding the following to ~/.xsession
just before the exec gnome-session ...
bit.
# Redirect the X11 beep to PulseAudio
pactl upload-sample \
/usr/share/sounds/freedesktop/stereo/dialog-information.oga \
x11-bell
pactl load-module \
module-x11-bell \
display=$DISPLAY \
sample=x11-bell
I happen to like dialog-information.oga
because it matches what I remember from GNOME,
but feel free to try different sounds.