Fix issues with smooth follow when used with zoomOnFocus, and updates to the follow threshold

This commit is contained in:
wheaney 2025-09-18 12:17:36 -07:00
parent 6ec42f6fec
commit 994dd4e648
5 changed files with 44 additions and 28 deletions

View File

@ -211,20 +211,23 @@ void BreezyDesktopEffect::reconfigure(ReconfigureFlags)
setAllDisplaysDistance(BreezyDesktopConfig::allDisplaysDistance() / 100.0f);
setDisplaySpacing(BreezyDesktopConfig::displaySpacing() / 1000.0f);
setZoomOnFocusEnabled(BreezyDesktopConfig::zoomOnFocusEnabled());
setSmoothFollowThreshold(BreezyDesktopConfig::smoothFollowThreshold());
qreal horiz = BreezyDesktopConfig::displayHorizontalOffset() / 100.0f;
qreal vert = BreezyDesktopConfig::displayVerticalOffset() / 100.0f;
bool offsetchanged = false;
if (!qFuzzyCompare(m_displayHorizontalOffset, horiz)) { m_displayHorizontalOffset = horiz; offsetchanged = true; }
if (!qFuzzyCompare(m_displayVerticalOffset, vert)) { m_displayVerticalOffset = vert; offsetchanged = true; }
if (offsetchanged) Q_EMIT displayOffsetChanged();
int wrap = BreezyDesktopConfig::displayWrappingScheme();
int aaQuality = BreezyDesktopConfig::antialiasingQuality();
bool removeVD = BreezyDesktopConfig::removeVirtualDisplaysOnDisable();
bool mirrorPhysicalDisplays = BreezyDesktopConfig::mirrorPhysicalDisplays();
bool changed = false;
if (!qFuzzyCompare(m_displayHorizontalOffset, horiz)) { m_displayHorizontalOffset = horiz; changed = true; }
if (!qFuzzyCompare(m_displayVerticalOffset, vert)) { m_displayVerticalOffset = vert; changed = true; }
if (m_displayWrappingScheme != wrap) { m_displayWrappingScheme = wrap; Q_EMIT displayWrappingSchemeChanged(); }
if (m_antialiasingQuality != aaQuality) { m_antialiasingQuality = aaQuality; Q_EMIT antialiasingQualityChanged(); }
if (m_removeVirtualDisplaysOnDisable != removeVD) { m_removeVirtualDisplaysOnDisable = removeVD; Q_EMIT removeVirtualDisplaysOnDisableChanged(); }
if (m_mirrorPhysicalDisplays != mirrorPhysicalDisplays) { m_mirrorPhysicalDisplays = mirrorPhysicalDisplays; Q_EMIT mirrorPhysicalDisplaysChanged(); }
if (changed) Q_EMIT displayOffsetChanged();
}
QVariantMap BreezyDesktopEffect::initialProperties(Output *screen)
@ -432,7 +435,7 @@ void BreezyDesktopEffect::setFocusedDisplayDistance(qreal distance) {
m_focusedDisplayDistance = std::clamp(distance, 0.2, m_allDisplaysDistance);
Q_EMIT focusedDisplayDistanceChanged();
if (m_smoothFollowEnabled) updateDriverDisplayDistance(m_focusedDisplayDistance);
if (m_smoothFollowEnabled) updateDriverSmoothFollowSettings();
}
}
@ -674,13 +677,24 @@ void BreezyDesktopEffect::updateImuRotation() {
m_smoothFollowEnabled = nextSmoothFollowEnabled;
Q_EMIT smoothFollowEnabledChanged();
if (nextSmoothFollowEnabled) updateDriverDisplayDistance(m_focusedDisplayDistance);
} else if (enabled && !wasEnabled) Q_EMIT smoothFollowEnabledChanged();
if (nextSmoothFollowEnabled) updateDriverSmoothFollowSettings();
} else if (enabled && !wasEnabled) {
Q_EMIT smoothFollowEnabledChanged();
if (nextSmoothFollowEnabled) updateDriverSmoothFollowSettings();
}
}
void BreezyDesktopEffect::updateDriverDisplayDistance(float distance) {
void BreezyDesktopEffect::setSmoothFollowThreshold(float threshold) {
if (m_smoothFollowThreshold != threshold) {
m_smoothFollowThreshold = threshold;
if (m_smoothFollowEnabled) updateDriverSmoothFollowSettings();
}
}
void BreezyDesktopEffect::updateDriverSmoothFollowSettings() {
QJsonObject flags;
flags.insert(QStringLiteral("breezy_desktop_display_distance"), distance);
flags.insert(QStringLiteral("breezy_desktop_display_distance"), m_focusedDisplayDistance);
flags.insert(QStringLiteral("breezy_desktop_follow_threshold"), m_smoothFollowThreshold);
XRDriverIPC::instance().writeControlFlags(flags);
}

View File

@ -133,7 +133,8 @@ namespace KWin
std::function<void()> triggeredFunc);
void recenter();
void toggleSmoothFollow();
void updateDriverDisplayDistance(float distance);
void setSmoothFollowThreshold(float threshold);
void updateDriverSmoothFollowSettings();
QString m_cursorImageSource;
QSize m_cursorImageSize;
@ -166,6 +167,7 @@ namespace KWin
int m_antialiasingQuality = 3; // 0=None, 1=Medium, 2=High, 3=VeryHigh
bool m_removeVirtualDisplaysOnDisable = true;
bool m_mirrorPhysicalDisplays = false;
float m_smoothFollowThreshold = 1.0f;
struct VirtualOutputInfo {
Output *output = nullptr;

View File

@ -116,7 +116,7 @@ BreezyDesktopEffectConfig::BreezyDesktopEffectConfig(QObject *parent, const KPlu
connect(ui.kcfg_FocusedDisplayDistance, &QSlider::valueChanged, this, &BreezyDesktopEffectConfig::save);
connect(ui.kcfg_AllDisplaysDistance, &QSlider::valueChanged, this, &BreezyDesktopEffectConfig::save);
connect(ui.kcfg_DisplaySpacing, &QSlider::valueChanged, this, &BreezyDesktopEffectConfig::save);
connect(ui.kcfg_SmoothFollowThreshold, &QSlider::valueChanged, this, &BreezyDesktopEffectConfig::updateSmoothFollowThreshold);
connect(ui.kcfg_SmoothFollowThreshold, &QSlider::valueChanged, this, &BreezyDesktopEffectConfig::save);
connect(ui.kcfg_DisplayHorizontalOffset, &QSlider::valueChanged, this, &BreezyDesktopEffectConfig::save);
connect(ui.kcfg_DisplayVerticalOffset, &QSlider::valueChanged, this, &BreezyDesktopEffectConfig::save);
connect(ui.kcfg_LookAheadOverride, &QSlider::valueChanged, this, &BreezyDesktopEffectConfig::save);
@ -519,14 +519,6 @@ void BreezyDesktopEffectConfig::updateSmoothFollowEnabled()
XRDriverIPC::instance().writeControlFlags(flags);
}
void BreezyDesktopEffectConfig::updateSmoothFollowThreshold()
{
BreezyDesktopEffectConfig::save();
QJsonObject flags;
flags.insert(QStringLiteral("breezy_desktop_follow_threshold"), ui.kcfg_SmoothFollowThreshold->value());
XRDriverIPC::instance().writeControlFlags(flags);
}
void BreezyDesktopEffectConfig::showStatus(QLabel *label, bool success, const QString &message) {
if (!label) return;
QPalette pal = label->palette();

View File

@ -31,7 +31,6 @@ private:
void updateDriverEnabled();
void updateMultitapEnabled();
void updateSmoothFollowEnabled();
void updateSmoothFollowThreshold();
void updateUiFromConfig();
void updateUiFromDefaultConfig();
void updateConfigFromUi();

View File

@ -46,12 +46,12 @@ Node {
if (smoothFollowEnabledChanged) {
let targetDisplay;
let targetProgress;
if (focusedIndex !== -1) {
if (smoothFollowEnabled && focusedIndex !== -1) {
focusedDisplay = breezyDesktop.displayAtIndex(focusedIndex);
targetDisplay = focusedDisplay;
targetProgress = 1.0;
startSmoothFollowFocusAnimation = true;
} else if (breezyDesktop.focusedMonitorIndex !== -1) {
} else if (!smoothFollowEnabled && breezyDesktop.focusedMonitorIndex !== -1) {
unfocusedDisplay = breezyDesktop.displayAtIndex(breezyDesktop.focusedMonitorIndex);
targetDisplay = unfocusedDisplay;
targetProgress = 0.0;
@ -126,9 +126,6 @@ Node {
const displayEus = displayEusVector(display);
// short circuit to avoid slerping if not needed
if (display.smoothFollowTransitionProgress === 0.0) {
return displayRotationVector(display, displayEus);
}
if (display.smoothFollowTransitionProgress === 1.0) {
return displaySmoothFollowVector(display, displayEus, smoothFollowRotation);
}
@ -197,17 +194,29 @@ Node {
let continueRunning = false;
const focusedDisplay = breezyDesktop.smoothFollowFocusedDisplay;
if (focusedDisplay) {
const smoothFollowRotation = smoothFollowQuat();
focusedDisplay.position = displayPosition(focusedDisplay, smoothFollowRotation);
continueRunning = focusedDisplay.smoothFollowTransitionProgress > 0.0;
if (continueRunning) {
const smoothFollowRotation = smoothFollowQuat();
focusedDisplay.eulerRotation = Qt.vector3d(0, 0, 0);
focusedDisplay.rotation = smoothFollowRotation;
// When smooth follow is running, we're updating the position of the display manually
// on every frame (avoid binding to a function that uses non-notify effect properties
// imuRotations and smoothFollowOrigin).
focusedDisplay.position = displayPosition(focusedDisplay, smoothFollowRotation);
} else {
focusedDisplay.rotation = Qt.quaternion(1, 0, 0, 0);
focusedDisplay.eulerRotation.x = focusedDisplay.screenRotationX;
focusedDisplay.eulerRotation.y = focusedDisplay.screenRotationY;
focusedDisplay.eulerRotation.z = 0.0;
// When smooth follow is done, this frame animation will no longer run so we need to
// rebind a safe function to the position property that will automatically update the
// position when delegate properties change. display properties don't often change,
// but zoomOnFocus does change monitorDistance, so we need the binding to pick that up.
focusedDisplay.position = Qt.binding(function() {
return displayRotationVector(this, displayEusVector(this));
}.bind(focusedDisplay) );
}
}