GtkSourceView fundraising – September/October report

I’ve launched two months ago a fundraising for the GtkSourceView library. I intend to write a report every two months, so that you can follow what’s going on in that project, and at the same occasion I can explain in more details some facets of the fundraising.

Only one maintainer (me)

For most of the code in GtkSourceView, there is basically only one remaining maintainer: myself. Tobias Schönberg helps to maintain and review some *.lang files (for the support of syntax highlighting), especially in the area of web development. But that’s it.

Here are the top 5 contributors, in terms of number of commits:

$ git shortlog -sn | head -5
1372 Sébastien Wilmet
531 Paolo Borelli
289 Ignacio Casal Quinteiro
200 Jesse van den Kieboom
149 Yevgen Muntyan

So you can see that I’m the first contributor. All the other developers also contributed during their free time, and they don’t have enough free time anymore (they have an unrelated full-time job, etc).

So in some way, the future of GtkSourceView rests in my hands.

File loading and saving

These past weeks my focus was on file loading and saving in Tepl (the incubator for GtkSourceView).

There are several layers for the file loading and saving:

  • The backend/toolkit part, i.e. the low-level API, it’s what I’ve added to GtkSourceView in 2014 but needs improvements.
  • The high-level API taking care of the frontend, part of the Tepl framework.
  • Some features that are built on top of the high-level API, for example an action to save all documents, or the auto-save to automatically save a document periodically.

For the first layer, the backend/toolkit part, Tepl provides two new things: file metadata (for example to save the cursor position) and a new file loader based on uchardet, to improve the character encoding auto-detection. This past month I’ve improved the new file loader, it is now in a good enough shape for most applications (but still lacks some features compared to the old file loader, so some work is still needed to be able to deprecate the old implementation).

For the second layer, I’ve started to create the high-level API. Creating the API is not the most difficult, the bulk of the work will be to improve what the implementation does internally (creating infobars, handling errors, etc).

The third layer has not yet started.

File loading and saving was not the only thing that I did these past two months, a lot of other smaller things have been done, for more details see the NEWS files:


Even if GtkSourceView already provides a lot of features, it is far from sufficient to create even a basic text editor (to have an implementation of a good quality). To give a concrete example, the core of gedit – if we remove all the plugins – is currently made of 40.000 lines of code! It’s a lot of work for a developer who wants to create a specialized text editor or a new IDE.

So my goal with GtkSourceView and Tepl is to make more code re-usable.

See the GtkSourceView fundraising on Liberapay. Thanks for your support!

GtkSourceView fundraising!

I’m launching a fundraising for GtkSourceView!

If you don’t know what GtkSourceView is, it’s a widely used library for text editors and IDEs (or text editing in general). For example on Debian, more than 50 applications rely on GtkSourceView, including gedit and GNOME Builder.

What less people know about is that GtkSourceView has been almost entirely developed by volunteer work, without being paid, except a few Google Summer of Code. So with the fundraising it’ll hopefully change, to bring the library to the next level!

Go to the fundraising on Liberapay for more information.


GObject design pattern: attached class extension

I wanted to share one recurrent API design that I’ve implemented several times and that I’ve found useful. I’ve coined it “attached class extension”. It is not a complete description like the design patterns documented in the Gang of Four book (I didn’t want to write 10 pages on the subject), it is more a draft. Also the most difficult is to come up with good names, so comments welcome 😉


Adding a GObject property or signal to an existing class, but modifying that class is not possible (because it is part of another module), and creating a subclass is not desirable.

Also Unknown As

“One-to-one class extension”, or simply “class extension”, or “extending class”, or “Siamese class”.


First example: in the gspell library, we would like to extend the GtkTextView class to add spell-checking. We need to create a boolean property to enable/disable the feature. Subclassing GtkTextView is not desirable because the GtkSourceView library already has a subclass (and it should be possible in an application to use both GtkSourceView and gspell at the same time ((Why not implementing spell-checking in GtkSourceView then? Because gspell also supports GtkEntry.)) ).

Before describing the “attached class extension” design pattern, another solution is described, to have some contrast and thus to better understand the design pattern.

Since subclassing is not desirable in our case, as always with Object-Oriented Programming: composition to the rescue! A possible solution is to create a direct subclass of GObject that takes by composition a GtkTextView reference (with a construct-only property). But this has a small disadvantage: the application needs to create and store an additional object. One example in the wild of such pattern is the GtkSourceSearchContext class which takes a GtkSourceBuffer reference to extend it with search capability. Note that there is a one-to-many relationship between GtkSourceBuffer and GtkSourceSearchContext, since it is possible to create several SearchContext instances for the same Buffer. And note that the application needs to store both the Buffer and the SearchContext objects. This pattern could be named “one-to-many class extension”, or “detached class extension”.

The solution with the “attached class extension” or “one-to-one class extension” design pattern also uses composition, but in the reverse direction: see the implementation of the gspell_text_view_get_from_gtk_text_view() function, it speaks for itself. It uses g_object_get_data() and g_object_set_data_full(), to store the GspellTextView object in the GtkTextView. So the GtkTextView object has a strong reference to the GspellTextView; when the GtkTextView is destroyed, so is the GspellTextView. The nice thing with this design pattern is that an application wanting to enable spell-checking doesn’t need to store any additional object, the application has normally already a reference to the GtkTextView, so, by extension, it has also access to the GspellTextView. With this implementation, GtkTextView can store only one GspellTextView, so it is a one-to-one relationship.

Other Examples

I’ve applied this design pattern several other times in gspell, Amtk and Tepl. To give a few other examples:

  • GspellEntry: adding spell-checking to GtkEntry. GspellEntry is not a subclass of GtkEntry because there is already GtkSearchEntry.
  • AmtkMenuShell that extends GtkMenuShell to add convenience signals. GtkMenuShell is the abstract class to derive the GtkMenu and GtkMenuBar subclasses. The convenience signals must work with any GtkMenuShell subclass.
  • AmtkApplicationWindow, an extension of GtkApplicationWindow to add a statusbar property. Subclassing GtkApplicationWindow in a library is not desirable, because several libraries might want to extend GtkApplicationWindow and an application needs to be able to use all those extensions at the same time (the same applies to GtkApplication).

Amtk – Actions, Menus and Toolbars Kit for GTK+

GtkUIManager has been deprecated without a good replacement for applications that want to keep a traditional UI (with a menubar, toolbar and statusbar). So I’ve written a new shared library called Amtk, currently developed inside the Tepl repository. It is a basic GtkUIManager replacement based on GAction. If you are interested, read the Amtk introduction (it explains the problems with what GTK+ currently provides and that Amtk solves) and the API reference.

Note that the library is not yet finished, factory functions are missing, release early release often etc. But I think that what remains to be done is not a lot of work (for my needs at least).

Gtef library renamed to Tepl – Text editor product line

Gtef (GTK+ text editor framework) has been renamed to Tepl (Text editor product line). The end of Tepl is pronounced like in “apple”.

I didn’t really like the name Gtef. And since the project is still young, it was easy to rename everything.

I’ve also written a more complete introduction.

The name “Text editor product line” was inspired by this book: Feature-Oriented Software Product Lines. It’s an interesting book, I’m learning new things, like the difference between a white-box framework and a black-box framework, or cross-cutting concerns (and how to better handle them), etc.

New chapter in my GLib/GTK+ getting started guide




Good learning 😉

gspell maintenance

The gspell bug tracker is perfect again, there are only feature requests (marked as enhancements).

I’ve fixed two bugs recently, the second one was not that easy to fix:

  • One crash (a failed assertion) probably due to a bug in an underlying library.
  • A responsiveness problem when editing long lines. It turned out that the spell-checking code for GtkTextView was very slow (200 ms to re-check the long line). So I’ve written a new implementation, which is 20x faster! So with 10 ms it’s now responsive.

And I regularly do other various maintenance tasks in gspell, as can be seen in the Git repository.

gspell is now used by at least 6 applications (see the list on the wiki page), and with both GtkTextView and GtkEntry support I’m sure a lot more applications will use it in the future.

If you like the work I’m doing, the gspell fundraising is still open. Your donations encourage me to continue to take care of gspell, to make it a rock-solid library and well-maintained in the long term. Thanks!

Gtef 2.0 – GTK+ Text Editor Framework


The main goal of Gtef is to ease the development of text editors and IDEs based on GTK+ and GtkSourceView, by providing a higher-level API.

Some background information is written on the wiki:

In this blog post I’ll explain in more details some aspects of Gtef: why a new library was needed, why calling it a framework, and one feature that I worked on during this cycle (a new file loader). There are more stuff already in the pipeline and will maybe be covered by future blog posts, stay tuned (and see the roadmap) 😉

Iterative API design + stability guarantees

In Gtef, I want to be able to break the API at any time. Because API design is hard, it needs an iterative process. Sometimes we see possible improvements several years later. But application developers want a stable API. So the solution is simple: bumping the major version each time an API break is desirable, every 6 months if needed! Gtef 1.0 and Gtef 2.0 are parallel-installable, so an application depending on Gtef 1.0 still compiles fine.

Gtef is a small library, so it’s not a problem if there are e.g. 5 different gtef *.so loaded in memory at the same time. For a library like GTK+, releasing a new major version every 6 months would be more problematic for memory consumption and application startup time.

A concrete benefit of being able to break the API at any time: a contributor (David Rabel) wanted to implement code folding. In GtkSourceView there are several old branches for code folding, but nothing was merged because it was incomplete. In Gtef it is not a problem to merge the first iteration of a class. So even if the code folding API is not finished, there has been at least some progress: two classes have been merged in Gtef. The code will be maintained instead of bit-rotting in a branch. Unfortunately David Rabel doesn’t have the time anymore to continue contributing, but in the future if someone wants to implement code folding, the first steps are already done!


Gtef is the acronym for “GTK+ Text Editor Framework”, but the framework part is not yet finished. The idea is to provide the main application architecture for text editors and IDEs: a GtkApplication on top, containing GtkApplicationWindow’s, containing a GtkNotebook, containing tabs (GtkGrid’s), with each tab containing a GtkSourceView widget. If you look at the current Gtef API, there is only one missing subclass: GtkNotebook. So the core of the framework is almost done, I hope to finish it for GNOME 3.26. I’ll probably make the GtkNotebook part optional (if a text editor prefers only one GtkSourceView per window) or replacable by something else (e.g. a GtkStack plus GtkStackSwitcher). Let’s see what I’ll come up with.

Of course once the core of the framework is finished, to be more useful it’ll need an implementation for common features: file loading and saving, search and replace, etc. With the framework in place, it’ll be possible to offer a much higher-level API for those features than what is currently available in GtkSourceView.

Also, it’s interesting to note that there is a (somewhat) clear boundary between GtkSourceView and Gtef: the top level object in GtkSourceView is the GtkSourceView widget, while the GtkSourceView widget is at the bottom of the containment hierarchy in Gtef. I said “somewhat” because there is also GtkSourceBuffer and GtefBuffer, and both libraries have other classes for peripheral, self-contained features.

New file loader based on uchardet

The file loading and saving API in GtkSourceView is quite low-level, it contains only the backend part. In case of error, the application needs to display the error (preferably in a GtkInfoBar) and for some errors provide actions like choosing another character encoding manually. One goal of Gtef will be to provide a simpler API, taking care of all kinds of errors, showing GtkInfoBars etc.

But how the backend works has an impact on the GUI. The file loading and saving classes in GtkSourceView come from gedit, and I’m not entirely happy with the gedit UI for file loading and saving. There are several problems, one of them is that GtkFileChooserNative cannot be used with the current gedit UI so it’s problematic to sandbox the application with Flatpak.

With gedit, when we open a file from a GtkFileChooserDialog, there is a combobox for the encoding: by default the encoding is auto-detected from a configurable list of encodings, and it is possible to choose manually an encoding from that same list. I want to get rid of that combobox, to always auto-detect the encoding (it’s simpler for the user), and to be able to use GtkFileChooserNative (because custom widgets like the combobox cannot be added to a GtkFileChooserNative).

The problem with the file loader implementation in GtkSourceView is that the encoding auto-detection is not that good, hence the need for the combobox in the GtkFileChooserDialog in gedit. But to detect the encoding, there is now a simple to use library called uchardet, maintained by Jehan Pagès, and based on the Mozilla universal charset detection code. Since the encoding auto-detection is much better with uchardet, it will be possible to remove the combobox and use GtkFileChooserNative!

Jehan started to modify GtkSourceFileLoader (or, more precisely, the internal class GtkSourceBufferOutputStream) to use uchardet, but as a comment in GtkSourceBufferOutputStream explains, that code is a big headache… And the encoding detection is based only on the first 8KB of the file, which results in bugs if for example the first 8KB are only ASCII characters and a strange character appears later. Changing that implementation to take into account the whole content of the file was not easily possible, so instead, I decided to write a new implementation from scratch, in Gtef, called GtefFileLoader. It was done in Gtef and not in GtkSourceView, to not break the GtkSourceView API, and to have the time in Gtef to write the implementation and API incrementally (trying to keep the API as close as possible to the GtkSourceView API).

The new GtefFileLoader takes a simpler approach, doing things sequentially instead of doing everything at the same time (the reason for the headache). 1) Loading the content in memory, 2) determining the encoding, 3) converting the content to UTF-8 and inserting the result into the GtkTextBuffer.

Note that for step 2, determining the encoding, it would have been entirely possible without uchardet, by counting the number of invalid characters and taking the first encoding for which there are no errors (or taking the one with the fewest errors, escaping the invalid characters). And when uchardet is used, that method can serve as a nice fallback. Since all the content is in memory, it should be fast enough even if it is done on the whole content (GtkTextView doesn’t support very big files anyway, 50MB is the default maximum in GtefFileLoader).

GtefFileLoader is usable and works well, but it is still missing quite a few features compared to GtkSourceFileLoader: escaping invalid characters, loading from a GInputStream (e.g. stdin) and gzip uncompression support. And I would like to add more features: refuse to load very long lines (it is not well supported by GtkTextView) and possibly ask to split the line, and detect binary files.

The higher-level API is not yet created, GtefFileLoader is still “just” the backend part.

Re: Consider the maintainer

I’ve read this LWN article: Consider the maintainer. It was a great read, and I want to share my thoughts, from my experience on being a maintainer (or helping the maintenance) of several GNOME modules.

GNOME has a lot of existing code, but let’s face it, it has also a lot of bugs (just look at bugzilla, but the code also contains a lot of not-yet-reported bugs). For a piece of software to be successful, I’m convinced that it has to be stable, mostly bug-free. Stability is not the only property of a successful software, but without it it has way less chance to be successful in the long run (after the hype wave is gone and the harsh reality resurfaces).

There is a big difference between (a) writing a feature, but in reality it’s full of bugs, and (b) writing the same feature, but “mostly bug-free” (targeting bug-free code). It certainly takes the double of time, probably more. The last 10% of perfection are the most difficult.

Paolo Borelli likes to explain that there are two kinds of developers: the maintainers and the developers who prefer to write crazy-new-experimental features (with a gray scale in-between). It is similar with the difference between useful tasks vs interesting tasks that I talked about in a previous blog post: some useful tasks like writing unit tests are not terribly interesting to do, but I think that in general a maintainer-kind-of-developer writes more tests. And Paolo said that I’m clearly on the maintainer side, caring a lot about code quality, stability, documentation, tests, bug triaging, etc.

Reducing complexity

The key, with a lot of existing but not perfect code, is to reduce complexity:

  • Improving the coding style for better readability;
  • Doing lots of small (or less-small) refactorings;
  • Writing utility classes;
  • Extracting from a big class a set of smaller classes so that the initial class delegates some of its work;
  • Writing re-usable code, by writing a library, and documenting the classes with GTK-Doc;
  • Etc.

