rules: add window rule to force tearing on or off

This allows the user to override which presentation mode individual apps request
This commit is contained in:
Xaver Hugl 2024-07-06 15:37:35 +02:00
parent 1dab5fb328
commit 5316cf8d50
7 changed files with 68 additions and 38 deletions

View file

@ -329,7 +329,7 @@ void WaylandCompositor::composite(RenderLoop *renderLoop)
const bool wantsAdaptiveSync = activeWindow && activeWindow->isOnOutput(output) && activeWindow->wantsAdaptiveSync(); const bool wantsAdaptiveSync = activeWindow && activeWindow->isOnOutput(output) && activeWindow->wantsAdaptiveSync();
const bool vrr = (output->capabilities() & Output::Capability::Vrr) && (output->vrrPolicy() == VrrPolicy::Always || (output->vrrPolicy() == VrrPolicy::Automatic && 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; const bool tearing = (output->capabilities() & Output::Capability::Tearing) && options->allowTearing() && activeFullscreenItem && activeWindow->wantsTearing(activeFullscreenItem->presentationHint() == PresentationModeHint::Async);
if (vrr) { if (vrr) {
frame->setPresentationMode(tearing ? PresentationMode::AdaptiveAsync : PresentationMode::AdaptiveSync); frame->setPresentationMode(tearing ? PresentationMode::AdaptiveAsync : PresentationMode::AdaptiveSync);
} else { } else {

View file

@ -724,6 +724,11 @@ void RulesModel::populateRuleList()
RulePolicy::ForceRule, RuleItem::Boolean, RulePolicy::ForceRule, RuleItem::Boolean,
i18n("Adaptive Sync"), i18n("Appearance & Fixes"), i18n("Adaptive Sync"), i18n("Appearance & Fixes"),
QIcon::fromTheme("monitor-symbolic"))); QIcon::fromTheme("monitor-symbolic")));
addRule(new RuleItem(QLatin1String("tearing"),
RulePolicy::ForceRule, RuleItem::Boolean,
i18n("Allow Tearing"), i18n("Appearance & Fixes"),
QIcon::fromTheme("monitor-symbolic")));
} }
const QHash<QString, QString> RulesModel::x11PropertyHash() const QHash<QString, QString> RulesModel::x11PropertyHash()

View file

@ -76,6 +76,7 @@ Rules::Rules()
, disableglobalshortcutsrule(UnusedForceRule) , disableglobalshortcutsrule(UnusedForceRule)
, desktopfilerule(UnusedSetRule) , desktopfilerule(UnusedSetRule)
, adaptivesyncrule(UnusedForceRule) , adaptivesyncrule(UnusedForceRule)
, tearingrule(UnusedForceRule)
{ {
} }
@ -160,6 +161,7 @@ void Rules::readFromSettings(const RuleSettings *settings)
READ_SET_RULE(desktopfile); READ_SET_RULE(desktopfile);
READ_FORCE_RULE(layer, ); READ_FORCE_RULE(layer, );
READ_FORCE_RULE(adaptivesync, ); READ_FORCE_RULE(adaptivesync, );
READ_FORCE_RULE(tearing, );
} }
#undef READ_MATCH_STRING #undef READ_MATCH_STRING
@ -255,43 +257,44 @@ void Rules::write(RuleSettings *settings) const
// returns true if it doesn't affect anything // returns true if it doesn't affect anything
bool Rules::isEmpty() const bool Rules::isEmpty() const
{ {
return (placementrule == UnusedForceRule return placementrule == UnusedForceRule
&& positionrule == UnusedSetRule && positionrule == UnusedSetRule
&& sizerule == UnusedSetRule && sizerule == UnusedSetRule
&& minsizerule == UnusedForceRule && minsizerule == UnusedForceRule
&& maxsizerule == UnusedForceRule && maxsizerule == UnusedForceRule
&& opacityactiverule == UnusedForceRule && opacityactiverule == UnusedForceRule
&& opacityinactiverule == UnusedForceRule && opacityinactiverule == UnusedForceRule
&& ignoregeometryrule == UnusedSetRule && ignoregeometryrule == UnusedSetRule
&& desktopsrule == UnusedSetRule && desktopsrule == UnusedSetRule
&& screenrule == UnusedSetRule && screenrule == UnusedSetRule
&& activityrule == UnusedSetRule && activityrule == UnusedSetRule
&& maximizevertrule == UnusedSetRule && maximizevertrule == UnusedSetRule
&& maximizehorizrule == UnusedSetRule && maximizehorizrule == UnusedSetRule
&& minimizerule == UnusedSetRule && minimizerule == UnusedSetRule
&& shaderule == UnusedSetRule && shaderule == UnusedSetRule
&& skiptaskbarrule == UnusedSetRule && skiptaskbarrule == UnusedSetRule
&& skippagerrule == UnusedSetRule && skippagerrule == UnusedSetRule
&& skipswitcherrule == UnusedSetRule && skipswitcherrule == UnusedSetRule
&& aboverule == UnusedSetRule && aboverule == UnusedSetRule
&& belowrule == UnusedSetRule && belowrule == UnusedSetRule
&& fullscreenrule == UnusedSetRule && fullscreenrule == UnusedSetRule
&& noborderrule == UnusedSetRule && noborderrule == UnusedSetRule
&& decocolorrule == UnusedForceRule && decocolorrule == UnusedForceRule
&& blockcompositingrule == UnusedForceRule && blockcompositingrule == UnusedForceRule
&& fsplevelrule == UnusedForceRule && fsplevelrule == UnusedForceRule
&& fpplevelrule == UnusedForceRule && fpplevelrule == UnusedForceRule
&& acceptfocusrule == UnusedForceRule && acceptfocusrule == UnusedForceRule
&& closeablerule == UnusedForceRule && closeablerule == UnusedForceRule
&& autogrouprule == UnusedForceRule && autogrouprule == UnusedForceRule
&& autogroupfgrule == UnusedForceRule && autogroupfgrule == UnusedForceRule
&& autogroupidrule == UnusedForceRule && autogroupidrule == UnusedForceRule
&& strictgeometryrule == UnusedForceRule && strictgeometryrule == UnusedForceRule
&& shortcutrule == UnusedSetRule && shortcutrule == UnusedSetRule
&& disableglobalshortcutsrule == UnusedForceRule && disableglobalshortcutsrule == UnusedForceRule
&& desktopfilerule == UnusedSetRule && desktopfilerule == UnusedSetRule
&& layerrule == UnusedForceRule && layerrule == UnusedForceRule
&& adaptivesyncrule == UnusedForceRule); && adaptivesyncrule == UnusedForceRule
&& tearingrule == UnusedForceRule;
} }
Rules::ForceRule Rules::convertForceRule(int v) Rules::ForceRule Rules::convertForceRule(int v)
@ -686,6 +689,7 @@ APPLY_RULE(shortcut, Shortcut, QString)
APPLY_FORCE_RULE(disableglobalshortcuts, DisableGlobalShortcuts, bool) APPLY_FORCE_RULE(disableglobalshortcuts, DisableGlobalShortcuts, bool)
APPLY_RULE(desktopfile, DesktopFile, QString) APPLY_RULE(desktopfile, DesktopFile, QString)
APPLY_FORCE_RULE(adaptivesync, AdaptiveSync, bool) APPLY_FORCE_RULE(adaptivesync, AdaptiveSync, bool)
APPLY_FORCE_RULE(tearing, Tearing, bool)
#undef APPLY_RULE #undef APPLY_RULE
#undef APPLY_FORCE_RULE #undef APPLY_FORCE_RULE
@ -745,6 +749,7 @@ bool Rules::discardUsed(bool withdrawn)
DISCARD_USED_SET_RULE(desktopfile); DISCARD_USED_SET_RULE(desktopfile);
DISCARD_USED_FORCE_RULE(layer); DISCARD_USED_FORCE_RULE(layer);
DISCARD_USED_FORCE_RULE(adaptivesync); DISCARD_USED_FORCE_RULE(adaptivesync);
DISCARD_USED_FORCE_RULE(tearing);
return changed; return changed;
} }
@ -893,6 +898,7 @@ CHECK_FORCE_RULE(DisableGlobalShortcuts, bool)
CHECK_RULE(DesktopFile, QString) CHECK_RULE(DesktopFile, QString)
CHECK_FORCE_RULE(Layer, Layer) CHECK_FORCE_RULE(Layer, Layer)
CHECK_FORCE_RULE(AdaptiveSync, bool) CHECK_FORCE_RULE(AdaptiveSync, bool)
CHECK_FORCE_RULE(Tearing, bool)
#undef CHECK_RULE #undef CHECK_RULE
#undef CHECK_FORCE_RULE #undef CHECK_FORCE_RULE

