diff --git a/src/compositor.cpp b/src/compositor.cpp index 71ab022364..634690bf2d 100644 --- a/src/compositor.cpp +++ b/src/compositor.cpp @@ -165,7 +165,8 @@ void Compositor::composite(RenderLoop *renderLoop) SurfaceItem *const activeFullscreenItem = activeWindow && activeWindow->isFullScreen() ? activeWindow->surfaceItem() : nullptr; frame->setContentType(activeWindow && activeFullscreenItem ? activeFullscreenItem->contentType() : ContentType::None); - const bool vrr = (output->capabilities() & Output::Capability::Vrr) && (output->vrrPolicy() == VrrPolicy::Always || (output->vrrPolicy() == VrrPolicy::Automatic && activeFullscreenItem)); + const bool wantsAdaptiveSync = activeWindow && activeWindow->wantsAdaptiveSync(); + const bool vrr = (output->capabilities() & Output::Capability::Vrr) && (output->vrrPolicy() == VrrPolicy::Always || (output->vrrPolicy() == VrrPolicy::Automatic && wantsAdaptiveSync)); const bool tearing = (output->capabilities() & Output::Capability::Tearing) && options->allowTearing() && activeFullscreenItem && activeFullscreenItem->presentationHint() == PresentationModeHint::Async; if (vrr) { frame->setPresentationMode(tearing ? PresentationMode::AdaptiveAsync : PresentationMode::AdaptiveSync); diff --git a/src/kcms/rules/rulesmodel.cpp b/src/kcms/rules/rulesmodel.cpp index 3bb1f4aa7d..c89c976f81 100644 --- a/src/kcms/rules/rulesmodel.cpp +++ b/src/kcms/rules/rulesmodel.cpp @@ -719,6 +719,11 @@ void RulesModel::populateRuleList() i18n("Layer"), i18n("Appearance & Fixes"), QIcon::fromTheme("view-sort"))); layer->setOptionsData(layerModelData()); + + addRule(new RuleItem(QLatin1String("adaptivesync"), + RulePolicy::ForceRule, RuleItem::Boolean, + i18n("Adaptive Sync"), i18n("Appearance & Fixes"), + QIcon::fromTheme("monitor-symbolic"))); } const QHash RulesModel::x11PropertyHash() diff --git a/src/rules.cpp b/src/rules.cpp index 3cb9a539c3..d58689a1ce 100644 --- a/src/rules.cpp +++ b/src/rules.cpp @@ -75,6 +75,7 @@ Rules::Rules() , shortcutrule(UnusedSetRule) , disableglobalshortcutsrule(UnusedForceRule) , desktopfilerule(UnusedSetRule) + , adaptivesyncrule(UnusedForceRule) { } @@ -157,6 +158,7 @@ void Rules::readFromSettings(const RuleSettings *settings) READ_FORCE_RULE(disableglobalshortcuts, ); READ_SET_RULE(desktopfile); READ_FORCE_RULE(layer, ); + READ_FORCE_RULE(adaptivesync, ); } #undef READ_MATCH_STRING @@ -235,6 +237,7 @@ void Rules::write(RuleSettings *settings) const WRITE_FORCE_RULE(disableglobalshortcuts, Disableglobalshortcuts, ); WRITE_SET_RULE(desktopfile, Desktopfile, ); WRITE_FORCE_RULE(layer, Layer, ); + WRITE_FORCE_RULE(adaptivesync, Adaptivesync, ); } #undef WRITE_MATCH_STRING @@ -279,7 +282,8 @@ bool Rules::isEmpty() const && shortcutrule == UnusedSetRule && disableglobalshortcutsrule == UnusedForceRule && desktopfilerule == UnusedSetRule - && layerrule == UnusedForceRule); + && layerrule == UnusedForceRule + && adaptivesyncrule == UnusedForceRule); } Rules::ForceRule Rules::convertForceRule(int v) @@ -637,6 +641,7 @@ APPLY_FORCE_RULE(strictgeometry, StrictGeometry, bool) APPLY_RULE(shortcut, Shortcut, QString) APPLY_FORCE_RULE(disableglobalshortcuts, DisableGlobalShortcuts, bool) APPLY_RULE(desktopfile, DesktopFile, QString) +APPLY_FORCE_RULE(adaptivesync, AdaptiveSync, bool) #undef APPLY_RULE #undef APPLY_FORCE_RULE @@ -695,6 +700,7 @@ bool Rules::discardUsed(bool withdrawn) DISCARD_USED_FORCE_RULE(disableglobalshortcuts); DISCARD_USED_SET_RULE(desktopfile); DISCARD_USED_FORCE_RULE(layer); + DISCARD_USED_FORCE_RULE(adaptivesync); return changed; } @@ -842,6 +848,7 @@ CHECK_RULE(Shortcut, QString) CHECK_FORCE_RULE(DisableGlobalShortcuts, bool) CHECK_RULE(DesktopFile, QString) CHECK_FORCE_RULE(Layer, Layer) +CHECK_FORCE_RULE(AdaptiveSync, bool) #undef CHECK_RULE #undef CHECK_FORCE_RULE diff --git a/src/rules.h b/src/rules.h index d55f3da9f7..c18c8701d0 100644 --- a/src/rules.h +++ b/src/rules.h @@ -77,6 +77,7 @@ public: bool checkDisableGlobalShortcuts(bool disable) const; QString checkDesktopFile(QString desktopFile, bool init = false) const; Layer checkLayer(Layer layer) const; + bool checkAdaptiveSync(bool adaptivesync) const; private: MaximizeMode checkMaximizeVert(MaximizeMode mode, bool init) const; @@ -185,6 +186,7 @@ public: bool applyDisableGlobalShortcuts(bool &disable) const; bool applyDesktopFile(QString &desktopFile, bool init) const; bool applyLayer(enum Layer &layer) const; + bool applyAdaptiveSync(bool &adaptivesync) const; private: #endif @@ -288,6 +290,8 @@ private: ForceRule disableglobalshortcutsrule; QString desktopfile; SetRule desktopfilerule; + bool adaptivesync; + ForceRule adaptivesyncrule; friend QDebug &operator<<(QDebug &stream, const Rules *); }; diff --git a/src/rulesettings.kcfg b/src/rulesettings.kcfg index dabaec6e96..67cf4f7f38 100644 --- a/src/rulesettings.kcfg +++ b/src/rulesettings.kcfg @@ -441,5 +441,14 @@ Rules::UnusedForceRule + + + + true + + + + Rules::UnusedForceRule + diff --git a/src/window.cpp b/src/window.cpp index 620efe09f0..361b8c7e40 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -3954,6 +3954,11 @@ void Window::setFullScreen(bool set) qCWarning(KWIN_CORE, "%s doesn't support setting fullscreen state", metaObject()->className()); } +bool Window::wantsAdaptiveSync() const +{ + return rules()->checkAdaptiveSync(isFullScreen()); +} + /** * Returns @c true if the Window can be minimized; otherwise @c false. * diff --git a/src/window.h b/src/window.h index 1f6040b207..160cc0f061 100644 --- a/src/window.h +++ b/src/window.h @@ -1000,6 +1000,8 @@ public: virtual bool isRequestedFullScreen() const; virtual void setFullScreen(bool set); + bool wantsAdaptiveSync() const; + QRectF geometryRestore() const; virtual bool isMaximizable() const; virtual MaximizeMode maximizeMode() const;