Even for an application, it is useful to write most of the code as an internal library, documented with GTK-Doc. Browsing the classes in Devhelp is such a nice way to discover and understand the codebase for new contributors (even if the contributor has already a lot of experience with GLib/GTK+).

Another “maintainer task” that I’ve often done: when I start contributing to a certain class, I read the whole code of that class, trying to understand every line of code, doing lots of small refactorings along the way, simplifying the code, using new GLib or GTK+ APIs, etc. When doing this exercise, I have often discovered (and fixed) bugs that were not reported in the bug tracker. Then to achieve what I wanted to do initially, with the much better knowledge of the code, I know how to do it properly, not with a quick hack to do the minimal amount of change that I sometimes see passing. As a result the code has less bugs, there is less chance to introduce new bugs, and the code is easier to understand and thus more maintainable. There is no secrets, it takes more time to do that, but the result is better.

Some books that were very useful to me:

Of course I didn’t read all those books at once, practicing is also important. I nowadays read approximately one computing science book per year.

About new contributors and code reviews

When I started to contribute to GtkSourceView several years ago, I had already developed a complete LaTeX editor based on GtkSourceView (by myself), read several of the above books (most importantly Code Complete) and applied what I learned. I had already a lot of experience with GTK+. So starting to contribute to GtkSourceView was easy, my patches were accepted easily and I think it was not too much work for the reviewers. I then became a co-maintainer.

Contrast this with all those newbies wanting to contribute to GNOME for the first time, without any experience with GLib/GTK+. They don’t even know how to contribute, how to compile the code, they probably don’t know well the command line or git, etc. So if a maintainer wants to help those newcomers, it takes a lot of time. I think this is partly a problem of documentation (that I’m trying to solve with this guide on GLib/GTK+). But even with good documentation, if the new contributor needs to learn for the first time GTK+, it will require too much time for the maintainer. What I would suggest is for newcomers to start by writing a new application on their own; for that a list of ideas of missing applications would be helpful.

This is maybe a little controversial, but the talk Consider the maintainer was also controversial, by suggesting for instance: “Maintainers should be able to say that a project is simply not accepting contributions, or to limit contributors to a small, known group of developers.”

When a company wants to hire a developer, they can choose the best candidate, or if no candidates fit they can also choose to keep the existing team as-is. In Free Software, anyone can send a patch; sometimes it takes a lot of time to explain everything and then after a short time the contributor never comes back. Remember also the well-known fact that adding people to a late project makes it later (usually, but there are exceptions).

Another interesting glimpse, from Hackers and Painters (Paul Graham):


Other topics

I could talk about other topics, such as the lack of statistics (I don’t even know the number of people executing the code I write!) or trying to avoid sources of endless maintenance burden (example: GtkSourceView syntax highlighting definition files, the maintenance could clearly be better distributed, with one maintainer per *.lang file). But this blog post is already quite long, so I’ll not expand on those topics.

In short, there is clearly matter for thoughts and improvements in how we work, to get more things done.

Spell-checking for GtkEntry in gspell

It’s done! Everything that I wanted to do initially for the fundraising of gspell is implemented (for the milestone 1).

The main steps were:

  1. Basic infrastructure, insert underlines to misspelled words.
  2. Add the context menu, and have common code between GtkTextView and GtkEntry.
  3. Do not check the word currently typed. Ditto, have common code between GtkTextView and GtkEntry, to define the policy at only one place.
  4. Better word boundaries: take into account apostrophes and dashes.
  5. Take care of a few other details, like forcing to disable spell-checking when the GtkEntry is in password mode.

The fundraising has a second milestone with “Various Other Improvements”, which is currently at 17%, so I’ll do a few more small tasks. For example fixing bug #772406 (a unit test fails with aspell, while it works fine with hunspell, the kind of problems that arise when multiple backends can be used and work slightly differently) and what is described in bug #761921 comment #1 (a first possible step for a better Windows support).