Управление сессиями на EGLFS QPA backend
Работая на бэкэнде QPA такого EGLFS нет X11. Что является поставщиком функциональности менеджера сеансов (сервис, как systemd-logind
или что-то еще, скажем, по Ubuntu) по делу?
С помощью QtDBus
Я могу взаимодействовать с systemd-logind
непосредственно:
#define LOGIND_DBUS_SERVICE "org.freedesktop.login1"
#define LOGIND_DBUS_PATH "/org/freedesktop/login1"
#define LOGIND_DBUS_INTERFACE "org.freedesktop.login1.Manager"
QDBusInterface logind{LOGIND_DBUS_SERVICE, LOGIND_DBUS_PATH, LOGIND_DBUS_INTERFACE, QDBusConnection::systemBus()}; // class data member
// somewhere into constructor
if (!logind.connection().connect(logind.service(), logind.path(), logind.interface(), "PrepareForShutdown",
this, SLOT(onPrepareForShutdown(bool)))) {
Q_ASSERT(false);
}
Цель приведенного выше кода состоит в том, чтобы выйти из приложения условно и с задержкой (с таймером обратного отсчета, показанным в диалоговом окне приложения) после получения сигнала. я использую logind
Возможность временно заблокировать / заблокировать возможность выключения системы.
Под единством (xcb
QPA) если я поменяю с gsettings set org.gnome.settings-daemon.plugins.power button-power 'interactive'
(или через dconf-tools
' dconf-editor
) чтобы 'shutdown'
, то я подозреваю, что мое приложение не закрывается должным образом. Просто убит. Потому что лог-файлы не сбрасываются на диск.
Если это изменилось на 'nothing'
, затем org.freedesktop.login1.Manager
не излучает PrepareForShutdown(bool start)
Сигнал вообще и кнопка выключения питания тоже не действуют. Этот режим бесполезен.
В 'interactive'
(когда я подтверждаю выключение / перезагрузку с помощью кнопок Unity) и 'shutdown'
Режимы есть большая проблема:
QDBusUnixFileDescriptor poweroffInhibitor; // application-liftime class data member
// somewhere into constructor
if (QDBusUnixFileDescriptor::isSupported()) { // enable inhibition if possible
if (logind.connection().connectionCapabilities() & QDBusConnection::UnixFileDescriptorPassing) {
const auto what = QStringLiteral("shutdown:idle");
const auto who = qAppName();
const auto why = QStringLiteral("Need to safely save logs");
const auto mode = QStringLiteral("block"); // block, delay
const QDBusReply< QDBusUnixFileDescriptor > reply = logind.callWithArgumentList(QDBus::Block, "Inhibit", {what, who, why, mode});
if (!reply.isValid()) {
const auto error = reply.error();
qCWarning(powerScheduleCategory).noquote()
<< tr("Unable to inhibit (what is '%1', who is '%2', why is '%3', mode is '%4'): %5 (%6)")
.arg(what, who, why, mode,
error.name(), error.message());
} else {
poweroffInhibitor = reply.value();
if (!poweroffInhibitor.isValid()) {
qCWarning(powerScheduleCategory).noquote()
<< tr("Invalid UNIX file descriptor is returned from logind");
} else {
qCInfo(powerScheduleCategory).noquote()
<< tr("UNIX file descriptor '%1' is returned from logind")
.arg(poweroffInhibitor.fileDescriptor());
}
}
} else {
qCWarning(powerScheduleCategory).noquote()
<< tr("D-Bus connection %1 does not support UNIX file descriptors data type")
.arg(logind.connection().name());
}
} else {
qCWarning(powerScheduleCategory).noquote()
<< tr("OS %1 (kernel %2) does not support UNIX file descriptors")
.arg(QSysInfo::productType(), QSysInfo::kernelType());
}
Хранение незамкнутого дескриптора файла UNIX -"ингибитора" (или в равной степени его dup()
-licate) полностью игнорируется Unity (или Ubuntu, не знаю, кто за это отвечает и какие термины я должен использовать, чтобы описать это здесь) в любом режиме, когда я использую кнопки (графические или аппаратные).
Я уверен, что запрет на самом деле включен. Потому что работает reboot
(shutdown -r now
и т. д.) от непривилегированной пользовательской оболочки не дает никакого эффекта и выводит на стандартный вывод причины запретов (точно what, who, why, mode
указанное выше, происхождение из моего приложения и другие строки из других системных ингибиторов).
Приложение является единственным графическим интерфейсом пользователя, предоставленным в системе для пользователя в течение всего срока его службы. Поэтому я хочу обработать (подтвердить, отклонить с помощью модальных диалоговых приложений) события, связанные с управлением питанием, от системы /ACPI/ менеджера сеансов (не знаю, кто из них) сам.
Как добиться желаемого на безголовой системе? Ubuntu или Ubuntu- как один. Возможно на основе systemd
,
Будет QSessionManager
функциональность работает на EGLFS QPA хотя бы в ограниченной форме (как на Windows или macOS)?