From 3afe464c538e78c5626892ec82efa3614fe11a6b Mon Sep 17 00:00:00 2001 From: Luca Toniolo <10792599+grandixximo@users.noreply.github.com> Date: Sat, 30 May 2026 11:20:09 +0800 Subject: [PATCH] touchy: exit on SIGTERM touchy ignored SIGTERM (GLib/PyGObject absorbs the signal), so a caller tearing it down had to escalate to SIGKILL. Install a SIGTERM handler that quits the GTK main loop, deferring the quit to the loop via GLib.idle_add since GTK calls are not safe directly from a signal handler. atexit cleanup (child processes, prefs) still runs. This does not touch the interactive window-close path. SIGTERM is a system terminate request and should not require confirmation. Note: PyGObject still prints a benign KeyboardInterrupt on this shutdown; that is pre-existing (touchy printed it on SIGTERM before too, it just did not exit) and is emitted from PyGObject's C layer, so it is not suppressible from Python here. Surfaced by the ui-smoke tests (PR #4054). --- src/emc/usr_intf/touchy/touchy.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/emc/usr_intf/touchy/touchy.py b/src/emc/usr_intf/touchy/touchy.py index 05b76c3097c..830eb586106 100755 --- a/src/emc/usr_intf/touchy/touchy.py +++ b/src/emc/usr_intf/touchy/touchy.py @@ -905,4 +905,13 @@ def trivkins(self): else: res = os.spawnvp(os.P_WAIT, "halcmd", ["halcmd", "-i", inifile, "-f", f]) if res: raise SystemExit(res) + + # Exit cleanly on SIGTERM. Without this touchy ignores the signal + # (GLib/PyGObject absorbs it), so a caller has to escalate to SIGKILL. + # The handler defers the quit to the main loop, since GTK calls are not + # safe directly from a signal handler. + def _signal_quit(signum, frame): + GLib.idle_add(Gtk.main_quit) + signal.signal(signal.SIGTERM, _signal_quit) + Gtk.main()