diff --git a/autotests/integration/kwin_wayland_test.cpp b/autotests/integration/kwin_wayland_test.cpp --- a/autotests/integration/kwin_wayland_test.cpp +++ b/autotests/integration/kwin_wayland_test.cpp @@ -126,7 +126,7 @@ { disconnect(kwinApp()->platform(), &Platform::screensQueried, this, &WaylandTestApplication::continueStartupWithScreens); createScreens(); - createCompositor(); + WaylandCompositor::create(); connect(Compositor::self(), &Compositor::sceneCreated, this, &WaylandTestApplication::continueStartupWithScene); } diff --git a/composite.h b/composite.h --- a/composite.h +++ b/composite.h @@ -2,8 +2,9 @@ KWin - the KDE window manager This file is part of the KDE project. -Copyright (C) 2011 Arthur Arlt -Copyright (C) 2012 Martin Gräßlin +Copyright © 2011 Arthur Arlt +Copyright © 2012 Martin Gräßlin +Copyright © 2019 Roman Gilg 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 @@ -18,12 +19,10 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . *********************************************************************/ +#pragma once -#ifndef KWIN_COMPOSITE_H -#define KWIN_COMPOSITE_H -// KWin #include -// Qt + #include #include #include @@ -36,31 +35,29 @@ class CompositorSelectionOwner; class Scene; -class KWIN_EXPORT Compositor : public QObject { +class KWIN_EXPORT Compositor : public QObject +{ Q_OBJECT public: - enum SuspendReason { NoReasonSuspend = 0, UserSuspend = 1<<0, BlockRuleSuspend = 1<<1, ScriptSuspend = 1<<2, AllReasonSuspend = 0xff }; - Q_DECLARE_FLAGS(SuspendReasons, SuspendReason) - ~Compositor(); + virtual ~Compositor(); + // when adding repaints caused by a window, you probably want to use // either Toplevel::addRepaint() or Toplevel::addWorkspaceRepaint() void addRepaint(const QRect& r); void addRepaint(const QRegion& r); void addRepaint(int x, int y, int w, int h); + /** * Whether the Compositor is active. That is a Scene is present and the Compositor is * not shutting down itself. **/ bool isActive(); - int xrrRefreshRate() const { - return m_xrrRefreshRate; - } - void setCompositeResetTimer(int msecs); bool hasScene() const { return m_scene != NULL; } + // TODO: only x11? /** * Checks whether @p w is the Scene's overlay window. **/ @@ -74,16 +71,6 @@ return m_scene; } - /** - * @brief Checks whether the Compositor has already been created by the Workspace. - * - * This method can be used to check whether self will return the Compositor instance or @c null. - * - * @return bool @c true if the Compositor has been created, @c false otherwise - **/ - static bool isCreated() { - return s_compositor != NULL; - } /** * @brief Static check to test whether the Compositor is available and active. * @@ -97,56 +84,28 @@ void keepSupportProperty(xcb_atom_t atom); void removeSupportProperty(xcb_atom_t atom); + static Compositor* self(); + static Compositor *s_compositor; + public Q_SLOTS: void addRepaintFull(); - /** - * @brief Suspends the Compositor if it is currently active. - * - * Note: it is possible that the Compositor is not able to suspend. Use isActive to check - * whether the Compositor has been suspended. - * - * @return void - * @see resume - * @see isActive - **/ - void suspend(Compositor::SuspendReason reason); - /** - * @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 isActive to check - * whether the Compositor has been resumed. Also check isCompositingPossible and - * 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(Compositor::SuspendReason reason); /** * Actual slot to perform the toggling compositing. * That is if the Compositor is suspended it will be resumed and if the Compositor is active * it will be suspended. - * Invoked primarily by the keybinding. + * Invoked primarily by the keybinding (shortcut default: Shift + Alt + F12). * TODO: make private slot **/ - void slotToggleCompositing(); + virtual void slotToggleCompositing() {} /** * Re-initializes the Compositor completely. * Connected to the D-Bus signal org.kde.KWin /KWin reinitCompositing **/ - void slotReinitialize(); + virtual void slotReinitialize(); /** * Schedules a new repaint if no repaint is currently scheduled. **/ void scheduleRepaint(); - void updateCompositeBlocking(); - void updateCompositeBlocking(KWin::Client* c); /** * Notifies the compositor that SwapBuffers() is about to be called. @@ -160,69 +119,151 @@ **/ void bufferSwapComplete(); + virtual void updateCompositeBlocking() {} + + virtual bool setup(); + Q_SIGNALS: void compositingToggled(bool active); void aboutToDestroy(); void aboutToToggleCompositing(); void sceneCreated(); void bufferSwapCompleted(); protected: + explicit Compositor(QObject *parent); void timerEvent(QTimerEvent *te); + /** + * Continues the startup after Scene And Workspace are created + **/ + virtual bool startupWithWorkspace(); -private Q_SLOTS: - void setup(); /** * Called from setupCompositing() when the CompositingPrefs are ready. **/ void slotCompositingOptionsInitialized(); + virtual void slotConfigChanged(); void finish(); + + bool m_finishing; // finish() sets this variable while shutting down + bool m_starting; // start() sets this variable while starting /** * Restarts the Compositor if running. * That is the Compositor will be stopped and started again. **/ void restart(); + +private: void performCompositing(); - void slotConfigChanged(); void releaseCompositorSelection(); void deleteUnusedSupportProperties(); -private: void claimCompositorSelection(); void setCompositeTimer(); bool windowRepaintsPending() const; - /** - * Continues the startup after Scene And Workspace are created - **/ - void startupWithWorkspace(); void setupX11Support(); - /** - * Whether the Compositor is currently suspended, 8 bits encoding the reason - **/ - SuspendReasons m_suspended; - QBasicTimer compositeTimer; CompositorSelectionOwner *m_selectionOwner; QTimer m_releaseSelectionTimer; QList m_unusedSupportProperties; QTimer m_unusedSupportPropertyTimer; qint64 vBlankInterval, fpsInterval; - int m_xrrRefreshRate; QRegion repaints_region; - QTimer compositeResetTimer; // for compressing composite resets - bool m_finishing; // finish() sets this variable while shutting down - bool m_starting; // start() sets this variable while starting qint64 m_timeSinceLastVBlank; Scene *m_scene; bool m_bufferSwapPending; bool m_composeAtSwapCompletion; int m_framesToTestForSafety = 3; QElapsedTimer m_monotonicClock; +}; + +class KWIN_EXPORT WaylandCompositor : public Compositor +{ + Q_OBJECT +public: + explicit WaylandCompositor(QObject *parent = nullptr); + ~WaylandCompositor() override = default; + + + static WaylandCompositor* create(QObject *parent = nullptr); + +private: + bool setup() override; - KWIN_SINGLETON_VARIABLE(Compositor, s_compositor) }; -} -# endif // KWIN_COMPOSITE_H +class KWIN_EXPORT X11Compositor : public Compositor +{ + Q_OBJECT +public: + enum SuspendReason { NoReasonSuspend = 0, + UserSuspend = 1 << 0, + BlockRuleSuspend = 1 << 1, + ScriptSuspend = 1 << 2, + AllReasonSuspend = 0xff + }; + Q_DECLARE_FLAGS(SuspendReasons, SuspendReason) + + explicit X11Compositor(QObject *parent = nullptr); + ~X11Compositor() override = default; + + static X11Compositor* create(QObject *parent = nullptr); + + bool startupWithWorkspace() override; + + /** + * @brief Suspends the Compositor if it is currently active. + * + * Note: it is possible that the Compositor is not able to suspend. Use isActive to check + * whether the Compositor has been suspended. + * + * @return void + * @see resume + * @see isActive + **/ + void suspend(X11Compositor::SuspendReason reason); + /** + * @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 isActive to check + * whether the Compositor has been resumed. Also check isCompositingPossible and + * 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(X11Compositor::SuspendReason reason); + + void slotReinitialize() override; + void slotToggleCompositing() override; + + void updateCompositeBlocking() override; + void updateCompositeBlocking(KWin::Client* c); + + int xrrRefreshRate() const { + return m_xrrRefreshRate; + } + + void setCompositeResetTimer(int msecs); + +private: + bool setup() override; + void slotConfigChanged() override; + /** + * Whether the Compositor is currently suspended, 8 bits encoding the reason + **/ + SuspendReasons m_suspended; + int m_xrrRefreshRate; + QTimer m_compositeResetTimer; // for compressing composite resets +}; + +} diff --git a/composite.cpp b/composite.cpp --- a/composite.cpp +++ b/composite.cpp @@ -2,7 +2,8 @@ KWin - the KDE window manager This file is part of the KDE project. -Copyright (C) 2006 Lubos Lunak +Copyright © 2006 Lubos Lunak +Copyright © 2019 Roman Gilg 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 @@ -62,12 +63,34 @@ #include -Q_DECLARE_METATYPE(KWin::Compositor::SuspendReason) +Q_DECLARE_METATYPE(KWin::X11Compositor::SuspendReason) namespace KWin { -extern int currentRefreshRate(); +static inline qint64 milliToNano(int milli) { return qint64(milli) * 1000 * 1000; } +static inline qint64 nanoToMilli(int nano) { return nano / (1000*1000); } + +Compositor *Compositor::s_compositor = nullptr; +Compositor* Compositor::self() +{ + return s_compositor; +} + +WaylandCompositor* WaylandCompositor::create(QObject *parent) +{ + Q_ASSERT(!s_compositor); + auto *compositor = new WaylandCompositor(parent); + s_compositor = compositor; + return compositor; +} +X11Compositor* X11Compositor::create(QObject *parent) +{ + Q_ASSERT(!s_compositor); + auto *compositor = new X11Compositor(parent); + s_compositor = compositor; + return compositor; +} class CompositorSelectionOwner : public KSelectionOwner { @@ -90,49 +113,44 @@ bool m_owning; }; -KWIN_SINGLETON_FACTORY_VARIABLE(Compositor, s_compositor) - -static inline qint64 milliToNano(int milli) { return qint64(milli) * 1000 * 1000; } -static inline qint64 nanoToMilli(int nano) { return nano / (1000*1000); } - -Compositor::Compositor(QObject* workspace) - : QObject(workspace) - , m_suspended(options->isUseCompositing() ? NoReasonSuspend : UserSuspend) +Compositor::Compositor(QObject* parent) + : QObject(parent) + , m_finishing(false) + , m_starting(false) , m_selectionOwner(NULL) , vBlankInterval(0) , fpsInterval(0) - , m_xrrRefreshRate(0) - , m_finishing(false) - , m_starting(false) , m_timeSinceLastVBlank(0) , m_scene(NULL) , m_bufferSwapPending(false) , m_composeAtSwapCompletion(false) { - qRegisterMetaType("Compositor::SuspendReason"); - connect(&compositeResetTimer, SIGNAL(timeout()), SLOT(restart())); connect(options, &Options::configChanged, this, &Compositor::slotConfigChanged); - compositeResetTimer.setSingleShot(true); m_monotonicClock.start(); // 2 sec which should be enough to restart the compositor static const int compositorLostMessageDelay = 2000; m_releaseSelectionTimer.setSingleShot(true); m_releaseSelectionTimer.setInterval(compositorLostMessageDelay); - connect(&m_releaseSelectionTimer, SIGNAL(timeout()), SLOT(releaseCompositorSelection())); + connect(&m_releaseSelectionTimer, &QTimer::timeout, this, &Compositor::releaseCompositorSelection); m_unusedSupportPropertyTimer.setInterval(compositorLostMessageDelay); m_unusedSupportPropertyTimer.setSingleShot(true); - connect(&m_unusedSupportPropertyTimer, SIGNAL(timeout()), SLOT(deleteUnusedSupportProperties())); + connect(&m_unusedSupportPropertyTimer, &QTimer::timeout, this, &Compositor::deleteUnusedSupportProperties); // delay the call to setup by one event cycle // The ctor of this class is invoked from the Workspace ctor, that means before // Workspace is completely constructed, so calling Workspace::self() would result // in undefined behavior. This is fixed by using a delayed invocation. + // + // TODO: This is a hack anyway but in Wayland case this explanation is also not correct, + // since the Compositor is started from Application directly. Still it does not + // work here either. So the TODO is to clean this up in general. if (kwinApp()->platform()->isReady()) { QMetaObject::invokeMethod(this, "setup", Qt::QueuedConnection); } + connect(kwinApp()->platform(), &Platform::readyChanged, this, [this] (bool ready) { if (ready) { @@ -166,37 +184,16 @@ } -void Compositor::setup() +bool Compositor::setup() { if (kwinApp()->isTerminating()) { // don't setup while KWin is terminating. An event to restart might be lingering in the event queue due to graphics reset - return; - } - if (hasScene()) - return; - if (m_suspended) { - QStringList reasons; - if (m_suspended & UserSuspend) { - reasons << QStringLiteral("Disabled by User"); - } - if (m_suspended & BlockRuleSuspend) { - reasons << QStringLiteral("Disabled by Window"); - } - if (m_suspended & ScriptSuspend) { - reasons << QStringLiteral("Disabled by Script"); - } - qCDebug(KWIN_CORE) << "Compositing is suspended, reason:" << reasons; - return; - } else if (!kwinApp()->platform()->compositingPossible()) { - qCCritical(KWIN_CORE) << "Compositing is not possible"; - return; + return false; } - m_starting = true; - - if (!options->isCompositingInitialized()) { - options->reloadCompositingSettings(true); + if (hasScene()) { + return false; } - slotCompositingOptionsInitialized(); + return true; } extern int screen_number; // main.cpp @@ -319,20 +316,20 @@ xcb_composite_redirect_subwindows(c, kwinApp()->x11RootWindow(), XCB_COMPOSITE_REDIRECT_MANUAL); } -void Compositor::startupWithWorkspace() +bool Compositor::startupWithWorkspace() { if (!m_starting) { - return; + return false; } connect(kwinApp(), &Application::x11ConnectionChanged, this, &Compositor::setupX11Support, Qt::UniqueConnection); Workspace::self()->markXStackingOrderAsDirty(); Q_ASSERT(m_scene); connect(workspace(), &Workspace::destroyed, this, [this] { compositeTimer.stop(); }); setupX11Support(); - m_xrrRefreshRate = KWin::currentRefreshRate(); + fpsInterval = options->maxFpsInterval(); if (m_scene->syncsToVBlank()) { // if we do vsync, set the fps to the next multiple of the vblank rate - vBlankInterval = milliToNano(1000) / m_xrrRefreshRate; + vBlankInterval = milliToNano(1000) / Options::currentRefreshRate(); fpsInterval = qMax((fpsInterval / vBlankInterval) * vBlankInterval, vBlankInterval); } else vBlankInterval = milliToNano(1); // no sync - DO NOT set "0", would cause div-by-zero segfaults. @@ -374,6 +371,7 @@ // render at least once performCompositing(); + return true; } void Compositor::scheduleRepaint() @@ -496,13 +494,10 @@ void Compositor::slotConfigChanged() { - if (!m_suspended) { - setup(); - if (effects) // setupCompositing() may fail - effects->reconfigure(); - addRepaintFull(); - } else - finish(); + setup(); + if (effects) // setupCompositing() may fail + effects->reconfigure(); + addRepaintFull(); } void Compositor::slotReinitialize() @@ -512,87 +507,14 @@ // Restart compositing finish(); - // resume compositing if suspended - m_suspended = NoReasonSuspend; - options->setCompositingInitialized(false); + options->setCompositingInitialized(false); // TODO: why? setup(); if (effects) { // setup() may fail effects->reconfigure(); } } -// for the shortcut -void Compositor::slotToggleCompositing() -{ - if (kwinApp()->platform()->requiresCompositing()) { - // we are not allowed to turn on/off compositing - return; - } - if (m_suspended) { // direct user call; clear all bits - resume(AllReasonSuspend); - } else { // but only set the user one (sufficient to suspend) - suspend(UserSuspend); - } -} - -void Compositor::updateCompositeBlocking() -{ - updateCompositeBlocking(NULL); -} - -void Compositor::updateCompositeBlocking(Client *c) -{ - if (kwinApp()->platform()->requiresCompositing()) { - return; - } - if (c) { // if c == 0 we just check if we can resume - if (c->isBlockingCompositing()) { - if (!(m_suspended & BlockRuleSuspend)) // do NOT attempt to call suspend(true); from within the eventchain! - QMetaObject::invokeMethod(this, "suspend", Qt::QueuedConnection, Q_ARG(Compositor::SuspendReason, BlockRuleSuspend)); - } - } - else if (m_suspended & BlockRuleSuspend) { // lost a client and we're blocked - can we resume? - bool resume = true; - for (ClientList::ConstIterator it = Workspace::self()->clientList().constBegin(); it != Workspace::self()->clientList().constEnd(); ++it) { - if ((*it)->isBlockingCompositing()) { - resume = false; - break; - } - } - if (resume) { // do NOT attempt to call suspend(false); from within the eventchain! - QMetaObject::invokeMethod(this, "resume", Qt::QueuedConnection, Q_ARG(Compositor::SuspendReason, BlockRuleSuspend)); - } - } -} - -void Compositor::suspend(Compositor::SuspendReason reason) -{ - if (kwinApp()->platform()->requiresCompositing()) { - return; - } - 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(); -} - -void Compositor::resume(Compositor::SuspendReason reason) -{ - Q_ASSERT(reason != NoReasonSuspend); - m_suspended &= ~reason; - setup(); // signal "toggled" is eventually emitted from within setup -} - void Compositor::restart() { if (hasScene()) { @@ -827,11 +749,6 @@ return false; } -void Compositor::setCompositeResetTimer(int msecs) -{ - compositeResetTimer.start(msecs); -} - void Compositor::setCompositeTimer() { if (!hasScene()) // should not really happen, but there may be e.g. some damage events still pending @@ -930,7 +847,161 @@ return m_scene->overlayWindow()->isVisible(); } -} // namespace +WaylandCompositor::WaylandCompositor(QObject *parent) + : Compositor(parent) +{ +} + +X11Compositor::X11Compositor(QObject *parent) + : Compositor(parent) + , m_suspended(options->isUseCompositing() ? NoReasonSuspend : UserSuspend) + , m_xrrRefreshRate(0) +{ + qRegisterMetaType("X11Compositor::SuspendReason"); + connect(&m_compositeResetTimer, &QTimer::timeout, this, &X11Compositor::restart); + m_compositeResetTimer.setSingleShot(true); +} + +void X11Compositor::suspend(X11Compositor::SuspendReason reason) +{ + Q_ASSERT(reason != NoReasonSuspend); + m_suspended |= reason; + if (reason & 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(); +} + +void X11Compositor::slotReinitialize() +{ + // resume compositing if suspended + m_suspended = NoReasonSuspend; + X11Compositor::slotReinitialize(); +} + +void X11Compositor::resume(X11Compositor::SuspendReason reason) +{ + Q_ASSERT(reason != NoReasonSuspend); + m_suspended &= ~reason; + setup(); // signal "toggled" is eventually emitted from within setup +} + +void X11Compositor::slotToggleCompositing() +{ + if (m_suspended) { // direct user call; clear all bits + resume(AllReasonSuspend); + } else { // but only set the user one (sufficient to suspend) + suspend(UserSuspend); + } +} + +void X11Compositor::updateCompositeBlocking() +{ + updateCompositeBlocking(NULL); +} + +void X11Compositor::updateCompositeBlocking(Client *c) +{ + if (c) { // if c == 0 we just check if we can resume + if (c->isBlockingCompositing()) { + if (!(m_suspended & BlockRuleSuspend)) // do NOT attempt to call suspend(true); from within the eventchain! + QMetaObject::invokeMethod(this, "suspend", Qt::QueuedConnection, Q_ARG(X11Compositor::SuspendReason, BlockRuleSuspend)); + } + } + else if (m_suspended & BlockRuleSuspend) { // lost a client and we're blocked - can we resume? + bool resume = true; + for (ClientList::ConstIterator it = Workspace::self()->clientList().constBegin(); it != Workspace::self()->clientList().constEnd(); ++it) { + if ((*it)->isBlockingCompositing()) { + resume = false; + break; + } + } + if (resume) { // do NOT attempt to call suspend(false); from within the eventchain! + QMetaObject::invokeMethod(this, "resume", Qt::QueuedConnection, Q_ARG(X11Compositor::SuspendReason, BlockRuleSuspend)); + } + } +} + +bool X11Compositor::startupWithWorkspace() +{ + if (!Compositor::startupWithWorkspace()) { + return false; + } + m_xrrRefreshRate = Options::currentRefreshRate(); + return true; +} + +bool WaylandCompositor::setup() +{ + if (!Compositor::setup()) { + return false; + } + + m_starting = true; + + // TODO: is this at all relevant for Wayland? + if (!options->isCompositingInitialized()) { + options->reloadCompositingSettings(true); + } + slotCompositingOptionsInitialized(); + return true; +} + +bool X11Compositor::setup() +{ + if (!Compositor::setup()) { + return false; + } + + if (m_suspended) { + QStringList reasons; + if (m_suspended & UserSuspend) { + reasons << QStringLiteral("Disabled by User"); + } + if (m_suspended & BlockRuleSuspend) { + reasons << QStringLiteral("Disabled by Window"); + } + if (m_suspended & ScriptSuspend) { + reasons << QStringLiteral("Disabled by Script"); + } + qCDebug(KWIN_CORE) << "Compositing is suspended, reason:" << reasons; + return false; + + } else if (!kwinApp()->platform()->compositingPossible()) { + qCCritical(KWIN_CORE) << "Compositing is not possible"; + return false; + } + m_starting = true; + + if (!options->isCompositingInitialized()) { + options->reloadCompositingSettings(true); + } + slotCompositingOptionsInitialized(); + return true; +} + +void X11Compositor::slotConfigChanged() +{ + if (m_suspended) { + finish(); + } else { + Compositor::slotConfigChanged(); + } +} + +void X11Compositor::setCompositeResetTimer(int msecs) +{ + m_compositeResetTimer.start(msecs); +} + +} // included for CompositorSelectionOwner #include "composite.moc" diff --git a/dbusinterface.cpp b/dbusinterface.cpp --- a/dbusinterface.cpp +++ b/dbusinterface.cpp @@ -309,12 +309,16 @@ void CompositorDBusInterface::resume() { - m_compositor->resume(Compositor::ScriptSuspend); + if (kwinApp()->operationMode() == Application::OperationModeX11) { + static_cast(m_compositor)->resume(X11Compositor::ScriptSuspend); + } } void CompositorDBusInterface::suspend() { - m_compositor->suspend(Compositor::ScriptSuspend); + if (kwinApp()->operationMode() == Application::OperationModeX11) { + static_cast(m_compositor)->suspend(X11Compositor::ScriptSuspend); + } } QStringList CompositorDBusInterface::supportedOpenGLPlatformInterfaces() const diff --git a/main.h b/main.h --- a/main.h +++ b/main.h @@ -212,7 +212,6 @@ void createWorkspace(); void createAtoms(); void createOptions(); - void createCompositor(); void setupEventFilters(); void destroyWorkspace(); void destroyCompositor(); diff --git a/main.cpp b/main.cpp --- a/main.cpp +++ b/main.cpp @@ -310,11 +310,6 @@ options = new Options; } -void Application::createCompositor() -{ - Compositor::create(this); -} - void Application::setupEventFilters() { installNativeEventFilter(m_eventFilter.data()); diff --git a/main_wayland.cpp b/main_wayland.cpp --- a/main_wayland.cpp +++ b/main_wayland.cpp @@ -180,7 +180,7 @@ { disconnect(kwinApp()->platform(), &Platform::screensQueried, this, &ApplicationWayland::continueStartupWithScreens); createScreens(); - createCompositor(); + WaylandCompositor::create(kwinApp()); connect(Compositor::self(), &Compositor::sceneCreated, this, &ApplicationWayland::continueStartupWithScene); } diff --git a/options.cpp b/options.cpp --- a/options.cpp +++ b/options.cpp @@ -41,11 +41,6 @@ #ifndef KCMRULES -int currentRefreshRate() -{ - return Options::currentRefreshRate(); -} - int Options::currentRefreshRate() { int rate = -1; diff --git a/plugins/platforms/x11/standalone/screens_xrandr.cpp b/plugins/platforms/x11/standalone/screens_xrandr.cpp --- a/plugins/platforms/x11/standalone/screens_xrandr.cpp +++ b/plugins/platforms/x11/standalone/screens_xrandr.cpp @@ -80,8 +80,9 @@ // desktopResized() should take care of when the size or // shape of the desktop has changed, but we also want to // catch refresh rate changes - if (Compositor::self()->xrrRefreshRate() != Options::currentRefreshRate()) - Compositor::self()->setCompositeResetTimer(0); + auto *compositor = static_cast(Compositor::self()); + if (compositor->xrrRefreshRate() != Options::currentRefreshRate()) + compositor->setCompositeResetTimer(0); } #endif diff --git a/plugins/scenes/opengl/scene_opengl.cpp b/plugins/scenes/opengl/scene_opengl.cpp --- a/plugins/scenes/opengl/scene_opengl.cpp +++ b/plugins/scenes/opengl/scene_opengl.cpp @@ -84,9 +84,6 @@ namespace KWin { -extern int currentRefreshRate(); - - /** * SyncObject represents a fence used to synchronize operations in * the kwin command stream with operations in the X command stream. @@ -823,11 +820,15 @@ } bool SceneOpenGL::viewportLimitsMatched(const QSize &size) const { + if (kwinApp()->operationMode() != Application::OperationModeX11) { + // TODO: On Wayland we can't suspend. Find a solution that works here as well! + return true; + } GLint limit[2]; glGetIntegerv(GL_MAX_VIEWPORT_DIMS, limit); if (limit[0] < size.width() || limit[1] < size.height()) { - QMetaObject::invokeMethod(Compositor::self(), "suspend", - Qt::QueuedConnection, Q_ARG(Compositor::SuspendReason, Compositor::AllReasonSuspend)); + QMetaObject::invokeMethod(static_cast(Compositor::self()), "suspend", + Qt::QueuedConnection, Q_ARG(X11Compositor::SuspendReason, X11Compositor::AllReasonSuspend)); return false; } return true; diff --git a/thumbnailitem.cpp b/thumbnailitem.cpp --- a/thumbnailitem.cpp +++ b/thumbnailitem.cpp @@ -41,7 +41,6 @@ , m_saturation(1.0) , m_clipToItem() { - Q_ASSERT(Compositor::isCreated()); connect(Compositor::self(), SIGNAL(compositingToggled(bool)), SLOT(compositingToggled())); compositingToggled(); QTimer::singleShot(0, this, SLOT(init())); diff --git a/workspace.cpp b/workspace.cpp --- a/workspace.cpp +++ b/workspace.cpp @@ -176,7 +176,8 @@ if (Compositor::self()) { m_compositor = Compositor::self(); } else { - m_compositor = Compositor::create(this); + Q_ASSERT(kwinApp()->operationMode() == Application::OperationMode::OperationModeX11); + m_compositor = X11Compositor::create(this); } connect(this, &Workspace::currentDesktopChanged, m_compositor, &Compositor::addRepaintFull); connect(m_compositor, &QObject::destroyed, this, [this] { m_compositor = nullptr; });