1

I am trying to precisely control the content of a GTK tooltip, but whatever I do, there is always a border remaining.

My real content is much more advanced, but the problem is 100% reproduced with just a gtk_label. The gtk container whose class is tooltip and which contains my custom widget has a weird border/padding behavior: if I add border, only the 6 outer pixels are visible, and if the border drops below 6px, a weird extra padding using the background-color takes over, and the effective border never gets below these 6px:

Border around tooltip

Here is the minimal source code to reproduce with border: 0;:

// Compile with:
// gcc tooltip.c -o tooltip `pkg-config --cflags --libs gtk+-3.0`
#include <gtk/gtk.h>
static gboolean on_query_tooltip(GtkWidget *, gint, gint, gboolean, GtkTooltip *tooltip, gpointer) {
 GtkWidget *label = gtk_label_new(NULL);
 gtk_label_set_text(GTK_LABEL(label), "Single content.");
 gtk_widget_show_all(label);
 gtk_tooltip_set_custom(tooltip, label);
 return TRUE;
}
int main(int argc, char **argv) {
 gtk_init(&argc, &argv);
 const gchar *css =
 "tooltip {"
 " background-color: #f00;"
 " padding: 0;"
 " margin: 0;"
 " border: 0;"
 " border-radius: 0;"
 "}"
 "tooltip > box {"
 " background-color: #00f;"
 " padding: 0;"
 " margin: 0;"
 " border: 0;"
 "}"
 "tooltip > box > label {"
 " background-color: #0f0;"
 " color: #000;"
 " padding: 0;"
 " margin: 0;"
 " border: 0;"
 " text-shadow: none;"
 "}";
 GtkCssProvider *prov = gtk_css_provider_new();
 GError *err = NULL;
 gtk_css_provider_load_from_data(prov, css, -1, &err);
 if (err) { g_printerr("CSS error: %s\n", err->message); g_error_free(err); }
 gtk_style_context_add_provider_for_screen(
 gdk_screen_get_default(), GTK_STYLE_PROVIDER(prov),
 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
 g_object_unref(prov);
 GtkWidget *win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 gtk_window_set_default_size(GTK_WINDOW(win), 200, 100);
 g_signal_connect(win, "destroy", G_CALLBACK(gtk_main_quit), NULL);
 GtkWidget *label = gtk_label_new("hover me");
 gtk_widget_set_halign(label, GTK_ALIGN_CENTER);
 gtk_widget_set_valign(label, GTK_ALIGN_CENTER);
 gtk_widget_set_has_tooltip(label, TRUE);
 g_signal_connect(label, "query-tooltip", G_CALLBACK(on_query_tooltip), NULL);
 gtk_container_add(GTK_CONTAINER(win), label);
 gtk_widget_show_all(win);
 gtk_main();
 return 0;
}

I suspect that this 6px border was hardcoded somewhere to make the default border-radius: 6px work, but I can't find any reference to this.

Progman
20.1k7 gold badges60 silver badges89 bronze badges
asked Sep 24, 2025 at 9:22

1 Answer 1

0

This 6px border is hard coded, it can't be modified by a GTK program. The solution is to use my own tooltip window. Here is a minimal example for anyone having the same issue.

#include <gtk/gtk.h>
static gboolean
on_query_tooltip(GtkWidget *widget, gint x, gint y, gboolean keyboard_mode,
 GtkTooltip *tooltip, gpointer user_data)
{
 // We are using our own tooltip window; do NOT use gtk_tooltip_set_custom() here.
 GtkWindow *tw = gtk_widget_get_tooltip_window(widget);
 if (!tw) return FALSE; // shouldn't happen once we've set a custom window
 // The window is a GtkBin -\> get its first child (our box)
 GtkWidget *box = gtk_bin_get_child(GTK_BIN(tw));
 // Clear any previous content
 if (box) {
 GList *children = gtk_container_get_children(GTK_CONTAINER(box));
 for (GList *l = children; l; l = l-\>next)
 gtk_container_remove(GTK_CONTAINER(box), GTK_WIDGET(l-\>data));
 g_list_free(children);
 }
 // Add your content
 GtkWidget *label = gtk_label_new("Single content.");
 gtk_container_add(GTK_CONTAINER(box), label);
 gtk_widget_show_all(GTK_WIDGET(box));
 return TRUE;
}
int main(int argc, char **argv)
{
 gtk_init(&argc, &argv);
 const gchar *css =
 ".tooltip {"
 " background-color: #fff;"
 "}";
 GtkCssProvider *prov = gtk_css_provider_new();
 gtk_css_provider_load_from_data(prov, css, -1, NULL);
 gtk_style_context_add_provider_for_screen(gdk_screen_get_default(),
 GTK_STYLE_PROVIDER(prov), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
 g_object_unref(prov);
 GtkWidget *win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 gtk_window_set_default_size(GTK_WINDOW(win), 200, 100);
 g_signal_connect(win, "destroy", G_CALLBACK(gtk_main_quit), NULL);
 GtkWidget *label = gtk_label_new("hover me");
 gtk_widget_set_halign(label, GTK_ALIGN_CENTER);
 gtk_widget_set_valign(label, GTK_ALIGN_CENTER);
 gtk_container_add(GTK_CONTAINER(win), label);
 // Create our own tooltip window (no 6px margins)
 GtkWidget *tipwin = gtk_window_new(GTK_WINDOW_POPUP);
 gtk_window_set_type_hint(GTK_WINDOW(tipwin), GDK_WINDOW_TYPE_HINT_TOOLTIP);
 // Give it the usual tooltip classes so CSS applies
 GtkStyleContext *ctx = gtk_widget_get_style_context(tipwin);
 gtk_style_context_add_class(ctx, "tooltip");
 GtkWidget *box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
 gtk_container_add(GTK_CONTAINER(tipwin), box);
 gtk_widget_show(box);
 // Use our window for this widget’s tooltip
 gtk_widget_set_tooltip_window(label, GTK_WINDOW(tipwin));
 gtk_widget_set_has_tooltip(label, TRUE);
 g_signal_connect(label, "query-tooltip", G_CALLBACK(on_query_tooltip), NULL);
 gtk_widget_show_all(win);
 gtk_main();
 return 0;
}
answered Oct 4, 2025 at 10:45
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.