Delay releasing the compositor selection
When turning off the compositor do not release the compositor selection directly but delay it through a timer. The idea is that the internal change when e.g. restarting the compositor or switching from XRender to OpenGL should not be visible to the outside world. This hopefully makes restarting the compositor more robust in Plasma due to the SelectionWatcher sometimes reporting incorrect results. When restarting KWin the change does not matter as the selection gets force claimed by the new instance anyway. CCBUG: 179042 REVIEW: 106844
This commit is contained in:
parent
aa34dbd059
commit
986d9e5613
2 changed files with 45 additions and 5 deletions
|
@ -118,6 +118,11 @@ Compositor::Compositor(QObject* workspace)
|
||||||
unredirectTimer.setSingleShot(true);
|
unredirectTimer.setSingleShot(true);
|
||||||
compositeResetTimer.setSingleShot(true);
|
compositeResetTimer.setSingleShot(true);
|
||||||
nextPaintReference.invalidate(); // Initialize the timer
|
nextPaintReference.invalidate(); // Initialize the timer
|
||||||
|
|
||||||
|
m_releaseSelectionTimer.setSingleShot(true);
|
||||||
|
// 2 sec which should be enough to restart the compositor
|
||||||
|
m_releaseSelectionTimer.setInterval(2000);
|
||||||
|
connect(&m_releaseSelectionTimer, SIGNAL(timeout()), SLOT(releaseCompositorSelection()));
|
||||||
// delay the call to setup by one event cycle
|
// delay the call to setup by one event cycle
|
||||||
// The ctor of this class is invoked from the Workspace ctor, that means before
|
// The ctor of this class is invoked from the Workspace ctor, that means before
|
||||||
// Workspace is completely constructed, so calling Workspace::self() would result
|
// Workspace is completely constructed, so calling Workspace::self() would result
|
||||||
|
@ -128,6 +133,7 @@ Compositor::Compositor(QObject* workspace)
|
||||||
Compositor::~Compositor()
|
Compositor::~Compositor()
|
||||||
{
|
{
|
||||||
finish();
|
finish();
|
||||||
|
delete cm_selection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -142,6 +148,7 @@ void Compositor::setup()
|
||||||
kError(1212) << "Compositing is not possible";
|
kError(1212) << "Compositing is not possible";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
m_starting = true;
|
||||||
|
|
||||||
if (!options->isCompositingInitialized()) {
|
if (!options->isCompositingInitialized()) {
|
||||||
#ifndef KWIN_HAVE_OPENGLES
|
#ifndef KWIN_HAVE_OPENGLES
|
||||||
|
@ -166,8 +173,10 @@ void Compositor::slotCompositingOptionsInitialized()
|
||||||
{
|
{
|
||||||
char selection_name[ 100 ];
|
char selection_name[ 100 ];
|
||||||
sprintf(selection_name, "_NET_WM_CM_S%d", DefaultScreen(display()));
|
sprintf(selection_name, "_NET_WM_CM_S%d", DefaultScreen(display()));
|
||||||
cm_selection = new KSelectionOwner(selection_name);
|
if (!cm_selection) {
|
||||||
connect(cm_selection, SIGNAL(lostOwnership()), SLOT(finish()));
|
cm_selection = new KSelectionOwner(selection_name);
|
||||||
|
connect(cm_selection, SIGNAL(lostOwnership()), SLOT(finish()));
|
||||||
|
}
|
||||||
cm_selection->claim(true); // force claiming
|
cm_selection->claim(true); // force claiming
|
||||||
|
|
||||||
switch(options->compositingMode()) {
|
switch(options->compositingMode()) {
|
||||||
|
@ -214,7 +223,8 @@ void Compositor::slotCompositingOptionsInitialized()
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
kDebug(1212) << "No compositing enabled";
|
kDebug(1212) << "No compositing enabled";
|
||||||
delete cm_selection;
|
m_starting = false;
|
||||||
|
cm_selection->release();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (m_scene == NULL || m_scene->initFailed()) {
|
if (m_scene == NULL || m_scene->initFailed()) {
|
||||||
|
@ -222,7 +232,8 @@ void Compositor::slotCompositingOptionsInitialized()
|
||||||
kError(1212) << "Consult http://techbase.kde.org/Projects/KWin/4.0-release-notes#Setting_up";
|
kError(1212) << "Consult http://techbase.kde.org/Projects/KWin/4.0-release-notes#Setting_up";
|
||||||
delete m_scene;
|
delete m_scene;
|
||||||
m_scene = NULL;
|
m_scene = NULL;
|
||||||
delete cm_selection;
|
m_starting = false;
|
||||||
|
cm_selection->release();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_xrrRefreshRate = KWin::currentRefreshRate();
|
m_xrrRefreshRate = KWin::currentRefreshRate();
|
||||||
|
@ -247,6 +258,11 @@ void Compositor::slotCompositingOptionsInitialized()
|
||||||
|
|
||||||
emit compositingToggled(true);
|
emit compositingToggled(true);
|
||||||
|
|
||||||
|
m_starting = false;
|
||||||
|
if (m_releaseSelectionTimer.isActive()) {
|
||||||
|
m_releaseSelectionTimer.stop();
|
||||||
|
}
|
||||||
|
|
||||||
// render at least once
|
// render at least once
|
||||||
compositeTimer.stop();
|
compositeTimer.stop();
|
||||||
performCompositing();
|
performCompositing();
|
||||||
|
@ -263,7 +279,7 @@ void Compositor::finish()
|
||||||
if (!hasScene())
|
if (!hasScene())
|
||||||
return;
|
return;
|
||||||
m_finishing = true;
|
m_finishing = true;
|
||||||
delete cm_selection;
|
m_releaseSelectionTimer.start();
|
||||||
foreach (Client * c, Workspace::self()->clientList())
|
foreach (Client * c, Workspace::self()->clientList())
|
||||||
m_scene->windowClosed(c, NULL);
|
m_scene->windowClosed(c, NULL);
|
||||||
foreach (Client * c, Workspace::self()->desktopList())
|
foreach (Client * c, Workspace::self()->desktopList())
|
||||||
|
@ -304,6 +320,27 @@ void Compositor::finish()
|
||||||
emit compositingToggled(false);
|
emit compositingToggled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Compositor::releaseCompositorSelection()
|
||||||
|
{
|
||||||
|
if (hasScene() && !m_finishing) {
|
||||||
|
// compositor is up and running again, no need to release the selection
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (m_starting) {
|
||||||
|
// currently still starting the compositor, it might fail, so restart the timer to test again
|
||||||
|
m_releaseSelectionTimer.start();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_finishing) {
|
||||||
|
// still shutting down, a restart might follow, so restart the timer to test again
|
||||||
|
m_releaseSelectionTimer.start();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
kDebug(1212) << "Releasing compositor selection";
|
||||||
|
cm_selection->release();
|
||||||
|
}
|
||||||
|
|
||||||
// OpenGL self-check failed, fallback to XRender
|
// OpenGL self-check failed, fallback to XRender
|
||||||
void Compositor::fallbackToXRenderCompositing()
|
void Compositor::fallbackToXRenderCompositing()
|
||||||
{
|
{
|
||||||
|
|
|
@ -275,6 +275,7 @@ private Q_SLOTS:
|
||||||
void performMousePoll();
|
void performMousePoll();
|
||||||
void delayedCheckUnredirect();
|
void delayedCheckUnredirect();
|
||||||
void slotConfigChanged();
|
void slotConfigChanged();
|
||||||
|
void releaseCompositorSelection();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Compositor(QObject *workspace);
|
Compositor(QObject *workspace);
|
||||||
|
@ -298,6 +299,7 @@ private:
|
||||||
bool m_blocked;
|
bool m_blocked;
|
||||||
QBasicTimer compositeTimer;
|
QBasicTimer compositeTimer;
|
||||||
KSelectionOwner* cm_selection;
|
KSelectionOwner* cm_selection;
|
||||||
|
QTimer m_releaseSelectionTimer;
|
||||||
uint vBlankInterval, fpsInterval;
|
uint vBlankInterval, fpsInterval;
|
||||||
int m_xrrRefreshRate;
|
int m_xrrRefreshRate;
|
||||||
QElapsedTimer nextPaintReference;
|
QElapsedTimer nextPaintReference;
|
||||||
|
@ -308,6 +310,7 @@ private:
|
||||||
bool forceUnredirectCheck;
|
bool forceUnredirectCheck;
|
||||||
QTimer compositeResetTimer; // for compressing composite resets
|
QTimer compositeResetTimer; // for compressing composite resets
|
||||||
bool m_finishing; // finish() sets this variable while shutting down
|
bool m_finishing; // finish() sets this variable while shutting down
|
||||||
|
bool m_starting; // start() sets this variable while starting
|
||||||
int m_timeSinceLastVBlank, m_nextFrameDelay;
|
int m_timeSinceLastVBlank, m_nextFrameDelay;
|
||||||
Scene *m_scene;
|
Scene *m_scene;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue