diff --git a/config.conf b/config.conf index 67726c7..f4c1ab0 100644 --- a/config.conf +++ b/config.conf @@ -49,7 +49,8 @@ sloppyfocus=1 warpcursor=1 focus_cross_monitor=0 focus_cross_tag=1 - +enable_floating_snap=1 +snap_distance=80 # keyboard repeat_rate=25 diff --git a/src/config/parse_config.h b/src/config/parse_config.h index 0e50151..501979b 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -108,6 +108,8 @@ typedef struct { int scroller_prefer_center; int focus_cross_monitor; int focus_cross_tag; + int snap_distance; + int enable_floating_snap; unsigned int swipe_min_threshold; float *scroller_proportion_preset; int scroller_proportion_preset_count; @@ -604,6 +606,10 @@ void parse_config_line(Config *config, const char *line) { config->focus_cross_monitor = atoi(value); } else if (strcmp(key, "focus_cross_tag") == 0) { config->focus_cross_tag = atoi(value); + } else if (strcmp(key, "snap_distance") == 0) { + config->snap_distance = atoi(value); + } else if (strcmp(key, "enable_floating_snap") == 0) { + config->enable_floating_snap = atoi(value); } else if (strcmp(key, "swipe_min_threshold") == 0) { config->swipe_min_threshold = atoi(value); } else if (strcmp(key, "scroller_proportion_preset") == 0) { @@ -1220,6 +1226,8 @@ void override_config(void) { scroller_focus_center = config.scroller_focus_center; focus_cross_monitor = config.focus_cross_monitor; focus_cross_tag = config.focus_cross_tag; + snap_distance = config.snap_distance; + enable_floating_snap = config.enable_floating_snap; swipe_min_threshold = config.swipe_min_threshold; scroller_prefer_center = config.scroller_prefer_center; @@ -1314,6 +1322,8 @@ void set_value_default() { config.scroller_prefer_center = scroller_prefer_center; config.focus_cross_monitor = focus_cross_monitor; config.focus_cross_tag = focus_cross_tag; + config.snap_distance = snap_distance; + config.enable_floating_snap = enable_floating_snap; config.swipe_min_threshold = swipe_min_threshold; config.bypass_surface_visibility = diff --git a/src/config/preset_config.h b/src/config/preset_config.h index edccc48..20f0a29 100644 --- a/src/config/preset_config.h +++ b/src/config/preset_config.h @@ -51,6 +51,8 @@ int scroller_focus_center = 0; int scroller_prefer_center = 0; int focus_cross_monitor = 0; int focus_cross_tag = 0; +int snap_distance = 80; +int enable_floating_snap = 1; unsigned int swipe_min_threshold = 20; diff --git a/src/maomao.c b/src/maomao.c index fc6777b..67bc01b 100644 --- a/src/maomao.c +++ b/src/maomao.c @@ -1837,6 +1837,73 @@ Client *center_select(Monitor *m) { return target_c; } +void apply_window_snap(Client *c) { + int snap_up = 99999, snap_down = 99999, snap_left = 99999, snap_right = 99999; + int snap_up_temp = 0 ,snap_down_temp = 0, snap_left_temp = 0, snap_right_temp = 0; + int snap_up_screen = 0, snap_down_screen = 0, snap_left_screen = 0, snap_right_screen = 0; + Client *tc; + if (!c || !c->mon || !client_surface(c)->mapped || c->iskilling) + return; + + if (!c->isfloating || !enable_floating_snap) + return; + + // 第一次遍历,计算客户端数量 + wl_list_for_each(tc, &clients, link) { + if (tc && tc->isfloating && !tc->iskilling && client_surface(tc)->mapped && VISIBLEON(tc, c->mon)) { + snap_left_temp = c->geom.x - tc->geom.x - tc->geom.width; + snap_right_temp = tc->geom.x - c->geom.x - c->geom.width; + snap_up_temp = c->geom.y - tc->geom.y - tc->geom.height; + snap_down_temp = tc->geom.y - c->geom.y - c->geom.height; + if (snap_left_temp < snap_left && snap_left_temp >= 0) { + snap_left = snap_left_temp; + } + if (snap_right_temp < snap_right && snap_right_temp >= 0) { + snap_right = snap_right_temp; + } + if (snap_up_temp < snap_up && snap_up_temp >= 0) { + snap_up = snap_up_temp; + } + if (snap_down_temp < snap_down && snap_down_temp >= 0) { + snap_down = snap_down_temp; + } + } + } + + snap_left_screen = c->geom.x - c->mon->m.x; + snap_right_screen = c->mon->m.x + c->mon->m.width - c->geom.x - c->geom.width; + snap_up_screen = c->geom.y - c->mon->m.y; + snap_down_screen = c->mon->m.y + c->mon->m.height - c->geom.y - c->geom.height; + + if(snap_up_screen > 0 && snap_up_screen < snap_up) + snap_up = snap_up_screen; + if(snap_down_screen > 0 && snap_down_screen < snap_down) + snap_down = snap_down_screen; + if(snap_left_screen > 0 && snap_left_screen < snap_left) + snap_left = snap_left_screen; + if(snap_right_screen > 0 && snap_right_screen < snap_right) + snap_right = snap_right_screen; + + if(snap_left < snap_right && snap_left < snap_distance) { + c->geom.x = c->geom.x - snap_left; + } + + if(snap_right <= snap_left && snap_right < snap_distance) { + c->geom.x = c->geom.x + snap_right; + } + + if(snap_up < snap_down && snap_up < snap_distance) { + c->geom.y = c->geom.y - snap_up; + } + + if(snap_down <= snap_up && snap_down < snap_distance) { + c->geom.y = c->geom.y + snap_down; + } + + resize(c,c->geom,1); + +} + Client *find_client_by_direction(Client *tc, const Arg *arg, bool findfloating, bool align) { Client *c; @@ -2335,6 +2402,7 @@ buttonpress(struct wl_listener *listener, void *data) { reset_foreign_tolevel(grabc); selmon->prevsel = selmon->sel; selmon->sel = grabc; + apply_window_snap(grabc); grabc = NULL; return; } else {