Merge pull request #889 from pix-code/main

feat: add trackpad accel config options
This commit is contained in:
DreamMaoMao 2026-05-04 12:23:49 +08:00 committed by GitHub
commit 2960bc063b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 108 additions and 72 deletions

View file

@ -154,7 +154,7 @@ meson build -Dprefix=/usr
sudo ninja -C build install sudo ninja -C build install
git clone https://github.com/mangowm/mango.git git clone https://github.com/mangowm/mango.git
cd mangowm cd mango
meson build -Dprefix=/usr meson build -Dprefix=/usr
sudo ninja -C build install sudo ninja -C build install
``` ```

View file

@ -35,6 +35,19 @@ xkb_rules_options=caps:escape,ctrl:nocaps
--- ---
### Mouse Settings
Configuration for external mice.
| Setting | Default | Description |
| :--- | :--- | :--- |
| `mouse_natural_scrolling` | `0` | Invert scrolling direction. |
| `mouse_accel_profile` | `2` | `0` (None), `1` (Flat), `2` (Adaptive). |
| `mouse_accel_speed` | `0.0` | Speed adjustment (-1.0 to 1.0). |
| `left_handed` | `0` | Swap left and right buttons. |
| `axis_scroll_factor` | `1.0` | Scroll factor for axis scroll speed (0.110.0). |
---
### Trackpad Settings ### Trackpad Settings
Specific settings for laptop touchpads. Some settings may require a relogin to take effect. Specific settings for laptop touchpads. Some settings may require a relogin to take effect.
@ -45,15 +58,19 @@ Specific settings for laptop touchpads. Some settings may require a relogin to t
| `tap_to_click` | `1` | Tap to trigger a left click. | | `tap_to_click` | `1` | Tap to trigger a left click. |
| `tap_and_drag` | `1` | Tap and hold to drag items. | | `tap_and_drag` | `1` | Tap and hold to drag items. |
| `trackpad_natural_scrolling` | `0` | Invert scrolling direction (natural scrolling). | | `trackpad_natural_scrolling` | `0` | Invert scrolling direction (natural scrolling). |
| `trackpad_accel_profile` | `2` | `0` (None), `1` (Flat), `2` (Adaptive). |
| `trackpad_accel_speed` | `0.0` | Speed adjustment (-1.0 to 1.0). |
| `scroll_button` | `274` | The mouse button that use for scrolling(272 to 279). | `scroll_button` | `274` | The mouse button that use for scrolling(272 to 279).
| `scroll_method` | `1` | `1` (Two-finger), `2` (Edge), `4` (Button). | | `scroll_method` | `1` | `1` (Two-finger), `2` (Edge), `4` (Button). |
| `click_method` | `1` | `1` (Button areas), `2` (Clickfinger). | | `click_method` | `1` | `1` (Button areas), `2` (Clickfinger). |
| `send_events_mode` | `0` | `0` (Enabled), `1` (Disabled), `2` (Disabled on external mouse). |
| `drag_lock` | `1` | Lock dragging after tapping. | | `drag_lock` | `1` | Lock dragging after tapping. |
| `disable_while_typing` | `1` | Disable trackpad while typing. | | `disable_while_typing` | `1` | Disable trackpad while typing. |
| `left_handed` | `0` | Swap left/right buttons. | | `left_handed` | `0` | Swap left/right buttons. |
| `middle_button_emulation` | `0` | Emulate middle button. | | `middle_button_emulation` | `0` | Emulate middle button. |
| `swipe_min_threshold` | `1` | Minimum swipe threshold. | | `swipe_min_threshold` | `1` | Minimum swipe threshold when use gesture. |
| `button_map` | `0` | `0` (Left/right/middle), `1` (Left/middle/right). |
| `trackpad_scroll_factor` | `1.0` | Scroll factor for trackpad scroll speed (0.110.0). |
--- ---
**Detailed descriptions:** **Detailed descriptions:**
@ -79,9 +96,9 @@ Specific settings for laptop touchpads. Some settings may require a relogin to t
- `1` — Button areas: use software-defined areas on the touchpad to generate button events. - `1` — Button areas: use software-defined areas on the touchpad to generate button events.
- `2` — Clickfinger: the number of fingers determines which button is pressed. - `2` — Clickfinger: the number of fingers determines which button is pressed.
- `accel_profile` values: - `mouse_accel_profile` or `trackpad_scroll_profile` values:
- `0` — No acceleration. - `0` — No acceleration.
- `1` — Flat: no dynamic acceleration. Pointer speed = original input speed × (1 + `accel_speed`). - `1` — Flat: no dynamic acceleration. Pointer speed = original input speed × (1 + `mouse_accel_speed`).
- `2` — Adaptive: slow movement results in less acceleration, fast movement results in more. - `2` — Adaptive: slow movement results in less acceleration, fast movement results in more.
- `button_map` values: - `button_map` values:
@ -94,24 +111,6 @@ Specific settings for laptop touchpads. Some settings may require a relogin to t
- `2` — Disable this device when an external pointer device is plugged in. - `2` — Disable this device when an external pointer device is plugged in.
--- ---
### Mouse Settings
Configuration for external mice.
| Setting | Default | Description |
| :--- | :--- | :--- |
| `mouse_natural_scrolling` | `0` | Invert scrolling direction. |
| `accel_profile` | `2` | `0` (None), `1` (Flat), `2` (Adaptive). |
| `accel_speed` | `0.0` | Speed adjustment (-1.0 to 1.0). |
| `left_handed` | `0` | Swap left and right buttons. |
| `middle_button_emulation` | `0` | Emulate middle button. |
| `swipe_min_threshold` | `1` | Minimum swipe threshold. |
| `send_events_mode` | `0` | `0` (Enabled), `1` (Disabled), `2` (Disabled on external mouse). |
| `button_map` | `0` | `0` (Left/right/middle), `1` (Left/middle/right). |
---
--- ---
## Keyboard Layout Switching ## Keyboard Layout Switching

