diff --git a/CMakeLists.txt b/CMakeLists.txt index 9906279686..60d3c66cf7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -400,7 +400,7 @@ endif() kconfig_add_kcfg_files(kwin_KDEINIT_SRCS settings.kcfgc) qt5_add_dbus_adaptor( kwin_KDEINIT_SRCS org.kde.KWin.xml dbusinterface.h KWin::DBusInterface ) -qt5_add_dbus_adaptor( kwin_KDEINIT_SRCS org.kde.kwin.Compositing.xml composite.h KWin::Compositor ) +qt5_add_dbus_adaptor( kwin_KDEINIT_SRCS org.kde.kwin.Compositing.xml dbusinterface.h KWin::CompositorDBusInterface ) qt5_add_dbus_adaptor( kwin_KDEINIT_SRCS ${kwin_effects_dbus_xml} effects.h KWin::EffectsHandlerImpl ) qt5_add_dbus_interface( kwin_KDEINIT_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.ScreenSaver.xml screenlocker_interface) diff --git a/composite.cpp b/composite.cpp index d0a1947aae..1913d1f10e 100644 --- a/composite.cpp +++ b/composite.cpp @@ -18,8 +18,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . *********************************************************************/ #include "composite.h" -#include "compositingadaptor.h" +#include "dbusinterface.h" #include "utils.h" #include #include "workspace.h" @@ -47,7 +47,6 @@ along with this program. If not, see . #include #include #include -#include #include #include #include @@ -92,11 +91,6 @@ Compositor::Compositor(QObject* workspace) , m_waitingForFrameRendered(false) { qRegisterMetaType("Compositor::SuspendReason"); - new CompositingAdaptor(this); - QDBusConnection dbus = QDBusConnection::sessionBus(); - dbus.registerObject(QStringLiteral("/Compositor"), this); - dbus.connect(QString(), QStringLiteral("/Compositor"), QStringLiteral("org.kde.kwin.Compositing"), - QStringLiteral("reinit"), this, SLOT(slotReinitialize())); connect(&unredirectTimer, SIGNAL(timeout()), SLOT(delayedCheckUnredirect())); connect(&compositeResetTimer, SIGNAL(timeout()), SLOT(restart())); connect(workspace, SIGNAL(configChanged()), SLOT(slotConfigChanged())); @@ -127,6 +121,9 @@ Compositor::Compositor(QObject* workspace) // Workspace is completely constructed, so calling Workspace::self() would result // in undefined behavior. This is fixed by using a delayed invocation. QMetaObject::invokeMethod(this, "setup", Qt::QueuedConnection); + + // register DBus + new CompositorDBusInterface(this); } Compositor::~Compositor() @@ -455,22 +452,6 @@ void Compositor::slotToggleCompositing() } } -// for the dbus call -void Compositor::toggleCompositing() -{ - slotToggleCompositing(); // TODO only operate on script level here? - if (m_suspended) { - // when disabled show a shortcut how the user can get back compositing - const auto shortcuts = KGlobalAccel::self()->shortcut(workspace()->findChild(QStringLiteral("Suspend Compositing"))); - if (!shortcuts.isEmpty()) { - // display notification only if there is the shortcut - const QString message = i18n("Desktop effects have been suspended by another application.
" - "You can resume using the '%1' shortcut.", shortcuts.first().toString(QKeySequence::NativeText)); - KNotification::event(QStringLiteral("compositingsuspendeddbus"), message); - } - } -} - void Compositor::updateCompositeBlocking() { updateCompositeBlocking(NULL); @@ -508,6 +489,16 @@ void Compositor::suspend(Compositor::SuspendReason reason) } Q_ASSERT(reason != NoReasonSuspend); m_suspended |= reason; + if (reason & KWin::Compositor::ScriptSuspend) { + // when disabled show a shortcut how the user can get back compositing + const auto shortcuts = KGlobalAccel::self()->shortcut(workspace()->findChild(QStringLiteral("Suspend Compositing"))); + if (!shortcuts.isEmpty()) { + // display notification only if there is the shortcut + const QString message = i18n("Desktop effects have been suspended by another application.
" + "You can resume using the '%1' shortcut.", shortcuts.first().toString(QKeySequence::NativeText)); + KNotification::event(QStringLiteral("compositingsuspendeddbus"), message); + } + } finish(); } @@ -518,18 +509,6 @@ void Compositor::resume(Compositor::SuspendReason reason) setup(); // signal "toggled" is eventually emitted from within setup } -void Compositor::setCompositing(bool active) -{ - if (kwinApp()->requiresCompositing()) { - return; - } - if (active) { - resume(ScriptSuspend); - } else { - suspend(ScriptSuspend); - } -} - void Compositor::restart() { if (hasScene()) { @@ -835,59 +814,6 @@ void Compositor::setOverlayWindowVisibility(bool visible) } } -bool Compositor::isCompositingPossible() const -{ - return CompositingPrefs::compositingPossible(); -} - -QString Compositor::compositingNotPossibleReason() const -{ - return CompositingPrefs::compositingNotPossibleReason(); -} - -bool Compositor::isOpenGLBroken() const -{ - return CompositingPrefs::openGlIsBroken(); -} - -QString Compositor::compositingType() const -{ - if (!hasScene()) { - return QStringLiteral("none"); - } - switch (m_scene->compositingType()) { - case XRenderCompositing: - return QStringLiteral("xrender"); - case OpenGL2Compositing: -#ifdef KWIN_HAVE_OPENGLES - return QStringLiteral("gles"); -#else - return QStringLiteral("gl2"); -#endif - case QPainterCompositing: - return "qpainter"; - case NoCompositing: - default: - return QStringLiteral("none"); - } -} - -QStringList Compositor::supportedOpenGLPlatformInterfaces() const -{ - QStringList interfaces; - bool supportsGlx = (kwinApp()->operationMode() == Application::OperationModeX11); -#ifdef KWIN_HAVE_OPENGLES - supportsGlx = false; -#endif - if (supportsGlx) { - interfaces << QStringLiteral("glx"); - } -#ifdef KWIN_HAVE_EGL - interfaces << QStringLiteral("egl"); -#endif - return interfaces; -} - /***************************************************** * Workspace ****************************************************/ diff --git a/composite.h b/composite.h index a53cdd3629..b4aa8d2e54 100644 --- a/composite.h +++ b/composite.h @@ -51,44 +51,6 @@ private Q_SLOTS: class Compositor : public QObject { Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "org.kde.kwin.Compositing") - /** - * @brief Whether the Compositor is active. That is a Scene is present and the Compositor is - * not shutting down itself. - **/ - Q_PROPERTY(bool active READ isActive) - /** - * @brief Whether compositing is possible. Mostly means whether the required X extensions - * are available. - **/ - Q_PROPERTY(bool compositingPossible READ isCompositingPossible) - /** - * @brief The reason why compositing is not possible. Empty String if compositing is possible. - **/ - Q_PROPERTY(QString compositingNotPossibleReason READ compositingNotPossibleReason) - /** - * @brief Whether OpenGL has failed badly in the past (crash) and is considered as broken. - **/ - Q_PROPERTY(bool openGLIsBroken READ isOpenGLBroken) - /** - * The type of the currently used Scene: - * @li @c none No Compositing - * @li @c xrender XRender - * @li @c gl1 OpenGL 1 - * @li @c gl2 OpenGL 2 - * @li @c gles OpenGL ES 2 - **/ - Q_PROPERTY(QString compositingType READ compositingType) - /** - * @brief All currently supported OpenGLPlatformInterfaces. - * - * Possible values: - * @li glx - * @li egl - * - * Values depend on operation mode and compile time options. - **/ - Q_PROPERTY(QStringList supportedOpenGLPlatformInterfaces READ supportedOpenGLPlatformInterfaces) public: enum SuspendReason { NoReasonSuspend = 0, UserSuspend = 1<<0, BlockRuleSuspend = 1<<1, ScriptSuspend = 1<<2, AllReasonSuspend = 0xff }; Q_DECLARE_FLAGS(SuspendReasons, SuspendReason) @@ -163,23 +125,8 @@ public: void keepSupportProperty(xcb_atom_t atom); void removeSupportProperty(xcb_atom_t atom); - // D-Bus: getters for Properties, see documentation on the property - bool isCompositingPossible() const; - QString compositingNotPossibleReason() const; - bool isOpenGLBroken() const; - QString compositingType() const; - QStringList supportedOpenGLPlatformInterfaces() const; - public Q_SLOTS: void addRepaintFull(); - /** - * Called from the D-Bus interface. Does the same as slotToggleCompositing with the - * addition to show a notification on how to revert the compositing state. - * @see resume - * @see suspend - * @deprecated Use suspend or resume instead - **/ - Q_SCRIPTABLE void toggleCompositing(); /** * @brief Suspends the Compositor if it is currently active. * @@ -190,7 +137,6 @@ public Q_SLOTS: * @see resume * @see isActive **/ - Q_SCRIPTABLE inline void suspend() { suspend(ScriptSuspend); } void suspend(Compositor::SuspendReason reason); /** * @brief Resumes the Compositor if it is currently suspended. @@ -209,36 +155,7 @@ public Q_SLOTS: * @see isCompositingPossible * @see isOpenGLBroken **/ - Q_SCRIPTABLE inline void resume() { resume(ScriptSuspend); } void resume(Compositor::SuspendReason reason); - /** - * @brief Tries to suspend or resume the Compositor based on @p active. - * - * In case the Compositor is already in the asked for state this method is doing nothing. In - * case it does not match it is tried to either resume or suspend the Compositor. - * - * Note: these operations may fail. There is no guarantee that after calling this method to - * enable/disable the Compositor, it actually changes to the state. Use @link isActive to check - * the actual state of the Compositor. - * - * Note: The starting of the Compositor can require some time and is partially done threaded. - * After this method returns the setup may not have been completed. - * - * Note: This function only impacts whether compositing is suspended or resumed by scripts - * or dbus calls. Compositing may be suspended for user will or a window rule - no matter how - * often you call this function! - * - * @param active Whether the Compositor should be resumed (@c true) or suspended (@c false) - * @return void - * @see suspend - * @see resume - * @see isActive - * @see isCompositingPossible - * @see isOpenGLBroken - **/ - // NOTICE this is atm. for script usage *ONLY* and needs to be extended like resume / suspend are - // if intended to be used from within KWin code! - Q_SCRIPTABLE void setCompositing(bool active); /** * Actual slot to perform the toggling compositing. * That is if the Compositor is suspended it will be resumed and if the Compositor is active @@ -261,10 +178,8 @@ public Q_SLOTS: void updateCompositeBlocking(); void updateCompositeBlocking(KWin::Client* c); - // For the D-Bus interface - Q_SIGNALS: - Q_SCRIPTABLE void compositingToggled(bool active); + void compositingToggled(bool active); protected: void timerEvent(QTimerEvent *te); diff --git a/dbusinterface.cpp b/dbusinterface.cpp index 59c353e5aa..345b45b6aa 100644 --- a/dbusinterface.cpp +++ b/dbusinterface.cpp @@ -20,10 +20,15 @@ along with this program. If not, see . // own #include "dbusinterface.h" +#include "compositingadaptor.h" // kwin +#include "composite.h" +#include "compositingprefs.h" +#include "main.h" #include "placement.h" #include "kwinadaptor.h" +#include "scene.h" #include "workspace.h" #include "virtualdesktops.h" #ifdef KWIN_BUILD_ACTIVITIES @@ -143,4 +148,85 @@ void DBusInterface::previousDesktop() VirtualDesktopManager::self()->moveTo(); } + +CompositorDBusInterface::CompositorDBusInterface(Compositor *parent) + : QObject(parent) + , m_compositor(parent) +{ + connect(m_compositor, &Compositor::compositingToggled, this, &CompositorDBusInterface::compositingToggled); + new CompositingAdaptor(this); + QDBusConnection dbus = QDBusConnection::sessionBus(); + dbus.registerObject(QStringLiteral("/Compositor"), this); + dbus.connect(QString(), QStringLiteral("/Compositor"), QStringLiteral("org.kde.kwin.Compositing"), + QStringLiteral("reinit"), m_compositor, SLOT(slotReinitialize())); +} + +QString CompositorDBusInterface::compositingNotPossibleReason() const +{ + return CompositingPrefs::compositingNotPossibleReason(); +} + +QString CompositorDBusInterface::compositingType() const +{ + if (!m_compositor->hasScene()) { + return QStringLiteral("none"); + } + switch (m_compositor->scene()->compositingType()) { + case XRenderCompositing: + return QStringLiteral("xrender"); + case OpenGL2Compositing: +#ifdef KWIN_HAVE_OPENGLES + return QStringLiteral("gles"); +#else + return QStringLiteral("gl2"); +#endif + case QPainterCompositing: + return "qpainter"; + case NoCompositing: + default: + return QStringLiteral("none"); + } +} + +bool CompositorDBusInterface::isActive() const +{ + return m_compositor->isActive(); +} + +bool CompositorDBusInterface::isCompositingPossible() const +{ + return CompositingPrefs::compositingPossible(); +} + +bool CompositorDBusInterface::isOpenGLBroken() const +{ + return CompositingPrefs::openGlIsBroken(); +} + +void CompositorDBusInterface::resume() +{ + m_compositor->resume(Compositor::ScriptSuspend); +} + +void CompositorDBusInterface::suspend() +{ + m_compositor->suspend(Compositor::ScriptSuspend); +} + +QStringList CompositorDBusInterface::supportedOpenGLPlatformInterfaces() const +{ + QStringList interfaces; + bool supportsGlx = (kwinApp()->operationMode() == Application::OperationModeX11); +#ifdef KWIN_HAVE_OPENGLES + supportsGlx = false; +#endif + if (supportsGlx) { + interfaces << QStringLiteral("glx"); + } +#ifdef KWIN_HAVE_EGL + interfaces << QStringLiteral("egl"); +#endif + return interfaces; +} + } // namespace diff --git a/dbusinterface.h b/dbusinterface.h index 32e8273575..1c0a875127 100644 --- a/dbusinterface.h +++ b/dbusinterface.h @@ -27,6 +27,8 @@ along with this program. If not, see . namespace KWin { +class Compositor; + /** * @brief This class is a wrapper for the org.kde.KWin D-Bus interface. * @@ -67,6 +69,96 @@ private Q_SLOTS: void becomeKWinService(const QString &service); }; +class CompositorDBusInterface : public QObject +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.kde.kwin.Compositing") + /** + * @brief Whether the Compositor is active. That is a Scene is present and the Compositor is + * not shutting down itself. + **/ + Q_PROPERTY(bool active READ isActive) + /** + * @brief Whether compositing is possible. Mostly means whether the required X extensions + * are available. + **/ + Q_PROPERTY(bool compositingPossible READ isCompositingPossible) + /** + * @brief The reason why compositing is not possible. Empty String if compositing is possible. + **/ + Q_PROPERTY(QString compositingNotPossibleReason READ compositingNotPossibleReason) + /** + * @brief Whether OpenGL has failed badly in the past (crash) and is considered as broken. + **/ + Q_PROPERTY(bool openGLIsBroken READ isOpenGLBroken) + /** + * The type of the currently used Scene: + * @li @c none No Compositing + * @li @c xrender XRender + * @li @c gl1 OpenGL 1 + * @li @c gl2 OpenGL 2 + * @li @c gles OpenGL ES 2 + **/ + Q_PROPERTY(QString compositingType READ compositingType) + /** + * @brief All currently supported OpenGLPlatformInterfaces. + * + * Possible values: + * @li glx + * @li egl + * + * Values depend on operation mode and compile time options. + **/ + Q_PROPERTY(QStringList supportedOpenGLPlatformInterfaces READ supportedOpenGLPlatformInterfaces) +public: + explicit CompositorDBusInterface(Compositor *parent); + virtual ~CompositorDBusInterface() = default; + + bool isActive() const; + bool isCompositingPossible() const; + QString compositingNotPossibleReason() const; + bool isOpenGLBroken() const; + QString compositingType() const; + QStringList supportedOpenGLPlatformInterfaces() const; + +public Q_SLOTS: + /** + * @brief Suspends the Compositor if it is currently active. + * + * Note: it is possible that the Compositor is not able to suspend. Use @link isActive to check + * whether the Compositor has been suspended. + * + * @return void + * @see resume + * @see isActive + **/ + void suspend(); + /** + * @brief Resumes the Compositor if it is currently suspended. + * + * Note: it is possible that the Compositor cannot be resumed, that is there might be Clients + * blocking the usage of Compositing or the Scene might be broken. Use @link isActive to check + * whether the Compositor has been resumed. Also check @link isCompositingPossible and + * @link isOpenGLBroken. + * + * Note: The starting of the Compositor can require some time and is partially done threaded. + * After this method returns the setup may not have been completed. + * + * @return void + * @see suspend + * @see isActive + * @see isCompositingPossible + * @see isOpenGLBroken + **/ + void resume(); + +Q_SIGNALS: + void compositingToggled(bool active); + +private: + Compositor *m_compositor; +}; + } // namespace #endif // KWIN_DBUS_INTERFACE_H diff --git a/org.kde.kwin.Compositing.xml b/org.kde.kwin.Compositing.xml index 4b657f0513..d98732e121 100644 --- a/org.kde.kwin.Compositing.xml +++ b/org.kde.kwin.Compositing.xml @@ -10,14 +10,9 @@ - - - - -