diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -556,6 +556,7 @@ 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 --- a/effects.cpp +++ b/effects.cpp @@ -212,6 +212,7 @@ #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 --- a/effects/cube/cube.cpp +++ b/effects/cube/cube.cpp @@ -101,6 +101,16 @@ 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 --- a/effects/desktopgrid/desktopgrid.cpp +++ b/effects/desktopgrid/desktopgrid.cpp @@ -88,6 +88,14 @@ 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 --- a/effects/flipswitch/flipswitch.cpp +++ b/effects/flipswitch/flipswitch.cpp @@ -75,6 +75,10 @@ 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 --- a/effects/presentwindows/presentwindows.cpp +++ b/effects/presentwindows/presentwindows.cpp @@ -111,6 +111,9 @@ reCreateGrids(); } ); + connect(effects, &EffectsHandler::screenAboutToLock, this, [this]() { + setActive(false); + }); } PresentWindowsEffect::~PresentWindowsEffect() diff --git a/libkwineffects/kwineffects.h b/libkwineffects/kwineffects.h --- a/libkwineffects/kwineffects.h +++ b/libkwineffects/kwineffects.h @@ -1661,6 +1661,13 @@ **/ 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.h b/screenlockerwatcher.h --- a/screenlockerwatcher.h +++ b/screenlockerwatcher.h @@ -25,6 +25,7 @@ #include class OrgFreedesktopScreenSaverInterface; +class OrgKdeScreensaverInterface; class QDBusServiceWatcher; class QDBusPendingCallWatcher; @@ -41,15 +42,17 @@ } Q_SIGNALS: void locked(bool locked); + void aboutToLock(); private Q_SLOTS: void setLocked(bool activated); void activeQueried(QDBusPendingCallWatcher *watcher); void serviceOwnerChanged(const QString &serviceName, const QString &oldOwner, const QString &newOwner); void serviceRegisteredQueried(); void serviceOwnerQueried(); private: void initialize(); - OrgFreedesktopScreenSaverInterface *m_interface; + OrgFreedesktopScreenSaverInterface *m_interface = nullptr; + OrgKdeScreensaverInterface *m_kdeInterface = nullptr; QDBusServiceWatcher *m_serviceWatcher; bool m_locked; diff --git a/screenlockerwatcher.cpp b/screenlockerwatcher.cpp --- a/screenlockerwatcher.cpp +++ b/screenlockerwatcher.cpp @@ -24,6 +24,7 @@ #include // dbus generated #include "screenlocker_interface.h" +#include "kscreenlocker_interface.h" namespace KWin { @@ -34,7 +35,6 @@ ScreenLockerWatcher::ScreenLockerWatcher(QObject *parent) : QObject(parent) - , m_interface(NULL) , m_serviceWatcher(new QDBusServiceWatcher(this)) , m_locked(false) { @@ -70,13 +70,18 @@ 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); } }