|

hammerhead-xdm r12: power-button confirm dialog + nudge lower

hammerhead-xdm r12: power-button confirm dialog + nudge lower

- hh-greeter-power: Shutdown/Reboot now pop a centered Athena confirm dialog
  ([Shut down]/[Reboot] + Cancel) instead of firing immediately.
- Xsetup_0: nudge the button bar down (-geometry -40-12).
Author: Chris Tusa <chris.tusa@leafscale.com>
Date: Jul 24, 2026 13:34
Changeset: 1aff37681e833b46f4d024f35883ff0a880538c5
Branch: default

Diff

diff -r 3cc433d0a00d -r 1aff37681e83 base/hammerhead-xdm/Xresources
--- a/base/hammerhead-xdm/Xresources	Fri Jul 24 13:30:53 2026 -0500
+++ b/base/hammerhead-xdm/Xresources	Fri Jul 24 13:34:37 2026 -0500
@@ -91,6 +91,12 @@
 HhGreeterPower*Command.internalWidth:	14
 HhGreeterPower*Command.internalHeight:	8
 HhGreeterPower*Command.font:		-*-helvetica-bold-r-normal-*-14-*-*-*-*-*-iso8859-1
+! Confirmation dialog (Shut down? / Reboot?)
+HhGreeterPower*Dialog.background:	#12303a
+HhGreeterPower*Dialog.borderColor:	#1fb6b6
+HhGreeterPower*Dialog.label.background:	#12303a
+HhGreeterPower*Dialog.label.foreground:	#cfe0e0
+HhGreeterPower*Dialog.label.font:	-*-helvetica-medium-r-normal-*-14-*-*-*-*-*-iso8859-1
 
 XConsole.text.geometry:	480x130
 XConsole.verbose:	true
diff -r 3cc433d0a00d -r 1aff37681e83 base/hammerhead-xdm/Xsetup_0
--- a/base/hammerhead-xdm/Xsetup_0	Fri Jul 24 13:30:53 2026 -0500
+++ b/base/hammerhead-xdm/Xsetup_0	Fri Jul 24 13:34:37 2026 -0500
@@ -14,4 +14,4 @@
 
 # Shutdown/Reboot button bar, bottom-right corner (no WM on the greeter).
 # Killed by Xstartup on login so it never leaks into the user's session.
-/usr/local/bin/hh-greeter-power -geometry -40-40 &
+/usr/local/bin/hh-greeter-power -geometry -40-12 &
diff -r 3cc433d0a00d -r 1aff37681e83 base/hammerhead-xdm/hh-greeter-power.c
--- a/base/hammerhead-xdm/hh-greeter-power.c	Fri Jul 24 13:30:53 2026 -0500
+++ b/base/hammerhead-xdm/hh-greeter-power.c	Fri Jul 24 13:34:37 2026 -0500
@@ -1,14 +1,13 @@
 /*
  * hh-greeter-power.c - a tiny Athena (Xaw) button bar with Shutdown and
- * Reboot buttons for the xdm greeter.
+ * Reboot buttons for the xdm greeter, each guarded by a confirmation popup.
  *
  * xdm's classic xlogin greeter has no power buttons, and the greeter display
  * runs with no window manager. This standalone client is launched by
  * Xsetup_0 (as root, so `zygctl poweroff`/`reboot` have the privilege to run)
  * and killed by Xstartup when a session begins, so it never leaks into the
- * user's desktop. Styling + placement come from the HhGreeterPower* resources
- * in Xresources (loaded onto the server by xrdb) plus the -geometry passed by
- * Xsetup_0.
+ * user's desktop. Styling comes from the HhGreeterPower* resources in
+ * Xresources (loaded by xrdb); placement from the -geometry Xsetup_0 passes.
  *
  * Build: cc hh-greeter-power.c -I$PREFIX/include -L$PREFIX/lib -R$PREFIX/lib \
  *        -lXaw7 -lXmu -lXt -lX11 -o hh-greeter-power
@@ -18,43 +17,104 @@
 #include <X11/Shell.h>
 #include <X11/Xaw/Box.h>
 #include <X11/Xaw/Command.h>
+#include <X11/Xaw/Dialog.h>
 #include <stdlib.h>
 
+static Widget toplevel;
+static Widget confirm_popup = NULL;
+static const char *pending_cmd = NULL;
+
+static void
+dismiss(void)
+{
+    if (confirm_popup != NULL) {
+        XtPopdown(confirm_popup);
+        XtDestroyWidget(confirm_popup);
+        confirm_popup = NULL;
+    }
+}
+
+static void
+do_it(Widget w, XtPointer client, XtPointer call)
+{
+    (void) w; (void) client; (void) call;
+    if (pending_cmd != NULL)
+        (void) system(pending_cmd);   /* machine goes down; no return expected */
+    dismiss();
+}
+
 static void
