Debounce settings writes and save them on SIGTERM

- DebouncedStore, taken out of WindowSettings, now also saves the opacity
  slider once a drag ends instead of on every step
- SIGTERM/SIGINT (how KWin stops the input method) quit normally, so
  pending geometry and settings are written
- The slider's minimum opacity comes from Settings instead of a copy in QML

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-15 10:13:56 +02:00
co-authored by Claude Opus 5.5
parent cb7cf1e04d
commit 990d62ffcf
11 changed files with 127 additions and 31 deletions
+44
View File
@@ -0,0 +1,44 @@
#include "QuitOnSignal.h"
#include <QCoreApplication>
#include <QSocketNotifier>
#include <csignal>
#include <sys/signalfd.h>
#include <unistd.h>
namespace {
sigset_t quitSignals()
{
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGTERM);
sigaddset(&set, SIGINT);
return set;
}
} // namespace
void blockQuitSignals()
{
const sigset_t set = quitSignals();
pthread_sigmask(SIG_BLOCK, &set, nullptr);
}
void quitOnSignal()
{
const sigset_t set = quitSignals();
const int fd = signalfd(-1, &set, SFD_CLOEXEC | SFD_NONBLOCK);
if (fd < 0) {
qWarning("signalfd failed: settings may not be saved on SIGTERM");
pthread_sigmask(SIG_UNBLOCK, &set, nullptr);
return;
}
auto *notifier = new QSocketNotifier(fd, QSocketNotifier::Read, QCoreApplication::instance());
QObject::connect(notifier, &QSocketNotifier::activated, notifier, [fd] {
signalfd_siginfo info;
while (read(fd, &info, sizeof info) == sizeof info) { }
QCoreApplication::quit();
});
}
+8
View File
@@ -0,0 +1,8 @@
#pragma once
// KWin stops the input method with SIGTERM. Turns SIGTERM and SIGINT into a
// normal quit, so destructors run and pending settings are written.
// Call before QGuiApplication: threads Qt starts must inherit the blocked mask.
void blockQuitSignals();
// Call once the application exists.
void quitOnSignal();