From 32655d6612e98c8f97b8e3a4eb5ef91e16a663ad Mon Sep 17 00:00:00 2001 From: infirit Date: Sun, 26 Jul 2015 02:03:20 +0200 Subject: nodoka: Shape windows without compositing --- src/themes/nodoka/nodoka-theme.c | 109 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/src/themes/nodoka/nodoka-theme.c b/src/themes/nodoka/nodoka-theme.c index aa80cd6..6c2fc0b 100644 --- a/src/themes/nodoka/nodoka-theme.c +++ b/src/themes/nodoka/nodoka-theme.c @@ -66,6 +66,8 @@ typedef struct int width; int height; + int last_width; + int last_height; guchar urgency; glong timeout; @@ -499,6 +501,98 @@ draw_pie(GtkWidget *pie, WindowData *windata, cairo_t *cr) cairo_fill (cr); } +#if GTK_CHECK_VERSION (3, 0, 0) +static void +update_shape_region (cairo_surface_t *surface, + WindowData *windata) +{ + cairo_region_t *region; + + if (windata->width == windata->last_width && windata->height == windata->last_height) + { + return; + } + + if (windata->width == 0 || windata->height == 0) + { + GtkAllocation allocation; + gtk_widget_get_allocation (windata->win, &allocation); + + windata->width = MAX (allocation.width, 1); + windata->height = MAX (allocation.height, 1); + } + + if (!windata->composited) { + cairo_region_t *region; + + region = gdk_cairo_region_create_from_surface (surface); + gtk_widget_shape_combine_region (windata->win, region); + cairo_region_destroy (region); + } else { + gtk_widget_shape_combine_region (windata->win, NULL); + return; + } + + windata->last_width = windata->width; + windata->last_height = windata->height; +} +#else +static void +update_shape_mask (WindowData* windata) +{ + cairo_t *cr; + GdkBitmap* mask; + + if (windata->width == windata->last_width && windata->height == windata->last_height) + { + return; + } + + if (windata->width == 0 || windata->height == 0) + { + GtkAllocation allocation; + + gtk_widget_get_allocation (windata->win, &allocation); + + windata->width = MAX (allocation.width, 1); + windata->height = MAX (allocation.height, 1); + } + + if (windata->composited) + { + gtk_widget_shape_combine_mask (windata->win, NULL, 0, 0); + return; + } + + windata->last_width = windata->width; + windata->last_height = windata->height; + + mask = (GdkBitmap*) gdk_pixmap_new (NULL, windata->width, windata->height, 1); + + if (mask == NULL) + { + return; + } + cr = gdk_cairo_create (mask); + + if (cairo_status (cr) == CAIRO_STATUS_SUCCESS) + { + cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); + cairo_paint (cr); + + cairo_set_operator (cr, CAIRO_OPERATOR_OVER); + cairo_set_source_rgb (cr, 1.0f, 1.0f, 1.0f); + nodoka_rounded_rectangle (cr, 0, 0, windata->width , windata->height, 6); + cairo_fill (cr); + + gtk_widget_shape_combine_mask (windata->win, mask, 0, 0); + } + + cairo_destroy (cr); + g_object_unref (mask); +} +#endif + static gboolean paint_window(GtkWidget *widget, #if GTK_CHECK_VERSION (3, 0, 0) @@ -563,6 +657,12 @@ paint_window(GtkWidget *widget, cairo_paint (cr); cairo_restore (cr); +#if GTK_CHECK_VERSION (3, 0, 0) + update_shape_region (surface, windata); +#else + update_shape_mask (windata); +#endif + #if !GTK_CHECK_VERSION (3, 0, 0) cairo_destroy(cr); #endif @@ -586,6 +686,13 @@ configure_event_cb(GtkWidget *nw, return FALSE; } +static void on_composited_changed (GtkWidget* window, WindowData* windata) +{ + windata->composited = gdk_screen_is_composited (gtk_widget_get_screen(window)); + + gtk_widget_queue_draw (window); +} + static gboolean countdown_expose_cb(GtkWidget *pie, #if GTK_CHECK_VERSION (3, 0, 0) @@ -732,6 +839,8 @@ create_notification(UrlClickedCb url_clicked) g_signal_connect(G_OBJECT(win), "configure_event", G_CALLBACK(configure_event_cb), windata); + g_signal_connect (G_OBJECT (win), "composited-changed", G_CALLBACK (on_composited_changed), windata); + /* * For some reason, there are occasionally graphics glitches when * repainting the window. Despite filling the window with a background -- cgit v1.2.1