View file

@ -78,6 +78,7 @@ public:
QString checkDesktopFile(QString desktopFile, bool init = false) const; QString checkDesktopFile(QString desktopFile, bool init = false) const;
Layer checkLayer(Layer layer) const; Layer checkLayer(Layer layer) const;
bool checkAdaptiveSync(bool adaptivesync) const; bool checkAdaptiveSync(bool adaptivesync) const;
bool checkTearing(bool requestsTearing) const;
private: private:
MaximizeMode checkMaximizeVert(MaximizeMode mode, bool init) const; MaximizeMode checkMaximizeVert(MaximizeMode mode, bool init) const;
@ -189,6 +190,7 @@ public:
bool applyDesktopFile(QString &desktopFile, bool init) const; bool applyDesktopFile(QString &desktopFile, bool init) const;
bool applyLayer(enum Layer &layer) const; bool applyLayer(enum Layer &layer) const;
bool applyAdaptiveSync(bool &adaptivesync) const; bool applyAdaptiveSync(bool &adaptivesync) const;
bool applyTearing(bool &tearing) const;
private: private:
#endif #endif
@ -295,6 +297,8 @@ private:
SetRule desktopfilerule; SetRule desktopfilerule;
bool adaptivesync; bool adaptivesync;
ForceRule adaptivesyncrule; ForceRule adaptivesyncrule;
bool tearing;
ForceRule tearingrule;
friend QDebug &operator<<(QDebug &stream, const Rules *); friend QDebug &operator<<(QDebug &stream, const Rules *);
}; };

View file

@ -450,5 +450,14 @@
<label>AdaptiveSync rule type</label> <label>AdaptiveSync rule type</label>
<default code="true">Rules::UnusedForceRule</default> <default code="true">Rules::UnusedForceRule</default>
</entry> </entry>
<entry name="tearing" type="Bool">
<label>Allow Tearing</label>
<default>true</default>
</entry>
<entry name="tearingrule" type="Int">
<label>Tearing rule type</label>
<default code="true">Rules::UnusedForceRule</default>
</entry>
</group> </group>
</kcfg> </kcfg>

View file

@ -4032,6 +4032,11 @@ bool Window::wantsAdaptiveSync() const
return rules()->checkAdaptiveSync(isFullScreen()); return rules()->checkAdaptiveSync(isFullScreen());
} }
bool Window::wantsTearing(bool tearingRequested) const
{
return rules()->checkTearing(tearingRequested);
}
/** /**
* Returns @c true if the Window can be minimized; otherwise @c false. * Returns @c true if the Window can be minimized; otherwise @c false.
* *

View file

@ -1004,6 +1004,7 @@ public:
virtual void setFullScreen(bool set); virtual void setFullScreen(bool set);
bool wantsAdaptiveSync() const; bool wantsAdaptiveSync() const;
bool wantsTearing(bool tearingRequested) const;
QRectF geometryRestore() const; QRectF geometryRestore() const;
void setGeometryRestore(const QRectF &rect); void setGeometryRestore(const QRectF &rect);