I’m trying to achieve smooth rounding of corners for a child widget. In order to apply this rounding to nested widgets later on, I use region clipping, but the corners look jagged. Is there a way to do this with antialiasing in gtk3? I use this code:
#include <gtk/gtk.h>
#include <gtk/gtkx.h>
#include <cairo.h>
static void set_rounded_corners(GtkWidget *widget, double radius)
{
if (GdkWindow *gdk_window = gtk_widget_get_window(widget)) {
int width = gtk_widget_get_allocated_width(widget);
int height = gtk_widget_get_allocated_height(widget);
cairo_surface_t *sfc = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
cairo_t *cr = cairo_create(sfc);
cairo_set_antialias(cr, CAIRO_ANTIALIAS_BEST);
cairo_set_source_rgba(cr, 1, 1, 1, 1);
cairo_move_to(cr, radius, 0);
cairo_arc(cr, width - radius, radius, radius, -G_PI_2, 0);
cairo_arc(cr, width - radius, height - radius, radius, 0, G_PI_2);
cairo_arc(cr, radius, height - radius, radius, G_PI_2, G_PI);
cairo_arc(cr, radius, radius, radius, G_PI, -G_PI_2);
cairo_close_path(cr);
cairo_fill(cr);
cairo_surface_t *sfc_tgt = cairo_get_target(cr);
cairo_surface_flush(sfc_tgt);
cairo_region_t *mask = gdk_cairo_region_create_from_surface(sfc_tgt);
gdk_window_shape_combine_region(gdk_window, mask, 0, 0);
cairo_region_destroy(mask);
cairo_destroy(cr);
cairo_surface_destroy(sfc);
}
}
static void on_size_allocate(GtkWidget *widget, GdkRectangle*, gpointer)
{
set_rounded_corners(widget, 6);
}
int main(int argc, char *argv[])
{
gtk_init(&argc, &argv);
... // create top_level_window window
gtk_widget_set_app_paintable(top_level_window, TRUE);
GdkScreen *scr = gtk_widget_get_screen(top_level_window);
GdkVisual *vis = gdk_screen_get_rgba_visual(scr);
gtk_widget_set_visual(top_level_window, vis);
... // create child_widget
g_signal_connect(G_OBJECT(child_widget), "size-allocate", G_CALLBACK(on_size_allocate), NULL);
gtk_main();
}