<CelestialCrafter>
hiyaa, whats the point of river spawn? is there anything different between `river spawn x` and `x &`?
CelestialCrafter has quit [Quit: Client closed]
angry_vincent has joined #river
leopoldek has quit [Ping timeout: 252 seconds]
sespiros_ has joined #river
sespiros has quit [Ping timeout: 272 seconds]
sespiros_ is now known as sespiros
talismanick has joined #river
ayushnix has quit [Ping timeout: 256 seconds]
Guest39 has joined #river
Guest39 has quit [Client Quit]
Guest39 has joined #river
Guest39 has quit [Quit: Client closed]
fossdd has quit [*.net *.split]
LarstiQ has quit [*.net *.split]
LarstiQ has joined #river
fossdd_ has joined #river
hmht has joined #river
osaut has joined #river
osaut has quit [Quit: WeeChat 4.3.0]
waleee has joined #river
<leon-p>
ifreund: what is the reasoning behind keeping keybind modes server-side? One additional roundtrip after keybind trigger seems reasonable to allow for greater flexibility
<leon-p>
also the name "next_mode" implies some sort of mode stack you could pop
<ifreund>
note that we would need to buffer an arbitrary number of key events during that roundtrip on the server side and replay them after the keybind client acked the keybind trigger
<leon-p>
the use case that will be complicated a bit with the modes are emacs-style keychords. Imagine a user wanted to have a few keychords like "S-x w 3", "S-x w 2" etc. for window operations. With the modes, you first need to translate those into the necessery modes, without modes you could just match database-like
<leon-p>
FWIW I think limiting the amount of buffered key events to something low, like a few hundred would be fine
<ifreund>
also, an arbitrary DFA can already express any possible keybinding scheme unless I'm mistaken
<leon-p>
all use casses are served either way, it's just about ergonomics
<leon-p>
I mean there is one scheme we don't serve: the other meaning of "chording" where multiple keys are pressed/released simultaneously
<leon-p>
but that one is way less commonly used, so whatever
<ifreund>
you mean like, if A and B are pressed at "the same time" (+/- 10ms or whatever) a keybind is triggered?
<leon-p>
exactly
<leon-p>
(I am fine btw with the modes, just wondered about the reasoning)
<ifreund>
I personally see expressing `S-x w 3` in terms of modes as globally simpler than roundtripping and dynamically creating/destroying keybinds after ever keypress in the sequence
<ifreund>
fwiw, I think this is how it's implemented internally in emacs as well
<ifreund>
there's a global keymap, C-x puts you in the "C-x" keymap
<ifreund>
etc.
<leon-p>
Another use case I had in mind was this macOS tool were you press some modifier plus a letter and it will focus the first window where the first letter of either app-id or title match the given letter. But this is still possible, you just have to create keybinds from the windowlist instead of querying the window list after the keybind.
<leon-p>
I probably need to think about this more, because creating modes when parsing keybind descriptors really isn't hard
<ifreund>
leon-p: I'd be open to some different mode "styles" that e.g. capture or block all input instead of passing it along to the focused window
<leon-p>
also, how will this interact with the pointer? I can imagine users wanting different options for clicking while holding a modifier
<ifreund>
alternatively, your "modifier" could cause the WM to create and focus a surface of its own that gets the keyboard input
<ifreund>
I haven't decided how pointer bindings should work yet
<ifreund>
they probably need to be done in the river-window-management protocol itself rather than this separate one
<leon-p>
I'll think about it, but all use cases I myself would realistically use are satisfied
IchikaZou has joined #river
IchikaZou has quit [Remote host closed the connection]
angry_vincent has quit [Ping timeout: 272 seconds]
leopoldek has joined #river
lbia has quit [Ping timeout: 255 seconds]
Guest67 has joined #river
Guest67 has quit [Client Quit]
belanthor has joined #river
ThatGuestAgain has joined #river
<ThatGuestAgain>
I'm still exploring how enhancable the mapping system is with external scripts, and how far I can get *without* a longterm helper process for now. I've found a problem with the locked mode.
<ThatGuestAgain>
Locked mode causes two mode changes between which key events are not processed by the prior mode. At unlock, the prior mode is restored, but by that time, it is the wrong mode.
<ThatGuestAgain>
Key events (releases) during lock should already have changed that mode, but could not. Mappings in locked mode don't help: they neither know the prior mode nor can they influence the next. Ideas how I can work around that?
<leon-p>
what's the use case / issue?
<ThatGuestAgain>
One takeaway from yesterdays discussion is that if I want to have non-trivial mapping semantics, the only place I can put state in is the mode.
<ThatGuestAgain>
So if part of the semantics I associate with a mode is a key that is held down and releasing it should get me out of the mode, releasing it in locked mode throws me back in the wrong mode at unlock.
<leon-p>
once the keybind protocol lands, you'll need a long-running process for those anyway, then you can keep all the extra state you like
lbia has joined #river
<ThatGuestAgain>
I don't see how 'keeping extra state' helps here. The modes get out of sync with the state of the keyboard either way.
<leon-p>
perhaps we can introduce a way to set the mode auto-enterred after locked mode to the keybind protocol
<leon-p>
otherwise I still don't see real-world issues with this
lbia has quit [Ping timeout: 256 seconds]
<ifreund>
perhaps it would be better if locked always transitioned to normal mode on unlock
lbia has joined #river
<ThatGuestAgain>
I am not trying to get changes here, I went way to far with my suggestion yesterday. I'm just wondering if someone does know a workaround. Yes, the issue is very real world for me : ) It would have gotten me stuck in the wrong mode an hour ago if I hadn't realized while typing the mappings.
lbia has quit [Max SendQ exceeded]
<ThatGuestAgain>
ifreund That would lead to similar issues, just other symptoms. As I said, I won't ask you to change river behaviour for me anymore xD I was trying to ask what to do as a user, not how river should change : )
lbia has joined #river
<ifreund>
I don't mind changing river's behavior to make things better, I like making things better
<ifreund>
I'm not terribly happy with how locked mode works right now in any case
lbia has quit [Max SendQ exceeded]
lbia has joined #river
<ThatGuestAgain>
Well I have an idea but I assume its a too drastic one once again... Making locked not a mode but a flag similar to -release/-repeat.
<ifreund>
actually I'd be totally happy with that from an implementation perspective if that solves your issues
<ThatGuestAgain>
Not asking, I promised not too... its an **theoretical idea** :)
lbia has quit [Max SendQ exceeded]
<ifreund>
ThatGuestAgain: I honestly value your input here, you're pushing the bounds of what river's keybinding system can support which is really valueable right in this moment as I am working on the design for the new keybind protocol
<leon-p>
making locked a per-bind property has other issues: imagine I have mediakey binds in my main mode which are flagged as locked. now I enter a theoretical window-resize mode or something. I move away from my keyboard for a few minutes, the session locks. The window resize mode is still active and as such my media keys won't work
<ifreund>
and if we specify that the lock event transitions to normal mode?
<ifreund>
(in addition to per-keybind locked flag)
<leon-p>
that would be my preferred solution
<leon-p>
in my mental model, keybind modes are transient, as such it makes sense to me that locking "aborts" modes
<ifreund>
ThatGuestAgain: I'm having trouble coming up with a use-case where exiting locked mode always transitioning to normal mode would cause problems
<ifreund>
could you share what "similar issues, just other symptoms" you had in mind?
belanthor has quit [Quit: Leaving]
<ThatGuestAgain>
The core issue is locking changing mode outside of my control. If not every mode change is made by an 'enter-mode' command, I cannot reliable tell the mode still is what I think it is. By tangling locking and mode in any way, locking will interfere.
<ThatGuestAgain>
What I am trying is implementing modes as temporary and entering modes as composing as discussed earlier. (Mapping compiler, etc.)
<ifreund>
I think it would still be clear what mode one is in. The session locks => you are in locked mode. The session unlocks => you are in normal mode
Guest20 has joined #river
<Guest20>
hi
<Guest20>
can anybody help
<ifreund>
many people can, but you need to ask a question first
<Guest20>
i wanna change command of the same hotkey in cycle like on first press it does something, on second it does something differently and then back to the first command
<leon-p>
Guest20: you'll want to do that in a script. Write some state to a file at the end, at the beginning of the script you read the state from the file and change behaviour based on that
<leon-p>
pretty simple in bash
osaut has joined #river
<Guest20>
ok i will try
<ThatGuestAgain>
ifreund Yes, but now instead of being thrown into the prior mode unexpectedly the system is thrown in normal mode unexpectedly. That is clear to the user, but the user perspective does not matter. The perspective of the mapping system is what gets confused.
<ThatGuestAgain>
The state it has to keep track of (the mode) over time is overwritten by locking and it does not get any notice. It has to anticipate that at any point in time all the mappings it currently provides are silently wiped by locking.
<ifreund>
the only state a keybind system should store is the mode
<leon-p>
would this be solved by adding an event to inform the keybinds client that locked mode was entered / left?
<ifreund>
river allows as many modes as you like as long as as your computer has memory to hold them
angry_vincent has joined #river
<leon-p>
I mean, what the other guest asked about could technically be done in the keybind system, that would be additional state which is per-bind not per-mode
hmht has quit [Remote host closed the connection]
<Guest20>
how to write state to the file is that sh file that i need to run on riverctl spawn?
<ifreund>
leon-p: that state is not really related to keybinds or modes directly though, it's part of the action
<leon-p>
fair
<ifreund>
the architecture I envision is that the user defines a state machine taking key events as input and sending keybind trigger events as output
<ifreund>
this state machine lives in the compositor process
<leon-p>
Guest20: create a file somewhere, f.e. in your .cache where you write some string to and then at the top of your script just switch on the `head -1`
<ifreund>
the only state that affects the triggering of keybinds is that state of the state machine
<ifreund>
ThatGuestAgain has a use case that would be better served by state machine that can be in multiple states at once (a NFA rather than a DFA)
<ifreund>
and a naieve NFA implemention isn't really that complex so I've been toying with the idea of supporting NFAs directly in the new protocol rather than only DFAs
hmht has joined #river
<leon-p>
NFA and DFA map losslessly and the potential size of a struct wrapping a river_keybind_mode_v1 at the client side isn't that large so I see no issue with this
<ifreund>
yeah they map losslessly but the equivalent DFA for an NFA can have exponentially more states and would require users to do the power set construction or whatever
<ifreund>
I don't know if the exponentially more states is really a problematic amount of memory in practice or not though
<leon-p>
"users" are still programmers writing a keybind client, not end-users. I think we can reasonably expect them to do some extra work if they need it
<ifreund>
It is a goal of mine to make writing WMs and keybinding code as accessible as possible, not all programmers have taken univeristy level automata theory courses or have the mathematical background needed to pick up the ideas quickly
<ifreund>
many river users may not do any programming beyond bash scripts tying things together
<ifreund>
anyhow, I'm not going to make supporting NFAs in the protocol a blocker for pushnig the WM protocol stuff forward, but I will make sure the protocol can be extended to support NFAs if I want to in the future
<Guest20>
this must include something like if? dk how to implement that
<ifreund>
Guest20: bash has an if statement, search engines are your friend
<Guest20>
ok missed that init is shell script
<ThatGuestAgain>
Sorry, I can't quite keep up with answering all your points ifreund leon-p . Maybe the root of the misunderstanding is to you both the user is completely aware of the mode and hence all is clear to him even when silently changed.
<ThatGuestAgain>
But to me, the mode is something my system needs to change on potentially any key up/down and must not be messed with from the outside to implement the keymap compiler approach I was told to go with yesterday.
<ThatGuestAgain>
Locking does mess with it. Even with how you think about alternatives to the current behaviour above. So I have to accept that mode will always be tied to locking and may be messed up at any time and have to change my approch to my mapping system.
<ThatGuestAgain>
I'll see what options that leaves me with. I think this forces me to make state/mode very much a concern of the user, not something I can leverage internally. I'll double check a few times though if system-internal usage really is out of the window.
<ThatGuestAgain>
Please tell me to stop it when my ramblings on keys get to annoying '=D I weirdly care more about that than the precise arrangement of windows.
<ifreund>
heh, no worries
<ThatGuestAgain>
Will the wm be able to inspect what mode is active, what modes exist and what enter-mode mappings exist?
<ifreund>
the idea is that the wm defines a state machine that lives in the compositor process at startup or when the user manually edits the configuration
<ifreund>
all state related to how keybindings are interpreted is defined by that state machine
<ifreund>
and after defining the state machine, the wm does nothing keybinding related except receive events when keybindings are triggered
<ThatGuestAgain>
If I understand correctly, the state can be changed by two things: keybindings and locking. Right? At least that is how it is now.
hmht has quit [Ping timeout: 252 seconds]
<ifreund>
yes that's correct
<ifreund>
I agree that it would be more flexible in theory to have the transitions that occur on lock/unlock defined by the user as well but don't yet understand the use-case that requires that
<ifreund>
my current plan is to have a transition from every state to the locked state on the lock event and a transition from every state to the normal state on the unlock event
ThatGuestAgain has quit [Ping timeout: 250 seconds]
Guest20 has quit [Quit: Client closed]
<leon-p>
thinking about it, don't we need to buffer key events anyway? imagine a user has a mode entered with S-c, then a keybind "w" which does some action and in addition to that action also returns to normal mode. If the user now presses "S-c w S-c w" very quickly, river might interpret the second "S-c" while still in that mode
<leon-p>
bad example, because those binds can't be typed that quickly
<ifreund>
leon-p: no, there's no race there. On the server side the "w" in question will send a trigger event for that keybind to the client and synchronously transition to normal mode before processing further input events
<leon-p>
ah, I see. next_mode is called on the keybind when setting it up, not when receiving the trigger
<leon-p>
that makes more sense
<ifreund>
yeah, probably needs a better name/docs
adamcstephens_ has joined #river
<leon-p>
I would probably also add a request to change the mode
<leon-p>
a client may want to switch based on factors outside the automata scope
adamcstephens has quit [Ping timeout: 268 seconds]
adamcstephens_ is now known as adamcstephens
<ifreund>
leon-p: like what?
<ifreund>
doing that will always be racy as far as I can tell
<ifreund>
which is why I didn't add it
groknull has joined #river
ThatGuestAgain has joined #river
groknull has quit [Remote host closed the connection]
lbia has joined #river
groknull has joined #river
<ThatGuestAgain>
So locking will still wipe the automaton state and the wm can't stop it. That is why I asked if the wm can inspect what mode/state is active. Or alternatively, will it get notified when locking wipes the state? Thanks to the events it recieves it can at least keep track of the state itself.
groknull has quit [Remote host closed the connection]
<ThatGuestAgain>
... except potentially on lock, that is my question.
<ThatGuestAgain>
Nevermind, ignore it. I just realized my state explosion would be severe. Like... millions of intermediate/transistion states. I'll have to do this completely differently anyways.
osaut has quit [Ping timeout: 268 seconds]
osaut has joined #river
vimproved_ has joined #river
vimproved_ has quit [Remote host closed the connection]
vimproved_ has joined #river
vimproved_ has quit [Remote host closed the connection]
vimproved_ has joined #river
zayd has joined #river
belanthor has joined #river
angry_vincent has quit [Ping timeout: 240 seconds]
<ThatGuestAgain>
Wait. I'm so stupid. The entire time I thought of the protocol to be pretty much what `riverctl (un)map` plus `riverctl ...mode...` are. It is not. Not at all. Because the actual actions like `spawn foot` are not on the compositor side any more.
<ThatGuestAgain>
These actions are on wm side. The only outgoing effect of the state machine is wether to send the key event to the focused window or to the wm. Nothing other than that boolean decision (and internal state change). Am I _now_ getting it? Or still wrong?
ThatGuestAgain has quit [Ping timeout: 250 seconds]
<ifreund>
yes you are getting it :)
<ifreund>
and like I said, if the state explosion becomes prohibitive in practice I'm open to supporting NFAs instead of just DFAs
ThatGuestAgain has joined #river
<ThatGuestAgain>
The reason I was trying to get so much logic into the state machine was that I had the current model in mind. But with the actions moved out of the compositor, much of the issues I have disappear. I understand your reasonings much better now. I also think my goals do not require state explosion anymore, a few states will be enough. Returning to
<ThatGuestAgain>
default is also fine now (returning to pre-lock does still break my goals, I think). Anyways, I have been so terribly misunderstanding the protocol part, very sorry about that. Now I know for sure I won't bother trying to build it on top of current river (still state explosion and unavoidable races) and look forward to wms!
<ThatGuestAgain>
I was trying to put most of my logic into the state machine because I thought that is where actions are. With the actions being in the wm anyways, most logic can be there too. I somehow just didn't grasp that.
<ThatGuestAgain>
Phew. Oof. All my bad. Good night
ThatGuestAgain has quit [Quit: Client closed]
osaut has quit [Quit: WeeChat 4.3.0]
<ifreund>
no worries at all!
xtvl has quit [Ping timeout: 260 seconds]
alexherbo2 has joined #river
alexherbo2 has quit [Remote host closed the connection]
alexherbo2 has joined #river
belanthor has quit [Quit: Leaving]
Szadek has quit [Quit: off]
Szadek has joined #river
neeasade has joined #river
thesock has joined #river
Szadek8 has joined #river
Szadek has quit [Ping timeout: 264 seconds]
Szadek8 is now known as Szadek
Szadek4 has joined #river
alexherbo2 has quit [Remote host closed the connection]