-poweroff_cb(Widget w, XtPointer client, XtPointer call)
+cancel(Widget w, XtPointer client, XtPointer call)
 {
     (void) w; (void) client; (void) call;
-    (void) system("/sbin/zygctl poweroff");
+    dismiss();
+}
+
+/* Pop a centered confirmation dialog for a power action. */
+static void
+confirm(const char *prompt, const char *cmd, const char *okLabel)
+{
+    Widget dlg;
+    Dimension pw, ph;
+    Position px, py;
+    int sw, sh;
+
+    dismiss();                 /* only one popup at a time */
+    pending_cmd = cmd;
+
+    confirm_popup = XtVaCreatePopupShell("confirm",
+        transientShellWidgetClass, toplevel, (char *)NULL);
+    dlg = XtVaCreateManagedWidget("dialog", dialogWidgetClass, confirm_popup,
+        XtNlabel, prompt, (char *)NULL);
+    XawDialogAddButton(dlg, okLabel, do_it, NULL);
+    XawDialogAddButton(dlg, "Cancel", cancel, NULL);
+
+    /* Center on screen (no window manager to place it). */
+    XtRealizeWidget(confirm_popup);
+    XtVaGetValues(confirm_popup, XtNwidth, &pw, XtNheight, &ph, (char *)NULL);
+    sw = WidthOfScreen(XtScreen(toplevel));
+    sh = HeightOfScreen(XtScreen(toplevel));
+    px = (Position)((sw - (int)pw) / 2);
+    py = (Position)((sh - (int)ph) / 2);
+    XtVaSetValues(confirm_popup, XtNx, px, XtNy, py, (char *)NULL);
+    XtPopup(confirm_popup, XtGrabExclusive);
+}
+
+static void
+shutdown_cb(Widget w, XtPointer client, XtPointer call)
+{
+    (void) w; (void) client; (void) call;
+    confirm("Shut down this system?", "/sbin/zygctl poweroff", "Shut down");
 }
 
 static void
 reboot_cb(Widget w, XtPointer client, XtPointer call)
 {
     (void) w; (void) client; (void) call;
-    (void) system("/sbin/zygctl reboot");
+    confirm("Reboot this system?", "/sbin/zygctl reboot", "Reboot");
 }
 
 int
 main(int argc, char **argv)
 {
     XtAppContext app;
-    Widget top, box, sd, rb;
+    Widget box, sd, rb;
 
-    top = XtOpenApplication(&app, "HhGreeterPower", NULL, 0, &argc, argv,
+    toplevel = XtOpenApplication(&app, "HhGreeterPower", NULL, 0, &argc, argv,
         NULL, applicationShellWidgetClass, NULL, 0);
 
-    box = XtVaCreateManagedWidget("box", boxWidgetClass, top,
+    box = XtVaCreateManagedWidget("box", boxWidgetClass, toplevel,
         XtNorientation, XtorientHorizontal, (char *)NULL);
 
     sd = XtVaCreateManagedWidget("Shutdown", commandWidgetClass, box,
         (char *)NULL);
-    XtAddCallback(sd, XtNcallback, poweroff_cb, NULL);
+    XtAddCallback(sd, XtNcallback, shutdown_cb, NULL);
 
     rb = XtVaCreateManagedWidget("Reboot", commandWidgetClass, box,
         (char *)NULL);
     XtAddCallback(rb, XtNcallback, reboot_cb, NULL);
 
-    XtRealizeWidget(top);
+    XtRealizeWidget(toplevel);
     XtAppMainLoop(app);
     return 0;
 }
diff -r 3cc433d0a00d -r 1aff37681e83 base/hammerhead-xdm/package.toml
--- a/base/hammerhead-xdm/package.toml	Fri Jul 24 13:30:53 2026 -0500
+++ b/base/hammerhead-xdm/package.toml	Fri Jul 24 13:34:37 2026 -0500
@@ -10,7 +10,7 @@
 [package]
 name = "hammerhead-xdm"
 version = "1.0.0"
-release = 11
+release = 12
 description = "Zygaena marine-dark xdm greeter branding, system Xsession/Xservers wiring, and a disabled zyginit xdm service"
 url = "https://git.sharkos.one/zygaena/hammerhead"
 license = "CDDL-1.0"