diff --git a/src/config/parse_config.h b/src/config/parse_config.h index 9c27872..3aa1377 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -83,6 +83,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; @@ -1732,6 +1733,7 @@ void 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; @@ -1789,6 +1791,8 @@ void 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 ac5edf9..95c2d3e 100644 --- a/src/mango.c +++ b/src/mango.c @@ -388,6 +388,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; @@ -1214,6 +1215,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); @@ -3187,6 +3189,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); // 将视图提升到顶层 @@ -3232,6 +3239,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 @@ -3261,7 +3272,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 @@ -3720,6 +3733,7 @@ void init_client_properties(Client *c) { c->focused_opacity = focused_opacity; c->unfocused_opacity = unfocused_opacity; c->nofocus = 0; + c->stayfocused = 0; c->nofadein = 0; c->nofadeout = 0; c->no_force_center = 0; @@ -5432,6 +5446,9 @@ void unmapnotify(struct wl_listener *listener, void *data) { } } + if (c->stayfocused && c == exclusive_focus) + exclusive_focus = NULL; + if (c->mon && c->mon == selmon) { Client *nextfocus = focustop(selmon);