Move Workspace's compositing functions to own class Compositor

All Workspace functions which were implemented in the file composite.cpp
were moved to an own class Compositor. The header entries were moved as well.
All functions calls are updated.
icc-effect-5.14.5
Arthur Arlt 2011-08-21 21:50:23 +02:00 committed by Martin Gräßlin
parent ab6e4a41da
commit f3739469a2
11 changed files with 396 additions and 211 deletions

View File

@ -41,6 +41,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "rules.h"
#include "useractions.h"
#include <QX11Info>
#include "composite.h"
namespace KWin
{
@ -873,7 +874,9 @@ void Client::setActive(bool act)
emit activeChanged();
updateMouseGrab();
updateUrgency(); // demand attention again if it's still urgent
workspace()->checkUnredirect();
if (workspace()->compositor()) {
workspace()->compositor()->checkUnredirect();
}
}
void Client::startupIdChanged()

View File

@ -24,6 +24,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "options.h"
#include <kconfiggroup.h>
#include "composite.h"
namespace KWin
{
@ -215,7 +216,10 @@ void Bridge::grabXServer(bool grab)
bool Bridge::compositingActive() const
{
return c->workspace()->compositingActive();
if (c->workspace()->compositor()) {
return c->workspace()->compositor()->compositingActive();
}
return false;
}
QRect Bridge::transparentRect() const

View File

@ -35,6 +35,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <signal.h>
#include "bridge.h"
#include "composite.h"
#include "group.h"
#include "workspace.h"
#include "atoms.h"
@ -612,7 +613,7 @@ void Client::resizeDecorationPixmaps()
XFreePixmap(display(), decorationPixmapTop.handle());
}
if (workspace()->compositingActive() && effects->compositingType() == OpenGLCompositing) {
if (workspace()->compositor() && workspace()->compositor()->compositingActive() && effects->compositingType() == OpenGLCompositing) {
decorationPixmapTop = QPixmap(tr.size());
m_responsibleForDecoPixmap = false;
} else {
@ -631,7 +632,7 @@ void Client::resizeDecorationPixmaps()
XFreePixmap(display(), decorationPixmapBottom.handle());
}
if (workspace()->compositingActive() && effects->compositingType() == OpenGLCompositing) {
if (workspace()->compositor() && workspace()->compositor()->compositingActive() && effects->compositingType() == OpenGLCompositing) {
decorationPixmapBottom = QPixmap(br.size());
m_responsibleForDecoPixmap = false;
} else {
@ -650,7 +651,7 @@ void Client::resizeDecorationPixmaps()
XFreePixmap(display(), decorationPixmapLeft.handle());
}
if (workspace()->compositingActive() && effects->compositingType() == OpenGLCompositing) {
if (workspace()->compositor() && workspace()->compositor()->compositingActive() && effects->compositingType() == OpenGLCompositing) {
decorationPixmapLeft = QPixmap(lr.size());
m_responsibleForDecoPixmap = false;
} else {
@ -669,7 +670,7 @@ void Client::resizeDecorationPixmaps()
XFreePixmap(display(), decorationPixmapRight.handle());
}
if (workspace()->compositingActive() && effects->compositingType() == OpenGLCompositing) {
if (workspace()->compositor() && workspace()->compositor()->compositingActive() && effects->compositingType() == OpenGLCompositing) {
decorationPixmapRight = QPixmap(rr.size());
m_responsibleForDecoPixmap = false;
} else {
@ -1260,7 +1261,9 @@ void Client::internalShow(allowed_t)
XMapWindow(display(), inputId());
updateHiddenPreview();
}
workspace()->checkUnredirect();
if (workspace()->compositor()) {
workspace()->compositor()->checkUnredirect();
}
}
void Client::internalHide(allowed_t)
@ -1275,7 +1278,9 @@ void Client::internalHide(allowed_t)
updateHiddenPreview();
addWorkspaceRepaint(visibleRect());
workspace()->clientHidden(this);
workspace()->checkUnredirect();
if (workspace()->compositor()) {
workspace()->compositor()->checkUnredirect();
}
}
void Client::internalKeep(allowed_t)
@ -1292,7 +1297,9 @@ void Client::internalKeep(allowed_t)
updateHiddenPreview();
addWorkspaceRepaint(visibleRect());
workspace()->clientHidden(this);
workspace()->checkUnredirect();
if (workspace()->compositor()) {
workspace()->compositor()->checkUnredirect();
}
}
/**
@ -2332,8 +2339,8 @@ void Client::setBlockingCompositing(bool block)
{
const bool usedToBlock = blocks_compositing;
blocks_compositing = rules()->checkBlockCompositing(block);
if (usedToBlock != blocks_compositing) {
workspace()->updateCompositeBlocking(blocks_compositing ? this : 0);
if (usedToBlock != blocks_compositing && workspace()->compositor()) {
workspace()->compositor()->updateCompositeBlocking(blocks_compositing ? this : 0);
emit blockingCompositingChanged();
}
}

View File

@ -54,6 +54,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "shadow.h"
#include "useractions.h"
#include "compositingprefs.h"
#include "composite.h"
#include "notifications.h"
#include <stdio.h>
@ -62,6 +63,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <QtCore/QFutureWatcher>
#include <QMenu>
#include <QTimerEvent>
#include <QDateTime>
#include <kaction.h>
#include <kactioncollection.h>
#include <klocale.h>
@ -81,7 +83,31 @@ extern int currentRefreshRate();
// Workspace
//****************************************
void Workspace::setupCompositing()
Compositor::Compositor(Workspace* workspace)
: QObject(workspace)
, compositingSuspended(!options->isUseCompositing())
, compositingBlocked(false)
, m_xrrRefreshRate(0)
, m_workspace(workspace)
{
connect(&unredirectTimer, SIGNAL(timeout()), SLOT(delayedCheckUnredirect()));
connect(&compositeResetTimer, SIGNAL(timeout()), SLOT(resetCompositing()));
connect(workspace, SIGNAL(configChanged()), SLOT(slotConfigChanged()));
connect(workspace, SIGNAL(reinitializeCompositing()), SLOT(slotReinitialize()));
connect(&mousePollingTimer, SIGNAL(timeout()), SLOT(performMousePoll()));
unredirectTimer.setSingleShot(true);
compositeResetTimer.setSingleShot(true);
nextPaintReference.invalidate(); // Initialize the timer
setupCompositing();
}
Compositor::~Compositor()
{
finishCompositing();
}
void Compositor::setupCompositing()
{
if (scene != NULL)
return;
@ -112,7 +138,7 @@ void Workspace::setupCompositing()
}
}
void Workspace::slotCompositingOptionsInitialized()
void Compositor::slotCompositingOptionsInitialized()
{
char selection_name[ 100 ];
sprintf(selection_name, "_NET_WM_CM_S%d", DefaultScreen(display()));
@ -141,7 +167,7 @@ void Workspace::slotCompositingOptionsInitialized()
}
#endif
scene = new SceneOpenGL(this);
scene = new SceneOpenGL(m_workspace);
// TODO: Add 30 second delay to protect against screen freezes as well
unsafeConfig.writeEntry("OpenGLIsUnsafe", false);
@ -159,7 +185,7 @@ void Workspace::slotCompositingOptionsInitialized()
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
case XRenderCompositing:
kDebug(1212) << "Initializing XRender compositing";
scene = new SceneXrender(this);
scene = new SceneXrender(m_workspace);
break;
#endif
default:
@ -175,10 +201,10 @@ void Workspace::slotCompositingOptionsInitialized()
delete cm_selection;
return;
}
xrrRefreshRate = KWin::currentRefreshRate();
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
vBlankInterval = (1000 << 10) / xrrRefreshRate;
vBlankInterval = (1000 << 10) / m_xrrRefreshRate;
fpsInterval = qMax((fpsInterval / vBlankInterval) * vBlankInterval, vBlankInterval);
} else
vBlankInterval = 1 << 10; // no sync - DO NOT set "0", would cause div-by-zero segfaults.
@ -187,11 +213,11 @@ void Workspace::slotCompositingOptionsInitialized()
XCompositeRedirectSubwindows(display(), rootWindow(), CompositeRedirectManual);
new EffectsHandlerImpl(scene->compositingType()); // sets also the 'effects' pointer
addRepaintFull();
foreach (Client * c, clients)
foreach (Client * c, m_workspace->clientList())
c->setupCompositing();
foreach (Client * c, desktops)
foreach (Client * c, m_workspace->desktopList())
c->setupCompositing();
foreach (Unmanaged * c, unmanaged)
foreach (Unmanaged * c, m_workspace->unmanagedList())
c->setupCompositing();
// render at least once
@ -199,27 +225,33 @@ void Workspace::slotCompositingOptionsInitialized()
performCompositing();
}
void Workspace::finishCompositing()
void Compositor::checkCompositeTimer()
{
if (!compositeTimer.isActive())
setCompositeTimer();
}
void Compositor::finishCompositing()
{
if (scene == NULL)
return;
m_finishingCompositing = true;
delete cm_selection;
foreach (Client * c, clients)
foreach (Client * c, m_workspace->clientList())
scene->windowClosed(c, NULL);
foreach (Client * c, desktops)
foreach (Client * c, m_workspace->desktopList())
scene->windowClosed(c, NULL);
foreach (Unmanaged * c, unmanaged)
foreach (Unmanaged * c, m_workspace->unmanagedList())
scene->windowClosed(c, NULL);
foreach (Deleted * c, deleted)
foreach (Deleted * c, m_workspace->deletedList())
scene->windowDeleted(c);
foreach (Client * c, clients)
foreach (Client * c, m_workspace->clientList())
c->finishCompositing();
foreach (Client * c, desktops)
foreach (Client * c, m_workspace->desktopList())
c->finishCompositing();
foreach (Unmanaged * c, unmanaged)
foreach (Unmanaged * c, m_workspace->unmanagedList())
c->finishCompositing();
foreach (Deleted * c, deleted)
foreach (Deleted * c, m_workspace->deletedList())
c->finishCompositing();
XCompositeUnredirectSubwindows(display(), rootWindow(), CompositeRedirectManual);
delete effects;
@ -229,8 +261,8 @@ void Workspace::finishCompositing()
compositeTimer.stop();
mousePollingTimer.stop();
repaints_region = QRegion();
for (ClientList::ConstIterator it = clients.constBegin();
it != clients.constEnd();
for (ClientList::ConstIterator it = m_workspace->clientList().constBegin();
it != m_workspace->clientList().constEnd();
++it) {
// forward all opacity values to the frame in case there'll be other CM running
if ((*it)->opacity() != 1.0) {
@ -238,15 +270,14 @@ void Workspace::finishCompositing()
i.setOpacity(static_cast< unsigned long >((*it)->opacity() * 0xffffffff));
}
}
m_userActionsMenu->discard(); // force re-creation of the Alt+F3 popup (opacity option)
// discard all Deleted windows (#152914)
while (!deleted.isEmpty())
deleted.first()->discard(Allowed);
while (!m_workspace->deletedList().isEmpty())
m_workspace->deletedList().first()->discard(Allowed);
m_finishingCompositing = false;
}
// OpenGL self-check failed, fallback to XRender
void Workspace::fallbackToXRenderCompositing()
void Compositor::fallbackToXRenderCompositing()
{
finishCompositing();
KConfigGroup config(KGlobal::config(), "Compositing");
@ -254,7 +285,7 @@ void Workspace::fallbackToXRenderCompositing()
config.writeEntry("GraphicsSystem", "native");
config.sync();
if (Extensions::nonNativePixmaps()) { // must restart to change the graphicssystem
restartKWin("automatic graphicssystem change for XRender backend");
emit signalRestartKWin("automatic graphicssystem change for XRender backend");
return;
} else {
options->setCompositingMode(XRenderCompositing);
@ -262,26 +293,47 @@ void Workspace::fallbackToXRenderCompositing()
}
}
void Workspace::lostCMSelection()
void Compositor::lostCMSelection()
{
kDebug(1212) << "Lost compositing manager selection";
finishCompositing();
}
void Compositor::slotConfigChanged()
{
if (!compositingSuspended) {
setupCompositing();
if (effects) // setupCompositing() may fail
effects->reconfigure();
addRepaintFull();
} else
finishCompositing();
}
void Compositor::slotReinitialize()
{
// Restart compositing
finishCompositing();
// resume compositing if suspended
compositingSuspended = false;
options->setCompositingInitialized(false);
setupCompositing();
}
// for the shortcut
void Workspace::slotToggleCompositing()
void Compositor::slotToggleCompositing()
{
suspendCompositing(!compositingSuspended);
}
// for the dbus call
void Workspace::toggleCompositing()
void Compositor::toggleCompositing()
{
slotToggleCompositing();
if (compositingSuspended) {
// when disabled show a shortcut how the user can get back compositing
QString shortcut, message;
if (KAction* action = qobject_cast<KAction*>(keys->action("Suspend Compositing")))
if (KAction* action = qobject_cast<KAction*>(m_workspace->actionCollection()->action("Suspend Compositing")))
shortcut = action->globalShortcut().primary().toString(QKeySequence::NativeText);
if (!shortcut.isEmpty()) {
// display notification only if there is the shortcut
@ -299,7 +351,7 @@ QStringList Workspace::activeEffects() const
return QStringList();
}
void Workspace::updateCompositeBlocking(Client *c)
void Compositor::updateCompositeBlocking(Client *c)
{
if (c) { // if c == 0 we just check if we can resume
if (c->isBlockingCompositing()) {
@ -312,7 +364,7 @@ void Workspace::updateCompositeBlocking(Client *c)
// NOTICE do NOT check for "compositingSuspended" or "!compositing()"
// only "resume" if it was really disabled for a block
bool resume = true;
for (ClientList::ConstIterator it = clients.constBegin(); it != clients.constEnd(); ++it) {
for (ClientList::ConstIterator it = m_workspace->clientList().constBegin(); it != m_workspace->clientList().constEnd(); ++it) {
if ((*it)->isBlockingCompositing()) {
resume = false;
break;
@ -326,25 +378,20 @@ void Workspace::updateCompositeBlocking(Client *c)
}
}
void Workspace::suspendCompositing()
void Compositor::suspendCompositing()
{
suspendCompositing(true);
}
void Workspace::suspendCompositing(bool suspend)
void Compositor::suspendCompositing(bool suspend)
{
compositingSuspended = suspend;
finishCompositing();
setupCompositing(); // will do nothing if suspended
// notify decorations that composition state has changed
if (hasDecorationPlugin()) {
KDecorationFactory* factory = mgr->factory();
factory->reset(SettingCompositing);
}
emit compositingToggled(!compositingSuspended);
}
void Workspace::resetCompositing()
void Compositor::resetCompositing()
{
if (compositing()) {
finishCompositing();
@ -352,7 +399,7 @@ void Workspace::resetCompositing()
}
}
void Workspace::addRepaint(int x, int y, int w, int h)
void Compositor::addRepaint(int x, int y, int w, int h)
{
if (!compositing())
return;
@ -360,7 +407,7 @@ void Workspace::addRepaint(int x, int y, int w, int h)
checkCompositeTimer();
}
void Workspace::addRepaint(const QRect& r)
void Compositor::addRepaint(const QRect& r)
{
if (!compositing())
return;
@ -368,7 +415,7 @@ void Workspace::addRepaint(const QRect& r)
checkCompositeTimer();
}
void Workspace::addRepaint(const QRegion& r)
void Compositor::addRepaint(const QRegion& r)
{
if (!compositing())
return;
@ -376,7 +423,7 @@ void Workspace::addRepaint(const QRegion& r)
checkCompositeTimer();
}
void Workspace::addRepaintFull()
void Compositor::addRepaintFull()
{
if (!compositing())
return;
@ -384,7 +431,7 @@ void Workspace::addRepaintFull()
checkCompositeTimer();
}
void Workspace::timerEvent(QTimerEvent *te)
void Compositor::timerEvent(QTimerEvent *te)
{
if (te->timerId() == compositeTimer.timerId()) {
compositeTimer.stop();
@ -394,7 +441,7 @@ void Workspace::timerEvent(QTimerEvent *te)
}
static bool s_pending = false;
void Workspace::performCompositing()
void Compositor::performCompositing()
{
if (!scene->overlayWindow()->isVisible())
return; // nothing is visible anyway
@ -410,8 +457,8 @@ void Workspace::performCompositing()
}
s_pending = pending;
// create a list of all windows in the stacking order
ToplevelList windows = xStackingOrder();
foreach (EffectWindow *c, static_cast< EffectsHandlerImpl* >(effects)->elevatedWindows()) {
ToplevelList windows = m_workspace->xStackingOrder();
foreach (EffectWindow * c, static_cast< EffectsHandlerImpl* >(effects)->elevatedWindows()) {
Toplevel* t = static_cast< EffectWindowImpl* >(c)->window();
windows.removeAll(t);
windows.append(t);
@ -437,29 +484,34 @@ void Workspace::performCompositing()
checkCompositeTimer();
}
void Workspace::performMousePoll()
void Compositor::performMousePoll()
{
checkCursorPos();
m_workspace->checkCursorPos();
}
bool Workspace::windowRepaintsPending() const
bool Compositor::windowRepaintsPending() const
{
foreach (Toplevel * c, clients)
foreach (Toplevel * c, m_workspace->clientList())
if (!c->repaints().isEmpty())
return true;
foreach (Toplevel * c, desktops)
foreach (Toplevel * c, m_workspace->desktopList())
if (!c->repaints().isEmpty())
return true;
foreach (Toplevel * c, unmanaged)
foreach (Toplevel * c, m_workspace->unmanagedList())
if (!c->repaints().isEmpty())
return true;
foreach (Toplevel * c, deleted)
foreach (Toplevel * c, m_workspace->deletedList())
if (!c->repaints().isEmpty())
return true;
return false;
}
void Workspace::setCompositeTimer()
void Compositor::setCompositeResetTimer(int msecs)
{
compositeResetTimer.start(msecs);
}
void Compositor::setCompositeTimer()
{
if (!compositing()) // should not really happen, but there may be e.g. some damage events still pending
return;
@ -498,23 +550,23 @@ void Workspace::setCompositeTimer()
compositeTimer.start(qMin(padding, 250u), this); // force 4fps minimum
}
void Workspace::startMousePolling()
void Compositor::startMousePolling()
{
mousePollingTimer.start(20); // 50Hz. TODO: How often do we really need to poll?
}
void Workspace::stopMousePolling()
void Compositor::stopMousePolling()
{
mousePollingTimer.stop();
}
bool Workspace::compositingActive()
bool Compositor::compositingActive()
{
return !m_finishingCompositing && compositing();
}
// force is needed when the list of windows changes (e.g. a window goes away)
void Workspace::checkUnredirect(bool force)
void Compositor::checkUnredirect(bool force)
{
if (!compositing() || scene->overlayWindow()->window() == None || !options->isUnredirectFullscreen())
return;
@ -524,15 +576,15 @@ void Workspace::checkUnredirect(bool force)
unredirectTimer.start(0);
}
void Workspace::delayedCheckUnredirect()
void Compositor::delayedCheckUnredirect()
{
if (!compositing() || scene->overlayWindow()->window() == None || !options->isUnredirectFullscreen())
return;
ToplevelList list;
bool changed = forceUnredirectCheck;
foreach (Client * c, clients)
foreach (Client * c, m_workspace->clientList())
list.append(c);
foreach (Unmanaged * c, unmanaged)
foreach (Unmanaged * c, m_workspace->unmanagedList())
list.append(c);
foreach (Toplevel * c, list) {
if (c->updateUnredirectedState())
@ -552,7 +604,9 @@ void Workspace::delayedCheckUnredirect()
scene->overlayWindow()->setShape(reg);
}
/*****************************************************
* Compositing related D-Bus interface from Workspace
****************************************************/
bool Workspace::compositingPossible() const
{
return CompositingPrefs::compositingPossible();
@ -605,7 +659,7 @@ bool Toplevel::setupCompositing()
damage_region = QRegion(0, 0, width(), height());
effect_window = new EffectWindowImpl(this);
unredirect = false;
workspace()->checkUnredirect(true);
workspace()->compositor()->checkUnredirect(true);
scene->windowAdded(this);
return true;
}
@ -615,7 +669,7 @@ void Toplevel::finishCompositing()
damageRatio = 0.0;
if (damage_handle == None)
return;
workspace()->checkUnredirect(true);
workspace()->compositor()->checkUnredirect(true);
if (effect_window->window() == this) { // otherwise it's already passed to Deleted, don't free data
discardWindowPixmap();
delete effect_window;
@ -775,7 +829,7 @@ void Toplevel::addDamage(int x, int y, int w, int h)
effect_window->setData(LanczosCacheRole, QVariant());
}
}
workspace()->checkCompositeTimer();
workspace()->compositor()->checkCompositeTimer();
}
void Toplevel::addDamageFull()
@ -796,7 +850,7 @@ void Toplevel::addDamageFull()
effect_window->setData(LanczosCacheRole, QVariant());
}
}
workspace()->checkCompositeTimer();
workspace()->compositor()->checkCompositeTimer();
}
void Toplevel::resetDamage(const QRect& r)
@ -814,7 +868,7 @@ void Toplevel::addRepaint(const QRect& r)
return;
}
repaints_region += r;
workspace()->checkCompositeTimer();
workspace()->compositor()->checkCompositeTimer();
}
void Toplevel::addRepaint(int x, int y, int w, int h)
@ -829,7 +883,7 @@ void Toplevel::addRepaint(const QRegion& r)
return;
}
repaints_region += r;
workspace()->checkCompositeTimer();
workspace()->compositor()->checkCompositeTimer();
}
void Toplevel::addLayerRepaint(const QRect& r)
@ -838,7 +892,7 @@ void Toplevel::addLayerRepaint(const QRect& r)
return;
}
layer_repaints_region += r;
workspace()->checkCompositeTimer();
workspace()->compositor()->checkCompositeTimer();
}
void Toplevel::addLayerRepaint(int x, int y, int w, int h)
@ -852,13 +906,13 @@ void Toplevel::addLayerRepaint(const QRegion& r)
if (!compositing())
return;
layer_repaints_region += r;
workspace()->checkCompositeTimer();
workspace()->compositor()->checkCompositeTimer();
}
void Toplevel::addRepaintFull()
{
repaints_region = visibleRect().translated(-pos());
workspace()->checkCompositeTimer();
workspace()->compositor()->checkCompositeTimer();
}
void Toplevel::resetRepaints()
@ -876,7 +930,7 @@ void Toplevel::addWorkspaceRepaint(const QRect& r2)
{
if (!compositing())
return;
workspace()->addRepaint(r2);
workspace()->compositor()->addRepaint(r2);
}
bool Toplevel::updateUnredirectedState()
@ -904,7 +958,7 @@ void Toplevel::suspendUnredirect(bool suspend)
if (unredirectSuspend == suspend)
return;
unredirectSuspend = suspend;
workspace()->checkUnredirect();
workspace()->compositor()->checkUnredirect();
}
//****************************************

