feat: add option edge_scroller_focus_allow_speed

This commit is contained in:
DreamMaoMao 2026-05-23 15:21:39 +08:00
parent 373ebfac33
commit 2fefb42a6c
4 changed files with 19 additions and 2 deletions

View file

@ -57,6 +57,7 @@ scroller_default_proportion=0.8
scroller_focus_center=0 scroller_focus_center=0
scroller_prefer_center=0 scroller_prefer_center=0
edge_scroller_pointer_focus=1 edge_scroller_pointer_focus=1
edge_scroller_focus_allow_speed=0.0
scroller_default_proportion_single=1.0 scroller_default_proportion_single=1.0
scroller_proportion_preset=0.5,0.8,1.0 scroller_proportion_preset=0.5,0.8,1.0

View file

@ -38,6 +38,7 @@ The Scroller layout positions windows in a scrollable strip, similar to PaperWM.
| `scroller_prefer_center` | `0` | Center focused window only if it was outside the view. | | `scroller_prefer_center` | `0` | Center focused window only if it was outside the view. |
| `scroller_prefer_overspread` | `1` | Allow windows to overspread when there's extra space. | | `scroller_prefer_overspread` | `1` | Allow windows to overspread when there's extra space. |
| `edge_scroller_pointer_focus` | `1` | Focus windows even if partially off-screen. | | `edge_scroller_pointer_focus` | `1` | Focus windows even if partially off-screen. |
| `edge_scroller_focus_allow_speed` | `0.0` | Allow pointer focus to happen if the pointer moves at a speed greater than this value. |
| `scroller_proportion_preset` | `0.5,0.8,1.0` | Presets for cycling window widths. | | `scroller_proportion_preset` | `0.5,0.8,1.0` | Presets for cycling window widths. |
| `scroller_ignore_proportion_single` | `1` | Ignore proportion adjustments for single windows. | | `scroller_ignore_proportion_single` | `1` | Ignore proportion adjustments for single windows. |
| `scroller_default_proportion_single` | `1.0` | Default proportion for single windows in scroller. **Requires `scroller_ignore_proportion_single=0` to take effect.** | | `scroller_default_proportion_single` | `1.0` | Default proportion for single windows in scroller. **Requires `scroller_ignore_proportion_single=0` to take effect.** |
@ -56,6 +57,7 @@ scroller_focus_center=0
scroller_prefer_center=0 scroller_prefer_center=0
scroller_prefer_overspread=1 scroller_prefer_overspread=1
edge_scroller_pointer_focus=1 edge_scroller_pointer_focus=1
edge_scroller_focus_allow_speed=0.0
scroller_default_proportion_single=1.0 scroller_default_proportion_single=1.0
scroller_proportion_preset=0.5,0.8,1.0 scroller_proportion_preset=0.5,0.8,1.0
``` ```

View file

@ -216,6 +216,7 @@ typedef struct {
int32_t scroller_prefer_center; int32_t scroller_prefer_center;
int32_t scroller_prefer_overspread; int32_t scroller_prefer_overspread;
int32_t edge_scroller_pointer_focus; int32_t edge_scroller_pointer_focus;
double edge_scroller_focus_allow_speed;
int32_t focus_cross_monitor; int32_t focus_cross_monitor;
int32_t exchange_cross_monitor; int32_t exchange_cross_monitor;
int32_t scratchpad_cross_monitor; int32_t scratchpad_cross_monitor;
@ -1396,6 +1397,8 @@ bool parse_option(Config *config, char *key, char *value) {
config->scroller_prefer_overspread = atoi(value); config->scroller_prefer_overspread = atoi(value);
} else if (strcmp(key, "edge_scroller_pointer_focus") == 0) { } else if (strcmp(key, "edge_scroller_pointer_focus") == 0) {
config->edge_scroller_pointer_focus = atoi(value); config->edge_scroller_pointer_focus = atoi(value);
} else if (strcmp(key, "edge_scroller_focus_allow_speed") == 0) {
config->edge_scroller_focus_allow_speed = atof(value);
} else if (strcmp(key, "focus_cross_monitor") == 0) { } else if (strcmp(key, "focus_cross_monitor") == 0) {
config->focus_cross_monitor = atoi(value); config->focus_cross_monitor = atoi(value);
} else if (strcmp(key, "exchange_cross_monitor") == 0) { } else if (strcmp(key, "exchange_cross_monitor") == 0) {
@ -3229,6 +3232,8 @@ void override_config(void) {
CLAMP_INT(config.scroller_prefer_overspread, 0, 1); CLAMP_INT(config.scroller_prefer_overspread, 0, 1);
config.edge_scroller_pointer_focus = config.edge_scroller_pointer_focus =
CLAMP_INT(config.edge_scroller_pointer_focus, 0, 1); CLAMP_INT(config.edge_scroller_pointer_focus, 0, 1);
config.edge_scroller_focus_allow_speed =
CLAMP_FLOAT(config.edge_scroller_focus_allow_speed, 0.0f, 1000.0f);
config.scroller_structs = CLAMP_INT(config.scroller_structs, 0, 1000); config.scroller_structs = CLAMP_INT(config.scroller_structs, 0, 1000);
config.default_mfact = CLAMP_FLOAT(config.default_mfact, 0.1f, 0.9f); config.default_mfact = CLAMP_FLOAT(config.default_mfact, 0.1f, 0.9f);
config.default_nmaster = CLAMP_INT(config.default_nmaster, 1, 1000); config.default_nmaster = CLAMP_INT(config.default_nmaster, 1, 1000);
@ -3423,6 +3428,7 @@ void set_value_default() {
config.scroller_prefer_center = 0; config.scroller_prefer_center = 0;
config.scroller_prefer_overspread = 1; config.scroller_prefer_overspread = 1;
config.edge_scroller_pointer_focus = 1; config.edge_scroller_pointer_focus = 1;
config.edge_scroller_focus_allow_speed = 0.0f;
config.focus_cross_monitor = 0; config.focus_cross_monitor = 0;
config.exchange_cross_monitor = 0; config.exchange_cross_monitor = 0;
config.scratchpad_cross_monitor = 0; config.scratchpad_cross_monitor = 0;

View file

@ -4789,14 +4789,22 @@ void motionnotify(uint32_t time, struct wlr_input_device *device, double dx,
} }
should_lock = false; should_lock = false;
double speed = 0.0f;
if (config.edge_scroller_pointer_focus) {
speed = sqrt(dx * dx + dy * dy);
}
if (!scroller_focus_lock || !(c && c->mon && !INSIDEMON(c))) { if (!scroller_focus_lock || !(c && c->mon && !INSIDEMON(c))) {
if (c && c->mon && is_scroller_layout(c->mon) && !INSIDEMON(c)) { if (c && c->mon && is_scroller_layout(c->mon) && !INSIDEMON(c)) {
should_lock = true; should_lock = true;
} }
if (!(!config.edge_scroller_pointer_focus && c && c->mon && if (!((!config.edge_scroller_pointer_focus ||
is_scroller_layout(c->mon) && !INSIDEMON(c))) speed < config.edge_scroller_focus_allow_speed) &&
c && c->mon && is_scroller_layout(c->mon) && !INSIDEMON(c))) {
pointerfocus(c, surface, sx, sy, time); pointerfocus(c, surface, sx, sy, time);
}
if (should_lock && c && c->mon && ISTILED(c) && c == c->mon->sel) { if (should_lock && c && c->mon && ISTILED(c) && c == c->mon->sel) {
scroller_focus_lock = 1; scroller_focus_lock = 1;