Skip to content

The XFCE4 Panel in dwmยค

Achievementsยค

  • We completely switched off dwm's systray patch and set the status bar to a constant empty string => cpu problem solved.

  • Then we got XFCE4's panel to work, instead:

State changeable and saved:

Plugins work:

Fading out when not hovered:

A lot of plugins out of the box:

Plus all 3rd party systray aware apps work.

How did we do itยค

Starting itยค

We use the autostart patch - but xinit and the likes would also work.

Here we configured in autostart.sh of dwm to run this:

~ โฏ cat bin/panel.sh
#xfce4-session NEVER EVER DO THIS IN DWM!
xfce4-panel --disable-wm-check

The panel was then shown and we moved it to the right place with the mouse.

Then we required a few hacks in dwm to get it working like a real statusbar.

Rules in config.hยค

Declaratively it is possible to have it shown on all tags like this:

static const Rule rules[] = {
    /* class                  instance    title       tags mask   , iscentered,    isfloating,     monitor */
    { "Xfce4-panel",          NULL,       NULL,       (1 << 9) - 1,     0,                0,           -1 },

The (1 << 9) - 1 sets a 1 on all 9 tags.

But what you get is not yet really behaving like a status bar - The window has the same thick border like all others - All tags hint an active application on them in the tag bar - The window, at every redraw, is being offset by dwm to reside below the status bar

Some imperative changesยค

Lets fix that in dwm.c, matching on the name of the panel:

diff --git a/dwm.c b/dwm.c
index 60dde29..6c67456 100644
--- a/dwm.c
+++ b/dwm.c
@@ -615,6 +615,10 @@ configure(Client *c)
     ce.above = None;
     ce.override_redirect = False;
 
+    /* if (!strcmp(c->name, "xfce4-panel")) { */ 
+    // the panel's initial settings
+    /*     c->y = ce.y = ce.border_width = c->bw = 0; */
+    /* } */
     XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&ce);
 }
 
@@ -794,6 +798,7 @@ drawbar(Monitor *m)
     resizebarwin(m);
 
     for (c = m->clients; c; c = c->next) {
+        // prevent showing the panel as active application:
+        if (!strcmp(c->name, "xfce4-panel")) continue;
         occ |= c->tags;
         if (c->isurgent)
             urg |= c->tags;
@@ -1171,6 +1176,9 @@ manage(Window w, XWindowAttributes *wa)
         c->x = (c->mon->mw - WIDTH(c)) / 2 + 500;
         c->y = (c->mon->mh - HEIGHT(c)) / 2;
     }
+    // no border - even when active
+    // do not match on y, does not have it yet possibly:
+    if (!strcmp(c->name, "xfce4-panel")) c->bw = c->oldbw = 0;
+
     wc.border_width = c->bw;
     XConfigureWindow(dpy, w, CWBorderWidth, &wc);
     XSetWindowBorder(dpy, w, scheme[SchemeNorm][ColBorder].pixel);

and lastly forcing to keep the position at 0 and never have a border:

void
resizeclient(Client *c, int x, int y, int w, int h)
{

	XWindowChanges wc;

	c->oldx = c->x; c->x = wc.x = x;
	c->oldy = c->y; c->y = wc.y = y;
	c->oldw = c->w; c->w = wc.width = w;
	c->oldh = c->h; c->h = wc.height = h;
	wc.border_width = c->bw;
	if (((nexttiled(c->mon->clients) == c && !nexttiled(c->next))
	    || &monocle == c->mon->lt[c->mon->sellt]->arrange))
	{
		c->w = wc.width += c->bw * 2;
		c->h = wc.height += c->bw * 2;
		wc.border_width = 0;
	}
+   if (!strcmp(c->name, "xfce4-panel")) { 
+       c->y = c->oldy = c->bw = wc.y = wc.border_width = 0;
+   }

	XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
	configure(c);
	XSync(dpy, False);
}

Settings of the panel itself:ยค

Along the way: A Neat WM Test Setup, Using Xephyrยค

Having to restart the WM after any change sucks. Especially when it crashes the usual restart loop turns ugly.

So I looked a bit around and found this: There is an X application which behaves as a normal X client - but offers a full X Display environment inside(!): xnest. Check it out: https://wiki.archlinux.org/title/Xephyr

So with

~ โฏ cat bin/xnest
#!/usr/bin/env bash
Xephyr -br -ac -noreset -screen 1100x1000 :1 &
sleep 1
DISPLAY=:1 "${1:-dwm}"

we get an instantly starting dwm build of our liking, started within a normal X11 window :-)

When you hit ctrl-shift with it focussed it grabs all your mouse and keyboard events - even the parent's dwm hotkeys - which I find pretty remarkable. No need to redeclare all your hotkeys within your test builds, so that they do not collide with your 'real' window manager's ones.

This is something which makes testing of WM builds fare more convenient than with e.g. docker or VNC window rooted builds.

Only downside is that the inner WM is running in the same filesystem, if you not re-root it, i.e. when you set e.g. your wallpaper, it will behave exactly like the outside one - setting it. No isolation, clear. But ideal for our purpose.

Back to top