Skip to content

Commit 5540d08

Browse files
committed
feat: replace kernel file with udev for touchpad control
This commit replaces the kernel file-based touchpad control mechanism with a udev-based solution. The main changes include: 1. Removed dependency on /proc/uos/touchpad_switch kernel file 2. Implemented udev rules to control touchpad via LIBINPUT_IGNORE_DEVICE environment variable 3. Added udev monitor to track touchpad device changes in real-time 4. Enhanced system touchpad integration with proper DBus property synchronization 5. Improved channel handling in transient units to prevent blocking The new approach uses udev rules to set LIBINPUT_IGNORE_DEVICE=1 for touchpad devices when disabled, which is more reliable and portable across different kernel versions. The system now properly monitors device changes and synchronizes touchpad state between user session and system level. Log: Touchpad control now uses udev rules instead of kernel files Influence: 1. Test touchpad enable/disable functionality through settings 2. Verify touchpad state persists after reboot 3. Test touchpad hotplug detection (plug/unplug external touchpad) 4. Verify touchpad toggle keyboard shortcuts work correctly 5. Test touchpad behavior when mouse is connected/disconnected 6. Check system logs for any udev-related errors feat: 使用 udev 替代内核文件控制触控板 本次提交将基于内核文件的触控板控制机制替换为基于 udev 的解决方案。主要变 更包括: 1. 移除对 /proc/uos/touchpad_switch 内核文件的依赖 2. 实现 udev 规则通过 LIBINPUT_IGNORE_DEVICE 环境变量控制触控板 3. 添加 udev 监视器实时跟踪触控板设备变化 4. 增强系统触控板集成,实现正确的 DBus 属性同步 5. 改进瞬态单元中的通道处理以防止阻塞 新方法使用 udev 规则在禁用触控板时设置 LIBINPUT_IGNORE_DEVICE=1,这种方 法更可靠且可在不同内核版本间移植。系统现在能正确监控设备变化并在用户会话 和系统级别之间同步触控板状态。 Log: 触控板控制现在使用 udev 规则替代内核文件 PMS: BUG-342407 Influence: 1. 通过设置测试触控板启用/禁用功能 2. 验证重启后触控板状态持久化 3. 测试触控板热插拔检测(插拔外接触控板) 4. 验证触控板切换键盘快捷键正常工作 5. 测试连接/断开鼠标时的触控板行为 6. 检查系统日志中是否有 udev 相关错误
1 parent b209345 commit 5540d08

9 files changed

Lines changed: 514 additions & 186 deletions

File tree

