[Back to blog]
[Link] tags: C code Linux convenience design
21 June 2018
I've been using Linux for over a decade now, and I find myself always with several terminals open, each with something running in them that I cycle through.
A problem with desktop environments that have a window bar and support alt+tab, is that each terminal has the same icon, and so I have to cycle through all of them, until I get to the correct one.
I've tried solving this by using some terminal software that supports custom background colors, but XFCE changes the window screenshot, in the Alt+Tab window, to grayscale. Also this doesn't help with the XFCE panel.
I had the idea that these should all have distinct icons, with different silhouettes, so that they are easy and quick to recognise. But I figured this would be a good feature for a desktop environment, and that meant a lot of work.
That was until I came across a tool made by Paul Evans ( http://www.leonerd.org.uk ), called xseticon ( http://www.leonerd.org.uk/code/xseticon/ ). The X protocol allows you to change the icon of other X windows, and that is what xseticon does. So all I had to do, was write a program that spawns a new terminal, then looks up the X window that was created for it. This was done by checking the PID of the window, which I got from the _NET_WM_PID atom, with the PID I got from the fork() call. Once I had the window ID, I found the PNG icon I wanted to use for this window, and then I called execv to xseticon, with the window ID and the PNG path. The way I select PNGs, is simply with a global array in the code, and then I create a file in $HOME/.icongiver that stores the previous iterator value. This way it simply iterates through the array, in modulus of the array size.
One weird issue that I never figured out, is that when the program was launched from the XFCE Application Finder, it wouldn't give the terminal an icon. I solved this by creating a script, with a /bin/bash bang that only calls my program. I then copied this script into /usr/local/bin.
I made these icons for myself to use. I'm not trained at this stuff, but it is an enjoyable activity. Mostly I just used the circle select tool in The Gimp, and the bucket tool to fill in color.
This is how it looks on the XFCE panel. The top most icon is what the default is. It's for a terminal that's been running since before I started this project.
And here it is in the Alt+Tab window,
This does not solve the problem entirely, but it does help. And for 2 hours of programming, I expect the effort to have been worth it.
It is only one file of C code, with system dependent variables being #define'd at the top.
Now I want to write about licensing. Of course this program is so simple that any license I put on it is merely symbolic; but I decided to go with GPLv3. And I'm worried where the community is going with MIT licenses, and the like. Worried, but not certain, that it is a very bad thing to do, which only propels the giants and furthers consolidation.
It is weird to think that the GPL wasn't a big part of why the FOSS community exists today. And most tech companies who have adopted open source, have done so because they have had to. This implies that open source has beaten proprietary, in at least some fields. What does it then mean to MIT license your software? To my mind, it means that corporations can freely kick and scream about change, and delay it as much as possible, but then do not have to pay anything when they lose. Because the software was MIT licensed, when the corporation makes the decision that they've lost, they just jump over at no cost and fight again.
I also recognise that the MIT license, and licenses similar to it, can benefit small business because the GPL gets in the way. But if my worry is founded on something, then I don't think the solution is to move to a MIT license. The solution might instead be to have multiple licenses, for different team sizes. However I also see that it isn't that simple, because a large corporation can create a smaller team that gets the MIT licensed version of a FOSS project, but then gives that back to the large corporation.
I realize that I'm hardly adding much to the conversion, but I like to use writing to learn what I think. And I do not have the answer, but I'm also not content with what is currently happening, and so I'd like to link to an article I read that touches on the subject - https://jacobinmag.com/2018/06/github-microsoft-open-source-code-technology
The source code and the icon PNGs can be downloaded here - https://itjac.me/releases/icongiver.tar.bz2
[Link] tags: C code breakout blog
02 June 2018
I have managed to get my breakout clone to draw images into a window, and so I would like to post pictures alongside my blog posts from now on. This meant adding features to my blog software.
There were two major features that I had been excited about implementing. One is images, and the other is tags. I implemented both.
When I was thinking about how to implement image support, I had the idea that I wanted my entire blog to be just one file, and therefore one connection, instead of several connections, one for each image and the blog. I'm not an expert in networking, but I do know about the caravan concept, and I've read some about how connections take time to setup. I also decided this approach, because I've unfortunately had some web development experience, and knew that it was possible to embed image data directly into the img tag, using base64 encoding.
Once I finished implementing the base64 embed, I decided to test it against just linking to a PNG file, and it turns out that there was no speed difference. I'm not used to analysing network speeds, and I just used my browsers dev tools, but it looks like the browser just waits a bunch of milliseconds to draw the embedded base64 image. The way I read it from the "waterfall", is that downloading the HTML data is about the same, but then one version takes a decent amount of time to connect, and download the PNG, while the embedded version just waits for the same amount of time as the connection would have taken.
This is disappointing because with the embedded version, the source of my website becomes much worse to read and people can't download my images, unless they copy them, and paste them into some software like The GIMP.
I have to conclude that I had a bad idea, but I'm going to keep the embedded version, because then the code gets some use and I don't want to make this project a chore. So far it has been a wonderful project that brings result, with almost no effort.
It became clear to me that instead of any complexity, I could just create a file for every tag page. So now I have a tags subdirectory, with a file for each tag, and each file contains the entire HTML necessary to work correctly. This means that everything gets copied however many times is necessary, but I consider it worth the price, when considering the savings on complexity.
It also gave me an exercise in operating on data. I decided that when each tag is parsed, a linked list of tags get searched and when a hit is made, a pointer to the blog entry is added to that node, or a new node gets added. Then when I generate the tag files, I go through the list, create a file based on the name, create a new AST for each entry on that tag node and then I run the exact same AST writing code that creates the full blog on that file.
One other major change I made is to make my parser two step. I do not know if I will keep it this way, but I've really wanted to make a two step parser for some time, and so I just decided to make that an excuse for this one.
[Link] tags: C code design breakout blog
8 May 2018
When I started writing this blog, I immediately wrote a program in C that I call "blog_composer", which in the beginning just iterated through a directory, non-recursively, and combined each file into one HTML file. I copied a quicksort algorithm from Wikipedia, so that the files get ordered before I read from them, meaning that the file with the name that has the smallest value, is the first blog post. Then I just named my files blog001, blog002, etc.
It turns out this was not sufficient, because HTML does not recognise the newline character (\n) as a new line, and so I had to do some parsing. I decided to do the easiest thing, and just replace the \n character, with the br tag. But the br tag is more characters than \n, and my code just read the file into a buffer. I then decided to just put the work in, and write a tokenizer and AST tree.
Fortunately I did it in a short day, because I've done this kind of work before, and so now my code sets a start position, then reads until EOF or it finds \n. It then sets that as an end position, creates a "token", which is just a range in the buffer, and it adds the token to an array, and one token for \n, if it wasn't EOF. It then sets the start position again, and repeats.
Once the entire file is tokenized, I read the tokens and generate nodes for the AST from that.
This worked, and I felt I could write for some time now at least, without it bothering me. But I had URLs in my first post, and it was disapointing that those weren't clickable, so I couldn't stop thinking about improving it immediately after.
A day or two later I'm again at the code, and now I've decided to properly tokenize it. Every word is a token and they get added to an array. Tokens are seperated by whitespace, and then I have a special test for '\n' that adds an extra token for newline, after adding the word. I was a bit worried that the code would get very complicated, because I don't want every token to be an AST node, I instead want one node for a sequence of text, then one node for a new line, then a text node again, etc. Surprisingly, the code for this turned out much more elegant than I had anticipated. I don't know how to describe it without going into detail about the code, which I do not want to do, but what I realized was that a node only has to be added if the token is a known token, e.g. new line, or it is not and we are not currently reading text.
With this code working, I had an easy time adding URL support. I did not want to have to write an URL tag everytime I wrote an URL, instead I wanted the parser to just match "http" and then recognise that the rest of this token is a URL. This works for http links and https, but it also meant that I had to have specific code for URLs, which wasn't too bad.
At this point I had no styling information on my blog, and I didn't want any due to load times. However I came upon this - http://bettermotherfuckingwebsite.com/ - and despite the fact that I consider that website very ugly, which makes their arrogance look laughable, I realized that I'm an outlier and that some of the things written there were true. I get this because I've seen the reactions, and heard the opinions of people around me. Personally I really like https://danluu.com and http://nothings.org
One thing from the "better website" website, I consider a good argument is that people are less inclined to read something, if each sentence is as big as the width of your screen. It feels like you are taking on an arduous task.
However, as I said, I consider their example ugly, and that's mostly because of how little of the width they use. So I decided instead to use something I learned lightly about quite some time ago, the golden ratio. The golden ratio is supposedly the ratio something has to have, compared to the full size, so that humans enjoy looking at it. More importantly it gave me a goal, and so I set out to calculate what it means for my blog. The definition for the golden ratio is (a + b)/a = a / b, and I know that (a + b) = 1, because that's 100%, which is the entire screen. So I solved 1/a = a/b, by observing that b = a^2 solves it, and then I put a + a^2 = 1 into WolframAlpha, and got the two roots. I'm only interested in the positive root, and it turns out it's 0.618... while the golden ratio is 1.618. This means that if (a + b) = 1, then a = (the golden ratio) - 1. Ok, it looks like I way overcomplicated things. But although it looks easy, I can't figure out the easier solution.
The conclusion was that I just went with width = 62%.
I decided to use all the other style information I got from the "better website" website, mostly because I don't want to do this stuff. But I can also see the argument for lighter font colors, because I have been convinced previously about the idea that you want to keep the baseline in a sort of medium, or moderate position. This lets you to make things louder or more silent.
I was convinced about this idea from people on the internet who mix music.