diff --git a/qml/AppUI/FullScreenFooter.qml b/qml/AppUI/FullScreenFooter.qml index ab6bd95..54de039 100644 --- a/qml/AppUI/FullScreenFooter.qml +++ b/qml/AppUI/FullScreenFooter.qml @@ -53,8 +53,12 @@ Row { hoverEnabled: true ToolTip.visible: containsMouse ToolTip.text: powerButtonBase.toolTip + acceptedButtons: Qt.LeftButton | Qt.RightButton + property int spacingFromMenu: 8 + onClicked: { - powerButtonBase.clicked() + var buttonPosition = powerButtonArea.mapToGlobal(width, height); + powerButtonBase.clicked(mouse.button === Qt.LeftButton, buttonPosition.x - width - spacingFromMenu, buttonPosition.y + spacingFromMenu, mainWindow.isFullScreen); } } } diff --git a/qml/AppUI/Sidebar.qml b/qml/AppUI/Sidebar.qml index 7802084..61c4ae5 100644 --- a/qml/AppUI/Sidebar.qml +++ b/qml/AppUI/Sidebar.qml @@ -124,8 +124,12 @@ Item { hoverEnabled: true ToolTip.visible: hovered ToolTip.text: powerButtonBase.toolTip + acceptedButtons: Qt.LeftButton | Qt.RightButton + property int spacingFromMenu: 16 + onClicked: { - powerButtonBase.clicked() + var buttonPosition = powerButtonArea.mapToGlobal(width, height); + powerButtonBase.clicked(mouse.button === Qt.LeftButton, buttonPosition.x + spacingFromMenu, buttonPosition.y + spacingFromMenu, mainWindow.isFullScreen); } onEntered: { hovered = true diff --git a/src/utils/power-button.cpp b/src/utils/power-button.cpp index 283b2d3..dbde67a 100644 --- a/src/utils/power-button.cpp +++ b/src/utils/power-button.cpp @@ -18,8 +18,11 @@ #include #include +#include +#include #include "power-button.h" +#include "app-manager.h" #define KYLIN_POWER_NORMAL_PATH_MAJOR "qrc:///res/icon/pad_mainpower.svg" @@ -48,7 +51,98 @@ QString PowerButton::getToolTip() return {tr("power")}; } -void PowerButton::clicked() +void PowerButton::clicked(bool leftButtonClicked, int mouseX, int mouseY, bool isFullScreen) { - QProcess::startDetached("ukui-session-tools"); + if (leftButtonClicked) { + QProcess::startDetached("ukui-session-tools"); + } else { + openMenu(mouseX, mouseY, isFullScreen); + } +} + +void PowerButton::openMenu(int menuX, int menuY, bool isFullScreen) +{ + QMenu powerMenu; + QDBusReply reply; + QDBusInterface qDBusInterface("org.gnome.SessionManager", "/org/gnome/SessionManager", + "org.gnome.SessionManager", QDBusConnection::sessionBus()); + + if (canSwitch() && hasMultipleUsers()) { + connect(powerMenu.addAction(tr("Switch user")), &QAction::triggered, &powerMenu, [] { + AppManager::instance()->launchBinaryApp("ukui-session-tools", "--switchuser"); + }); + } + + reply = qDBusInterface.call("canHibernate"); + if (reply.isValid() && reply.value()) { + connect(powerMenu.addAction(tr("Hibernate")), &QAction::triggered, &powerMenu, [] { + AppManager::instance()->launchBinaryApp("ukui-session-tools", "--hibernate"); + }); + } + + reply = qDBusInterface.call("canSuspend"); + if (reply.isValid() && reply.value()) { + connect(powerMenu.addAction(tr("Suspend")), &QAction::triggered, &powerMenu, [] { + AppManager::instance()->launchBinaryApp("ukui-session-tools", "--suspend"); + }); + } + + connect(powerMenu.addAction(tr("Lock Screen")), &QAction::triggered, &powerMenu, [] { + AppManager::instance()->launchBinaryApp("ukui-screensaver-command", "-l"); + }); + + reply = qDBusInterface.call("canLogout"); + if (reply.isValid() && reply.value()) { + connect(powerMenu.addAction(tr("Log Out")), &QAction::triggered, &powerMenu, [] { + AppManager::instance()->launchBinaryApp("ukui-session-tools", "--logout"); + }); + } + + reply = qDBusInterface.call("canReboot"); + if (reply.isValid() && reply.value()) { + connect(powerMenu.addAction(tr("Reboot")), &QAction::triggered, &powerMenu, [] { + AppManager::instance()->launchBinaryApp("ukui-session-tools", "--reboot"); + }); + } + + reply = qDBusInterface.call("canPowerOff"); + if (reply.isValid() && reply.value()) { + connect(powerMenu.addAction(tr("Power Off")), &QAction::triggered, &powerMenu, [] { + AppManager::instance()->launchBinaryApp("ukui-session-tools", "--shutdown"); + }); + } + + powerMenu.setAttribute(Qt::WA_DeleteOnClose); + + if (isFullScreen) { + powerMenu.exec(QPoint(menuX - powerMenu.sizeHint().width(), menuY - powerMenu.sizeHint().height())); + } else { + powerMenu.exec(QPoint(menuX, menuY - powerMenu.sizeHint().height())); + } +} + +bool PowerButton::hasMultipleUsers() +{ + QDBusInterface interface("org.freedesktop.Accounts", "/org/freedesktop/Accounts", + "org.freedesktop.DBus.Properties", QDBusConnection::systemBus()); + + if (!interface.isValid()) { + return false; + } + + QDBusReply reply = interface.call("Get", "org.freedesktop.Accounts", "HasMultipleUsers"); + return reply.value().toBool(); +} + +bool PowerButton::canSwitch() +{ + QDBusInterface interface("org.freedesktop.DisplayManager", "/org/freedesktop/DisplayManager/Seat0", + "org.freedesktop.DBus.Properties", QDBusConnection::systemBus()); + + if (!interface.isValid()) { + return false; + } + + QDBusReply reply = interface.call("Get", "org.freedesktop.DisplayManager.Seat", "CanSwitch"); + return reply.value().toBool(); } diff --git a/src/utils/power-button.h b/src/utils/power-button.h index 1b1611a..0fe6c36 100644 --- a/src/utils/power-button.h +++ b/src/utils/power-button.h @@ -19,6 +19,7 @@ #define POWERBUTTON_H #include +#include namespace UkuiMenu { @@ -35,7 +36,12 @@ public: QString getToolTip(); public Q_SLOTS: - void clicked(); + void clicked(bool leftButtonClicked, int mouseX, int mouseY, bool isFullScreen); + +private: + void openMenu(int menuX, int menuY, bool isFullScreen); + bool hasMultipleUsers(); + bool canSwitch(); Q_SIGNALS: void iconChanged();