Skip to content

fix(inputdevices): refactor natural scroll event logging for accurate…#1105

Merged
Ivy233 merged 1 commit into
linuxdeepin:masterfrom
Ivy233:fix/event-natural-scroll-log
May 14, 2026
Merged

fix(inputdevices): refactor natural scroll event logging for accurate…#1105
Ivy233 merged 1 commit into
linuxdeepin:masterfrom
Ivy233:fix/event-natural-scroll-log

Conversation

@Ivy233
Copy link
Copy Markdown
Contributor

@Ivy233 Ivy233 commented May 14, 2026

… reporting

Rename event fields and restructure logging triggers to ensure each event is reported exactly once from the correct source:

  • Rename mouse_natural_scroll -> mouse_scroll_native_on
  • Rename touchpad_natural_scroll -> touchpad_scroll_native_on
  • Report mouse and touchpad separately on startup instead of combined
  • Move logging from enableNaturalScroll() to dconfig change callbacks to avoid duplicate events during device hotplug/init
  • Add touchpad hotplug detection: report real value on plug-in, empty value on unplug, no event otherwise
  • Remove LogOnStartup and LogNaturalScroll helper functions

修改自然滚动事件埋点字段名及上报逻辑,确保事件准确上报:

  • 重命名字段 mouse_natural_scroll -> mouse_scroll_native_on
  • 重命名字段 touchpad_natural_scroll -> touchpad_scroll_native_on
  • 开机时鼠标和触摸板分别独立上报,不再合并
  • 将埋点从 enableNaturalScroll() 移至 dconfig 值变更回调, 避免设备热插拔和初始化时重复上报
  • 新增触摸板热插拔检测:插入时上报真实值,拔出时上报空值, 其他情况不触发
  • 移除 LogOnStartup 和 LogNaturalScroll 辅助函数

Test:

  1. systemctl --user restart org.dde.session.Daemon1 -> 2 events: mouse_scroll_native_on ("true"/"false") + touchpad_scroll_native_on ("true"/"false")
  2. Toggle touchpad natural scroll in control center -> 1 event: touchpad_scroll_native_on only
  3. Toggle mouse natural scroll in control center -> 1 event: mouse_scroll_native_on only
  4. Unbind touchpad via sysfs (simulates unplug) -> 1 event: touchpad_scroll_native_on ("")
  5. Bind touchpad via sysfs (simulates plug-in) -> 1 event: touchpad_scroll_native_on ("true"/"false")

PMS: BUG-361165、BUG-361159、BUG-361147、BUG-361141

Summary by Sourcery

Refine natural scroll telemetry to log mouse and touchpad states separately and accurately across startup, configuration changes, and touchpad hotplug events.

New Features:

  • Report touchpad hotplug events by sending the current natural scroll value on plug-in and an empty value on unplug.

Bug Fixes:

  • Prevent duplicate natural scroll events by moving logging from runtime enablement functions to configuration change callbacks.

Enhancements:

  • Rename natural scroll logging fields for mouse and touchpad and switch to per-device reporting instead of a combined event.
  • Simplify event logging by removing the delayed startup logger and combined natural scroll helper.

@Ivy233 Ivy233 requested a review from mhduiy May 14, 2026 05:48
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented May 14, 2026

Reviewer's Guide

Refactors natural scroll event logging so mouse and touchpad states are reported via separate, renamed fields, and events are emitted exactly once from startup and dconfig change paths, with added touchpad hotplug handling and removal of unused helpers.

Sequence diagram for refactored natural scroll event logging

sequenceDiagram
    participant Manager
    participant Mouse
    participant Touchpad
    participant EventLog

    alt [startup]
        Manager->>Manager: init
        Manager->>Mouse: initMouseDConfig
        Manager->>Touchpad: initTouchpadDConfig
        Manager->>EventLog: LogMouseNaturalScroll(m.mouse.NaturalScroll.Get())
        Manager->>EventLog: LogTouchpadNaturalScroll(m.tpad.NaturalScroll.Get(), m.tpad.Exist)
    end

    alt [mouse natural scroll dconfig change]
        Mouse->>Mouse: initMouseDConfig
        Mouse->>Mouse: enableNaturalScroll()
        Mouse->>EventLog: LogMouseNaturalScroll(m.NaturalScroll.Get())
    end

    alt [touchpad natural scroll dconfig change]
        Touchpad->>Touchpad: initTouchpadDConfig
        Touchpad->>Touchpad: enableNaturalScroll()
        Touchpad->>EventLog: LogTouchpadNaturalScroll(tpad.NaturalScroll.Get(), true)
    end

    alt [touchpad hotplug]
        Touchpad->>Touchpad: handleDeviceChanged()
        alt [touchpad plugged in]
            Touchpad->>EventLog: LogTouchpadNaturalScroll(tpad.NaturalScroll.Get(), true)
        else [touchpad unplugged]
            Touchpad->>EventLog: LogTouchpadNaturalScroll(false, false)
        end
    end
