This commit is contained in:
0xwal 2026-01-18 10:09:26 +00:00 committed by GitHub
commit 7fe18f9db9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 111 additions and 10 deletions

View file

@ -178,6 +178,12 @@ bind=SUPER,o,toggleoverlay,
bind=SUPER+SHIFT,I,restore_minimized bind=SUPER+SHIFT,I,restore_minimized
bind=ALT,z,toggle_scratchpad bind=ALT,z,toggle_scratchpad
# window opacity control
bind=SUPER,equal,inc_opacity,0.1
bind=SUPER,minus,dec_opacity,0.1
bind=SUPER+SHIFT,o,toggle_opacity,
bind=SUPER+SHIFT,c,clear_custom_opacity,
# scroller layout # scroller layout
bind=ALT,e,set_proportion,1.0 bind=ALT,e,set_proportion,1.0
bind=ALT,x,switch_proportion_preset, bind=ALT,x,switch_proportion_preset,

View file

@ -1044,10 +1044,17 @@ void client_set_focused_opacity_animation(Client *c) {
return; return;
} }
float opacity =
c == selmon->sel ? c->focused_opacity : c->unfocused_opacity;
if (c->custom_opacity > 0.0f) {
opacity = c->custom_opacity;
}
c->opacity_animation.duration = animation_duration_focus; c->opacity_animation.duration = animation_duration_focus;
memcpy(c->opacity_animation.target_border_color, border_color, memcpy(c->opacity_animation.target_border_color, border_color,
sizeof(c->opacity_animation.target_border_color)); sizeof(c->opacity_animation.target_border_color));
c->opacity_animation.target_opacity = c->focused_opacity; c->opacity_animation.target_opacity = opacity;
c->opacity_animation.time_started = get_now_in_ms(); c->opacity_animation.time_started = get_now_in_ms();
if (c->opacity_animation.running) { if (c->opacity_animation.running) {
memcpy(c->opacity_animation.initial_border_color, memcpy(c->opacity_animation.initial_border_color,
@ -1070,6 +1077,13 @@ void client_set_unfocused_opacity_animation(Client *c) {
// Start border color animation to unfocused // Start border color animation to unfocused
float *border_color = get_border_color(c); float *border_color = get_border_color(c);
float opacity =
c == selmon->sel ? c->focused_opacity : c->unfocused_opacity;
if (c->custom_opacity > 0.0f) {
opacity = c->custom_opacity;
}
if (!animations) { if (!animations) {
setborder_color(c); setborder_color(c);
return; return;
@ -1079,7 +1093,7 @@ void client_set_unfocused_opacity_animation(Client *c) {
memcpy(c->opacity_animation.target_border_color, border_color, memcpy(c->opacity_animation.target_border_color, border_color,
sizeof(c->opacity_animation.target_border_color)); sizeof(c->opacity_animation.target_border_color));
// Start opacity animation to unfocused // Start opacity animation to unfocused
c->opacity_animation.target_opacity = c->unfocused_opacity; c->opacity_animation.target_opacity = opacity;
c->opacity_animation.time_started = get_now_in_ms(); c->opacity_animation.time_started = get_now_in_ms();
if (c->opacity_animation.running) { if (c->opacity_animation.running) {
@ -1103,6 +1117,13 @@ void client_set_unfocused_opacity_animation(Client *c) {
bool client_apply_focus_opacity(Client *c) { bool client_apply_focus_opacity(Client *c) {
// Animate focus transitions (opacity + border color) // Animate focus transitions (opacity + border color)
float *border_color = get_border_color(c); float *border_color = get_border_color(c);
float opacity =
c == selmon->sel ? c->focused_opacity : c->unfocused_opacity;
if (c->custom_opacity > 0.0f) {
opacity = c->custom_opacity;
}
if (c->isfullscreen) { if (c->isfullscreen) {
c->opacity_animation.running = false; c->opacity_animation.running = false;
client_set_opacity(c, 1); client_set_opacity(c, 1);
@ -1122,8 +1143,6 @@ bool client_apply_focus_opacity(Client *c) {
float percent = float percent =
animation_fade_in && !c->nofadein ? opacity_eased_progress : 1.0; animation_fade_in && !c->nofadein ? opacity_eased_progress : 1.0;
float opacity =
c == selmon->sel ? c->focused_opacity : c->unfocused_opacity;
float target_opacity = float target_opacity =
percent * (1.0 - fadein_begin_opacity) + fadein_begin_opacity; percent * (1.0 - fadein_begin_opacity) + fadein_begin_opacity;
@ -1168,16 +1187,16 @@ bool client_apply_focus_opacity(Client *c) {
} }
} else if (c == selmon->sel) { } else if (c == selmon->sel) {
c->opacity_animation.running = false; c->opacity_animation.running = false;
c->opacity_animation.current_opacity = c->focused_opacity; c->opacity_animation.current_opacity = opacity;
memcpy(c->opacity_animation.current_border_color, border_color, memcpy(c->opacity_animation.current_border_color, border_color,
sizeof(c->opacity_animation.current_border_color)); sizeof(c->opacity_animation.current_border_color));
client_set_opacity(c, c->focused_opacity); client_set_opacity(c, opacity);
} else { } else {
c->opacity_animation.running = false; c->opacity_animation.running = false;
c->opacity_animation.current_opacity = c->unfocused_opacity; c->opacity_animation.current_opacity = opacity;
memcpy(c->opacity_animation.current_border_color, border_color, memcpy(c->opacity_animation.current_border_color, border_color,
sizeof(c->opacity_animation.current_border_color)); sizeof(c->opacity_animation.current_border_color));
client_set_opacity(c, c->unfocused_opacity); client_set_opacity(c, opacity);
} }
return false; return false;

View file

@ -1083,6 +1083,16 @@ FuncType parse_func_name(char *func_name, Arg *arg, char *arg_value,
} else if (strcmp(func_name, "scroller_stack") == 0) { } else if (strcmp(func_name, "scroller_stack") == 0) {
func = scroller_stack; func = scroller_stack;
(*arg).i = parse_direction(arg_value); (*arg).i = parse_direction(arg_value);
} else if (strcmp(func_name, "toggle_opacity") == 0) {
func = toggle_opacity;
} else if (strcmp(func_name, "inc_opacity") == 0) {
(*arg).f = atof(arg_value);
func = inc_opacity;
} else if (strcmp(func_name, "dec_opacity") == 0) {
(*arg).f = atof(arg_value);
func = dec_opacity;
} else if (strcmp(func_name, "clear_custom_opacity") == 0) {
func = clear_custom_opacity;
} else { } else {
return NULL; return NULL;
} }

View file

@ -69,4 +69,8 @@ int32_t setoption(const Arg *arg);
int32_t disable_monitor(const Arg *arg); int32_t disable_monitor(const Arg *arg);
int32_t enable_monitor(const Arg *arg); int32_t enable_monitor(const Arg *arg);
int32_t toggle_monitor(const Arg *arg); int32_t toggle_monitor(const Arg *arg);
int32_t scroller_stack(const Arg *arg); int32_t scroller_stack(const Arg *arg);
int32_t toggle_opacity(const Arg *arg);
int32_t inc_opacity(const Arg *arg);
int32_t dec_opacity(const Arg *arg);
int32_t clear_custom_opacity(const Arg *arg);

View file

@ -1672,4 +1672,64 @@ int32_t scroller_stack(const Arg *arg) {
arrange(selmon, false, false); arrange(selmon, false, false);
return 0; return 0;
} }
int32_t toggle_opacity(const Arg *arg) {
Client *c = selmon->sel;
if (!c)
return 0;
if (c->custom_opacity > 0.0f) {
c->custom_opacity = 0.0f;
client_set_opacity(c, c->focused_opacity);
} else {
c->custom_opacity = 1.0f;
client_set_opacity(c, 1.0f);
}
return 0;
}
int32_t inc_opacity(const Arg *arg) {
Client *c = selmon->sel;
if (!c)
return 0;
float value = CLAMP_FLOAT(arg->f, 0.01f, 1.0f);
if (c->custom_opacity == 0.0f) {
c->custom_opacity = c->focused_opacity;
}
float target = MIN(c->custom_opacity + value, 1.0f);
c->custom_opacity = target;
client_set_opacity(c, target);
return 0;
}
int32_t dec_opacity(const Arg *arg) {
Client *c = selmon->sel;
if (!c)
return 0;
float value = CLAMP_FLOAT(arg->f, 0.01f, 1.0f);
if (c->custom_opacity == 0.0f) {
c->custom_opacity = c->focused_opacity;
}
float target = MAX(c->custom_opacity - value, 0.01f);
c->custom_opacity = target;
client_set_opacity(c, target);
return 0;
}
int32_t clear_custom_opacity(const Arg *arg) {
Client *c = selmon->sel;
if (!c)
return 0;
c->custom_opacity = 0.0f;
client_set_opacity(c, c->focused_opacity);
return 0;
}

View file

@ -401,6 +401,7 @@ struct Client {
int32_t isunglobal; int32_t isunglobal;
float focused_opacity; float focused_opacity;
float unfocused_opacity; float unfocused_opacity;
float custom_opacity;
char oldmonname[128]; char oldmonname[128];
int32_t noblur; int32_t noblur;
double master_mfact_per, master_inner_per, stack_inner_per; double master_mfact_per, master_inner_per, stack_inner_per;
@ -3741,6 +3742,7 @@ void init_client_properties(Client *c) {
c->fake_no_border = false; c->fake_no_border = false;
c->focused_opacity = focused_opacity; c->focused_opacity = focused_opacity;
c->unfocused_opacity = unfocused_opacity; c->unfocused_opacity = unfocused_opacity;
c->custom_opacity = 0.0f;
c->nofocus = 0; c->nofocus = 0;
c->nofadein = 0; c->nofadein = 0;
c->nofadeout = 0; c->nofadeout = 0;