@@ -195,17 +195,19 @@ typedef struct {
195195 const Arg arg ;
196196} Axis ;
197197
198- struct input_device {
198+ typedef struct {
199199 struct wl_list link ;
200200 struct wlr_input_device * wlr_device ;
201201 struct libinput_device * libinput_device ;
202202 struct wl_listener destroy_listener ; // 用于监听设备销毁事件
203- };
203+ void * device_data ; // 新增:指向设备特定数据(如 Switch)
204+ } InputDevice ;
204205
205206typedef struct {
206207 struct wl_list link ;
207208 struct wlr_switch * wlr_switch ;
208209 struct wl_listener toggle ;
210+ InputDevice * input_dev ;
209211} Switch ;
210212
211213struct dwl_animation {
@@ -515,10 +517,9 @@ static void createmon(struct wl_listener *listener, void *data);
515517static void createnotify (struct wl_listener * listener , void * data );
516518static void createpointer (struct wlr_pointer * pointer );
517519static void configure_pointer (struct libinput_device * device );
518- static void destroypointer (struct wl_listener * listener , void * data );
520+ static void destroyinputdevice (struct wl_listener * listener , void * data );
519521static void createswitch (struct wlr_switch * switch_device );
520522static void switch_toggle (struct wl_listener * listener , void * data );
521- static void cleanupswitches ();
522523static void createpointerconstraint (struct wl_listener * listener , void * data );
523524static void cursorconstrain (struct wlr_pointer_constraint_v1 * constraint );
524525static void commitpopup (struct wl_listener * listener , void * data );
@@ -746,8 +747,7 @@ static struct wlr_pointer_constraint_v1 *active_constraint;
746747static struct wlr_seat * seat ;
747748static KeyboardGroup * kb_group ;
748749static struct wl_list keyboards ;
749- static struct wl_list pointers ;
750- static struct wl_list switches ;
750+ static struct wl_list inputdevices ;
751751static unsigned int cursor_mode ;
752752static Client * grabc ;
753753static int grabcx , grabcy ; /* client-relative */
@@ -1999,8 +1999,6 @@ void cleanup(void) {
19991999
20002000 dwl_im_relay_finish (dwl_input_method_relay );
20012001
2002- cleanupswitches ();
2003-
20042002 /* If it's not destroyed manually it will cause a use-after-free of
20052003 * wlr_seat. Destroy it until it's fixed in the wlroots side */
20062004 wlr_backend_destroy (backend );
@@ -2697,13 +2695,32 @@ createnotify(struct wl_listener *listener, void *data) {
26972695 LISTEN (& toplevel -> events .set_title , & c -> set_title , updatetitle );
26982696}
26992697
2700- void destroypointer (struct wl_listener * listener , void * data ) {
2701- struct input_device * input_dev =
2698+ void destroyinputdevice (struct wl_listener * listener , void * data ) {
2699+ InputDevice * input_dev =
27022700 wl_container_of (listener , input_dev , destroy_listener );
27032701
2702+ // 清理设备特定数据
2703+ if (input_dev -> device_data ) {
2704+ // 根据设备类型进行特定清理
2705+ switch (input_dev -> wlr_device -> type ) {
2706+ case WLR_INPUT_DEVICE_SWITCH : {
2707+ Switch * sw = (Switch * )input_dev -> device_data ;
2708+ // 移除 toggle 监听器
2709+ wl_list_remove (& sw -> toggle .link );
2710+ // 释放 Switch 内存
2711+ free (sw );
2712+ break ;
2713+ }
2714+ // 可以添加其他设备类型的清理代码
2715+ default :
2716+ break ;
2717+ }
2718+ input_dev -> device_data = NULL ;
2719+ }
2720+
27042721 // 从设备列表中移除
27052722 wl_list_remove (& input_dev -> link );
2706- // 移除监听器
2723+ // 移除 destroy 监听器
27072724 wl_list_remove (& input_dev -> destroy_listener .link );
27082725 // 释放内存
27092726 free (input_dev );
@@ -2759,14 +2776,14 @@ void createpointer(struct wlr_pointer *pointer) {
27592776 configure_pointer (device );
27602777 }
27612778
2762- struct input_device * input_dev = calloc (1 , sizeof (struct input_device ));
2779+ InputDevice * input_dev = calloc (1 , sizeof (InputDevice ));
27632780 input_dev -> wlr_device = & pointer -> base ;
27642781 input_dev -> libinput_device = device ;
27652782
2766- input_dev -> destroy_listener .notify = destroypointer ;
2783+ input_dev -> destroy_listener .notify = destroyinputdevice ;
27672784 wl_signal_add (& pointer -> base .events .destroy , & input_dev -> destroy_listener );
27682785
2769- wl_list_insert (& pointers , & input_dev -> link );
2786+ wl_list_insert (& inputdevices , & input_dev -> link );
27702787
27712788 wlr_cursor_attach_input_device (cursor , & pointer -> base );
27722789}
@@ -2792,27 +2809,32 @@ void switch_toggle(struct wl_listener *listener, void *data) {
27922809}
27932810
27942811void createswitch (struct wlr_switch * switch_device ) {
2812+ struct libinput_device * device =
2813+ wlr_libinput_get_device_handle (& switch_device -> base );
2814+
2815+ InputDevice * input_dev = calloc (1 , sizeof (InputDevice ));
2816+ input_dev -> wlr_device = & switch_device -> base ;
2817+ input_dev -> libinput_device = device ;
2818+ input_dev -> device_data = NULL ; // 初始化为 NULL
2819+
2820+ input_dev -> destroy_listener .notify = destroyinputdevice ;
2821+ wl_signal_add (& switch_device -> base .events .destroy ,
2822+ & input_dev -> destroy_listener );
2823+
2824+ // 创建 Switch 特定数据
27952825 Switch * sw = calloc (1 , sizeof (Switch ));
27962826 sw -> wlr_switch = switch_device ;
27972827 sw -> toggle .notify = switch_toggle ;
2798- wl_signal_add ( & switch_device -> events . toggle , & sw -> toggle ) ;
2828+ sw -> input_dev = input_dev ;
27992829
2800- // 添加到全局列表(可选,用于统一管理)
2801- wl_list_insert (& switches , & sw -> link );
2802- }
2803-
2804- void cleanupswitches () {
2805- Switch * sw , * tmp ;
2806- wl_list_for_each_safe (sw , tmp , & switches , link ) {
2807- // 移除事件监听
2808- wl_list_remove (& sw -> toggle .link );
2830+ // 将 Switch 指针保存到 input_device 中
2831+ input_dev -> device_data = sw ;
28092832
2810- // 从列表中移除
2811- wl_list_remove ( & sw -> link );
2833+ // 添加 toggle 监听器
2834+ wl_signal_add ( & switch_device -> events . toggle , & sw -> toggle );
28122835
2813- // 释放内存
2814- free (sw );
2815- }
2836+ // 添加到全局列表
2837+ wl_list_insert (& inputdevices , & input_dev -> link );
28162838}
28172839
28182840void createpointerconstraint (struct wl_listener * listener , void * data ) {
@@ -3654,7 +3676,7 @@ void motionabsolute(struct wl_listener *listener, void *data) {
36543676 return ;
36553677 }
36563678
3657- if (!event -> time_msec ) /* this is 0 with virtual pointers */
3679+ if (!event -> time_msec ) /* this is 0 with virtual pointer */
36583680 wlr_cursor_warp_absolute (cursor , & event -> pointer -> base , event -> x ,
36593681 event -> y );
36603682
@@ -4756,8 +4778,7 @@ void setup(void) {
47564778 * to let us know when new input devices are available on the backend.
47574779 */
47584780 wl_list_init (& keyboards );
4759- wl_list_init (& pointers );
4760- wl_list_init (& switches );
4781+ wl_list_init (& inputdevices );
47614782 wl_signal_add (& backend -> events .new_input , & new_input_device );
47624783 virtual_keyboard_mgr = wlr_virtual_keyboard_manager_v1_create (dpy );
47634784 wl_signal_add (& virtual_keyboard_mgr -> events .new_virtual_keyboard ,
0 commit comments