Make the Scene owned by the Compositor

The Scene has always been created and destroyed inside what is
now the split out compositor. Which means it is actually owned
by the Compositor. The static pointer has never been needed
inside KWin core. Access to the Scene is not required for the
Window Manager. The only real usage is in the EffectsHandlerImpl
and in utils.h to provide a convenient way to figure out whether
compositing is currently active (scene != NULL).

The EffectsHandlerImpl gets also created by the Compositor after
the Scene is created and gets deleted just before the Scene gets
deleted. This allows to inject the Scene into the EffectsHandlerImpl
to resolve the static access in this class.

The convenient way to access the compositing() in utils.h had
to go. To provide the same feature the Compositor provides a
hasScene() access which has the same behavior as the old method.
In order to keep the code changes small in Workspace and Toplevel
a new method compositing() is defined which properly resolves
the state. A disadvantage is that this can no longer be inlined
and consists of several method calls and pointer checks.
icc-effect-5.14.5
Martin Gräßlin 2012-08-16 21:19:54 +02:00
parent 523b537962
commit 2d954a6bf3
14 changed files with 157 additions and 72 deletions

View File

@ -88,6 +88,7 @@ Compositor::Compositor(QObject* workspace)
, compositingSuspended(!options->isUseCompositing())
, compositingBlocked(false)
, m_xrrRefreshRate(0)
, m_scene(NULL)
{
connect(&unredirectTimer, SIGNAL(timeout()), SLOT(delayedCheckUnredirect()));
connect(&compositeResetTimer, SIGNAL(timeout()), SLOT(resetCompositing()));
@ -112,7 +113,7 @@ Compositor::~Compositor()
void Compositor::setupCompositing()
{
if (scene != NULL)
if (hasScene())
return;
if (compositingSuspended) {
kDebug(1212) << "Compositing is suspended";
@ -170,16 +171,16 @@ void Compositor::slotCompositingOptionsInitialized()
}
#endif
scene = new SceneOpenGL(Workspace::self());
m_scene = new SceneOpenGL(Workspace::self());
// TODO: Add 30 second delay to protect against screen freezes as well
unsafeConfig.writeEntry("OpenGLIsUnsafe", false);
unsafeConfig.sync();
if (!scene->initFailed())
if (!m_scene->initFailed())
break; // -->
delete scene;
scene = NULL;
delete m_scene;
m_scene = NULL;
}
// Do not Fall back to XRender - it causes problems when selfcheck fails during startup, but works later on
@ -188,7 +189,7 @@ void Compositor::slotCompositingOptionsInitialized()
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
case XRenderCompositing:
kDebug(1212) << "Initializing XRender compositing";
scene = new SceneXrender(Workspace::self());
m_scene = new SceneXrender(Workspace::self());
break;
#endif
default:
@ -196,17 +197,17 @@ void Compositor::slotCompositingOptionsInitialized()
delete cm_selection;
return;
}
if (scene == NULL || scene->initFailed()) {
if (m_scene == NULL || m_scene->initFailed()) {
kError(1212) << "Failed to initialize compositing, compositing disabled";
kError(1212) << "Consult http://techbase.kde.org/Projects/KWin/4.0-release-notes#Setting_up";
delete scene;
scene = NULL;
delete m_scene;
m_scene = NULL;
delete cm_selection;
return;
}
m_xrrRefreshRate = KWin::currentRefreshRate();
fpsInterval = (options->maxFpsInterval() << 10);
if (scene->waitSyncAvailable()) { // if we do vsync, set the fps to the next multiple of the vblank rate
if (m_scene->waitSyncAvailable()) { // if we do vsync, set the fps to the next multiple of the vblank rate
vBlankInterval = (1000 << 10) / m_xrrRefreshRate;
fpsInterval = qMax((fpsInterval / vBlankInterval) * vBlankInterval, vBlankInterval);
} else
@ -214,7 +215,7 @@ void Compositor::slotCompositingOptionsInitialized()
m_timeSinceLastVBlank = fpsInterval - 1; // means "start now" - we don't have even a slight idea when the first vsync will occur
checkCompositeTimer();
XCompositeRedirectSubwindows(display(), rootWindow(), CompositeRedirectManual);
new EffectsHandlerImpl(scene->compositingType()); // sets also the 'effects' pointer
new EffectsHandlerImpl(m_scene); // sets also the 'effects' pointer
addRepaintFull();
foreach (Client * c, Workspace::self()->clientList())
c->setupCompositing();
@ -236,18 +237,18 @@ void Compositor::checkCompositeTimer()
void Compositor::finishCompositing()
{
if (scene == NULL)
if (!hasScene())
return;
m_finishingCompositing = true;
delete cm_selection;
foreach (Client * c, Workspace::self()->clientList())
scene->windowClosed(c, NULL);
m_scene->windowClosed(c, NULL);
foreach (Client * c, Workspace::self()->desktopList())
scene->windowClosed(c, NULL);
m_scene->windowClosed(c, NULL);
foreach (Unmanaged * c, Workspace::self()->unmanagedList())
scene->windowClosed(c, NULL);
m_scene->windowClosed(c, NULL);
foreach (Deleted * c, Workspace::self()->deletedList())
scene->windowDeleted(c);
m_scene->windowDeleted(c);
foreach (Client * c, Workspace::self()->clientList())
c->finishCompositing();
foreach (Client * c, Workspace::self()->desktopList())
@ -259,8 +260,8 @@ void Compositor::finishCompositing()
XCompositeUnredirectSubwindows(display(), rootWindow(), CompositeRedirectManual);
delete effects;
effects = NULL;
delete scene;
scene = NULL;
delete m_scene;
m_scene = NULL;
compositeTimer.stop();
mousePollingTimer.stop();
repaints_region = QRegion();
@ -396,7 +397,7 @@ void Compositor::suspendCompositing(bool suspend)
void Compositor::resetCompositing()
{
if (compositing()) {
if (hasScene()) {
finishCompositing();
QTimer::singleShot(0, this, SLOT(setupCompositing()));
}
@ -404,7 +405,7 @@ void Compositor::resetCompositing()
void Compositor::addRepaint(int x, int y, int w, int h)
{
if (!compositing())
if (!hasScene())
return;
repaints_region += QRegion(x, y, w, h);
checkCompositeTimer();
@ -412,7 +413,7 @@ void Compositor::addRepaint(int x, int y, int w, int h)
void Compositor::addRepaint(const QRect& r)
{
if (!compositing())
if (!hasScene())
return;
repaints_region += r;
checkCompositeTimer();
@ -420,7 +421,7 @@ void Compositor::addRepaint(const QRect& r)
void Compositor::addRepaint(const QRegion& r)
{
if (!compositing())
if (!hasScene())
return;
repaints_region += r;
checkCompositeTimer();
@ -428,7 +429,7 @@ void Compositor::addRepaint(const QRegion& r)
void Compositor::addRepaintFull()
{
if (!compositing())
if (!hasScene())
return;
repaints_region = QRegion(0, 0, displayWidth(), displayHeight());
checkCompositeTimer();
@ -446,12 +447,12 @@ void Compositor::timerEvent(QTimerEvent *te)
static bool s_pending = false;
void Compositor::performCompositing()
{
if (!scene->overlayWindow()->isVisible())
if (!isOverlayWindowVisible())
return; // nothing is visible anyway
bool pending = !repaints_region.isEmpty() || windowRepaintsPending();
if (!(pending || s_pending)) {
scene->idle();
m_scene->idle();
// Note: It would seem here we should undo suspended unredirect, but when scenes need
// it for some reason, e.g. transformations or translucency, the next pass that does not
// need this anymore and paints normally will also reset the suspended unredirect.
@ -479,7 +480,7 @@ void Compositor::performCompositing()
// clear all repaints, so that post-pass can add repaints for the next repaint
repaints_region = QRegion();
m_timeSinceLastVBlank = scene->paint(repaints, windows);
m_timeSinceLastVBlank = m_scene->paint(repaints, windows);
// Trigger at least one more pass even if there would be nothing to paint, so that scene->idle()
// is called the next time. If there would be nothing pending, it will not restart the timer and
// checkCompositeTime() would restart it again somewhen later, called from functions that
@ -516,12 +517,12 @@ void Compositor::setCompositeResetTimer(int msecs)
void Compositor::setCompositeTimer()
{
if (!compositing()) // should not really happen, but there may be e.g. some damage events still pending
if (!hasScene()) // should not really happen, but there may be e.g. some damage events still pending
return;
uint padding = m_timeSinceLastVBlank << 10;
if (scene->waitSyncAvailable()) {
if (m_scene->waitSyncAvailable()) {
// TODO: make vBlankTime dynamic?!
// It's required because glXWaitVideoSync will *likely* block a full frame if one enters
@ -565,13 +566,13 @@ void Compositor::stopMousePolling()
bool Compositor::compositingActive()
{
return !m_finishingCompositing && compositing();
return !m_finishingCompositing && hasScene();
}
// force is needed when the list of windows changes (e.g. a window goes away)
void Compositor::checkUnredirect(bool force)
{
if (!compositing() || scene->overlayWindow()->window() == None || !options->isUnredirectFullscreen())
if (!hasScene() || m_scene->overlayWindow()->window() == None || !options->isUnredirectFullscreen())
return;
if (force)
forceUnredirectCheck = true;
@ -581,7 +582,7 @@ void Compositor::checkUnredirect(bool force)
void Compositor::delayedCheckUnredirect()
{
if (!compositing() || scene->overlayWindow()->window() == None || !options->isUnredirectFullscreen())
if (!hasScene() || m_scene->overlayWindow()->window() == None || !options->isUnredirectFullscreen())
return;
ToplevelList list;
bool changed = forceUnredirectCheck;
@ -604,7 +605,50 @@ void Compositor::delayedCheckUnredirect()
if (c->unredirected())
reg -= c->geometry();
}
scene->overlayWindow()->setShape(reg);
m_scene->overlayWindow()->setShape(reg);
}
bool Compositor::checkForOverlayWindow(WId w) const
{
if (!hasScene()) {
// no scene, so it cannot be the overlay window
return false;
}
if (!m_scene->overlayWindow()) {
// no overlay window, it cannot be the overlay
return false;
}
// and compare the window ID's
return w == m_scene->overlayWindow()->window();
}
WId Compositor::overlayWindow() const
{
if (!hasScene()) {
return None;
}
if (!m_scene->overlayWindow()) {
return None;
}
return m_scene->overlayWindow()->window();
}
bool Compositor::isOverlayWindowVisible() const
{
if (!hasScene()) {
return false;
}
if (!m_scene->overlayWindow()) {
return false;
}
return m_scene->overlayWindow()->isVisible();
}
void Compositor::setOverlayWindowVisibility(bool visible)
{
if (hasScene() && m_scene->overlayWindow()) {
m_scene->overlayWindow()->setVisibility(visible);
}
}
/*****************************************************
@ -647,6 +691,11 @@ QString Workspace::compositingType()
return "none";
}
bool Workspace::compositing() const
{
return m_compositor && m_compositor->hasScene();
}
//****************************************
// Toplevel
//****************************************
@ -663,7 +712,7 @@ bool Toplevel::setupCompositing()
effect_window = new EffectWindowImpl(this);
unredirect = false;
workspace()->compositor()->checkUnredirect(true);
scene->windowAdded(this);
workspace()->compositor()->scene()->windowAdded(this);
return true;
}
@ -784,6 +833,12 @@ void Toplevel::damageNotifyEvent(XDamageNotifyEvent* e)
}
}
bool Toplevel::compositing() const
{
Compositor *c = workspace()->compositor();
return c && c->hasScene();
}
void Client::damageNotifyEvent(XDamageNotifyEvent* e)
{
#ifdef HAVE_XSYNC

View File

@ -28,6 +28,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
namespace KWin {
class Scene;
class Compositor : public QObject {
Q_OBJECT
@ -57,6 +58,30 @@ public:
int nextFrameDelay() {
return m_nextFrameDelay;
}
bool hasScene() const {
return m_scene != NULL;
}
/**
* Checks whether @p w is the Scene's overlay window.
**/
bool checkForOverlayWindow(WId w) const;
/**
* @returns The Scene's Overlay X Window.
**/
WId overlayWindow() const;
/**
* @returns Whether the Scene's Overlay X Window is visible.
**/
bool isOverlayWindowVisible() const;
/**
* Set's the Scene's Overlay X Window visibility to @p visible.
**/
void setOverlayWindowVisibility(bool visible);
Scene *scene() {
return m_scene;
}
public Q_SLOTS:
void addRepaintFull();
@ -105,6 +130,7 @@ private:
QTimer compositeResetTimer; // for compressing composite resets
bool m_finishingCompositing; // finishCompositing() sets this variable while shutting down
int m_timeSinceLastVBlank, m_nextFrameDelay;
Scene *m_scene;
};
}

View File

@ -96,12 +96,13 @@ static void deleteWindowProperty(Window win, long int atom)
//---------------------
EffectsHandlerImpl::EffectsHandlerImpl(CompositingType type)
: EffectsHandler(type)
EffectsHandlerImpl::EffectsHandlerImpl(Scene *scene)
: EffectsHandler(scene->compositingType())
, keyboard_grab_effect(NULL)
, fullscreen_effect(0)
, next_window_quad_type(EFFECT_QUAD_TYPE_START)
, mouse_poll_ref_count(0)
, m_scene(scene)
{
// init is important, otherwise causes crashes when quads are build before the first painting pass start
m_currentBuildQuadsIterator = m_activeEffects.end();
@ -242,7 +243,7 @@ void EffectsHandlerImpl::paintScreen(int mask, QRegion region, ScreenPaintData&
(*m_currentPaintScreenIterator++)->paintScreen(mask, region, data);
--m_currentPaintScreenIterator;
} else
scene->finalPaintScreen(mask, region, data);
m_scene->finalPaintScreen(mask, region, data);
}
void EffectsHandlerImpl::postPaintScreen()
@ -269,7 +270,7 @@ void EffectsHandlerImpl::paintWindow(EffectWindow* w, int mask, QRegion region,
(*m_currentPaintWindowIterator++)->paintWindow(w, mask, region, data);
--m_currentPaintWindowIterator;
} else
scene->finalPaintWindow(static_cast<EffectWindowImpl*>(w), mask, region, data);
m_scene->finalPaintWindow(static_cast<EffectWindowImpl*>(w), mask, region, data);
}
void EffectsHandlerImpl::paintEffectFrame(EffectFrame* frame, QRegion region, double opacity, double frameOpacity)
@ -306,7 +307,7 @@ void EffectsHandlerImpl::drawWindow(EffectWindow* w, int mask, QRegion region, W
(*m_currentDrawWindowIterator++)->drawWindow(w, mask, region, data);
--m_currentDrawWindowIterator;
} else
scene->finalDrawWindow(static_cast<EffectWindowImpl*>(w), mask, region, data);
m_scene->finalDrawWindow(static_cast<EffectWindowImpl*>(w), mask, region, data);
}
void EffectsHandlerImpl::buildQuads(EffectWindow* w, WindowQuadList& quadList)
@ -585,7 +586,7 @@ bool EffectsHandlerImpl::hasKeyboardGrab() const
void EffectsHandlerImpl::desktopResized(const QSize &size)
{
scene->screenGeometryChanged(size);
m_scene->screenGeometryChanged(size);
emit screenGeometryChanged(size);
Workspace::self()->compositor()->addRepaintFull();
}
@ -1136,7 +1137,7 @@ void EffectsHandlerImpl::reserveElectricBorderSwitching(bool reserve, Qt::Orient
unsigned long EffectsHandlerImpl::xrenderBufferPicture()
{
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
if (SceneXrender* s = dynamic_cast< SceneXrender* >(scene))
if (SceneXrender* s = dynamic_cast< SceneXrender* >(m_scene))
return s->bufferPicture();
#endif
return None;

View File

@ -47,7 +47,7 @@ class EffectsHandlerImpl : public EffectsHandler
{
Q_OBJECT
public:
EffectsHandlerImpl(CompositingType type);
EffectsHandlerImpl(Scene *scene);
virtual ~EffectsHandlerImpl();
virtual void prePaintScreen(ScreenPrePaintData& data, int time);
virtual void paintScreen(int mask, QRegion region, ScreenPaintData& data);
@ -228,6 +228,7 @@ private:
QList< Effect* >::iterator m_currentPaintEffectFrameIterator;
QList< Effect* >::iterator m_currentPaintScreenIterator;
QList< Effect* >::iterator m_currentBuildQuadsIterator;
Scene *m_scene;
};
class EffectWindowImpl : public EffectWindow

View File

@ -443,17 +443,17 @@ bool Workspace::workspaceEvent(XEvent * e)
case Expose:
if (compositing()
&& (e->xexpose.window == rootWindow() // root window needs repainting
|| (scene->overlayWindow()->window() != None && e->xexpose.window == scene->overlayWindow()->window()))) { // overlay needs repainting
|| (m_compositor->overlayWindow() != None && e->xexpose.window == m_compositor->overlayWindow()))) { // overlay needs repainting
if (m_compositor) {
m_compositor->addRepaint(e->xexpose.x, e->xexpose.y, e->xexpose.width, e->xexpose.height);
}
}
break;
case VisibilityNotify:
if (compositing() && scene->overlayWindow()->window() != None && e->xvisibility.window == scene->overlayWindow()->window()) {
bool was_visible = scene->overlayWindow()->isVisible();
scene->overlayWindow()->setVisibility((e->xvisibility.state != VisibilityFullyObscured));
if (!was_visible && scene->overlayWindow()->isVisible()) {
if (compositing() && m_compositor->overlayWindow() != None && e->xvisibility.window == m_compositor->overlayWindow()) {
bool was_visible = m_compositor->isOverlayWindowVisible();
m_compositor->setOverlayWindowVisibility((e->xvisibility.state != VisibilityFullyObscured));
if (!was_visible && m_compositor->isOverlayWindowVisible()) {
// hack for #154825
if (m_compositor) {
m_compositor->addRepaintFull();

View File

@ -24,11 +24,11 @@ DEALINGS IN THE SOFTWARE.
#include "paintredirector.h"
#include "workspace.h"
#include <kdebug.h>
#include <qevent.h>
#include <qpainter.h>
#include <qmath.h>
#include "utils.h"
namespace KWin
{
@ -82,7 +82,7 @@ bool PaintRedirector::eventFilter(QObject* o, QEvent* e)
break;
}
case QEvent::Paint: {
if (!compositing()) {
if (Workspace::self()->compositingActive()) {
return false;
}
if (!recursionCheck) {

View File

@ -93,8 +93,6 @@ namespace KWin
// Scene
//****************************************
Scene* scene = 0;
Scene::Scene(Workspace* ws)
: QObject(ws)
, wspace(ws)
@ -102,6 +100,7 @@ Scene::Scene(Workspace* ws)
, m_overlayWindow(new OverlayWindow())
{
last_time.invalidate(); // Initialize the timer
connect(Workspace::self(), SIGNAL(deletedRemoved(KWin::Deleted*)), SLOT(windowDeleted(KWin::Deleted*)));
}
Scene::~Scene()

View File

@ -60,8 +60,6 @@ public:
// a new window has been created
virtual void windowAdded(Toplevel*) = 0;
// a window has been destroyed
virtual void windowDeleted(Deleted*) = 0;
/**
* Method invoked when the screen geometry is changed.
* Reimplementing classes should also invoke the parent method
@ -100,6 +98,8 @@ public:
}
OverlayWindow* overlayWindow();
public Q_SLOTS:
// a window has been destroyed
virtual void windowDeleted(KWin::Deleted*) = 0;
// opacity of a window changed
virtual void windowOpacityChanged(KWin::Toplevel* c) = 0;
// shape/size of a window changed
@ -244,8 +244,6 @@ protected:
EffectFrameImpl* m_effectFrame;
};
extern Scene* scene;
inline
int Scene::Window::x() const
{

View File

@ -208,7 +208,9 @@ void SceneOpenGL::paintBackground(QRegion region)
void SceneOpenGL::windowAdded(Toplevel* c)
{
assert(!windows.contains(c));
windows[ c ] = new Window(c);
Window *w = new Window(c);
windows[ c ] = w;
w->setScene(this);
connect(c, SIGNAL(opacityChanged(KWin::Toplevel*,qreal)), SLOT(windowOpacityChanged(KWin::Toplevel*)));
connect(c, SIGNAL(geometryShapeChanged(KWin::Toplevel*,QRect)), SLOT(windowGeometryShapeChanged(KWin::Toplevel*)));
connect(c, SIGNAL(windowClosed(KWin::Toplevel*,KWin::Deleted*)), SLOT(windowClosed(KWin::Toplevel*,KWin::Deleted*)));
@ -347,6 +349,7 @@ SceneOpenGL::Window::Window(Toplevel* c)
, leftTexture()
, rightTexture()
, bottomTexture()
, m_scene(NULL)
{
}
@ -578,7 +581,7 @@ void SceneOpenGL::Window::performPaint(int mask, QRegion region, WindowPaintData
restoreStates(Content, data.opacity(), data.brightness(), data.saturation(), data.shader);
texture.unbind();
#ifndef KWIN_HAVE_OPENGLES
if (static_cast<SceneOpenGL*>(scene)->debug) {
if (m_scene && m_scene->debug) {
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
renderQuads(mask, region, contentQuads, &texture, false, hardwareClipping);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
@ -652,7 +655,7 @@ void SceneOpenGL::Window::paintDecoration(const QPixmap* decoration, TextureType
restoreStates(decorationType, data.opacity() * data.decorationOpacity(), data.brightness(), data.saturation(), data.shader);
decorationTexture->unbind();
#ifndef KWIN_HAVE_OPENGLES
if (static_cast<SceneOpenGL*>(scene)->debug) {
if (m_scene && m_scene->debug) {
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
GLVertexBuffer::streamingBuffer()->render(region, GL_TRIANGLES, hardwareClipping);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
@ -688,7 +691,7 @@ void SceneOpenGL::Window::paintShadow(const QRegion &region, const WindowPaintDa
restoreStates(Shadow, data.opacity(), data.brightness(), data.saturation(), data.shader, texture);
texture->unbind();
#ifndef KWIN_HAVE_OPENGLES
if (static_cast<SceneOpenGL*>(scene)->debug) {
if (m_scene && m_scene->debug) {
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
renderQuads(0, region, quads, texture, true, hardwareClipping);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

View File

@ -168,6 +168,9 @@ public:
bool bindTexture();
void discardTexture();
void checkTextureSize();
void setScene(SceneOpenGL *scene) {
m_scene = scene;
}
protected:
enum TextureType {
@ -199,6 +202,7 @@ private:
Texture leftTexture;
Texture rightTexture;
Texture bottomTexture;
SceneOpenGL *m_scene;
};
class SceneOpenGL::EffectFrame

View File

@ -314,6 +314,10 @@ protected:
void getWmClientLeader();
void getWmClientMachine();
void setReadyForPainting();
/**
* @returns Whether there is a compositor and it is active.
**/
bool compositing() const;
/**
* This function fetches the opaque region from this Toplevel.

View File

@ -253,13 +253,6 @@ bool grabbedXServer();
bool grabXKeyboard(Window w = rootWindow());
void ungrabXKeyboard();
class Scene;
extern Scene* scene;
inline bool compositing()
{
return scene != NULL;
}
// the docs say it's UrgencyHint, but it's often #defined as XUrgencyHint
#ifndef UrgencyHint
#define UrgencyHint XUrgencyHint

View File

@ -543,7 +543,7 @@ Client* Workspace::createClient(Window w, bool is_mapped)
Unmanaged* Workspace::createUnmanaged(Window w)
{
if (compositing() && w == scene->overlayWindow()->window())
if (m_compositor && m_compositor->checkForOverlayWindow(w))
return NULL;
Unmanaged* c = new Unmanaged(this);
if (!c->track(w)) {
@ -705,8 +705,6 @@ void Workspace::addDeleted(Deleted* c, Toplevel *orig, allowed_t)
void Workspace::removeDeleted(Deleted* c, allowed_t)
{
assert(deleted.contains(c));
if (scene)
scene->windowDeleted(c);
emit deletedRemoved(c);
deleted.removeAll(c);
unconstrained_stacking_order.removeAll(c);
@ -1165,8 +1163,6 @@ unsigned int ObscuringWindows::max_cache_size = 0;
void ObscuringWindows::create(Client* c)
{
if (compositing())
return; // Not needed with compositing
if (cached == 0)
cached = new QList<Window>;
Window obs_win;
@ -1244,7 +1240,7 @@ bool Workspace::setCurrentDesktop(int new_desktop)
continue;
}
if (!c->isOnDesktop(new_desktop) && c != movingClient && c->isOnCurrentActivity()) {
if (c->isShown(true) && c->isOnDesktop(old_desktop))
if (c->isShown(true) && c->isOnDesktop(old_desktop) && !compositing())
obs_wins.create(c);
(c)->updateVisibility();
}
@ -1465,7 +1461,7 @@ void Workspace::updateCurrentActivity(const QString &new_activity)
continue;
}
if (!c->isOnActivity(new_activity) && c != movingClient && c->isOnCurrentDesktop()) {
if (c->isShown(true) && c->isOnActivity(old_activity))
if (c->isShown(true) && c->isOnActivity(old_activity) && !compositing())
obs_wins.create(c);
c->updateVisibility();
}

View File

@ -761,6 +761,11 @@ private:
static NET::WindowType txtToWindowType(const char* txt);
static bool sessionInfoWindowTypeMatch(Client* c, SessionInfo* info);
/**
* @returns Whether we have a Compositor and it is active (Scene created)
**/
bool compositing() const;
Client* active_client;
Client* last_active_client;
Client* most_recently_raised; // Used ONLY by raiseOrLowerClient()