g_clear_{s,}list() in GLib 2.63.3

On the topic of new APIs in GLib, https://gitlab.gnome.org/GNOME/glib/commit/58ba7d78fbd7ecb4c0df2dc7e251627ebbffb9d5 is now a thing (whenever 2.63.3 sees the light of day).

Nothing super exciting, but it will scratch my own itch in refactoring some code later, since we do lots of (or variants of)

if (NULL != bar)
    foo_free (bar);
    bar = NULL;

That also includes lists, for which there is no sugar in case you want to also free the elements. With the change, you will be able to simply write

g_clear_list (&slist, NULL);    // does g_list_free()
g_clear_slist (&slist, g_free); // does g_slist_free_full()

Reporting problems in Flatpak applications

(Repost from https://abrt.github.io/, pardon any terrible formatting)


If you’ve ever experienced a crash in a Flatpak application, you might have noticed that there is no notification coming from ABRT for it, and maybe you even noticed some strange messages in the system journal:

abrt-server[…]: Unsupported container technology

The above appears when ABRT attempts to collect information about the container (currently only Docker and LXC), if the binary has been detected to have been run in one. For Flatpak applications, we probably get enough information already, so we can just special-case and do nothing instead.

Unfortunately, getting things like stack traces gets a bit more complicated than that.

For core dumps, I’ve experimented with a quick hack that reads mountinfo from the dump directory[0], creates a new user namespace, mounts the app and runtime directories, and, finally, generates a trace, which is workable enough to be used in a report, even without debug extensions installed. However, this is all until the user decides to update, which would likely invalidate the paths in mountinfo. For that, I should probably explore utilizing OSTree to check out the known commits first.

As for Python exceptions, things don’t really work at all. But, to put things in perspective, this is how it looks right now:

  •  A path configuration file is installed; it contains only an import line for the actual handler
  • Python opens it during initialization, executes all lines that start with import, which, conveniently, causes our code to run and override sys.excepthook

It’s not even close to being elegant, and people are already arguing about removing support (or, rather, coming up with a better alternative) for such things: https://bugs.python.org/issue33944. To support such an implementation, we would likely need to provide a runtime extension, or ask anyone shipping Python to include our handler.

To make things worse, the handler communicates with ABRT using a UNIX socket, which would at the very least require all apps to have host access. A better way would probably be utilizing a D-Bus API, and that would require having a portal, so that, again, we don’t have to punch holes in the sandbox.

Finally, there are still a couple unanswered questions:

What about other kinds of problems? At the moment, I can only think of Java programs as being supported and possibly coming with their own set of challenges.

How do we handle this from the server side? Everything is built around traditional packaging, where components belong to a specific release of a specific operating system (distro). In the end, it could require some rearchitecting in FAF (now ABRT Analytics) and ABRT itself.

[0] – From that we can only infer the OSTree ref and commit. There does exist Flatpak instance data in XDG_RUNTIME_DIR/.flatpak, but we cannot rely on it, due to its garbage-collected nature.

Treading New Waters

Water, molluscs, oh what a thrill!

Today, we are not talking about Nautilus, but rather it’s just me bragging!

After a month of waiting, talking, waiting, writing and waiting some more, I’m officially a month away from starting at Red Hat (and moving to Brno, so some of you I’ll get to meet as well), working on all things ABRT. Since my GNOME work really helped me sell myself, maybe I’ll manage to help bridge whatever gap there exists between the two.

As far as Nautilus goes, this will probably not change a whole lot, as Carlos still holds the mollusc-wrangling-champion belt. Well, the feature-removal cabal meetings might take a new form. :p

That’s it for now, take care!

GTK+ 4 and Nautilus </GSoC>

Another summer here at GNOME HQ comes to an end. While certainly eventful, it unfortunately did not result in a production-ready Nautilus port to GTK+ 4 (unless you don’t intend to use the location entry or any other entry, but more on that later).

It works, and you can try it if you really (really) want to by doing so:

flatpak install https://gitlab.gnome.org/GNOME/gnome-apps-nightly/raw/master/NautilusGtk4.flatpakref

You will notice that DnD works differently as compared to the current stable version:

  • the default action isn’t set by Nautilus to “move” when dragging a file in its parent directory, but rather all possible actions (“copy”, “move”, “link”, “ask”) – that is due to changes in the DnD API in GTK+ in an effort to consolidate all the different action types (actions, suggested actions, selected actions);
  • “link” cannot be accessed with ctrl-shift when using Wayland, “ask” does not work in X;
  • “ask” does not result in a context menu being popped up, likely due to a bug in GTK+ and not in Nautilus;
  • sidebar drops are rejected and cause the “New bookmark” row to remain visible, which is caused by another reported GTK+ bug.

Another big issue is actions and their (global) accelerators. Due to changes in how these are activated in GTK+, Nautilus can no longer do the trick where it prevents that from happening if the currently-focused widget is an editable. Not being able to do that means that pressing ctrl-a while, say, renaming a file will select the files in the view instead of the text. Pressing delete immediately after will result in you fainting, as you’ve just trashed all the files (as had happened to me several times, and thank goodness it’s not permanent deletion). Given the shortcuts reworking effort in GTK+ that is currently in progress, it might be a breeze to fix the issues in the near future.

Aside from all that, there are some other small-ish and annoying issues, like drag icons not being offset in Wayland, the operations button losing its reveal animation, and probably something else I’m forgetting at the moment. So, if you’re interested in turning your computer into a jet engine or benchmarking GitLab, feel free to take a look at https://gitlab.gnome.org/GNOME/nautilus/merge_requests/266.

Nautilus and GTK+ 4

A couple weeks had passed, and the effort to make Nautilus buildable with GTK+ 4 had paid off – it builds (don’t mind the commit message, it’s about https://gitlab.gnome.org/GNOME/glib/commit/7e5db31d36532274c2b2428ef9bace796928785e) and runs!

Now, that alone doesn’t mean much, since Nautilus is nowhere near a usable state:

  • Some input event handlers rely on being able to chain up to the parent handler for certain things: the list view, in particular, on right clicks, to select the file before popping up a context menu for it. I don’t know of a way to achieve that yet, so the code is currently just commented out.
  • Support for XDS has been removed, as the implementation relied heavily on window properties, which have been removed. In particular, this should make DnD from file-roller to Nautilus useless (which doesn’t work in Wayland, either, AFAIR). Support for root window drops is gone as well, given that Nautilus does not handle the desktop.
  • Scrolling in canvas view broke completely and mouse rubberband selection is a tad wonky still, but only at the highest zoom level (at least it works great after moving it out to a drag gesture, despite breaking single-click selection, as the current selection is cleared at the beginning).
  • Header bar menus appear empty (not exactly a priority, although might be an easy win).
  • Canvas view item prelighting and selection coloring needs rethinking again and might end up looking differently. But, hey, at least the GtkSnapshot API is fun to use.

That’s all that comes to mind right now, but there’s still plenty to keep me busy.

Nautilus Tagged Entry Redux

It works!

Since my last post, the tagged entry became a subclass of GtkSearchEntry, as was the case with GdTaggedEntry (yay GTK+ 4) and the tags became GtkWidgets (instead of GtkBins). It didn’t take much effort to move from GtkBin to GtkWidget – only implementing size_allocate(), measure() and snapshot(), which are really trivial when working with actual widgets as children. That, and tweaking the appearance some more, as the move broke the styling a tad. Some perhaps questionable methods of dealing with that were employed, but nothing too nefarious.

With this out of the way now, I’ll be able to focus on porting the rest of Nautilus.

The code is available at https://gitlab.gnome.org/ernestask/tagged-entry, if you’re interested.

Tagged Entry in Nautilus

With the exams having been left in the past, I can get back to hacking on Nautilus again. This time, it’s coming up with a GTK+ 4-ready tagged entry for the search. Heavily inspired by Matthias’ prototype, here is a sneak peek at the work-in-progress implementation:

NautilusTaggedEntry and GtkSearchEntry for visual comparison (GTK+ 4)
GdTaggedEntry as a visual reference (GTK+ 3)

The styling still needs tweaking (I’m trying to reuse the entry-tag class from Adwaita as much as possible, but there are signs of breakage now that actual widgets are used) and the input – hooking up (oh, and the close button), but, so far, the code is infinitely simpler than that of GdTaggedEntry, which will hopefully remain to be true until the end. As of yet, the code isn’t anyplace public, but that should change by the end of the week, when all details are finalized. The code can be found at https://gitlab.gnome.org/ernestask/tagged-entry.

One downside to doing it the putting-things-into-boxen-and-adjusting-margins-and-padding way is that the new class can’t be used as a GtkSearchEntry transparently (for properties and signals), because then we run into ownership problems, but that’s nothing a simple getter can’t fix.

Anyhoo, to be continued soon-ish.

Input Event Handling in Nautilus

Designed by Smashicons from Flaticon

Gestures like these is now how almost all input is handled in Nautilus. The exception is the stuff that has no event controller counterpart in GTK+ 3.

This summer I’m working on porting Nautilus to GTK+ 4 as part of Google Summer of Code, and I’ve spent the entirety of the time on getting rid of deprecated 3.x API and obsolete ways of handling events. Despite slightly hack-ish ways of working around deprecations, it’s been smooth sailing so far – No Regressions! Almost ready to switch!

™ - one reported and fixed
† - “switch” here means staring at an endless stream of compiler errors

The hacks mostly pertain to replacing gtk_style_context_get_background_color():

Going back to event handling, the next immediate goal is to dismantle the old icon view we use, since it holds non-widget objects, which largely requires emulating GTK+ for event handling. The reason for that is simply that Nautilus predates GtkIconView and was never ported to using that (possibly for performance reasons). I’ve got code that uses gestures for button presses locally already, but will look for something better than adding a small GdkEvent clone that allows setting fields, which is required mostly for synthesizing “enter” and “leave” events for the children.

It’s a bit unfortunate that there only exists a subset of event controllers in GTK+ 3, but at the same time it’s a great opportunity to make the code GTK+ 4-compliant (still hoping to see the key event controllers soon). Where impossible to use one, I switched to handling ::event (bar some instances of ::key-press-event, where that prevented accelerator handlers from being run).

All in all, the pain has been minimal and I’m looking forward to getting back with a fresh perspective on things after the university exam period ends.

Edit: clarified the bit about the canvas view not holding widgets.

Post-GUADEC Write-Up

My first ever Gaudec [sic] is over. Unfortunately, it ended before the unconference, since I left to visit family in Scotland (didn’t want to turn the trip into a two-week vacation).

All the talks were great, and I’m sure that the ones I couldn’t attend were just as great, but I want to highlight a few:

Martin’s “Fantastic Layouts and Where to Find Them (and, most importantly, a working demo): this is powerful – showcasing a truly modern way to lay out UI elements, instead of writing blocks of XML by hand to achieve the same effect.

Jakub’s “The Inbetweens – Why Transitions Matter and Tobias’ “Building Interfaces from the Future right after: incredibly educational for someone who doesn’t have a background in design and everything that it entails, but strives to create good UIs. Even if the talks didn’t make me an expert, I’m still glad that they changed the way I think about user interface design.

Even something as “boring” as building GNOME in new ways (as opposed to something hip, like writing the code) is exciting, in that it has potential to remove tribal knowledge from existence or complex setup steps, which is highly relevant to newcomers (as can be moving to more familiar workflows (GitLab)).

Besides getting to hear about great new ideas and developments, getting to see and meet (and play Monopoly with) the people who make up GNOME was really exciting and I finally feel like I’m a part of this great community.

Without help from the Foundation, this experience would have been impossible. Thanks!

P.S. I got to be behind the camera for some of the talks, so if you see the silhouette of my head pop up on the screen, it says “hi”!


Redoing File Operation Management in Nautilus

This will serve as a sort of introduction to my project, as well as being a progress update.

Hi, I’m Ernestas and this summer I’m working on Nautilus as part of Google Summer of Code. The goal of the project is to have all I/O operations (i.e. file management, the cache, thumbnailing, searching) managed under a single entity with a capped worker thread count.

This talk by my mentor, Carlos, gives a reason why this is needed in a file manager – searching. Dropping down to the root folder and searching for something as innocent as, say, “a” will likely result in your demise, as Nautilus will happily perform an aggressive benchmark on your system instead of searching. Limiting the number of search jobs will help reduce the random reads performed by the disk as well as leaving the system in a usable state.

Another positive outcome is making the code more object-oriented – going from plain function calls and routing events in a very roundabout way to self-contained task classes with signals to provide progress information (e.g. file task progress, search hits, enumerating directory children for cache purposes) and all other nutrients required for a strong file manager. If the result is not having to split the vim window in four just to work in a nautilus-file-operations.c or nautilus-directory-async.c-equivalent file, I will be damn pleased.

The first two weeks haven’t been very eventful, as the exam schedule in my university clashes a bit with GSoC, but in a few days I will be able to return full-speed. Despite that, one of the goals has been reached – implementing a bare-bones task manager, creating a task API skeleton and porting over a file operation. The wip/ernestask/tasks branch contains the code if you’re interested.

The task manager currently allows limiting the running task count at compile time, but Carlos and I have discussed a more dynamic approach to take, once the groundwork is laid. As the task interface is generic, doing things like preventing conflicting operations as they are queued is a bit of a head-scratcher, but that will probably work out with error callbacks and the like. Another thing that is desirable is turning the manager into a scheduler of sorts, which can assign priorities to tasks, in turn letting short-lived, user-facing tasks take precedence (or something else entirely, this is yet to be decided).

Writing the tasks themselves is an experience in itself, requiring deep and wide class hierarchies (not to mention loads of private helper functions) to accomodate all idiosyncrasies of the code, but so far it’s been relatively straightforward. I’ll bet that a rain jacket will not help in the storm that is going to be shuffling around the code for the cache operations. :)

Talk to you again in a couple of weeks,