From 699dbecc2c6f1f6aaae7284a491b82bbd0f41bde Mon Sep 17 00:00:00 2001 From: fuleyi Date: Wed, 20 May 2026 13:15:16 +0800 Subject: [PATCH] fix: stop brightness transition on disable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Cancel any ongoing brightness transition before restoring brightness when auto brightness is stopped. 2. Cancel the active transition immediately when a manual brightness change is detected, both when auto brightness is being disabled and when auto adjustment is only temporarily paused. 3. Add AutoBrightnessManager.cancelOngoingTransition to stop the transition for the built-in monitor through TransitionManager.StopMonitor. 4. Prevent sensor light change handling and compensation ticks from continuing to adjust brightness after auto brightness has been turned off by also checking config.Enabled. 5. Add per-step transition callbacks in the brightness transition layer so brightness properties are updated progressively during the fade, instead of being set to the target value immediately at transition start. 6. Remove the premature property update in setBrightnessWithTransition and wire the transition callback in Manager.initTransitionManager to sync built-in monitor brightness and D-Bus properties on each step. Why: 1. When users turn off auto brightness or manually change brightness, an unfinished fade could continue running and override the user's latest brightness choice. 2. The previous implementation also exposed the target brightness property too early, making reported brightness inconsistent with the actual gradual transition state. 3. These changes make brightness behavior match user intent immediately and keep exported brightness state aligned with real transition progress. Log: Fixed an issue where brightness fading could continue after auto brightness was turned off, and improved real-time brightness state updates during transitions Influence: 1. Enable auto brightness, trigger a brightness transition, then turn off auto brightness and verify the transition stops immediately and brightness is restored without further fading. 2. During an active auto-brightness fade, manually change brightness and verify the ongoing transition is canceled and does not override the manual setting afterward. 3. In manual override mode, confirm no further sensor-driven brightness updates occur while auto brightness is disabled or paused. 4. Observe D-Bus or exposed brightness properties during a transition and verify they change step by step instead of jumping directly to the target value. 5. Test built-in monitor behavior specifically, including repeated enable/disable operations and rapid manual brightness adjustments, to ensure there are no lingering transitions. 6. Verify no regression in normal auto-brightness transitions when the feature remains enabled. fix: 关闭自动亮度时停止亮度渐变 1. 在停止自动亮度并恢复亮度前,先取消当前正在进行的亮度渐变。 2. 在检测到用户手动修改亮度时,立即取消当前渐变;无论是要直接关闭自动亮 度,还是仅临时暂停自动调节,都执行该处理。 3. 新增 AutoBrightnessManager.cancelOngoingTransition,通过 TransitionManager.StopMonitor 停止内置显示器上的渐变任务。 4. 在环境光变化处理和补偿定时任务中增加 config.Enabled 判断,避免自动亮 度关闭后仍继续调节亮度。 5. 在亮度渐变层增加逐步回调能力,使亮度属性在渐变过程中按步骤同步更新, 而不是在渐变开始时直接设置为目标值。 6. 移除 setBrightnessWithTransition 中过早设置亮度属性的逻辑,并在 Manager.initTransitionManager 中接入渐变回调,在每一步同步内置显示器亮度 和 D-Bus 属性。 Why: 1. 当用户关闭自动亮度或手动修改亮度时,未完成的渐变可能继续执行,并覆盖 用户最新设置的亮度。 2. 旧实现会过早暴露目标亮度属性,导致对外报告的亮度状态与实际渐变中的亮 度不一致。 3. 这些修改让亮度行为能够立即响应用户意图,并确保导出的亮度状态与真实渐 变进度保持一致。 Log: 修复关闭自动亮度后亮度渐变仍继续的问题,并改进渐变过程中的亮度状态 实时更新 Influence: 1. 开启自动亮度并触发一次亮度渐变,然后关闭自动亮度,验证渐变会立即停 止,亮度恢复后不会继续渐变。 2. 在自动亮度渐变进行中手动修改亮度,验证正在进行的渐变被取消,之后不会 再覆盖手动设置的亮度。 3. 在手动接管期间,确认自动亮度被关闭或暂停后,不会再收到传感器驱动的亮 度更新。 4. 在渐变过程中观察 D-Bus 或对外暴露的亮度属性,验证其会随每一步渐变逐步 变化,而不是直接跳到目标值。 5. 重点测试内置显示器场景,包括反复开关自动亮度和快速连续手动调节亮度, 确保不会残留未停止的渐变任务。 6. 验证自动亮度保持开启时,正常的亮度渐变流程没有回归问题。 PMS: BUG-358023 Change-Id: I27e29c376de575668e364e9612937c86cec41722 --- display1/auto_brightness.go | 26 ++++++++++- display1/brightness.go | 3 +- display1/brightness/brightness_transition.go | 46 +++++++++++++++++++- display1/manager.go | 16 +++++-- 4 files changed, 82 insertions(+), 9 deletions(-) diff --git a/display1/auto_brightness.go b/display1/auto_brightness.go index 7d748e9c9..f0d8756a7 100644 --- a/display1/auto_brightness.go +++ b/display1/auto_brightness.go @@ -254,6 +254,9 @@ func (abm *AutoBrightnessManager) Stop() error { atomic.StoreInt32(&abm.stopping, 1) abm.stopCompensationTimer() atomic.StoreInt32(&abm.stopping, 0) + + // 先取消正在进行的渐变,再恢复亮度 + abm.cancelOngoingTransition(abm.manager) abm.restoreSavedBrightness() if abm.sensorClient != nil { @@ -352,6 +355,8 @@ func (abm *AutoBrightnessManager) OnManualBrightnessChange() { manager := abm.manager abm.mutex.Unlock() logger.Info("[AutoBrightness] Manual brightness change detected, disabling auto brightness mode") + // 立即取消正在进行的渐变,防止渐变继续覆盖用户手动设置的亮度 + abm.cancelOngoingTransition(manager) // 异步保存配置并停止功能 go func() { err := abm.saveConfig() @@ -374,10 +379,14 @@ func (abm *AutoBrightnessManager) OnManualBrightnessChange() { abm.manualOverride = time.Now() overrideDuration := abm.config.ManualOverrideDuration sensorClient := abm.sensorClient + manager := abm.manager abm.mutex.Unlock() logger.Infof("[AutoBrightness] Manual brightness change detected, pausing auto adjustment for %d seconds", overrideDuration) + // 立即取消正在进行的渐变 + abm.cancelOngoingTransition(manager) + if sensorClient != nil && sensorClient.IsClaimed() { err := sensorClient.ReleaseLight() if err != nil { @@ -386,6 +395,18 @@ func (abm *AutoBrightnessManager) OnManualBrightnessChange() { } } +// cancelOngoingTransition 立即取消指定显示器上正在进行的渐变 +func (abm *AutoBrightnessManager) cancelOngoingTransition(manager *Manager) { + if manager == nil || manager.transitionManager == nil { + return + } + builtinMonitor := manager.getBuiltinMonitor() + if builtinMonitor == nil { + return + } + manager.transitionManager.StopMonitor(builtinMonitor.Name) +} + // resetHistoryState 重置历史状态,使下次能立即触发亮度调节 // 注意:此函数假设调用者已经持有锁 func (abm *AutoBrightnessManager) resetHistoryState() { @@ -594,11 +615,12 @@ func (abm *AutoBrightnessManager) onServiceChange(available bool) { func (abm *AutoBrightnessManager) onLightLevelChange(rawLightLevel int) { abm.mutex.Lock() running := abm.running + enabled := abm.config.Enabled inManualOverride := abm.isInManualOverride() abm.lastSensorDataTime = time.Now() abm.mutex.Unlock() - if !running || inManualOverride { + if !running || !enabled || inManualOverride { return } @@ -760,7 +782,7 @@ func (abm *AutoBrightnessManager) ensureSensorClaimed(sensorClient *SensorProxyC func (abm *AutoBrightnessManager) compensationTick() { abm.mutex.Lock() - if !abm.running { + if !abm.running || !abm.config.Enabled { abm.mutex.Unlock() return } diff --git a/display1/brightness.go b/display1/brightness.go index 14229ee56..6f63d2c48 100644 --- a/display1/brightness.go +++ b/display1/brightness.go @@ -294,6 +294,7 @@ func (m *Manager) setBrightnessAndSync(name string, value float64) error { } // setBrightnessWithTransition 使用渐变效果设置亮度(强制启用渐变) +// 亮度属性会在渐变过程中通过 onStepFunc 回调逐步更新,而非立即跳到目标值 func (m *Manager) setBrightnessWithTransition(name string, value float64) error { logger.Debug("Starting brightness setting with transition", name, value) monitors := m.getConnectedMonitors() @@ -322,8 +323,6 @@ func (m *Manager) setBrightnessWithTransition(name string, value float64) error } } - monitor.setPropBrightnessWithLock(value) - logger.Debug("end set brightness with transition", name, value) return nil diff --git a/display1/brightness/brightness_transition.go b/display1/brightness/brightness_transition.go index 452ccacab..3e0a61884 100644 --- a/display1/brightness/brightness_transition.go +++ b/display1/brightness/brightness_transition.go @@ -106,6 +106,9 @@ type TransitionExecutor struct { // 获取当前亮度百分比函数 getterFunc func() (float64, error) + // 每步回调(用于同步亮度属性到 D-Bus),参数为(显示器名称, 当前亮度百分比) + onStepFunc func(monitorName string, percent float64) + // 配置参数 config TransitionConfig @@ -126,6 +129,13 @@ func NewTransitionExecutor(monitorName string, brightnessType BrightnessType, se } } +// SetOnStepFunc 设置每步回调(用于在过渡过程中同步亮度属性到 D-Bus),参数为(显示器名称, 当前亮度百分比) +func (e *TransitionExecutor) SetOnStepFunc(fn func(monitorName string, percent float64)) { + e.mu.Lock() + defer e.mu.Unlock() + e.onStepFunc = fn +} + // SetBrightness 设置亮度(百分比,0.0 - 1.0) func (e *TransitionExecutor) SetBrightness(targetPercent float64) error { return e.SetBrightnessWithForce(targetPercent, false) @@ -281,11 +291,16 @@ func (e *TransitionExecutor) runTransition(task *transitionTask) { return } - // 更新实时值 + // 更新实时值并通知回调 e.mu.Lock() e.currentPercent = currentPercent + onStep := e.onStepFunc e.mu.Unlock() + if onStep != nil { + onStep(e.monitorName, currentPercent) + } + // 如果达到目标值,结束过渡 if abs(currentPercent-task.target) < epsilon { logger.Debugf("[%s] Transition completed: %.2f%% -> %.2f%%", e.monitorName, task.startValue*100, task.target*100) @@ -419,6 +434,9 @@ type TransitionManager struct { // 获取 Gamma 当前亮度的回调 getGammaFunc func(monitorName string) (float64, error) + + // 每步回调(用于同步亮度属性到 D-Bus),参数为(显示器名称, 当前亮度百分比) + onStepFunc func(monitorName string, percent float64) } // NewTransitionManager 创建统一过渡管理器 @@ -439,6 +457,16 @@ func (m *TransitionManager) SetEnabled(enabled bool) { } } +// SetOnStepFunc 设置每步回调(用于在过渡过程中同步亮度属性到 D-Bus),参数为(显示器名称, 当前亮度百分比) +func (m *TransitionManager) SetOnStepFunc(fn func(monitorName string, percent float64)) { + m.mu.Lock() + defer m.mu.Unlock() + m.onStepFunc = fn + for _, executor := range m.executors { + executor.SetOnStepFunc(fn) + } +} + // SetDuration 设置过渡时长(毫秒) func (m *TransitionManager) SetDuration(durationMs int) { m.mu.Lock() @@ -523,7 +551,12 @@ func (m *TransitionManager) SetBrightness(monitorName string, targetPercent floa m.mu.Lock() m.executors[monitorName] = executor + onStep := m.onStepFunc m.mu.Unlock() + + if onStep != nil { + executor.SetOnStepFunc(onStep) + } } return executor.SetBrightnessWithForce(targetPercent, forceTransition) @@ -589,6 +622,17 @@ func (m *TransitionManager) Stop() { } } +// StopMonitor 停止指定显示器的过渡 +func (m *TransitionManager) StopMonitor(monitorName string) { + m.mu.Lock() + executor, exists := m.executors[monitorName] + m.mu.Unlock() + + if exists { + executor.Stop() + } +} + // GetConfig 获取当前配置 func (m *TransitionManager) GetConfig() TransitionConfig { m.mu.Lock() diff --git a/display1/manager.go b/display1/manager.go index 2f50bc79c..32afb91e2 100644 --- a/display1/manager.go +++ b/display1/manager.go @@ -197,10 +197,10 @@ type Manager struct { debugOpts debugOptions redshiftRunner *redshiftRunner - sessionActive bool - sessionActiveMu sync.RWMutex - newSysCfg *SysRootConfig - cursorShowed bool + sessionActive bool + sessionActiveMu sync.RWMutex + newSysCfg *SysRootConfig + cursorShowed bool // dconfig com.deepin.Display displayConfigMgr configManager.Manager @@ -3716,6 +3716,14 @@ func (m *Manager) initTransitionManager() { }, ) + // 设置每步回调:在渐变过程中同步亮度属性到 D-Bus + m.transitionManager.SetOnStepFunc(func(monitorName string, percent float64) { + if m.builtinMonitor != nil && m.builtinMonitor.Name == monitorName { + m.builtinMonitor.setPropBrightnessWithLock(percent) + } + m.syncPropBrightness() + }) + logger.Infof("Unified transition manager initialized: enabled=%v, duration=%dms, stepPercent=%.2f%%, minInterval=%dms", m.transitionEnabled, m.transitionDuration, m.transitionStepPercent, m.transitionMinStepInterval) }