Thoughts on the Linux Mint X-Apps forks

You may be aware that Linux Mint has forked several GNOME applications, either directly from GNOME (Totem -> Xplayer, Evince -> Xreader, Eye of GNOME -> Xviewer), or indirectly via MATE (gedit -> pluma -> XEd).

GNOME is like the Debian of the Linux desktops. But is it a good thing? In the current state of the code, I don’t think so and I’ll explain why, with a solution: creating more shared libraries.

At the end of the day, it’s just a matter of design and usability concerns. We can safely say that the main reason behind the forks is that the Linux Mint developers don’t like the new design of GNOME applications with a GtkHeaderBar.

And there are perfectly valid reasons to not like headerbars. For gedit for example, see the list of usability regressions at this wiki page.

Currently the trend is GtkHeaderBar, but what will it be in 5 years, 10 years? Let’s face it, GNOME is here just following the new trend that came with smartphones and tablets.

So, a GNOME application developer needs to know that:

  • A GUI is an ever-changing thing, exactly like the clothes that you bought last year are already obsolete, right?
  • When the GUI changes too much, other developers don’t like it and fork the project. For valid reasons or not, this doesn’t matter.

The four X-Apps forks account for roughly 200k lines of code. In the short-term it works, Linux Mint has apps with a traditional UI. But hey, porting the code to GTK+ 4 will be another beast, because the four X-Apps still use the deprecated GtkUIManager and GtkAction APIs, among other things.

But when we look at the codebase, there are a lot of code that could be shared between a GNOME app and its fork(s). So there is a solution: creating more shared libraries. The shared libraries would contain the backend code, of course, but also some basic blocks for the UI. The application would just need to glue things up together, assembling objects, binding GObject properties to GSettings, create the main GtkWindow and a few other things.

The difference would be that instead of forking 200k lines of code, it would be forking maybe 20k lines, which is more manageable to maintain in the long term.

In the case of gedit, making its code more re-usable is exactly what I do since several years, but for another reason: being able to create easily specialized text editors or small IDEs.

Beside avoiding code duplication, creating a shared library has the nice side effect that it is much better documented (usually), and with an API browser like Devhelp, it’s a breeze to discover and understand a new codebase, it permits to have a nice overview of the classes. It’s of course possible to have such documentation for application code, but in practice few developers do that, although it would be a big step towards lowering the barrier to entry for newcomers.

When untangling some code from an application and putting it in a shared library, it is also easier to make the code unit testable (and unit tested!), or at least write a mini interactive test in case of frontend code. Making the code more stable, getting closer to bug-free code and thus more successful software.

Developing a shared library doesn’t necessarily mean to provide backward compatibility during 10 years. Nothing prevents you from bumping the major version of the library every 6 months if needed, making the new version parallel-installable with the previous major versions. So that applications are not forced to update the code when there is an API break.

But creating a library is more difficult, API design is hard. But in my opinion it is worth it. GNOME is not only a desktop environment with an application suite, it is also a development platform.

Posted in gedit, gspell, GtkSourceView, Programming, Thoughts | 11 Comments

Doing things that scale

In the software world, and with internet, we can do a lot of things that scale.

Answering a user question on IRC doesn’t scale, only one person and a few lurkers will benefit from it. Answering a user question on a mailing list scales a little better, since the answer is archived and can be searched for. What really scales is instead to improve the reference manual. Yes, you know, documentation. That way, normally the question will not surface again. You have written the documentation once and N readers benefit from it, regardless of N. It scales!

Another example. Writing an application versus writing a library. Writing an application or end-user software already scales in the sense that the programmer writes the code once, but it can be copied and installed N times for almost the same cost as one time. Writing a library scales more, since it can benefit N programs, and thus N^2 users if we use the asymptotic notation. It’s no longer linear, it’s quadratic! The lower-level the library, the more it scales.

Providing your work under a free/libre license scales more, since it can be re-distributed freely on the internet. There are some start-ups in the world that reinvent the wheel by writing proprietary software and provide technical support in their region only. By writing a free software instead, other start-ups can pop up in other regions of the world, and will start contributing to your codebase (if it’s a copyleft license, that is). For the human being advancement, free software is better since it more easily permits to not reinvent the wheel. Provided that it’s a high-quality software.

