mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2026-03-31 07:11:28 -04:00
Merge branch 'main' of https://github.com/mangowm/mango into configurable_tag_count
This commit is contained in:
commit
a4a06ca1d5
7 changed files with 244 additions and 172 deletions
|
|
@ -61,4 +61,7 @@
|
||||||
inspired by dwl but aiming to be more feature-rich.")
|
inspired by dwl but aiming to be more feature-rich.")
|
||||||
(license gpl3)))
|
(license gpl3)))
|
||||||
|
|
||||||
|
(define-deprecated-package mangowc
|
||||||
|
mangowm-git)
|
||||||
|
|
||||||
mangowm-git
|
mangowm-git
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,7 @@ typedef struct {
|
||||||
int32_t width, height; // Monitor resolution
|
int32_t width, height; // Monitor resolution
|
||||||
float refresh; // Refresh rate
|
float refresh; // Refresh rate
|
||||||
int32_t vrr; // variable refresh rate
|
int32_t vrr; // variable refresh rate
|
||||||
|
int32_t custom; // enable custom mode
|
||||||
} ConfigMonitorRule;
|
} ConfigMonitorRule;
|
||||||
|
|
||||||
// 修改后的宏定义
|
// 修改后的宏定义
|
||||||
|
|
@ -356,6 +357,8 @@ typedef struct {
|
||||||
int32_t single_scratchpad;
|
int32_t single_scratchpad;
|
||||||
int32_t xwayland_persistence;
|
int32_t xwayland_persistence;
|
||||||
int32_t syncobj_enable;
|
int32_t syncobj_enable;
|
||||||
|
float drag_tile_refresh_interval;
|
||||||
|
float drag_floating_refresh_interval;
|
||||||
int32_t allow_tearing;
|
int32_t allow_tearing;
|
||||||
int32_t allow_shortcuts_inhibit;
|
int32_t allow_shortcuts_inhibit;
|
||||||
int32_t allow_lock_transparent;
|
int32_t allow_lock_transparent;
|
||||||
|
|
@ -372,6 +375,9 @@ typedef int32_t (*FuncType)(const Arg *);
|
||||||
Config config;
|
Config config;
|
||||||
|
|
||||||
bool parse_config_file(Config *config, const char *file_path, bool must_exist);
|
bool parse_config_file(Config *config, const char *file_path, bool must_exist);
|
||||||
|
bool apply_rule_to_state(Monitor *m, const ConfigMonitorRule *rule,
|
||||||
|
struct wlr_output_state *state, int vrr, int custom);
|
||||||
|
bool monitor_matches_rule(Monitor *m, const ConfigMonitorRule *rule);
|
||||||
|
|
||||||
// Helper function to trim whitespace from start and end of a string
|
// Helper function to trim whitespace from start and end of a string
|
||||||
void trim_whitespace(char *str) {
|
void trim_whitespace(char *str) {
|
||||||
|
|
@ -947,6 +953,7 @@ FuncType parse_func_name(char *func_name, Arg *arg, char *arg_value,
|
||||||
(*arg).f = atof(arg_value);
|
(*arg).f = atof(arg_value);
|
||||||
} else if (strcmp(func_name, "switch_proportion_preset") == 0) {
|
} else if (strcmp(func_name, "switch_proportion_preset") == 0) {
|
||||||
func = switch_proportion_preset;
|
func = switch_proportion_preset;
|
||||||
|
(*arg).i = parse_circle_direction(arg_value);
|
||||||
} else if (strcmp(func_name, "viewtoleft") == 0) {
|
} else if (strcmp(func_name, "viewtoleft") == 0) {
|
||||||
func = viewtoleft;
|
func = viewtoleft;
|
||||||
(*arg).i = atoi(arg_value);
|
(*arg).i = atoi(arg_value);
|
||||||
|
|
@ -1395,6 +1402,10 @@ bool parse_option(Config *config, char *key, char *value) {
|
||||||
config->xwayland_persistence = atoi(value);
|
config->xwayland_persistence = atoi(value);
|
||||||
} else if (strcmp(key, "syncobj_enable") == 0) {
|
} else if (strcmp(key, "syncobj_enable") == 0) {
|
||||||
config->syncobj_enable = atoi(value);
|
config->syncobj_enable = atoi(value);
|
||||||
|
} else if (strcmp(key, "drag_tile_refresh_interval") == 0) {
|
||||||
|
config->drag_tile_refresh_interval = atof(value);
|
||||||
|
} else if (strcmp(key, "drag_floating_refresh_interval") == 0) {
|
||||||
|
config->drag_floating_refresh_interval = atof(value);
|
||||||
} else if (strcmp(key, "allow_tearing") == 0) {
|
} else if (strcmp(key, "allow_tearing") == 0) {
|
||||||
config->allow_tearing = atoi(value);
|
config->allow_tearing = atoi(value);
|
||||||
} else if (strcmp(key, "allow_shortcuts_inhibit") == 0) {
|
} else if (strcmp(key, "allow_shortcuts_inhibit") == 0) {
|
||||||
|
|
@ -1800,6 +1811,7 @@ bool parse_option(Config *config, char *key, char *value) {
|
||||||
rule->height = -1;
|
rule->height = -1;
|
||||||
rule->refresh = 0.0f;
|
rule->refresh = 0.0f;
|
||||||
rule->vrr = 0;
|
rule->vrr = 0;
|
||||||
|
rule->custom = 0;
|
||||||
|
|
||||||
bool parse_error = false;
|
bool parse_error = false;
|
||||||
char *token = strtok(value, ",");
|
char *token = strtok(value, ",");
|
||||||
|
|
@ -1837,6 +1849,8 @@ bool parse_option(Config *config, char *key, char *value) {
|
||||||
rule->refresh = CLAMP_FLOAT(atof(val), 0.001f, 1000.0f);
|
rule->refresh = CLAMP_FLOAT(atof(val), 0.001f, 1000.0f);
|
||||||
} else if (strcmp(key, "vrr") == 0) {
|
} else if (strcmp(key, "vrr") == 0) {
|
||||||
rule->vrr = CLAMP_INT(atoi(val), 0, 1);
|
rule->vrr = CLAMP_INT(atoi(val), 0, 1);
|
||||||
|
} else if (strcmp(key, "custom") == 0) {
|
||||||
|
rule->custom = CLAMP_INT(atoi(val), 0, 1);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"\033[1m\033[31m[ERROR]:\033[33m Unknown "
|
"\033[1m\033[31m[ERROR]:\033[33m Unknown "
|
||||||
|
|
@ -3145,6 +3159,13 @@ void override_config(void) {
|
||||||
// 杂项设置
|
// 杂项设置
|
||||||
xwayland_persistence = CLAMP_INT(config.xwayland_persistence, 0, 1);
|
xwayland_persistence = CLAMP_INT(config.xwayland_persistence, 0, 1);
|
||||||
syncobj_enable = CLAMP_INT(config.syncobj_enable, 0, 1);
|
syncobj_enable = CLAMP_INT(config.syncobj_enable, 0, 1);
|
||||||
|
drag_tile_refresh_interval =
|
||||||
|
CLAMP_FLOAT(config.drag_tile_refresh_interval, 1.0f, 16.0f);
|
||||||
|
drag_floating_refresh_interval =
|
||||||
|
CLAMP_FLOAT(config.drag_floating_refresh_interval, 1.0f, 16.0f);
|
||||||
|
drag_tile_to_tile = CLAMP_INT(config.drag_tile_to_tile, 0, 1);
|
||||||
|
drag_floating_refresh_interval =
|
||||||
|
CLAMP_FLOAT(config.drag_floating_refresh_interval, 0.0f, 1000.0f);
|
||||||
allow_tearing = CLAMP_INT(config.allow_tearing, 0, 2);
|
allow_tearing = CLAMP_INT(config.allow_tearing, 0, 2);
|
||||||
allow_shortcuts_inhibit = CLAMP_INT(config.allow_shortcuts_inhibit, 0, 1);
|
allow_shortcuts_inhibit = CLAMP_INT(config.allow_shortcuts_inhibit, 0, 1);
|
||||||
allow_lock_transparent = CLAMP_INT(config.allow_lock_transparent, 0, 1);
|
allow_lock_transparent = CLAMP_INT(config.allow_lock_transparent, 0, 1);
|
||||||
|
|
@ -3334,6 +3355,8 @@ void set_value_default() {
|
||||||
config.single_scratchpad = single_scratchpad;
|
config.single_scratchpad = single_scratchpad;
|
||||||
config.xwayland_persistence = xwayland_persistence;
|
config.xwayland_persistence = xwayland_persistence;
|
||||||
config.syncobj_enable = syncobj_enable;
|
config.syncobj_enable = syncobj_enable;
|
||||||
|
config.drag_tile_refresh_interval = drag_tile_refresh_interval;
|
||||||
|
config.drag_floating_refresh_interval = drag_floating_refresh_interval;
|
||||||
config.allow_tearing = allow_tearing;
|
config.allow_tearing = allow_tearing;
|
||||||
config.allow_shortcuts_inhibit = allow_shortcuts_inhibit;
|
config.allow_shortcuts_inhibit = allow_shortcuts_inhibit;
|
||||||
config.allow_lock_transparent = allow_lock_transparent;
|
config.allow_lock_transparent = allow_lock_transparent;
|
||||||
|
|
@ -3561,17 +3584,15 @@ void reset_blur_params(void) {
|
||||||
void reapply_monitor_rules(void) {
|
void reapply_monitor_rules(void) {
|
||||||
ConfigMonitorRule *mr;
|
ConfigMonitorRule *mr;
|
||||||
Monitor *m = NULL;
|
Monitor *m = NULL;
|
||||||
int32_t ji, vrr;
|
int32_t ji, vrr, custom;
|
||||||
int32_t mx, my;
|
int32_t mx, my;
|
||||||
struct wlr_output_state state;
|
struct wlr_output_state state;
|
||||||
struct wlr_output_mode *internal_mode = NULL;
|
|
||||||
wlr_output_state_init(&state);
|
|
||||||
bool match_rule = false;
|
|
||||||
|
|
||||||
wl_list_for_each(m, &mons, link) {
|
wl_list_for_each(m, &mons, link) {
|
||||||
if (!m->wlr_output->enabled) {
|
if (!m->wlr_output->enabled)
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
wlr_output_state_init(&state);
|
||||||
|
|
||||||
for (ji = 0; ji < config.monitor_rules_count; ji++) {
|
for (ji = 0; ji < config.monitor_rules_count; ji++) {
|
||||||
if (config.monitor_rules_count < 1)
|
if (config.monitor_rules_count < 1)
|
||||||
|
|
@ -3579,71 +3600,22 @@ void reapply_monitor_rules(void) {
|
||||||
|
|
||||||
mr = &config.monitor_rules[ji];
|
mr = &config.monitor_rules[ji];
|
||||||
|
|
||||||
// 检查是否匹配的变量
|
if (monitor_matches_rule(m, mr)) {
|
||||||
match_rule = true;
|
|
||||||
|
|
||||||
// 检查四个标识字段的匹配
|
|
||||||
if (mr->name != NULL) {
|
|
||||||
if (!regex_match(mr->name, m->wlr_output->name)) {
|
|
||||||
match_rule = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mr->make != NULL) {
|
|
||||||
if (m->wlr_output->make == NULL ||
|
|
||||||
strcmp(mr->make, m->wlr_output->make) != 0) {
|
|
||||||
match_rule = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mr->model != NULL) {
|
|
||||||
if (m->wlr_output->model == NULL ||
|
|
||||||
strcmp(mr->model, m->wlr_output->model) != 0) {
|
|
||||||
match_rule = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mr->serial != NULL) {
|
|
||||||
if (m->wlr_output->serial == NULL ||
|
|
||||||
strcmp(mr->serial, m->wlr_output->serial) != 0) {
|
|
||||||
match_rule = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 只有当所有指定的标识都匹配时才应用规则
|
|
||||||
if (match_rule) {
|
|
||||||
mx = mr->x == INT32_MAX ? m->m.x : mr->x;
|
mx = mr->x == INT32_MAX ? m->m.x : mr->x;
|
||||||
my = mr->y == INT32_MAX ? m->m.y : mr->y;
|
my = mr->y == INT32_MAX ? m->m.y : mr->y;
|
||||||
vrr = mr->vrr >= 0 ? mr->vrr : 0;
|
vrr = mr->vrr >= 0 ? mr->vrr : 0;
|
||||||
|
custom = mr->custom >= 0 ? mr->custom : 0;
|
||||||
|
|
||||||
if (mr->width > 0 && mr->height > 0 && mr->refresh > 0) {
|
(void)apply_rule_to_state(m, mr, &state, vrr, custom);
|
||||||
internal_mode = get_nearest_output_mode(
|
|
||||||
m->wlr_output, mr->width, mr->height, mr->refresh);
|
|
||||||
if (internal_mode) {
|
|
||||||
wlr_output_state_set_mode(&state, internal_mode);
|
|
||||||
} else if (wlr_output_is_headless(m->wlr_output)) {
|
|
||||||
wlr_output_state_set_custom_mode(
|
|
||||||
&state, mr->width, mr->height,
|
|
||||||
(int32_t)roundf(mr->refresh * 1000));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vrr) {
|
|
||||||
enable_adaptive_sync(m, &state);
|
|
||||||
} else {
|
|
||||||
wlr_output_state_set_adaptive_sync_enabled(&state, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
wlr_output_state_set_scale(&state, mr->scale);
|
|
||||||
wlr_output_state_set_transform(&state, mr->rr);
|
|
||||||
wlr_output_layout_add(output_layout, m->wlr_output, mx, my);
|
wlr_output_layout_add(output_layout, m->wlr_output, mx, my);
|
||||||
|
wlr_output_commit_state(m->wlr_output, &state);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_output_commit_state(m->wlr_output, &state);
|
|
||||||
wlr_output_state_finish(&state);
|
wlr_output_state_finish(&state);
|
||||||
updatemons(NULL, NULL);
|
|
||||||
}
|
}
|
||||||
|
updatemons(NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reapply_cursor_style(void) {
|
void reapply_cursor_style(void) {
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,7 @@ int32_t drag_warp_cursor = 1;
|
||||||
int32_t xwayland_persistence = 1; /* xwayland persistence */
|
int32_t xwayland_persistence = 1; /* xwayland persistence */
|
||||||
int32_t syncobj_enable = 0;
|
int32_t syncobj_enable = 0;
|
||||||
int32_t allow_lock_transparent = 0;
|
int32_t allow_lock_transparent = 0;
|
||||||
double drag_tile_refresh_interval = 16.0;
|
double drag_tile_refresh_interval = 8.0;
|
||||||
double drag_floating_refresh_interval = 8.0;
|
double drag_floating_refresh_interval = 8.0;
|
||||||
int32_t allow_tearing = TEARING_DISABLED;
|
int32_t allow_tearing = TEARING_DISABLED;
|
||||||
int32_t allow_shortcuts_inhibit = SHORTCUTS_INHIBIT_ENABLE;
|
int32_t allow_shortcuts_inhibit = SHORTCUTS_INHIBIT_ENABLE;
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,9 @@ int32_t exchange_client(const Arg *arg) {
|
||||||
if ((c->isfullscreen || c->ismaximizescreen) && !is_scroller_layout(c->mon))
|
if ((c->isfullscreen || c->ismaximizescreen) && !is_scroller_layout(c->mon))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
exchange_two_client(c, direction_select(arg));
|
Client *tc = direction_select(arg);
|
||||||
|
tc = get_focused_stack_client(tc);
|
||||||
|
exchange_two_client(c, tc);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1054,13 +1056,28 @@ int32_t switch_proportion_preset(const Arg *arg) {
|
||||||
for (int32_t i = 0; i < config.scroller_proportion_preset_count; i++) {
|
for (int32_t i = 0; i < config.scroller_proportion_preset_count; i++) {
|
||||||
if (config.scroller_proportion_preset[i] ==
|
if (config.scroller_proportion_preset[i] ==
|
||||||
tc->scroller_proportion) {
|
tc->scroller_proportion) {
|
||||||
if (i == config.scroller_proportion_preset_count - 1) {
|
|
||||||
target_proportion = config.scroller_proportion_preset[0];
|
if (arg->i == NEXT) {
|
||||||
break;
|
if (i == config.scroller_proportion_preset_count - 1) {
|
||||||
|
target_proportion =
|
||||||
|
config.scroller_proportion_preset[0];
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
target_proportion =
|
||||||
|
config.scroller_proportion_preset[i + 1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
target_proportion =
|
if (i == 0) {
|
||||||
config.scroller_proportion_preset[i + 1];
|
target_proportion =
|
||||||
break;
|
config.scroller_proportion_preset
|
||||||
|
[config.scroller_proportion_preset_count - 1];
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
target_proportion =
|
||||||
|
config.scroller_proportion_preset[i - 1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1419,6 +1436,7 @@ int32_t toggleview(const Arg *arg) {
|
||||||
|
|
||||||
uint32_t newtagset;
|
uint32_t newtagset;
|
||||||
uint32_t target;
|
uint32_t target;
|
||||||
|
Client *c = NULL;
|
||||||
|
|
||||||
target = arg->ui == 0 ? ~0 & TAGMASK : arg->ui;
|
target = arg->ui == 0 ? ~0 & TAGMASK : arg->ui;
|
||||||
|
|
||||||
|
|
@ -1427,6 +1445,11 @@ int32_t toggleview(const Arg *arg) {
|
||||||
if (newtagset) {
|
if (newtagset) {
|
||||||
selmon->tagset[selmon->seltags] = newtagset;
|
selmon->tagset[selmon->seltags] = newtagset;
|
||||||
focusclient(focustop(selmon), 1);
|
focusclient(focustop(selmon), 1);
|
||||||
|
wl_list_for_each(c, &clients, link) {
|
||||||
|
if (VISIBLEON(c, selmon) && ISTILED(c)) {
|
||||||
|
set_size_per(selmon, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
arrange(selmon, false, false);
|
arrange(selmon, false, false);
|
||||||
}
|
}
|
||||||
printstatus();
|
printstatus();
|
||||||
|
|
@ -1751,28 +1774,19 @@ int32_t scroller_stack(const Arg *arg) {
|
||||||
if (!c || !c->mon || c->isfloating || !is_scroller_layout(selmon))
|
if (!c || !c->mon || c->isfloating || !is_scroller_layout(selmon))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (c && (!client_only_in_one_tag(c) || c->isglobal || c->isunglobal))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
bool is_horizontal_layout =
|
bool is_horizontal_layout =
|
||||||
c->mon->pertag->ltidxs[c->mon->pertag->curtag]->id == SCROLLER ? true
|
c->mon->pertag->ltidxs[c->mon->pertag->curtag]->id == SCROLLER ? true
|
||||||
: false;
|
: false;
|
||||||
|
|
||||||
Client *target_client = find_client_by_direction(c, arg, false, true);
|
Client *target_client = find_client_by_direction(c, arg, false, true);
|
||||||
|
|
||||||
if (target_client && (!client_only_in_one_tag(target_client) ||
|
|
||||||
target_client->isglobal || target_client->isunglobal))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (target_client) {
|
if (target_client) {
|
||||||
stack_head = get_scroll_stack_head(target_client);
|
stack_head = get_scroll_stack_head(target_client);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c) {
|
source_stack_head = get_scroll_stack_head(c);
|
||||||
source_stack_head = get_scroll_stack_head(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stack_head == source_stack_head) {
|
if (source_stack_head == stack_head) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1820,6 +1834,10 @@ int32_t scroller_stack(const Arg *arg) {
|
||||||
|
|
||||||
if (!target_client || target_client->mon != c->mon) {
|
if (!target_client || target_client->mon != c->mon) {
|
||||||
return 0;
|
return 0;
|
||||||
|
} else {
|
||||||
|
c->isglobal = target_client->isglobal = 0;
|
||||||
|
c->isunglobal = target_client->isglobal = 0;
|
||||||
|
c->tags = target_client->tags = get_tags_first_tag(target_client->tags);
|
||||||
}
|
}
|
||||||
|
|
||||||
exit_scroller_stack(c);
|
exit_scroller_stack(c);
|
||||||
|
|
|
||||||
|
|
@ -44,15 +44,21 @@ void restore_size_per(Monitor *m, Client *c) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// it is possible that the current floating window is moved to another tag,
|
||||||
|
// but the tag has not executed save_old_size_per
|
||||||
|
// so it must be judged whether their old size values are initial values
|
||||||
|
|
||||||
if (!c->ismaster && c->old_stack_inner_per < 1.0 &&
|
if (!c->ismaster && c->old_stack_inner_per < 1.0 &&
|
||||||
c->stack_inner_per < 1.0) {
|
c->old_stack_inner_per > 0.0f && c->stack_inner_per < 1.0 &&
|
||||||
|
c->stack_inner_per > 0.0f) {
|
||||||
c->stack_inner_per = (1.0 - c->stack_inner_per) *
|
c->stack_inner_per = (1.0 - c->stack_inner_per) *
|
||||||
c->old_stack_inner_per /
|
c->old_stack_inner_per /
|
||||||
(1.0 - c->old_stack_inner_per);
|
(1.0 - c->old_stack_inner_per);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->ismaster && c->old_master_inner_per < 1.0 &&
|
if (c->ismaster && c->old_master_inner_per < 1.0 &&
|
||||||
c->master_inner_per < 1.0) {
|
c->old_master_inner_per > 0.0f && c->master_inner_per < 1.0 &&
|
||||||
|
c->master_inner_per > 0.0f) {
|
||||||
c->master_inner_per = (1.0 - c->master_inner_per) *
|
c->master_inner_per = (1.0 - c->master_inner_per) *
|
||||||
c->old_master_inner_per /
|
c->old_master_inner_per /
|
||||||
(1.0 - c->old_master_inner_per);
|
(1.0 - c->old_master_inner_per);
|
||||||
|
|
@ -61,10 +67,12 @@ void restore_size_per(Monitor *m, Client *c) {
|
||||||
wl_list_for_each(fc, &clients, link) {
|
wl_list_for_each(fc, &clients, link) {
|
||||||
if (VISIBLEON(fc, m) && ISTILED(fc) && fc != c && !fc->ismaster &&
|
if (VISIBLEON(fc, m) && ISTILED(fc) && fc != c && !fc->ismaster &&
|
||||||
fc->old_ismaster && fc->old_stack_inner_per < 1.0 &&
|
fc->old_ismaster && fc->old_stack_inner_per < 1.0 &&
|
||||||
fc->stack_inner_per < 1.0) {
|
fc->old_stack_inner_per > 0.0f && fc->stack_inner_per < 1.0 &&
|
||||||
|
fc->stack_inner_per > 0.0f) {
|
||||||
fc->stack_inner_per = (1.0 - fc->stack_inner_per) *
|
fc->stack_inner_per = (1.0 - fc->stack_inner_per) *
|
||||||
fc->old_stack_inner_per /
|
fc->old_stack_inner_per /
|
||||||
(1.0 - fc->old_stack_inner_per);
|
(1.0 - fc->old_stack_inner_per);
|
||||||
|
fc->old_ismaster = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -81,7 +89,7 @@ void set_size_per(Monitor *m, Client *c) {
|
||||||
wl_list_for_each(fc, &clients, link) {
|
wl_list_for_each(fc, &clients, link) {
|
||||||
if (VISIBLEON(fc, m) && ISTILED(fc) && fc != c) {
|
if (VISIBLEON(fc, m) && ISTILED(fc) && fc != c) {
|
||||||
if (current_layout->id == CENTER_TILE &&
|
if (current_layout->id == CENTER_TILE &&
|
||||||
!(fc->isleftstack ^ c->isleftstack))
|
(fc->isleftstack ^ c->isleftstack))
|
||||||
continue;
|
continue;
|
||||||
c->master_mfact_per = fc->master_mfact_per;
|
c->master_mfact_per = fc->master_mfact_per;
|
||||||
c->master_inner_per = fc->master_inner_per;
|
c->master_inner_per = fc->master_inner_per;
|
||||||
|
|
@ -271,6 +279,23 @@ void resize_tile_master_horizontal(Client *grabc, bool isdrag, int32_t offsetx,
|
||||||
// 应用到所有平铺窗口
|
// 应用到所有平铺窗口
|
||||||
wl_list_for_each(tc, &clients, link) {
|
wl_list_for_each(tc, &clients, link) {
|
||||||
if (VISIBLEON(tc, grabc->mon) && ISTILED(tc)) {
|
if (VISIBLEON(tc, grabc->mon) && ISTILED(tc)) {
|
||||||
|
|
||||||
|
if (!isdrag && tc != grabc) {
|
||||||
|
if (!tc->ismaster && new_stack_inner_per != 1.0f &&
|
||||||
|
grabc->old_stack_inner_per != 1.0f &&
|
||||||
|
(type != CENTER_TILE ||
|
||||||
|
!(grabc->isleftstack ^ tc->isleftstack)))
|
||||||
|
tc->stack_inner_per = (1 - new_stack_inner_per) /
|
||||||
|
(1 - grabc->old_stack_inner_per) *
|
||||||
|
tc->stack_inner_per;
|
||||||
|
if (tc->ismaster && new_master_inner_per != 1.0f &&
|
||||||
|
grabc->old_master_inner_per != 1.0f)
|
||||||
|
tc->master_inner_per =
|
||||||
|
(1.0f - new_master_inner_per) /
|
||||||
|
(1.0f - grabc->old_master_inner_per) *
|
||||||
|
tc->master_inner_per;
|
||||||
|
}
|
||||||
|
|
||||||
tc->master_mfact_per = new_master_mfact_per;
|
tc->master_mfact_per = new_master_mfact_per;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -426,6 +451,20 @@ void resize_tile_master_vertical(Client *grabc, bool isdrag, int32_t offsetx,
|
||||||
// 应用到所有平铺窗口
|
// 应用到所有平铺窗口
|
||||||
wl_list_for_each(tc, &clients, link) {
|
wl_list_for_each(tc, &clients, link) {
|
||||||
if (VISIBLEON(tc, grabc->mon) && ISTILED(tc)) {
|
if (VISIBLEON(tc, grabc->mon) && ISTILED(tc)) {
|
||||||
|
if (!isdrag && tc != grabc && type != CENTER_TILE) {
|
||||||
|
if (!tc->ismaster && new_stack_inner_per != 1.0f &&
|
||||||
|
grabc->old_stack_inner_per != 1.0f)
|
||||||
|
tc->stack_inner_per = (1 - new_stack_inner_per) /
|
||||||
|
(1 - grabc->old_stack_inner_per) *
|
||||||
|
tc->stack_inner_per;
|
||||||
|
if (tc->ismaster && new_master_inner_per != 1.0f &&
|
||||||
|
grabc->old_master_inner_per != 1.0f)
|
||||||
|
tc->master_inner_per =
|
||||||
|
(1.0f - new_master_inner_per) /
|
||||||
|
(1.0f - grabc->old_master_inner_per) *
|
||||||
|
tc->master_inner_per;
|
||||||
|
}
|
||||||
|
|
||||||
tc->master_mfact_per = new_master_mfact_per;
|
tc->master_mfact_per = new_master_mfact_per;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -448,6 +487,7 @@ void resize_tile_master_vertical(Client *grabc, bool isdrag, int32_t offsetx,
|
||||||
|
|
||||||
void resize_tile_scroller(Client *grabc, bool isdrag, int32_t offsetx,
|
void resize_tile_scroller(Client *grabc, bool isdrag, int32_t offsetx,
|
||||||
int32_t offsety, uint32_t time, bool isvertical) {
|
int32_t offsety, uint32_t time, bool isvertical) {
|
||||||
|
Client *tc = NULL;
|
||||||
float delta_x, delta_y;
|
float delta_x, delta_y;
|
||||||
float new_scroller_proportion;
|
float new_scroller_proportion;
|
||||||
float new_stack_proportion;
|
float new_stack_proportion;
|
||||||
|
|
@ -608,12 +648,22 @@ void resize_tile_scroller(Client *grabc, bool isdrag, int32_t offsetx,
|
||||||
// 应用限制,确保比例在合理范围内
|
// 应用限制,确保比例在合理范围内
|
||||||
new_scroller_proportion =
|
new_scroller_proportion =
|
||||||
fmaxf(0.1f, fminf(1.0f, new_scroller_proportion));
|
fmaxf(0.1f, fminf(1.0f, new_scroller_proportion));
|
||||||
new_stack_proportion = fmaxf(0.1f, fminf(1.0f, new_stack_proportion));
|
new_stack_proportion = fmaxf(0.1f, fminf(0.9f, new_stack_proportion));
|
||||||
|
|
||||||
grabc->stack_proportion = new_stack_proportion;
|
grabc->stack_proportion = new_stack_proportion;
|
||||||
|
|
||||||
stack_head->scroller_proportion = new_scroller_proportion;
|
stack_head->scroller_proportion = new_scroller_proportion;
|
||||||
|
|
||||||
|
wl_list_for_each(tc, &clients, link) {
|
||||||
|
if (!isdrag && new_stack_proportion != 1.0f &&
|
||||||
|
grabc->old_stack_proportion != 1.0f && tc != grabc &&
|
||||||
|
ISTILED(tc) && get_scroll_stack_head(tc) == stack_head) {
|
||||||
|
tc->stack_proportion = (1.0f - new_stack_proportion) /
|
||||||
|
(1.0f - grabc->old_stack_proportion) *
|
||||||
|
tc->stack_proportion;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!isdrag) {
|
if (!isdrag) {
|
||||||
arrange(grabc->mon, false, false);
|
arrange(grabc->mon, false, false);
|
||||||
return;
|
return;
|
||||||
|
|
@ -656,6 +706,18 @@ void resize_tile_client(Client *grabc, bool isdrag, int32_t offsetx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If there are no calculation omissions,
|
||||||
|
these two functions will never be triggered.
|
||||||
|
Just in case to facilitate the final investigation*/
|
||||||
|
|
||||||
|
void check_size_per_valid(Client *c) {
|
||||||
|
if (c->ismaster) {
|
||||||
|
assert(c->master_inner_per > 0.0f && c->master_inner_per <= 1.0f);
|
||||||
|
} else {
|
||||||
|
assert(c->stack_inner_per > 0.0f && c->stack_inner_per <= 1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void reset_size_per_mon(Monitor *m, int32_t tile_cilent_num,
|
void reset_size_per_mon(Monitor *m, int32_t tile_cilent_num,
|
||||||
double total_left_stack_hight_percent,
|
double total_left_stack_hight_percent,
|
||||||
double total_right_stack_hight_percent,
|
double total_right_stack_hight_percent,
|
||||||
|
|
@ -671,6 +733,7 @@ void reset_size_per_mon(Monitor *m, int32_t tile_cilent_num,
|
||||||
|
|
||||||
wl_list_for_each(c, &clients, link) {
|
wl_list_for_each(c, &clients, link) {
|
||||||
if (VISIBLEON(c, m) && ISTILED(c)) {
|
if (VISIBLEON(c, m) && ISTILED(c)) {
|
||||||
|
|
||||||
if (total_master_inner_percent > 0.0 && i < nmasters) {
|
if (total_master_inner_percent > 0.0 && i < nmasters) {
|
||||||
c->ismaster = true;
|
c->ismaster = true;
|
||||||
c->stack_inner_per = stack_num ? 1.0f / stack_num : 1.0f;
|
c->stack_inner_per = stack_num ? 1.0f / stack_num : 1.0f;
|
||||||
|
|
@ -686,17 +749,20 @@ void reset_size_per_mon(Monitor *m, int32_t tile_cilent_num,
|
||||||
: 1.0f;
|
: 1.0f;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
|
check_size_per_valid(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
wl_list_for_each(c, &clients, link) {
|
wl_list_for_each(c, &clients, link) {
|
||||||
if (VISIBLEON(c, m) && ISTILED(c)) {
|
if (VISIBLEON(c, m) && ISTILED(c)) {
|
||||||
|
|
||||||
if (total_master_inner_percent > 0.0 && i < nmasters) {
|
if (total_master_inner_percent > 0.0 && i < nmasters) {
|
||||||
c->ismaster = true;
|
c->ismaster = true;
|
||||||
if ((stack_index % 2) ^ (tile_cilent_num % 2 == 0)) {
|
if ((stack_index % 2) ^ (tile_cilent_num % 2 == 0)) {
|
||||||
c->stack_inner_per =
|
c->stack_inner_per =
|
||||||
stack_num > 1 ? 1.0f / ((stack_num - 1) / 2) : 1.0f;
|
stack_num > 1 ? 1.0f / ((stack_num - 1) / 2.0f)
|
||||||
|
: 1.0f;
|
||||||
} else {
|
} else {
|
||||||
c->stack_inner_per =
|
c->stack_inner_per =
|
||||||
stack_num > 1 ? 2.0f / stack_num : 1.0f;
|
stack_num > 1 ? 2.0f / stack_num : 1.0f;
|
||||||
|
|
@ -725,6 +791,8 @@ void reset_size_per_mon(Monitor *m, int32_t tile_cilent_num,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
|
check_size_per_valid(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
177
src/mango.c
177
src/mango.c
|
|
@ -806,7 +806,6 @@ static int32_t keep_idle_inhibit(void *data);
|
||||||
static void check_keep_idle_inhibit(Client *c);
|
static void check_keep_idle_inhibit(Client *c);
|
||||||
static void pre_caculate_before_arrange(Monitor *m, bool want_animation,
|
static void pre_caculate_before_arrange(Monitor *m, bool want_animation,
|
||||||
bool from_view, bool only_caculate);
|
bool from_view, bool only_caculate);
|
||||||
|
|
||||||
#include "data/static_keymap.h"
|
#include "data/static_keymap.h"
|
||||||
#include "dispatch/bind_declare.h"
|
#include "dispatch/bind_declare.h"
|
||||||
#include "layout/layout.h"
|
#include "layout/layout.h"
|
||||||
|
|
@ -2595,41 +2594,49 @@ void destroydecoration(struct wl_listener *listener, void *data) {
|
||||||
wl_list_remove(&c->set_decoration_mode.link);
|
wl_list_remove(&c->set_decoration_mode.link);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void popup_unconstrain(Popup *popup) {
|
static bool popup_unconstrain(Popup *popup) {
|
||||||
struct wlr_xdg_popup *wlr_popup = popup->wlr_popup;
|
struct wlr_xdg_popup *wlr_popup = popup->wlr_popup;
|
||||||
Client *c = NULL;
|
Client *c = NULL;
|
||||||
LayerSurface *l = NULL;
|
LayerSurface *l = NULL;
|
||||||
int32_t type = -1;
|
int32_t type = -1;
|
||||||
|
|
||||||
if (!wlr_popup || !wlr_popup->parent) {
|
if (!wlr_popup || !wlr_popup->parent) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_scene_node *parent_node = wlr_popup->parent->data;
|
struct wlr_scene_node *parent_node = wlr_popup->parent->data;
|
||||||
if (!parent_node) {
|
if (!parent_node) {
|
||||||
wlr_log(WLR_ERROR, "Popup parent has no scene node");
|
wlr_log(WLR_ERROR, "Popup parent has no scene node");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
type = toplevel_from_wlr_surface(wlr_popup->base->surface, &c, &l);
|
type = toplevel_from_wlr_surface(wlr_popup->base->surface, &c, &l);
|
||||||
if ((l && !l->mon) || (c && !c->mon)) {
|
if ((l && !l->mon) || (c && !c->mon)) {
|
||||||
wlr_xdg_popup_destroy(wlr_popup);
|
return true;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int parent_lx, parent_ly;
|
|
||||||
wlr_scene_node_coords(parent_node, &parent_lx, &parent_ly);
|
|
||||||
|
|
||||||
struct wlr_box usable = type == LayerShell ? l->mon->m : c->mon->w;
|
struct wlr_box usable = type == LayerShell ? l->mon->m : c->mon->w;
|
||||||
|
|
||||||
struct wlr_box constraint_box = {
|
int lx, ly;
|
||||||
.x = usable.x - parent_lx,
|
struct wlr_box constraint_box;
|
||||||
.y = usable.y - parent_ly,
|
|
||||||
.width = usable.width,
|
if (type == LayerShell) {
|
||||||
.height = usable.height,
|
wlr_scene_node_coords(&l->scene_layer->tree->node, &lx, &ly);
|
||||||
};
|
constraint_box.x = usable.x - lx;
|
||||||
|
constraint_box.y = usable.y - ly;
|
||||||
|
constraint_box.width = usable.width;
|
||||||
|
constraint_box.height = usable.height;
|
||||||
|
} else {
|
||||||
|
constraint_box.x =
|
||||||
|
usable.x - (c->geom.x + c->bw - c->surface.xdg->current.geometry.x);
|
||||||
|
constraint_box.y =
|
||||||
|
usable.y - (c->geom.y + c->bw - c->surface.xdg->current.geometry.y);
|
||||||
|
constraint_box.width = usable.width;
|
||||||
|
constraint_box.height = usable.height;
|
||||||
|
}
|
||||||
|
|
||||||
wlr_xdg_popup_unconstrain_from_box(wlr_popup, &constraint_box);
|
wlr_xdg_popup_unconstrain_from_box(wlr_popup, &constraint_box);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void destroypopup(struct wl_listener *listener, void *data) {
|
static void destroypopup(struct wl_listener *listener, void *data) {
|
||||||
|
|
@ -2643,14 +2650,16 @@ static void commitpopup(struct wl_listener *listener, void *data) {
|
||||||
Popup *popup = wl_container_of(listener, popup, commit);
|
Popup *popup = wl_container_of(listener, popup, commit);
|
||||||
|
|
||||||
struct wlr_surface *surface = data;
|
struct wlr_surface *surface = data;
|
||||||
|
bool should_destroy = false;
|
||||||
struct wlr_xdg_popup *wlr_popup =
|
struct wlr_xdg_popup *wlr_popup =
|
||||||
wlr_xdg_popup_try_from_wlr_surface(surface);
|
wlr_xdg_popup_try_from_wlr_surface(surface);
|
||||||
|
|
||||||
if (!wlr_popup || !wlr_popup->base->initial_commit)
|
if (!wlr_popup->base->initial_commit)
|
||||||
goto commitpopup_listen_free;
|
return;
|
||||||
|
|
||||||
if (!wlr_popup->parent || !wlr_popup->parent->data) {
|
if (!wlr_popup->parent || !wlr_popup->parent->data) {
|
||||||
goto commitpopup_listen_free;
|
should_destroy = true;
|
||||||
|
goto cleanup_popup_commit;
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_scene_node_raise_to_top(wlr_popup->parent->data);
|
wlr_scene_node_raise_to_top(wlr_popup->parent->data);
|
||||||
|
|
@ -2660,16 +2669,21 @@ static void commitpopup(struct wl_listener *listener, void *data) {
|
||||||
|
|
||||||
popup->wlr_popup = wlr_popup;
|
popup->wlr_popup = wlr_popup;
|
||||||
|
|
||||||
popup_unconstrain(popup);
|
should_destroy = popup_unconstrain(popup);
|
||||||
|
|
||||||
|
cleanup_popup_commit:
|
||||||
|
|
||||||
commitpopup_listen_free:
|
|
||||||
wl_list_remove(&popup->commit.link);
|
wl_list_remove(&popup->commit.link);
|
||||||
popup->commit.notify = NULL;
|
popup->commit.notify = NULL;
|
||||||
|
|
||||||
|
if (should_destroy) {
|
||||||
|
wlr_xdg_popup_destroy(wlr_popup);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void repositionpopup(struct wl_listener *listener, void *data) {
|
static void repositionpopup(struct wl_listener *listener, void *data) {
|
||||||
Popup *popup = wl_container_of(listener, popup, reposition);
|
Popup *popup = wl_container_of(listener, popup, reposition);
|
||||||
popup_unconstrain(popup);
|
(void)popup_unconstrain(popup);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void createpopup(struct wl_listener *listener, void *data) {
|
static void createpopup(struct wl_listener *listener, void *data) {
|
||||||
|
|
@ -2882,18 +2896,59 @@ void enable_adaptive_sync(Monitor *m, struct wlr_output_state *state) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool monitor_matches_rule(Monitor *m, const ConfigMonitorRule *rule) {
|
||||||
|
if (rule->name != NULL && !regex_match(rule->name, m->wlr_output->name))
|
||||||
|
return false;
|
||||||
|
if (rule->make != NULL && (m->wlr_output->make == NULL ||
|
||||||
|
strcmp(rule->make, m->wlr_output->make) != 0))
|
||||||
|
return false;
|
||||||
|
if (rule->model != NULL && (m->wlr_output->model == NULL ||
|
||||||
|
strcmp(rule->model, m->wlr_output->model) != 0))
|
||||||
|
return false;
|
||||||
|
if (rule->serial != NULL &&
|
||||||
|
(m->wlr_output->serial == NULL ||
|
||||||
|
strcmp(rule->serial, m->wlr_output->serial) != 0))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 将规则中的显示参数应用到 wlr_output_state 中,返回是否设置了自定义模式 */
|
||||||
|
bool apply_rule_to_state(Monitor *m, const ConfigMonitorRule *rule,
|
||||||
|
struct wlr_output_state *state, int vrr, int custom) {
|
||||||
|
bool mode_set = false;
|
||||||
|
if (rule->width > 0 && rule->height > 0 && rule->refresh > 0) {
|
||||||
|
struct wlr_output_mode *internal_mode = get_nearest_output_mode(
|
||||||
|
m->wlr_output, rule->width, rule->height, rule->refresh);
|
||||||
|
if (internal_mode) {
|
||||||
|
wlr_output_state_set_mode(state, internal_mode);
|
||||||
|
mode_set = true;
|
||||||
|
} else if (custom || wlr_output_is_headless(m->wlr_output)) {
|
||||||
|
wlr_output_state_set_custom_mode(
|
||||||
|
state, rule->width, rule->height,
|
||||||
|
(int32_t)roundf(rule->refresh * 1000));
|
||||||
|
mode_set = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (vrr) {
|
||||||
|
enable_adaptive_sync(m, state);
|
||||||
|
} else {
|
||||||
|
wlr_output_state_set_adaptive_sync_enabled(state, false);
|
||||||
|
}
|
||||||
|
wlr_output_state_set_scale(state, rule->scale);
|
||||||
|
wlr_output_state_set_transform(state, rule->rr);
|
||||||
|
return mode_set;
|
||||||
|
}
|
||||||
|
|
||||||
void createmon(struct wl_listener *listener, void *data) {
|
void createmon(struct wl_listener *listener, void *data) {
|
||||||
/* This event is raised by the backend when a new output (aka a display or
|
/* This event is raised by the backend when a new output (aka a display or
|
||||||
* monitor) becomes available. */
|
* monitor) becomes available. */
|
||||||
struct wlr_output *wlr_output = data;
|
struct wlr_output *wlr_output = data;
|
||||||
const ConfigMonitorRule *r;
|
const ConfigMonitorRule *r;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
int32_t ji, vrr;
|
int32_t ji, vrr, custom;
|
||||||
struct wlr_output_state state;
|
struct wlr_output_state state;
|
||||||
Monitor *m = NULL;
|
Monitor *m = NULL;
|
||||||
struct wlr_output_mode *internal_mode = NULL;
|
|
||||||
bool custom_monitor_mode = false;
|
bool custom_monitor_mode = false;
|
||||||
bool match_rule = false;
|
|
||||||
|
|
||||||
if (!wlr_output_init_render(wlr_output, alloc, drw))
|
if (!wlr_output_init_render(wlr_output, alloc, drw))
|
||||||
return;
|
return;
|
||||||
|
|
@ -2923,7 +2978,6 @@ void createmon(struct wl_listener *listener, void *data) {
|
||||||
for (i = 0; i < LENGTH(m->layers); i++)
|
for (i = 0; i < LENGTH(m->layers); i++)
|
||||||
wl_list_init(&m->layers[i]);
|
wl_list_init(&m->layers[i]);
|
||||||
|
|
||||||
wlr_output_state_init(&state);
|
|
||||||
/* Initialize monitor state using configured rules */
|
/* Initialize monitor state using configured rules */
|
||||||
m->gappih = gappih;
|
m->gappih = gappih;
|
||||||
m->gappiv = gappiv;
|
m->gappiv = gappiv;
|
||||||
|
|
@ -2936,6 +2990,8 @@ void createmon(struct wl_listener *listener, void *data) {
|
||||||
m->m.y = INT32_MAX;
|
m->m.y = INT32_MAX;
|
||||||
float scale = 1;
|
float scale = 1;
|
||||||
enum wl_output_transform rr = WL_OUTPUT_TRANSFORM_NORMAL;
|
enum wl_output_transform rr = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||||
|
|
||||||
|
wlr_output_state_init(&state);
|
||||||
wlr_output_state_set_scale(&state, scale);
|
wlr_output_state_set_scale(&state, scale);
|
||||||
wlr_output_state_set_transform(&state, rr);
|
wlr_output_state_set_transform(&state, rr);
|
||||||
|
|
||||||
|
|
@ -2945,74 +3001,21 @@ void createmon(struct wl_listener *listener, void *data) {
|
||||||
|
|
||||||
r = &config.monitor_rules[ji];
|
r = &config.monitor_rules[ji];
|
||||||
|
|
||||||
// 检查是否匹配的变量
|
if (monitor_matches_rule(m, r)) {
|
||||||
match_rule = true;
|
|
||||||
|
|
||||||
// 检查四个标识字段的匹配
|
|
||||||
if (r->name != NULL) {
|
|
||||||
if (!regex_match(r->name, m->wlr_output->name)) {
|
|
||||||
match_rule = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r->make != NULL) {
|
|
||||||
if (m->wlr_output->make == NULL ||
|
|
||||||
strcmp(r->make, m->wlr_output->make) != 0) {
|
|
||||||
match_rule = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r->model != NULL) {
|
|
||||||
if (m->wlr_output->model == NULL ||
|
|
||||||
strcmp(r->model, m->wlr_output->model) != 0) {
|
|
||||||
match_rule = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r->serial != NULL) {
|
|
||||||
if (m->wlr_output->serial == NULL ||
|
|
||||||
strcmp(r->serial, m->wlr_output->serial) != 0) {
|
|
||||||
match_rule = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (match_rule) {
|
|
||||||
m->m.x = r->x == INT32_MAX ? INT32_MAX : r->x;
|
m->m.x = r->x == INT32_MAX ? INT32_MAX : r->x;
|
||||||
m->m.y = r->y == INT32_MAX ? INT32_MAX : r->y;
|
m->m.y = r->y == INT32_MAX ? INT32_MAX : r->y;
|
||||||
vrr = r->vrr >= 0 ? r->vrr : 0;
|
vrr = r->vrr >= 0 ? r->vrr : 0;
|
||||||
|
custom = r->custom >= 0 ? r->custom : 0;
|
||||||
scale = r->scale;
|
scale = r->scale;
|
||||||
rr = r->rr;
|
rr = r->rr;
|
||||||
|
|
||||||
if (r->width > 0 && r->height > 0 && r->refresh > 0) {
|
if (apply_rule_to_state(m, r, &state, vrr, custom)) {
|
||||||
internal_mode = get_nearest_output_mode(m->wlr_output, r->width,
|
custom_monitor_mode = true;
|
||||||
r->height, r->refresh);
|
|
||||||
if (internal_mode) {
|
|
||||||
custom_monitor_mode = true;
|
|
||||||
wlr_output_state_set_mode(&state, internal_mode);
|
|
||||||
} else if (wlr_output_is_headless(m->wlr_output)) {
|
|
||||||
custom_monitor_mode = true;
|
|
||||||
wlr_output_state_set_custom_mode(
|
|
||||||
&state, r->width, r->height,
|
|
||||||
(int32_t)roundf(r->refresh * 1000));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
break; // 只应用第一个匹配规则
|
||||||
if (vrr) {
|
|
||||||
enable_adaptive_sync(m, &state);
|
|
||||||
} else {
|
|
||||||
wlr_output_state_set_adaptive_sync_enabled(&state, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
wlr_output_state_set_scale(&state, r->scale);
|
|
||||||
wlr_output_state_set_transform(&state, r->rr);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The mode is a tuple of (width, height, refresh rate), and each
|
|
||||||
* monitor supports only a specific set of modes. We just pick the
|
|
||||||
* monitor's preferred mode; a more sophisticated compositor would let
|
|
||||||
* the user configure it. */
|
|
||||||
if (!custom_monitor_mode)
|
if (!custom_monitor_mode)
|
||||||
wlr_output_state_set_mode(&state,
|
wlr_output_state_set_mode(&state,
|
||||||
wlr_output_preferred_mode(wlr_output));
|
wlr_output_preferred_mode(wlr_output));
|
||||||
|
|
@ -4037,6 +4040,9 @@ void init_client_properties(Client *c) {
|
||||||
c->master_mfact_per = 0.0f;
|
c->master_mfact_per = 0.0f;
|
||||||
c->master_inner_per = 0.0f;
|
c->master_inner_per = 0.0f;
|
||||||
c->stack_inner_per = 0.0f;
|
c->stack_inner_per = 0.0f;
|
||||||
|
c->old_stack_inner_per = 1.0f;
|
||||||
|
c->old_master_inner_per = 1.0f;
|
||||||
|
c->old_master_mfact_per = 1.0f;
|
||||||
c->isterm = 0;
|
c->isterm = 0;
|
||||||
c->allow_csd = 0;
|
c->allow_csd = 0;
|
||||||
c->force_maximize = 0;
|
c->force_maximize = 0;
|
||||||
|
|
@ -4839,6 +4845,11 @@ void exchange_two_client(Client *c1, Client *c2) {
|
||||||
} else {
|
} else {
|
||||||
arrange(c1->mon, false, false);
|
arrange(c1->mon, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// In order to facilitate repeated exchanges for get_focused_stack_client
|
||||||
|
// set c2 focus order behind c1
|
||||||
|
wl_list_remove(&c2->flink);
|
||||||
|
wl_list_insert(&c1->flink, &c2->flink);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_activation_env() {
|
void set_activation_env() {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue