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.
This commit is contained in:
parent
523b537962
commit
2d954a6bf3
14 changed files with 157 additions and 72 deletions
121
composite.cpp
121
composite.cpp
|
@ -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
|
||||
|
|
26
composite.h
26
composite.h
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
15
effects.cpp
15
effects.cpp
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
10
events.cpp
10
events.cpp
|
@ -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();
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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()
|
||||
|
|
6
scene.h
6
scene.h
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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 ®ion, 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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
7
utils.h
7
utils.h
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in a new issue