Commit 30de295c authored by Michael Natterer's avatar Michael Natterer 😴

app: make the alpha channel work on canvas overlay widgets

* app/widgets/gimpoverlaychild.c: when creating offscreen windows, try
  to set an RGBA colormap on the offscreen window's widget and use the
  RGBA colormap to create the window. This has to be done here,
  because it's not possible to get to the right screen *inside* the
  offscreen widget before it's parented, and we need that screen
  before the widget is realized, and the widget can't be parented
  before it's realized or it will get the wrong parent window.
  Everything clear now?

* app/widgets/gimpoverlayframe.c: draw the round corners only if the
  screen has an RGBA colormap.
parent c37c0024
......@@ -129,6 +129,8 @@ gimp_overlay_child_realize (GimpOverlayBox *box,
{
GtkWidget *widget;
GdkDisplay *display;
GdkScreen *screen;
GdkColormap *colormap;
GtkAllocation child_allocation;
GdkWindowAttr attributes;
gint attributes_mask;
......@@ -139,6 +141,11 @@ gimp_overlay_child_realize (GimpOverlayBox *box,
widget = GTK_WIDGET (box);
display = gtk_widget_get_display (widget);
screen = gtk_widget_get_screen (widget);
colormap = gdk_screen_get_rgba_colormap (screen);
if (colormap)
gtk_widget_set_colormap (child->widget, colormap);
gtk_widget_get_allocation (child->widget, &child_allocation);
......@@ -157,9 +164,9 @@ gimp_overlay_child_realize (GimpOverlayBox *box,
attributes.y = child_allocation.y;
attributes.window_type = GDK_WINDOW_OFFSCREEN;
attributes.wclass = GDK_INPUT_OUTPUT;
attributes.visual = gtk_widget_get_visual (widget);
attributes.colormap = gtk_widget_get_colormap (widget);
attributes.event_mask = gtk_widget_get_events (widget);
attributes.visual = gtk_widget_get_visual (child->widget);
attributes.colormap = gtk_widget_get_colormap (child->widget);
attributes.event_mask = gtk_widget_get_events (child->widget) | GDK_EXPOSURE_MASK;
attributes.cursor = gdk_cursor_new_for_display (display, GDK_LEFT_PTR);
attributes_mask = (GDK_WA_X |
......@@ -345,11 +352,13 @@ gimp_overlay_child_expose (GimpOverlayBox *box,
}
else if (event->window == child->window)
{
gtk_paint_flat_box (gtk_widget_get_style (widget),
#if 0
gtk_paint_flat_box (gtk_widget_get_style (child->widget),
event->window,
GTK_STATE_NORMAL, GTK_SHADOW_NONE,
&event->area, widget, NULL,
0, 0, -1, -1);
#endif
gtk_container_propagate_expose (GTK_CONTAINER (widget),
child->widget,
......
......@@ -53,19 +53,7 @@ gimp_overlay_frame_class_init (GimpOverlayFrameClass *klass)
static void
gimp_overlay_frame_init (GimpOverlayFrame *frame)
{
GtkWidget *widget = GTK_WIDGET (frame);
#if 0 /* crashes badly beause gtk+ doesn't support offscreen windows
* with colormap != parent_colormap yet
*/
GdkScreen *screen = gtk_widget_get_screen (widget);
GdkColormap *rgba = gdk_screen_get_rgba_colormap (screen);
if (rgba)
gtk_widget_set_colormap (widget, rgba);
#endif
gtk_widget_set_app_paintable (widget, TRUE);
gtk_widget_set_app_paintable (GTK_WIDGET (frame), TRUE);
}
static void
......@@ -122,62 +110,76 @@ static gboolean
gimp_overlay_frame_expose (GtkWidget *widget,
GdkEventExpose *eevent)
{
cairo_t *cr = gdk_cairo_create (gtk_widget_get_window (widget));
GtkStyle *style = gtk_widget_get_style (widget);
GtkAllocation allocation;
gint border_width;
gtk_widget_get_allocation (widget, &allocation);
cairo_t *cr = gdk_cairo_create (gtk_widget_get_window (widget));
GtkStyle *style = gtk_widget_get_style (widget);
gboolean rgba;
border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
rgba = gdk_screen_get_rgba_colormap (gtk_widget_get_screen (widget)) != NULL;
cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
gdk_cairo_region (cr, eevent->region);
cairo_clip_preserve (cr);
cairo_fill (cr);
if (rgba)
{
cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
gdk_cairo_region (cr, eevent->region);
cairo_clip_preserve (cr);
cairo_fill (cr);
}
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
gdk_cairo_set_source_color (cr, &style->bg[GTK_STATE_NORMAL]);
if (rgba)
{
GtkAllocation allocation;
gint border_width;
gtk_widget_get_allocation (widget, &allocation);
border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
#define DEG_TO_RAD(deg) ((deg) * (G_PI / 180.0))
cairo_arc (cr,
border_width,
border_width,
border_width,
DEG_TO_RAD (180),
DEG_TO_RAD (270));
cairo_line_to (cr,
cairo_arc (cr,
border_width,
border_width,
border_width,
DEG_TO_RAD (180),
DEG_TO_RAD (270));
cairo_line_to (cr,
allocation.width - border_width,
0);
cairo_arc (cr,
allocation.width - border_width,
0);
cairo_arc (cr,
allocation.width - border_width,
border_width,
border_width,
DEG_TO_RAD (270),
DEG_TO_RAD (0));
cairo_line_to (cr,
allocation.width,
allocation.height - border_width);
cairo_arc (cr,
allocation.width - border_width,
allocation.height - border_width,
border_width,
DEG_TO_RAD (0),
DEG_TO_RAD (90));
cairo_line_to (cr,
border_width,
allocation.height);
cairo_arc (cr,
border_width,
allocation.height - border_width,
border_width,
DEG_TO_RAD (90),
DEG_TO_RAD (180));
cairo_close_path (cr);
border_width,
DEG_TO_RAD (270),
DEG_TO_RAD (0));
cairo_line_to (cr,
allocation.width,
allocation.height - border_width);
cairo_arc (cr,
allocation.width - border_width,
allocation.height - border_width,
border_width,
DEG_TO_RAD (0),
DEG_TO_RAD (90));
cairo_line_to (cr,
border_width,
allocation.height);
cairo_arc (cr,
border_width,
allocation.height - border_width,
border_width,
DEG_TO_RAD (90),
DEG_TO_RAD (180));
cairo_close_path (cr);
}
else
{
gdk_cairo_region (cr, eevent->region);
}
cairo_fill (cr);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment