diff --git a/src/config/parse_config.h b/src/config/parse_config.h index fda401d9..aa3e3bea 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -85,6 +85,7 @@ typedef struct { int32_t width; int32_t height; int32_t nofocus; + int32_t stayfocused; int32_t nofadein; int32_t nofadeout; int32_t no_force_center; @@ -2064,6 +2065,7 @@ bool parse_option(Config *config, char *key, char *value) { rule->noswallow = -1; rule->noblur = -1; rule->nofocus = -1; + rule->stayfocused = -1; rule->nofadein = -1; rule->nofadeout = -1; rule->no_force_center = -1; @@ -2122,6 +2124,8 @@ bool parse_option(Config *config, char *key, char *value) { rule->offsety = atoi(val); } else if (strcmp(key, "nofocus") == 0) { rule->nofocus = atoi(val); + } else if (strcmp(key, "stayfocused") == 0) { + rule->stayfocused = atoi(val); } else if (strcmp(key, "nofadein") == 0) { rule->nofadein = atoi(val); } else if (strcmp(key, "nofadeout") == 0) { diff --git a/src/mango.c b/src/mango.c index f8f323d0..bb90bc2c 100644 --- a/src/mango.c +++ b/src/mango.c @@ -400,6 +400,7 @@ struct Client { bool scratchpad_switching_mon; bool fake_no_border; int32_t nofocus; + int32_t stayfocused; int32_t nofadein; int32_t nofadeout; int32_t no_force_center; @@ -1330,6 +1331,7 @@ static void apply_rule_properties(Client *c, const ConfigWinRule *r) { APPLY_INT_PROP(c, r, force_tearing); APPLY_INT_PROP(c, r, noswallow); APPLY_INT_PROP(c, r, nofocus); + APPLY_INT_PROP(c, r, stayfocused); APPLY_INT_PROP(c, r, nofadein); APPLY_INT_PROP(c, r, nofadeout); APPLY_INT_PROP(c, r, no_force_center); @@ -3502,6 +3504,11 @@ void focusclient(Client *c, int32_t lift) { if (c && c->nofocus) return; + /* Don't change focus away from a stayfocused window while it's visible */ + if (selmon && selmon->sel && selmon->sel != c && selmon->sel->stayfocused && + VISIBLEON(selmon->sel, selmon) && client_surface(selmon->sel)->mapped) + return; + /* Raise client in stacking order if requested */ if (c && lift) wlr_scene_node_raise_to_top(&c->scene->node); // 将视图提升到顶层 @@ -3549,6 +3556,10 @@ void focusclient(Client *c, int32_t lift) { // change border color c->isurgent = 0; + + // set exclusive_focus for stayfocused windows + if (c->stayfocused) + exclusive_focus = c; } // update other monitor focus disappear @@ -3578,7 +3589,9 @@ void focusclient(Client *c, int32_t lift) { l->layer_surface->current.layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP && l == exclusive_focus) { return; - } else if (w && w == exclusive_focus && client_wants_focus(w)) { + } else if (w && w == exclusive_focus && + (client_wants_focus(w) || w->stayfocused) && w->mon && + VISIBLEON(w, w->mon) && client_surface(w)->mapped) { return; /* Don't deactivate old_keyboard_focus_surface client if the new * one wants focus, as this causes issues with winecfg and @@ -4054,6 +4067,7 @@ void init_client_properties(Client *c) { c->focused_opacity = config.focused_opacity; c->unfocused_opacity = config.unfocused_opacity; c->nofocus = 0; + c->stayfocused = 0; c->nofadein = 0; c->nofadeout = 0; c->no_force_center = 0; @@ -6050,6 +6064,9 @@ void unmapnotify(struct wl_listener *listener, void *data) { } } + if (c->stayfocused && c == exclusive_focus) + exclusive_focus = NULL; + if (c->mon && c->mon == selmon) { if (next_in_stack && !c->swallowedby) { nextfocus = next_in_stack;