mirror of
https://codeberg.org/dwl/dwl-patches.git
synced 2025-09-07 11:44:51 +00:00
singletagset-pertag: init
Pertag for singletagset patch. Makes one set of rules for the tags instead of per output.
This commit is contained in:
parent
97c08710a7
commit
4d10ef76d4
22
patches/singletagset-pertag/README.md
Normal file
22
patches/singletagset-pertag/README.md
Normal file
@ -0,0 +1,22 @@
|
||||
### Description
|
||||
Pertag keeps layouts, mfact and nmaster per tag
|
||||
instead of per output.
|
||||
|
||||
This adapted version of pertag contains one version of
|
||||
the rules per all outputs, instead of one per output.
|
||||
This makes switching to tags from other monitors keep
|
||||
the window layout.
|
||||
|
||||
This patch expects [singletagset](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/singletagset) and [sticky](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/sticky)
|
||||
patch to be already in your tree committed. It applies onto it.
|
||||
|
||||
This patch is incompatible with [pertag](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/pertag).
|
||||
|
||||
### Download
|
||||
- [2024-07-26](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/singletagset-pertag/singletagset-pertag.patch)
|
||||
- [git branch](https://codeberg.org/Rutherther/dwl/src/branch/v0.7/singletagset-pertag)
|
||||
|
||||
### Authors
|
||||
- [Rutherther](https://codeberg.org/Rutherther)
|
||||
- [wochap (maintainer of pertag patch)](https://codeberg.org/wochap)
|
||||
- [Guido Cella (creator of pertag patch)](https://codeberg.org/guidocella)
|
261
patches/singletagset-pertag/singletagset-pertag.patch
Normal file
261
patches/singletagset-pertag/singletagset-pertag.patch
Normal file
@ -0,0 +1,261 @@
|
||||
From 4f6bdd3ea1fcc83abd962e9a2dc7737519164a6b Mon Sep 17 00:00:00 2001
|
||||
From: Rutherther <rutherther@proton.me>
|
||||
Date: Fri, 19 Jul 2024 16:25:46 +0200
|
||||
Subject: [PATCH] singletagset-pertag
|
||||
|
||||
---
|
||||
config.def.h | 12 +++++--
|
||||
dwl.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++------
|
||||
2 files changed, 90 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/config.def.h b/config.def.h
|
||||
index 22d2171..7feb04d 100644
|
||||
--- a/config.def.h
|
||||
+++ b/config.def.h
|
||||
@@ -43,12 +43,18 @@ static const Layout layouts[] = {
|
||||
*/
|
||||
/* NOTE: ALWAYS add a fallback rule, even if you are completely sure it won't be used */
|
||||
static const MonitorRule monrules[] = {
|
||||
- /* name mfact nmaster scale layout rotate/reflect x y */
|
||||
+ /* name scale rotate/reflect x y */
|
||||
/* example of a HiDPI laptop monitor:
|
||||
- { "eDP-1", 0.5f, 1, 2, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 },
|
||||
+ { "eDP-1", 2, WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 },
|
||||
*/
|
||||
/* defaults */
|
||||
- { NULL, 0.55f, 1, 1, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 },
|
||||
+ { NULL, 1, WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 },
|
||||
+};
|
||||
+
|
||||
+static const TagRule tagrules[] = {
|
||||
+ /* tag mfact nmaster layout */
|
||||
+ /* defaults */
|
||||
+ { 0, 0.55, 1, &layouts[0] }
|
||||
};
|
||||
|
||||
/* keyboard */
|
||||
diff --git a/dwl.c b/dwl.c
|
||||
index 40a6e48..465d9dd 100644
|
||||
--- a/dwl.c
|
||||
+++ b/dwl.c
|
||||
@@ -104,6 +104,7 @@ typedef struct {
|
||||
const Arg arg;
|
||||
} Button;
|
||||
|
||||
+typedef struct Pertag Pertag;
|
||||
typedef struct Monitor Monitor;
|
||||
typedef struct {
|
||||
/* Must keep these three elements in this order */
|
||||
@@ -209,6 +210,7 @@ struct Monitor {
|
||||
int nmaster;
|
||||
char ltsymbol[16];
|
||||
int asleep;
|
||||
+ unsigned int pertag[2]; /* the tag used for layout via pertag */
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
@@ -226,6 +228,13 @@ typedef struct {
|
||||
struct wl_listener destroy;
|
||||
} PointerConstraint;
|
||||
|
||||
+typedef struct {
|
||||
+ unsigned int tag;
|
||||
+ float mfact;
|
||||
+ int nmaster;
|
||||
+ const Layout *lt;
|
||||
+} TagRule;
|
||||
+
|
||||
typedef struct {
|
||||
const char *id;
|
||||
const char *title;
|
||||
@@ -245,6 +254,7 @@ typedef struct {
|
||||
|
||||
/* function declarations */
|
||||
static void applybounds(Client *c, struct wlr_box *bbox);
|
||||
+static void applypertag(Monitor *m);
|
||||
static void applyrules(Client *c);
|
||||
static void arrange(Monitor *m);
|
||||
static void arrangelayer(Monitor *m, struct wl_list *list,
|
||||
@@ -293,6 +303,7 @@ static void focusstack(const Arg *arg);
|
||||
static Client *focustop(Monitor *m);
|
||||
static void fullscreennotify(struct wl_listener *listener, void *data);
|
||||
static void gpureset(struct wl_listener *listener, void *data);
|
||||
+static unsigned int getpertagtag(unsigned int curtagset);
|
||||
static size_t getunusedtag(void);
|
||||
static void handlesig(int signo);
|
||||
static void incnmaster(const Arg *arg);
|
||||
@@ -415,6 +426,7 @@ static struct wlr_output_layout *output_layout;
|
||||
static struct wlr_box sgeom;
|
||||
static struct wl_list mons;
|
||||
static Monitor *selmon;
|
||||
+static Pertag pertag;
|
||||
|
||||
#ifdef XWAYLAND
|
||||
static void activatex11(struct wl_listener *listener, void *data);
|
||||
@@ -435,6 +447,13 @@ static xcb_atom_t netatom[NetLast];
|
||||
/* attempt to encapsulate suck into one file */
|
||||
#include "client.h"
|
||||
|
||||
+struct Pertag {
|
||||
+ int nmasters[TAGCOUNT + 1]; /* number of windows in master area */
|
||||
+ float mfacts[TAGCOUNT + 1]; /* mfacts per tag */
|
||||
+ unsigned int sellts[TAGCOUNT + 1]; /* selected layouts */
|
||||
+ const Layout *ltidxs[TAGCOUNT + 1][2]; /* matrix of tags and layouts indexes */
|
||||
+};
|
||||
+
|
||||
/* function implementations */
|
||||
void
|
||||
applybounds(Client *c, struct wlr_box *bbox)
|
||||
@@ -1023,6 +1042,33 @@ createlocksurface(struct wl_listener *listener, void *data)
|
||||
client_notify_enter(lock_surface->surface, wlr_seat_get_keyboard(seat));
|
||||
}
|
||||
|
||||
+unsigned int
|
||||
+getpertagtag(unsigned int curtagset)
|
||||
+{
|
||||
+ size_t i;
|
||||
+
|
||||
+ if (curtagset == TAGMASK) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if ((curtagset & TAGMASK) == 0) {
|
||||
+ return 0; // What to do in this case?
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; !(curtagset & 1 << i); i++) ;
|
||||
+ return i + 1;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+applypertag(Monitor *m)
|
||||
+{
|
||||
+ m->nmaster = pertag.nmasters[m->pertag[m->seltags]];
|
||||
+ m->mfact = pertag.mfacts[m->pertag[m->seltags]];
|
||||
+ m->sellt = pertag.sellts[m->pertag[m->seltags]];
|
||||
+ m->lt[m->sellt] = pertag.ltidxs[m->pertag[m->seltags]][m->sellt];
|
||||
+ m->lt[m->sellt^1] = pertag.ltidxs[m->pertag[m->seltags]][m->sellt^1];
|
||||
+}
|
||||
+
|
||||
void
|
||||
createmon(struct wl_listener *listener, void *data)
|
||||
{
|
||||
@@ -1046,14 +1092,12 @@ createmon(struct wl_listener *listener, void *data)
|
||||
wlr_output_state_init(&state);
|
||||
/* Initialize monitor state using configured rules */
|
||||
m->tagset[0] = m->tagset[1] = (1<<getunusedtag()) & TAGMASK;
|
||||
+ m->pertag[0] = m->pertag[1] = getpertagtag(m->tagset[0]);
|
||||
+ applypertag(m);
|
||||
for (r = monrules; r < END(monrules); r++) {
|
||||
if (!r->name || strstr(wlr_output->name, r->name)) {
|
||||
m->m.x = r->x;
|
||||
m->m.y = r->y;
|
||||
- m->mfact = r->mfact;
|
||||
- m->nmaster = r->nmaster;
|
||||
- m->lt[0] = r->lt;
|
||||
- m->lt[1] = &layouts[LENGTH(layouts) > 1 && r->lt != &layouts[1]];
|
||||
strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, LENGTH(m->ltsymbol));
|
||||
wlr_output_state_set_scale(&state, r->scale);
|
||||
wlr_output_state_set_transform(&state, r->rr);
|
||||
@@ -1597,7 +1641,7 @@ incnmaster(const Arg *arg)
|
||||
{
|
||||
if (!arg || !selmon)
|
||||
return;
|
||||
- selmon->nmaster = MAX(selmon->nmaster + arg->i, 0);
|
||||
+ selmon->nmaster = pertag.nmasters[selmon->pertag[selmon->seltags]] = MAX(selmon->nmaster + arg->i, 0);
|
||||
arrange(selmon);
|
||||
}
|
||||
|
||||
@@ -2433,9 +2477,9 @@ setlayout(const Arg *arg)
|
||||
if (!selmon)
|
||||
return;
|
||||
if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt])
|
||||
- selmon->sellt ^= 1;
|
||||
+ selmon->sellt = pertag.sellts[selmon->pertag[selmon->seltags]] ^= 1;
|
||||
if (arg && arg->v)
|
||||
- selmon->lt[selmon->sellt] = (Layout *)arg->v;
|
||||
+ selmon->lt[selmon->sellt] = pertag.ltidxs[selmon->pertag[selmon->seltags]][selmon->sellt] = (Layout *)arg->v;
|
||||
strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, LENGTH(selmon->ltsymbol));
|
||||
arrange(selmon);
|
||||
printstatus();
|
||||
@@ -2452,7 +2496,7 @@ setmfact(const Arg *arg)
|
||||
f = arg->f < 1.0f ? arg->f + selmon->mfact : arg->f - 1.0f;
|
||||
if (f < 0.1 || f > 0.9)
|
||||
return;
|
||||
- selmon->mfact = f;
|
||||
+ selmon->mfact = pertag.mfacts[selmon->pertag[selmon->seltags]] = f;
|
||||
arrange(selmon);
|
||||
}
|
||||
|
||||
@@ -2504,6 +2548,10 @@ setsel(struct wl_listener *listener, void *data)
|
||||
void
|
||||
setup(void)
|
||||
{
|
||||
+ const TagRule *r;
|
||||
+ struct xkb_context *context;
|
||||
+ struct xkb_keymap *keymap;
|
||||
+
|
||||
int i, sig[] = {SIGCHLD, SIGINT, SIGTERM, SIGPIPE};
|
||||
struct sigaction sa = {.sa_flags = SA_RESTART, .sa_handler = handlesig};
|
||||
sigemptyset(&sa.sa_mask);
|
||||
@@ -2596,6 +2644,19 @@ setup(void)
|
||||
LISTEN_STATIC(&output_layout->events.change, updatemons);
|
||||
wlr_xdg_output_manager_v1_create(dpy, output_layout);
|
||||
|
||||
+ for (i = 0; i <= TAGCOUNT; i++) {
|
||||
+ for (r = tagrules; r < END(tagrules); r++) {
|
||||
+ if (!r->tag || r->tag == i) {
|
||||
+ pertag.mfacts[i] = r->mfact;
|
||||
+ pertag.nmasters[i] = r->nmaster;
|
||||
+ pertag.sellts[i] = 0;
|
||||
+ pertag.ltidxs[i][0] = r->lt;
|
||||
+ pertag.ltidxs[i][1] = r->lt;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/* Configure a listener to be notified when new outputs are available on the
|
||||
* backend. */
|
||||
wl_list_init(&mons);
|
||||
@@ -2857,6 +2918,12 @@ toggleview(const Arg *arg)
|
||||
if (m !=selmon && newtagset & m->tagset[m->seltags])
|
||||
return;
|
||||
|
||||
+ // set new pertag tag only if the tag we were at was removed, or if all tags are shown.
|
||||
+ if (!(newtagset & 1 << (selmon->pertag[selmon->seltags] - 1)) || newtagset == TAGMASK) {
|
||||
+ selmon->pertag[selmon->seltags] = getpertagtag(newtagset);
|
||||
+ }
|
||||
+
|
||||
+ applypertag(selmon);
|
||||
selmon->tagset[selmon->seltags] = newtagset;
|
||||
attachclients(selmon);
|
||||
focusclient(focustop(selmon), 1);
|
||||
@@ -3072,6 +3139,8 @@ view(const Arg *arg)
|
||||
}
|
||||
m->seltags ^= 1;
|
||||
m->tagset[m->seltags] = origm->tagset[origm->seltags];
|
||||
+ m->pertag[m->seltags] = origm->pertag[origm->seltags];
|
||||
+ applypertag(m);
|
||||
attachclients(m);
|
||||
/* Beware: this changes selmon */
|
||||
focusclient(focustop(m), 1);
|
||||
@@ -3081,11 +3150,14 @@ view(const Arg *arg)
|
||||
}
|
||||
|
||||
origm->seltags ^= 1; /* toggle sel tagset */
|
||||
- if (arg->ui & TAGMASK)
|
||||
+ if (arg->ui & TAGMASK) {
|
||||
origm->tagset[origm->seltags] = arg->ui & TAGMASK;
|
||||
+ origm->pertag[origm->seltags] = getpertagtag(arg->ui & TAGMASK);
|
||||
+ }
|
||||
|
||||
/* Change selmon back to orig mon */
|
||||
selmon = origm;
|
||||
+ applypertag(origm);
|
||||
attachclients(origm);
|
||||
focusclient(focustop(origm), 1);
|
||||
arrange(origm);
|
||||
--
|
||||
2.45.2
|
||||
|
Loading…
x
Reference in New Issue
Block a user