Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Idea for a patch: loop 3 or more tags #327

Open
spavlovich001 opened this issue Jan 14, 2023 · 19 comments
Open

Idea for a patch: loop 3 or more tags #327

spavlovich001 opened this issue Jan 14, 2023 · 19 comments

Comments

@spavlovich001
Copy link

Idea for a patch: Case: there is an editor, a browser, a console. mod+tab can loop only two tags. Would like 3 or more. So that you can bind to one combination the looping of two tags, and to some other - the looping of three or more tags

@spavlovich001 spavlovich001 changed the title Idea for a patch.Loop 3 or more tags Idea for a patch: loop 3 or more tags Jan 14, 2023
@fov95
Copy link

fov95 commented Jan 14, 2023

Have you considered using the IPC patch for that?

@spavlovich001
Copy link
Author

Have you considered using the IPC patch for that?

IPC can implement static tag navigation. Or I'm wrong? How can it remember the last 2 or more visited tags?

@fov95
Copy link

fov95 commented Jan 14, 2023

It was just an idea.. I use IPC extensively for simple tasks, using temp files on tmpfs and a mix of dwm IPC and dwm config..
If you switch tags you can write to a file, have only the last 3 saved and read from it directly or even create a simple menu with the tags you want fixed..

@bakkeby
Copy link
Owner

bakkeby commented Jan 14, 2023

MOD+Tab does only one thing; it changes the view back to the previous view.

The proposal / idea here is to have a longer history of tag changes, and that MOD+Tab brings you further and further back in the history.

Personally I think this idea is not that great as it can get very confusing and unintuitive from a user / usability perspective as it can get hard to predict what happens next (who remembers what tag they were on six tag changes ago?).

Additionally one might expect to go forwards in this list as well. You also end up with questions like if you step 6 times back in the history and then you open a new tag, what happens with all future history items?

A better approach, in my opinion, is to remove the existing MOD+Tab keybinding for view(0) and instead set up new bindings for focusadjacenttag (viewtoleft, viewtoright), shiftview or shiftviewclients depending on preferred behaviour. The idea is that hitting MOD+Tab brings you to the tag on the right of the current tag while MOD+Shift+Tab brings you to the left. If using shiftviewclients it would bring you to the nearest tag that has clients. I find this to be an overall better use of the Tab keybinding. The view(0) to simply go to the previous tag can of course be bound to something else if that is still useful at times.

In terms of workflow I also like the toggletag patch which brings you to the previous view if you hit the same view binding twice (e.g. MOD+5 then MOD+5 will bring you back to the tag(s) you were on before you hit MOD+5 in the first place). This allows you to quickly view tags and refer back.

@spavlovich001
Copy link
Author

MOD+Tab does only one thing; it changes the view back to the previous view.

The proposal / idea here is to have a longer history of tag changes, and that MOD+Tab brings you further and further back in the history.

Personally I think this idea is not that great as it can get very confusing and unintuitive from a user / usability perspective as it can get hard to predict what happens next (who remembers what tag they were on six tag changes ago?).

Additionally one might expect to go forwards in this list as well. You also end up with questions like if you step 6 times back in the history and then you open a new tag, what happens with all future history items?

A better approach, in my opinion, is to remove the existing MOD+Tab keybinding for view(0) and instead set up new bindings for focusadjacenttag (viewtoleft, viewtoright), shiftview or shiftviewclients depending on preferred behaviour. The idea is that hitting MOD+Tab brings you to the tag on the right of the current tag while MOD+Shift+Tab brings you to the left. If using shiftviewclients it would bring you to the nearest tag that has clients. I find this to be an overall better use of the Tab keybinding. The view(0) to simply go to the previous tag can of course be bound to something else if that is still useful at times.

In terms of workflow I also like the toggletag patch which brings you to the previous view if you hit the same view binding twice (e.g. MOD+5 then MOD+5 will bring you back to the tag(s) you were on before you hit MOD+5 in the first place). This allows you to quickly view tags and refer back.

Once again, there is a browser tag (9), a docker project management tag (2), and a dual editor tag (5). How can I quickly navigate through these three tags? No way. I stand on the 2nd tag, clicked the 9th tag - immediately the looping disappeared between the 2nd and 5th tags

Algorithmically, everything is very simple. Any pressed tag (mod+1...9) pops the most recent tag in the history stack from the history stack. That is, there is a history for the last three tags. If there are tags 2, 5, 9 in the history and I pressed 8, then the 9 tag is forced out, i.e.

