rewriting chocobar

i really wanna rewrite chocobar but im lazy and also its not that bad so here's a quick blogpost while i procrastinate

a little bit of history

dtao

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

the birth of dbar

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?

when frustration glooms, motivation strikes

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]...

chocobar

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 screenshot of chocobar interpreting ansi colour escape sequences to display different segments with coloured text

and segment aligning screenshot of chocobar with aligned segments

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! screenshot of chocobar with tags, window title, music, volume, cpu & memory bars, date, menu

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

hindsight is 20/20

if you dive into the actual code its rather crappy

argv parsing

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!

multi-output support

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)

per-segment stuff

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

vt escape sequence compatibility

it's really ugly

there's a handle_esc function 150 lines long and i am Not Proud of it

plans

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??

in which my ambitions severely underestimate existing wayland protocols

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?

arcan

nah jk im not going down that rabbithole just yet

EXT-ZONES WOOHOO

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)

oh well

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 (:

check out the code here!

(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