Loading

File-Level Changes

Change Details Files
Refactor touchpad natural scroll logging to support empty-value reporting and new field name.
  • Replace combined startup logging helper with a touchpad-specific logger that accepts an existence flag and outputs an empty string when no touchpad is present.
  • Rename the touchpad event field from touchpad_natural_scroll to touchpad_scroll_native_on and update debug logging accordingly.
  • Remove the delayed LogOnStartup helper and the shared LogNaturalScroll function that logged both devices in one event.
inputdevices1/event_log.go
Align mouse natural scroll logging with new field naming and startup flow.
  • Rename the mouse event field from mouse_natural_scroll to mouse_scroll_native_on in log payloads.
  • Remove per-toggle logging from enableNaturalScroll and instead trigger logging from the mouse dconfig natural scroll change callback.
  • Change manager startup initialization to log mouse natural scroll directly via LogMouseNaturalScroll instead of the removed combined helper.
inputdevices1/event_log.go
inputdevices1/mouse.go
inputdevices1/manager.go
Trigger touchpad natural scroll logging from configuration changes and hotplug events instead of enableNaturalScroll.
  • Remove logging from Touchpad.enableNaturalScroll to avoid duplicate events during init/hotplug.
  • Add logging in the touchpad dconfig natural scroll change handler so each setting change emits exactly one event when a touchpad exists.
  • Extend Touchpad.handleDeviceChanged to detect existence changes and log the real natural scroll value on plug-in and an empty value on unplug using the new LogTouchpadNaturalScroll signature.
inputdevices1/touchpad.go
inputdevices1/event_log.go

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • The new LogTouchpadNaturalScroll(enabled bool, hasTouchpad bool) API is a bit confusing since enabled is ignored when hasTouchpad is false; consider either deriving the empty string internally from Exist (and dropping hasTouchpad), or documenting/changing the signature so callers don’t pass a meaningless enabled value on unplug.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new `LogTouchpadNaturalScroll(enabled bool, hasTouchpad bool)` API is a bit confusing since `enabled` is ignored when `hasTouchpad` is false; consider either deriving the empty string internally from `Exist` (and dropping `hasTouchpad`), or documenting/changing the signature so callers don’t pass a meaningless `enabled` value on unplug.

## Individual Comments

### Comment 1
<location path="inputdevices1/event_log.go" line_range="70-74" />
<code_context>
 	return "false"
 }
