diff --git a/CMakeLists.txt b/CMakeLists.txt index d31a9abf67..132c42332c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -556,6 +556,7 @@ qt5_add_dbus_adaptor( kwin_KDEINIT_SRCS org.kde.kwin.OrientationSensor.xml orien qt5_add_dbus_adaptor( kwin_KDEINIT_SRCS org.kde.KWin.VirtualDesktopManager.xml dbusinterface.h KWin::VirtualDesktopManagerDBusInterface ) qt5_add_dbus_interface( kwin_KDEINIT_SRCS ${KSCREENLOCKER_DBUS_INTERFACES_DIR}/kf5_org.freedesktop.ScreenSaver.xml screenlocker_interface ) +qt5_add_dbus_interface( kwin_KDEINIT_SRCS ${KSCREENLOCKER_DBUS_INTERFACES_DIR}/org.kde.screensaver.xml kscreenlocker_interface ) qt5_add_dbus_interface( kwin_KDEINIT_SRCS org.kde.kappmenu.xml appmenu_interface ) diff --git a/effects.cpp b/effects.cpp index b4b7b82020..d269510074 100644 --- a/effects.cpp +++ b/effects.cpp @@ -212,6 +212,7 @@ EffectsHandlerImpl::EffectsHandlerImpl(Compositor *compositor, Scene *scene) #endif connect(ScreenEdges::self(), &ScreenEdges::approaching, this, &EffectsHandler::screenEdgeApproaching); connect(ScreenLockerWatcher::self(), &ScreenLockerWatcher::locked, this, &EffectsHandler::screenLockingChanged); + connect(ScreenLockerWatcher::self(), &ScreenLockerWatcher::aboutToLock, this, &EffectsHandler::screenAboutToLock); connect(kwinApp(), &Application::x11ConnectionChanged, this, [this] { diff --git a/effects/cube/cube.cpp b/effects/cube/cube.cpp index 1208f2e39d..986c373046 100644 --- a/effects/cube/cube.cpp +++ b/effects/cube/cube.cpp @@ -101,6 +101,16 @@ CubeEffect::CubeEffect() connect(effects, &EffectsHandler::tabBoxAdded, this, &CubeEffect::slotTabBoxAdded); connect(effects, &EffectsHandler::tabBoxClosed, this, &CubeEffect::slotTabBoxClosed); connect(effects, &EffectsHandler::tabBoxUpdated, this, &CubeEffect::slotTabBoxUpdated); + connect(effects, &EffectsHandler::screenAboutToLock, this, [this]() { + // Set active(false) does not release key grabs until the animation completes + // As we know the lockscreen is trying to grab them, release them early + // all other grabs are released in the normal way + setActive(false); + if (keyboard_grab) { + effects->ungrabKeyboard(); + keyboard_grab = false; + } + }); reconfigure(ReconfigureAll); } diff --git a/effects/desktopgrid/desktopgrid.cpp b/effects/desktopgrid/desktopgrid.cpp index 1946174a13..2430544fcd 100644 --- a/effects/desktopgrid/desktopgrid.cpp +++ b/effects/desktopgrid/desktopgrid.cpp @@ -88,6 +88,14 @@ DesktopGridEffect::DesktopGridEffect() connect(effects, &EffectsHandler::windowGeometryShapeChanged, this, &DesktopGridEffect::slotWindowGeometryShapeChanged); connect(effects, &EffectsHandler::numberScreensChanged, this, &DesktopGridEffect::setup); + connect(effects, &EffectsHandler::screenAboutToLock, this, [this]() { + setActive(false); + if (keyboardGrab) { + effects->ungrabKeyboard(); + keyboardGrab = false; + } + }); + // Load all other configuration details reconfigure(ReconfigureAll); } diff --git a/effects/flipswitch/flipswitch.cpp b/effects/flipswitch/flipswitch.cpp index 890b6d881e..b66f047975 100644 --- a/effects/flipswitch/flipswitch.cpp +++ b/effects/flipswitch/flipswitch.cpp @@ -75,6 +75,10 @@ FlipSwitchEffect::FlipSwitchEffect() connect(effects, &EffectsHandler::tabBoxClosed, this, &FlipSwitchEffect::slotTabBoxClosed); connect(effects, &EffectsHandler::tabBoxUpdated, this, &FlipSwitchEffect::slotTabBoxUpdated); connect(effects, &EffectsHandler::tabBoxKeyEvent, this, &FlipSwitchEffect::slotTabBoxKeyEvent); + connect(effects, &EffectsHandler::screenAboutToLock, this, [this]() { + setActive(false, AllDesktopsMode); + setActive(false, CurrentDesktopMode); + }); } FlipSwitchEffect::~FlipSwitchEffect() diff --git a/effects/presentwindows/presentwindows.cpp b/effects/presentwindows/presentwindows.cpp index cf92a5be69..b37c771e43 100644 --- a/effects/presentwindows/presentwindows.cpp +++ b/effects/presentwindows/presentwindows.cpp @@ -111,6 +111,9 @@ PresentWindowsEffect::PresentWindowsEffect() reCreateGrids(); } ); + connect(effects, &EffectsHandler::screenAboutToLock, this, [this]() { + setActive(false); + }); } PresentWindowsEffect::~PresentWindowsEffect() diff --git a/libkwineffects/kwineffects.h b/libkwineffects/kwineffects.h index b8feed6558..7b2f3d73b8 100644 --- a/libkwineffects/kwineffects.h +++ b/libkwineffects/kwineffects.h @@ -1661,6 +1661,13 @@ Q_SIGNALS: **/ void screenLockingChanged(bool locked); + /** + * This signal is emitted just before the screen locker tries to grab keys and lock the screen + * Effects should release any grabs immediately + * @since 5.17 + **/ + void screenAboutToLock(); + /** * This signels is emitted when ever the stacking order is change, ie. a window is risen * or lowered diff --git a/screenlockerwatcher.cpp b/screenlockerwatcher.cpp index 91c0fde841..0fc1f29481 100644 --- a/screenlockerwatcher.cpp +++ b/screenlockerwatcher.cpp @@ -24,6 +24,7 @@ along with this program. If not, see . #include // dbus generated #include "screenlocker_interface.h" +#include "kscreenlocker_interface.h" namespace KWin { @@ -34,7 +35,6 @@ static const QString SCREEN_LOCKER_SERVICE_NAME = QStringLiteral("org.freedeskto ScreenLockerWatcher::ScreenLockerWatcher(QObject *parent) : QObject(parent) - , m_interface(NULL) , m_serviceWatcher(new QDBusServiceWatcher(this)) , m_locked(false) { @@ -70,13 +70,18 @@ void ScreenLockerWatcher::serviceOwnerChanged(const QString &serviceName, const return; } delete m_interface; - m_interface = NULL; + m_interface = nullptr; + delete m_kdeInterface; + m_kdeInterface = nullptr; + m_locked = false; if (!newOwner.isEmpty()) { m_interface = new OrgFreedesktopScreenSaverInterface(newOwner, QStringLiteral("/ScreenSaver"), QDBusConnection::sessionBus(), this); + m_kdeInterface = new OrgKdeScreensaverInterface(newOwner, QStringLiteral("/ScreenSaver"), QDBusConnection::sessionBus(), this); connect(m_interface, SIGNAL(ActiveChanged(bool)), SLOT(setLocked(bool))); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(m_interface->GetActive(), this); connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), SLOT(activeQueried(QDBusPendingCallWatcher*))); + connect(m_kdeInterface, &OrgKdeScreensaverInterface::AboutToLock, this, &ScreenLockerWatcher::aboutToLock); } } diff --git a/screenlockerwatcher.h b/screenlockerwatcher.h index 99bc503447..02aa68ba2e 100644 --- a/screenlockerwatcher.h +++ b/screenlockerwatcher.h @@ -25,6 +25,7 @@ along with this program. If not, see . #include class OrgFreedesktopScreenSaverInterface; +class OrgKdeScreensaverInterface; class QDBusServiceWatcher; class QDBusPendingCallWatcher; @@ -41,6 +42,7 @@ public: } Q_SIGNALS: void locked(bool locked); + void aboutToLock(); private Q_SLOTS: void setLocked(bool activated); void activeQueried(QDBusPendingCallWatcher *watcher); @@ -49,7 +51,8 @@ private Q_SLOTS: void serviceOwnerQueried(); private: void initialize(); - OrgFreedesktopScreenSaverInterface *m_interface; + OrgFreedesktopScreenSaverInterface *m_interface = nullptr; + OrgKdeScreensaverInterface *m_kdeInterface = nullptr; QDBusServiceWatcher *m_serviceWatcher; bool m_locked;