[gnome-desktop] rr-labeler: use a shape region if the widget is not composited
- From: Cosimo Cecchi <cosimoc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-desktop] rr-labeler: use a shape region if the widget is not composited
- Date: Wed, 26 Sep 2012 16:44:39 +0000 (UTC)
commit f92b50c28219f364e8978f9f4c856545cb7b729e
Author: Cosimo Cecchi <cosimoc gnome org>
Date: Tue Sep 25 16:15:39 2012 -0400
rr-labeler: use a shape region if the widget is not composited
Stolen pretty much as-is from the identical code in GtkTooltip. This
ensures the labels always stay round and with no artifacts below the
corners even in non-composited environments.
https://bugzilla.gnome.org/show_bug.cgi?id=684814
libgnome-desktop/gnome-rr-labeler.c | 83 +++++++++++++++++++++++++++++++----
1 files changed, 74 insertions(+), 9 deletions(-)
---
diff --git a/libgnome-desktop/gnome-rr-labeler.c b/libgnome-desktop/gnome-rr-labeler.c
index 918e106..e0c5a84 100644
--- a/libgnome-desktop/gnome-rr-labeler.c
+++ b/libgnome-desktop/gnome-rr-labeler.c
@@ -268,23 +268,25 @@ rounded_rectangle (cairo_t *cr,
* to match the corner radius */
#define LABEL_CORNER_RADIUS 6 + LABEL_WINDOW_EDGE_THICKNESS
-static gboolean
-label_window_draw_event_cb (GtkWidget *widget, cairo_t *cr, gpointer data)
+static void
+label_draw_background_and_frame (GtkWidget *widget, cairo_t *cr, gboolean for_shape)
{
+ GdkRGBA shape_color = { 0, 0, 0, 1 };
GdkRGBA *rgba;
GtkAllocation allocation;
rgba = g_object_get_data (G_OBJECT (widget), "rgba");
gtk_widget_get_allocation (widget, &allocation);
+ cairo_save (cr);
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
- /* clear any content */
- cairo_set_source_rgba (cr, 0, 0, 0, 0);
- cairo_paint (cr);
-
/* edge outline */
- cairo_set_source_rgba (cr, 0, 0, 0, 0.5);
+ if (for_shape)
+ gdk_cairo_set_source_rgba (cr, &shape_color);
+ else
+ cairo_set_source_rgba (cr, 0, 0, 0, 0.5);
+
rounded_rectangle (cr,
LABEL_WINDOW_EDGE_THICKNESS / 2.0,
LABEL_WINDOW_EDGE_THICKNESS / 2.0,
@@ -295,8 +297,13 @@ label_window_draw_event_cb (GtkWidget *widget, cairo_t *cr, gpointer data)
cairo_stroke (cr);
/* fill */
- rgba->alpha = 0.75;
- gdk_cairo_set_source_rgba (cr, rgba);
+ if (for_shape) {
+ gdk_cairo_set_source_rgba (cr, &shape_color);
+ } else {
+ rgba->alpha = 0.75;
+ gdk_cairo_set_source_rgba (cr, rgba);
+ }
+
rounded_rectangle (cr,
LABEL_WINDOW_EDGE_THICKNESS,
LABEL_WINDOW_EDGE_THICKNESS,
@@ -305,6 +312,53 @@ label_window_draw_event_cb (GtkWidget *widget, cairo_t *cr, gpointer data)
LABEL_CORNER_RADIUS, LABEL_CORNER_RADIUS);
cairo_fill (cr);
+ cairo_restore (cr);
+}
+
+static void
+maybe_update_shape (GtkWidget *widget)
+{
+ cairo_t *cr;
+ cairo_surface_t *surface;
+ cairo_region_t *region;
+
+ /* fallback to XShape only for non-composited clients */
+ if (gtk_widget_is_composited (widget)) {
+ gtk_widget_shape_combine_region (widget, NULL);
+ return;
+ }
+
+ surface = gdk_window_create_similar_surface (gtk_widget_get_window (widget),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ gtk_widget_get_allocated_width (widget),
+ gtk_widget_get_allocated_height (widget));
+
+ cr = cairo_create (surface);
+ label_draw_background_and_frame (widget, cr, TRUE);
+ cairo_destroy (cr);
+
+ region = gdk_cairo_region_create_from_surface (surface);
+ gtk_widget_shape_combine_region (widget, region);
+
+ cairo_surface_destroy (surface);
+ cairo_region_destroy (region);
+}
+
+static gboolean
+label_window_draw_event_cb (GtkWidget *widget, cairo_t *cr, gpointer data)
+{
+ if (gtk_widget_is_composited (widget)) {
+ /* clear any content */
+ cairo_save (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_rgba (cr, 0, 0, 0, 0);
+ cairo_paint (cr);
+ cairo_restore (cr);
+ }
+
+ maybe_update_shape (widget);
+ label_draw_background_and_frame (widget, cr, FALSE);
+
return FALSE;
}
@@ -337,6 +391,15 @@ label_window_realize_cb (GtkWidget *widget)
region = cairo_region_create ();
gtk_widget_input_shape_combine_region (widget, region);
cairo_region_destroy (region);
+
+ maybe_update_shape (widget);
+}
+
+static void
+label_window_composited_changed_cb (GtkWidget *widget, GnomeRRLabeler *labeler)
+{
+ if (gtk_widget_get_realized (widget))
+ maybe_update_shape (widget);
}
static GtkWidget *
@@ -373,6 +436,8 @@ create_label_window (GnomeRRLabeler *labeler, GnomeRROutputInfo *output, GdkRGBA
G_CALLBACK (label_window_draw_event_cb), labeler);
g_signal_connect (window, "realize",
G_CALLBACK (label_window_realize_cb), labeler);
+ g_signal_connect (window, "composited-changed",
+ G_CALLBACK (label_window_composited_changed_cb), labeler);
if (gnome_rr_config_get_clone (labeler->priv->config)) {
/* Keep this string in sync with gnome-control-center/capplets/display/xrandr-capplet.c:get_display_name() */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]