Skip to content

Commit 8f8efcb

Browse files
committed
fix: avoid mutual influence of monitor rules
1 parent 24134d4 commit 8f8efcb

2 files changed

Lines changed: 60 additions & 123 deletions

File tree

src/config/parse_config.h

Lines changed: 11 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,9 @@ typedef int32_t (*FuncType)(const Arg *);
372372
Config config;
373373

374374
bool parse_config_file(Config *config, const char *file_path, bool must_exist);
375+
bool apply_rule_to_state(Monitor *m, const ConfigMonitorRule *rule,
376+
struct wlr_output_state *state, int vrr, int custom);
377+
bool monitor_matches_rule(Monitor *m, const ConfigMonitorRule *rule);
375378

376379
// Helper function to trim whitespace from start and end of a string
377380
void trim_whitespace(char *str) {
@@ -3563,88 +3566,35 @@ void reapply_monitor_rules(void) {
35633566
int32_t ji, vrr, custom;
35643567
int32_t mx, my;
35653568
struct wlr_output_state state;
3566-
struct wlr_output_mode *internal_mode = NULL;
3567-
wlr_output_state_init(&state);
3568-
bool match_rule = false;
35693569

35703570
wl_list_for_each(m, &mons, link) {
3571-
if (!m->wlr_output->enabled) {
3571+
if (!m->wlr_output->enabled)
35723572
continue;
3573-
}
3573+
3574+
wlr_output_state_init(&state);
35743575

35753576
for (ji = 0; ji < config.monitor_rules_count; ji++) {
35763577
if (config.monitor_rules_count < 1)
35773578
break;
35783579

35793580
mr = &config.monitor_rules[ji];
35803581

3581-
// 检查是否匹配的变量
3582-
match_rule = true;
3583-
3584-
// 检查四个标识字段的匹配
3585-
if (mr->name != NULL) {
3586-
if (!regex_match(mr->name, m->wlr_output->name)) {
3587-
match_rule = false;
3588-
}
3589-
}
3590-
3591-
if (mr->make != NULL) {
3592-
if (m->wlr_output->make == NULL ||
3593-
strcmp(mr->make, m->wlr_output->make) != 0) {
3594-
match_rule = false;
3595-
}
3596-
}
3597-
3598-
if (mr->model != NULL) {
3599-
if (m->wlr_output->model == NULL ||
3600-
strcmp(mr->model, m->wlr_output->model) != 0) {
3601-
match_rule = false;
3602-
}
3603-
}
3604-
3605-
if (mr->serial != NULL) {
3606-
if (m->wlr_output->serial == NULL ||
3607-
strcmp(mr->serial, m->wlr_output->serial) != 0) {
3608-
match_rule = false;
3609-
}
3610-
}
3611-
3612-
// 只有当所有指定的标识都匹配时才应用规则
3613-
if (match_rule) {
3582+
if (monitor_matches_rule(m, mr)) {
36143583
mx = mr->x == INT32_MAX ? m->m.x : mr->x;
36153584
my = mr->y == INT32_MAX ? m->m.y : mr->y;
36163585
vrr = mr->vrr >= 0 ? mr->vrr : 0;
36173586
custom = mr->custom >= 0 ? mr->custom : 0;
36183587

3619-
if (mr->width > 0 && mr->height > 0 && mr->refresh > 0) {
3620-
internal_mode = get_nearest_output_mode(
3621-
m->wlr_output, mr->width, mr->height, mr->refresh);
3622-
if (internal_mode) {
3623-
wlr_output_state_set_mode(&state, internal_mode);
3624-
} else if (custom ||
3625-
wlr_output_is_headless(m->wlr_output)) {
3626-
wlr_output_state_set_custom_mode(
3627-
&state, mr->width, mr->height,
3628-
(int32_t)roundf(mr->refresh * 1000));
3629-
}
3630-
}
3631-
3632-
if (vrr) {
3633-
enable_adaptive_sync(m, &state);
3634-
} else {
3635-
wlr_output_state_set_adaptive_sync_enabled(&state, false);
3636-
}
3637-
3638-
wlr_output_state_set_scale(&state, mr->scale);
3639-
wlr_output_state_set_transform(&state, mr->rr);
3588+
(void)apply_rule_to_state(m, mr, &state, vrr, custom);
36403589
wlr_output_layout_add(output_layout, m->wlr_output, mx, my);
3590+
wlr_output_commit_state(m->wlr_output, &state);
3591+
break;
36413592
}
36423593
}
36433594

3644-
wlr_output_commit_state(m->wlr_output, &state);
36453595
wlr_output_state_finish(&state);
3646-
updatemons(NULL, NULL);
36473596
}
3597+
updatemons(NULL, NULL);
36483598
}
36493599

36503600
void reapply_cursor_style(void) {

src/mango.c

Lines changed: 49 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -806,7 +806,6 @@ static int32_t keep_idle_inhibit(void *data);
806806
static void check_keep_idle_inhibit(Client *c);
807807
static void pre_caculate_before_arrange(Monitor *m, bool want_animation,
808808
bool from_view, bool only_caculate);
809-
810809
#include "data/static_keymap.h"
811810
#include "dispatch/bind_declare.h"
812811
#include "layout/layout.h"
@@ -2878,6 +2877,49 @@ void enable_adaptive_sync(Monitor *m, struct wlr_output_state *state) {
28782877
}
28792878
}
28802879

2880+
bool monitor_matches_rule(Monitor *m, const ConfigMonitorRule *rule) {
2881+
if (rule->name != NULL && !regex_match(rule->name, m->wlr_output->name))
2882+
return false;
2883+
if (rule->make != NULL && (m->wlr_output->make == NULL ||
2884+
strcmp(rule->make, m->wlr_output->make) != 0))
2885+
return false;
2886+
if (rule->model != NULL && (m->wlr_output->model == NULL ||
2887+
strcmp(rule->model, m->wlr_output->model) != 0))
2888+
return false;
2889+
if (rule->serial != NULL &&
2890+
(m->wlr_output->serial == NULL ||
2891+
strcmp(rule->serial, m->wlr_output->serial) != 0))
2892+
return false;
2893+
return true;
2894+
}
2895+
2896+
/* 将规则中的显示参数应用到 wlr_output_state 中,返回是否设置了自定义模式 */
2897+
bool apply_rule_to_state(Monitor *m, const ConfigMonitorRule *rule,
2898+
struct wlr_output_state *state, int vrr, int custom) {
2899+
bool mode_set = false;
2900+
if (rule->width > 0 && rule->height > 0 && rule->refresh > 0) {
2901+
struct wlr_output_mode *internal_mode = get_nearest_output_mode(
2902+
m->wlr_output, rule->width, rule->height, rule->refresh);
2903+
if (internal_mode) {
2904+
wlr_output_state_set_mode(state, internal_mode);
2905+
mode_set = true;
2906+
} else if (custom || wlr_output_is_headless(m->wlr_output)) {
2907+
wlr_output_state_set_custom_mode(
2908+
state, rule->width, rule->height,
2909+
(int32_t)roundf(rule->refresh * 1000));
2910+
mode_set = true;
2911+
}
2912+
}
2913+
if (vrr) {
2914+
enable_adaptive_sync(m, state);
2915+
} else {
2916+
wlr_output_state_set_adaptive_sync_enabled(state, false);
2917+
}
2918+
wlr_output_state_set_scale(state, rule->scale);
2919+
wlr_output_state_set_transform(state, rule->rr);
2920+
return mode_set;
2921+
}
2922+
28812923
void createmon(struct wl_listener *listener, void *data) {
28822924
/* This event is raised by the backend when a new output (aka a display or
28832925
* monitor) becomes available. */
@@ -2887,9 +2929,7 @@ void createmon(struct wl_listener *listener, void *data) {
28872929
int32_t ji, vrr, custom;
28882930
struct wlr_output_state state;
28892931
Monitor *m = NULL;
2890-
struct wlr_output_mode *internal_mode = NULL;
28912932
bool custom_monitor_mode = false;
2892-
bool match_rule = false;
28932933

28942934
if (!wlr_output_init_render(wlr_output, alloc, drw))
28952935
return;
@@ -2919,7 +2959,6 @@ void createmon(struct wl_listener *listener, void *data) {
29192959
for (i = 0; i < LENGTH(m->layers); i++)
29202960
wl_list_init(&m->layers[i]);
29212961

2922-
wlr_output_state_init(&state);
29232962
/* Initialize monitor state using configured rules */
29242963
m->gappih = gappih;
29252964
m->gappiv = gappiv;
@@ -2932,6 +2971,8 @@ void createmon(struct wl_listener *listener, void *data) {
29322971
m->m.y = INT32_MAX;
29332972
float scale = 1;
29342973
enum wl_output_transform rr = WL_OUTPUT_TRANSFORM_NORMAL;
2974+
2975+
wlr_output_state_init(&state);
29352976
wlr_output_state_set_scale(&state, scale);
29362977
wlr_output_state_set_transform(&state, rr);
29372978

@@ -2941,75 +2982,21 @@ void createmon(struct wl_listener *listener, void *data) {
29412982

29422983
r = &config.monitor_rules[ji];
29432984

2944-
// 检查是否匹配的变量
2945-
match_rule = true;
2946-
2947-
// 检查四个标识字段的匹配
2948-
if (r->name != NULL) {
2949-
if (!regex_match(r->name, m->wlr_output->name)) {
2950-
match_rule = false;
2951-
}
2952-
}
2953-
2954-
if (r->make != NULL) {
2955-
if (m->wlr_output->make == NULL ||
2956-
strcmp(r->make, m->wlr_output->make) != 0) {
2957-
match_rule = false;
2958-
}
2959-
}
2960-
2961-
if (r->model != NULL) {
2962-
if (m->wlr_output->model == NULL ||
2963-
strcmp(r->model, m->wlr_output->model) != 0) {
2964-
match_rule = false;
2965-
}
2966-
}
2967-
2968-
if (r->serial != NULL) {
2969-
if (m->wlr_output->serial == NULL ||
2970-
strcmp(r->serial, m->wlr_output->serial) != 0) {
2971-
match_rule = false;
2972-
}
2973-
}
2974-
2975-
if (match_rule) {
2985+
if (monitor_matches_rule(m, r)) {
29762986
m->m.x = r->x == INT32_MAX ? INT32_MAX : r->x;
29772987
m->m.y = r->y == INT32_MAX ? INT32_MAX : r->y;
29782988
vrr = r->vrr >= 0 ? r->vrr : 0;
29792989
custom = r->custom >= 0 ? r->custom : 0;
29802990
scale = r->scale;
29812991
rr = r->rr;
29822992

2983-
if (r->width > 0 && r->height > 0 && r->refresh > 0) {
2984-
internal_mode = get_nearest_output_mode(m->wlr_output, r->width,
2985-
r->height, r->refresh);
2986-
if (internal_mode) {
2987-
custom_monitor_mode = true;
2988-
wlr_output_state_set_mode(&state, internal_mode);
2989-
} else if (custom || wlr_output_is_headless(m->wlr_output)) {
2990-
custom_monitor_mode = true;
2991-
wlr_output_state_set_custom_mode(
2992-
&state, r->width, r->height,
2993-
(int32_t)roundf(r->refresh * 1000));
2994-
}
2995-
}
2996-
2997-
if (vrr) {
2998-
enable_adaptive_sync(m, &state);
2999-
} else {
3000-
wlr_output_state_set_adaptive_sync_enabled(&state, false);
2993+
if (apply_rule_to_state(m, r, &state, vrr, custom)) {
2994+
custom_monitor_mode = true;
30012995
}
3002-
3003-
wlr_output_state_set_scale(&state, r->scale);
3004-
wlr_output_state_set_transform(&state, r->rr);
3005-
break;
2996+
break; // 只应用第一个匹配规则
30062997
}
30072998
}
30082999

3009-
/* The mode is a tuple of (width, height, refresh rate), and each
3010-
* monitor supports only a specific set of modes. We just pick the
3011-
* monitor's preferred mode; a more sophisticated compositor would let
3012-
* the user configure it. */
30133000
if (!custom_monitor_mode)
30143001
wlr_output_state_set_mode(&state,
30153002
wlr_output_preferred_mode(wlr_output));

0 commit comments

Comments
 (0)