i really wanna rewrite chocobar but im lazy and also its not that bad so here's a quick blogpost while i procrastinate
my first introduction to wayland clients (and hacking on C programs in general) was dtao. it's a frugal statusbar that at its core reads lines of text from stdin and displays them. unfortunately it's incredibly bare-bones (not even half the features of dzen) and it doesn't help that djpohly seems to have disappeared off the internet
made my own fork, mucked around with it, implemented click and scroll support, created a shellscript abomination of a stdin multiplexing framework
for a while i was content with my tags(dwl|awk+wtype|dtao)+status(dsystao(shellscripts)|dtao) statusbar mess solution
...
and then i discovered 9front's bar
excerpt from bar(1):
Bar reacts to mouse clicks by writing the "clicked" portion
of the text (enclosed by the separator) to standard output.
This can be used to perform additional actions by a custom
script.
this was absolutely mindblowing to me
buttons should describe what they do and the different widgets on a statusbar should already be unique (think sound volume vs music player) so it should be simple to separate them out
right?
right??
feast your eyes upon:
while IFS='' read -d '' -r l && IFS=' ' read -r b sy sx; do
case "$l" in
[0-9][0-9]:[0-9][0-9]" "*)
...
;;
'<'[\(X]*[0-9])
...
;;
*[+-=?][0-9]*%* | ' ')
...
;;
esac
done
there's a bit of extra stuff here,
i realized that i really liked being able to scroll
and i didnt like how bar(1) depended on a particular separator character,
so i hacked in ascii null character (\0
) support to delimit segments
when you interact with dbar it prints (null-delimited as well) the segment, mouse button, scrollx, scrolly
the funny read -d ''
stuff parses that
and the cursed case regex guesses which segment the status text is from
in order to handle the appropriate action
this is... hardly optimal, to say the least.
still a step up from dtao spawning a new vol +1
script for each scroll unit,
but dbar had its own problems too
dbar didn't support some of the more advanced features i'd hacked into dtao, namely text colouring and positioning
mostly because i didnt know how to implement them without relying on dtao's funky inline syntax
(also i lost the source code in a /home/ wipe from an accidental unprivileged rm -rf /
, but that's for another story)
unfortunately a certain event left me feeling kinda demotivated
still had the binary and everything worked fine enough so why bother?
so proud of this wordplay - notchoc 15/06/2024
holy shit its been almost a whole month since i started writing this "quick blogpost" - notchoc 08/07/2024
my inspiration for chocobar came hot on the heels of wlsnarf: specifically, the idea of configuring segments via commandline
from wlsnarf's ([-t <mimetype>]... -i <file>)...
cli arg pattern
which i had originally borrowed from ffmpeg's [[infile options] -i infile]...
the initial idea was for it to read from fifos
so something like bar -c <(clock) -r <(batt) can display the output of clock in the center and batt on the right
but i quickly realized that command substitution didn't allow for bidirectional communication (which is the main advantage of splitting i/o into discrete segments) and i didnt feel like making a bunch of named pipes
so i switched to spawning shell commands instead
here's some development screenshots showing off text coloration
and segment aligning
later on i also added inbuilt dropdown menu support (before that you had to listen for mouse hover and print collapsed or expanded accordingly)
chocobar uses ansi vt escape sequences for in-band signalling (think \e[0m
).
it supports... enough... i suppose... not tryna reimplement a full-blown vt state machine no thanks
bludgeoned osc8 into handling button presses too -- technically made redundant by segments + button input but it sure is convenient for when you just wanna spawn stuff and don't care about keeping state
now im finally happy with my bar!
i even managed to hack together a rain world threat layer mixer in an afternoon using shellscript lmk if you wanna learn more, id be happy to share
...
what was i writing about again?
oh right, chocobar kinda sucks
if you dive into the actual code its rather crappy
the default initializer stuff with default_segment is just kinda hacky and it sucks that there's no way to change the defaults (aside from recompiling)
after working on wltouchui (another project in desperate need of a blog post and/or readme) i realized its better to have the parameters come after the objects
so like [-i infile [infile options]]...
instead of [[infile options] -i infile]...
really proud of the system i came up with :D
basically a pointer keeps track of the current object being modified, this pointer initially points at a default object (preconfigured in config.h), so any params passed are assigned to this default object until it hits a "new object" param and the pointer is updated
new objects are created based off the default object and will thus inherit its properties
pretty elegant imo!
chocobar only supports displaying on one output but at least you can choose which
previously i had to wrap chocobar in a hacky script that would watch for outputs and spawn/kill chocobar instances for each output
not sure how i gaslit myself into being content with that :'P
though this one is a little iffy to address cos some segments need to be unique across monitors (think window manager tags and window title)
there's per-segment default fg/bg colors and width but no custom font or height
additionally chocobar puts every segment in the same surface which is kinda annoying since it has to position the contents at render time
it's really ugly
there's a handle_esc function 150 lines long and i am Not Proud of it
actually why not just split all the text stuff into a separate widget program
HMM
so the "statusbar" would effectively just be a window manager of its own
that's actually a really great idea since i can integrate wltouchui with chocobar: just have a joystick widget, a button widget, and some text rendering widgets
heck why not make it nestable! think menus and submenus
finally, i have attained the peak of extensibility??
well shit
there's no wayland protocol that allows for client-managed window positioning (as of 08/07/2024)
i mean it makes sense since most clients dont really have a need for that but was kinda hoping for something like...
wait.
what's this?
nah jk im not going down that rabbithole just yet
so i was browsing the wayland protocols as one does and found this gem
Every client may only have one zone, and can share the zone with trusted other processes by sharing its handle with them. That way, any external process that is contributing a window can create its window in relation to the other windows by sharing the same coordinate system
so clients can share surfaces with other clients and position them! this is EXACTLY what i need
unfortunately its already been 7 MONTHS in the making (jeez, poor matthias)
can't expect it to be merged anytime soon :/ anyw proper compositor support will probably be a while after that
(maybe i could try contributing? see if i can muster the time and courage)
ig ill just refactor chocobar for now and not do anything too fancy
oh whoops just accidentally nuked the vt escape sequence stuff
and replaced it with something even more complex and unusable somehow better oh well (:
(if you wanna do funny tricks like overlapping text, make sure to use my fork of drwl or feel free to complain to sewn about merging this pr :> )
made with <3 and /.gen.sh