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.22 on Debian 9 (“stretch”). 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.
Save this file as ~/.config/gnome-session/sessions/gnome-plus-i3.session
(you may need to create the intervening subdirectories yourself):
[GNOME Session] Name=GNOME + i3 RequiredComponents=gnome-flashback-init;gnome-flashback;i3;gnome-settings-daemon;
Other GNOME Flashback sessions include additional RequiredComponents like
gnome-panel
(for the traditional GNOME application menu and taskbar)
and nautilus-classic
(to draw desktop icons)
but since those aren’t related to hardware support,
I’ve left them out.
Also note that RequiredComponents aren’t executables,
they’re the names of .desktop files in /usr/share/applications
(amongst other places).
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.
So we just need to write a script that launches gnome-session
and tells it to run our i3-based session instead.
Save the following file as .xsession in your home directory:
# Menu tools use this value to decide which applications # are approriate for the current session. if [ -z $XDG_CURRENT_DESKTOP ]; then export XDG_CURRENT_DESKTOP="GNOME-Flashback:GNOME" fi # Run gnome-session and tell it to use our i3 session. exec gnome-session --session=gnome-plus-i3 --disable-acceleration-check
When gnome-session starts a session component,
it typically expects the the component to notify it via DBus
that the 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 GNOME log out dialog,
and which works as you’d expect.
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.
After following the above instructions, one difference I noticed between GNOME and i3 was that under GNOME, the terminal bell was a pleasant, subtle sound, while under i3, I got the traditional machine beep.
It turns out that something somewhere wasn’t telling PulseAudio
to replace the machine beep.
Never mind,
we can tell it ourselves.
Add 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.