2, 5, 9 press 8 --> 5, 9, 8

@bakkeby
Copy link
Owner

bakkeby commented Jan 17, 2023

How can I quickly navigate through these three tags?

You can quickly navigate to tag 2 using MOD+2, you can quickly navigate to tag 5 using MOD+5, you can quickly navigate to tag 8 using MOD+8. It is really not that complicated.

If you need to be able to use a single keybinding to go through these then you should look at the shiftviewclients patch instead.

@spavlovich001
Copy link
Author

You can quickly navigate to tag 2 using MOD+2, you can quickly navigate to tag 5 using MOD+5, you can quickly navigate to tag 8 using MOD+8. It is really not that complicated.

  1. And if it needs to be done 200 times a day?
  2. Why worry about which tag to click when you can just click mod+tab once or twice?

If you need to be able to use a single keybinding to go through these then you should look at the shiftviewclients patch >instead.

I have been using shiftview for a long time. This functionality is not for quickly switching between far tags. And for quick switching between three neighboring tags :)

// shiftview.c
{ MODKEY,                       XK_bracketleft,  shiftview, {-1} },
{ MODKEY,                       XK_bracketright, shiftview, {1} },
{ MODKEY,                       XK_Left,  shiftview, {-1} },
{ MODKEY,                       XK_Right, shiftview, {1} },

@bakkeby
Copy link
Owner

bakkeby commented Jan 17, 2023

If your ideal workflow is such that you need to change tags 200 times in a day, then hitting MOD+number 200 times beats hitting MOD+Tab 400 times (considering that about half the time you'd end up at the wrong tag).

The shiftview patch will shift through each individual tag yes. The shiftviewclients patch on the other hand would only shift through tags 2, 5 and 8 in this example as it only shifts between tags that are occupied by clients. More so you can control the direction in which the shift takes place giving you more control. As mentioned earlier you could bind this to MOD+Tab and MOD+Shift+Tab if you wanted to.

@spavlovich001
Copy link
Author

spavlovich001 commented Jan 17, 2023

If your ideal workflow is such that you need to change tags 200 times in a day, then hitting MOD+number 200 times beats hitting MOD+Tab 400 times (considering that about half the time you'd end up at the wrong tag).

The shiftview patch will shift through each individual tag yes. The shiftviewclients patch on the other hand would only shift through tags 2, 5 and 8 in this example as it only shifts between tags that are occupied by clients. More so you can control the direction in which the shift takes place giving you more control. As mentioned earlier you could bind this to MOD+Tab and MOD+Shift+Tab if you wanted to.

Okay, let's go from simple to complex: you need to quickly switch between two tags. What will you choose: manually switch the necessary tags or mod+tab? In the manual version, I need to remember which tag was the last one, but with mod + tab, I just clicked and that's it

The same story with three or more looped tags. I switched to tags 1, 3, 9 and mod+tab through them. It's easier for me to press mod+tab twice than to manually press tags.

shiftview: how many times do you need to click left\right to bypass 1,3 9 tag and return to 3 tag? :)

@bakkeby
Copy link
Owner

bakkeby commented Jan 17, 2023

shiftview: how many times do you need to click left\right to bypass 1,3 9 tag and return to 3 tag? :)

If you had actually taken the time to read what I wrote then you might have picked up on that the shiftviewclients patch does exactly what you want. It is not the same as the shiftview patch.

dwm-flexipatch/patches.def.h

Lines 1058 to 1061 in 6b7246c

/* This variant of the shiftview patch adds left and right circular shift through tags,
* but skips tags where there are no clients.
*/
#define SHIFTVIEW_CLIENTS_PATCH 0

dwm-flexipatch/config.def.h

Lines 1032 to 1035 in 6b7246c

#if SHIFTVIEW_CLIENTS_PATCH
{ MODKEY|Mod4Mask, XK_Tab, shiftviewclients, { .i = -1 } },
{ MODKEY|Mod4Mask, XK_backslash, shiftviewclients, { .i = +1 } },
#endif // SHIFTVIEW_CLIENTS_PATCH

So let's say that you were to set up two keybindings like:

	{ MODKEY|ShiftMask,             XK_Tab,         shiftviewclients,       { .i = -1 } },
	{ MODKEY,                       XK_Tab,         shiftviewclients,       { .i = +1 } },

