← home

GTK4 Cursor Manipulation

02 Jun 2022 - mat

A cursor can be used as a visual hint to users on how can they interact with an app. For example, for a pointer cursor, it is implied that an element is clickable. Progress cursor indicates that the application is currently working, and the user should wait.

In this post, we’ll look at various method we can use to modify cursor in GTK4.

Change Cursor on Hover

This usecase is used to give users a hint on how they can interact with an application element. In example pointer cursor over a button, text cursor over a text input, and so on.

Thankfully, unlike in GTK3, we can invoke a function call to set this instead of setting up the event manually. We have two functions for this:

gtk_widget_set_cursor

This function took 2 parameters. Widget pointer and cursor object. The Widget parameter is straightforward, it is the widget that we are going to give the hover cursor. The cursor parameter is a gdk object and it is nullable. In case the parameter is null, it will use the default cursor.

Take a look at the below snippet:

GtkButton *btn = gtk_button_new_with_label("hover me");
GdkCursor *cursor = gdk_cursor_new_from_name("pointer", NULL);
gtk_widget_set_cursor(btn, cursor);

Above, we created a new button and cursor. The cursor is a gdk object with a pointer as the cursor. You can refer to the gdk documentation for the list of available cursor names. Alternatively, you can use a custom image as a cursor with gdk_cursor_new_from_texture.

Note: if you are developing in Gnome Builder the cursor might not be changed if you run your project using the gui apps (ctrl+f5). You need to export the bundle and then run it manually (or install the exported flatpak project first) to make it work.

As you can see the cursor is automatically changed to pointer once it’s hovering on the button. In the next section, we’ll look at how to simplify this process even more.

gtk_widget_set_cursor_from_name

GTK has provided us with a shortcut for the above snippet. Take a look at the below snippet:

GtkButton *btn = gtk_button_new_with_label("hover me simple");
gtk_widget_set_cursor_from_name(btn, "pointer");

Using gtk_widget_set_cursor_from_name we can simply provide the cursor type name, without any need to create the cursor object ourselves. Take note that the cursor name is nullable. In this case, the widget will use the cursor inherited from the parent widget.

Change Cursor for Window

In GTK3 we have gdk_window_set_cursor which will change the cursor for a given window. It’s been deprecated in GTK4. Instead, we can use the function above by passing the window as our widget.

GtkWidget *window = gtk_application_window_new (app);
gtk_widget_set_cursor_from_name(window, "pointer");

As you can see, there’s no different than the previous snippet. The only difference is that we pass the window as a widget in exchange for the previous button.


To be completely honest, I choose this topic because I have spent hours debugging my project. Before I realize that the cursor won’t be changed if you run it inside the gnome-builder lol. Hopefully, this post can help you to avoid repeating my mistake. See you in another post!

← home