About a year ago, while in between jobs, I picked up yet another side project - a Linux desktop session manager written in Python. Like many of my projects, this one still isn't done, though I've made a lot of progress and shaved a bunch of yaks. I plan on writing more about the details of my session manager in future posts, but for today I want to focus on what, exactly, session management is and how it works.
What's a Desktop Session Manager?
When you turn on your Linux computer and boot to the login screen, what happens looks something like this:
- The BIOS boots the kernel
- which starts systemd, a program designed to start and monitor services
- which starts all the important system processes
- and then starts X11, a server for managing desktop graphics
- which in turn starts a login manager
A login manager is a program that grabs control of the X display and, to be tautological, manages logins. It presents you with a little UI that lets you enter your username and password and select what kind of session you want to start. I use one called LightDM that was written for Ubuntu and have a nice outrun theme set up for it.
What happens when you press enter is something like this:
- The login manager starts a session manager
- which starts a window manager
- and usually a menu bar, a desktop background and desktop icons
- and then starts everything in the XDG autostart directory
The session manager is the program that's in charge of starting all of these other pieces, and then shutting everything down gracefully when you log out. GNOME, KDE and XFCE all ship with their own session managers, called gnome-session
, startkde
and xfce4-session
respectively.
What Happens When You Aren't Using A Desktop Environment
The process I described prior is what happens when you're running a typical desktop-oriented Linux distribution, such as Ubuntu - but anyone that uses Arch knows that things aren't so simple! There's actually a lot of variation in how this works. For instance, if you start X without a login manager, it might look like this:
- You're presented with a text-only login prompt with no fancy graphics
- and after you log in you run a command called
startx
which fires up a program called xinit - which starts X11 and then runs a shell script located at
~/.xinitrc
my situation is a hybrid approach between these two strategies: I use a login manager but run ~/.xinitrc
in a session using xinit-xsession.
When Would You Want To Avoid A Desktop Environment Session Manager?
Often, session managers are deeply integrated with their respective desktop environments. gnome-session
is for starting GNOME, startkde
starts KDE, and so on. If you're using these desktop environments, they work great!
That said, as a Linux hobbyist, I don't use any of these environments and am instead running something fully custom. To wit, my ~/.xinitrc
(minus some X11 initialization boilerplate) looks like this:
# Mouse gestures
libinput-gestures-setup start
# Wallpapes
nitrogen --restore &
# Userspace mounting/unmounting of thumb drives
udiskie &
exec xmonad
Here, you can see that I fire up:
- libinput-gestures, which configures my trackpad so that two button scroll and three finger swipe to change desktops work, "like osx"
- nitrogen to draw a simple desktop background - a picture of a psychedelic rainbow cat I found like a decade ago and have kept around even as screen sizes have grown bigger than the original image
- udiskie to manage mounting and unmounting of usb thumb drives
- xmonad, a tiling window manager written in Haskell
The last line in an ~/.xinitrc
is usually exec'd and is usually the window manager.
This, in combination with xmobar, a really simple topbar that integrates with xmonad; dmenu, a lightweight menu program that I use to launch programs; and dunst, a DBus-activated notifications server; gives me a pretty pleasant and lightweight desktop. Xmonad in particular jells well with my brain, to the point that I set up a tiling window manager in OSX and will probably lord help me eventually write one for Windows.
Why You Actually Do Want a Desktop Manager
I'm pretty pleased with this setup, but using an ~/.xinitrc
file definitely has some downsides.
For instance, my bash script can't restart any of the services. nitrogen
and udiskie
are both backgrounded, and if they were to exit for any reason nothing would be there to catch that and start them again.
Another consequence of using a bash script that's maybe less intuitive is that shutdowns are less graceful. When I "log out", this is basically what happens:
- xmonad hard exits, killing the entire process tree
- the login manager detects that the session has exited and takes control of the screen again
What I would like to happen is something a little nicer:
- I tell my session manager that I want to log out
- my session manager sends SIGTERM signals to open/managed programs
- after a timeout the session manager has configurable behavior for sending a more aggressive SIGKILL
- the session manager then exits xmonad and gives control back to the login manager
as it stands, most programs are surprisingly OK at dealing with a hard exit, but I've gotten Firefox in an unhappy state many times by being careless when logging out.
Finally, session managers in Linux support a standard for auto-starting applications which is unknown to my ~/.xinitrc
file. Using this standard, you create .desktop files that specify what the programs are and how to start them, and the session manager will start all of them after the main environment is loaded. This isn't a great fit for the window manager or the status bar, but is a pretty good fit for starting tray applet adjacent tools like udiskie, as well as apps I always want open anyway, like Firefox and Slack.
korbenware
My desktop session manager project, called korbenware (named after my budgie and as an extended Homestar Runner reference), is being written with Python and Twisted as a base. While working on it have implemented most of the XDG autostart standard, built a spec-compliant replacement for xdg-open, implemented logging infrastructure for journald, extended twisted.runner.procmon (and sent them a patch!), implemented IPython autoawait for Twisted, ported a small piece of GLib to Python, have written a DBus RPC framework on top of txdbus, attrs and marshmallow, and more.
These are all things I plan on writing about in the future, but in the meantime, this hopefully straightforward primer on Linux desktop session management should stand as a source of necessary context as I visit these topics in the future.
Top comments (5)
Pretty Interesting project. Is there further info about korbenware? I would love to give a hand, I am struggling so much to find a decent session manager for my xmonad config.
Most of the session manager are desktop dependent and they don't work properly with xmonad
Funny enough, I never got to the point where I felt like it was "done" and I'm using Gnome right now so it's unlikely I'll give it the necessary elbow grease, but the source code is online at github.com/jfhbrook/public/tree/ma... if you're OK with some dragons and a lack of maintenance.
Well explained, thank you very much!
Could you please talk a little bit deeper into a session manager since I'm so curious about it?
I learned so many things about your experiences . thank so much for sharing this great work flow on session manager. i do appreciate that.