Now you have the following scenarios:

  • to go from tag 1 to tag 3 - 1 keypress MOD+Tab
  • to go from tag 3 to tag 9 - 1 keypress MOD+Tab
  • to go from tag 1 to tag 9 - 1 keypress MOD+Shift+Tab (or 2x MOD+Tab)
  • to go from tag 9 to tag 1 - 1 keypress MOD+Tab
  • to go from tag 9 to tag 3 - 1 keypress MOD+Shift+Tab (or 2x MOD+Tab)
  • to go from tag 3 to tag 1 - 1 keypress MOD+Shift+Tab (or 2x MOD+Tab)

@spavlovich001
Copy link
Author

spavlovich001 commented Jan 17, 2023

If you had actually taken the time to read what I wrote then you might have picked up on that the shiftviewclients patch does exactly what you want. It is not the same as the shiftview patch.

I read your post about shiftviewclients. Keyword: skips tags where there are no clients. I have all tags with clients. So it doesn't fit. Usually I have this (pay attention to the tags) http://0x0.st/ohP2.png

@bakkeby
Copy link
Owner

bakkeby commented Jan 18, 2023

I have all tags with clients. So it doesn't fit.

In that case it just means that you have misrepresented your problem statement from the very start.

The idea of having a history of the last three tags makes even less sense if you have clients on all tags. My reason for saying so is that if the primary workflow is to use MOD+Tab to switch between the browser tag (9), the docker project management tag (2) and the dual editor tag (5) then at some point you'll find the need to visit any of the other tags that have clients at which point that will break the primary workflow of moving between the three tags of 9, 2 and 5.

So to get it "working" again you'll have to manually prime it by going to tag 9, tag 2 and tag 5 at which point you are back in the game of using MOD+Tab to navigate between the three tags. This is an example of working for the tool.

But I get that you are convinced that this is the right solution for your particular workflow and perhaps it really is. I don't think it would be worth it for me to add something like this to dwm-flexipatch though unless it is something a lot of people would be asking for.

If you want to play around then achieving a rudimentary behaviour like this is not particularly complicated. Here is an example solution:

diff --git a/dwm.c b/dwm.c
index 9fe65b9..e967f6b 100644
--- a/dwm.c
+++ b/dwm.c
@@ -487,7 +487,7 @@ struct Monitor {
        #endif // SETBORDERPX_PATCH
        unsigned int seltags;
        unsigned int sellt;
-       unsigned int tagset[2];
+       unsigned int tagset[3];
        int showbar;
        #if TAB_PATCH
        int showtab;
@@ -4909,7 +4909,9 @@ view(const Arg *arg)
        #if BAR_TAGPREVIEW_PATCH
        tagpreviewswitchtag();
        #endif // BAR_TAGPREVIEW_PATCH
-       selmon->seltags ^= 1; /* toggle sel tagset */
+       selmon->seltags += 1;
+       if (selmon->seltags == LENGTH(selmon->tagset))
+               selmon->seltags = 0;
        #if PERTAG_PATCH
        pertagview(arg);
        #else

So if you are on tag 1 and you go to tag 2, 3 and 4 and you start pressing MOD+Tab then it will start over at tag 2, then 3, then 4.

If you wanted this in reverse then that is slightly more complicated as you would need seltags to increment when changing tags and decrement it when passing in 0. There will be associated bugs like if you start pressing MOD+Tab before you have changed tags then you will end up with no tags being selected (would have to be addressed in the createmon function).

If you happen to use the pertag patch then you would have to refactor that code as well as uses two variables curtag and prevtag to hold the current and previous pertag indexes. This would likely be the biggest hurdle to sort out.

@spavlovich001
Copy link
Author

spavlovich001 commented Jan 18, 2023

In general, it is a very common task to be able to quickly switch between several tags (more than two). It’s just that no one talks about it, but if you vote whether such functionality is needed or not, then I think that the answer from many people will be more positive than negative. Because in the workflow (especially on a single-monitor configuration), this question appears very often. The question of adding this functionality and the appearance of related problems associated with it is a question of the dwm architecture. That is, if the addition of some functionality affects many patches, this indicates that the architecture is bad

According to the movement history algorithm - everything is correct

I click tags 2, 5, 9(history stack is 259)
mod+tab == 2
mod+tab == 5
mod + tab == 9

Now I in tag 9. I manually set tag 7. History stack now is: 7,9,5. That is, in fact, this is a regular stack with overwriting the first elements with a new element

@bakkeby
Copy link
Owner

bakkeby commented Jan 18, 2023

That is, if the addition of some functionality affects many patches, this indicates that the architecture is bad

Sounds like you do not know dwm very well. Of course the architecture is going to be bad - dwm is not designed to be patched and every individual patch make up their own rules.

@spavlovich001
Copy link
Author

Sounds like you do not know dwm very well. Of course the architecture is going to be bad - dwm is not designed to be patched and every individual patch make up their own rules.

Yes, as you can see, expanding the functionality with patches imposes its own difficulties when expanding the functionality. If dwm were implemented as a library written in the OOP style, then all this would not cause such difficulties.

@bakkeby
Copy link
Owner

bakkeby commented Jan 18, 2023

If dwm were implemented as a library written in the OOP style, then all this would not cause such difficulties.

That is of course a big assumption - anything written as a library will generally be locked down to whatever API said library exposes. It may not necessarily be that easy to extend logic that the library is hardcoded to offer.

I believe penrose is such a library written in Rust with skyWM being an example implementation using said library.

@speedie1337
Copy link
Contributor

I mean when you want that level of customization you're probably better off learning how the window manager works so you can extend it in the way you want. (Or I suppose writing something from scratch)

That said I think this library idea would be more useful for Wayland because it seems to be very complex in comparison to X11.

@N-R-K
Copy link

N-R-K commented Jan 20, 2023

but if you vote whether such functionality is needed or not, then I think that the answer from many people will be more positive than negative

You can make that 2-1, because I agree with @bakkeby that such functionality is just confusing because no-one remembers what taglayout they had 4~9 changes ago. And you'd be much better off just making your tag-keys more accessible instead of spamming mod+tab 2~3 times.

For example: my tag (I use only 5 tags) keys are just mod+{h,j,k,l,;} to add that tag into the view - easily available right under my fingertips. And this can be extended to more than 5 tags by throwing in another modifer key into the mix.

Here's the config.h for reference:

#define TAGKEYS(KEY,TAG) \
	{ MODKEY|ShiftMask,             KEY,      tag,            {.ui = 1 << TAG} }, \
	{ MODKEY|AltMask,               KEY,      toggleview,     {.ui = 1 << TAG} }, \
	{ MODKEY|ControlMask,           KEY,      toggletag,      {.ui = 1 << TAG} },
	

	/* tag related stuff */
	TAGKEYS(                        XK_h,                      0)
	TAGKEYS(                        XK_j,                      1)
	TAGKEYS(                        XK_k,                      2)
	TAGKEYS(                        XK_l,                      3)
	TAGKEYS(                    XK_semicolon,                  4)
	{ MODKEY,                       XK_Tab,    view,           {0} },
	{ MODKEY,                       XK_1,      view,           {.ui = 1 << 0 } },
	{ MODKEY,                       XK_2,      view,           {.ui = 1 << 1 } },
	{ MODKEY,                       XK_3,      view,           {.ui = 1 << 2 } },
	{ MODKEY,                       XK_4,      view,           {.ui = 1 << 3 } },
	{ MODKEY,                       XK_5,      view,           {.ui = 1 << 4 } },
	{ MODKEY,                       XK_0,      view,           {.ui = ~0 } },
	{ MODKEY|ShiftMask,             XK_0,      tag,            {.ui = ~0 } },
	{ MODKEY,                       XK_j,      shiftview,      {.i = +1 } },
	{ MODKEY,                       XK_k,      shiftview,      {.i = -1 } },

At the end, it's always going to be more efficient in the long-run to configure the keybindings to be better and then getting used to them so you can accomplish what you want in 1 key-combo, instead of having to spam mod+tab however many times to get back to however many changes ago.

UtkarshVerma pushed a commit to UtkarshVerma/dwm that referenced this issue Feb 19, 2023
@spavlovich001
Copy link
Author

Hello, I got around to testing the patch. Not even half a year has passed :)
Everything is great, but there is a small bug, namely:
I press:

mod+3
mod+6
mod+8

Next I click

mod+tab
mod+tab
mod+tab

Everything is fine

But when I press mod+6 (standing on tag 8) and press

mod+tab
mod+tab
mod+tab

I'm stuck on tags
3, 6, 6. It seems to me that this is a little wrong. If the tag is in the list (tag 6) and I manually pressed mod+6, then tag8 should not disappear from the history stack, do you think?

@spavlovich001 spavlovich001 reopened this Oct 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants