feat: add windowrule option vrr_only_fullscreen

This commit is contained in:
DreamMaoMao 2026-06-23 14:45:06 +08:00
parent 68ac770281
commit b472fa11d1
3 changed files with 43 additions and 4 deletions

View file

@ -35,6 +35,7 @@ windowrule=Parameter:Values,Parameter:Values,appid:Values,title:Values
| `single_scratchpad` | integer | `0` / `1` (default 1) | Only show one out of named scratchpads or the normal scratchpad |
| `allow_shortcuts_inhibit` | integer | `0` / `1` (default 1) | Allow shortcuts to be inhibited by clients |
| `idleinhibit_when_focus` | integer | `0` / `1` (default 0) | Automatically keep idle inhibit active when this window is focused |
| `vrr_only_fullscreen` | integer | `0` / `1` (default 0) | VRR only fullscreen,you need to turn `vrr` to `0` in monitor rule first |
| `shield_when_capture` | integer | `0` / `1` | Shield window when captured |

View file

@ -80,6 +80,7 @@ typedef struct {
int32_t ignore_minimize;
int32_t isnosizehint;
int32_t idleinhibit_when_focus;
int32_t vrr_only_fullscreen;
char *monitor;
int32_t offsetx;
int32_t offsety;
@ -2364,6 +2365,7 @@ bool parse_option(Config *config, char *key, char *value) {
rule->ignore_minimize = -1;
rule->isnosizehint = -1;
rule->idleinhibit_when_focus = -1;
rule->vrr_only_fullscreen = -1;
rule->isterm = -1;
rule->allow_csd = -1;
rule->force_fakemaximize = -1;
@ -2478,6 +2480,8 @@ bool parse_option(Config *config, char *key, char *value) {
rule->isnosizehint = atoi(val);
} else if (strcmp(key, "idleinhibit_when_focus") == 0) {
rule->idleinhibit_when_focus = atoi(val);
} else if (strcmp(key, "vrr_only_fullscreen") == 0) {
rule->vrr_only_fullscreen = atoi(val);
} else if (strcmp(key, "isterm") == 0) {
rule->isterm = atoi(val);
} else if (strcmp(key, "allow_csd") == 0) {

View file

@ -379,7 +379,8 @@ struct Client {
struct wlr_foreign_toplevel_handle_v1 *foreign_toplevel;
int32_t isfloating, isurgent, isfullscreen, isfakefullscreen,
need_float_size_reduce, isminimized, isoverlay, isnosizehint,
ignore_maximize, ignore_minimize, idleinhibit_when_focus;
ignore_maximize, ignore_minimize, idleinhibit_when_focus,
vrr_only_fullscreen;
int32_t ismaximizescreen;
int32_t overview_backup_bw;
int32_t fullscreen_backup_x, fullscreen_backup_y, fullscreen_backup_w,
@ -595,6 +596,8 @@ struct Monitor {
struct wlr_ext_workspace_group_handle_v1 *ext_group;
bool iscleanuping;
int8_t carousel_anim_dir;
bool vrr_global_enable;
bool is_vrr_opening;
};
typedef struct {
@ -1653,6 +1656,7 @@ static void apply_rule_properties(Client *c, const ConfigWinRule *r) {
APPLY_INT_PROP(c, r, ignore_minimize);
APPLY_INT_PROP(c, r, isnosizehint);
APPLY_INT_PROP(c, r, idleinhibit_when_focus);
APPLY_INT_PROP(c, r, vrr_only_fullscreen);
APPLY_INT_PROP(c, r, isunglobal);
APPLY_INT_PROP(c, r, noblur);
APPLY_INT_PROP(c, r, allow_shortcuts_inhibit);
@ -3353,17 +3357,24 @@ struct wlr_output_mode *get_nearest_output_mode(struct wlr_output *output,
}
void enable_adaptive_sync(Monitor *m, struct wlr_output_state *state) {
wlr_output_state_set_adaptive_sync_enabled(state, true);
if (!wlr_output_test_state(m->wlr_output, state)) {
wlr_output_state_set_adaptive_sync_enabled(state, false);
wlr_log(WLR_DEBUG, "failed to enable adaptive sync for output %s",
m->wlr_output->name);
} else {
m->is_vrr_opening = true;
wlr_log(WLR_INFO, "adaptive sync enabled for output %s",
m->wlr_output->name);
}
}
void disable_adaptive_sync(Monitor *m, struct wlr_output_state *state) {
wlr_output_state_set_adaptive_sync_enabled(state, false);
m->is_vrr_opening = false;
}
bool monitor_matches_rule(Monitor *m, const ConfigMonitorRule *rule) {
if (rule->name != NULL && !regex_match(rule->name, m->wlr_output->name))
return false;
@ -3384,6 +3395,8 @@ bool monitor_matches_rule(Monitor *m, const ConfigMonitorRule *rule) {
bool apply_rule_to_state(Monitor *m, const ConfigMonitorRule *rule,
struct wlr_output_state *state, int vrr, int custom) {
bool mode_set = false;
m->vrr_global_enable = vrr;
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);
@ -3400,7 +3413,7 @@ bool apply_rule_to_state(Monitor *m, const ConfigMonitorRule *rule,
if (vrr) {
enable_adaptive_sync(m, state);
} else {
wlr_output_state_set_adaptive_sync_enabled(state, false);
disable_adaptive_sync(m, state);
}
wlr_output_state_set_scale(state, rule->scale);
wlr_output_state_set_transform(state, rule->rr);
@ -3439,6 +3452,8 @@ void createmon(struct wl_listener *listener, void *data) {
m->resizing_count_pending = 0;
m->resizing_count_current = 0;
m->carousel_anim_dir = 0;
m->vrr_global_enable = false;
m->is_vrr_opening = false;
m->wlr_output = wlr_output;
m->wlr_output->data = m;
@ -4603,6 +4618,7 @@ void init_client_properties(Client *c) {
c->force_tearing = 0;
c->allow_shortcuts_inhibit = SHORTCUTS_INHIBIT_ENABLE;
c->idleinhibit_when_focus = 0;
c->vrr_only_fullscreen = 0;
c->scroller_proportion_single = 0.0f;
c->float_geom.width = 0;
c->float_geom.height = 0;
@ -5140,8 +5156,12 @@ outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int32_t test) {
wlr_output_state_set_transform(&state, config_head->state.transform);
wlr_output_state_set_scale(&state, config_head->state.scale);
wlr_output_state_set_adaptive_sync_enabled(
&state, config_head->state.adaptive_sync_enabled);
if (config_head->state.adaptive_sync_enabled) {
enable_adaptive_sync(m, &state);
} else {
disable_adaptive_sync(m, &state);
}
apply_or_test:
ok &= test ? wlr_output_test_state(wlr_output, &state)
@ -6637,6 +6657,20 @@ void check_keep_idle_inhibit(Client *c) {
if (c && c->idleinhibit_when_focus && keep_idle_inhibit_source) {
wl_event_source_timer_update(keep_idle_inhibit_source, 1000);
}
if (c && c->mon && c->vrr_only_fullscreen && c->isfullscreen &&
!c->mon->is_vrr_opening) {
struct wlr_output_state state = {0};
enable_adaptive_sync(c->mon, &state);
} else if (c && c->mon && (!c->vrr_only_fullscreen || !c->isfullscreen)) {
if (!c->mon->is_vrr_opening && c->mon->vrr_global_enable) {
struct wlr_output_state state = {0};
enable_adaptive_sync(c->mon, &state);
} else if (c->mon->is_vrr_opening && !c->mon->vrr_global_enable) {
struct wlr_output_state state = {0};
disable_adaptive_sync(c->mon, &state);
}
}
}
int32_t keep_idle_inhibit(void *data) {