project-repo / cagebreak

Cagebreak: A Wayland Tiling Compositor Inspired by Ratpoison
MIT License
284 stars 19 forks source link

config issue #13

Closed kinleyd closed 2 years ago

kinleyd commented 2 years ago

I'm trying to do a minimal initial layout in config.

When I just have this at the end of my config: nextscreen exec firefox Firefox is correctly opened on what is the nextscreen relative to the default

However, when I try this: nextscreen exec firefox exec sleep 15 nextscreen exec alacritty all calls to nextscreen seem to be ignored as both Firefox and alacritty are opened in the default screen, and sleep seems to have no effect no matter what value I set.

Related to this is the slightly confusing status of the default screen: a) If I don't open any applications via the config file and then run an application, it will run on one screen. b) If I don't open any applications via the config file, call nextscreen or prevscreen, and then run an application, it opens in a screen different from what it should be if the screen in a) was in fact the default. nextscreen/prevscreen seem to be reading a different default value.

project-repo commented 2 years ago

Actually, the behaviour of exec sleep 15 is precisely as expected. The shell command is run, though cagebreak does not wait for its termination (in the same way it does not wait for firefox to terminate).

Cagebreak does not have builtin wait functionality because it does not require it: All the necessary waiting can be done from a shell script, which can invoke a command via ipc socket. If you have questions regarding how to do so, don't hesitate to ask!

Regarding the default screen/nextscreen/prevscreen part, could you please describe your setup in more detail. How many monitors does it take to reproduce this bug? What are the precise commands (and in which order must they be executed) that cause it to occur? Is there any additional information you would like to share?

cheers project-repo

kinleyd commented 2 years ago

Hi,, thanks for getting back.

Actually, the behaviour of exec sleep 15 is precisely as expected. The shell command is run, though cagebreak does not wait for its termination (in the same way it does not wait for firefox to terminate).

Cagebreak does not have builtin wait functionality because it does not require it: All the necessary waiting can be done from a shell script, which can invoke a command via ipc socket. If you have questions regarding how to do so, don't hesitate to ask!

OK. I was assuming the call to sleep would be a blocking call. So if I understand it correctly, for what I want to do, I would need to make a call to the ipc socket from cagebreak/config? I haven't used ipc sockets before so I spent the last couple of days exploring. I've settled on nmap-netcat and have had some success using the ipc socket from Emacs. I've not been able to chain multiple commands per call to the ipc socket (which is what I would like to do) but it seems that it must be scripted. Let me get back to you after I explore a bit more.

Regarding the default screen/nextscreen/prevscreen part, could you please describe your setup in more detail. How many monitors does it take to reproduce this bug? What are the precise commands (and in which order must they be executed) that cause it to occur? Is there any additional information you would like to share?

Will do. I think I will start another issue for that with the complete details. A question: Cagebreak doesn't support wlrandr and wdisplay, etc., so I've been getting my output details with swaymsg -t get_outputs. Could you let me know of a better way that works with Cagebreak?

Thanks!

kinleyd commented 2 years ago

I've been able to test configuring cagebreak with calls to the ipc socket and have faced the same problem:

I have file netcat-config which contains the following lines: nextscreen exec firefox

This works as expected when I call netcat: $ nc -i 5 -U $CAGEBREAK_SOCKET < ~/.config/cagebreak/netcat-config Active screen is changed to the next screen, and Firefox is launched on the next screen.

However if I change netcat-config to: nextscreen exec firefox prevscreen

Firefox is run on the current screen whereas it should run on the next screen with the current screen remaining the active screen. So basically the commands remain non-blocking as they were when called from cagebreak/config.

Could you tell me what I'm missing?

Edit: To get commands to be executed synchronously, are we restricted to executing one command per netcat call? I have that working but it is quite a lot of work, and it is still iffy using -i, -d, -w parameters with nmap-netcat.

project-repo commented 2 years ago

The problem with this approach is the same as the problem of writing the commands directly within the configuration file: exec firefox is non-blocking so prevscreen is called before firefox has launched and therefore firefox is then opened on the current screen.

To implement this correctly, one must use bash to wait for firefox to open instead of relying on cagebreak. For example:

#!/bin/bash

echo "nextscreen"|nc -i 5 -U $CAGEBREAK_SOCKET
firefox&disown #open firefox directly from the bash script, no need to involve cagebreak
sleep 10 #Wait 10 seconds for firefox to open
echo "prevscreen"|nc -i 5 -U $CAGEBREAK_SOCKET

Does that work? (In my case I had to add the option -w1 to nc and remove the -i 5 option so it wouldn't continue to wait for input though I assume that depends on which implementation you are using)

cheers project-repo

kinleyd commented 2 years ago

Ah thanks. That makes sense now. Having busied myself figuring out netcat, I had missed running all of that in a bash script. I must say that juggling the command structures and syntax required for cagebreak, netcat and emacs had me in quite a tizzy.

What I've found is that sleep works with commands/apps like firefox that are executed via bash (without exec). However, sleep does not affect calls to the IPC socket which continue to run asynchronously. So calls to prevscreen/nextscreen execute in their own time.

The only way around it was to run everything in Cagebreak. This is what I have in cb-netcat.sh:

echo "prevscreen" | nc -i 1 -U $CAGEBREAK_SOCKET
echo "exec emacs --daemon" | nc -i 1 -U $CAGEBREAK_SOCKET
echo "exec emacsclient -a \"\" -c -F \"((name . \\\"dired\\\"))\"" | nc -i 1 -U $CAGEBREAK_SOCKET
echo "exec firefox" | nc -i 1 -U $CAGEBREAK_SOCKET
echo "nextscreen" | nc -i 1 -U $CAGEBREAK_SOCKET
echo "exec emacsclient -a \"\" -c -F \"((name . \\\"cider\\\"))\"" | nc -i 1 -U $CAGEBREAK_SOCKET
echo "nextscreen" | nc -i 1 -U $CAGEBREAK_SOCKET
echo "exec emacsclient -a \"\" -c -F \"((name . \\\"todo\\\"))\"" | nc -i 1 -U $CAGEBREAK_SOCKET
echo "prevscreen" | nc -i 1 -U $CAGEBREAK_SOCKET

So, it finally works. Thank you!

My only observation is that this involved an additional bash script and dabbling with netcat. I'm glad I learned what I did, but wouldn't it be simpler to make the execution of cagebreak/config synchronous? :) It would make it easier for on boarding new users, and the IPC socket would continue to be useful for live tweaking of the system.

project-repo commented 2 years ago

I'm not quite sure what you mean with "sleep does not affect calls to the IPC socket"... The way to wait between commands run through the IPC socket is to first send one command to the socket with nc, then sleep and then send the next command. Or what exactly do you mean? Alternatively, since the -i 1 option causes nc to wait a second between executing the separate lines, running multiple commands in a single nc invocation should have a similar effect.

Glad to hear that you figured out how to do what you were planning to do! About your suggestion of running cagebreak config synchronously, that is unfortunatly not possible: For example, imagine if your cagebreak config would contain exec firefox. Then cagebreak would wait until firefox has terminated before executing the rest of the configuration (actually it would completely block while waiting for firefox), which is not very useful. To be able to run applications on startup it is therefore important that we split the application into a separate process and do not wait for it to terminate.

In any case, once #12 is implemented, the number of calls to sleep will hopefully decrease as cagebreak will be able to send notifications when certain events occur.

cheers, project-repo

kinleyd commented 2 years ago

I'm not quite sure what you mean with "sleep does not affect calls to the IPC socket"... The way to wait between commands run through the IPC socket is to first send one command to the socket with nc, then sleep and then send the next command. Or what exactly do you mean? Alternatively, since the -i 1 option causes nc to wait a second between executing the separate lines, running multiple commands in a single nc invocation should have a similar effect.

I stand corrected. The sleep command does block the next IPC call for the duration set. Earlier I thought it hadn't because the order of screens had changed to what wayland-info reports whereas I thought it was in the order 'cagebreak -s' reports.

Glad to hear that you figured out how to do what you were planning to do! About your suggestion of running cagebreak config synchronously, that is unfortunatly not possible: For example, imagine if your cagebreak config would contain exec firefox. Then cagebreak would wait until firefox has terminated before executing the rest of the configuration (actually it would completely block while waiting for firefox), which is not very useful. To be able to run applications on startup it is therefore important that we split the application into a separate process and do not wait for it to terminate.

Yes, of course, that makes perfect sense. Still, there must a way to make the wm's layout commands synchronous while leaving other other apps and processes run asynchronously? I understand that would entail some more work, but in the long run I think it would be a vital step to reduce the complexity for users to get up and running with Cagebreak. My 2c.

Thank you for your time!

project-repo commented 2 years ago

Thanks for your thoughts. Actually, cagebreak commands are already run synchronously, the point is that any call to exec is not blocking, meaning that the next command is executed before the exec command terminates.

I believe that all your layout needs will probably be met with the implementation of #12 (Putting graphical programs on specific monitors inside of specific tiles if I inferred this correctly.). The precise details of the implementation are yet to be determined.

Since the config issue seems to be explained and everything else may be discussed under #12, I am closing this issue.

cheers project-repo