Xfce Wiki

Sub domains
 

This page is just an extract of AndreLDM's blog. You may want to read the full Ultimate Contributor's Guide to Xfce.

Coding

This is the most effective way to help. We are always looking for new people to improve, fix, hack and eventually maintain Xfce’s components. You don’t have to be a ninja, just the basic knowledge of a programming language, preferably C, a bit of git and most importantly the desire to learn. Some people are scared of C, because they heard it’s too low level… Fear not, the language is quite simple. Yes, there are pitfalls and gotchas, as any other language, but the experience is improved by gtk’s and glib’s utility functions and abstractions.

First things first, Xfce’s modular architecture feature several components, some are part of its core and some are optional apps or panel plugins. Take some time to read their description. You might wonder what the heck is a window manager? or I never heard of freedesktop.org or d-bus, are they edible?. Search for them, I can’t possibly explain everything there is to know about Linux desktops in a single blog post.

In my opinion the best way to get started with code is to scratch your own itch, you know, deal with that annoying bug or a behavior that could be improved. The rule of thumb is to browse Xfce’s GitLab and look for that bug or report it in case no one noticed the problem until now. Then go to Xfce’s repository browser, clone the repository for the component you are about to hack, fix the problem and send a merge request. That’s easy for me to say, isn’t it? I’m going to prove you it is not that hard, let’s go step by step.

Building from source

Suppose we are interested in hacking xfce4-appfinder, the first thing we need to do is to build and be able to run that component:

git clone https://gitlab.xfce.org/xfce/xfce4-appfinder
cd xfce4-appfinder
./autogen.sh --prefix=/usr --enable-debug
make

The ./autogen.sh command will fail if you never compiled a Xfce component before, we need to have installed development packages for dependencies, unfortunately it’s hard to give instructions since package names vary between distributions. In most cases it helps a lot to not panic and read the error message. For example:

checking for exo-2 >= 0.12.0... not found
*** The required package exo-2 was not found on your system.

For Debian/Ubuntu sudo apt install libexo-2-dev does the trick. Actually on Debian/Ubuntu sudo apt build-dep [package-name] installs all build dependencies of the given package, xfce4-appfinder in our case. On Arch Linux, there is no *-dev packages, if you have Xfce installed, you will need to figure out fewer dependencies packages to install and you can also check the makedepends variable from the PKGBUILD of the component you are interested.

Moving on, the –prefix=/usr option is useful if you want to install the component on your system (with sudo make install), it means to replace the version provided by the system package manager. Be aware that daily usage of development builds is cool because of unreleased fixes and new features, but it’s also risky because new bugs may appear or due incompatibilities with stable components.

The –enable-debug allows interesting things for development such as debugging with gdb, more detailed backtraces and compiling warnings. Keep in mind that binaries with debug symbols are larger and possibly slower, often unnoticeable.

After make, the binary is ready to run, however xfce4-appfinder as some other Xfce components run in background (daemon mode), in this case we need to stop its process with xfce4-appfinder -q. Hint: this specific component has a preference to disable daemon mode (Preferences → General → Keep running instance in the background), so I recommend disabling it while in “write code-compile-run” loop. Now from the root of the repository, run src/xfce4-appfinder. Congratulations, you have just built your first component! If you don’t believe me, change the window title “Application Finder” (appfinder-window.c) to something else, build and run again with make && src/xfce4-appfinder.

This was just a quick summary of how to build Xfce components, here a much more detailed explanation.

Smashing bugs

Now to make things interesting let’s fix a bug, but this time I need you to clone and build Mousepad, Xfce’s text editor. The steps are very much the same, except that Mousepad does not run in background which makes things easier. Go on, clone and build it. Hopefully you have successfully built Mousepad by now, if not read carefully error messages spilled on the terminal, if you can’t figure them out searching those messages on the web could be helpful. If you tried really hard and nothing worked, ask for guidance at #xfce-dev, stay online and be patient, try one more time if no one replies after one day.

Now you are able to execute Mousepad with mousepad/mousepad from the source folder, we are ready to smash a real bug. Obviously I wouldn’t be so reckless to let a bug live just for beginners fix it and never push the fix, the bug I have in mind was fixed centuries ago (2014), actually it was one of my first contributed patches (when merge requests weren't a thing yet). With the magic of git, we can travel back to mousepad-0.3.0 (gtk2!) and smash that bug once again. Before we go back, clean the source folder with make distclean, now you are good to run git checkout mousepad-0.3.0. Git will complain that “you are in ‘detached HEAD’ state”, you might know what that means, otherwise ignore it for now and remember to learn git later, because you know, having a detached head is not comfortable at all ;)

Once again configure and build Mousepad (./autogen.sh && make) and fix the bug… Oh, but I haven’t even told what is broken :) Allow me: execute Mousepad, type “hello world”, save the file somewhere and close Mousepad. Now run Mousepad again and open that file, type some gibberish and choose File → Revert, it will ask for confirmation, press “Revert” and it says it failed to revert even though it worked. Weird, isn’t it?

So where do we get started? Have a look at the terminal, it says g_error_free: assertion 'error != NULL' failed, looks fishy. Open Mousepad source folder in your favorite editor. I hope the editor you are using features a text search on all files, because to locate the suspect part of code, we need to search for the error message from the dialog, in this case “Failed to reload the document.”. Ignore .po files, they are used only for translations. If you are still following me this far, you might have found the message at mousepad-window.c:3983 and look! Just below that line there is g_error_free which was mentioned by that terminal message, so we must be close, my dear Watson. Notice how that chunk of code is executed only if succeed is FALSE, and succeed is the result of mousepad_file_reload function call. Hmmm, let’s go into that function (mousepad-file.c:859), take your time to read it.

As you might have reckoned (or not, no worries), it starts with state checking, checks if the file still exists, clears a buffer and, the most important part, reloads the file, the result goes into a boolean also called succeed. At this point, you may want to use gdb to debug this code, but I won’t teach you this, there lots of tutorials out there. The poor’s man debug is printf, I use it a lot, though some claim it’s a bad practice. Anyway, try it, put g_print (“succeed is %s\n”, result ? “TRUE” : “FALSE”); in the line after succeed gets assigned (mousepad-file.c:886), then build and try to reproduce the bug, messages on terminal may help you understand what is happening. Ok, indeed succeed is FALSE at that point, so let’s dive into mousepad_file_open, then read it.

Found anything interesting? No? Go back and check its signature. Still no? What about its return type? Yes, it returns gint which is assigned to a gboolean variable! How is that even possible? If you know a bit C, you probably know any non-zero number yields TRUE when evaluated in a boolean expression, consequently 0 yields FALSE. If you read that function code, you saw that it returns non-zero when something went wrong (a common pattern in C programs and libraries). By now it should be clear that this is the opposite of what we expect for succeed, 0 means no error but when converted to boolean results in FALSE. So what is the fix? Well, try to figure it out yourself, you have all the information needed :)

Once you have your solution, compare it to the one provided in Bug #10636.

Sharing Code

Now you know how to build components and smash bugs, browse the isssues reported on Gitlab and try to fix something that looks easy. If you have an idea on how to fix some code that seems to work but you are not so sure, don’t be afraid to ask at #xfce-dev. Once you have a good enough solution, follow these steps in order to create a merge request. Wait a few days, if you get no answer, poke us at #xfce-dev or use the Xfce4-dev mailing list. After some merge requests, you may ask commit rights and join the dev club, yay!

This page is just an extract of AndreLDM's blog. You may want to read the full Ultimate Contributor's Guide to Xfce.