32 bit compositing suspension
REVIEW: 108304 BUG: 308438
This commit is contained in:
parent
31f20cb4b1
commit
c8e2b61f48
2 changed files with 40 additions and 37 deletions
|
@ -53,6 +53,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include <xcb/composite.h>
|
||||
#include <xcb/damage.h>
|
||||
|
||||
Q_DECLARE_METATYPE(KWin::Compositor::SuspendReason)
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
|
@ -68,8 +70,7 @@ Compositor *Compositor::createCompositor(QObject *parent)
|
|||
|
||||
Compositor::Compositor(QObject* workspace)
|
||||
: QObject(workspace)
|
||||
, m_suspended(!options->isUseCompositing())
|
||||
, m_blocked(false)
|
||||
, m_suspended(options->isUseCompositing() ? NoReasonSuspend : UserSuspend)
|
||||
, cm_selection(NULL)
|
||||
, vBlankInterval(0)
|
||||
, fpsInterval(0)
|
||||
|
@ -80,6 +81,7 @@ Compositor::Compositor(QObject* workspace)
|
|||
, m_nextFrameDelay(0)
|
||||
, m_scene(NULL)
|
||||
{
|
||||
qRegisterMetaType<Compositor::SuspendReason>("Compositor::SuspendReason");
|
||||
new CompositingAdaptor(this);
|
||||
QDBusConnection dbus = QDBusConnection::sessionBus();
|
||||
dbus.registerObject("/Compositor", this);
|
||||
|
@ -116,7 +118,7 @@ void Compositor::setup()
|
|||
if (hasScene())
|
||||
return;
|
||||
if (m_suspended) {
|
||||
kDebug(1212) << "Compositing is suspended";
|
||||
kDebug(1212) << "Compositing is suspended, reason:" << m_suspended;
|
||||
return;
|
||||
} else if (!CompositingPrefs::compositingPossible()) {
|
||||
kError(1212) << "Compositing is not possible";
|
||||
|
@ -365,7 +367,7 @@ void Compositor::slotReinitialize()
|
|||
// Restart compositing
|
||||
finish();
|
||||
// resume compositing if suspended
|
||||
m_suspended = false;
|
||||
m_suspended = NoReasonSuspend;
|
||||
options->setCompositingInitialized(false);
|
||||
setup();
|
||||
|
||||
|
@ -377,13 +379,17 @@ void Compositor::slotReinitialize()
|
|||
// for the shortcut
|
||||
void Compositor::slotToggleCompositing()
|
||||
{
|
||||
setCompositing(m_suspended);
|
||||
if (m_suspended) { // direct user call; clear all bits
|
||||
resume(AllReasonSuspend);
|
||||
} else { // but only set the user one (sufficient to suspend)
|
||||
suspend(UserSuspend);
|
||||
}
|
||||
}
|
||||
|
||||
// for the dbus call
|
||||
void Compositor::toggleCompositing()
|
||||
{
|
||||
slotToggleCompositing();
|
||||
slotToggleCompositing(); // TODO only operate on script level here?
|
||||
if (m_suspended) {
|
||||
// when disabled show a shortcut how the user can get back compositing
|
||||
QString shortcut, message;
|
||||
|
@ -407,14 +413,11 @@ void Compositor::updateCompositeBlocking(Client *c)
|
|||
{
|
||||
if (c) { // if c == 0 we just check if we can resume
|
||||
if (c->isBlockingCompositing()) {
|
||||
if (!m_blocked) // do NOT attempt to call suspend(true); from within the eventchain!
|
||||
QMetaObject::invokeMethod(this, "suspend", Qt::QueuedConnection);
|
||||
m_blocked = true;
|
||||
if (!(m_suspended & BlockRuleSuspend)) // do NOT attempt to call suspend(true); from within the eventchain!
|
||||
QMetaObject::invokeMethod(this, "suspend", Qt::QueuedConnection, Q_ARG(Compositor::SuspendReason, BlockRuleSuspend));
|
||||
}
|
||||
}
|
||||
else if (m_blocked) { // lost a client and we're blocked - can we resume?
|
||||
// NOTICE do NOT check for "m_Suspended" or "!compositing()"
|
||||
// only "resume" if it was really disabled for a block
|
||||
else if (m_suspended & BlockRuleSuspend) { // lost a client and we're blocked - can we resume?
|
||||
bool resume = true;
|
||||
for (ClientList::ConstIterator it = Workspace::self()->clientList().constBegin(); it != Workspace::self()->clientList().constEnd(); ++it) {
|
||||
if ((*it)->isBlockingCompositing()) {
|
||||
|
@ -423,38 +426,31 @@ void Compositor::updateCompositeBlocking(Client *c)
|
|||
}
|
||||
}
|
||||
if (resume) { // do NOT attempt to call suspend(false); from within the eventchain!
|
||||
m_blocked = false;
|
||||
if (m_suspended)
|
||||
QMetaObject::invokeMethod(this, "resume", Qt::QueuedConnection);
|
||||
QMetaObject::invokeMethod(this, "resume", Qt::QueuedConnection, Q_ARG(Compositor::SuspendReason, BlockRuleSuspend));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Compositor::suspend()
|
||||
void Compositor::suspend(Compositor::SuspendReason reason)
|
||||
{
|
||||
if (m_suspended) {
|
||||
return;
|
||||
}
|
||||
m_suspended = true;
|
||||
Q_ASSERT(reason != NoReasonSuspend);
|
||||
m_suspended |= reason;
|
||||
finish();
|
||||
}
|
||||
|
||||
void Compositor::resume()
|
||||
void Compositor::resume(Compositor::SuspendReason reason)
|
||||
{
|
||||
if (!m_suspended && hasScene()) {
|
||||
return;
|
||||
}
|
||||
m_suspended = false;
|
||||
// signal toggled is eventually emitted from within setup
|
||||
setup();
|
||||
Q_ASSERT(reason != NoReasonSuspend);
|
||||
m_suspended &= ~reason;
|
||||
setup(); // signal "toggled" is eventually emitted from within setup
|
||||
}
|
||||
|
||||
void Compositor::setCompositing(bool active)
|
||||
{
|
||||
if (active) {
|
||||
resume();
|
||||
resume(ScriptSuspend);
|
||||
} else {
|
||||
suspend();
|
||||
suspend(ScriptSuspend);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
23
composite.h
23
composite.h
|
@ -66,6 +66,8 @@ class Compositor : public QObject {
|
|||
**/
|
||||
Q_PROPERTY(QString compositingType READ compositingType)
|
||||
public:
|
||||
enum SuspendReason { NoReasonSuspend = 0, UserSuspend = 1<<0, BlockRuleSuspend = 1<<1, ScriptSuspend = 1<<2, AllReasonSuspend = 0xff };
|
||||
Q_DECLARE_FLAGS(SuspendReasons, SuspendReason)
|
||||
~Compositor();
|
||||
// when adding repaints caused by a window, you probably want to use
|
||||
// either Toplevel::addRepaint() or Toplevel::addWorkspaceRepaint()
|
||||
|
@ -186,7 +188,8 @@ public Q_SLOTS:
|
|||
* @see resume
|
||||
* @see isActive
|
||||
**/
|
||||
Q_SCRIPTABLE void suspend();
|
||||
Q_SCRIPTABLE inline void suspend() { suspend(ScriptSuspend); }
|
||||
void suspend(Compositor::SuspendReason reason);
|
||||
/**
|
||||
* @brief Resumes the Compositor if it is currently suspended.
|
||||
*
|
||||
|
@ -204,7 +207,8 @@ public Q_SLOTS:
|
|||
* @see isCompositingPossible
|
||||
* @see isOpenGLBroken
|
||||
**/
|
||||
Q_SCRIPTABLE void resume();
|
||||
Q_SCRIPTABLE inline void resume() { resume(ScriptSuspend); }
|
||||
void resume(Compositor::SuspendReason reason);
|
||||
/**
|
||||
* @brief Tries to suspend or resume the Compositor based on @p active.
|
||||
*
|
||||
|
@ -218,6 +222,10 @@ public Q_SLOTS:
|
|||
* Note: The starting of the Compositor can require some time and is partially done threaded.
|
||||
* After this method returns the setup may not have been completed.
|
||||
*
|
||||
* Note: This function only impacts whether compositing is suspended or resumed by scripts
|
||||
* or dbus calls. Compositing may be suspended for user will or a window rule - no matter how
|
||||
* often you call this function!
|
||||
*
|
||||
* @param active Whether the Compositor should be resumed (@c true) or suspended (@c false)
|
||||
* @return void
|
||||
* @see suspend
|
||||
|
@ -226,6 +234,8 @@ public Q_SLOTS:
|
|||
* @see isCompositingPossible
|
||||
* @see isOpenGLBroken
|
||||
**/
|
||||
// NOTICE this is atm. for script usage *ONLY* and needs to be extended like resume / suspend are
|
||||
// if intended to be used from within KWin code!
|
||||
Q_SCRIPTABLE void setCompositing(bool active);
|
||||
/**
|
||||
* Actual slot to perform the toggling compositing.
|
||||
|
@ -289,13 +299,10 @@ private:
|
|||
void restartKWin(const QString &reason);
|
||||
|
||||
/**
|
||||
* Whether the Compositor is currently suspended.
|
||||
* Whether the Compositor is currently suspended, 8 bits encoding the reason
|
||||
**/
|
||||
bool m_suspended;
|
||||
/**
|
||||
* Whether the Compositor is currently blocked by at least one Client requesting full resources.
|
||||
**/
|
||||
bool m_blocked;
|
||||
SuspendReasons m_suspended;
|
||||
|
||||
QBasicTimer compositeTimer;
|
||||
KSelectionOwner* cm_selection;
|
||||
QTimer m_releaseSelectionTimer;
|
||||
|
|
Loading…
Reference in a new issue