114
composite.h Normal file
View File

@ -0,0 +1,114 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2011 Arthur Arlt <a.arlt@stud.uni-heidelberg.de>
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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#ifndef KWIN_COMPOSITE_H
#define KWIN_COMPOSITE_H
#include <QtCore/QObject>
#include <QtCore/QTimer>
#include <QRegion>
#include <kmanagerselection.h>
#include "workspace.h"
namespace KWin {
class Workspace;
class Compositor : public QObject {
Q_OBJECT
public:
Compositor(Workspace *workspace);
~Compositor();
void checkCompositeTimer();
// 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);
void checkUnredirect(bool force = false);
void toggleCompositing();
void updateCompositeBlocking(Client* c = NULL);
// Mouse polling
void startMousePolling();
void stopMousePolling();
bool compositingActive();
int xrrRefreshRate() {
return m_xrrRefreshRate;
}
void setCompositeResetTimer(int msecs);
// returns the _estimated_ delay to the next screen update
// good for having a rough idea to calculate transformations, bad to rely on.
// might happen few ms earlier, might be an entire frame to short. This is NOT deterministic.
int nextFrameDelay() {
return m_nextFrameDelay;
}
public Q_SLOTS:
void addRepaintFull();
void slotToggleCompositing();
void suspendCompositing();
void suspendCompositing(bool suspend);
void resetCompositing();
Q_SIGNALS:
void compositingToggled(bool active);
void signalRestartKWin(const QString &reason);
protected:
void timerEvent(QTimerEvent *te);
private Q_SLOTS:
void setupCompositing();
/**
* Called from setupCompositing() when the CompositingPrefs are ready.
**/
void slotCompositingOptionsInitialized();
void finishCompositing();
void fallbackToXRenderCompositing();
void lostCMSelection();
void performCompositing();
void performMousePoll();
void delayedCheckUnredirect();
void slotConfigChanged();
void slotReinitialize();
private:
void setCompositeTimer();
bool windowRepaintsPending() const;
bool compositingSuspended, compositingBlocked;
QBasicTimer compositeTimer;
KSelectionOwner* cm_selection;
uint vBlankInterval, fpsInterval;
int m_xrrRefreshRate;
QElapsedTimer nextPaintReference;
QTimer mousePollingTimer;
QRegion repaints_region;
Workspace* m_workspace;
QTimer unredirectTimer;
bool forceUnredirectCheck;
QTimer compositeResetTimer; // for compressing composite resets
bool m_finishingCompositing; // finishCompositing() sets this variable while shutting down
int m_timeSinceLastVBlank, m_nextFrameDelay;
};
}
# endif // KWIN_COMPOSITE_H

