mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2026-03-07 04:34:24 -05:00
fix: avoid mutual influence of monitor rules
This commit is contained in:
parent
29a4f93b4e
commit
ebcf238bd3
2 changed files with 60 additions and 123 deletions
|
|
@ -353,6 +353,9 @@ typedef int32_t (*FuncType)(const Arg *);
|
|||
Config config;
|
||||
|
||||
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
|
||||
void trim_whitespace(char *str) {
|
||||
|
|
@ -3419,14 +3422,12 @@ void reapply_monitor_rules(void) {
|
|||
int32_t ji, vrr, custom;
|
||||
int32_t mx, my;
|
||||
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) {
|
||||
if (!m->wlr_output->enabled) {
|
||||
if (!m->wlr_output->enabled)
|
||||
continue;
|
||||
}
|
||||
|
||||
wlr_output_state_init(&state);
|
||||
|
||||
for (ji = 0; ji < config.monitor_rules_count; ji++) {
|
||||
if (config.monitor_rules_count < 1)
|
||||
|
|
@ -3434,73 +3435,22 @@ void reapply_monitor_rules(void) {
|
|||
|
||||
mr = &config.monitor_rules[ji];
|
||||
|
||||
// 检查是否匹配的变量
|
||||
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) {
|
||||
if (monitor_matches_rule(m, mr)) {
|
||||
mx = mr->x == INT32_MAX ? m->m.x : mr->x;
|
||||
my = mr->y == INT32_MAX ? m->m.y : mr->y;
|
||||
vrr = mr->vrr >= 0 ? mr->vrr : 0;
|
||||
custom = mr->custom >= 0 ? mr->custom : 0;
|
||||
|
||||
if (mr->width > 0 && mr->height > 0 && mr->refresh > 0) {
|
||||
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 (custom ||
|
||||
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);
|
||||
(void)apply_rule_to_state(m, mr, &state, vrr, custom);
|
||||
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);
|
||||
updatemons(NULL, NULL);
|
||||
}
|
||||
updatemons(NULL, NULL);
|
||||
}
|
||||
|
||||
void reapply_cursor_style(void) {
|
||||
|
|
|
|||
111
src/mango.c
111
src/mango.c
|
|
@ -820,7 +820,6 @@ static int32_t keep_idle_inhibit(void *data);
|
|||
static void check_keep_idle_inhibit(Client *c);
|
||||
static void pre_caculate_before_arrange(Monitor *m, bool want_animation,
|
||||
bool from_view, bool only_caculate);
|
||||
|
||||
#include "data/static_keymap.h"
|
||||
#include "dispatch/bind_declare.h"
|
||||
#include "layout/layout.h"
|
||||
|
|
@ -2840,6 +2839,49 @@ 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) {
|
||||
/* This event is raised by the backend when a new output (aka a display or
|
||||
* monitor) becomes available. */
|
||||
|
|
@ -2849,9 +2891,7 @@ void createmon(struct wl_listener *listener, void *data) {
|
|||
int32_t ji, vrr, custom;
|
||||
struct wlr_output_state state;
|
||||
Monitor *m = NULL;
|
||||
struct wlr_output_mode *internal_mode = NULL;
|
||||
bool custom_monitor_mode = false;
|
||||
bool match_rule = false;
|
||||
|
||||
if (!wlr_output_init_render(wlr_output, alloc, drw))
|
||||
return;
|
||||
|
|
@ -2881,7 +2921,6 @@ void createmon(struct wl_listener *listener, void *data) {
|
|||
for (i = 0; i < LENGTH(m->layers); i++)
|
||||
wl_list_init(&m->layers[i]);
|
||||
|
||||
wlr_output_state_init(&state);
|
||||
/* Initialize monitor state using configured rules */
|
||||
m->gappih = gappih;
|
||||
m->gappiv = gappiv;
|
||||
|
|
@ -2894,6 +2933,8 @@ void createmon(struct wl_listener *listener, void *data) {
|
|||
m->m.y = INT32_MAX;
|
||||
float scale = 1;
|
||||
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_transform(&state, rr);
|
||||
|
||||
|
|
@ -2903,38 +2944,7 @@ void createmon(struct wl_listener *listener, void *data) {
|
|||
|
||||
r = &config.monitor_rules[ji];
|
||||
|
||||
// 检查是否匹配的变量
|
||||
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) {
|
||||
if (monitor_matches_rule(m, r)) {
|
||||
m->m.x = r->x == INT32_MAX ? INT32_MAX : r->x;
|
||||
m->m.y = r->y == INT32_MAX ? INT32_MAX : r->y;
|
||||
vrr = r->vrr >= 0 ? r->vrr : 0;
|
||||
|
|
@ -2942,36 +2952,13 @@ void createmon(struct wl_listener *listener, void *data) {
|
|||
scale = r->scale;
|
||||
rr = r->rr;
|
||||
|
||||
if (r->width > 0 && r->height > 0 && r->refresh > 0) {
|
||||
internal_mode = get_nearest_output_mode(m->wlr_output, r->width,
|
||||
r->height, r->refresh);
|
||||
if (internal_mode) {
|
||||
custom_monitor_mode = true;
|
||||
wlr_output_state_set_mode(&state, internal_mode);
|
||||
} else if (custom || 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));
|
||||
}
|
||||
if (apply_rule_to_state(m, r, &state, vrr, custom)) {
|
||||
custom_monitor_mode = true;
|
||||
}
|
||||
|
||||
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;
|
||||
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)
|
||||
wlr_output_state_set_mode(&state,
|
||||
wlr_output_preferred_mode(wlr_output));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue