Introduce a config option whether applications are allowed to block compositing

Summary:
From feedback we got it seems that not all users agree to games and
other applications blocking compositing. Some users prefer to have
compositing always on even if this gives a small performance penelity.

This change introduces a dedicated config option to specify whether games
are allowed to block compositing. By default this option is enabled.

The setting can be overwritten with a window specific rule. So usecases
like all windows except this very specific one are supported.

In the user interface the config option is shown where previously the
unredirect fullscreen option was shown.

Test Plan:
Run a game which should block compositing, verified it blocks.
Changed the setting, run the game again, verified it doesn't block. And
once more for with allowing to block.

Reviewers: #kwin, #plasma_on_wayland, #vdg

Subscribers: plasma-devel, kwin

Tags: #plasma_on_wayland, #kwin

Differential Revision: https://phabricator.kde.org/D2584
icc-effect-5.14.5
Martin Gräßlin 2016-08-26 08:56:42 +02:00
parent c6a840413a
commit 853020336f
8 changed files with 77 additions and 22 deletions

View File

@ -1822,7 +1822,7 @@ bool Client::acceptsFocus() const
void Client::setBlockingCompositing(bool block)
{
const bool usedToBlock = blocks_compositing;
blocks_compositing = rules()->checkBlockCompositing(block);
blocks_compositing = rules()->checkBlockCompositing(block && options->windowsBlockCompositing());
if (usedToBlock != blocks_compositing) {
emit blockingCompositingChanged(blocks_compositing ? this : 0);
}

View File

@ -48,6 +48,7 @@ Compositing::Compositing(QObject *parent)
, m_changed(false)
, m_openGLPlatformInterfaceModel(new OpenGLPlatformInterfaceModel(this))
, m_openGLPlatformInterface(0)
, m_windowsBlockCompositing(true)
{
reset();
connect(this, &Compositing::animationSpeedChanged, this, &Compositing::changed);
@ -59,6 +60,7 @@ Compositing::Compositing(QObject *parent)
connect(this, &Compositing::compositingTypeChanged, this, &Compositing::changed);
connect(this, &Compositing::compositingEnabledChanged, this, &Compositing::changed);
connect(this, &Compositing::openGLPlatformInterfaceChanged, this, &Compositing::changed);
connect(this, &Compositing::windowsBlockCompositingChanged, this, &Compositing::changed);
connect(this, &Compositing::changed, [this]{
m_changed = true;
@ -112,6 +114,8 @@ void Compositing::reset()
const QModelIndex index = m_openGLPlatformInterfaceModel->indexForKey(kwinConfig.readEntry("GLPlatformInterface", "glx"));
setOpenGLPlatformInterface(index.isValid() ? index.row() : 0);
setWindowsBlockCompositing(kwinConfig.readEntry("WindowsBlockCompositing", true));
m_changed = false;
}
@ -126,6 +130,7 @@ void Compositing::defaults()
setCompositingType(CompositingType::OPENGL20_INDEX);
const QModelIndex index = m_openGLPlatformInterfaceModel->indexForKey(QStringLiteral("glx"));
setOpenGLPlatformInterface(index.isValid() ? index.row() : 0);
setWindowsBlockCompositing(true);
m_changed = true;
}
@ -324,6 +329,7 @@ void Compositing::save()
if (glIndex.isValid()) {
kwinConfig.writeEntry("GLPlatformInterface", glIndex.data(Qt::UserRole).toString());
}
kwinConfig.writeEntry("WindowsBlockCompositing", windowsBlockCompositing());
kwinConfig.sync();
if (m_changed) {
@ -355,6 +361,20 @@ void Compositing::setOpenGLPlatformInterface(int interface)
emit openGLPlatformInterfaceChanged(interface);
}
bool Compositing::windowsBlockCompositing() const
{
return m_windowsBlockCompositing;
}
void Compositing::setWindowsBlockCompositing(bool set)
{
if (m_windowsBlockCompositing == set) {
return;
}
m_windowsBlockCompositing = set;
emit windowsBlockCompositingChanged(set);
}
CompositingType::CompositingType(QObject *parent)
: QAbstractItemModel(parent) {

View File

@ -44,6 +44,7 @@ class Compositing : public QObject
Q_PROPERTY(bool compositingEnabled READ compositingEnabled WRITE setCompositingEnabled NOTIFY compositingEnabledChanged)
Q_PROPERTY(KWin::Compositing::OpenGLPlatformInterfaceModel *openGLPlatformInterfaceModel READ openGLPlatformInterfaceModel CONSTANT)
Q_PROPERTY(int openGLPlatformInterface READ openGLPlatformInterface WRITE setOpenGLPlatformInterface NOTIFY openGLPlatformInterfaceChanged)
Q_PROPERTY(bool windowsBlockCompositing READ windowsBlockCompositing WRITE setWindowsBlockCompositing NOTIFY windowsBlockCompositingChanged)
public:
explicit Compositing(QObject *parent = 0);
@ -59,6 +60,7 @@ public:
int compositingType() const;
bool compositingEnabled() const;
int openGLPlatformInterface() const;
bool windowsBlockCompositing() const;
OpenGLPlatformInterfaceModel *openGLPlatformInterfaceModel() const;
@ -71,6 +73,7 @@ public:
void setCompositingType(int index);
void setCompositingEnabled(bool enalbed);
void setOpenGLPlatformInterface(int interface);
void setWindowsBlockCompositing(bool set);
void save();
@ -89,6 +92,7 @@ Q_SIGNALS:
void compositingTypeChanged(int);
void compositingEnabledChanged(bool);
void openGLPlatformInterfaceChanged(int);
void windowsBlockCompositingChanged(bool);
private:
int m_animationSpeed;
@ -102,6 +106,7 @@ private:
bool m_changed;
OpenGLPlatformInterfaceModel *m_openGLPlatformInterfaceModel;
int m_openGLPlatformInterface;
bool m_windowsBlockCompositing;
};

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>481</width>
<height>349</height>
<width>462</width>
<height>377</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout">
@ -21,19 +21,16 @@
<property name="visible">
<bool>false</bool>
</property>
<property name="text">
<property name="text" stdset="0">
<string>OpenGL compositing (the default) has crashed KWin in the past.
This was most likely due to a driver bug.
If you think that you have meanwhile upgraded to a stable driver,
you can reset this protection but be aware that this might result in an immediate crash!
Alternatively, you might want to use the XRender backend instead.</string>
</property>
<property name="wordWrap">
<property name="wordWrap" stdset="0">
<bool>true</bool>
</property>
<property name="messageType">
<enum>KMessageWidget::Warning</enum>
</property>
</widget>
</item>
<item>
@ -41,15 +38,12 @@ Alternatively, you might want to use the XRender backend instead.</string>
<property name="visible">
<bool>false</bool>
</property>
<property name="text">
<property name="text" stdset="0">
<string>Scale method &quot;Accurate&quot; is not supported by all hardware and can cause performance regressions and rendering artifacts.</string>
</property>
<property name="wordWrap">
<property name="wordWrap" stdset="0">
<bool>true</bool>
</property>
<property name="messageType">
<enum>KMessageWidget::Warning</enum>
</property>
</widget>
</item>
<item>
@ -57,12 +51,9 @@ Alternatively, you might want to use the XRender backend instead.</string>
<property name="visible">
<bool>false</bool>
</property>
<property name="wordWrap">
<property name="wordWrap" stdset="0">
<bool>true</bool>
</property>
<property name="messageType">
<enum>KMessageWidget::Warning</enum>
</property>
</widget>
</item>
<item>
@ -70,15 +61,12 @@ Alternatively, you might want to use the XRender backend instead.</string>
<property name="visible">
<bool>false</bool>
</property>
<property name="text">
<property name="text" stdset="0">
<string>Keeping the window thumbnail always interferes with the minimized state of windows. This can result in windows not suspending their work when minimized.</string>
</property>
<property name="wordWrap">
<property name="wordWrap" stdset="0">
<bool>true</bool>
</property>
<property name="messageType">
<enum>KMessageWidget::Warning</enum>
</property>
</widget>
</item>
</layout>
@ -295,6 +283,18 @@ Alternatively, you might want to use the XRender backend instead.</string>
</property>
</widget>
</item>
<item row="13" column="1">
<widget class="QCheckBox" name="windowsBlockCompositing">
<property name="toolTip">
<string>Applications can set a hint to block compositing when the window is open.
This brings performance improvements for e.g. games.
The setting can be overruled by window-specific rules.</string>
</property>
<property name="text">
<string>Allow applications to block compositing</string>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>

View File

@ -169,6 +169,11 @@ void KWinCompositingSettings::init()
connect(m_compositing, &Compositing::glColorCorrectionChanged, m_form.colorCorrection, &QCheckBox::setChecked);
connect(m_form.colorCorrection, &QCheckBox::toggled, m_compositing, &Compositing::setGlColorCorrection);
// windows blocking compositing
m_form.windowsBlockCompositing->setChecked(m_compositing->windowsBlockCompositing());
connect(m_compositing, &Compositing::windowsBlockCompositingChanged, m_form.windowsBlockCompositing, &QCheckBox::setChecked);
connect(m_form.windowsBlockCompositing, &QCheckBox::toggled, m_compositing, &Compositing::setWindowsBlockCompositing);
// compositing type
CompositingType *type = new CompositingType(this);
m_form.type->setModel(type);

View File

@ -262,6 +262,9 @@
<entry name="GLPlatformInterface" type="String">
<default>glx</default>
</entry>
<entry name="WindowsBlockCompositing" type="Bool">
<default>true</default>
</entry>
</group>
<group name="TabBox">
<entry name="ShowDelay" type="Bool">

View File

@ -125,6 +125,7 @@ Options::Options(QObject *parent)
, m_glCoreProfile(Options::defaultGLCoreProfile())
, m_glPreferBufferSwap(Options::defaultGlPreferBufferSwap())
, m_glPlatformInterface(Options::defaultGlPlatformInterface())
, m_windowsBlockCompositing(true)
, OpTitlebarDblClick(Options::defaultOperationTitlebarDblClick())
, CmdActiveTitlebar1(Options::defaultCommandActiveTitlebar1())
, CmdActiveTitlebar2(Options::defaultCommandActiveTitlebar2())
@ -714,6 +715,15 @@ void Options::setGLCoreProfile(bool value)
emit glCoreProfileChanged();
}
void Options::setWindowsBlockCompositing(bool value)
{
if (m_windowsBlockCompositing == value) {
return;
}
m_windowsBlockCompositing = value;
emit windowsBlockCompositingChanged();
}
void Options::setGlPreferBufferSwap(char glPreferBufferSwap)
{
if (glPreferBufferSwap == 'a') {
@ -886,6 +896,7 @@ void Options::syncFromKcfgc()
setElectricBorderMaximize(m_settings->electricBorderMaximize());
setElectricBorderTiling(m_settings->electricBorderTiling());
setElectricBorderCornerRatio(m_settings->electricBorderCornerRatio());
setWindowsBlockCompositing(m_settings->windowsBlockCompositing());
}
@ -956,6 +967,8 @@ void Options::reloadCompositingSettings(bool force)
if (!loadCompositingConfig(force)) {
return;
}
m_settings->load();
syncFromKcfgc();
// from now on we've an initial setup and don't have to reload settings on compositing activation
// see Workspace::setupCompositing(), composite.cpp
setCompositingInitialized(true);

View File

@ -190,6 +190,7 @@ class KWIN_EXPORT Options : public QObject
Q_PROPERTY(bool glCoreProfile READ glCoreProfile WRITE setGLCoreProfile NOTIFY glCoreProfileChanged)
Q_PROPERTY(GlSwapStrategy glPreferBufferSwap READ glPreferBufferSwap WRITE setGlPreferBufferSwap NOTIFY glPreferBufferSwapChanged)
Q_PROPERTY(KWin::OpenGLPlatformInterface glPlatformInterface READ glPlatformInterface WRITE setGlPlatformInterface NOTIFY glPlatformInterfaceChanged)
Q_PROPERTY(bool windowsBlockCompositing READ windowsBlockCompositing WRITE setWindowsBlockCompositing NOTIFY windowsBlockCompositingChanged)
public:
explicit Options(QObject *parent = NULL);
@ -593,6 +594,11 @@ public:
return m_glPreferBufferSwap;
}
bool windowsBlockCompositing() const
{
return m_windowsBlockCompositing;
}
QStringList modifierOnlyDBusShortcut(Qt::KeyboardModifier mod) const;
// setters
@ -656,6 +662,7 @@ public:
void setGLCoreProfile(bool glCoreProfile);
void setGlPreferBufferSwap(char glPreferBufferSwap);
void setGlPlatformInterface(OpenGLPlatformInterface interface);
void setWindowsBlockCompositing(bool set);
// default values
static WindowOperation defaultOperationTitlebarDblClick() {
@ -848,6 +855,7 @@ Q_SIGNALS:
void glCoreProfileChanged();
void glPreferBufferSwapChanged();
void glPlatformInterfaceChanged();
void windowsBlockCompositingChanged();
void configChanged();
@ -897,6 +905,7 @@ private:
bool m_glCoreProfile;
GlSwapStrategy m_glPreferBufferSwap;
OpenGLPlatformInterface m_glPlatformInterface;
bool m_windowsBlockCompositing;
WindowOperation OpTitlebarDblClick;
WindowOperation opMaxButtonRightClick = defaultOperationMaxButtonRightClick();