This can go on and on. You get the picture. But doing something that scales is generally more difficult. It takes more time in the short-term, but in the long-term everybody wins.

Posted in Programming, Thoughts | Leave a comment

API vs ABI

I repeatedly see other people doing the mistake, so a little reminder doesn’t hurt.

  • API: Application Programming Interface
  • ABI: Application Binary Interface

The difference can be easily explained by knowing what to do for some code when the API or ABI breaks in a library that the code depends on:

  • If only the ABI breaks, then you just need to re-compile the code.
  • If the API breaks, you need to adapt the code.
  • When the code doesn’t compile anymore, you need to adapt it, so it’s both an API and ABI break.
  • When the code still compiles fine but you need to adapt it, it’s only an API break.

Example of an ABI break only: when the size of a public struct changes.

Example of an ABI and API break: when a function is renamed.

Example of an API break only: CSS in GTK+ 3.20, or when a function doesn’t do the same as what was documented before (in an incompatible way).

That’s it.

Posted in Programming | 6 Comments

Libtool convenience library to unit test private functions

Only the public API of a library is exported, so when a program is dynamically linked to the DSO (Dynamic Shared Object), it can only use the public functions.

So how do you unit test the private classes of your library?

There is a simple solution, having a Libtool convenience library that contains the whole code of the library, but without an -export linker flag, so that all functions can still be accessed. You then link that *.la file to your unit tests and also to the real library where you add the appropriate -export flag.

You can see that in action in GtkSourceView and gspell. For example in gspell:

When you run make in verbose mode with make V=1, you see that the libtool commands statically link the convenience static library (a file with the *.a extension) into the unit test programs and into the DSO.

That way the *.c files are compiled only once, and adding a unit test to the testsuite/Makefile.am is straightforward.

Posted in gspell, GtkSourceView, Programming | Leave a comment

gCSVedit now hosted on SourceForge

I don’t know if you remember, but I announced in November a small project, called gCSVedit. It’s a small text editor for viewing and editing CSV, TSV, etc files.

I’ve released the 0.2 stable version recently. It is at least now consumable outside Jhbuild.

And, gCSVedit is now hosted on SourceForge instead of GitHub. Because SourceForge is cool again. The forge of SourceForge is free software, unlike GitHub. The users (will) download the tarballs/bundles/installers that *I* have generated, not what GitHub thinks is good to ship. And if the need arises, I can open a mailing list.

Also, I like how each software on SourceForge has a consistent set of information, presented with the same template. You just need to fill up a form with the name, a short description, a long description, the license, a screenshot, an icon, some tags, and such like. It’s better than a README.md file or copying a wiki template manually (if the template is modified, the changes are not echoed…).

The missing thing (both on GitHub and SourceForge, but not on gnome.org) is for the art of (not) managing translations, from the maintainer’s point of view. But a service like Transifex can fill the gap I think.

Posted in gCSVedit | 5 Comments

gspell news bis

Some more gspell news (see the previous iteration):

  • gspell has been re-licensed from GPLv2+ to LGPLv2.1+.
  • gspell no longer depends on the libxml2 and GtkSourceView libraries.
  • gspell 1.0 will be released at the same time as GNOME 3.20 (in a few weeks), with a stable API.
  • There has been several iterations on the API, making it easier to use. See below.
  • In gedit 3.18 there was a regression: the current word being typed was spell checked… which is now fixed, because it was annoying to have a red wavy underline appearing constantly while typing…
  • Words with apostrophes – like “doesn’t” – are now supported!
  • And a testsuite has been written.

API design

See the gspell API reference. There are two things worth mentioning that are generally useful when designing APIs.

First, a constraint has been directly translated into the API itself instead of allowing an illogical combination in an application.

More specifically, for the same GtkTextBuffer, it doesn’t make sense to use a different GspellChecker between an inline checker and an “external” checker (e.g. a dialog window). Since it’s the same GtkTextBuffer, it should be the same GspellChecker to share the session dictionary (when you click on Ignore All, the word is added to the session dictionary). So instead of having a spell-checker property on both the inline checker and the external checker, now a GspellChecker must be attached to a GtkTextBuffer with gspell_text_buffer_set_spell_checker(). That latter function takes a GtkTextBuffer argument, there is no GspellTextBuffer subclass since there is already one in the GtkSourceView library. That’s where g_object_set_data() becomes useful. And by attaching the GspellChecker to the GtkTextBuffer, we no longer need to keep the GspellChecker object around in the application code, we can get it with gspell_text_buffer_get_spell_checker().

The other thing worth mentioning is that at another place a class is more lax and accepts a certain state instead of documenting “please check the value of …”. More precisely, GspellChecker now accepts a NULL language in the case there are no dictionaries installed.

One of my goals when developing gspell is also to learn writing good APIs, so if you see some possible improvements, don’t hesitate! It’s too late for the 1.x versions, but I can keep a bug around on bugzilla with the 2.0 target. And of course, any other comments or testing are welcome.

Thanks to Paolo Borelli for the API review, and thanks to the numerous GNOME translators! gspell 1.0 will be rock solid!

Posted in gspell | Leave a comment

Refocus

This is a more personal blog post. Sometimes all those GNOME programming projects are driving me crazy. These last few weeks I needed to rest (that’s why I came only one afternoon at the Developer Experience hackfest, and why I didn’t come to FOSDEM this year (although living nearby)). Yeah, it can happen.

It was time to change a little my focus.

Over the years I created or got involved in more and more projects. When we want to go in too many directions, we make little progress in each. So it’s better to focus only on one or a few projects, and try to make significant progress in those.

Projects that I will no longer actively develop or maintain (at least not during my free time):

Project that I want to “finish” this development cycle:

Project that I’m excited about for the next development cycle:

Other projects that I care about and that I want to do in the future, without any guarantees:

  • Improving file printing in gedit, to be like in Firefox
  • Write a new chapter in my GLib/GTK+ tutorial

Note that for that last item, I would use LaTeXila of course, so if there are some regressions due to some library changes (you perfectly know which library in particular I mean), I’ll probably become aware of the regressions and fix them. Without any guarantees, I repeat. So if someone wants to take over LaTeXila maintenance, I would be more than happy. In the condition that I can still recognize my old pet project afterwards and is still mostly bug-free.

Cat non-fooding

Why such a change of focus? Devhelp was initially a side project for me, and making the gedit source code more re-usable was my main focus during these last years (but along the way it involved also fixing bugs, improving the code readability and making the codebase less a mess, basically).

To explain the refocus, some facts/timeline:

  • I’ve almost always used Vim to program in C.
  • For LaTeX I also used Vim, but at some point I discovered Kile (a Qt application) to write LaTeX documents, because for LaTeX I found that a GUI application has some convenient features.
  • During the summer 2009, I started to write LaTeXila – a new LaTeX editor based on GtkSourceView – to have a LaTeX editor following the GNOME philosophy and based on GTK+.
  • I discovered Vala, and there was a nice gedit plugin for the Vala auto-completion, so I ended up using gedit to develop LaTeXila.
  • At some point I started to contribute to GtkSourceView to fix some bugs, and I used Vim since it is written in C.
  • I got hooked to GtkSourceView development and became a co-maintainer, with the project to make more code of gedit re-usable, to share more code between gedit and LaTeXila.
  • Then my dislike about Vala was growing and growing.
  • I’m no longer a student, so I now rarely use LaTeX.

Basically, I now use gedit mainly for non-programming text editing tasks, e.g. drafting a blog post. In fact, the spell checking is more convenient to use with a GUI application than with Vim. Another use-case of gedit for me is to print a text file. That’s it.

And cat-fooding is important (I’m more a cat person, so I prefer to talk about cat-fooding, or the lack thereof).

For programming, I’m now used to my tmux session with a ‘git’ tab, a ‘build’ tab and several files opened in Vim in the following tabs. I can do everything with the keyboard. I can program during one hour without touching the mouse. I think I would be much less productive if I come back to a terminal + gedit.

But I’m convinced that specialized text editors would be easier to use and configure for the first time than a general-purpose text editor with plugins, tons of options, lengthy configuration files, and such like. And developing libraries to ease the creation of new text editors was an interesting technical project to me.

Anyway, Devhelp is an application that I heavily use. So that’s why I want to improve it. And it’s still in the Developer Experience field. And with the Vim mode of GNOME Builder, I’ll maybe come back one day to a GUI text editor for programming.

Petula Clark – Downtown

Posted in Me Myself and I | 6 Comments

Task-oriented desktop and applications?

I wanted to add a comment to Allan’s blog post The next big thing, but too late! comments are already closed (side note, I think it’s a general problem on blogs.gnome.org or it’s a WordPress issue, or both).

So, at Flock 2014, Langdon White talked about “Fedora for Developers” (video), with the following idea, among other things: Desktop integration with “tasks” (with saved state).

It reminded me about a discussion that I had with gedit developers back in 2011. We talked about profiles: being able to create different gedit profiles, for example one for the C language and one for Vala. Different gedit instances could be launched with different profiles. They would behave as independent apps, with different settings, different plugins activated, a different UI state, and so on. Of course a profile could be created for each programming project, or… task.

But a task often involves launching several applications. So to resume a complete task quickly, in one step, it either needs some desktop integration, or another application could be responsible to create tasks and resume them. But either way it needs coordination with applications.

Posted in Thoughts | 8 Comments

gspell news

  • gspell is now fully hosted on gnome.org!
  • There is now a mailing list.
  • In addition to LaTeXila, gspell is now also used by gedit (5,800 lines removed, yay!).
  • The 0.1.x version has branched and is meant to be installed alongside GNOME 3.18.
  • If everything goes fine, the 1.0 version will be released at the same time as GNOME 3.20, with a stable API.

API reviews are more than welcome!

Stay tuned.

Posted in gedit, gspell | 3 Comments

Announcing gCSVedit, a simple text editor to edit CSV files

As part of my job at the Université Catholique de Louvain, one of my projects is to develop gCSVedit, a small and simple text editor to edit CSV files.

gCSVedit is now a free/libre software (GPLv3+ license) and is hosted on SourceForge.

Other delimiter-separated values (DSV) files are supported, not just comma-separated values (CSV) files, but “CSV” is more commonly used to refer to that kind of file.

Screenshot of gCSVedit

gCSVedit with the columns aligned. Note also the gray bullets to represent the spaces present in the file.

Why developing a new application for editing CSV files?

CSV files can already be opened in a spreadsheet software like LibreOffice Calc and Gnumeric. But it’s not really user-friendly. Just to open the file you need to provide tons of options:

Screenshot of opening a CSV file with LibreOffice Calc

Opening a CSV file with LibreOffice Calc

A general-purpose text editor like gedit is not the best choice either, because the columns are not aligned. There are some plugins for Eclipse or other IDEs available, but launching and using a complete IDE just to view or edit a CSV file is not user-friendly either.

The best is a specialized application, to do just one thing but do it well. With a user interface that goes straight to the point.

Spreadsheet or text editor?

With a text editor, all characters are visible, including the delimiters. We have thus a greater control. When writing a script to extract the data contained in the file, it’s important to view every character in case of problems (like an extra separator in the data but not for the column titles).

Also, some software that generate CSV files sometimes also include an header, i.e. some text before the actual CSV fields. With a text editor, the header can be shown naturally.

Future plans

Create an installer for Windows. Create an xdg-app for GNU/Linux. And implement more features of course!

Hopefully in the future it’ll be possible to re-use more code of gedit, to have a decent text editor (although gCSVedit is already completely usable).

So, nothing revolutionary here, it’s a small project. But I think it can bring a better usability. Comments, questions?

PS: to show where are the real spaces (those present in the file, not those added for the alignment), I’ve already contributed to GtkSourceView and GTK+. There will maybe be more contributions in the future, for example to implement a utility to insert virtual spaces, i.e. the text editor should behave as if the added spaces didn’t exist. Or, finally implement rectangular selection in GtkTextView.

Edit: gCSVedit was hosted on GitHub, but it is now hosted on SourceForge. So the URLs have been updated.

Posted in gCSVedit, gedit, GtkSourceView | 7 Comments