Libui: a portable GUI library for C
github.com
github.com
I suppose all I really wanted to say was that maybe people in general should open their mouths / comment boxes less. (Yeah my comment sucks, doesn't listen to its own advice...)
For example, what might have been an innocent question for one person is actually an annoying nag to somebody else, because they've been answering that sort of question for a long time and have built up an expectation for everyone else to do more research first. The person asking the innocent question doesn't know that they're the hundredth person to ask, so to them the response seems harsh and unkind. Someone observing the exchange from the outside is going to have their own judgments on the quality of the community.
The solution to difficult communication isn't to communicate less, it's generally to communicate more and that doesn't necessarily mean more conversations, because communication can take place in many different ways.
What would help even more is to approach communication with some level of empathy and compassion, and accountability for how you react to those reaching out to you (or those you're reaching out to, of course). If it always seems difficult and sucky then you need to understand why you continue to see it that way, why you get frustrated, and what you can do for your part in that communication to make it more pleasant for yourself. And then make that position clear so there's no misunderstanding of intent.
A large part of communication in those terms, and at the scale we're looking at here, is setting clear boundaries on how you wish to be communicated with and how you'll do your best to respond. It's not useful to act out and complain and moan because nobody can guess what it is you want from them.
It's okay to have that attitude about tutorials, and guides to internals, and other satellite docs, but not core documentation (reference manual or spec).
Have you checked this: https://github.com/andlabs/libui/blob/master/examples/contro... ?
Give me an example over documentation any day.
This is usually how I work. I only look for the documentation when it does not work.
Secondly, exams code can get outdated just as much as human documentation. I've lost count of the number of times I've gone to compile example code only to find it doesn't work because of API changes or such like. I've also had example code crash my whole machine because it effectively created a fork bomb (thanks Microsoft for that one!)
So the arguement of example code Vs documentation isn't a mutually exclusive one.
In fact the main open source project I'm working on automatically generates it's documentation to help ensure its accuracy - and I know for a fact that I'm not the only person to do this.
"I shouldn't be forced to make a contribution to a project" OMG.
Anyways, the whole argument doesn't matter and is totally irrelevant. Serious teams/engineers will analyze the code, consider using it, and then assign developers to help out with documentation if it provides sufficient value proposition. And thus the cycle of OS improvement continues.
Yes, documentation would be nice, but code quality is 100x more important. 100 times out of 100 i'll pick the project with better code quality over better documentation.
BTW, clear, understandable code and APIs is an example of good code quality. And of course, well written unit/integration tests usually provide sufficient example code.
One of the most beautiful C codebases I’ve seen - the SSH IPsec stack - had the most succinct yet comprehensive documentation. Linux kernel has virtually none of the latter but the quality is still very high. Then there’s something like Miranda IM - complete clusterfuck of the code, but really well documented. A lot Java code is that way too, but also with documentation rehashing trivial facts rather than explaining anything.
However, what does seem like a sign of a good code is longer intro comments in header files that explain the design rationale and how things fit together in general. It’s basically a level up from verbose API description, but when done right it makes the API obvious without any further detailing.
In my opinion, good documentation has three parts (four if you include a tutorial too):
First is a document explaining rationale, high level/big picture design, tradeoffs, when to use what. Usually a prose document with some sample code snippets where appropriate. Second, example code showing how to solve different use cases. Finally, an api reference (often auto generated from docstrings).
Different projects need different levels of each of these. For example, a relatively simple library might get away with a few short paragraphs for the prose documentation and maybe the api reference is literally just listing the public functions (if the names and parameter names are descriptive), this can be generated without any additional markup. If the api is complex, then it may need some explanation. Or the text documentation needs to be more detailed.
Obviously I don’t expect this from everyone who release some code online. For small code snippets, I’m happy with a commented example use and appreciative that you released the code at all. However, don’t be surprised if your code doesn’t get used then and if you want me to contribute, then I need to understand your project and without documentation I can’t do that. If I don’t understand your project, I risk that any PR I do is wasted effort and my time is limited (but I’ll happily help projects I use out regardless, where I can. I may need some guidance though)
The C API documentation includes a ton of example code: https://ffmpeg.org/doxygen/4.0/dir_687bdf86e8e626c2168c3a2d1...
In addition to having both a man page and a --help option, The FFmpeg CLI tool has very thorough documentation: https://ffmpeg.org/ffmpeg.html
I don't understand how FFmpeg could in any way be considered to have no documentation and no code samples.
Documentation is so important if you want to get people interested in your project. Personally, I value good documentation above features because without documentation I may never learn how to use your features and may never get started using the project. If I never use your project then there’s zero chance that I will contribute. Or, like above, I do, but run out of steam really quickly and lose interest.
By reading the code? You're posing it as some kind of impossible paradox, but with the full source code available you have a pretty readable specification of how it works.
Don’t get me wrong, I’m talking extremes here and I don’t expect a lot from someone’s passion project in terms of documentation effort, just a little helping hand if you want me to have a good experience (which is a prerequisite for me to care enough to contribute).
I agree - the high level design and stuff is hard. But being a user and having the code allows you to document
1. Function level documentation including inputs, outputs. Even if you don’t understand how it fits in to the bigger picture.
2. Provide examples of working code (recipes) with some explanation of what it does.
The question wasn't "is it harder to figure out what the code does by reading it than reading well written documentation?", it was "how can you submit a pull request for documentation when there’s no documentation for you to understand the code with", and the obvious answer is: by reading the code—in fact, that's ongoing work by some of the project's contributors.
If you don't have time for that, its not the problem of the authors.
That said, were this a commercially driven enterprise, the lack of documentation is an issue. But, true fact, most open source projects can immediately benefit from the involvement of someone, anyone, willing to update the docs .. so, be a hero: submit a PR, someone.
People that know C should be able to read and understand the interface file at:
https://github.com/andlabs/libui/blob/master/ui.h
The function / variable names are informative enough. There are examples which should get you started at:
https://github.com/andlabs/libui/tree/master/examples
Even if they would add comments to the interface files (that may be used to generate docs), it will not add much value if it will become as follows:
// Set window title. First argument should be the window and the second the title as a string
uiWindowSetTitle(uiWindow *w, const char *title);
What I think is more important is adding tests etc. Tests can then also serve as a kind of documentation.They would have to be written with documentation in mind, which distracts them from their primary purpose: catching bugs. Trying to understand Monocypher from just its test suite¹ for instance would be a pretty bad idea. That test suite is top notch at catching bugs, but it sucks big time at documenting Monocypher.
https://github.com/LoupVaillant/Monocypher/blob/master/tests...
I agree with your point about reading the signals of which projects are probably the best.
But with great power comes great responsibility. It's entirely possible YOU are the person who makes this project great, just by the Butterfly Effect of getting the documentation good enough that the next person who comes along will be willing to choose this and push a little harder, and so on.
You're not forced. You're not obligated.
But if you show up, you get to make decisions.
That's not true with documentation. the decision has already been made. if you show up later and write the docs then you're just hoping you interpreted the decision correctly and aren't misleading people.
If there wasn't an intentional design decision, then who knows if the behavior you try to document lasts beyond the current version, who knows how quickly that documentation is out of date. (Likely if a project doesn't care about documentation before you arrive, they might not likely care about stale documentation either.)
I think that it's better to be clear about it. I'd find it rude if someone said "thanks for your feedback" without intending to seriously evaluate or address it. If submitting pull requests is the best way to get work done in a project, its maintainers should be clear about it.
You have no obligation to contribute to the project, but if you think it is lacking in some respects, making your own contribution is the most obvious way forward. So you give some constructive criticism, and the response is a suggestion for a way to address it. No one is telling you that you are obligated to contribute, and no one is calling you out. You want work done and you aren't compensating anyone for doing it, so the only way the work will ever be made is if some actual contributors' interests happen to align with yours, if you become a contributor yourself or if someone is willing to work for you without compensation.
As it stands with this library, there is an open master issue to improve the documentation. The author has acknowledged the problem and is accepting pull requests to improve it. The general advice to improve the documentation is at this point is not adding any information to the contributors of the project, because now it's only a matter of actually documenting the issues in the github ticket system and for people to put in the work. The suggestion to make a contribution yourself makes even more sense given this context.
> I shouldn't be forced to make a contribution to a project if I just don't think it's doing everything right.
You use the words "obligation" and "force" very loosely throughout your post. It's not adding to your point that you blatantly misrepresent the suggestion to contribute the work that you want to see put into an open source project as some sort of coercion or shaming.
One of the ways it can be done is to start independent documentation effort, without even considering to merge it to project repository. Then, having these "draft" docs, it will be easier to make "official" documentation. Even blog posts "how to get started with libui" can be useful. This project looks very promising, like WXWidgets, but in C and not C++, for this reason it has lots of language bindings already.
If you don't already feel the project has value, I doubt the availability of documentation would sway you.
>I shouldn't be forced to make a contribution to a project if I just don't think it's doing everything right.
You're not being forced to do anything. We're just saying different people have different priorities: what's important to you might not be important to other people. Who knows? Maybe the programmer thought the header file was sufficient. It might very well be more than enough for his own needs. Instead of saying "somebody should write detailed documentation", people expect that you will be that somebody, since you're the one who raised the issue.
Other projects building on andlabs/ui and https://github.com/parro-it/libui-node:
It allows to build the whole UI using HTML, CSS and JS and leverage it with all the tooling and libraries already built for the web.
So OK maybe I can get some insight reading the code. The "common" folder seems a good place to start[2]. Um, no. Short, generic uninformative filenames ("matrix.c", "control.c") and very few introductory comments. The opposite of "literate programming".
Your hostility toward an MIT licensed project is what is ruining the open-contribution model of developing software. In 2005, it was "Hey, this looks great, want me to write up a documentation?" Now it's "Not up to my standards, it's a joke." Absolutely disgusting behavior that is becoming gradually more common.
_UI_EXTERN const char *uiInit(uiInitOptions *options);
uiInitOptions is a struct that contains a single size_t Size. What's it the size of? Can I pass a NULL pointer? Does this function take ownership of the pointer, and if so, does it need to be allocated with malloc? If not, when can I free it - can I use a pointer onto my stack? Why does it take a non-const pointer - does the size (of whatever) change? What's the string that's returned? What's the lifetime of the string that's returned? Can another thread call uiInit, or does that break everything horribly? Or does it only break horribly if you don't copy the returned string first?You don't need documentation, sure. But it's a good way to get users of the library that make wild assumptions so that you can no longer make reasonable upgrades to the library without breaking them, and that makes nobody (neither the library author, who wants people to use it, nor the users themselves, nor end users) happy.
With regards to your last paragraph, a common misconception is that a "payment" of open-source software is number of users. That would be true for proprietary software where payment = number of users * price, but for open-source software the developers couldn't care less (except maybe superficially, but this mental reward is insignificant for the long-term motivation for a project). They want to make a library that solves their own problems and is stable. They allow people to help improve the library in exchange for releasing it for their unrestricted use. Otherwise, there is little motivation to release it. When I find a new library that solves a problem in an interesting way, I learn using whatever is available (existing documentation, headers, source, and examples) and write down the difficult parts. The price I pay for using the software is to send my notes back to the developers in a polished, organized form that is consistent with their existing documentation. Then, no one needs to repeat what I've done in the future.
Not to mention that the developers that wrote the project in the first place are in a much better position to write documentation than anyone else (in the past I've had to review documentation from external contributors and I'm pretty sure it would've been phenomenally faster if I'd just written it in the first place -- it isn't their fault, it's just that I know the code and its history much better than them because I've maintained it).
Your second point is a good one, but the developers are in a better position to write actual features and fix bugs than anyone else, and since documentation is more public-facing than source code, it's actually a better choice if someone wants to contribute anything at all, so the primary developers can spend their time more wisely. I certainly know the "phenomenally faster if I'd just written it in the first place" effect well, which is why I recommend to contributers to not do drive-by contributions but spend a good week writing notes while they use the library, and then convert to high-quality documentation, effectively adopting a section like you would with a community garden. Quality over quantity. And if the documentation attempt is low quality, it's still a much nicer way to prod the developer to write some documentation, so he/she can use it to define their quality standards or as a possible outline.
Was it, really? I think the parent comments did a good job at pointing out a potential, actionable, flaw in this project. That doesn't mean that they should be "scolded" for pointing it out or that they themselves need to fix it.
Open source contribution happens when the contributor has invested themself in the project and wants to maintain the relationship. Perhaps the requester is evaluating multiple packages and wants to inform the project why they're going with another one instead. Maybe they got to the point in their evaluation that they're ready to commit only to discover a critical issue hidden in the (lack of) documentation.
It also comes off as hostile since implies that the requester's time is less valuable than the project maintainer's. Perhaps the requester is busy contributing to other open source projects. Perhaps the requester only has time right now to use the software, but has the goal of contributing in the future.
The project's maintainer's responsibility is maintaining the software, presumably because of some personal interest. Reporting and even expecting them to fix issues is absolutely normal.
It is. In large projects, there are relatively few maintainers responsible for evaluating the requests, reports and code from lots of people. They're scarce resources.
https://www.youtube.com/watch?v=fMeH7wqOwXA https://www.slideshare.net/linaroorg/maintainer
The main benefit is that it forces one to try to be professional and consistent, and to avoid being flippant, cryptic, didactic, and condescending.
Keep in mind that cutting customers loose is a natural part of the game, too. If someone demands to get a Big Mac at Chipotle there's no law that says they get to block the line for eternity.
geofft doesn't have an "issue" because he's not using the library; he can avoid the non-documentation problem for himself quite adequately by ignoring the library and moving to a different one.
> If you can answer those questions,
No you can't. You can only reverse engineer what the code does, not what the programmer intended.
Why would I sit there reverse engineering someone's code to write a document for them which codifies the bugs they didn't intend to make? They will just reject the doc "oh, thanks for writing this but that's not what's supposed to happen; that's a bug. Can you wait until next release and then change your document based on the new code? Thanks.".
Fuck that, you know?
Will the designer even take the document seriously going forward? Or will he just regard that as someone else's unimportant opinion about what a particular revision of his program did once upon a time?
We already know something about the designer's attitude is toward documentation, from the lack of it.
Satellite documentation: different story. I mean, tutorials, guides to internals and things like that. But, no, I'm not writing the basic, fundamental spec for your undocumented code you've already written.
I agree with this position. I am also working on my own open-source projects, as well as other projects that I know have conscientious maintainers and a high-quality community. Why should I contribute my time to this project?
To be a little blunt: if this project has not thought about things like ownership of pointers and concurrency safety, it is not a project I think other people should use. My time is limited, and I use it on improving projects that I think are worth improving.
> for open-source software the developers couldn't care less (except maybe superficially, but this mental reward is insignificant for the long-term motivation for a project). They want to make a library that solves their own problems and is stable.
As an open-source maintainer, this doesn't describe me at all. I care more about things that improve the world than things that amuse me. (I also work on a few things that amuse me, but they're relatively clear about that status, and f they're not, I welcome someone calling me out on it.) All the long-term projects I work on are motivated by wanting that project to be a healthy project available as a compelling option for as many people as possible.
I had the rather delightful experience of starting a new job recently and finding that the next team over had just decided to start using a project I've been maintaining for a few years. If I had not spent time writing both code and documentation that welcomed unknown future users, this would never have happened. (And I still have not written nearly enough documentation for it!)
If my motivation were just filling my own needs, I probably wouldn't publish software at all. If it were that plus bolstering my personal brand, it would go on my blog or as CC-BY-NC-ND or something. My entire motivation for releasing software under a free license is for other people to use it.
This is a bit extreme. My first thoughts (honestly) is yes, what is the size of. Following their advice to follow their examples, I looked at examples and it literally just zeros a uiInitOptions on the stack and sends it in. Thus I think it's something I wouldn't really need to care about usually.
As for whether I need to worry about saving 8 bytes on the stack or elsewhere, that seems like such a rare question (amongst the questions people would have) that it would motivate digging a little bit. It took me probably 3 minutes to find the answer[0].
As someone said above, this is one cat's work in their free time. The gratuitous criticism is very unfair to them especially when you're worried about out circumstances most devs wouldn't have to deal with or care about.
[0] https://github.com/andlabs/libui/blob/master/unix/main.c#L11
I mean, yes, I can probably guess some things and end up with something that works with the current version of the library, but why would I choose this library to build on top of if I'm just guessing?
The code cannot possibly answer the question of what changes the developers may make to the project in releases they consider backwards-compatible. My question is entirely about the API, not about the code itself.
Hobby or personal-interest projects with an expectation of no real use don't need externally-facing documentation because they have no externally-facing APIs at all, not because their APIs are obvious.
I work on several personal projects whenever I have free time and feel like programming. I keep them on private repositories because I don't think they are ready for publication. I'm not sure if they're ever gonna be ready.
The only issue I see with the parent comment is that it's a bit harsh. But it's good advice to someone "trying to get better at their craft": writing software, especially one intended to be used by others, without documentation, is generally poor practice. It's not entitled at all, as far as I can see: it's not saying "I should have documentation for this project I use for free"–as far as I'm aware, they're not even using it at all. They're just evaluating whether as an interesting project they might want to take a look at later.
Let's just stay realistic: this guy is not selling a product, he's coding up something out of his own interest and is showing it to the world on github. I'm sure his interest in coding this up is much greater than his interest in writing documentation, so why should he focus on the latter? "So that anybody else can use his stuff" comes to mind as a first answer, and that's fair enough. But maybe that hasn't been his foremost interest.
One aspect that I see here is that with all the different language bindings, we're not talking about a documentation that would be trivial to write. I could imagine that an effort like that requires a lot of subtle changes to the API as more functionality is added which makes keeping the documentation up-to-date a tedious and quite hard thing to do -- so something that isn't a lot of fun. And isn't fun the main reason hobby projects get started on github in the first place?
I see your point that the current state of the project makes it very hard to use for you. Fair enough. But maybe it can become interesting again in the future when more documentation has been added -- perhaps even though the help of others. After all, it's an open source project.
void uiGridInsertAt(uiGrid *g, uiControl *c, uiControl *existing, uiAt at, int xspan, int yspan, int hexpand, uiAlign halign, int vexpand, uiAlign valign);
The overall feeling is that it’s a [small] subset of GTK. I think they try to fill an empty cross-platform niche between lightweight and native-looking Tk and heavies like GTK and Qt. Doc could explain how is that better than Tk itself, but it has to be written. The other possibility is that they do it for fun and distinctive use cases are shallow – this is often seen in second order ui kits.As for documentation, that is an active WIP. I have recently pinned down a documentation style I like, and applied it to the newest APIs; all that's left to do really is to spread it to the older APIs as well, and write a tool to turn that documentation into HTML, because I have not found a documentation tool that operates how I want it to.
At my most recent stint in a software company once of the most frequently heard retorts about absent documentation was "the code IS the documentation".
Yet often these same people were the first to complain when another developer or operations staff hadn't documented something and they'd got themselves into a pickle trying to guess what was going on rather than read the code themselves.
Often the people most vocal about documentation are the worst at preparing it themselves in my experience, a form of projection onto others. YMMV.
Higher level docs would be nice though, goals and non-goals, high level feature roadmap etc.
For example a cursory reading of the code suggests that there is no a11y support, which is a deal breaker for some projects and not so important for others, it would be nice to know where that sits on the roadmap
What have people not yet figured out about cross-platform graphics? If we knew exactly what was wrong, we could fix it...
---
g->children = new std::vector<struct gridChild *>;
g->indexof = new std::map<uiControl *, size_t>;
At least needless level of indirection ...https://github.com/andlabs/libui/blob/master/windows/grid.cp...
- accessibility
- localization
- text rendering
- input methods
- widget toolkit
- event loop
- HIG
The document should also contain example code for something basic for every platform. All this information could be then used to create the Right Thing Toolkit.
Probably it should aim for the future. So only include APIs that most probably would not be deprecated in 5 years. The platforms that I'm thinking about: Android, Freedesktop/Unix-like, iOS, macOS and Windows.
I was wondering what is current situation with Windows. Is UWP the future or will it be soon replaced by yet another API? Is side-loading currently as effortless as running of Win32 apps? Or maybe Win32 is good enough, because they will always support it?
[0] as opposed to the Worse is Better, because that's current situation and it's not all that hard, use SDL or whatever and draw everything yourself.
> Now that libui is separate, package ui has become a binding to libui.
> As such, package ui is the only official binding.
From the README — https://github.com/andlabs/libui#language-bindings
I like the toga project in python : https://pybee.org/project/projects/libraries/toga/
Tkinter is terribly integrated and QT hard to install so toga hits a sweet spot. But it's very immature.
My favorite toolkit is still wx, however it just reached V3 compat so it's considered unstable. You can pip install it (well, linux support is so so yet) and all the UI looks native, including the file dialogs.
The library (GTK) feels the same in every language, whether it's C, Python, Go, etc.
I admit, it can be a hassle to get the library up and running, but once you do that, it is surprisingly simple to code in.
I wouldn't say it looks like garbage, but if you want a more native look and feel you could certainly set it up in the settings.
(For example: you could look at https://stackoverflow.com/questions/37035936/how-to-get-nati... )
As a library purely coded in C, I still believe that GTK and GNOME lay a solid foundation for easy development in C.
Before downvoting you might want to give GTK another chance. Even this libui library uses GTK under the hood for linux.
Even electron apps don't try to reinvent this one and pop the OS widget.
I did something a little similar about 20 years ago in my two McGraw Hill books Portable GUI in C++. But Libui looks very much better.
It should be set to prototype by default.
Clearly it must not be a problem, I just don't understand how people work around it.
Interesting but since GTK+ itself is cross-platforms it feels a bit heavy to wrap it.
Only in theory. It does not look and behave even close to native anywhere except on GNOME 3 with default settings.
If yes, then you can check these two [1][2].
Can you tell the difference? https://3.bp.blogspot.com/-O1Naap_IGVQ/VGJsRBEfQjI/AAAAAAAAA...
Electron also has LGPL dependencies (Blink, FFMPEG) and libui depends on GTK which is also under LGPL so...