mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2026-07-06 00:06:43 -04:00
better feedback with no animations and multi-gesture handling
This commit is contained in:
parent
596e0a9ed3
commit
868feb48b7
6 changed files with 122 additions and 55 deletions
|
|
@ -120,6 +120,7 @@ swipe_min_threshold=1
|
|||
gesturebind=none,horizontal,4,tagscrub
|
||||
gesture_swipe_distance=500
|
||||
gesture_commit_ratio=0.5
|
||||
gesture_axis_lock=16
|
||||
|
||||
# mouse
|
||||
# need relogin to make it apply
|
||||
|
|
|
|||
|
|
@ -107,6 +107,8 @@ The scrub follows your `trackpad_natural_scrolling` setting.
|
|||
|
||||
`gesture_commit_ratio` (0–1, default `0.5`) sets how far through that distance you must swipe to commit a `tagscrub`, e.g. `0.3` commits after 30%. A fast flick can commit a bit below this via momentum.
|
||||
|
||||
`gesture_axis_lock` (px, default `16`) is how far the swipe must travel before the scrub decides whether it's along its axis. Raise it if imprecise swipes get misread.
|
||||
|
||||
```ini
|
||||
gesture_swipe_distance=500
|
||||
gesture_commit_ratio=0.5
|
||||
|
|
|
|||
|
|
@ -50,6 +50,23 @@ static inline void tag_scrub_stage(Monitor *m, int dir) {
|
|||
m->scrub_rubberband = false;
|
||||
m->scrub_incoming_tag = (uint32_t)target;
|
||||
|
||||
/* Mango lays out tags lazily: a tag you moved a window off of
|
||||
* keeps stale window geometry until it's viewed. This is very annoying
|
||||
* Here i try to predict the arrangement of the tag just so the tags don't
|
||||
* appear miss-aligned in the scrub.
|
||||
* */
|
||||
{
|
||||
uint32_t saved_curtag = m->pertag->curtag;
|
||||
uint32_t saved_tagset = m->tagset[m->seltags];
|
||||
m->pertag->curtag = (uint32_t)target;
|
||||
m->tagset[m->seltags] = (1u << (target - 1));
|
||||
pre_caculate_before_arrange(m, false, false, true);
|
||||
m->pertag->ltidxs[target]->arrange(m);
|
||||
m->pertag->curtag = saved_curtag;
|
||||
m->tagset[m->seltags] = saved_tagset;
|
||||
pre_caculate_before_arrange(m, false, false, true);
|
||||
}
|
||||
|
||||
Client *c;
|
||||
uint32_t inbit = 1u << (target - 1);
|
||||
wl_list_for_each(c, &clients, link) {
|
||||
|
|
@ -122,6 +139,23 @@ static inline void tag_scrub_apply(Monitor *m, double progress) {
|
|||
|
||||
static inline bool tag_scrub_active(Monitor *m) { return m && m->scrub_active; }
|
||||
|
||||
static inline bool tag_scrub_engaged(Monitor *m) {
|
||||
return m && m->scrub_active && m->scrub_axis_locked;
|
||||
}
|
||||
|
||||
static inline void tag_scrub_abort(Monitor *m) {
|
||||
if (!m)
|
||||
return;
|
||||
m->scrub_active = false;
|
||||
m->scrub_axis_locked = false;
|
||||
m->scrub_dir = 0;
|
||||
m->scrub_progress = 0.0;
|
||||
m->scrub_accum = 0.0;
|
||||
m->scrub_velocity = 0.0;
|
||||
m->scrub_incoming_tag = 0;
|
||||
m->scrub_rubberband = false;
|
||||
}
|
||||
|
||||
static inline bool tag_scrub_arm(Monitor *m, const GestureBinding *g) {
|
||||
if (!m || m->isoverview || m->pertag->curtag == 0)
|
||||
return false;
|
||||
|
|
@ -136,6 +170,7 @@ static inline bool tag_scrub_arm(Monitor *m, const GestureBinding *g) {
|
|||
m->scrub_velocity = 0.0;
|
||||
m->scrub_last_delta = 0.0;
|
||||
m->scrub_last_time = 0;
|
||||
m->scrub_axis_locked = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -143,6 +178,21 @@ static inline void tag_scrub_feed(Monitor *m, double dx, double dy,
|
|||
uint32_t time_msec) {
|
||||
if (!m->scrub_active)
|
||||
return;
|
||||
|
||||
if (!m->scrub_axis_locked) {
|
||||
double along = (m->scrub_axis == HORIZONTAL) ? swipe_dx : swipe_dy;
|
||||
double perp = (m->scrub_axis == HORIZONTAL) ? swipe_dy : swipe_dx;
|
||||
double a = along < 0 ? -along : along;
|
||||
double p = perp < 0 ? -perp : perp;
|
||||
if (a + p < (double)config.gesture_axis_lock)
|
||||
return;
|
||||
if (p > a) {
|
||||
m->scrub_active = false;
|
||||
return;
|
||||
}
|
||||
m->scrub_axis_locked = true;
|
||||
}
|
||||
|
||||
double delta = (m->scrub_axis == HORIZONTAL) ? dx : dy;
|
||||
if (config.trackpad_natural_scrolling)
|
||||
delta = -delta;
|
||||
|
|
@ -162,7 +212,13 @@ static inline void tag_scrub_feed(Monitor *m, double dx, double dy,
|
|||
|
||||
if (!config.animations) {
|
||||
m->scrub_dir = (int8_t)dir;
|
||||
m->scrub_progress = mag_p;
|
||||
uint32_t mask = tag_scrub_occupied_mask(m);
|
||||
int target =
|
||||
tag_scrub_neighbor((int)m->pertag->curtag, dir, LENGTH(tags), mask,
|
||||
m->scrub_have_client, config.tag_carousel);
|
||||
m->scrub_rubberband = (dir != 0 && target == 0);
|
||||
m->scrub_incoming_tag = 0;
|
||||
tag_scrub_apply(m, mag_p);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -178,35 +234,32 @@ static inline void tag_scrub_release(Monitor *m, bool cancelled) {
|
|||
if (!m->scrub_active)
|
||||
return;
|
||||
|
||||
if (!config.animations) {
|
||||
double oriented_v = m->scrub_velocity * (double)m->scrub_dir;
|
||||
if (!cancelled && m->scrub_dir != 0 &&
|
||||
gesture_scrub_should_commit(m->scrub_progress, oriented_v,
|
||||
config.gesture_commit_ratio)) {
|
||||
uint32_t mask = tag_scrub_occupied_mask(m);
|
||||
int target = tag_scrub_neighbor(
|
||||
(int)m->pertag->curtag, m->scrub_dir, LENGTH(tags), mask,
|
||||
m->scrub_have_client, config.tag_carousel);
|
||||
if (target != 0)
|
||||
view_in_mon(&(Arg){.ui = 1u << (target - 1)}, false, m, true);
|
||||
}
|
||||
m->scrub_active = false;
|
||||
m->scrub_dir = 0;
|
||||
m->scrub_progress = 0.0;
|
||||
m->scrub_accum = 0.0;
|
||||
m->scrub_velocity = 0.0;
|
||||
return;
|
||||
}
|
||||
|
||||
double oriented_v = m->scrub_velocity * (double)m->scrub_dir;
|
||||
bool commit = !cancelled && !m->scrub_rubberband && m->scrub_incoming_tag &&
|
||||
if (!config.animations) {
|
||||
bool commit = !cancelled && m->scrub_dir != 0 && !m->scrub_rubberband &&
|
||||
gesture_scrub_should_commit(m->scrub_progress, oriented_v,
|
||||
config.gesture_commit_ratio);
|
||||
int target = 0;
|
||||
if (commit) {
|
||||
uint32_t mask = tag_scrub_occupied_mask(m);
|
||||
target = tag_scrub_neighbor(
|
||||
(int)m->pertag->curtag, m->scrub_dir, LENGTH(tags), mask,
|
||||
m->scrub_have_client, config.tag_carousel);
|
||||
}
|
||||
if (target != 0)
|
||||
view_in_mon(&(Arg){.ui = 1u << (target - 1)}, false, m, true);
|
||||
else
|
||||
arrange(m, true, true);
|
||||
} else {
|
||||
bool commit = !cancelled && !m->scrub_rubberband &&
|
||||
m->scrub_incoming_tag &&
|
||||
gesture_scrub_should_commit(m->scrub_progress, oriented_v,
|
||||
config.gesture_commit_ratio);
|
||||
|
||||
if (commit) {
|
||||
Client *c;
|
||||
uint32_t inbit = 1u << (m->scrub_incoming_tag - 1);
|
||||
uint32_t curbit = 1u << (m->pertag->curtag - 1);
|
||||
Client *c;
|
||||
wl_list_for_each(c, &clients, link) {
|
||||
if (c->mon == m && ISTILED(c) &&
|
||||
((c->tags & inbit) || (c->tags & curbit)))
|
||||
|
|
@ -222,8 +275,8 @@ static inline void tag_scrub_release(Monitor *m, bool cancelled) {
|
|||
wl_list_for_each(c, &clients, link) {
|
||||
if (c->mon != m || !ISTILED(c))
|
||||
continue;
|
||||
bool is_incoming =
|
||||
inbit && (c->tags & inbit) && !(c->isglobal || c->isunglobal);
|
||||
bool is_incoming = inbit && (c->tags & inbit) &&
|
||||
!(c->isglobal || c->isunglobal);
|
||||
if (!is_incoming && !(c->tags & curbit))
|
||||
continue;
|
||||
|
||||
|
|
@ -239,8 +292,10 @@ static inline void tag_scrub_release(Monitor *m, bool cancelled) {
|
|||
}
|
||||
request_fresh_all_monitors();
|
||||
}
|
||||
}
|
||||
|
||||
m->scrub_active = false;
|
||||
m->scrub_axis_locked = false;
|
||||
m->scrub_dir = 0;
|
||||
m->scrub_progress = 0.0;
|
||||
m->scrub_accum = 0.0;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ static inline int tag_scrub_neighbor(int curtag, int dir, int ntags,
|
|||
bool wrap) {
|
||||
if (curtag < 1 || curtag > ntags || (dir != 1 && dir != -1))
|
||||
return 0;
|
||||
bool only_current_occupied = (occupied_mask & ~(1u << (curtag - 1))) == 0;
|
||||
bool skip_empty = have_client && !only_current_occupied;
|
||||
int t = curtag;
|
||||
for (int step = 0; step < ntags; step++) {
|
||||
t += dir;
|
||||
|
|
@ -35,7 +37,7 @@ static inline int tag_scrub_neighbor(int curtag, int dir, int ntags,
|
|||
}
|
||||
if (t == curtag)
|
||||
return 0;
|
||||
if (!have_client)
|
||||
if (!skip_empty)
|
||||
return t;
|
||||
if (occupied_mask & (1u << (t - 1)))
|
||||
return t;
|
||||
|
|
|
|||
|
|
@ -238,6 +238,7 @@ typedef struct {
|
|||
uint32_t swipe_min_threshold;
|
||||
float gesture_commit_ratio;
|
||||
int32_t gesture_swipe_distance;
|
||||
int32_t gesture_axis_lock;
|
||||
float focused_opacity;
|
||||
float unfocused_opacity;
|
||||
float *scroller_proportion_preset;
|
||||
|
|
@ -1538,6 +1539,8 @@ bool parse_option(Config *config, char *key, char *value) {
|
|||
config->gesture_commit_ratio = atof(value);
|
||||
} else if (strcmp(key, "gesture_swipe_distance") == 0) {
|
||||
config->gesture_swipe_distance = atoi(value);
|
||||
} else if (strcmp(key, "gesture_axis_lock") == 0) {
|
||||
config->gesture_axis_lock = atoi(value);
|
||||
} else if (strcmp(key, "focused_opacity") == 0) {
|
||||
config->focused_opacity = atof(value);
|
||||
} else if (strcmp(key, "unfocused_opacity") == 0) {
|
||||
|
|
@ -3569,6 +3572,7 @@ void override_config(void) {
|
|||
CLAMP_FLOAT(config.gesture_commit_ratio, 0.0f, 1.0f);
|
||||
config.gesture_swipe_distance =
|
||||
CLAMP_INT(config.gesture_swipe_distance, 50, 4000);
|
||||
config.gesture_axis_lock = CLAMP_INT(config.gesture_axis_lock, 0, 1000);
|
||||
config.mouse_natural_scrolling =
|
||||
CLAMP_INT(config.mouse_natural_scrolling, 0, 1);
|
||||
config.mouse_accel_profile = CLAMP_INT(config.mouse_accel_profile, 0, 2);
|
||||
|
|
@ -3726,6 +3730,7 @@ void set_value_default() {
|
|||
config.swipe_min_threshold = 1;
|
||||
config.gesture_commit_ratio = 0.5f;
|
||||
config.gesture_swipe_distance = 500;
|
||||
config.gesture_axis_lock = 16;
|
||||
|
||||
config.idleinhibit_ignore_visible = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -591,6 +591,7 @@ struct Monitor {
|
|||
double scrub_last_delta;
|
||||
uint32_t scrub_last_time;
|
||||
double scrub_velocity;
|
||||
bool scrub_axis_locked;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -2212,9 +2213,10 @@ void swipe_update(struct wl_listener *listener, void *data) {
|
|||
void swipe_end(struct wl_listener *listener, void *data) {
|
||||
struct wlr_pointer_swipe_end_event *event = data;
|
||||
|
||||
if (tag_scrub_active(selmon)) {
|
||||
if (tag_scrub_engaged(selmon)) {
|
||||
tag_scrub_release(selmon, event->cancelled);
|
||||
} else {
|
||||
tag_scrub_abort(selmon);
|
||||
ongesture(event);
|
||||
}
|
||||
swipe_dx = 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue