From 67e6a6154f260c2e6a46d084d40b3b87c203346e Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Mon, 2 Jun 2025 22:56:56 +0800 Subject: [PATCH] feat: support winrule option isunglobal unglobal no manage by layout and no get focus by keyboard --- src/layout/layout.h | 53 +++++++++++++-------------------------------- src/maomao.c | 28 ++++++++++++------------ 2 files changed, 29 insertions(+), 52 deletions(-) diff --git a/src/layout/layout.h b/src/layout/layout.h index 1fb9a30..cdcb738 100644 --- a/src/layout/layout.h +++ b/src/layout/layout.h @@ -11,10 +11,7 @@ void fibonacci(Monitor *mon, int s) { cur_gappoh = smartgaps && mon->visible_clients == 1 ? 0 : cur_gappoh; cur_gappov = smartgaps && mon->visible_clients == 1 ? 0 : cur_gappov; // Count visible clients - wl_list_for_each(c, &clients, link) if (VISIBLEON(c, mon) && !c->isfloating && - !c->iskilling && !c->isfullscreen && - !c->ismaxmizescreen && - !c->animation.tagouting) n++; + wl_list_for_each(c, &clients, link) if (VISIBLEON(c, mon) && ISTILED(c)) n++; if (n == 0) return; @@ -27,8 +24,7 @@ void fibonacci(Monitor *mon, int s) { // First pass: calculate client geometries wl_list_for_each(c, &clients, link) { - if (!VISIBLEON(c, mon) || c->isfloating || c->iskilling || - c->isfullscreen || c->ismaxmizescreen || c->animation.tagouting) + if (!VISIBLEON(c, mon) || !ISTILED(c)) continue; c->bw = mon->visible_clients == 1 && no_border_when_single && smartgaps @@ -86,8 +82,7 @@ void fibonacci(Monitor *mon, int s) { // Second pass: apply gaps between clients wl_list_for_each(c, &clients, link) { - if (!VISIBLEON(c, mon) || c->isfloating || c->iskilling || - c->isfullscreen || c->ismaxmizescreen || c->animation.tagouting) + if (!VISIBLEON(c, mon) || !ISTILED(c)) continue; unsigned int right_gap = 0; @@ -95,8 +90,7 @@ void fibonacci(Monitor *mon, int s) { Client *nc; wl_list_for_each(nc, &clients, link) { - if (!VISIBLEON(nc, mon) || nc->isfloating || nc->iskilling || - nc->isfullscreen || nc->ismaxmizescreen || nc->animation.tagouting) + if (!VISIBLEON(nc, mon) || !ISTILED(nc)) continue; if (c == nc) @@ -137,9 +131,7 @@ void grid(Monitor *m) { // 第一次遍历,计算 n 的值 wl_list_for_each(c, &clients, link) { - if (VISIBLEON(c, c->mon) && (m->isoverview || ISTILED(c)) && - !client_should_ignore_focus(c) && !c->iskilling && - !c->animation.tagouting && c->mon == selmon) { + if (VISIBLEON(c, c->mon) && !c->isunglobal && (m->isoverview || ISTILED(c))) { n++; } } @@ -153,9 +145,7 @@ void grid(Monitor *m) { c->bw = m->visible_clients == 1 && no_border_when_single && smartgaps ? 0 : borderpx; - if (VISIBLEON(c, c->mon) && (m->isoverview || ISTILED(c)) && - !client_should_ignore_focus(c) && !c->iskilling && - !c->animation.tagouting && c->mon == selmon) { + if (VISIBLEON(c, c->mon) && !c->isunglobal && (m->isoverview || ISTILED(c))) { cw = (m->w.width - 2 * overviewgappo) * 0.7; ch = (m->w.height - 2 * overviewgappo) * 0.8; c->geom.x = m->w.x + (m->w.width - cw) / 2; @@ -176,9 +166,7 @@ void grid(Monitor *m) { c->bw = m->visible_clients == 1 && no_border_when_single && smartgaps ? 0 : borderpx; - if (VISIBLEON(c, c->mon) && (m->isoverview || ISTILED(c)) && - !client_should_ignore_focus(c) && !c->iskilling && - !c->animation.tagouting && c->mon == selmon) { + if (VISIBLEON(c, c->mon) && !c->isunglobal && (m->isoverview || ISTILED(c))) { if (i == 0) { c->geom.x = m->w.x + overviewgappo; c->geom.y = m->w.y + (m->w.height - ch) / 2 + overviewgappo; @@ -223,9 +211,7 @@ void grid(Monitor *m) { c->bw = m->visible_clients == 1 && no_border_when_single && smartgaps ? 0 : borderpx; - if (VISIBLEON(c, c->mon) && (m->isoverview || ISTILED(c)) && - !client_should_ignore_focus(c) && !c->iskilling && - !c->animation.tagouting && c->mon == selmon) { + if (VISIBLEON(c, c->mon) && !c->isunglobal && (m->isoverview || ISTILED(c))) { cx = m->w.x + (i % cols) * (cw + overviewgappi); cy = m->w.y + (i / cols) * (ch + overviewgappi); if (overcols && i >= n - overcols) { @@ -255,8 +241,7 @@ void deck(Monitor *m) { cur_gappoh = smartgaps && m->visible_clients == 1 ? 0 : cur_gappoh; cur_gappov = smartgaps && m->visible_clients == 1 ? 0 : cur_gappov; - wl_list_for_each(c, &clients, link) if (VISIBLEON(c, m) && !c->isfloating && - !c->isfullscreen) n++; + wl_list_for_each(c, &clients, link) if (VISIBLEON(c, m) && ISTILED(c)) n++; if (n == 0) return; @@ -271,7 +256,7 @@ void deck(Monitor *m) { i = my = 0; wl_list_for_each(c, &clients, link) { - if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen) + if (!VISIBLEON(c, m) || !ISTILED(c)) continue; if (i < m->nmaster) { // Master area clients @@ -323,9 +308,7 @@ void scroller(Monitor *m) { // 第一次遍历,计算 n 的值 wl_list_for_each(c, &clients, link) { - if (VISIBLEON(c, c->mon) && !client_is_unmanaged(c) && !c->isfloating && - !c->isfullscreen && !c->ismaxmizescreen && !c->iskilling && - !c->animation.tagouting && c->mon == m) { + if (VISIBLEON(c, c->mon) && ISTILED(c)) { n++; } } @@ -344,9 +327,7 @@ void scroller(Monitor *m) { // 第二次遍历,填充 tempClients n = 0; wl_list_for_each(c, &clients, link) { - if (VISIBLEON(c, c->mon) && !client_is_unmanaged(c) && !c->isfloating && - !c->isfullscreen && !c->ismaxmizescreen && !c->iskilling && - !c->animation.tagouting && c->mon == m) { + if (VISIBLEON(c, c->mon) && ISTILED(c)) { tempClients[n] = c; n++; } @@ -445,9 +426,7 @@ void tile(Monitor *m) { Client *c; wl_list_for_each(c, &clients, - link) if (VISIBLEON(c, m) && !c->animation.tagouting && - !c->iskilling && !c->isfloating && - !c->isfullscreen && !c->ismaxmizescreen) n++; + link) if (VISIBLEON(c, m) && ISTILED(c)) n++; if (n == 0) return; @@ -471,8 +450,7 @@ void tile(Monitor *m) { i = 0; my = ty = cur_gappoh; wl_list_for_each(c, &clients, link) { - if (!VISIBLEON(c, m) || c->iskilling || c->animation.tagouting || - c->isfloating || c->isfullscreen || c->ismaxmizescreen) + if (!VISIBLEON(c, m) || !ISTILED(c)) continue; if (i < selmon->pertag->nmasters[selmon->pertag->curtag]) { r = MIN(n, selmon->pertag->nmasters[selmon->pertag->curtag]) - i; @@ -504,8 +482,7 @@ monocle(Monitor *m) { Client *c; wl_list_for_each(c, &clients, link) { - if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen || - c->ismaxmizescreen || c->iskilling || c->animation.tagouting) + if (!VISIBLEON(c, m) || !ISTILED(c)) continue; resize(c, m->w, 0); } diff --git a/src/maomao.c b/src/maomao.c index 6b384ba..655c858 100644 --- a/src/maomao.c +++ b/src/maomao.c @@ -88,8 +88,8 @@ #define GEZERO(A) ((A) >= 0 ? (A) : 0) #define CLEANMASK(mask) (mask & ~WLR_MODIFIER_CAPS) #define ISTILED(A) \ - (!(A)->isfloating && !(A)->isminied && !(A)->iskilling && \ - !(A)->isfloating && !(A)->ismaxmizescreen && !(A)->isfullscreen) + (!(A)->isfloating && !(A)->isminied && !(A)->iskilling && !client_should_ignore_focus(A) && \ + !(A)->isunglobal && !(A)->animation.tagouting && !(A)->ismaxmizescreen && !(A)->isfullscreen) #define VISIBLEON(C, M) \ ((M) && (C)->mon == (M) && ((C)->tags & (M)->tagset[(M)->seltags])) #define LENGTH(X) (sizeof X / sizeof X[0]) @@ -278,6 +278,7 @@ struct Client { bool fake_no_border; int nofadein; int no_force_center; + int isunglobal; }; typedef struct { @@ -1875,10 +1876,8 @@ applyrules(Client *c) { r->isopenscratchpad > 0 ? r->isopenscratchpad : c->isopenscratchpad; c->isglobal = r->isglobal > 0 ? r->isglobal : c->isglobal; c->isoverlay = r->isoverlay > 0 ? r->isoverlay : c->isoverlay; - c->isglobal = r->isunglobal > 0 && (client_is_unmanaged(c) || - client_should_ignore_focus(c)) - ? r->isunglobal - : c->isglobal; + c->isunglobal = r->isunglobal > 0 ? r->isunglobal : c->isunglobal; + newtags = r->tags > 0 ? r->tags | newtags : newtags; i = 0; wl_list_for_each(m, &mons, link) if (r->monitor == i++) mon = m; @@ -1973,7 +1972,7 @@ arrange(Monitor *m, bool want_animation) { if (c->iskilling) continue; - if (c->mon == m && c->isglobal) { + if (c->mon == m && (c->isglobal || c->isunglobal)) { c->tags = m->tagset[m->seltags]; if (selmon->sel == NULL) focusclient(c, 0); @@ -2233,7 +2232,7 @@ Client *find_client_by_direction(Client *tc, const Arg *arg, bool findfloating, // 第一次遍历,计算客户端数量 wl_list_for_each(c, &clients, link) { - if (c && (findfloating || !c->isfloating) && + if (c && (findfloating || !c->isfloating) && !c->isunglobal && (focus_cross_monitor || c->mon == selmon) && (c->tags & c->mon->tagset[c->mon->seltags])) { last++; @@ -2254,7 +2253,7 @@ Client *find_client_by_direction(Client *tc, const Arg *arg, bool findfloating, // 第二次遍历,填充 tempClients last = -1; wl_list_for_each(c, &clients, link) { - if (c && (findfloating || !c->isfloating) && + if (c && (findfloating || !c->isfloating) && !c->isunglobal && (focus_cross_monitor || c->mon == selmon) && (c->tags & c->mon->tagset[c->mon->seltags])) { last++; @@ -4016,7 +4015,7 @@ Client * // 0.5 focustop(Monitor *m) { Client *c; wl_list_for_each(c, &fstack, flink) { - if (c->iskilling) + if (c->iskilling || c->isunglobal) continue; if (VISIBLEON(c, m)) return c; @@ -4487,6 +4486,7 @@ mapnotify(struct wl_listener *listener, void *data) { c->isglobal = 0; c->isminied = 0; c->isoverlay = 0; + c->isunglobal = 0; c->is_in_scratchpad = 0; c->isnamedscratchpand = 0; c->is_scratchpad_show = 0; @@ -5344,7 +5344,7 @@ void resize(Client *c, struct wlr_box geo, int interact) { c->animainit_geom = c->geom; } - if (c->isglobal && c->isfloating && c->animation.action == TAG) { + if ((c->isglobal|| c->isunglobal) && c->isfloating && c->animation.action == TAG) { c->animainit_geom = c->geom; } @@ -6493,7 +6493,7 @@ void toggleoverview(const Arg *arg) { wl_list_for_each(c, &clients, link) if (c && c->mon == selmon && !client_is_unmanaged(c) && !client_should_ignore_focus(c) && - !c->isminied) { + !c->isminied && !c->isunglobal) { visible_client_number++; } if (visible_client_number > 0) { @@ -6514,12 +6514,12 @@ void toggleoverview(const Arg *arg) { // overview到正常视图,还原之前退出的浮动和全屏窗口状态 if (selmon->isoverview) { wl_list_for_each(c, &clients, link) { - if (c && !client_is_unmanaged(c) && !client_should_ignore_focus(c)) + if (c && !client_is_unmanaged(c) && !client_should_ignore_focus(c) && !c->isunglobal) overview_backup(c); } } else { wl_list_for_each(c, &clients, link) { - if (c && !c->iskilling && !client_is_unmanaged(c) && + if (c && !c->iskilling && !client_is_unmanaged(c) && !c->isunglobal && !client_should_ignore_focus(c) && client_surface(c)->mapped) overview_restore(c, &(Arg){.ui = target}); }