Closed andrew-grechkin closed 2 years ago
Subscribing to events in FIFO is convenient if it's necessary to process them.
Not really...
Most times, you can just pipe the output of bspc subscribe
to your program:
#!/bin/sh --
bspc subscribe report | some_program
# or
#bspc subsribe node_add | some_program
# or...
bspc subscribe
is the same as bspc subscribe report
, but it's not documented.You would only need to use --fifo
if you need a named pipe because you need to pass that pipe to a program as an argument; e.g.:
#!/bin/sh --
some_program --events-from-file "$(bspc subscribe --fifo node_add)"
Or if you need to pass multiple of these pipes to a scripts, or if you need to pass these pipes to a script that needs stdin for something else:
#!/bin/sh --
my_script \
--bspwm-pipe "$(bspc subscribe --fifo report)" \
--some-other-pipe /path/to/some/pipe
#!/bin/sh --
cd -- ~/pix || exit
find . -type f -name '*.png' '!' -path '*
*' | my_script "$(bspc subscribe --fifo desktop_focus)"
This is quite a niche use case.
But even in this case, I would suggest to use something like this instead to create the named pipe:
#!/bin/sh --
bspwmpipepath=/tmp/my_script_tmppipe
clockpipepath=/tmp/my_script_tmppipe
trap 'rm -f -- "$bspwmpipepath" "$clockpipepath"' EXIT
mkfifo -- "$bspwmpipepath" "$clockpipepath" || exit
bspc subscribe report > "$bspwmpipepath" &
clock -s > "$clockpipepath" &
my_script --bspwm-pipe "$bspwmpipepath" --clock-pipe "$clockpipepath"
clock
from baskerville/sutilsIf you have bash
, you can simply use process substitution:
#!/bin/bash --
my_script --bspwm-pipe <(bspc subscribe report) --clock-pipe <(clock -s)
bspc subscribe --fifo
may be nice so you don't have to create a named pipe yourself with mkfifo
that you will then have to delete.
But in bash
with <()
, you don't have to worry about that since bash
will delete the named pipe automatically, that is if an actual named pipe is created at all since, on linux at least, bash
will just use linux's procfs's named pipes.
bspc subscribe --fifo
is quite terrible since bspwm
will hang until the named pipe at the path it outputted is not opened for reading; any mouse click will not be handled, all your bspc
commands (so also your sxhkd
hotkeys that use bspc
commands) will just hang, &c until the pipe is finally opened by some process and they will be handled and executed at once.
You can try by running bspc subscribe --fifo
in a terminal and then clicking around, nothing will work, until you run cat /path/to/that/file
(you can use the same terminal) and all the clicks will be handled at once (in order).
That is the reason why using $(bspc subscribe --fifo)
more than once without opening the file at the path returned by the first one will cause a deadlock; e.g.:
#!/bin/sh --
some_program -- "$(bspc subscribe --fifo report)" "$(bspc subscribe --fifo report)"
The second bspc subscribe --fifo
will hang since bspwm
can't respond to it, because it is hanging waiting for the named pipe at the path returned by the first bspc subscribe --fifo
to be opened, which can't be done by some_program
since the shell didn't start it yet, because the second bspc subscribe --fifo
is hanging.
Process substitution and bspc subscribe > pipe &; ... pipe
don't cause bspwm
to hang:
#!/bin/bash --
some_program <(bspc subscribe report) <(bspc subscribe report)
# or
##!/bin/sh --
#trap 'rm -f pipe1 pipe2' EXIT
#mkfifo pipe1 pipe2 || exit
#bspc subscribe report > pipe1 &
#bspc subscribe report > pipe2 &
#some_program pipe1 pipe2
And if you run someprogramyoudontcontrol --pipe "$(bspc subscribe --fifo)"
you have to hope that program will open the pipe that soon enough and that it will open it at all instead of printing Invalid option: '--piep'
and hiding from you the path that you now have to open to fix bspwm
being hung. (you can probably use ls /run/user/"$UID"
to figure out what pipe you need to open in this case.)
I suggest to avoid subscribe --fifo
(use it only if you actually need to create a direct pipe with bspwm
(for some reason?)) since there better options that don't hang bspwm
(indirect pipe connected to the output of bspc subscribe
that receives data from bspwm
through a UNIX socket), and a named pipe is rarely needed anyway as I said at the beginning.
I'm trying to understand the events format and doing the simple test:
You can just read the manual, it is documented quite well there (except for not specifying what T
, and M
; S
, P
, L
, and M
; and T
, P
, F
, =
, and @
mean, but you can easily figure those out):
REPORT FORMAT Each report event message is composed of items separated by colons. Each item has the form <type><value> where <type> is the first character of the item. M<monitor_name> Focused monitor. m<monitor_name> Unfocused monitor. O<desktop_name> Occupied focused desktop. o<desktop_name> Occupied unfocused desktop. F<desktop_name> Free focused desktop. f<desktop_name> Free unfocused desktop. U<desktop_name> Urgent focused desktop. u<desktop_name> Urgent unfocused desktop. L(T|M) Layout of the focused desktop of a monitor. T(T|P|F|=|@) State of the focused node of a focused desktop. G(S?P?L?M?) Active flags of the focused node of a focused desktop.
- readable online here
I see the events are sent but all of them are equal. Doesn't matter what i'm doing: adding node, removing or just focus.
As bspc subscribe report
is implemented now. bspwm
will sending a report string anytime any event happens that could change it (node_focus
, desktop_focus
, desktop_add
, etc.) occurs even if the report string didn't actually change.
All the events that bspwm
reports are listed in the manual (readable online here), you can experiment with them by running bspc subscribe all
in a terminal (you are not using --fifo
so don't worry ;)
) and then clicking and moving things around.
As you can tell from the description above quoted from the manual, the string did not change because you were only clicking on other tiled windows with no flags set in the same desktop.
If, for example, you had clicked on a floating window (with no flags set) or changed the state of the focused window to floating
, it would have been slightly different:
WMeDP-1:f1:f2:f3:f4:f5:f6:f7:f8:f9:O0:LT:TF:G
Or, if you had focused desktop 2:
# if it is a desktop in tiled layout
WMeDP-1:f1:F2:f3:f4:f5:f6:f7:f8:f9:o0:LT
# if it is a desktop in monocle layout
WMeDP-1:f1:F2:f3:f4:f5:f6:f7:f8:f9:o0:LM
thanks a lot @emanuele6 for the explanation now it's clear that subscribe --fifo is not what I have anticipated
Subscribing to events in FIFO is convenient if it's necessary to process them.
I'm trying to understand the events format and doing the simple test:
I see the events are sent but all of them are equal. Doesn't matter what i'm doing: adding node, removing or just focus. Is there anything I'm doing wrong or subscribe --fifo has issues?