arieboven / dwm

My custom dwm build
MIT License
2 stars 1 forks source link

How to automatically reset to default layout for a tag once it is empty? #1

Open ysl2 opened 11 months ago

ysl2 commented 11 months ago

Hi Arie,

I have searched on internet and find this post: https://www.reddit.com/r/suckless/comments/s2ch3f/dwm_how_to_reset_to_tiled_layout_when_all_windows/

diff --git a/dwm.c b/dwm.c
index a96f33c..787cd2a 100644
--- a/dwm.c
+++ b/dwm.c
@@ -189,6 +189,7 @@ static void pop(Client *);
 static void propertynotify(XEvent *e);
 static void quit(const Arg *arg);
 static Monitor *recttomon(int x, int y, int w, int h);
+static void resetlayout(const Arg *arg);
 static void resize(Client *c, int x, int y, int w, int h, int interact);
 static void resizeclient(Client *c, int x, int y, int w, int h);
 static void resizemouse(const Arg *arg);
@@ -1269,6 +1270,16 @@ recttomon(int x, int y, int w, int h)
    return r;
 }

+void
+resetlayout(const Arg *arg)
+{
+   Arg default_layout = {.v = &layouts[0]};
+   Arg default_mfact = {.f = mfact + 1};
+
+   setlayout(&default_layout);
+   setmfact(&default_mfact);
+}
+
 void
 resize(Client *c, int x, int y, int w, int h, int interact)
 {
@@ -1788,6 +1799,8 @@ unmanage(Client *c, int destroyed)
    focus(NULL);
    updateclientlist();
    arrange(m);
+   if (!(nexttiled(m->clients)))
+       resetlayout(NULL);
 }

 void

Thanks for your instruction! But I think it seems not a good way. Beacuse It will check all clients in a monitor instead of a specific tag. And this might be dangerous, beacuse we have focus(NULL); updateclientlist(); arrange(m); in the above of resetlayout(), the current focus tag might be already changed. Then it calls resetlayout(), the setlayout() subfunction (in resetlayout()) calls arrange() if the selmon->sel is not empty. So it might cause potential duplicate arrange() call.

So I wonder if there has a safe way to achieve the goal? Thanks ! :-)

arieboven commented 10 months ago

Thank you for your Issue regarding the function resetlayout.

I have had a closer look and found out that this implementation I made is not correct, I did not encounter any problems with it yet. The resetlayout function affects the active monitor. The Client which is unmanaged does not need to be on the active monitor. So, this means that when the last Client of a tag is unmanaged on a different monitor the resetlayout function will be called on the active monitor which is not meant to happen.

The nexttiled(m->clients) does look for a next Client that is visible (exuding floating Clients). So, if no Client is visible it will call the resetlayout function. This does indeed need to change to Clients on a specific tag if the pertag patch is in use.

The resetlayout function calls setmfact. This function calls arrange(), there you have already a duplicate.

I have unfortunate not yet a solution to this issue. My first thought is to make a separate function which resets the layout, and the mfact on the correct monitor. With the pertag patch also the correct tag. I will look for a solution, If you also have a suggestion please let me know.