common/systemdunit/transientunit.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,16 @@ func (t *TransientUnit) WaitforFinish(sigLoop *dbusutil.SignalLoop) bool {
8181
return false
8282
}
8383
t.unit.InitSignalExt(sigLoop, true)
84-
var result = make(chan string)
84+
var result = make(chan string, 1) // buffered channel to prevent blocking
8585
t.unit.ConnectPropertiesChanged(func(interfaceName string, changedProperties map[string]dbus.Variant, invalidatedProperties []string) {
8686
_, ok := changedProperties["ActiveState"]
8787
if ok {
8888
val := changedProperties["ActiveState"].String()
89-
result <- val
89+
select {
90+
case result <- val:
91+
default:
92+
// channel is full or closed, skip this update
93+
}
9094
}
9195
})
9296
defer func() {

inputdevices1/ifc.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
package inputdevices
66

77
import (
8+
"fmt"
9+
810
"github.com/godbus/dbus/v5"
911
langselector "github.com/linuxdeepin/dde-daemon/langselector1"
1012
"github.com/linuxdeepin/go-lib/dbusutil"
@@ -31,8 +33,12 @@ func (tpad *Touchpad) Reset() *dbus.Error {
3133
}
3234

3335
func (tpad *Touchpad) Enable(enabled bool) *dbus.Error {
34-
tpad.enable(enabled)
35-
return nil
36+
sysTP := tpad.sysTouchPad
37+
if sysTP != nil {
38+
return dbusutil.ToError(sysTP.SetTouchpadEnable(0, enabled))
39+
} else {
40+
return dbusutil.ToError(fmt.Errorf("system touchpad is nul"))
41+
}
3642
}
3743

3844
func (w *Wacom) Reset() *dbus.Error {

inputdevices1/inputdevices_dbusutil.go

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

inputdevices1/mouse.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ func (m *Mouse) init() {
9595
tpad := m.touchPad
9696

9797
if !m.Exist {
98-
if tpad.Exist && tpad.TPadEnable.Get() {
98+
if tpad.Exist && tpad.TPadEnable {
9999
tpad.setDisableTemporary(false)
100100
}
101101
return
@@ -107,7 +107,7 @@ func (m *Mouse) init() {
107107
m.enableAdaptiveAccelProfile()
108108
m.motionAcceleration()
109109
m.motionThreshold()
110-
if m.DisableTpad.Get() && tpad.TPadEnable.Get() {
110+
if m.DisableTpad.Get() && tpad.TPadEnable {
111111
m.disableTouchPad()
112112
}
113113
}

inputdevices1/touchpad.go

Lines changed: 65 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,14 @@ const (
5050
)
5151

5252
type Touchpad struct {
53-
service *dbusutil.Service
54-
PropsMu sync.RWMutex
55-
Exist bool
56-
DeviceList string
53+
service *dbusutil.Service
54+
PropsMu sync.RWMutex
55+
sysTouchPad inputdevices.Touchpad
56+
Exist bool
57+
DeviceList string
5758

5859
// dbusutil-gen: ignore-below
59-
TPadEnable dconfig.Bool `prop:"access:rw"`
60+
TPadEnable bool `prop:"access:rw"` // 通过监听 system 端 Enable 属性动态更新,不使用 dconfig
6061
LeftHanded dconfig.Bool `prop:"access:rw"`
6162
DisableIfTyping dconfig.Bool `prop:"access:rw"`
6263
NaturalScroll dconfig.Bool `prop:"access:rw"`
@@ -98,7 +99,6 @@ func newTouchpad(service *dbusutil.Service) *Touchpad {
9899
panic("Touchpad DConfig initialization failed - cannot continue without dconfig support")
99100
}
100101

101-
tpad.TPadEnable.Bind(tpad.dsgTouchpadConfig, dconfigKeyTouchpadEnabled)
102102
tpad.LeftHanded.Bind(tpad.dsgTouchpadConfig, dconfigKeyTouchpadLeftHanded)
103103
tpad.DisableIfTyping.Bind(tpad.dsgTouchpadConfig, dconfigKeyTouchpadDisableTyping)
104104
tpad.NaturalScroll.Bind(tpad.dsgTouchpadConfig, dconfigKeyTouchpadNaturalScroll)
@@ -117,18 +117,47 @@ func newTouchpad(service *dbusutil.Service) *Touchpad {
117117
tpad.DoubleClick.Bind(tpad.dsgMouseConfig, dconfigKeyDoubleClick)
118118
tpad.DragThreshold.Bind(tpad.dsgMouseConfig, dconfigKeyDragThreshold)
119119

120-
// TODO: treeland环境暂不支持
121-
if hasTreeLand {
122-
return tpad
123-
}
124-
tpad.updateDXTpads()
125-
126120
if conn, err := dbus.SystemBus(); err != nil {
127121
logger.Warning(err)
128122
} else {
129123
tpad.systemConn = conn
130124
tpad.systemSigLoop = dbusutil.NewSignalLoop(conn, 10)
125+
tpad.sysTouchPad, err = inputdevices.NewTouchpad(tpad.systemConn, "/org/deepin/dde/InputDevices1/Touchpad")
126+
if err != nil {
127+
logger.Warning(err)
128+
} else {
129+
// 在这里注册信号监听,避免 init 中重复注册
130+
tpad.sysTouchPad.InitSignalExt(tpad.systemSigLoop, true)
131+
tpad.sysTouchPad.Enable().ConnectChanged(func(hasValue bool, value bool) {
132+
if !hasValue {
133+
return
134+
}
135+
logger.Infof("System touchpad Enable changed: %v", value)
136+
tpad.enable(value)
137+
})
138+
// 因为通过udev禁用触控板时, libinput感知不到触控板,通过系统touchpad查询是否存在触控板设备
139+
tpad.sysTouchPad.DeviceList().ConnectChanged(func(hasValue bool, value []string) {
140+
if !hasValue {
141+
return
142+
}
143+
logger.Infof("System touchpad DeviceList changed: %v", value)
144+
if !tpad.TPadEnable {
145+
if len(value) == 0 {
146+
tpad.setPropExist(false)
147+
} else {
148+
tpad.setPropExist(true)
149+
}
150+
}
151+
})
152+
tpad.systemSigLoop.Start()
153+
tpad.TPadEnable, _ = tpad.sysTouchPad.Enable().Get(0)
154+
}
155+
}
156+
// TODO: treeland环境暂不支持
157+
if hasTreeLand {
158+
return tpad
131159
}
160+
tpad.updateDXTpads()
132161

133162
return tpad
134163
}
@@ -180,28 +209,15 @@ func (tpad *Touchpad) init() {
180209
return
181210
}
182211

183-
if tpad.systemConn != nil {
184-
sysTouchPad, err := inputdevices.NewTouchpad(tpad.systemConn, "/org/deepin/dde/InputDevices1/Touchpad")
185-
if err != nil {
212+
// 从 system 端获取初始状态
213+
if tpad.sysTouchPad != nil {
214+
if enabled, err := tpad.sysTouchPad.Enable().Get(0); err != nil {
186215
logger.Warning(err)
187216
} else {
188-
sysTouchPad.InitSignalExt(tpad.systemSigLoop, true)
189-
sysTouchPad.Enable().ConnectChanged(func(hasValue bool, value bool) {
190-
if !hasValue {
191-
return
192-
}
193-
tpad.enable(value)
194-
})
195-
if enabled, err := sysTouchPad.Enable().Get(0); err != nil {
196-
logger.Warning(err)
197-
} else {
198-
tpad.TPadEnable.Set(enabled)
199-
}
217+
tpad.setPropTPadEnable(enabled)
200218
}
201219
}
202220

203-
currentState := tpad.TPadEnable.Get()
204-
tpad.forceEnable(currentState)
205221
tpad.enableLeftHanded()
206222
tpad.enableNaturalScroll()
207223
tpad.enableEdgeScroll()
@@ -213,10 +229,6 @@ func (tpad *Touchpad) init() {
213229
tpad.disableWhileTyping()
214230
tpad.enablePalmDetect()
215231
tpad.setPalmDimensions()
216-
217-
if tpad.systemSigLoop != nil {
218-
tpad.systemSigLoop.Start()
219-
}
220232
}
221233

222234
func (tpad *Touchpad) handleDeviceChanged() {
@@ -238,44 +250,46 @@ func (tpad *Touchpad) updateDXTpads() {
238250

239251
tpad.PropsMu.Lock()
240252
var v string
241-
if len(tpad.devInfos) == 0 {
242-
tpad.setPropExist(false)
253+
if tpad.TPadEnable {
254+
if len(tpad.devInfos) == 0 {
255+
tpad.setPropExist(false)
256+
} else {
257+
tpad.setPropExist(true)
258+
v = tpad.devInfos.string()
259+
}
243260
} else {
244-
tpad.setPropExist(true)
245-
v = tpad.devInfos.string()
261+
if tpad.sysTouchPad != nil {
262+
sysTpList, _ := tpad.sysTouchPad.DeviceList().Get(0)
263+
tpad.setPropExist(len(sysTpList) > 0)
264+
}
246265
}
266+
247267
tpad.setPropDeviceList(v)
248268
tpad.PropsMu.Unlock()
249269
}
250270

251271
// 受鼠标禁用触控板影响,临时关闭触控板
252272
func (tpad *Touchpad) setDisableTemporary(disable bool) {
253-
if disable == tpad.disableTemporary {
254-
return
255-
}
256273
if len(tpad.devInfos) > 0 {
257274
for _, v := range tpad.devInfos {
258-
err := v.Enable(!disable && tpad.TPadEnable.Get())
275+
err := v.Enable(!disable && tpad.TPadEnable)
259276
if err != nil {
260277
logger.Warningf("Enable '%v - %v' failed: %v",
261278
v.Id, v.Name, err)
262279
}
263280
}
264281
}
265-
tpad.disableTemporary = disable
266282
}
267283

268284
func (tpad *Touchpad) enable(enabled bool) {
269-
if enabled == tpad.TPadEnable.Get() {
285+
if enabled == tpad.TPadEnable {
270286
return
271287
}
272-
tpad.forceEnable(enabled)
273-
}
274-
275-
func (tpad *Touchpad) forceEnable(enabled bool) {
276-
if len(tpad.devInfos) > 0 {
288+
// 禁用时有system 的touchpad设置
289+
// 重新开启时,需要考虑插入鼠标时禁用触控板
290+
if len(tpad.devInfos) > 0 && enabled {
277291
for _, v := range tpad.devInfos {
278-
err := v.Enable(!tpad.disableTemporary && enabled)
292+
err := v.Enable(!tpad.disableTemporary)
279293
if err != nil {
280294
logger.Warningf("Enable '%v - %v' failed: %v",
281295
v.Id, v.Name, err)
@@ -284,13 +298,7 @@ func (tpad *Touchpad) forceEnable(enabled bool) {
284298
}
285299

286300
enableGesture(enabled)
287-
tpad.TPadEnable.Set(enabled)
288-
sysTouchPad, err := inputdevices.NewTouchpad(tpad.systemConn, "/org/deepin/dde/InputDevices1/Touchpad")
289-
if err == nil && sysTouchPad != nil {
290-
if err = sysTouchPad.SetTouchpadEnable(0, enabled); err != nil {
291-
logger.Warning(err)
292-
}
293-
}
301+
tpad.setPropTPadEnable(enabled)
294302
}
295303

296304
func (tpad *Touchpad) enableLeftHanded() {
@@ -544,7 +552,7 @@ func enableGesture(enabled bool) {
544552
return
545553
}
546554

547-
dconfig.SetValue("dconfig", enabled)
555+
dconfig.SetValue("touchpadEnabled", enabled)
548556
}
549557

550558
func (tpad *Touchpad) initTouchpadDConfig() error {
@@ -562,13 +570,6 @@ func (tpad *Touchpad) initTouchpadDConfig() error {
562570
tpad.dsgTouchpadConfig.ConnectValueChanged(func(key string) {
563571
logger.Debugf("Touchpad dconfig value changed: %s", key)
564572
switch key {
565-
case dconfigKeyTouchpadEnabled:
566-
enabled, err := tpad.dsgTouchpadConfig.GetValueBool(dconfigKeyTouchpadEnabled)
567-
if err != nil {
568-
logger.Warningf("Failed to get touchpad enabled value from dconfig: %v", err)
569-
} else {
570-
tpad.enable(enabled)
571-
}
572573
case dconfigKeyTouchpadLeftHanded:
573574
tpad.enableLeftHanded()
574575
case dconfigKeyTouchpadDisableTyping:

system/inputdevices1/libinput.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ func log_handler_go(priority C.enum_libinput_log_priority, cstr *C.char) {
2525
case C.LIBINPUT_LOG_PRIORITY_INFO:
2626
logger.Info(str)
2727
case C.LIBINPUT_LOG_PRIORITY_ERROR:
28-
logger.Error(str)
28+
logger.Warning(str)
2929
}
3030
}
3131

0 commit comments

Comments
 (0)