-
-// LogOnStartup logs the current state on startup with a delay
-// Both touchpad and mouse natural scroll states are logged in one combined event
-func LogOnStartup(touchpadNaturalScroll, mouseNaturalScroll bool) {
-	// Delay logging to ensure the event log system is ready
-	time.AfterFunc(5*time.Second, func() {
-		LogNaturalScroll(touchpadNaturalScroll, mouseNaturalScroll)
-	})
</code_context>
<issue_to_address>
**issue (bug_risk):** Removing the delayed startup logging might reintroduce a race with the event log initialization.

The previous `LogOnStartup` delayed logging by 5s so the event log system was ready before startup events were written; the new code logs immediately. Please confirm whether `eventlog.WriteEventLog` is now guaranteed to be safe at startup, and if not, keep a small delay (at this call site) rather than removing it entirely to avoid losing events.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread inputdevices1/event_log.go
… reporting

Rename event fields and restructure logging triggers to ensure
each event is reported exactly once from the correct source:

- Rename mouse_natural_scroll -> mouse_scroll_native_on
- Rename touchpad_natural_scroll -> touchpad_scroll_native_on
- Report mouse and touchpad separately on startup instead of combined
- Move logging from enableNaturalScroll() to dconfig change callbacks
  to avoid duplicate events during device hotplug/init
- Add touchpad hotplug detection: report real value on plug-in,
  empty value on unplug, no event otherwise
- Remove LogOnStartup and LogNaturalScroll helper functions

修改自然滚动事件埋点字段名及上报逻辑,确保事件准确上报:
- 重命名字段 mouse_natural_scroll -> mouse_scroll_native_on
- 重命名字段 touchpad_natural_scroll -> touchpad_scroll_native_on
- 开机时鼠标和触摸板分别独立上报,不再合并
- 将埋点从 enableNaturalScroll() 移至 dconfig 值变更回调,
  避免设备热插拔和初始化时重复上报
- 新增触摸板热插拔检测:插入时上报真实值,拔出时上报空值,
  其他情况不触发
- 移除 LogOnStartup 和 LogNaturalScroll 辅助函数

Test:
1. systemctl --user restart org.dde.session.Daemon1
   -> 2 events: mouse_scroll_native_on ("true"/"false") +
      touchpad_scroll_native_on ("true"/"false")
2. Toggle touchpad natural scroll in control center
   -> 1 event: touchpad_scroll_native_on only
3. Toggle mouse natural scroll in control center
   -> 1 event: mouse_scroll_native_on only
4. Unbind touchpad via sysfs (simulates unplug)
   -> 1 event: touchpad_scroll_native_on ("")
5. Bind touchpad via sysfs (simulates plug-in)
   -> 1 event: touchpad_scroll_native_on ("true"/"false")

PMS: BUG-361165、BUG-361159、BUG-361147、BUG-361141
@Ivy233 Ivy233 force-pushed the fix/event-natural-scroll-log branch from 9cb24a0 to 06483c6 Compare May 14, 2026 07:49
@deepin-ci-robot
Copy link
Copy Markdown

deepin pr auto review

你好!我是你的智能编程助手 CodeGeeX。我已仔细审查了你提供的 Git Diff。本次代码变更主要重构了输入设备(触控板和鼠标)自然滚动状态的事件日志记录逻辑,将原本的合并日志拆分为独立记录,并增加了对触控板热插拔场景的处理。

以下是我从语法逻辑、代码质量、代码性能和代码安全四个维度提出的详细审查意见和改进建议:

1. 语法与逻辑

  • 逻辑变更:移除了启动时的延迟日志机制

    • 原逻辑LogOnStartup 使用了 time.AfterFunc(5*time.Second, ...),延迟 5 秒发送日志,这通常是为了等待事件日志系统初始化完成。
    • 新逻辑:在 manager.go 中直接同步调用 LogMouseNaturalScrollLogTouchpadNaturalScroll
    • 潜在风险:如果事件日志系统(eventlog)在此刻尚未初始化就绪,这些启动日志可能会静默丢失。
    • 建议:请确认 eventlog.WriteEventLog 内部是否已经做了缓冲或重试机制。如果是,移除延迟是合理的;如果不是,建议保留延迟机制,或者确保 init 函数在事件日志系统就绪后才被调用。
  • 逻辑变更:运行时配置变更的日志触发点移动

    • 原逻辑:在 enableNaturalScroll() 业务逻辑执行完毕后记录日志。
    • 新逻辑:移入 initMouseDConfig / initTouchpadDConfigswitch case 分支中。
    • 评价:这是一个很好的改进!将日志记录与配置变更的触发源绑定,而不是与底层的执行函数绑定,避免了业务函数被多处复用时产生重复日志,逻辑更加清晰。
  • 逻辑边界:触控板不存在时的日志值

    • LogTouchpadNaturalScroll 中,当 hasTouchpadfalse 时,value 被赋值为空字符串 ""
    • 建议:需确认下游的数据分析系统(消费这些日志的系统)是否能正确解析空字符串 ""。如果下游期望的是布尔值,空字符串可能会导致 JSON 解析类型不一致(期望 bool 却收到 string)。如果确实需要表示“不存在”,建议使用明确的字符串如 "null""not_exist",并在下游统一约定。

2. 代码质量

  • 函数签名设计:LogTouchpadNaturalScroll 的参数

    • 当前签名为 LogTouchpadNaturalScroll(enabled bool, hasTouchpad bool)。当 hasTouchpadfalse 时,enabled 参数实际上是被忽略的(因为 value 会被直接置为 "")。
    • 建议:为了调用方的语义更清晰,避免产生“为什么触控板不存在还要传 enabled 状态”的困惑,可以考虑使用 Optional 模式或结构体作为参数。但在 Go 语言中,最简单的方式是保持现状,但必须补充详细的注释说明当 hasTouchpadfalseenabled 将被忽略。目前的注释已经有一点说明,这很好,可以再强化一下:
      // LogTouchpadNaturalScroll logs touchpad natural scroll state.
      // When hasTouchpad is false, the enabled parameter is ignored and an empty value is reported.
      func LogTouchpadNaturalScroll(enabled bool, hasTouchpad bool) {
  • 冗余代码清理

    • event_log.go 中,boolToString 函数依然保留,这很好。但原 LogNaturalScrollLogOnStartup 的删除非常干净。
    • 评价:代码精简度提升,去除了合并日志的复杂度,符合单一职责原则。

3. 代码性能

  • 热插拔事件处理中的性能考量
    • touchpad.gohandleDeviceChanged() 中,每次设备变更都会调用 tpad.updateDXTpads()tpad.init()
    • 潜在风险:如果内核层由于硬件抖动短时间内发送大量的设备插拔事件(UDEV 事件风暴),这段逻辑会被频繁触发,每次都会执行日志写入。
    • 建议:虽然 eventlog.WriteEventLog 通常只是写缓冲区,性能影响不大,但如果 tpad.init() 包含重量级的硬件配置操作,建议在 handleDeviceChanged 中加入防抖逻辑,例如使用 time.AfterFunc 合并短时间内的事件。

4. 代码安全

  • 日志注入与敏感信息泄露

    • 本次修改只涉及硬件配置状态的记录(开关状态),不涉及用户敏感信息,且 boolToString 严格限制了输出为 "true""false"(不存在时为 ""),不存在日志注入和敏感信息泄露的风险。安全性良好。
  • 并发安全

    • handleDeviceChanged 修改了 tpad.Exist 状态并记录日志。如果设备变更事件是在不同的 Goroutine 中派发的,需要注意 tpad.Exist 的并发读写问题。
    • 建议:请确认 tpad.Exist 是否有并发保护。如果没有,在多线程场景下可能会产生数据竞争。建议使用 sync.Mutex 保护相关字段,或确保事件回调在同一个串行队列中执行。

综合改进建议代码示例

针对上述部分建议,我对 event_log.gotouchpad.go 的相关代码进行了微调示范:

event_log.go 改进:

// LogTouchpadNaturalScroll logs touchpad natural scroll state
// When hasTouchpad is false, the enabled parameter is ignored and an empty value is reported to indicate absence.
func LogTouchpadNaturalScroll(enabled bool, hasTouchpad bool) {
	value := ""
	if hasTouchpad {
		value = boolToString(enabled)
	}
	data := &eventlog.EventLogData{
		Tid:    EventTidNaturalScroll,
		Target: "natural_scroll",
		Message: map[string]string{
			// 建议确认下游是否能接受空字符串,若不能,可考虑 "null" 或 "not_exist"
			"touchpad_scroll_native_on": value, 
		},
	}
	if eventlog.WriteEventLog(data) {
		logger.Debug("EventLog: touchpad natural scroll:", value)
	}
}

touchpad.go 改进(增加防抖与并发提醒):

func (tpad *Touchpad) handleDeviceChanged() {
	// TODO: 如果此函数可能在多个 Goroutine 并发调用,需要加锁保护 tpad 的状态
	// tpad.mu.Lock()
	// defer tpad.mu.Unlock()

	oldExist := tpad.Exist
	tpad.updateDXTpads()
	tpad.init()

	if oldExist != tpad.Exist {
		if tpad.Exist {
			// Touchpad plugged in: report real value
			LogTouchpadNaturalScroll(tpad.NaturalScroll.Get(), true)
		} else {
			// Touchpad unplugged: report empty value (false is ignored)
			LogTouchpadNaturalScroll(false, false)
		}
	}
}

总结:本次代码变更整体思路清晰,重构方向正确,降低了模块间的耦合,并完善了热插拔场景的日志覆盖。只需稍微注意启动时序(延迟日志移除的影响)和空字符串的下游兼容性即可。

@deepin-ci-robot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: Ivy233, mhduiy

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@Ivy233 Ivy233 merged commit 4d29cc8 into linuxdeepin:master May 14, 2026
16 of 18 checks passed
@Ivy233 Ivy233 deleted the fix/event-natural-scroll-log branch May 14, 2026 10:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants