Created on Fri. 05 November 2021
What's up I'm back with more dwm stuff! I wanted to work on something different today. So I wanted to finally implement a little tray to my config!
I basically looking for a mac OS style system tray like so:
I really had no other idea of what to add and I thought it would be a cool addition. So with some research I discovered tint2. This thing is great you can basically create the panel you want from it. By default it's really ugly but you can push it far like so:
I tried a lot of approaches but to cut through all of my research (I spent 5hours on this) I found a trick where I can just run it and have dwm ignore it. Basically that's what my patch does. You give it the class of a window and it will just ignore it. So the window will be on every tag and not show up in the task bar as if it was part of the window manager.
To get this effect I had to reverse engineer DWM a bit more looking to other patches and how dwm handles windows. My first target was finding how to hide the border that dwm gives to windows basically when a window is created it will set the border width:
Basically this screenshot is from the edited code but before my edit those 4 lines consisted of the single following line:
c->bw = borderpx;
So I just added a check to see if the window class name was the value provided in panel_str and if it is set the border width to 0. Now that the border width is ignored let's make tint2 stick on every page!
To do that I basically trick dwm in never hiding the program when I switch tag:
Basically this function is recursive so for every window it will either show or hide it from the currently selected tag (basically tags are desktops). So in red is the code I added where if the class name of the window is panel_str it will just never hide it!
Here is the end result with tint2's default theme. This patch could be used for any other kind of program! Now on my config I use a custom version and this is how it looks:
Mine is basically a fancy search system and a way to view what programs are opened and navigate to them graphically. I also have a little system tray for things like bluetooth and my screenshot tool :)
Two days ago I published this post that you are reading and I had a few bugs so if you came back to see the bug fix. Here it is! So the tag manager at the top left would display an active tab all of the time because tint2 was running so I decided to edit it so that it never counted tint2 as a currently running app:
This slice of code is hard to understand even I was confused originally but basically we use an int where each bit represent if there is an application opened on a tag:
WHILE open_windows: IS open_windows.current_tag = current_tag: SET occ TAG BIT TO 1
This is very theoretical but imagine it like you have the first bit of (0 0 0 0) representing the first tag. If you have a window inside of the first tag well the occ variable would look like this (1 0 0 0). I also had a bug that allowed you to close tint2 with the close shortcut I repaired that but blocking the close functionality if the program matches the supplied value!
Now currently I have a bug that is a bit hard to fix. I have to be able to skip tint2 in the selection of the window when using the XK_j and XK_k shortcuts. I managed to make it work going up the stack but not going down it. So I will have to fix that one day :D
Thank you for reading this! The patch will be on my github and is available on the widget through the link ;)