Accéder au contenu principal

Writing a custom spinner

What are spinners

A spinner is a widget in charge of displaying some indefinite amount of activity via a spinning circle-ish image. They use de "spinner" style class and are visible when the "active" state flag is set.

Turning a widget into a spinner

Turning a widget into a spinner is pretty simple, just add the "spinner" style class to the widget's style context! But now your widget is probably invisible, and that's normal: as said just before, spinners are drawn only if they have the "active" state flag on, just set your widget's state flags and you're done!

Now, depending on the widget you make spin you may have very different results. If your widget is a GtkImage, it will start spinning as if it was a spinner itself, funky results (and vomit) guaranteed! All the other widgets I tested (GtkLabel, GtkBox, …) don't change (they are visible and they don't spin).

If you want to render a spinner on an existing widget, you'll have to subclass it and to override its gtk_widget_draw() method to draw it and then render the spinner with gtk_render_activity().

If you want to render a spinner on an image, you'll unfortunately have to write a custom widget drawing the image and then the spinner on top of it.

Writing a custom spinner widget

Now that we know how to turn a widget into a spinner, we can build our very own custom spinner widgets!

I wrote a widget rendering a thumbnail for Boxes' list view. To do so:

  • I inherited GtkDrawingArea,
  • I overrode its gtk_widget_draw() method to draw it as I wanted,
  • I added the "spinner" style class to the widget so it can render the spinner,
  • I set the widget as active so it can be visible despite the "spinner" style class,
  • I drew the base of my widget as I wanted it to be,
  • I drew the spinner with gtk_render_activity() on top when I wanted it to be drawn.

Unfortunately you can't use the "active" state as a trigger without removing the "spinner" style class, hence it is simpler to just let them always on and add a custom trigger to draw the spinner itself or not.

Customizing the spinner

You can customize a spinner with CSS! As an exemple, if you want to slow down the spinner a bit, you can write the following "slow-spinner" class and add it to any spinner's style context:

.slow-spinner {
    animation-duration: 2s;

If you know or learn anything interesting about spinners, don't hesitate to share you knowledge in the comments! =)


Posts les plus consultés de ce blog

GTK+ Apps on Phones

As some of you may already know, I recently joined Purism to help developing GTK+ apps for the upcoming Librem 5 phone.Purism and GNOME share a lot of ideas and values, so the GNOME HIG and GNOME apps are what we will focus on primarily: we will do all we can to not fork nor to reinvent the wheel but to help allowing existing GTK+ applications to work on phones.How Fit are Existing GTK+ Apps?Phones are very different from laptops and even tablets: their screen is very small and their main input method is a single thumb on a touchscreen. Luckily, many GNOME applications are touch-friendly and are fit for small screens. Many applications present you a tree of information you can browse and I see two main layouts used by for GNOME applications to let you navigate it.A first kind of layout is found in applications like Documents, I'll call it stack UI: it uses all the available space to display the collection of information sources (in that case, documents), clicking an element from t…

The Path to GNOME Games 3.26

Games received a non-negligible amount of changes that you will find in 3.26. These changes can be big as much small, and more are to come!Building the Games CollectionGames presents your games collection and if everything goes as expected, it does so without the need of any input from you. From an implementation point of view it sounds simple to do, just ask Tracker “Hey, gimme all the games” and it’s done. If only it was that simple! 😃 The system has no idea which files represent games and which doesn’t, but it can associate a MIME type to each file thanks to shared-mime-info. shared-mime-info already had a few video game related MIME types and we added a lot more such as application/x-genesis-rom.That done, we can query Tracker for files having specific MIME types that we know to often represent video game files. Unfortunately, each of these files doesn’t necessarily represent a game and a game isn’t necessarily represented by a single file: some files may be invalid and hence rep…

One Widget to Adapt Them All and to The Librem 5 Port Them

In my previous article I shared my plans to help porting existing GTK+ applications to Purism's upcoming Librem 5 phone without having to fork them. This article will present the GTK+ widget I developed for Purism to make this happen.For more information on what Purism is working on for the Librem 5, please check Nicole Faerber's latest article.C'est pas sorcierThe underlying idea is to allow applications to dynamically switch between the two main GNOME application layouts: a row of panels — each panel being the view of an element from the previous one — and a stack of panels. The goal isn't to changes applications using the stack paradigm but the ones using the row one, allowing them to reach smaller sizes and to be usable on constrained sizes while keeping their initial paradigm and design when the screen space is sufficient. The development cost to port the applications to this adaptive design should be as low as possible.To achieve that, I wrote a GTK+ widget which…