Software Engineer's Blog

Ubuntu Clamshell Mode: Use a Closed Laptop With an External Monitor

Ubuntu Clamshell Mode: Use a Closed Laptop With an External Monitor

Clamshell mode is when you close the laptop lid but keep using it — driving an external monitor, with a separate keyboard and mouse, like a small desktop. On a Mac it just works; on Ubuntu, closing the lid suspends the machine mid-session.

The tempting fix is to make the lid do nothing, ever. But for a laptop you still carry around, that’s the wrong trade — you want it to sleep when you close it and drop it in your bag. What you actually want is conditional: stay awake when it’s docked to a monitor, sleep normally when it isn’t.

The key: docked vs not docked

systemd already models this distinction with two separate lid settings:

  • HandleLidSwitch — what to do on lid close in the plain case. Its default is suspend, and you want to keep that so the laptop still sleeps in your bag.
  • HandleLidSwitchDocked — used instead when the system is docked. The useful part: this one already defaults to ignore, so when systemd considers you docked it ignores the lid out of the box.

That shifts the real question from what value to set to whether systemd thinks you’re docked. Per logind, “docked” means a docking station is inserted or more than one display is connected. With an external monitor attached, that’s usually already true — so on most setups the default ignore keeps the machine awake with the lid shut and you don’t need to change anything. Setting it explicitly just makes the intent clear:

[Login]
HandleLidSwitchDocked=ignore

If closing the lid still suspends the machine while it’s driving a monitor, docked detection isn’t firing on your hardware — or your desktop environment is holding a lid inhibitor that overrides the HandleLidSwitch* settings entirely. Check the inhibitors and the docked state before assuming a config value is wrong:

systemd-inhibit --list

Only if docked detection genuinely fails on your machine should you fall back to ignoring the lid unconditionally with HandleLidSwitch=ignore — the headless server setup’s approach — accepting that it then won’t suspend even undocked.

Edit /etc/systemd/logind.conf, set the line you need, and reload:

sudo systemctl restart systemd-logind

The other half: display and input

Ignoring the lid only keeps the machine awake. To actually use it closed, two more things have to be true:

  • An external display must be connected — over HDMI, DisplayPort, or a USB-C dock. That connection is also what makes systemd consider the laptop “docked,” so it’s doing double duty here.
  • You need external input — a USB or Bluetooth keyboard and mouse, since the laptop’s own are shut inside. Pair the Bluetooth ones before you close the lid the first time; it’s easier than fishing for them blind.

When you close the lid, GNOME moves the session to the external monitor and it becomes your primary display. If the screen goes black instead, check the cable/dock first — a flaky connection reads as “undocked,” which sends you back to the plain HandleLidSwitch=suspend path.

Verify both behaviors

The point of the conditional setup is that it does two different things, so test both:

  • Docked — external monitor connected, close the lid. The session should stay on the monitor and the machine stays awake.
  • Undocked — unplug the monitor, close the lid. It should suspend as normal.

If it stays awake even undocked, you’ve set HandleLidSwitch=ignore (the blanket switch) — either the single-monitor fallback above, or by accident. That’s fine if you meant it; just know the laptop won’t sleep in your bag anymore. Confirm the docked value with:

$ busctl get-property org.freedesktop.login1 /org/freedesktop/login1 \
    org.freedesktop.login1.Manager HandleLidSwitchDocked
s "ignore"

(Note: systemctl show systemd-logind -p HandleLidSwitchDocked returns nothing — that command shows the service unit’s properties, not logind’s lid settings. Query the login1 D-Bus Manager with busctl as above.)

If instead you want the laptop to never sleep — no monitor, running purely as a 24/7 box over SSH — that’s a different goal; see headless server mode, which shuts down every sleep trigger unconditionally.