View File

@ -50,6 +50,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <Plasma/Theme>
#include <assert.h>
#include "composite.h"
namespace KWin
@ -509,7 +510,7 @@ void EffectsHandlerImpl::slotPaddingChanged(Toplevel* t, const QRect& old)
void EffectsHandlerImpl::setActiveFullScreenEffect(Effect* e)
{
fullscreen_effect = e;
Workspace::self()->checkUnredirect();
Workspace::self()->compositor()->checkUnredirect();
}
Effect* EffectsHandlerImpl::activeFullScreenEffect() const
@ -565,7 +566,7 @@ void* EffectsHandlerImpl::getProxy(QString name)
void EffectsHandlerImpl::startMousePolling()
{
if (!mouse_poll_ref_count) // Start timer if required
Workspace::self()->startMousePolling();
Workspace::self()->compositor()->startMousePolling();
mouse_poll_ref_count++;
}
@ -574,7 +575,7 @@ void EffectsHandlerImpl::stopMousePolling()
assert(mouse_poll_ref_count);
mouse_poll_ref_count--;
if (!mouse_poll_ref_count) // Stop timer if required
Workspace::self()->stopMousePolling();
Workspace::self()->compositor()->stopMousePolling();
}
bool EffectsHandlerImpl::hasKeyboardGrab() const
@ -586,7 +587,7 @@ void EffectsHandlerImpl::desktopResized(const QSize &size)
{
scene->screenGeometryChanged(size);
emit screenGeometryChanged(size);
Workspace::self()->addRepaintFull();
Workspace::self()->compositor()->addRepaintFull();
}
void EffectsHandlerImpl::slotPropertyNotify(Toplevel* t, long int atom)
@ -908,22 +909,22 @@ EffectWindow* EffectsHandlerImpl::currentTabBoxWindow() const
void EffectsHandlerImpl::addRepaintFull()
{
Workspace::self()->addRepaintFull();
Workspace::self()->compositor()->addRepaintFull();
}
void EffectsHandlerImpl::addRepaint(const QRect& r)
{
Workspace::self()->addRepaint(r);
Workspace::self()->compositor()->addRepaint(r);
}
void EffectsHandlerImpl::addRepaint(const QRegion& r)
{
Workspace::self()->addRepaint(r);
Workspace::self()->compositor()->addRepaint(r);
}
void EffectsHandlerImpl::addRepaint(int x, int y, int w, int h)
{
Workspace::self()->addRepaint(x, y, w, h);
Workspace::self()->compositor()->addRepaint(x, y, w, h);
}
int EffectsHandlerImpl::activeScreen() const
@ -1191,7 +1192,7 @@ QStringList EffectsHandlerImpl::listOfEffects() const
bool EffectsHandlerImpl::loadEffect(const QString& name, bool checkDefault)
{
Workspace::self()->addRepaintFull();
Workspace::self()->compositor()->addRepaintFull();
if (!name.startsWith(QLatin1String("kwin4_effect_")))
kWarning(1212) << "Effect names usually have kwin4_effect_ prefix" ;
@ -1329,7 +1330,7 @@ bool EffectsHandlerImpl::loadScriptedEffect(const QString& name, KService *servi
void EffectsHandlerImpl::unloadEffect(const QString& name)
{
Workspace::self()->addRepaintFull();
Workspace::self()->compositor()->addRepaintFull();
for (QMap< int, EffectPair >::iterator it = effect_order.begin(); it != effect_order.end(); ++it) {
if (it.value().first == name) {

View File

@ -51,6 +51,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <X11/Xatom.h>
#include <QX11Info>
#include "composite.h"
namespace KWin
{
@ -442,7 +444,9 @@ bool Workspace::workspaceEvent(XEvent * e)
if (compositing()
&& (e->xexpose.window == rootWindow() // root window needs repainting
|| (scene->overlayWindow()->window() != None && e->xexpose.window == scene->overlayWindow()->window()))) { // overlay needs repainting
addRepaint(e->xexpose.x, e->xexpose.y, e->xexpose.width, e->xexpose.height);
if (m_compositor) {
m_compositor->addRepaint(e->xexpose.x, e->xexpose.y, e->xexpose.width, e->xexpose.height);
}
}
break;
case VisibilityNotify:
@ -451,21 +455,25 @@ bool Workspace::workspaceEvent(XEvent * e)
scene->overlayWindow()->setVisibility((e->xvisibility.state != VisibilityFullyObscured));
if (!was_visible && scene->overlayWindow()->isVisible()) {
// hack for #154825
addRepaintFull();
QTimer::singleShot(2000, this, SLOT(addRepaintFull()));
if (m_compositor) {
m_compositor->addRepaintFull();
QTimer::singleShot(2000, m_compositor, SLOT(addRepaintFull()));
}
}
if (m_compositor) {
m_compositor->checkCompositeTimer();
}
checkCompositeTimer();
}
break;
default:
if (e->type == Extensions::randrNotifyEvent() && Extensions::randrAvailable()) {
XRRUpdateConfiguration(e);
if (compositing()) {
if (compositing() && m_compositor) {
// 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 (xrrRefreshRate != currentRefreshRate())
compositeResetTimer.start(0);
if (m_compositor->xrrRefreshRate() != currentRefreshRate())
m_compositor->setCompositeResetTimer(0);
}
} else if (e->type == Extensions::syncAlarmNotifyEvent() && Extensions::syncAvailable()) {

View File

@ -28,6 +28,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "client.h"
#include "composite.h"
#include "workspace.h"
#include <kapplication.h>
@ -1909,7 +1910,9 @@ void Client::setGeometry(int x, int y, int w, int h, ForceGeometry_t force)
// to detect changes
workspace()->checkActiveScreen(this);
workspace()->updateStackingOrder();
workspace()->checkUnredirect();
if (workspace()->compositor()) {
workspace()->compositor()->checkUnredirect();
}
// need to regenerate decoration pixmaps when either
// - size is changed
@ -1983,7 +1986,9 @@ void Client::plainResize(int w, int h, ForceGeometry_t force)
updateWindowRules(Rules::Position|Rules::Size);
workspace()->checkActiveScreen(this);
workspace()->updateStackingOrder();
workspace()->checkUnredirect();
if (workspace()->compositor()) {
workspace()->compositor()->checkUnredirect();
}
discardWindowPixmap();
emit geometryShapeChanged(this, geom_before_block);
const QRect deco_rect = visibleRect();
@ -2028,7 +2033,9 @@ void Client::move(int x, int y, ForceGeometry_t force)
updateWindowRules(Rules::Position);
workspace()->checkActiveScreen(this);
workspace()->updateStackingOrder();
workspace()->checkUnredirect();
if (workspace()->compositor()) {
workspace()->compositor()->checkUnredirect();
}
// client itself is not damaged
const QRect deco_rect = visibleRect();
addLayerRepaint(deco_rect_before_block);
@ -2374,7 +2381,9 @@ void Client::setFullScreen(bool set, bool user)
}
}
updateWindowRules(Rules::Fullscreen|Rules::Position|Rules::Size);
workspace()->checkUnredirect();
if (workspace()->compositor()) {
workspace()->compositor()->checkUnredirect();
}
if (was_fs != isFullScreen()) {
emit clientFullScreenSet(this, set, user);

View File

@ -86,6 +86,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "deleted.h"
#include "effects.h"
#include <QX11Info>
#include "composite.h"
namespace KWin
{
@ -130,7 +131,10 @@ void Workspace::updateStackingOrder(bool propagate_new_clients)
#endif
if (changed || propagate_new_clients) {
propagateClients(propagate_new_clients);
addRepaintFull();
if (m_compositor) {
m_compositor->addRepaintFull();
}
if (active_client)
active_client->updateMouseGrab();
}
@ -712,7 +716,9 @@ ToplevelList Workspace::xStackingOrder() const
}
if (windows != NULL)
XFree(windows);
const_cast< Workspace* >(this)->checkUnredirect();
if (m_compositor) {
const_cast< Workspace* >(this)->m_compositor->checkUnredirect();
}
return x_stacking;
}

View File

@ -45,6 +45,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <QtDBus/QtDBus>
#include "client.h"
#include "composite.h"
#ifdef KWIN_BUILD_TABBOX
#include "tabbox.h"
#endif
@ -105,7 +106,6 @@ Workspace::Workspace(bool restore)
, m_screenEdgeOrientation(0)
#endif
// Unsorted
, m_nextFrameDelay(0)
, active_popup(NULL)
, active_popup_client(NULL)
, temporaryRulesMessages("_KDE_NET_WM_TEMPORARY_RULES", NULL, false)
@ -140,14 +140,8 @@ Workspace::Workspace(bool restore)
, set_active_client_recursion(0)
, block_stacking_updates(0)
, forced_global_mouse_grab(false)
, cm_selection(NULL)
, compositingSuspended(false)
, compositingBlocked(false)
, xrrRefreshRate(0)
, transSlider(NULL)
, transButton(NULL)
, forceUnredirectCheck(true)
, m_finishingCompositing(false)
, m_scripting(NULL)
{
// If KWin was already running it saved its configuration after loosing the selection -> Reread
@ -183,11 +177,6 @@ Workspace::Workspace(bool restore)
connect(&temporaryRulesMessages, SIGNAL(gotMessage(QString)),
this, SLOT(gotTemporaryRulesMessage(QString)));
connect(&rulesUpdatedTimer, SIGNAL(timeout()), this, SLOT(writeWindowRules()));
connect(&unredirectTimer, SIGNAL(timeout()), this, SLOT(delayedCheckUnredirect()));
connect(&compositeResetTimer, SIGNAL(timeout()), this, SLOT(resetCompositing()));
unredirectTimer.setSingleShot(true);
compositeResetTimer.setSingleShot(true);
updateXTime(); // Needed for proper initialization of user_time in Client ctor
delayFocusTimer = 0;
@ -212,13 +201,15 @@ Workspace::Workspace(bool restore)
ExposureMask
);
compositingSuspended = !options->isUseCompositing();
#ifdef KWIN_BUILD_TABBOX
// need to create the tabbox before compositing scene is setup
tab_box = new TabBox::TabBox(this);
#endif
setupCompositing();
m_compositor = new Compositor(this);
connect(m_compositor, SIGNAL(compositingToggled(bool)), SIGNAL(compositingToggled(bool)));
connect(m_compositor, SIGNAL(compositingToggled(bool)), SLOT(slotCompositingToggled()));
connect(m_compositor, SIGNAL(signalRestartKWin(QString)), SLOT(slotRestartKwin(QString)));
// Compatibility
long data = 1;
@ -398,7 +389,6 @@ void Workspace::init()
connect(&reconfigureTimer, SIGNAL(timeout()), this, SLOT(slotReconfigure()));
connect(&updateToolWindowsTimer, SIGNAL(timeout()), this, SLOT(slotUpdateToolWindows()));
connect(&mousePollingTimer, SIGNAL(timeout()), SLOT(performMousePoll()));
connect(KGlobalSettings::self(), SIGNAL(appearanceChanged()), this, SLOT(reconfigure()));
connect(KGlobalSettings::self(), SIGNAL(settingsChanged(int)), this, SLOT(slotSettingsChanged(int)));
@ -491,7 +481,7 @@ void Workspace::init()
Workspace::~Workspace()
{
finishCompositing();
delete m_compositor;
blockStackingUpdates(true);
// TODO: grabXServer();
@ -674,7 +664,9 @@ void Workspace::removeClient(Client* c, allowed_t)
updateStackingOrder(true);
updateCompositeBlocking();
if (m_compositor) {
m_compositor->updateCompositeBlocking();
}
#ifdef KWIN_BUILD_TABBOX
if (tabBox()->isDisplayed())
@ -920,7 +912,10 @@ bool Workspace::waitForCompositingSetup()
reconfigureTimer.stop();
slotReconfigure();
}
return compositingActive();
if (m_compositor) {
return m_compositor->compositingActive();
}
return false;
}
void Workspace::slotSettingsChanged(int category)
@ -991,15 +986,6 @@ void Workspace::slotReconfigure()
}
m_screenEdge.update();
#endif
if (!compositingSuspended) {
setupCompositing();
if (effects) // setupCompositing() may fail
effects->reconfigure();
addRepaintFull();
} else
finishCompositing();
loadWindowRules();
for (ClientList::Iterator it = clients.begin();
it != clients.end();
@ -1028,6 +1014,11 @@ void Workspace::slotReconfigure()
}
}
void Workspace::slotRestartKwin(const QString& reason)
{
restartKWin(reason);
}
void Workspace::restartKWin(const QString &reason)
{
kDebug(1212) << "restarting kwin for:" << reason;
@ -1051,14 +1042,7 @@ void Workspace::slotReinitCompositing()
#ifdef KWIN_BUILD_SCREENEDGES
m_screenEdge.update();
#endif
// Restart compositing
finishCompositing();
// resume compositing if suspended
compositingSuspended = false;
options->setCompositingInitialized(false);
setupCompositing();
emit reinitializeCompositing();
if (hasDecorationPlugin()) {
KDecorationFactory* factory = mgr->factory();
factory->reset(SettingCompositing);
@ -1362,8 +1346,8 @@ bool Workspace::setCurrentDesktop(int new_desktop)
// s += QString::number( desktop_focus_chain[i] ) + ", ";
//kDebug( 1212 ) << s << "}\n";
if (compositing())
addRepaintFull();
if (compositing() && m_compositor)
m_compositor->addRepaintFull();
emit currentDesktopChanged(old_desktop, movingClient);
return true;
@ -1574,8 +1558,8 @@ void Workspace::updateCurrentActivity(const QString &new_activity)
//if ( effects != NULL && old_desktop != 0 && old_desktop != new_desktop )
// static_cast<EffectsHandlerImpl*>( effects )->desktopChanged( old_desktop );
if (compositing())
addRepaintFull();
if (compositing() && m_compositor)
m_compositor->addRepaintFull();
}
@ -2283,6 +2267,43 @@ QString Workspace::supportInformation() const
return support;
}
void Workspace::slotCompositingToggled()
{
// notify decorations that composition state has changed
if (hasDecorationPlugin()) {
KDecorationFactory* factory = mgr->factory();
factory->reset(SettingCompositing);
}
}
/*
* Called from D-BUS
*/
bool Workspace::compositingActive()
{
if (m_compositor) {
return m_compositor->compositingActive();
}
return false;
}
/*
* Called from D-BUS
*/
void Workspace::toggleCompositing()
{
if (m_compositor) {
m_compositor->toggleCompositing();
}
}
void Workspace::slotToggleCompositing()
{
if (m_compositor) {
m_compositor->slotToggleCompositing();
}
}
} // namespace
#include "workspace.moc"

View File

@ -80,6 +80,7 @@ class Rules;
class Scripting;
class UserActionsMenu;
class WindowRules;
class Compositor;
class Workspace : public QObject, public KDecorationDefines
{
@ -192,6 +193,18 @@ public:
const UnmanagedList &unmanagedList() const {
return unmanaged;
}
/**
* @return List of desktop "clients" currently managed by Workspace
**/
const ClientList &desktopList() const {
return desktops;
}
/**
* @return List of deleted "clients" currently managed by Workspace
**/
const DeletedList &deletedList() const {
return deleted;
}
Outline* outline();
#ifdef KWIN_BUILD_SCREENEDGES
@ -309,6 +322,7 @@ private:
ScreenEdge m_screenEdge;
Qt::Orientations m_screenEdgeOrientation;
#endif
Compositor *m_compositor;
//-------------------------------------------------
// Unsorted
@ -381,14 +395,12 @@ public:
// KDE4 remove me - And it's also in the DCOP interface :(
void showWindowMenuAt(unsigned long id, int x, int y);
void toggleCompositing();
void loadEffect(const QString& name);
void toggleEffect(const QString& name);
void reconfigureEffect(const QString& name);
void unloadEffect(const QString& name);
QString supportInformationForEffect(const QString& name) const;
void updateCompositeBlocking(Client* c = NULL);
QStringList loadedEffects() const;
QStringList listOfEffects() const;
@ -500,6 +512,7 @@ public:
void disableGlobalShortcuts(bool disable);
void disableGlobalShortcutsForClient(bool disable);
QPoint cursorPos() const;
void checkCursorPos();
void sessionSaveStarted();
void sessionSaveDone();
@ -518,30 +531,15 @@ public:
QPoint focusMousePosition() const;
void toggleTopDockShadows(bool on);
// 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);
void checkUnredirect(bool force = false);
void checkCompositeTimer();
// returns the _estimated_ delay to the next screen update
// good for having a rough idea to calculate transformations, bad to rely on.
// might happen few ms earlier, might be an entire frame to short. This is NOT deterministic.
int nextFrameDelay();
// Mouse polling
void startMousePolling();
void stopMousePolling();
Client* getMovingClient() {
return movingClient;
}
public slots:
void addRepaintFull();
Compositor* compositor() const {
return m_compositor;
}
public slots:
// Keybindings
void slotSwitchDesktopNext();
void slotSwitchDesktopPrevious();
@ -617,7 +615,7 @@ public slots:
void reconfigure();
void slotReconfigure();
void slotReinitCompositing();
void resetCompositing();
void slotCompositingToggled();
void slotKillWindow();
@ -627,8 +625,6 @@ public slots:
void slotInvertScreen();
void updateClientArea();
void suspendCompositing();
void suspendCompositing(bool suspend);
void slotActivateNextTab(); // Slot to move left the active Client.
void slotActivatePrevTab(); // Slot to move right the active Client.
@ -644,25 +640,13 @@ private slots:
void writeWindowRules();
void slotBlockShortcuts(int data);
void slotReloadConfig();
void setupCompositing();
/**
* Called from setupCompositing() when the CompositingPrefs are ready.
**/
void slotCompositingOptionsInitialized();
void finishCompositing();
void fallbackToXRenderCompositing();
void performCompositing();
void performMousePoll();
void lostCMSelection();
void resetCursorPosTime();
void delayedCheckUnredirect();
void updateCurrentActivity(const QString &new_activity);
void slotActivityRemoved(const QString &activity);
void slotActivityAdded(const QString &activity);
void reallyStopActivity(const QString &id); //dbus deadlocks suck
void handleActivityReply();
protected:
void timerEvent(QTimerEvent *te);
void slotRestartKwin(const QString &reason);
Q_SIGNALS:
Q_SCRIPTABLE void compositingToggled(bool active);
@ -689,6 +673,7 @@ signals:
Qt::KeyboardModifiers modifiers, Qt::KeyboardModifiers oldmodifiers);
void propertyNotify(long a);
void configChanged();
void reinitializeCompositing();
/**
* This signal is emitted when the global
* activity is changed
@ -712,7 +697,6 @@ private:
void initShortcuts();
void restartKWin(const QString &reason);
void setupWindowShortcut(Client* c);
void checkCursorPos();
enum Direction {
DirectionNorth,
DirectionEast,
@ -753,10 +737,6 @@ private:
void closeActivePopup();
void updateClientArea(bool force);
bool windowRepaintsPending() const;
void setCompositeTimer();
int m_timeSinceLastVBlank, m_nextFrameDelay;
typedef QHash< QString, QVector<int> > DesktopFocusChains;
DesktopFocusChains::Iterator m_desktopFocusChain;
DesktopFocusChains m_activitiesDesktopFocusChain;
@ -882,19 +862,8 @@ private:
bool forced_global_mouse_grab;
friend class StackingUpdatesBlocker;
KSelectionOwner* cm_selection;
bool compositingSuspended, compositingBlocked;
QBasicTimer compositeTimer;
QTimer mousePollingTimer;
uint vBlankInterval, fpsInterval;
int xrrRefreshRate; // used only for compositing
QRegion repaints_region;
QSlider* transSlider;
QPushButton* transButton;
QTimer unredirectTimer;
bool forceUnredirectCheck;
QTimer compositeResetTimer; // for compressing composite resets
bool m_finishingCompositing; // finishCompositing() sets this variable while shutting down
Scripting *m_scripting;
@ -1146,17 +1115,6 @@ inline bool Workspace::hasClient(const Client* c)
return findClient(ClientMatchPredicate(c));
}
inline void Workspace::checkCompositeTimer()
{
if (!compositeTimer.isActive())
setCompositeTimer();
}
inline int Workspace::nextFrameDelay()
{
return m_nextFrameDelay;
}
inline bool Workspace::hasDecorationPlugin() const
{
if (!mgr) {