diff --git a/applets/lock_logout/contents/ui/ConfigGeneral.qml b/applets/lock_logout/contents/ui/ConfigGeneral.qml index 1f5e7b704..10c8ae099 100644 --- a/applets/lock_logout/contents/ui/ConfigGeneral.qml +++ b/applets/lock_logout/contents/ui/ConfigGeneral.qml @@ -1,93 +1,93 @@ /* * Copyright 2013 Sebastian Kügler * Copyright 2015 Kai Uwe Broulik * * 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 of the License, 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 Street, Fifth Floor, Boston, MA 2.010-1301, USA. */ import QtQuick 2.0 import QtQuick.Layouts 1.1 as QtLayouts import QtQuick.Controls 1.0 as QtControls import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.extras 2.0 as PlasmaExtras Item { id: iconsPage width: childrenRect.width height: childrenRect.height implicitWidth: pageColumn.implicitWidth implicitHeight: pageColumn.implicitHeight readonly property int checkedOptions: leave.checked + lock.checked + switchUser.checked + hibernate.checked + sleep.checked property alias cfg_show_requestShutDown: leave.checked property alias cfg_show_lockScreen: lock.checked property alias cfg_show_switchUser: switchUser.checked property alias cfg_show_suspendToDisk: hibernate.checked property alias cfg_show_suspendToRam: sleep.checked readonly property bool canLockScreen: dataEngine.data["Sleep States"].LockScreen readonly property bool canSuspend: dataEngine.data["Sleep States"].Suspend readonly property bool canHibernate: dataEngine.data["Sleep States"].Hibernate SystemPalette { id: sypal } PlasmaCore.DataSource { id: dataEngine engine: "powermanagement" connectedSources: ["Sleep States"] } QtLayouts.ColumnLayout { id: pageColumn anchors.left: parent.left PlasmaExtras.Heading { text: i18nc("Heading for list of actions (leave, lock, shutdown, ...)", "Actions") color: syspal.text level: 2 } QtControls.CheckBox { id: leave text: i18n("Leave") // ensure user cannot have all options unchecked enabled: checkedOptions > 1 || !checked } QtControls.CheckBox { id: lock text: i18n("Lock") enabled: iconsPage.canLockScreen && (checkedOptions > 1 || !checked) } QtControls.CheckBox { id: switchUser text: i18n("Switch User") enabled: checkedOptions > 1 || !checked } QtControls.CheckBox { id: hibernate text: i18n("Hibernate") enabled: iconsPage.canHibernate && (checkedOptions > 1 || !checked) } QtControls.CheckBox { id: sleep - text: i18n("Suspend") + text: i18nc("Suspend to RAM", "Sleep") enabled: iconsPage.canSuspend && (checkedOptions > 1 || !checked) } } } diff --git a/applets/lock_logout/contents/ui/data.js b/applets/lock_logout/contents/ui/data.js index f81f598ac..6ccca7f55 100644 --- a/applets/lock_logout/contents/ui/data.js +++ b/applets/lock_logout/contents/ui/data.js @@ -1,29 +1,29 @@ var data = [{ icon: "system-lock-screen", operation: "lockScreen", tooltip_mainText: i18n("Lock"), tooltip_subText: i18n("Lock the screen"), requires: "LockScreen" }, { icon: "system-switch-user", operation: "switchUser", tooltip_mainText: i18n("Switch user"), tooltip_subText: i18n("Start a parallel session as a different user") }, { icon: "system-shutdown", operation: "requestShutDown", tooltip_mainText: i18n("Leave..."), tooltip_subText: i18n("Logout, turn off or restart the computer") }, { icon: "system-suspend", operation: "suspendToRam", - tooltip_mainText: i18n("Suspend"), + tooltip_mainText: i18nc("Suspend to RAM", "Sleep"), tooltip_subText: i18n("Sleep (suspend to RAM)"), requires: "Suspend" }, { icon: "system-suspend-hibernate", operation: "suspendToDisk", tooltip_mainText: i18n("Hibernate"), tooltip_subText: i18n("Hibernate (suspend to disk)"), requires: "Hibernate" }] diff --git a/applets/lock_logout/contents/ui/lockout.qml b/applets/lock_logout/contents/ui/lockout.qml index 80e7e53b8..1f6f64bed 100644 --- a/applets/lock_logout/contents/ui/lockout.qml +++ b/applets/lock_logout/contents/ui/lockout.qml @@ -1,179 +1,179 @@ /* * Copyright 2011 Viranch Mehta * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library 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 Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import QtQuick 2.0 import QtQuick.Layouts 1.0 import org.kde.plasma.plasmoid 2.0 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 2.0 import org.kde.kquickcontrolsaddons 2.0 import "data.js" as Data Flow { id: lockout Layout.minimumWidth: { if (plasmoid.formFactor === PlasmaCore.Types.Vertical) { return 0 } else if (plasmoid.formFactor === PlasmaCore.Types.Horizontal) { return height < minButtonSize * visibleButtons ? height * visibleButtons : height / visibleButtons - 1; } else { return width > height ? minButtonSize * visibleButtons : minButtonSize } } Layout.minimumHeight: { if (plasmoid.formFactor === PlasmaCore.Types.Vertical) { return width >= minButtonSize * visibleButtons ? width / visibleButtons - 1 : width * visibleButtons } else if (plasmoid.formFactor === PlasmaCore.Types.Horizontal) { return 0 } else { return width > height ? minButtonSize : minButtonSize * visibleButtons } } Layout.preferredWidth: Layout.minimumWidth Layout.preferredHeight: Layout.minimumHeight readonly property int minButtonSize: units.iconSizes.small Plasmoid.preferredRepresentation: Plasmoid.fullRepresentation readonly property int visibleButtons: { var count = 0 for (var i = 0, j = items.count; i < j; ++i) { if (items.itemAt(i).visible) { ++count } } return count } flow: { if ((plasmoid.formFactor === PlasmaCore.Types.Vertical && width >= minButtonSize * visibleButtons) || (plasmoid.formFactor === PlasmaCore.Types.Horizontal && height < minButtonSize * visibleButtons) || (width > height)) { return Flow.LeftToRight // horizontal } else { return Flow.TopToBottom // vertical } } PlasmaCore.DataSource { id: dataEngine engine: "powermanagement" connectedSources: ["PowerDevil", "Sleep States"] } Repeater { id: items property int itemWidth: parent.flow==Flow.LeftToRight ? Math.floor(parent.width/visibleButtons) : parent.width property int itemHeight: parent.flow==Flow.TopToBottom ? Math.floor(parent.height/visibleButtons) : parent.height property int iconSize: Math.min(itemWidth, itemHeight) model: Data.data delegate: Item { id: iconDelegate visible: plasmoid.configuration["show_" + modelData.operation] && (!modelData.hasOwnProperty("requires") || dataEngine.data["Sleep States"][modelData.requires]) width: items.itemWidth height: items.itemHeight PlasmaCore.IconItem { id: iconButton width: items.iconSize height: items.iconSize anchors.centerIn: parent source: modelData.icon scale: mouseArea.pressed ? 0.9 : 1 active: mouseArea.containsMouse MouseArea { id: mouseArea anchors.fill: parent hoverEnabled: true onReleased: clickHandler(modelData.operation, this) PlasmaCore.ToolTipArea { anchors.fill: parent mainText: modelData.tooltip_mainText subText: modelData.tooltip_subText icon: modelData.icon } } } } } Component { id: hibernateDialogComponent QueryDialog { titleIcon: "system-suspend-hibernate" titleText: i18n("Hibernate") message: i18n("Do you want to suspend to disk (hibernate)?") location: plasmoid.location acceptButtonText: i18n("Yes") rejectButtonText: i18n("No") onAccepted: performOperation("suspendToDisk") } } property QueryDialog hibernateDialog Component { id: sleepDialogComponent QueryDialog { titleIcon: "system-suspend" - titleText: i18n("Suspend") + titleText: i18nc("Suspend to RAM", "Sleep") message: i18n("Do you want to suspend to RAM (sleep)?") location: plasmoid.location acceptButtonText: i18n("Yes") rejectButtonText: i18n("No") onAccepted: performOperation("suspendToRam") } } property QueryDialog sleepDialog function clickHandler(what, button) { if (what == "suspendToDisk") { if (!hibernateDialog) { hibernateDialog = hibernateDialogComponent.createObject(lockout); } hibernateDialog.visualParent = button hibernateDialog.open(); } else if (what == "suspendToRam") { if (!sleepDialog) { sleepDialog = sleepDialogComponent.createObject(lockout); } sleepDialog.visualParent = button sleepDialog.open(); } else { performOperation(what); } } function performOperation(what) { var service = dataEngine.serviceForSource("PowerDevil"); var operation = service.operationDescription(what); service.startOperationCall(operation); } } diff --git a/lookandfeel/contents/logout/Logout.qml b/lookandfeel/contents/logout/Logout.qml index f26b15645..d3eff2f10 100644 --- a/lookandfeel/contents/logout/Logout.qml +++ b/lookandfeel/contents/logout/Logout.qml @@ -1,245 +1,245 @@ /*************************************************************************** * Copyright (C) 2014 by Aleix Pol Gonzalez * * * * 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 of the License, 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 Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ import QtQuick 2.2 import QtQuick.Layouts 1.2 import QtQuick.Controls 1.1 as Controls import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 2.0 as PlasmaComponents import org.kde.kcoreaddons 1.0 as KCoreAddons import "../components" import "timer.js" as AutoTriggerTimer import org.kde.plasma.private.sessions 2.0 PlasmaCore.ColorScope { id: root colorGroup: PlasmaCore.Theme.ComplementaryColorGroup height: screenGeometry.height width: screenGeometry.width signal logoutRequested() signal haltRequested() signal suspendRequested(int spdMethod) signal rebootRequested() signal rebootRequested2(int opt) signal cancelRequested() signal lockScreenRequested() property alias backgroundColor: backgroundRect.color function sleepRequested() { root.suspendRequested(2); } function hibernateRequested() { root.suspendRequested(4); } property real timeout: 30 property real remainingTime: root.timeout property var currentAction: { switch (sdtype) { case ShutdownType.ShutdownTypeReboot: return root.rebootRequested; case ShutdownType.ShutdownTypeHalt: return root.haltRequested; default: return root.logoutRequested; } } KCoreAddons.KUser { id: kuser } // For showing a "other users are logged in" hint SessionsModel { id: sessionsModel includeUnusedSessions: false } Controls.Action { onTriggered: root.cancelRequested() shortcut: "Escape" } onRemainingTimeChanged: { if (remainingTime <= 0) { root.currentAction(); } } Timer { id: countDownTimer running: true repeat: true interval: 1000 onTriggered: remainingTime-- Component.onCompleted: { AutoTriggerTimer.addCancelAutoTriggerCallback(function() { countDownTimer.running = false; }); } } function isLightColor(color) { return Math.max(color.r, color.g, color.b) > 0.5 } Rectangle { id: backgroundRect anchors.fill: parent //use "black" because this is intended to look like a general darkening of the scene. a dark gray as normal background would just look too "washed out" color: root.isLightColor(PlasmaCore.ColorScope.backgroundColor) ? PlasmaCore.ColorScope.backgroundColor : "black" opacity: 0.5 } MouseArea { anchors.fill: parent onClicked: root.cancelRequested() } UserDelegate { width: units.iconSizes.enormous height: width anchors { horizontalCenter: parent.horizontalCenter bottom: parent.verticalCenter } constrainText: false avatarPath: kuser.faceIconUrl iconSource: "user-identity" isCurrent: true name: kuser.fullName } ColumnLayout { anchors { top: parent.verticalCenter topMargin: units.gridUnit * 2 horizontalCenter: parent.horizontalCenter } spacing: units.largeSpacing height: Math.max(implicitHeight, units.gridUnit * 10) width: Math.max(implicitWidth, units.gridUnit * 16) PlasmaComponents.Label { Layout.maximumWidth: units.gridUnit * 16 Layout.alignment: Qt.AlignHCenter Layout.fillWidth: true horizontalAlignment: Text.AlignHCenter wrapMode: Text.WordWrap font.italic: true text: i18ndp("plasma_lookandfeel_org.kde.lookandfeel", "One other user is currently logged in. If the computer is shut down or rebooted, that user may lose work.", "%1 other users are currently logged in. If the computer is shut down or rebooted, those users may lose work.", sessionsModel.count) visible: sessionsModel.count > 1 } RowLayout { spacing: units.largeSpacing * 2 Layout.alignment: Qt.AlignHCenter LogoutButton { id: suspendButton iconSource: "system-suspend" - text: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Suspend") + text: i18ndc("plasma_lookandfeel_org.kde.lookandfeel", "Suspend to RAM", "Sleep") action: root.sleepRequested KeyNavigation.left: logoutButton KeyNavigation.right: hibernateButton visible: spdMethods.SuspendState } LogoutButton { id: hibernateButton iconSource: "system-suspend-hibernate" text: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Hibernate") action: root.hibernateRequested KeyNavigation.left: suspendButton KeyNavigation.right: rebootButton visible: spdMethods.HibernateState } LogoutButton { id: rebootButton iconSource: "system-reboot" text: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Reboot") action: root.rebootRequested KeyNavigation.left: hibernateButton KeyNavigation.right: shutdownButton focus: sdtype == ShutdownType.ShutdownTypeReboot visible: maysd } LogoutButton { id: shutdownButton iconSource: "system-shutdown" text: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Shut Down") action: root.haltRequested KeyNavigation.left: rebootButton KeyNavigation.right: logoutButton focus: sdtype == ShutdownType.ShutdownTypeHalt visible: maysd } LogoutButton { id: logoutButton iconSource: "system-log-out" text: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Logout") action: root.logoutRequested KeyNavigation.left: shutdownButton KeyNavigation.right: suspendButton focus: sdtype == ShutdownType.ShutdownTypeNone visible: canLogout } } PlasmaComponents.Label { Layout.alignment: Qt.AlignHCenter //opacity, as visible would re-layout opacity: countDownTimer.running ? 1 : 0 Behavior on opacity { OpacityAnimator { duration: units.longDuration easing.type: Easing.InOutQuad } } text: { switch (sdtype) { case ShutdownType.ShutdownTypeReboot: return i18ndp("plasma_lookandfeel_org.kde.lookandfeel", "Reboot in 1 second", "Reboot in %1 seconds", root.remainingTime); case ShutdownType.ShutdownTypeHalt: return i18ndp("plasma_lookandfeel_org.kde.lookandfeel", "Shutting down in 1 second", "Shutting down in %1 seconds", root.remainingTime); default: return i18ndp("plasma_lookandfeel_org.kde.lookandfeel", "Logging out in 1 second", "Logging out in %1 seconds", root.remainingTime); } } } RowLayout { Layout.alignment: Qt.AlignHCenter PlasmaComponents.Button { enabled: root.currentAction != null text: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "OK") onClicked: root.currentAction() } PlasmaComponents.Button { text: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Cancel") onClicked: root.cancelRequested() } } } } diff --git a/runners/powerdevil/PowerDevilRunner.cpp b/runners/powerdevil/PowerDevilRunner.cpp index 6b92b9c6f..95f0274de 100644 --- a/runners/powerdevil/PowerDevilRunner.cpp +++ b/runners/powerdevil/PowerDevilRunner.cpp @@ -1,263 +1,265 @@ /*************************************************************************** * Copyright 2008 by Dario Freddi * * Copyright 2008 by Sebastian Kügler * * * * 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 of the License, 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 Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ #include "PowerDevilRunner.h" #include #include #include #include #include #include #include #include #include #include K_EXPORT_PLASMA_RUNNER(powerdevil, PowerDevilRunner) PowerDevilRunner::PowerDevilRunner(QObject *parent, const QVariantList &args) : Plasma::AbstractRunner(parent, args), m_shortestCommand(1000) { qDBusRegisterMetaType< StringStringMap >(); setObjectName( QLatin1String("PowerDevil" )); setIgnoredTypes(Plasma::RunnerContext::Directory | Plasma::RunnerContext::File | Plasma::RunnerContext::NetworkLocation | Plasma::RunnerContext::Help); updateStatus(); initUpdateTriggers(); /* Let's define all the words here. m_words contains all the words that * will eventually trigger a match in the runner. */ QStringList commands; commands << i18nc("Note this is a KRunner keyword", "suspend") << i18nc("Note this is a KRunner keyword", "sleep") << i18nc("Note this is a KRunner keyword", "hibernate") << i18nc("Note this is a KRunner keyword", "to disk") << i18nc("Note this is a KRunner keyword", "to ram") << i18nc("Note this is a KRunner keyword", "screen brightness") << i18nc("Note this is a KRunner keyword", "dim screen"); foreach (const QString &command, commands) { if (command.length() < m_shortestCommand) { m_shortestCommand = command.length(); } } } void PowerDevilRunner::updateSyntaxes() { QList syntaxes; syntaxes.append(Plasma::RunnerSyntax(i18nc("Note this is a KRunner keyword", "suspend"), i18n("Lists system suspend (e.g. sleep, hibernate) options " "and allows them to be activated"))); QSet< Solid::PowerManagement::SleepState > states = Solid::PowerManagement::supportedSleepStates(); if (states.contains(Solid::PowerManagement::SuspendState)) { Plasma::RunnerSyntax sleepSyntax(i18nc("Note this is a KRunner keyword", "sleep"), i18n("Suspends the system to RAM")); sleepSyntax.addExampleQuery(i18nc("Note this is a KRunner keyword", "to ram")); syntaxes.append(sleepSyntax); } if (states.contains(Solid::PowerManagement::HibernateState)) { Plasma::RunnerSyntax hibernateSyntax(i18nc("Note this is a KRunner keyword", "hibernate"), i18n("Suspends the system to disk")); hibernateSyntax.addExampleQuery(i18nc("Note this is a KRunner keyword", "to disk")); syntaxes.append(hibernateSyntax); } Plasma::RunnerSyntax brightnessSyntax(i18nc("Note this is a KRunner keyword", "screen brightness"), // xgettext:no-c-format i18n("Lists screen brightness options or sets it to the brightness defined by :q:; " "e.g. screen brightness 50 would dim the screen to 50% maximum brightness")); brightnessSyntax.addExampleQuery(i18nc("Note this is a KRunner keyword", "dim screen")); syntaxes.append(brightnessSyntax); setSyntaxes(syntaxes); } PowerDevilRunner::~PowerDevilRunner() { } void PowerDevilRunner::initUpdateTriggers() { // Also receive updates triggered through the DBus QDBusConnection dbus = QDBusConnection::sessionBus(); if (dbus.interface()->isServiceRegistered(QStringLiteral("org.kde.Solid.PowerManagement"))) { if (!dbus.connect(QStringLiteral("org.kde.Solid.PowerManagement"), QStringLiteral("/org/kde/Solid/PowerManagement"), QStringLiteral("org.kde.Solid.PowerManagement"), QStringLiteral("configurationReloaded"), this, SLOT(updateStatus()))) { qDebug() << "error!"; } } } void PowerDevilRunner::updateStatus() { updateSyntaxes(); } bool PowerDevilRunner::parseQuery(const QString& query, const QList& rxList, QString& parameter) const { foreach (const QRegExp& rx, rxList) { if (rx.exactMatch(query)) { parameter = rx.cap(1).trimmed(); return true; } } return false; } void PowerDevilRunner::match(Plasma::RunnerContext &context) { const QString term = context.query(); if (term.length() < m_shortestCommand) { return; } QList matches; QString parameter; if (parseQuery(term, QList() << QRegExp(i18nc("Note this is a KRunner keyword; %1 is a parameter", "screen brightness %1", QStringLiteral("(.*)")), Qt::CaseInsensitive) << QRegExp(i18nc("Note this is a KRunner keyword", "screen brightness"), Qt::CaseInsensitive) << QRegExp(i18nc("Note this is a KRunner keyword; %1 is a parameter", "dim screen %1", QStringLiteral("(.*)")), Qt::CaseInsensitive) << QRegExp(i18nc("Note this is a KRunner keyword", "dim screen"), Qt::CaseInsensitive), parameter)) { if (!parameter.isEmpty()) { bool test; int b = parameter.toInt(&test); if (test) { int brightness = qBound(0, b, 100); Plasma::QueryMatch match(this); match.setType(Plasma::QueryMatch::ExactMatch); match.setIconName(QStringLiteral("preferences-system-power-management")); match.setText(i18n("Set Brightness to %1", brightness)); match.setData(brightness); match.setRelevance(1); match.setId(QStringLiteral("BrightnessChange")); matches.append(match); } } else { Plasma::QueryMatch match1(this); match1.setType(Plasma::QueryMatch::ExactMatch); match1.setIconName(QStringLiteral("preferences-system-power-management")); match1.setText(i18n("Dim screen totally")); match1.setRelevance(1); match1.setId(QStringLiteral("DimTotal")); matches.append(match1); Plasma::QueryMatch match2(this); match2.setType(Plasma::QueryMatch::ExactMatch); match2.setIconName(QStringLiteral("preferences-system-power-management")); match2.setText(i18n("Dim screen by half")); match2.setRelevance(1); match2.setId(QStringLiteral("DimHalf")); matches.append(match2); } - } else if (term.compare(i18nc("Note this is a KRunner keyword", "suspend"), Qt::CaseInsensitive) == 0) { + } else if (term.compare(i18nc("Note this is a KRunner keyword", "sleep"), Qt::CaseInsensitive) == 0) { QSet< Solid::PowerManagement::SleepState > states = Solid::PowerManagement::supportedSleepStates(); if (states.contains(Solid::PowerManagement::SuspendState)) { addSuspendMatch(Solid::PowerManagement::SuspendState, matches); } if (states.contains(Solid::PowerManagement::HibernateState)) { addSuspendMatch(Solid::PowerManagement::HibernateState, matches); } - } else if (term.compare(i18nc("Note this is a KRunner keyword", "sleep"), Qt::CaseInsensitive) == 0 || + } else if (term.compare(i18nc("Note this is a KRunner keyword", "suspend"), Qt::CaseInsensitive) == 0 || term.compare(i18nc("Note this is a KRunner keyword", "to ram"), Qt::CaseInsensitive) == 0) { addSuspendMatch(Solid::PowerManagement::SuspendState, matches); } else if (term.compare(i18nc("Note this is a KRunner keyword", "hibernate"), Qt::CaseInsensitive) == 0 || term.compare(i18nc("Note this is a KRunner keyword", "to disk"), Qt::CaseInsensitive) == 0) { addSuspendMatch(Solid::PowerManagement::HibernateState, matches); } if (!matches.isEmpty()) { context.addMatches(matches); } } void PowerDevilRunner::addSuspendMatch(int value, QList &matches) { Plasma::QueryMatch match(this); match.setType(Plasma::QueryMatch::ExactMatch); switch ((Solid::PowerManagement::SleepState)value) { case Solid::PowerManagement::SuspendState: case Solid::PowerManagement::StandbyState: match.setIconName(QStringLiteral("system-suspend")); - match.setText(i18n("Suspend")); + match.setText(i18nc("Suspend to RAM", "Sleep")); + match.setSubtext(i18n("Suspend to RAM")); match.setRelevance(1); break; case Solid::PowerManagement::HibernateState: match.setIconName(QStringLiteral("system-suspend-hibernate")); - match.setText(i18n("Hibernate")); + match.setText(i18nc("Suspend to disk", "Hibernate")); + match.setSubtext(i18n("Suspend to disk")); match.setRelevance(0.99); break; } match.setData(value); - match.setId(QStringLiteral("Suspend")); + match.setId(QStringLiteral("Sleep")); matches.append(match); } void PowerDevilRunner::run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match) { Q_UNUSED(context) QDBusInterface iface(QStringLiteral("org.kde.Solid.PowerManagement"), QStringLiteral("/org/kde/Solid/PowerManagement"), QStringLiteral("org.kde.Solid.PowerManagement")); QDBusInterface brightnessIface(QStringLiteral("org.kde.Solid.PowerManagement"), QStringLiteral("/org/kde/Solid/PowerManagement/Actions/BrightnessControl"), QStringLiteral("org.kde.Solid.PowerManagement.Actions.BrightnessControl")); if (match.id().startsWith(QLatin1String("PowerDevil_ProfileChange"))) { iface.asyncCall(QStringLiteral("loadProfile"), match.data().toString()); } else if (match.id() == QLatin1String("PowerDevil_BrightnessChange")) { brightnessIface.asyncCall(QStringLiteral("setBrightness"), match.data().toInt()); } else if (match.id() == QLatin1String("PowerDevil_DimTotal")) { brightnessIface.asyncCall(QStringLiteral("setBrightness"), 0); } else if (match.id() == QLatin1String("PowerDevil_DimHalf")) { QDBusReply brightness = brightnessIface.asyncCall(QStringLiteral("brightness")); brightnessIface.asyncCall(QStringLiteral("setBrightness"), static_cast(brightness / 2)); } else if (match.id().startsWith(QLatin1String("PowerDevil_Suspend"))) { switch ((Solid::PowerManagement::SleepState)match.data().toInt()) { case Solid::PowerManagement::SuspendState: case Solid::PowerManagement::StandbyState: Solid::PowerManagement::requestSleep(Solid::PowerManagement::SuspendState, nullptr, nullptr); break; case Solid::PowerManagement::HibernateState: Solid::PowerManagement::requestSleep(Solid::PowerManagement::HibernateState, nullptr, nullptr); break; } } } #include "PowerDevilRunner.moc" diff --git a/sddm-theme/Main.qml b/sddm-theme/Main.qml index 28421c4a2..e1fef19fa 100644 --- a/sddm-theme/Main.qml +++ b/sddm-theme/Main.qml @@ -1,443 +1,443 @@ /* * Copyright 2016 David Edmundson * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library 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 Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import QtQuick 2.2 import QtQuick.Layouts 1.1 import QtQuick.Controls 1.1 import QtGraphicalEffects 1.0 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 2.0 as PlasmaComponents import org.kde.plasma.extras 2.0 as PlasmaExtras import "components" PlasmaCore.ColorScope { id: root colorGroup: PlasmaCore.Theme.ComplementaryColorGroup width: 1600 height: 900 property string notificationMessage LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft LayoutMirroring.childrenInherit: true PlasmaCore.DataSource { id: keystateSource engine: "keystate" connectedSources: "Caps Lock" } Item { id: wallpaper anchors.fill: parent Repeater { model: screenModel Background { x: geometry.x; y: geometry.y; width: geometry.width; height: geometry.height sceneBackgroundType: config.type sceneBackgroundColor: config.color sceneBackgroundImage: config.background } } } MouseArea { id: loginScreenRoot anchors.fill: parent property bool uiVisible: true property bool blockUI: mainStack.depth > 1 || userListComponent.mainPasswordBox.text.length > 0 || inputPanel.keyboardActive || config.type != "image" hoverEnabled: true drag.filterChildren: true onPressed: uiVisible = true; onPositionChanged: uiVisible = true; onUiVisibleChanged: { if (blockUI) { fadeoutTimer.running = false; } else if (uiVisible) { fadeoutTimer.restart(); } } onBlockUIChanged: { if (blockUI) { fadeoutTimer.running = false; uiVisible = true; } else { fadeoutTimer.restart(); } } Keys.onPressed: { uiVisible = true; event.accepted = false; } //takes one full minute for the ui to disappear Timer { id: fadeoutTimer running: true interval: 60000 onTriggered: { if (!loginScreenRoot.blockUI) { loginScreenRoot.uiVisible = false; } } } WallpaperFader { visible: config.type == "image" anchors.fill: parent state: loginScreenRoot.uiVisible ? "on" : "off" source: wallpaper mainStack: mainStack footer: footer clock: clock } Clock { id: clock visible: y > 0 y: (userListComponent.userList.y + mainStack.y)/2 - height/2 anchors.horizontalCenter: parent.horizontalCenter } StackView { id: mainStack anchors { left: parent.left right: parent.right } height: root.height focus: true //StackView is an implicit focus scope, so we need to give this focus so the item inside will have it Timer { //SDDM has a bug in 0.13 where even though we set the focus on the right item within the window, the window doesn't have focus //it is fixed in 6d5b36b28907b16280ff78995fef764bb0c573db which will be 0.14 //we need to call "window->activate()" *After* it's been shown. We can't control that in QML so we use a shoddy timer //it's been this way for all Plasma 5.x without a huge problem running: true repeat: false interval: 200 onTriggered: mainStack.forceActiveFocus() } initialItem: Login { id: userListComponent userListModel: userModel loginScreenUiVisible: loginScreenRoot.uiVisible userListCurrentIndex: userModel.lastIndex >= 0 ? userModel.lastIndex : 0 lastUserName: userModel.lastUser showUserList: { if ( !userListModel.hasOwnProperty("count") || !userListModel.hasOwnProperty("disableAvatarsThreshold")) return (userList.y + mainStack.y) > 0 if ( userListModel.count == 0 ) return false return userListModel.count <= userListModel.disableAvatarsThreshold && (userList.y + mainStack.y) > 0 } notificationMessage: { var text = "" if (keystateSource.data["Caps Lock"]["Locked"]) { text += i18nd("plasma_lookandfeel_org.kde.lookandfeel","Caps Lock is on") if (root.notificationMessage) { text += " • " } } text += root.notificationMessage return text } actionItems: [ ActionButton { iconSource: "system-suspend" - text: i18nd("plasma_lookandfeel_org.kde.lookandfeel","Suspend") + text: i18ndc("plasma_lookandfeel_org.kde.lookandfeel","Suspend to RAM","Sleep") onClicked: sddm.suspend() enabled: sddm.canSuspend visible: !inputPanel.keyboardActive }, ActionButton { iconSource: "system-reboot" text: i18nd("plasma_lookandfeel_org.kde.lookandfeel","Restart") onClicked: sddm.reboot() enabled: sddm.canReboot visible: !inputPanel.keyboardActive }, ActionButton { iconSource: "system-shutdown" text: i18nd("plasma_lookandfeel_org.kde.lookandfeel","Shut Down") onClicked: sddm.powerOff() enabled: sddm.canPowerOff visible: !inputPanel.keyboardActive }, ActionButton { iconSource: "system-user-prompt" text: i18ndc("plasma_lookandfeel_org.kde.lookandfeel", "For switching to a username and password prompt", "Other...") onClicked: mainStack.push(userPromptComponent) enabled: true visible: !userListComponent.showUsernamePrompt && !inputPanel.keyboardActive }] onLoginRequest: { root.notificationMessage = "" sddm.login(username, password, sessionButton.currentIndex) } } Behavior on opacity { OpacityAnimator { duration: units.longDuration } } } Loader { id: inputPanel state: "hidden" property bool keyboardActive: item ? item.active : false onKeyboardActiveChanged: { if (keyboardActive) { state = "visible" } else { state = "hidden"; } } source: "components/VirtualKeyboard.qml" anchors { left: parent.left right: parent.right } function showHide() { state = state == "hidden" ? "visible" : "hidden"; } states: [ State { name: "visible" PropertyChanges { target: mainStack y: Math.min(0, root.height - inputPanel.height - userListComponent.visibleBoundary) } PropertyChanges { target: inputPanel y: root.height - inputPanel.height opacity: 1 } }, State { name: "hidden" PropertyChanges { target: mainStack y: 0 } PropertyChanges { target: inputPanel y: root.height - root.height/4 opacity: 0 } } ] transitions: [ Transition { from: "hidden" to: "visible" SequentialAnimation { ScriptAction { script: { inputPanel.item.activated = true; Qt.inputMethod.show(); } } ParallelAnimation { NumberAnimation { target: mainStack property: "y" duration: units.longDuration easing.type: Easing.InOutQuad } NumberAnimation { target: inputPanel property: "y" duration: units.longDuration easing.type: Easing.OutQuad } OpacityAnimator { target: inputPanel duration: units.longDuration easing.type: Easing.OutQuad } } } }, Transition { from: "visible" to: "hidden" SequentialAnimation { ParallelAnimation { NumberAnimation { target: mainStack property: "y" duration: units.longDuration easing.type: Easing.InOutQuad } NumberAnimation { target: inputPanel property: "y" duration: units.longDuration easing.type: Easing.InQuad } OpacityAnimator { target: inputPanel duration: units.longDuration easing.type: Easing.InQuad } } ScriptAction { script: { Qt.inputMethod.hide(); } } } } ] } Component { id: userPromptComponent Login { showUsernamePrompt: true notificationMessage: root.notificationMessage loginScreenUiVisible: loginScreenRoot.uiVisible userListModel: QtObject { property string name: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Type in Username and Password") property string iconSource: "" } onLoginRequest: { root.notificationMessage = "" sddm.login(username, password, sessionButton.currentIndex) } actionItems: [ ActionButton { iconSource: "system-suspend" text: i18nd("plasma_lookandfeel_org.kde.lookandfeel","Suspend") onClicked: sddm.suspend() enabled: sddm.canSuspend visible: !inputPanel.keyboardActive }, ActionButton { iconSource: "system-reboot" text: i18nd("plasma_lookandfeel_org.kde.lookandfeel","Restart") onClicked: sddm.reboot() enabled: sddm.canReboot visible: !inputPanel.keyboardActive }, ActionButton { iconSource: "system-shutdown" text: i18nd("plasma_lookandfeel_org.kde.lookandfeel","Shut Down") onClicked: sddm.powerOff() enabled: sddm.canPowerOff visible: !inputPanel.keyboardActive }, ActionButton { iconSource: "system-user-list" text: i18nd("plasma_lookandfeel_org.kde.lookandfeel","List Users") onClicked: mainStack.pop() visible: !inputPanel.keyboardActive } ] } } //Footer RowLayout { id: footer anchors { bottom: parent.bottom left: parent.left right: parent.right margins: units.smallSpacing } Behavior on opacity { OpacityAnimator { duration: units.longDuration } } PlasmaComponents.ToolButton { text: i18ndc("plasma_lookandfeel_org.kde.lookandfeel", "Button to show/hide virtual keyboard", "Virtual Keyboard") iconName: inputPanel.keyboardActive ? "input-keyboard-virtual-on" : "input-keyboard-virtual-off" onClicked: inputPanel.showHide() visible: inputPanel.status == Loader.Ready } KeyboardButton { } SessionButton { id: sessionButton } Item { Layout.fillWidth: true } Battery { } } } Connections { target: sddm onLoginFailed: { notificationMessage = i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Login Failed") } onLoginSucceeded: { //note SDDM will kill the greeter at some random point after this //there is no certainty any transition will finish, it depends on the time it //takes to complete the init mainStack.opacity = 0 footer.opacity = 0 } } onNotificationMessageChanged: { if (notificationMessage) { notificationResetTimer.start(); } } Timer { id: notificationResetTimer interval: 3000 onTriggered: notificationMessage = "" } }