From 853020336f13af2d91f007ba7eccca3239d5e7a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Fri, 26 Aug 2016 08:56:42 +0200 Subject: [PATCH] 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 --- client.cpp | 2 +- kcmkwin/kwincompositing/compositing.cpp | 20 ++++++++++++ kcmkwin/kwincompositing/compositing.h | 5 +++ kcmkwin/kwincompositing/compositing.ui | 42 ++++++++++++------------- kcmkwin/kwincompositing/main.cpp | 5 +++ kwin.kcfg | 3 ++ options.cpp | 13 ++++++++ options.h | 9 ++++++ 8 files changed, 77 insertions(+), 22 deletions(-) diff --git a/client.cpp b/client.cpp index dc1765953..8542ba6be 100644 --- a/client.cpp +++ b/client.cpp @@ -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); } diff --git a/kcmkwin/kwincompositing/compositing.cpp b/kcmkwin/kwincompositing/compositing.cpp index 76ce6590c..5f0815b6e 100644 --- a/kcmkwin/kwincompositing/compositing.cpp +++ b/kcmkwin/kwincompositing/compositing.cpp @@ -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) { diff --git a/kcmkwin/kwincompositing/compositing.h b/kcmkwin/kwincompositing/compositing.h index 00dcb1507..e739b2531 100644 --- a/kcmkwin/kwincompositing/compositing.h +++ b/kcmkwin/kwincompositing/compositing.h @@ -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; }; diff --git a/kcmkwin/kwincompositing/compositing.ui b/kcmkwin/kwincompositing/compositing.ui index ef1343c06..0cc7a0f16 100644 --- a/kcmkwin/kwincompositing/compositing.ui +++ b/kcmkwin/kwincompositing/compositing.ui @@ -6,8 +6,8 @@ 0 0 - 481 - 349 + 462 + 377 @@ -21,19 +21,16 @@ false - + 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. - + true - - KMessageWidget::Warning - @@ -41,15 +38,12 @@ Alternatively, you might want to use the XRender backend instead. false - + Scale method "Accurate" is not supported by all hardware and can cause performance regressions and rendering artifacts. - + true - - KMessageWidget::Warning - @@ -57,12 +51,9 @@ Alternatively, you might want to use the XRender backend instead. false - + true - - KMessageWidget::Warning - @@ -70,15 +61,12 @@ Alternatively, you might want to use the XRender backend instead. false - + Keeping the window thumbnail always interferes with the minimized state of windows. This can result in windows not suspending their work when minimized. - + true - - KMessageWidget::Warning - @@ -295,6 +283,18 @@ Alternatively, you might want to use the XRender backend instead. + + + + 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. + + + Allow applications to block compositing + + + diff --git a/kcmkwin/kwincompositing/main.cpp b/kcmkwin/kwincompositing/main.cpp index 2d03829e1..cd4aac682 100644 --- a/kcmkwin/kwincompositing/main.cpp +++ b/kcmkwin/kwincompositing/main.cpp @@ -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); diff --git a/kwin.kcfg b/kwin.kcfg index 763482c7c..2b52ec46a 100644 --- a/kwin.kcfg +++ b/kwin.kcfg @@ -262,6 +262,9 @@ glx + + true + diff --git a/options.cpp b/options.cpp index 48daad54f..d195642db 100644 --- a/options.cpp +++ b/options.cpp @@ -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); diff --git a/options.h b/options.h index 7f4bb0e67..43ee0a6ad 100644 --- a/options.h +++ b/options.h @@ -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();