View file

@ -25,7 +25,6 @@ description: Advanced settings for XWayland, focus behavior, and system integrat
| `drag_corner` | `3` | Corner for drag-to-tile detection (0: none, 13: corners, 4: auto-detect). | | `drag_corner` | `3` | Corner for drag-to-tile detection (0: none, 13: corners, 4: auto-detect). |
| `drag_warp_cursor` | `1` | Warp cursor when dragging windows to tile. | | `drag_warp_cursor` | `1` | Warp cursor when dragging windows to tile. |
| `axis_bind_apply_timeout` | `100` | Timeout (ms) for detecting consecutive scroll events for axis bindings. | | `axis_bind_apply_timeout` | `100` | Timeout (ms) for detecting consecutive scroll events for axis bindings. |
| `axis_scroll_factor` | `1.0` | Scroll factor for axis scroll speed (0.110.0). |
## Multi-Monitor & Tags ## Multi-Monitor & Tags

View file

@ -262,26 +262,33 @@ typedef struct {
int32_t repeat_delay; int32_t repeat_delay;
uint32_t numlockon; uint32_t numlockon;
/* Trackpad */ /* common pointer */
int32_t disable_trackpad;
int32_t tap_to_click;
int32_t tap_and_drag;
int32_t drag_lock;
int32_t mouse_natural_scrolling;
int32_t trackpad_natural_scrolling;
int32_t disable_while_typing; int32_t disable_while_typing;
int32_t left_handed; int32_t left_handed;
int32_t middle_button_emulation; int32_t middle_button_emulation;
uint32_t accel_profile;
double accel_speed;
uint32_t scroll_method; uint32_t scroll_method;
uint32_t scroll_button; uint32_t scroll_button;
uint32_t click_method; uint32_t click_method;
uint32_t send_events_mode; uint32_t send_events_mode;
uint32_t button_map;
/* mouse */
int32_t mouse_natural_scrolling;
uint32_t mouse_accel_profile;
double mouse_accel_speed;
double axis_scroll_factor; double axis_scroll_factor;
/* Trackpad */
int32_t trackpad_natural_scrolling;
uint32_t trackpad_accel_profile;
double trackpad_accel_speed;
double trackpad_scroll_factor;
int32_t disable_trackpad;
int32_t tap_to_click;
int32_t tap_and_drag;
int32_t drag_lock;
uint32_t button_map;
/* window effects */
int32_t blur; int32_t blur;
int32_t blur_layer; int32_t blur_layer;
int32_t blur_optimized; int32_t blur_optimized;
@ -297,6 +304,7 @@ typedef struct {
int32_t shadows_position_y; int32_t shadows_position_y;
float shadowscolor[4]; float shadowscolor[4];
/* appearance */
int32_t smartgaps; int32_t smartgaps;
uint32_t gappih; uint32_t gappih;
uint32_t gappiv; uint32_t gappiv;
@ -1661,10 +1669,14 @@ bool parse_option(Config *config, char *key, char *value) {
config->left_handed = atoi(value); config->left_handed = atoi(value);
} else if (strcmp(key, "middle_button_emulation") == 0) { } else if (strcmp(key, "middle_button_emulation") == 0) {
config->middle_button_emulation = atoi(value); config->middle_button_emulation = atoi(value);
} else if (strcmp(key, "accel_profile") == 0) { } else if (strcmp(key, "mouse_accel_profile") == 0) {
config->accel_profile = atoi(value); config->mouse_accel_profile = atoi(value);
} else if (strcmp(key, "accel_speed") == 0) { } else if (strcmp(key, "mouse_accel_speed") == 0) {
config->accel_speed = atof(value); config->mouse_accel_speed = atof(value);
} else if (strcmp(key, "trackpad_accel_profile") == 0) {
config->trackpad_accel_profile = atoi(value);
} else if (strcmp(key, "trackpad_accel_speed") == 0) {
config->trackpad_accel_speed = atof(value);
} else if (strcmp(key, "scroll_method") == 0) { } else if (strcmp(key, "scroll_method") == 0) {
config->scroll_method = atoi(value); config->scroll_method = atoi(value);
} else if (strcmp(key, "scroll_button") == 0) { } else if (strcmp(key, "scroll_button") == 0) {
@ -1677,6 +1689,8 @@ bool parse_option(Config *config, char *key, char *value) {
config->button_map = atoi(value); config->button_map = atoi(value);
} else if (strcmp(key, "axis_scroll_factor") == 0) { } else if (strcmp(key, "axis_scroll_factor") == 0) {
config->axis_scroll_factor = atof(value); config->axis_scroll_factor = atof(value);
} else if (strcmp(key, "trackpad_scroll_factor") == 0) {
config->trackpad_scroll_factor = atof(value);
} else if (strcmp(key, "gappih") == 0) { } else if (strcmp(key, "gappih") == 0) {
config->gappih = atoi(value); config->gappih = atoi(value);
} else if (strcmp(key, "gappiv") == 0) { } else if (strcmp(key, "gappiv") == 0) {
@ -3210,8 +3224,13 @@ void override_config(void) {
config.swipe_min_threshold = CLAMP_INT(config.swipe_min_threshold, 1, 1000); config.swipe_min_threshold = CLAMP_INT(config.swipe_min_threshold, 1, 1000);
config.mouse_natural_scrolling = config.mouse_natural_scrolling =
CLAMP_INT(config.mouse_natural_scrolling, 0, 1); CLAMP_INT(config.mouse_natural_scrolling, 0, 1);
config.accel_profile = CLAMP_INT(config.accel_profile, 0, 2); config.mouse_accel_profile = CLAMP_INT(config.mouse_accel_profile, 0, 2);
config.accel_speed = CLAMP_FLOAT(config.accel_speed, -1.0f, 1.0f); config.mouse_accel_speed =
CLAMP_FLOAT(config.mouse_accel_speed, -1.0f, 1.0f);
config.trackpad_accel_profile =
CLAMP_INT(config.trackpad_accel_profile, 0, 2);
config.trackpad_accel_speed =
CLAMP_FLOAT(config.trackpad_accel_speed, -1.0f, 1.0f);
config.scroll_method = CLAMP_INT(config.scroll_method, 0, 4); config.scroll_method = CLAMP_INT(config.scroll_method, 0, 4);
config.scroll_button = CLAMP_INT(config.scroll_button, 272, 279); config.scroll_button = CLAMP_INT(config.scroll_button, 272, 279);
config.click_method = CLAMP_INT(config.click_method, 0, 2); config.click_method = CLAMP_INT(config.click_method, 0, 2);
@ -3219,6 +3238,8 @@ void override_config(void) {
config.button_map = CLAMP_INT(config.button_map, 0, 1); config.button_map = CLAMP_INT(config.button_map, 0, 1);
config.axis_scroll_factor = config.axis_scroll_factor =
CLAMP_FLOAT(config.axis_scroll_factor, 0.1f, 10.0f); CLAMP_FLOAT(config.axis_scroll_factor, 0.1f, 10.0f);
config.trackpad_scroll_factor =
CLAMP_FLOAT(config.trackpad_scroll_factor, 0.1f, 10.0f);
config.gappih = CLAMP_INT(config.gappih, 0, 1000); config.gappih = CLAMP_INT(config.gappih, 0, 1000);
config.gappiv = CLAMP_INT(config.gappiv, 0, 1000); config.gappiv = CLAMP_INT(config.gappiv, 0, 1000);
config.gappoh = CLAMP_INT(config.gappoh, 0, 1000); config.gappoh = CLAMP_INT(config.gappoh, 0, 1000);
@ -3311,6 +3332,7 @@ void set_value_default() {
config.scratchpad_cross_monitor = 0; config.scratchpad_cross_monitor = 0;
config.focus_cross_tag = 0; config.focus_cross_tag = 0;
config.axis_scroll_factor = 1.0; config.axis_scroll_factor = 1.0;
config.trackpad_scroll_factor = 1.0;
config.view_current_to_back = 0; config.view_current_to_back = 0;
config.single_scratchpad = 1; config.single_scratchpad = 1;
config.xwayland_persistence = 1; config.xwayland_persistence = 1;
@ -3351,8 +3373,10 @@ void set_value_default() {
config.disable_while_typing = 1; config.disable_while_typing = 1;
config.left_handed = 0; config.left_handed = 0;
config.middle_button_emulation = 0; config.middle_button_emulation = 0;
config.accel_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE; config.mouse_accel_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE;
config.accel_speed = 0.0; config.mouse_accel_speed = 0.0;
config.trackpad_accel_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE;
config.trackpad_accel_speed = 0.0;
config.scroll_method = LIBINPUT_CONFIG_SCROLL_2FG; config.scroll_method = LIBINPUT_CONFIG_SCROLL_2FG;
config.scroll_button = 274; config.scroll_button = 274;
config.click_method = LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS; config.click_method = LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS;

View file

@ -1838,9 +1838,21 @@ void arrangelayers(Monitor *m) {
arrangelayer(m, &m->layers[i], &usable_area, 0); arrangelayer(m, &m->layers[i], &usable_area, 0);
} }
bool pointer_is_trackpad(struct wlr_pointer *pointer) {
struct libinput_device *device;
if (wlr_input_device_is_libinput(&pointer->base) &&
(device = wlr_libinput_get_device_handle(&pointer->base))) {
if (libinput_device_config_tap_get_finger_count(device) > 0) {
return true;
}
}
return false;
}
void // 鼠标滚轮事件 void // 鼠标滚轮事件
axisnotify(struct wl_listener *listener, void *data) { axisnotify(struct wl_listener *listener, void *data) {
/* This event is forwarded by the cursor when a pointer emits an axis event, /* This event is forwarded by the cursor when a pointer emits an axis event,
* for example when you move the scroll wheel. */ * for example when you move the scroll wheel. */
struct wlr_pointer_axis_event *event = data; struct wlr_pointer_axis_event *event = data;
@ -1849,6 +1861,7 @@ axisnotify(struct wl_listener *listener, void *data) {
AxisBinding *a; AxisBinding *a;
int32_t ji; int32_t ji;
uint32_t adir; uint32_t adir;
double target_scroll_factor;
// IDLE_NOTIFY_ACTIVITY; // IDLE_NOTIFY_ACTIVITY;
handlecursoractivity(); handlecursoractivity();
wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
@ -1895,12 +1908,17 @@ axisnotify(struct wl_listener *listener, void *data) {
* implemented checking the event's orientation and the delta of the event * implemented checking the event's orientation and the delta of the event
*/ */
/* Notify the client with pointer focus of the axis event. */ /* Notify the client with pointer focus of the axis event. */
target_scroll_factor = pointer_is_trackpad(event->pointer)
? config.axis_scroll_factor
: config.trackpad_scroll_factor;
wlr_seat_pointer_notify_axis( wlr_seat_pointer_notify_axis(
seat, // 滚轮事件发送给客户端也就是窗口 seat, // 滚轮事件发送给客户端也就是窗口
event->time_msec, event->orientation, event->time_msec, event->orientation,
event->delta * config.axis_scroll_factor, event->delta * config.axis_scroll_factor,
roundf(event->delta_discrete * config.axis_scroll_factor), roundf(event->delta_discrete * target_scroll_factor), event->source,
event->source, event->relative_direction); event->relative_direction);
} }
int32_t ongesture(struct wlr_pointer_swipe_end_event *event) { int32_t ongesture(struct wlr_pointer_swipe_end_event *event) {
@ -2054,21 +2072,11 @@ void place_drag_tile_client(Client *c) {
} }
bool check_trackpad_disabled(struct wlr_pointer *pointer) { bool check_trackpad_disabled(struct wlr_pointer *pointer) {
struct libinput_device *device; if (!config.disable_trackpad) {
if (!config.disable_trackpad)
return false; return false;
if (wlr_input_device_is_libinput(&pointer->base) &&
(device = wlr_libinput_get_device_handle(&pointer->base))) {
// 如果是触摸板且被禁用,忽略事件
if (libinput_device_config_tap_get_finger_count(device) > 0) {
return true; // 不处理事件
}
} }
return false; return pointer_is_trackpad(pointer);
} }
void // 鼠标按键事件 void // 鼠标按键事件
@ -3206,6 +3214,22 @@ void destroyinputdevice(struct wl_listener *listener, void *data) {
free(input_dev); free(input_dev);
} }
void pointer_set_accel(struct libinput_device *device, bool natural_scrolling,
uint32_t mouse_accel_profile, double mouse_accel_speed) {
libinput_device_config_scroll_set_natural_scroll_enabled(device,
natural_scrolling);
if (mouse_accel_profile &&
libinput_device_config_accel_is_available(device)) {
libinput_device_config_accel_set_profile(device, mouse_accel_profile);
libinput_device_config_accel_set_speed(device, mouse_accel_speed);
} else {
// profile cannot be directly applied to 0, need to set to 1 first
libinput_device_config_accel_set_profile(device, 1);
libinput_device_config_accel_set_profile(device, 0);
libinput_device_config_accel_set_speed(device, 0);
}
}
void configure_pointer(struct libinput_device *device) { void configure_pointer(struct libinput_device *device) {
if (libinput_device_config_tap_get_finger_count(device)) { if (libinput_device_config_tap_get_finger_count(device)) {
libinput_device_config_tap_set_enabled(device, config.tap_to_click); libinput_device_config_tap_set_enabled(device, config.tap_to_click);
@ -3214,11 +3238,12 @@ void configure_pointer(struct libinput_device *device) {
libinput_device_config_tap_set_drag_lock_enabled(device, libinput_device_config_tap_set_drag_lock_enabled(device,
config.drag_lock); config.drag_lock);
libinput_device_config_tap_set_button_map(device, config.button_map); libinput_device_config_tap_set_button_map(device, config.button_map);
libinput_device_config_scroll_set_natural_scroll_enabled( pointer_set_accel(device, config.trackpad_natural_scrolling,
device, config.trackpad_natural_scrolling); config.trackpad_accel_profile,
config.trackpad_accel_speed);
} else { } else {
libinput_device_config_scroll_set_natural_scroll_enabled( pointer_set_accel(device, config.mouse_natural_scrolling,
device, config.mouse_natural_scrolling); config.mouse_accel_profile, config.mouse_accel_speed);
} }
if (libinput_device_config_dwt_is_available(device)) if (libinput_device_config_dwt_is_available(device))
@ -3246,17 +3271,6 @@ void configure_pointer(struct libinput_device *device) {
if (libinput_device_config_send_events_get_modes(device)) if (libinput_device_config_send_events_get_modes(device))
libinput_device_config_send_events_set_mode(device, libinput_device_config_send_events_set_mode(device,
config.send_events_mode); config.send_events_mode);
if (config.accel_profile &&
libinput_device_config_accel_is_available(device)) {
libinput_device_config_accel_set_profile(device, config.accel_profile);
libinput_device_config_accel_set_speed(device, config.accel_speed);
} else {
// profile cannot be directly applied to 0, need to set to 1 first
libinput_device_config_accel_set_profile(device, 1);
libinput_device_config_accel_set_profile(device, 0);
libinput_device_config_accel_set_speed(device, 0);
}
} }
void createpointer(struct wlr_pointer *pointer) { void createpointer(struct wlr_pointer *pointer) {