feat: support winrule option isunglobal

unglobal no manage by layout and no get focus by keyboard
This commit is contained in:
DreamMaoMao 2025-06-02 22:56:56 +08:00
parent 183f417f33
commit 67e6a6154f
2 changed files with 29 additions and 52 deletions

View file

@ -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);
}

View file

@ -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});
}