Files

521 lines
17 KiB
C++
Raw Permalink Normal View History

2020-01-17 13:56:30 +08:00
/*
2021-11-15 15:16:40 +08:00
* Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd.
* 2010-2016 LXQt team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301, USA.
**/
2019-07-25 15:56:20 +08:00
#include <QApplication>
2019-08-26 16:42:49 +08:00
#include <QWidget>
#include <QDebug>
#include <QDesktopWidget>
2020-02-26 23:11:14 +08:00
#include <QFile>
#include <QTranslator>
#include <QCommandLineParser>
2019-12-17 15:47:45 +08:00
#include <QString>
2020-01-17 13:56:30 +08:00
#include <QSoundEffect>
2020-02-07 18:14:18 +08:00
#include <QTimer>
#include <QGSettings/QGSettings>
#include <X11/Xlib.h>
2019-07-25 15:56:20 +08:00
#include <QMessageBox>
#include <QDBusInterface>
#include <QDBusReply>
2019-12-17 15:47:45 +08:00
#include "ukuipower.h"
2020-01-17 13:56:30 +08:00
#include "mainwindow.h"
2021-11-15 15:16:40 +08:00
#include "loginedusers.h"
#include "lockchecker.h"
2021-04-21 09:32:49 +08:00
#include <QPushButton>
2021-01-30 15:21:06 +08:00
#include <sys/file.h>
#include <stdio.h>
#include <stdlib.h>
2021-03-04 14:44:40 +08:00
#include <pwd.h>
2021-04-22 14:33:32 +08:00
#include <ukui-log4qt.h>
2021-01-30 15:21:06 +08:00
#ifdef signals
#undef signals
#endif
2021-11-15 15:16:40 +08:00
/*菜单栏调用睡眠且有inhibitor阻塞时调用此函数进行消息提示*/
bool sleepInhibitorCheck(int doaction)
2021-11-23 09:02:11 +08:00
{
2021-04-21 09:32:49 +08:00
QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Warning);
msgBox.setWindowFlags(Qt::WindowStaysOnTopHint);
2021-11-15 15:16:40 +08:00
QString message;
QStringList Inhibitors;
QStringList Reason;
LockChecker::getSleepInhibitors(Inhibitors, Reason);
for (int i = 0; i < Inhibitors.length(); ++i) {
QString num = QString("%1").arg(Inhibitors.at(i));
QString reason = QString("%1 \n").arg(Reason.at(i));
QString inhibitMessage = "";
2022-03-30 10:25:59 +08:00
if(doaction == 1)//主要是为了睡眠、休眠中文翻译上作区分
inhibitMessage = num + QObject::tr(" is block system") + QObject::tr(" into sleep for reason ") + reason;//休眠
else
inhibitMessage = num + QObject::tr(" is block system ") + QObject::tr("into sleep for reason ") + reason;//睡眠
2021-11-15 15:16:40 +08:00
message.append(std::move(inhibitMessage));
}
// QString messageStr = "";
// if(doaction == 1)
// messageStr = QObject::tr("Are you sure") + QObject::tr(" you want to get system into sleep?");//休眠
// else
// messageStr = QObject::tr("Are you sure you want to get system into sleep?");//睡眠
// message.append(std::move(messageStr));
2021-11-15 15:16:40 +08:00
msgBox.setText(message);
QPushButton *cancelButton = msgBox.addButton(QObject::tr("cancel"), QMessageBox::ActionRole);
//QPushButton *confirmButton = msgBox.addButton(QObject::tr("confirm"), QMessageBox::RejectRole);
2021-11-15 15:16:40 +08:00
msgBox.exec();
if (msgBox.clickedButton() == cancelButton)
{
2021-11-15 15:16:40 +08:00
return false;
}
// else if (msgBox.clickedButton() == confirmButton)
// {
// return true;
// }
else
{
2021-11-15 15:16:40 +08:00
return false;
}
}
/*菜单栏调用重启或关机且有inhibitor阻塞时调用此函数进行消息提示*/
bool shutdownInhibitorCheck(int doaction)
2021-11-23 09:02:11 +08:00
{
2021-11-15 15:16:40 +08:00
QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Warning);
msgBox.setWindowFlags(Qt::WindowStaysOnTopHint);
QString message;
QStringList Inhibitors;
QStringList Reason;
LockChecker::getShutdownInhibitors(Inhibitors, Reason);
for(int i = 0; i < Inhibitors.length(); ++i) {
QString num = QString("%1").arg(Inhibitors.at(i));
QString reason = QString("%1 \n").arg(Reason.at(i));
QString inhibitMessage = "";
if(doaction == 5)
inhibitMessage = num + QObject::tr(" is block system into reboot for reason ") + reason;//重启
else
inhibitMessage = num + QObject::tr(" is block system into shutdown for reason ") + reason;//关机
2021-11-15 15:16:40 +08:00
message.append(std::move(inhibitMessage));
}
/*
QString messageStr = "";
if(doaction == 5)
messageStr = QObject::tr("Are you sure you want to reboot?");//重启
else
messageStr = QObject::tr("Are you sure you want to shutdown?");//关机
message.append(std::move(messageStr));
*/
2021-11-15 15:16:40 +08:00
msgBox.setText(message);
QPushButton *cancelButton = msgBox.addButton(QObject::tr("cancel"), QMessageBox::ActionRole);
//QPushButton *confirmButton = msgBox.addButton(QObject::tr("confirm"), QMessageBox::RejectRole);
2021-11-15 15:16:40 +08:00
msgBox.exec();
if (msgBox.clickedButton() == cancelButton)
{
qDebug() << "cancelButton";
2021-11-15 15:16:40 +08:00
return false;
}
// else if (msgBox.clickedButton() == confirmButton)
// {
// qDebug() << "confirmButton";
// return true;
// }
else
{
2021-11-15 15:16:40 +08:00
return false;
}
}
2021-11-23 09:02:11 +08:00
bool messageboxCheck()
{
2021-11-15 15:16:40 +08:00
QMessageBox msgBox;
// msgBox.setWindowTitle(QObject::tr("conform"));
msgBox.setIcon(QMessageBox::Warning);
msgBox.setWindowFlags(Qt::WindowStaysOnTopHint);
// msgBox.setModal(false);
msgBox.setText(QObject::tr("Multiple users are logged in at the same time.Are you sure you want to close this system?"));
QPushButton *cancelButton = msgBox.addButton(QObject::tr("cancel"), QMessageBox::ActionRole);
2021-04-21 09:32:49 +08:00
QPushButton *confirmButton = msgBox.addButton(QObject::tr("confirm"), QMessageBox::RejectRole);
msgBox.exec();
if (msgBox.clickedButton() == cancelButton) {
2021-06-30 14:11:11 +08:00
qDebug() << "cancel!";
2021-04-21 09:32:49 +08:00
return false;
} else if (msgBox.clickedButton() == confirmButton) {
2021-06-30 14:11:11 +08:00
qDebug() << "confirm!";
2021-04-21 09:32:49 +08:00
return true;
2021-09-23 15:43:53 +08:00
} else {
2021-04-21 09:32:49 +08:00
return false;
2021-09-23 15:43:53 +08:00
}
2021-04-21 09:32:49 +08:00
}
2021-11-23 09:02:11 +08:00
void messagecheck()
{
2021-01-18 20:39:07 +08:00
QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Warning);
msgBox.setWindowFlags(Qt::WindowStaysOnTopHint);
2021-11-15 15:16:40 +08:00
QString t1 = QObject::tr("System update or package installation in progress,this function is temporarily unavailable.");
2021-09-23 15:43:53 +08:00
QString t2 = QObject::tr("System backup or restore in progress,this function is temporarily unavailable.");
2021-02-26 10:36:55 +08:00
QFile file_update("/tmp/lock/kylin-update.lock");
QFile file_backup("/tmp/lock/kylin-backup.lock");
2021-06-30 14:11:11 +08:00
if (file_update.exists()) {
2021-02-26 10:36:55 +08:00
msgBox.setText(t1);
}
2021-06-30 14:11:11 +08:00
if (file_backup.exists()) {
2021-02-26 10:36:55 +08:00
msgBox.setText(t2);
}
2021-01-18 20:39:07 +08:00
QPushButton *cancelButton = msgBox.addButton(QObject::tr("OK"), QMessageBox::RejectRole);
2021-01-18 20:39:07 +08:00
msgBox.exec();
if (msgBox.clickedButton() == cancelButton) {
qDebug() << "OK!";
}
2021-01-18 20:39:07 +08:00
}
2021-11-23 09:02:11 +08:00
bool playShutdownMusic(UkuiPower &powermanager, int num, int cc, QTimer *up_to_time)
2021-01-30 15:21:06 +08:00
{
2021-06-30 14:11:11 +08:00
if (cc == 1) {
if (num == 1 || num == 5 || num == 6) {
2021-01-18 20:39:07 +08:00
messagecheck();
exit(0);
}
2021-06-30 14:11:11 +08:00
} else if (cc == 2) {
if (num == 1 || num == 4 || num == 5 || num == 6) {
messagecheck();
exit(0);
}
2021-01-18 20:39:07 +08:00
}
2021-06-30 14:11:11 +08:00
bool play_music = false;
QGSettings *gs = new QGSettings("org.ukui.session", "/org/ukui/desktop/session/");
if (num == 4) {
2021-04-01 13:40:51 +08:00
play_music = gs->get("logout-music").toBool();
2021-03-12 13:48:55 +08:00
}
2021-06-30 14:11:11 +08:00
if (num == 5 || num == 6) {
2021-04-01 13:40:51 +08:00
play_music = gs->get("poweroff-music").toBool();
2021-03-12 13:48:55 +08:00
}
2021-06-30 14:11:11 +08:00
if (num == 0 || num == 1 || num == 2) {
play_music = false;
}
2021-04-01 13:40:51 +08:00
2021-06-30 14:11:11 +08:00
gs->set("win-key-release", false);
static int action = num;
2021-06-30 14:11:11 +08:00
if (num == 4 || num == 0) {
QDBusInterface dbus("org.gnome.SessionManager", "/org/gnome/SessionManager",
"org.gnome.SessionManager", QDBusConnection::sessionBus());
if (!dbus.isValid()) {
qWarning() << "dbusCall: QDBusInterface is invalid";
return false;
}
2021-06-01 16:02:59 +08:00
QDBusMessage msg;
// if (num == 4) {
// msg = dbus.call("emitStartLogout");
// }
2021-06-01 16:02:59 +08:00
2021-11-15 15:16:40 +08:00
if (num == 0) {
2021-06-01 16:02:59 +08:00
msg = dbus.call("emitPrepareForSwitchuser");
2021-11-15 15:16:40 +08:00
}
if (!msg.errorName().isEmpty()) {
qWarning() << "Dbus error: " << msg;
}
}
2020-04-18 20:36:34 +08:00
if (play_music) {
2021-06-30 14:11:11 +08:00
// up_to_time and soundplayer can not be define out of this if().
// otherwise run ukui-session-tools --suspend with segmente error.
// because they will be delate at the end of the playShutdownMusic().
QObject::connect(up_to_time, &QTimer::timeout, [&]() {
2021-11-18 17:37:59 +08:00
if (powermanager.canAction(UkuiPower::Action(action))) {
powermanager.doAction(UkuiPower::Action(action));
}
exit(0);
});
2021-11-15 15:16:40 +08:00
QString xdg_session_type = qgetenv("XDG_SESSION_TYPE");
2021-06-30 14:11:11 +08:00
if (num == 5 || num == 6) {
2021-11-15 15:16:40 +08:00
if (xdg_session_type == "wayland") {
QProcess::startDetached("paplay --volume=23456 /usr/share/ukui/ukui-session-manager/shutdown.wav");
2021-11-23 09:02:11 +08:00
} else {
2021-11-15 15:16:40 +08:00
QProcess::startDetached("aplay /usr/share/ukui/ukui-session-manager/shutdown.wav");
2021-11-23 09:02:11 +08:00
}
2022-01-07 20:33:27 +08:00
up_to_time->start(5000);
2021-06-30 14:11:11 +08:00
} else if (num == 4) {
2021-11-15 15:16:40 +08:00
if (xdg_session_type == "wayland") {
QProcess::startDetached("paplay --volume=23456 /usr/share/ukui/ukui-session-manager/logout.wav");
2021-11-23 09:02:11 +08:00
} else {
2021-11-15 15:16:40 +08:00
QProcess::startDetached("aplay /usr/share/ukui/ukui-session-manager/logout.wav");
2021-11-23 09:02:11 +08:00
}
2022-01-07 20:33:27 +08:00
up_to_time->start(2000);
2021-06-30 14:11:11 +08:00
} else {
qDebug() << "error num";
2021-03-05 17:09:33 +08:00
return false;
}
2020-04-18 20:36:34 +08:00
} else {
if (powermanager.canAction(UkuiPower::Action(action))) {
powermanager.doAction(UkuiPower::Action(action));
}
exit(0);
}
return false;
}
2022-03-22 14:27:25 +08:00
/**
* @brief 判断当前是否处于锁屏
*/
bool screensaverIsActive()
{
QDBusMessage message = QDBusMessage::createMethodCall("org.ukui.ScreenSaver",
"/",
"org.ukui.ScreenSaver",
"GetLockState");
QDBusMessage response = QDBusConnection::sessionBus().call(message);
//判断method是否被正确返回
if (response.type() == QDBusMessage::ReplyMessage)
{
//从返回参数获取返回值
bool isActive = response.arguments()[0].toBool();
qDebug() << "screensaver isActive:" << isActive;
return isActive;
}
else
{
qDebug() << "QDBusMessage failed!";
return false;
}
}
2021-11-15 15:16:40 +08:00
int main(int argc, char* argv[])
2019-07-25 15:56:20 +08:00
{
2021-04-22 14:33:32 +08:00
initUkuiLog4qt("ukui-session-tools");
2021-11-15 15:16:40 +08:00
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
2020-07-21 07:00:46 +00:00
2021-11-15 15:16:40 +08:00
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
#endif
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
#endif
2021-03-11 16:00:47 +08:00
QApplication a(argc, argv);
2021-11-15 15:16:40 +08:00
// int cc = check_lock();
int cc = LockChecker::checkLock();
2021-11-23 09:02:11 +08:00
qDebug() << cc << " cc";
2021-01-30 15:21:06 +08:00
// Load ts files
const QString locale = QLocale::system().name();
2021-06-30 14:11:11 +08:00
QTranslator translator;
qDebug() << "local: " << locale;
qDebug() << "path: " << QStringLiteral(UKUI_TRANSLATIONS_DIR) + QStringLiteral("/ukui-session-manager");
2021-11-23 09:02:11 +08:00
if (translator.load(locale, QStringLiteral(UKUI_TRANSLATIONS_DIR) + QStringLiteral("/ukui-session-manager"))) {
2021-06-30 14:11:11 +08:00
a.installTranslator(&translator);
} else {
2021-06-30 14:11:11 +08:00
qDebug() << "Load translations file failed!";
}
UkuiPower powermanager(&a);
2021-06-30 14:11:11 +08:00
bool flag = true;
2021-06-30 14:11:11 +08:00
// define in the main() avoid scope error.
2021-03-13 15:38:06 +08:00
QTimer *up_to_time = new QTimer();
up_to_time->setSingleShot(true);
2021-06-30 14:11:11 +08:00
QGSettings *gs = new QGSettings("org.ukui.session", "/org/ukui/desktop/session/");
gs->set("win-key-release", true);
2021-04-21 09:32:49 +08:00
bool lock_file = false;
bool lock_user = false;
2021-06-30 14:11:11 +08:00
if (cc == 1) {
2021-04-21 09:32:49 +08:00
lock_file = true;
}
2021-06-30 14:11:11 +08:00
if (cc == 2) {
2021-04-21 09:32:49 +08:00
lock_file = true;
lock_user = true;
}
QCommandLineParser parser;
2021-06-30 14:11:11 +08:00
parser.setApplicationDescription(
QApplication::tr("UKUI session tools, show the shutdown dialog without any arguments."));
2019-12-17 15:47:45 +08:00
const QString VERINFO = QStringLiteral("2.0");
a.setApplicationVersion(VERINFO);
parser.addHelpOption();
parser.addVersionOption();
2021-06-30 14:11:11 +08:00
QCommandLineOption switchuserOption(QStringLiteral("switchuser"),
QApplication::tr("Switch the user of this computer."));
parser.addOption(switchuserOption);
2021-06-30 14:11:11 +08:00
QCommandLineOption hibernateOption(QStringLiteral("hibernate"),
QApplication::tr("Hibernate this computer."));
2020-12-07 20:54:08 +08:00
parser.addOption(hibernateOption);
2021-06-30 14:11:11 +08:00
QCommandLineOption suspendOption(QStringLiteral("suspend"),
QApplication::tr("Suspend this computer."));
parser.addOption(suspendOption);
2021-06-30 14:11:11 +08:00
QCommandLineOption logoutOption(QStringLiteral("logout"),
QApplication::tr("Logout this computer."));
parser.addOption(logoutOption);
2021-06-30 14:11:11 +08:00
QCommandLineOption rebootOption(QStringLiteral("reboot"),
QApplication::tr("Restart this computer."));
parser.addOption(rebootOption);
2021-06-30 14:11:11 +08:00
QCommandLineOption shutdownOption(QStringLiteral("shutdown"),
QApplication::tr("Shutdown this computer."));
parser.addOption(shutdownOption);
parser.process(a);
if (parser.isSet(switchuserOption)) {
2021-11-15 15:16:40 +08:00
flag = playShutdownMusic(powermanager, 0, cc, up_to_time);
}
2020-12-07 20:54:08 +08:00
if (parser.isSet(hibernateOption)) {
2021-11-15 15:16:40 +08:00
if (LockChecker::isSleepBlocked()) {
if (sleepInhibitorCheck(1)) {
2021-11-15 15:16:40 +08:00
flag = playShutdownMusic(powermanager, 1, cc, up_to_time);
} else {
return 0;
}
} else {
flag = playShutdownMusic(powermanager, 1, cc, up_to_time);
}
2020-12-07 20:54:08 +08:00
}
if (parser.isSet(suspendOption)) {
2021-11-15 15:16:40 +08:00
if (LockChecker::isSleepBlocked()) {
if (sleepInhibitorCheck(2)) {
2021-11-15 15:16:40 +08:00
flag = playShutdownMusic(powermanager, 2, cc, up_to_time);
} else {
return 0;
}
} else {
flag = playShutdownMusic(powermanager, 2, cc, up_to_time);
}
}
if (parser.isSet(logoutOption)) {
2021-11-15 15:16:40 +08:00
flag = playShutdownMusic(powermanager, 4, cc, up_to_time);
}
if (parser.isSet(rebootOption)) {
2021-11-15 15:16:40 +08:00
if (LockChecker::isShutdownBlocked()) {//有inhibitor的情况下
if (shutdownInhibitorCheck(5)) {//先提醒inhibitor
2021-11-15 15:16:40 +08:00
if (LockChecker::getLoginedUsers().count() > 1) {//再提醒多个用户登录的情况
if (messageboxCheck()) {
flag = playShutdownMusic(powermanager, 5, cc, up_to_time);
} else {
return 0;
}
} else {
flag = playShutdownMusic(powermanager, 5, cc, up_to_time);
}
2021-09-23 17:13:19 +08:00
} else {
2021-04-21 09:32:49 +08:00
return 0;
2021-06-30 14:11:11 +08:00
}
2021-11-15 15:16:40 +08:00
} else {//没有inhibitor的情况下
if (LockChecker::getLoginedUsers().count() > 1) {//提醒多个用户登录的情况
if (messageboxCheck()) {
flag = playShutdownMusic(powermanager, 5, cc, up_to_time);
} else {
return 0;
}
} else {
flag = playShutdownMusic(powermanager, 5, cc, up_to_time);
}
2021-09-23 17:13:19 +08:00
}
2021-11-15 15:16:40 +08:00
}
if (parser.isSet(shutdownOption)) {
2021-11-15 15:16:40 +08:00
if (LockChecker::isShutdownBlocked()) {
if (shutdownInhibitorCheck(6)) {
2021-11-15 15:16:40 +08:00
if (LockChecker::getLoginedUsers().count() > 1) {
if (messageboxCheck()) {
flag = playShutdownMusic(powermanager, 6, cc, up_to_time);
} else {
return 0;
}
} else {
flag = playShutdownMusic(powermanager, 6, cc, up_to_time);
}
2021-09-23 15:43:53 +08:00
} else {
2021-04-21 09:32:49 +08:00
return 0;
2021-06-30 14:11:11 +08:00
}
2021-09-23 15:43:53 +08:00
} else {
2021-11-15 15:16:40 +08:00
if (LockChecker::getLoginedUsers().count() > 1) {//提醒多个用户登录的情况
if (messageboxCheck()) {
flag = playShutdownMusic(powermanager, 6, cc, up_to_time);
2021-11-15 15:16:40 +08:00
} else {
return 0;
}
} else {
flag = playShutdownMusic(powermanager, 6, cc, up_to_time);
2021-11-15 15:16:40 +08:00
}
2021-09-23 15:43:53 +08:00
}
2021-11-15 15:16:40 +08:00
}
if(screensaverIsActive())
{
exit(0);
}
2020-02-07 18:14:18 +08:00
if (flag) {
// Load qss file
2021-11-15 15:16:40 +08:00
MainWindow *w = new MainWindow(lock_file, lock_user);
2020-02-07 18:14:18 +08:00
QFile qss(":/powerwin.qss");
qss.open(QFile::ReadOnly);
a.setStyleSheet(qss.readAll());
qss.close();
w->show();
2021-06-30 14:11:11 +08:00
QObject::connect(w, &MainWindow::signalTostart, [&]() {
// 从界面点击 切换用户、睡眠和休眠 按钮,则等待界面隐藏再执行命令
if (w->defaultnum < 3) {
2021-11-15 15:16:40 +08:00
w->hide();
QTimer::singleShot(500, [&]() {
playShutdownMusic(powermanager, w->defaultnum, cc, up_to_time);
});
} else
playShutdownMusic(powermanager, w->defaultnum, cc, up_to_time);
2020-02-07 18:14:18 +08:00
});
}
2019-07-25 15:56:20 +08:00
return a.exec();
}