~tsdh/swayr#22: 
Multiple Window Switching: switch-to-matching-or-urgent-or-lru-window

(After #21.)

When using switch-to-matching-or-urgent-or-lru-window, it seems that only one window is switched to when the target is multiple windows. Perhaps this is a sway specification, but swayr's switch-to-app-or-urgent-or-lru-window allows switching to each of the multiple windows in turn, as expected. I would appreciate it if the switch-to-matching-or-urgent-or-lru-window window switching target would work this way, how do you feel?

Status
RESOLVED IMPLEMENTED
Submitter
~tkna
Assigned to
No-one
Submitted
2 months ago
Updated
14 days ago
Labels
enhancement swayr

~tsdh 2 months ago

No, switch-to-app-or-urgent-or-lru-window (and the other switch-to-* commands) won't switch through all windows, either. For example, if you have three foot terminals open, then swayr switch-to-app-or-urgent-or-lru-window foot will switch back and forth between two of them never reaching the third and never reaching another non-foot window.

The thing with switch-to-matching-or-urgent-or-lru-window is that here swayr just sends CRITERIA focus to sway and observes if a focus change happens. If it does, that's it. Otherwise it'll focus the first urgent or LRU window. The difference between this command and the other switch-to-*-or-lru-window commands is that the window selection is performed by sway and not swayr. CRITERIA focus seems to always select the same window if the criteria doesn't change whereas in the other commands, swayrs does the search for a matching window itself by iterating the LRU-sorted list of windows. Since that list is constantly re-sorted on focus events, you get different results if more than one window match.

So long story short: I guess the switch-to-*-or-urgent-or-lru-window commands are mostly suited for apps where you have only one single window. And yes, the slight inconsistency between the switch-to-matching-or-urgent-or-lru-window command and the others is unfortunate. Basically, here I had the choice to (1) just feed the criteria to sway or (2) implement the criteria API (including a parser) myself. I chose (1).

I have a TODO in my code saying that it would be great if sway had some command like CRITERIA matches or something which wouldn't do anything but just print/return the list of windows matching the criteria so that IPC clients can re-use sway's CRITERIA evaluation. Unfortunately, I think the sway policy is to not add new features which aren't available in i3 as well.

~tkna 2 months ago

I have tried to see if I can do a dirty hack in bash by using a FIFO or PID file, but I think it would be difficult without a list of PIDs arranged in the order in which I have focused on the window in the past.

There doesn't seem to be any representation of PIDs in i3's criteria. https://i3wm.org/docs/userguide.html#command_criteria

Maybe there is something that can be improved if it is PID related and not related to this issue.

~tsdh 2 months ago

FWIW, I have an idea on how to make the switch-to-* commands visit all matching windows one after the other before going to the urgent/lru window but that requires some larger changes which I don't know I'll find the time to implement.

~tkna 2 months ago*

Thank you for your kindness. I am sorry if I seem to be bothering you. There is no need to be reserved with me. Please don't strain yourself. I trust your development skills and sense of style. This is your castle and your domain. At least when you reply to me, you do not have to explain in detail, you can give me a rough summary, an emotional dictum, or an abstract image in a curt manner, or you can withhold or ignore my response. By all means, make your time a priority.

~tsdh 2 months ago

"~tkna" outgoing@sr.ht writes:

Thank you for your kindness.

You're welcome.

I am sorry if I seem to be bothering you. There is no need to be reserved with me. Please don't strain yourself.

I won't, don't worry. The issue you've observed is real. It's just not present in the original "there's at most one matching window" use-case. But of course that doesn't mean it's not important.

I trust your development skills and sense of style. This is your castle and your domain. At least when you reply to me, you do not have to explain in detail, you can give me a rough summary, an emotional dictum, or an abstract image in a curt manner, or you can withhold or ignore my response. By all means, make your time a priority.

I've responded with details also for myself so that I can quickly recapture the context when I find some time to fix the issue.

Thanks for your kind words, Tassilo

~tsdh referenced this from #24 a month ago

~tsdh a month ago

I've released swayr-0.20.0-beta.0 from the next branch just now. Have a look at that branch's README.md, especially the non-menu switchers section.

Please give it a try and report back.

~tkna a month ago*

Thank you. This may be a naive form, but this is how I am starting my testing.

Building a test environment

$ paru -R swayr-git
$ mkdir ~/.cache/paru/clone/swayr-git_next
$ cp -p ~/.cache/paru/clone/swayr-git/PKGBUILD ~/.cache/paru/clone/swayr-git_next/
$ cd ~/.cache/paru/clone/swayr-git_next
$ $EDITOR PKGBUILD
$ grep "^\(source\|pkgver\)=" PKGBUILD
pkgver=r350.07f45db
source=("${pkgname%-*}::git+https://git.sr.ht/~tsdh/swayr#branch=next")
$ makepkg -is
$ paru -Q swayr-git
swayr-git r350.07f45db-1
$ pgrep swayr
$ which swayr swayrd
/usr/bin/swayr
/usr/bin/swayrd
$ exec env RUST_BACKTRACE=1 RUST_LOG=swayr=debug swayrd 2>&1 | tee -a /tmp/swayrd.log

~/.config/sway/config

include $HOME/.config/sway/config.d/*.conf

~/.config/sway/config.d/test.conf

set $mode_test "Test key[*]?"
mode $mode_test {
    bindsym 0 exec swayr switch-to-urgent-or-lru-window
    bindsym 1 exec swayr switch-to-app-or-urgent-or-lru-window foot
    bindsym 2 exec swayr switch-to-mark-or-urgent-or-lru-window m
    bindsym 3 exec swayr switch-to-matching-or-urgent-or-lru-window app_id=foot
    bindsym 4 exec swayr switch-to-matching-or-urgent-or-lru-window app_id=__focused__
    # back to normal: Escape
    bindsym Escape mode "default"
}
bindsym $mod+t mode $mode_test

At any rate, one thing I noticed is that when executing 1 above, in addition to the target app_id (foot), the LRU window and the first current window are also switch destinations. capture: https://streamable.com/50vdhl

This is correct in the sense of the command's wording, but it seems inconvenient if you want to switch to only multiple FOOTs. In a naive way, I came up with the following method.

  1. Do not transition to the LRU window and the first window if there are more than one windows specified as switch targets
  2. No transition to the LRU window if there are more than one windows specified as switch targets
  3. Specify the targets you want to omit with options like the following
swayr switch-to-app-or-urgent-or-lru-window --ignore first,lru <app_id>

Personally, I think 3. is the way to go, but I am wondering if there is a use case where the LRU window needs to be included in the switch destination if there are more than two windows specified as the switch target. If that seems unlikely, then one might make it a standard behavior. How do you feel about it? I'm sorry if I'm misguided.

~tsdh a month ago

"~tkna" outgoing@sr.ht writes:

Building a test environment

...

I cannot comment on that but it looks alright.

~/.config/sway/config.d/test.conf

    bindsym 1 exec swayr switch-to-app-or-urgent-or-lru-window foot
...
    bindsym 3 exec swayr switch-to-matching-or-urgent-or-lru-window app_id=foot
    bindsym 4 exec swayr switch-to-matching-or-urgent-or-lru-window app_id=__focused> ```

Those latter two have syntax errors, criteria are written as:

  [app_id="foot"]
  [app_id=__focused__]

Note the brackets.

Maybe you also need to do some shell quoting, e.g., '[app_id="foot"]' should be a safe bet.

At any rate, one thing I noticed is that when executing 1 above, in addition to the target app_id (foot), the LRU window and the first current window are also switch destinations. capture: https://streamable.com/50vdhl

This is correct in the sense of the command's wording, but it seems inconvenient if you want to switch to only multiple FOOTs.

Hm, if your desire is to just cycle through all FOOTs, then maybe switch-to-XXX-or-urgent-or-lru-window is not what you want because as you say, they do what name and docs suggest.

In a naive way, I came up with the following method.

  1. Do not transition to the LRU window and the first window if there are more than two windows specified as switch targets
  2. No transition to the LRU window if there are more than two windows specified as switch targets

The "switch targets" except for LRU and original window are not computed in advance because in the course of a sequence, windows might become urgent or new matching windows might appear (or disappear) and we want to catch them, too.

  1. Specify the targets you want to omit with options like the following
swayr switch-to-app-or-urgent-or-lru-window --ignore first,lru <app_id>

That might work. --ignore first would mean not to be able to come back to the original window? Who would want that?

Hm, would flags --skip-urgent and --skip-lru make sense? That should be quite easy to implement.

Bye, Tassilo

~tkna a month ago*

Maybe you also need to do some shell quoting, e.g., '[app_id="foot"]' should be a safe bet.

Thank you👍

That might work. --ignore first would mean not to be able to come back to the original window? Who would want that?

For example, in the following, "switch targets" is clearly foot. My image is that it is the plural of this.

swaymsg '[app_id="foot"]' focus

If most of the windows used are predefined/key-bound as switch destinations, I think it would be helpful in some cases to be able to specify them explicitly. This was not possible with the existing sway functionality, so I imagine it would be useful to be able to do this. There may be cases where it is more convenient to return to the original window after comparing the various behaviors, but having the option to specify it would give us peace of mind that we can respond to unexpected use cases.

Hm, would flags --skip-urgent and --skip-lru make sense? That should be quite easy to implement.

Thank you🤤

On a slightly unrelated note, and maybe you've already planned this, but I was thinking that it might be easier to develop if the switch-type options were something like an alias for switch-to-matching-or-urgent-or-lru-window. Sorry if I am off the mark with my naive imagination not knowing the situation.

~tsdh a month ago

Hm, would flags --skip-urgent and --skip-lru make sense? That should be quite easy to implement.

Thank you🤤

Please pull and built anew. All switch-to-x commands now have --skip-urgent, --skip-lru, and --skip-origin.

On a slightly unrelated note, and maybe you've already planned this, but I was thinking that it might be easier to develop if the switch-type options were something like an alias for switch-to-matching-or-urgent-or-lru-window.

Yes, I've thought about this but decided to keep the app/mark commands separate because there's actually a difference: those two compare the given string with the windows' app_id/window class/marks for equality whereas all string values in the criteria queries are considered to be regular expressions. Of course, the switch-to-matching-or-urgent-or-lru-window could have a flag telling if the strings in criteria are to be interpreted as plain strings or regexes but I would like to keep it simple.

And actually all the logic is in one central function which is called by all switch-to variants and receives (next to other args) a closure predicate deciding if a window matches or not. The predicates for the app/mark case are very easy oneliners whereas criteria are a bit more elaborate: the string is parsed to a data structure which is then interpreted by a more complicated predicate. So in the end, I wouldn't really save more than one or two lines of code.

Bye, Tassilo

~tkna a month ago*

Thanks. I did the following. b-g appears to be the problem. Sorry if I am wrong about something.

$ paru -Q swayr-git
swayr-git r351.5b072d2-1
$

To create an urgent window, execute the following commands in Alacritty, etc.

while true ; do sleep 5 ; echo -e "\a" ; done

Test a-g

set $mode_test "Test key[*]?"
mode $mode_test {
    bindsym a exec swayr switch-to-app-or-urgent-or-lru-window foot --skip-urgent
    bindsym b exec swayr switch-to-app-or-urgent-or-lru-window foot --skip-urgent --skip-lru
    bindsym c exec swayr switch-to-app-or-urgent-or-lru-window foot --skip-urgent --skip-lru --skip-origin
    bindsym d exec swayr switch-to-app-or-urgent-or-lru-window foot --skip-urgent --skip-origin
    bindsym e exec swayr switch-to-app-or-urgent-or-lru-window foot --skip-lru
    bindsym f exec swayr switch-to-app-or-urgent-or-lru-window foot --skip-lru --skip-origin
    bindsym g exec swayr switch-to-app-or-urgent-or-lru-window foot --skip-origin
    # back to normal: Escape
    bindsym Escape mode "default"
}
bindsym $mod+t mode $mode_test

capture: https://streamable.com/b6mac2

  • a: No problems that I can see
  • b: Switching to origin too often
  • c: It doesn't switch in the middle
  • d: Some keys don't switch even after key input
  • e: Switching to origin too often
  • f: Some keys do not switch even after key presses
  • g: Some parts do not switch even after key presses, do not switch to LRU, and sometimes switch to origin

~tsdh a month ago

Thanks, good recipe. I've found a bug where the skip flags for lru & origin would also inhibit matching foot windows when that foot window also was the original window or the LRU window. Of course, in that case, it must be visited.

I guess there are still some problems. I'll have a look when I find some time.

~tsdh a month ago

Ok, I've made some other refinements. At least when walking the code in my head, it seems to do the right thing. ;-)

One thing you have to consider with the LRU window is the focus.lockin_delay, i.e., when you switch to some window and then switch away again quickly (750ms by default), that intermediate window won't become "locked in", that is, it won't get its timestamp refreshed and thus not become the LRU window.

~tkna a month ago

Thanks. Looks like there is a problem with a-d,g

$ paru -Q swayr-git
swayr-git r353.b02f486-1
$ 

capture: https://streamable.com/lapt4f

  • a: sometimes does not skip urgent
  • b: sometimes does not skip urgent
  • c: sometimes does not skip urgent
  • d: sometimes does not skip urgent
  • e: appears to be OK
  • f: appears to be OK
  • g: probably skips lru, switches to origin after switching to urgent

~tsdh a month ago*

Thanks, found the bug for a-d: the skip flags have been reset when forcing a new cycle when no switch-to target has been left over.

I haven't managed to reproduce g, though. Maybe there's no bug but it may be that LRU and origin switch roles after a cycle has completed. You can get better (less) log messages when restricting the swayr log to just the cmds module using env RUST_BACKTRACE=1 RUST_LOG=swayr::cmds=debug swayrd. There are the following messages:

  • "Initialized SwitchToMatchingData: {:?}" when a new cycle starts
  • "Switching to by urgency or matching predicate" when switching to a window by urgency hint or by matching
  • "Switching to LRU" (self-explanatory)
  • "Switching back to origin" (self-explanatory)
  • And maybe "No origin window" when the origin window has disappeared at the time where we should switch back to it.

That should shed some light.

~tkna a month ago*

Sorry if it's unavoidable due to specifications, etc.

$ paru -Q swayr-git
swayr-git r355.8d34a76-1
$

capture: https://streamable.com/hiz3wo

  • a: The switch destination order changes on the second cycle
  • b: The switch destination order changes on the second cycle
  • c: The switch destination order changes on the second cycle
  • d: Sometimes switches to origin
  • e: The switch destination order changes on the second cycle
  • f: The switch destination order changes on the second cycle
  • g: No longer switches to LRU on the second cycle

~tsdh a month ago

That the order changes in every cycle is caused by swayr always sorting windows in this order: urgent windows (sorted by last focus time), non-urgent windows (again, sorted by last focus time), current window last. So when you have 3 foot windows a, b, c and you visit them in this order, then the LRU order afterwards will naturally be c, b, a.

I could change that easily and provide a stable order (by id) but I think the current way makes sense. You usually wouldn't cycle all foot windows and LRU and then start over again but you'd stop at the window you are interested in. And the assumption is that most of the time, the most interesting window is one of those which you've used last.

With respect to d: I couldn't reproduce and also didn't see a line "Switching back to origin" in the log in your screencast. I think that the origin window of the first cycle ends up as LRU window in the second cycle or something alike.

~tkna a month ago

I could change that easily and provide a stable order (by id) but I think the current way makes sense. You usually wouldn't cycle all foot windows and LRU and then start over again but you'd stop at the window you are interested in. And the assumption is that most of the time, the most interesting window is one of those which you've used last.

It certainly makes more sense that way. Thank you.

The phenomenon mentioned in d was not shown in the screencast. My apologies. I think that when I tested it before, it was treated as an LRU instead of an origin, because the window I assumed as origin had a short duration of stay. As for the g, I was also convinced that if --skip-origin is present, the window is switched to LRU at the end of the first round and then origin is skipped, so that window becomes origin for the second round and is skipped again, and the number of places to switch is decreasing with each round.

Sorry to change the subject so much from there, but I was thinking about LRU. I feel that LRU is a function to go back to the previous window when the window currently in focus is the switch destination. In that sense, once the focus is shifted to the second switch destination, I feel that the meaning of LRU is ambiguous. (Is it one before origin? Is it one before the window currently in focus?) How about switching to LRU only when the current focus is on origin and the next switch destination is origin itself and nothing else?

~tsdh a month ago

I've found a bug affecting LRU/origin and another problem which could lead to surprising behavior when switching focus by other means than swayr during a switch-to-* sequence.

~tsdh a month ago*

Also, there's a new misc.auto_nop_delay config option which is the number of milliseconds after which swayr will execute a nop command. For example, when you set it to 5000 and then do some switch-to-* cycle, 5 seconds after your last command an automatic nop will be executed terminating this cycle. This reduces surprises when you found the window you are looking for and stay there and minutes later want to start another cycle but effectively resume the cycle you've started previously.

If misc.auto_nop_delay is not specified explicitly in your config, that feature is turned off.

~tkna a month ago

Thank you. I see that misc.auto_nop_delay = <msec> absorbed the difference in perception of LRU and origin due to the user's operation style. As for what I said above about lru, I could set --skip-lru in my usage to make the operation comfortable even if there is only one window to switch to, so it seems to be fine as it is now.

It might be useful if the following options could be set in config.toml.

skip-urgent = false
skip-lru = false
skip-origin = false

~tkna a month ago*

I have tested the following form.

$ paru -Q swayr-git
swayr-git r362.e5db1f3-1
$ sudo pacman -S rxvt-unicode
$ 
$ alias swayrd_dbg='RUST_BACKTRACE=1 RUST_LOG=swayr::cmds=debug swayrd 2>&1 | tee /tmp/swayrd_cmds=debug_$(date --utc +%Y%m%d-%H%M%S).log'
$ alias swayrd_dbg_v='RUST_BACKTRACE=1 RUST_LOG=swayr=debug swayrd 2>&1 | tee /tmp/swayrd_$(date --utc +%Y%m%d-%H%M%S).log'
$ 
$ head -n 1 ~/.config/swayr/config.toml
misc.auto_nop_delay = 5000
$ swayrd_dbg_v

~/.config/sway/config.d/test.conf

set $mode_test "Test key[*]?"
mode $mode_test {
    bindsym a exec swayr switch-to-app-or-urgent-or-lru-window foot --skip-urgent
    bindsym b exec swayr switch-to-app-or-urgent-or-lru-window foot --skip-urgent --skip-lru
    bindsym c exec swayr switch-to-app-or-urgent-or-lru-window foot --skip-urgent --skip-lru --skip-origin
    bindsym d exec swayr switch-to-app-or-urgent-or-lru-window foot --skip-urgent --skip-origin
    bindsym e exec swayr switch-to-app-or-urgent-or-lru-window foot --skip-lru
    bindsym f exec swayr switch-to-app-or-urgent-or-lru-window foot --skip-lru --skip-origin
    bindsym g exec swayr switch-to-app-or-urgent-or-lru-window foot --skip-origin
    bindsym h exec swayr switch-to-matching-or-urgent-or-lru-window '[app_id="foot"]'
    bindsym i exec swayr switch-to-matching-or-urgent-or-lru-window '[app_id="foot"]' --skip-urgent
    bindsym j exec swayr switch-to-matching-or-urgent-or-lru-window '[app_id="foot"]' --skip-urgent --skip-lru
    bindsym k exec swayr switch-to-matching-or-urgent-or-lru-window '[app_id="foot"]' --skip-urgent --skip-lru --skip-origin
    bindsym l exec swayr switch-to-matching-or-urgent-or-lru-window '[app_id="foot"]' --skip-urgent --skip-origin
    bindsym m exec swayr switch-to-matching-or-urgent-or-lru-window '[app_id="foot"]' --skip-lru
    bindsym n exec swayr switch-to-matching-or-urgent-or-lru-window '[app_id="foot"]' --skip-lru --skip-origin
    bindsym o exec swayr switch-to-matching-or-urgent-or-lru-window '[app_id="foot"]' --skip-origin
    bindsym p exec swayr switch-to-matching-or-urgent-or-lru-window '[class="URxvt"]'
    bindsym q exec swayr switch-to-matching-or-urgent-or-lru-window '[app_id="foot" class="URxvt"]'
    bindsym r exec swayr switch-to-matching-or-urgent-or-lru-window '[app_id="foot" class="URxvt"]' --skip-urgent
    bindsym s exec swayr switch-to-matching-or-urgent-or-lru-window '[app_id="foot" class="URxvt"]' --skip-urgent --skip-lru
    bindsym t exec swayr switch-to-matching-or-urgent-or-lru-window '[app_id="foot" class="URxvt"]' --skip-urgent --skip-lru --skip-origin
    bindsym u exec swayr switch-to-matching-or-urgent-or-lru-window '[app_id="foot" class="URxvt"]' --skip-urgent --skip-origin
    bindsym v exec swayr switch-to-matching-or-urgent-or-lru-window '[app_id="foot" class="URxvt"]' --skip-lru
    bindsym w exec swayr switch-to-matching-or-urgent-or-lru-window '[app_id="foot" class="URxvt"]' --skip-lru --skip-origin
    bindsym x exec swayr switch-to-matching-or-urgent-or-lru-window '[app_id="foot" class="URxvt"]' --skip-origin
    # back to normal: Escape
    bindsym Escape mode "default"
}
bindsym $mod+t mode $mode_test
  • a-p: No problem seems to be detected
  • q: Cannot switch to target window
  • r: swayrd crashes with the following error
[2022-07-06T11:45:50Z DEBUG swayr::cmds] Switching back to origin

thread 'main' has overflowed its stack
fatal runtime error: stack overflow

screencast: https://streamable.com/momnpl

debug-log: https://firestorage.jp/download/9f640442a413bb3998353e1ce91373ad504ab6e0

~tsdh a month ago

Hey, thanks for the extensive testing!

Wrt. q, what do you mean with "cannot switch to target window"? Do you mean the window matched by the criteria? If so, that's correct because there cannot be a window which has both app_id="foot" and class="URxvt". Only wayland windows have an app_id and only X11/xwayland windows have a class.

Wrt. the crash: I only got it on s. When a switch-to command couldn't do anything, it reset its state and called itself recursively. I've added a termination criterion.

~tkna a month ago

I see, you mean matching on the AND condition, not the OR condition. I didn't realize that, sorry. I redid it with the following for now.

$ paru -Q swayr-git
swayr-git r363.1cff0d2-1
$ foot --title foot#1 & foot --title foot#2 &
set $mode_test "Test key[*]?"
mode $mode_test {
    bindsym p exec swayr switch-to-matching-or-urgent-or-lru-window '[app_id="foot" title="foot#1"]'
    bindsym q exec swayr switch-to-matching-or-urgent-or-lru-window '[app_id="foot" title="foot#1"]' --skip-urgent
    bindsym r exec swayr switch-to-matching-or-urgent-or-lru-window '[app_id="foot" title="foot#1"]' --skip-urgent --skip-lru
    bindsym s exec swayr switch-to-matching-or-urgent-or-lru-window '[app_id="foot" title="foot#1"]' --skip-urgent --skip-lru --skip-origin
    bindsym t exec swayr switch-to-matching-or-urgent-or-lru-window '[app_id="foot" title="foot#1"]' --skip-urgent --skip-origin
    bindsym u exec swayr switch-to-matching-or-urgent-or-lru-window '[app_id="foot" title="foot#1"]' --skip-lru
    bindsym v exec swayr switch-to-matching-or-urgent-or-lru-window '[app_id="foot" title="foot#1"]' --skip-lru --skip-origin
    bindsym w exec swayr switch-to-matching-or-urgent-or-lru-window '[app_id="foot" title="foot#1"]' --skip-origin
    bindsym x exec swayr switch-to-matching-or-urgent-or-lru-window '[app_id="foot" title="foot#"]'
    bindsym z exec swayr switch-to-matching-or-urgent-or-lru-window '[app_id="foot" title="foot#"]' --skip-urgent --skip-lru --skip-origin
    # back to normal: Escape
    bindsym Escape mode "default"
}
bindsym $mod+t mode $mode_test
  • p-z: no problems as far as I can see

Thank you very much. I will do some more testing with PID.

~tsdh a month ago

Yeah, criteria are implicitly AND-ed. BTW, swayr supports a name=foo criteria which sway doesn't have. That matches app_id or class whatever is set. So here you don't need to care if its a native wayland or X11 window.

~tkna a month ago

The following does not appear to work. Am I doing something wrong?

swayr switch-to-matching-or-urgent-or-lru-window '[name="foot"]'
$ paru -Q swayr-git
swayr-git r363.1cff0d2-1
$ which app_id_class
app_id_class () {
        echo "* APP_ID *"
        swaymsg -t get_tree | grep "app_id" | sed -e "s@^ *.*: @@g" -e "s@[\",]@@g" -e "s@ \+@\n@g" | sort -u
        echo -e "\n* CLASS *"
        swaymsg -t get_tree | jq -r "..|try .window_properties .class" | sort -u
}
$ app_id_class | grep "\*\|foot" 
* APP_ID *
foot
* CLASS *
$ alias swayrd_dbg='pkill swayrd ; RUST_BACKTRACE=1 RUST_LOG=swayr::cmds=debug swayrd 2>&1 | tee /tmp/swayrd_cmds=debug_$(date --utc +%Y%m%d-%H%M%S).log'
$ alias swayrd_dbg_v='pkill swayrd ; RUST_BACKTRACE=1 RUST_LOG=swayr=debug swayrd 2>&1 | tee /tmp/swayrd_$(date --utc +%Y%m%d-%H%M%S).log'
$ swayrd_dbg_v

Having run out of alphabets to make identifiers and key bindings I start Test2.

set $mode_test "Test2 key[*]?"
mode $mode_test {
    bindsym a exec swayr switch-to-matching-or-urgent-or-lru-window '[name="foot"]'
    bindsym b exec swayr switch-to-matching-or-urgent-or-lru-window '[name=foot]'
    bindsym c exec swayr switch-to-matching-or-urgent-or-lru-window [name=foot]
    # back to normal: Escape
    bindsym Escape mode "default"
}
bindsym $mod+t mode $mode_test
  • a-c: do not switch. The debug log is below
[a@gb1 ~]$ swayrd_dbg_v
[2022-07-08T08:30:28Z DEBUG swayr::shared::cfg] Loading config from /home/a/.config/swayr/config.toml.
[2022-07-08T08:30:28Z DEBUG swayr::daemon] Connecting to sway for subscribing to events...
[2022-07-08T08:30:28Z DEBUG swayr::daemon] Deleted stale socket from previous run.
[2022-07-08T08:30:29Z DEBUG swayr::daemon] Handled window event type Focus
[2022-07-08T08:30:30Z DEBUG swayr::daemon] Locking-in focus on 11
[2022-07-08T08:30:33Z DEBUG swayr::daemon] Executing auto-nop.
[2022-07-08T08:30:33Z INFO  swayr::cmds] Running SwayrCommand Nop
[2022-07-08T08:30:36Z INFO  swayr::cmds] Running SwayrCommand SwitchToMatchingOrUrgentOrLRUWindow { criteria: "[name=\"foot\"]", skip_urgent: false, skip_lru: false, skip_origin: false }
[2022-07-08T08:30:36Z ERROR swayr::criteria] Could not parse criteria query [name="foot"]: error at 1:2: expected one of "]", "app_id", "app_name", "class", "con_id", "con_mark", "floating", "instance", "pid", "tiling", "title", [' ' | '\t']
[2022-07-08T08:30:41Z DEBUG swayr::daemon] Executing auto-nop.
[2022-07-08T08:30:41Z INFO  swayr::cmds] Running SwayrCommand Nop
[2022-07-08T08:30:42Z DEBUG swayr::daemon] Handled window event type Focus
^C
[a@gb1 ~]$

~tsdh a month ago

Hi again,

[2022-07-08T08:30:36Z ERROR swayr::criteria] Could not parse criteria query [name="foot"]: error at 1:2: expected one of "]", "app_id", "app_name", "class", "con_id", "con_mark", "floating", "instance", "pid", "tiling", "title", [' ' | '\t']

Ups, sorry, that thing is called app_name, not name. See the docs at https://git.sr.ht/~tsdh/swayr/tree/next/item/README.md#swayr-non-menu-switchers.

Bye, Tassilo

~tkna 30 days ago

Thanks. I have tested the following.

$ foot --title foot#1 & foot --title foot#2 &
$ alacritty
$ paru -S sunvox qutebrowser
$ sunvox_opengl &
$ pgrep -a sunvox_opengl
816200 sunvox_opengl
$ qutebrowser &
$ pgrep -a qutebrowser
608129 /usr/bin/python3 /usr/bin/qutebrowser --untrusted-args
$ 
    bindsym d exec swayr switch-to-matching-or-urgent-or-lru-window '[app_name="foot"]'
    bindsym e exec swayr switch-to-matching-or-urgent-or-lru-window '[app_name="Alacritty"]'
    bindsym f exec swayr switch-to-matching-or-urgent-or-lru-window '[app_name="foot" title="foot#1"]'
    bindsym g exec swayr switch-to-matching-or-urgent-or-lru-window '[app_name="foot" title="foot#1"]' --skip-urgent
    bindsym h exec swayr switch-to-matching-or-urgent-or-lru-window '[app_name="foot" title="foot#1"]' --skip-urgent --skip-lru
    bindsym i exec swayr switch-to-matching-or-urgent-or-lru-window '[app_name="foot" title="foot#1"]' --skip-urgent --skip-lru --skip-origin
    bindsym j exec swayr switch-to-matching-or-urgent-or-lru-window '[app_name="foot" title="foot#1"]' --skip-urgent --skip-origin
    bindsym k exec swayr switch-to-matching-or-urgent-or-lru-window '[app_name="foot" title="foot#1"]' --skip-lru
    bindsym l exec swayr switch-to-matching-or-urgent-or-lru-window '[app_name="foot" title="foot#1"]' --skip-lru --skip-origin
    bindsym m exec swayr switch-to-matching-or-urgent-or-lru-window '[app_name="foot" title="foot#1"]' --skip-origin
    bindsym n exec swayr switch-to-matching-or-urgent-or-lru-window '[app_name="foot" title="foot#"]'
    bindsym o exec swayr switch-to-matching-or-urgent-or-lru-window '[app_name="foot" title="foot#"]' --skip-urgent --skip-lru --skip-origin
    bindsym p exec swayr switch-to-matching-or-urgent-or-lru-window '[app_name="foo[t]" title="foot[#.*]"]' --skip-urgent --skip-lru
    bindsym q exec swayr switch-to-matching-or-urgent-or-lru-window '[title="foot.*"]'
    bindsym r exec swayr switch-to-matching-or-urgent-or-lru-window '[pid=608129]'
    bindsym s exec swayr switch-to-matching-or-urgent-or-lru-window '[title="SunVox v]'
    bindsym t exec swayr switch-to-matching-or-urgent-or-lru-window '[pid=816200]'
  • d-r: appears to be OK
  • s,t: can't switch

As for s,t, I think it is difficult to switch because the application does not have app_id or class. As for me, I don't currently use it regularly, so there is little need for it.

~tsdh 29 days ago

I've tested the switching by criteria [pid=<pid>] and it works fine for me. Could you please post how this SunVox thingy is shown in the swaymsg -t get_tree JSON output?

~tkna 29 days ago

Sorry, I must have written the command wrong and misunderstood something. I wrote the following u,v and it worked as expected.

$ pgrep -a sunvox
1178894 sunvox_opengl
$
    bindsym u exec swayr switch-to-matching-or-urgent-or-lru-window '[title="SunVox v"]'
    bindsym v exec swayr switch-to-matching-or-urgent-or-lru-window '[pid=1178894]' --skip-lru
    bindsym w exec swayr switch-to-matching-or-urgent-or-lru-window '[title="(SunVox v|\.sunvox)"]' --skip-lru
    bindsym x exec swayr switch-to-matching-or-urgent-or-lru-window '[app_name="foot|Alacritty"]' --skip-lru

By writing w,x I was also able to match OR conditions on the same CRITERIA type. screencast: https://streamable.com/mcmgh4

This is just a curiosity question, but is there a way to write an OR condition to connect different CRITERIA types?

~tsdh 29 days ago

Well, yes, every criteria where a regexp is accepted allows you to use alternatives because regular expressions support that.

With respect to OR between different criteria: right now that's not possible because my aim was to basically implement the CRITERIA spec of sway which doesn't support that. It wouldn't be hard to come up with a syntactically simple form of allowing alternatives, e.g., [foo=bar baz=17] is always AND-ed but you could have [OR [foo=bar baz=17] [foo=quux baz=42]] in order to have alternatives. Of course, then you would also want to have a NOT in order to be complete.

As said, it wouldn't be too hard to implement but before such extensions, someone should ask the sway developers if their long-term plans include such an extension. If so, swayr should of course use the same syntax.

~tkna 29 days ago

I don't know yet if there are any specific use cases for me, but in the direction of extending the functionality, I feel that the ability to make CRITERIA OR conditional would cover most cases I can imagine right now.

If you don't mind, I will write an issue on sway's github. May I quote this ticket for explanation? Is that a bit hasty?

~tsdh 29 days ago

Sure, as soon as you have AND/OR/NOT you can express anything there can be in propositional logic.

AFAIK, the current sway policy is to implement no new features unless i3 has them, too. So I guess a ticket might be a bit hasty. I guess I'll just ask on #sway@libera.chat at some point in time.

~tkna 29 days ago

Understood. I would be happy to be informed of any progress.

~tsdh REPORTED IMPLEMENTED 15 days ago

I'm closing this ticket because I think everything works now and I've released 0.20.0.

Feel free to open a new ticket for the composition of criteria queries using OR/NOT.

~tkna 14 days ago

Understood. Thanks for the great design and implementation!

~tkna 14 days ago

I wrote that ticket #25

Register here or Log in to comment, or comment via email.