Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion src/plugin-qt/power/session/powermanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,30 @@ void PowerManager::SetPrepareSuspend(int state)

void PowerManager::TurnOffScreen()
{
doTurnOffScreen();
if (!m_screenCtrl || !m_screenCtrl->isValid()) {
qWarning(logPowerSession) << "Ignoring screen-off request: screen controller unavailable";
return;
}
// The power button toggles the screen: while the screen is off a press
// wakes it instead of blanking it again.
if (m_screenCtrl->isAllOff()) {
qInfo(logPowerSession) << "Screen is off, turning it back on";
TurnOnScreen();
return;
}

if (m_useWayland) {
doTurnOffScreen();
return;
}

if (m_screenBlackLock)
doLock(true);
SetPrepareSuspend(PS_ButtonClick);

setDPMSModeOff();

SetPrepareSuspend(PS_Finish);
}

void PowerManager::TurnOnScreen()
Expand Down
103 changes: 8 additions & 95 deletions src/plugin-qt/shortcut/tools/dde-shortcut-tool/powercontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,6 @@
DCORE_USE_NAMESPACE
DGUI_USE_NAMESPACE

// Power1 SetPrepareSuspend states (match dde-daemon keybinding1/utils.go).
static constexpr int kSuspendStateFinish = 3;
static constexpr int kSuspendStateButtonClick = 7;

// Delay between switching on the KWin BlackScreen mask and triggering DPMS off.
// bug-209669: on some vendor machines DPMS-off blocks the lock screen Show
// until DPMS is back on, causing a wake-flash-then-lock visual glitch. The
// mask hides the gap; 100ms is enough for the compositor to draw it.
static constexpr int kBlackScreenMaskDelayMs = 100;

namespace {

bool isWaylandSession()
Expand Down Expand Up @@ -160,13 +150,6 @@ int PowerController::getPowerButtonAction(DConfig *config, bool onBattery)
return config->value(key, PowerActionShowUI).toInt();
}

bool PowerController::shouldLockOnScreenBlack(DConfig *config)
{
if (!config)
return true;
return config->value(Config::KEY_SCREEN_BLACK_LOCK, true).toBool();
}

bool PowerController::shouldLockOnSleep(DConfig *config)
{
if (!config)
Expand Down Expand Up @@ -260,45 +243,6 @@ bool PowerController::hasMultipleDisplaySession()
return userSessions >= 2;
}

void PowerController::doPrepareSuspend()
{
QDBusInterface power("org.deepin.dde.Power1", "/org/deepin/dde/Power1", "org.deepin.dde.Power1",
QDBusConnection::sessionBus());
if (!power.isValid())
return;
power.call("SetPrepareSuspend", kSuspendStateButtonClick);
}

void PowerController::undoPrepareSuspend()
{
QDBusInterface power("org.deepin.dde.Power1", "/org/deepin/dde/Power1", "org.deepin.dde.Power1",
QDBusConnection::sessionBus());
if (!power.isValid())
return;
power.call("SetPrepareSuspend", kSuspendStateFinish);
}

bool PowerController::isWmBlackScreenActive()
{
QDBusInterface kwin("org.kde.KWin", "/BlackScreen", "org.kde.kwin.BlackScreen",
QDBusConnection::sessionBus());
if (!kwin.isValid())
return false;
QDBusReply<bool> reply = kwin.call("getActive");
return reply.isValid() && reply.value();
}

void PowerController::setWmBlackScreenActive(bool active)
{
QDBusInterface kwin("org.kde.KWin", "/BlackScreen", "org.kde.kwin.BlackScreen",
QDBusConnection::sessionBus());
if (!kwin.isValid()) {
qWarning() << "PowerController: KWin BlackScreen not available";
return;
}
kwin.call("setActive", active);
}

void PowerController::doLock(bool autoStartAuth)
{
qInfo() << "PowerController: lock screen (autoStartAuth=" << autoStartAuth << ")";
Expand Down Expand Up @@ -427,47 +371,16 @@ void PowerController::systemHibernate()

void PowerController::systemTurnOffScreen()
{
qInfo() << "PowerController: turn off screen";

if (isWaylandSession()) {
QDBusInterface power("org.deepin.dde.Power1", "/org/deepin/dde/Power1",
"org.deepin.dde.Power1", QDBusConnection::sessionBus());
if (power.isValid()) {
power.call("TurnOffScreen");
} else {
qWarning() << "PowerController: Power1 unavailable for TurnOffScreen";
}
qInfo() << "PowerController: turn off screen via Power1";
QDBusInterface power("org.deepin.dde.Power1", "/org/deepin/dde/Power1",
"org.deepin.dde.Power1", QDBusConnection::sessionBus());
if (!power.isValid()) {
qWarning() << "PowerController: Power1 unavailable for TurnOffScreen";
return;
}

DConfig *config = createPowerConfig(this);
const bool screenBlackLock = shouldLockOnScreenBlack(config);

// Order matters (bug-209669):
// 1) lock the screen BEFORE DPMS off, otherwise the lock UI's Show
// call blocks until DPMS comes back on, causing a wake-flash
// 2) tell power daemon we're putting the screen down so it stops
// racing us
// 3) cover the gap between "DPMS still on" and "lock UI drawn" with
// the KWin BlackScreen mask
if (screenBlackLock)
doLock(true);

doPrepareSuspend();

const bool needMask = screenBlackLock && !isWmBlackScreenActive();
if (needMask) {
setWmBlackScreenActive(true);
QThread::msleep(kBlackScreenMaskDelayMs);
}

QProcess::execute("xset", {"dpms", "force", "off"});

if (needMask)
setWmBlackScreenActive(false);

undoPrepareSuspend();

const QDBusReply<void> reply = power.call("TurnOffScreen");
if (!reply.isValid())
qWarning() << "PowerController: TurnOffScreen failed:" << reply.error().message();
}

void PowerController::showShutdownUI()
Expand Down
14 changes: 1 addition & 13 deletions src/plugin-qt/shortcut/tools/dde-shortcut-tool/powercontroller.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@ class DConfig;
*
* Invoked as `/usr/bin/dde-shortcut-tool power <action>` from the keybinding
* shortcut for the physical power key (keycode 116) and other power-related
* shortcuts. Ports the dde-daemon keybinding1 power-button logic, including
* the bug-209669 turn-off-screen sequence and the X11 anti-flicker path
* through ShutdownFront1.
* shortcuts. Power transitions are delegated to the owning session services.
*/
class PowerController : public BaseController
{
Expand All @@ -48,7 +46,6 @@ class PowerController : public BaseController
private:
bool isOnBattery();
int getPowerButtonAction(Dtk::Core::DConfig *config, bool onBattery);
bool shouldLockOnScreenBlack(Dtk::Core::DConfig *config);
bool shouldLockOnSleep(Dtk::Core::DConfig *config);

bool callSessionBool(const char *method);
Expand All @@ -59,15 +56,6 @@ class PowerController : public BaseController
bool hasShutdownInhibit();
bool hasMultipleDisplaySession();

// Power1 (session bus) PrepareSuspend notification, keeps the power
// daemon from racing the screen-off transition.
void doPrepareSuspend();
void undoPrepareSuspend();

// KWin BlackScreen effect (Treeland/X11 visual mask, separate from DPMS).
bool isWmBlackScreenActive();
void setWmBlackScreenActive(bool active);

void systemShutdown();
void systemSuspend();
void systemHibernate();
Expand Down
Loading