diff --git a/src/Makefile.am b/src/Makefile.am index 168bd7251..1037c34b8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -45,6 +45,8 @@ mutter_SOURCES= \ compositor/tidy/tidy-texture-frame.h \ gdk-compat.h \ gtk-compat.h \ + gdk2-drawing-utils.c \ + gdk2-drawing-utils.h \ include/compositor.h \ include/mutter-plugin.h \ include/mutter-window.h \ @@ -146,6 +148,8 @@ libmutter_private_la_SOURCES= \ ui/preview-widget.c \ ui/preview-widget.h \ include/region.h \ + gdk2-drawing-utils.c \ + gdk2-drawing-utils.h \ ui/theme-parser.c \ ui/theme-parser.h \ ui/theme.c \ diff --git a/src/gdk-compat.h b/src/gdk-compat.h index 501b4f438..1554af3d5 100644 --- a/src/gdk-compat.h +++ b/src/gdk-compat.h @@ -2,6 +2,7 @@ #define __GDK_COMPAT_H__ #include +#include /* Provide a compatibility layer for accessor function introduced * in GTK+ 2.22 which we need to build without deprecated GDK symbols. @@ -15,6 +16,33 @@ #endif /*GTK_CHECK_VERSION */ +static inline gboolean +gdk_cairo_get_clip_rectangle (cairo_t *cr, + GdkRectangle *rect) +{ + double x1, y1, x2, y2; + gboolean clip_exists; + + cairo_clip_extents (cr, &x1, &y1, &x2, &y2); + + clip_exists = x1 < x2 && y1 < y2; + + if (rect) + { + x1 = floor (x1); + y1 = floor (y1); + x2 = ceil (x2); + y2 = ceil (y2); + + rect->x = CLAMP (x1, G_MININT, G_MAXINT); + rect->y = CLAMP (y1, G_MININT, G_MAXINT); + rect->width = CLAMP (x2 - x1, G_MININT, G_MAXINT); + rect->height = CLAMP (y2 - y1, G_MININT, G_MAXINT); + } + + return clip_exists; +} + /* Compatibility with old GDK key symbols */ #ifndef GDK_KEY_Escape diff --git a/src/gdk2-drawing-utils.c b/src/gdk2-drawing-utils.c new file mode 100644 index 000000000..558d56338 --- /dev/null +++ b/src/gdk2-drawing-utils.c @@ -0,0 +1,174 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2010 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include + +#include "gdk2-drawing-utils.h" + +#include + +#include "gdk-compat.h" + +static const cairo_user_data_key_t context_key; + +cairo_t * +meta_cairo_create (GdkDrawable *drawable) +{ + cairo_t *cr; + + cr = gdk_cairo_create (drawable); + cairo_set_user_data (cr, &context_key, drawable, NULL); + + return cr; +} + +static GdkWindow * +extract_window (cairo_t *cr, + int *dx, + int *dy, + GdkRectangle *clip_area) +{ + GdkWindow *window = cairo_get_user_data (cr, &context_key); + cairo_matrix_t matrix; + + g_assert (dx != NULL); + g_assert (dy != NULL); + g_assert (clip_area != NULL); + + /* lots of stuff that mustn't happen because we can't cope with it. */ + if (window == NULL) + { + g_error ("Could not get the GdkWindow from the cairo context passed to\n" + "theme drawing functions. A GdkWindow must be set on all cairo\n" + "context passed to theme drawing functions when using GTK2.\n" + "Please use meta_cairo_create() to create the Cairo context.\n"); + } + cairo_get_matrix (cr, &matrix); + if (matrix.xx != 1.0 || matrix.yy != 1.0 || + matrix.xy != 0.0 || matrix.yx != 0.0 || + floor (matrix.x0) != matrix.x0 || + floor (matrix.y0) != matrix.y0) + { + g_error ("GTK2 drawing requires that the matrix set on the cairo context\n" + "is an integer translation, however that is not the case.\n"); + } + + gdk_cairo_get_clip_rectangle (cr, clip_area); + clip_area->x += matrix.x0; + clip_area->y += matrix.y0; + + *dx = matrix.x0; + *dy = matrix.y0; + + return window; +} + +void +meta_paint_vline (GtkStyle *style, + cairo_t *cr, + GtkStateType state_type, + GtkWidget *widget, + const gchar *detail, + gint y1_, + gint y2_, + gint x) +{ + int dx, dy; + GdkWindow *window; + GdkRectangle area; + + window = extract_window (cr, &dx, &dy, &area); + + gtk_paint_vline (style, window, state_type, &area, + widget, detail, y1_ + dy, y2_ + dy, x + dx); +} + +void +meta_paint_arrow (GtkStyle *style, + cairo_t *cr, + GtkStateType state_type, + GtkShadowType shadow_type, + GtkWidget *widget, + const gchar *detail, + GtkArrowType arrow_type, + gboolean fill, + gint x, + gint y, + gint width, + gint height) +{ + int dx, dy; + GdkWindow *window; + GdkRectangle area; + + window = extract_window (cr, &dx, &dy, &area); + + gtk_paint_arrow (style, window, state_type, shadow_type, + &area, widget, detail, arrow_type, + fill, x + dx, y + dy, width, height); +} + +void +meta_paint_box (GtkStyle *style, + cairo_t *cr, + GtkStateType state_type, + GtkShadowType shadow_type, + GtkWidget *widget, + const gchar *detail, + gint x, + gint y, + gint width, + gint height) +{ + int dx, dy; + GdkWindow *window; + GdkRectangle area; + + window = extract_window (cr, &dx, &dy, &area); + + gtk_paint_box (style, window, state_type, shadow_type, + &area, widget, detail, + x + dx, y + dy, width, height); +} + +void +meta_paint_flat_box (GtkStyle *style, + cairo_t *cr, + GtkStateType state_type, + GtkShadowType shadow_type, + GtkWidget *widget, + const gchar *detail, + gint x, + gint y, + gint width, + gint height) +{ + int dx, dy; + GdkWindow *window; + GdkRectangle area; + + window = extract_window (cr, &dx, &dy, &area); + + gtk_paint_flat_box (style, window, state_type, shadow_type, + &area, widget, detail, + x + dx, y + dy, width, height); +} + diff --git a/src/gdk2-drawing-utils.h b/src/gdk2-drawing-utils.h new file mode 100644 index 000000000..d3ce3026a --- /dev/null +++ b/src/gdk2-drawing-utils.h @@ -0,0 +1,71 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2010 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef __GTK3_COMPAT_H__ +#define __GTK3_COMPAT_H__ + +#include + +/* This function only exists for GTK2 code. */ +cairo_t * meta_cairo_create (GdkDrawable *drawable); + +void meta_paint_vline (GtkStyle *style, + cairo_t *cr, + GtkStateType state_type, + GtkWidget *widget, + const gchar *detail, + gint y1_, + gint y2_, + gint x); +void meta_paint_arrow (GtkStyle *style, + cairo_t *cr, + GtkStateType state_type, + GtkShadowType shadow_type, + GtkWidget *widget, + const gchar *detail, + GtkArrowType arrow_type, + gboolean fill, + gint x, + gint y, + gint width, + gint height); +void meta_paint_box (GtkStyle *style, + cairo_t *cr, + GtkStateType state_type, + GtkShadowType shadow_type, + GtkWidget *widget, + const gchar *detail, + gint x, + gint y, + gint width, + gint height); +void meta_paint_flat_box (GtkStyle *style, + cairo_t *cr, + GtkStateType state_type, + GtkShadowType shadow_type, + GtkWidget *widget, + const gchar *detail, + gint x, + gint y, + gint width, + gint height); + +#endif /* __GTK3_COMPAT_H__ */ diff --git a/src/ui/frames.c b/src/ui/frames.c index fa59b6ad0..b952cab5b 100644 --- a/src/ui/frames.c +++ b/src/ui/frames.c @@ -36,6 +36,7 @@ #include "prefs.h" #include "ui.h" +#include "gdk2-drawing-utils.h" #include "gtk-compat.h" #include "gdk-compat.h" @@ -2384,6 +2385,7 @@ meta_frames_paint_to_drawable (MetaFrames *frames, MetaButtonLayout button_layout; MetaGrabOp grab_op; Display *display; + cairo_t *cr; widget = GTK_WIDGET (frames); display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); @@ -2496,11 +2498,12 @@ meta_frames_paint_to_drawable (MetaFrames *frames, meta_prefs_get_button_layout (&button_layout); + cr = meta_cairo_create (drawable); + meta_theme_draw_frame_with_style (meta_theme_get_current (), frame->style, widget, - drawable, - NULL, /* &areas[i], */ + cr, x_offset, y_offset, type, flags, @@ -2510,6 +2513,8 @@ meta_frames_paint_to_drawable (MetaFrames *frames, &button_layout, button_states, mini_icon, icon); + + cairo_destroy (cr); } static void diff --git a/src/ui/preview-widget.c b/src/ui/preview-widget.c index 87229e062..87b641afb 100644 --- a/src/ui/preview-widget.c +++ b/src/ui/preview-widget.c @@ -28,6 +28,8 @@ #include #include "preview-widget.h" +#include "gdk2-drawing-utils.h" + static void meta_preview_size_request (GtkWidget *widget, GtkRequisition *req); static void meta_preview_size_allocate (GtkWidget *widget, @@ -220,10 +222,15 @@ meta_preview_expose (GtkWidget *widget, if (preview->theme) { + cairo_t *cr; + + cr = meta_cairo_create (gtk_widget_get_window (widget)); + gdk_cairo_region (cr, event->region); + cairo_clip (cr); + meta_theme_draw_frame (preview->theme, widget, - gtk_widget_get_window (widget), - &event->area, + cr, allocation.x + border_width, allocation.y + border_width, preview->type, @@ -235,6 +242,8 @@ meta_preview_expose (GtkWidget *widget, button_states, meta_preview_get_mini_icon (), meta_preview_get_icon ()); + + cairo_destroy (cr); } /* draw child */ diff --git a/src/ui/theme-viewer.c b/src/ui/theme-viewer.c index 04a5b7680..7c0d3b1b4 100644 --- a/src/ui/theme-viewer.c +++ b/src/ui/theme-viewer.c @@ -35,6 +35,8 @@ #define _(x) dgettext (GETTEXT_PACKAGE, x) #define N_(x) x +#include "gdk2-drawing-utils.h" + /* We need to compute all different button arrangements * in terms of button location. We don't care about * different arrangements in terms of button function. @@ -959,6 +961,7 @@ run_theme_benchmark (void) #define ITERATIONS 100 int client_width; int client_height; + cairo_t *cr; int inc; widget = gtk_window_new (GTK_WINDOW_TOPLEVEL); @@ -1009,10 +1012,11 @@ run_theme_benchmark (void) client_height + top_height + bottom_height, -1); + cr = meta_cairo_create (pixmap); + meta_theme_draw_frame (global_theme, widget, - pixmap, - NULL, + cr, 0, 0, META_FRAME_TYPE_NORMAL, get_flags (widget), @@ -1024,6 +1028,7 @@ run_theme_benchmark (void) meta_preview_get_mini_icon (), meta_preview_get_icon ()); + cairo_destroy (cr); g_object_unref (G_OBJECT (pixmap)); ++i; diff --git a/src/ui/theme.c b/src/ui/theme.c index 6e51a5d37..0e308a5b7 100644 --- a/src/ui/theme.c +++ b/src/ui/theme.c @@ -63,6 +63,8 @@ #include #include "gtk-compat.h" +#include "gdk-compat.h" +#include "gdk2-drawing-utils.h" #define GDK_COLOR_RGBA(color) \ ((guint32) (0xff | \ @@ -3448,25 +3450,17 @@ static void meta_draw_op_draw_with_env (const MetaDrawOp *op, GtkStyle *style_gtk, GtkWidget *widget, - GdkDrawable *drawable, - const GdkRectangle *clip, + cairo_t *cr, const MetaDrawInfo *info, MetaRectangle rect, MetaPositionExprEnv *env) { GdkColor color; - cairo_t *cr; - cr = gdk_cairo_create (drawable); + cairo_save (cr); cairo_set_line_width (cr, 1.0); - if (clip) - { - gdk_cairo_rectangle (cr, clip); - cairo_clip (cr); - } - switch (op->type) { case META_DRAW_LINE: @@ -3716,11 +3710,10 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op, rwidth = parse_size_unchecked (op->data.gtk_arrow.width, env); rheight = parse_size_unchecked (op->data.gtk_arrow.height, env); - gtk_paint_arrow (style_gtk, - drawable, + meta_paint_arrow (style_gtk, + cr, op->data.gtk_arrow.state, op->data.gtk_arrow.shadow, - (GdkRectangle*) clip, widget, "metacity", op->data.gtk_arrow.arrow, @@ -3738,11 +3731,10 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op, rwidth = parse_size_unchecked (op->data.gtk_box.width, env); rheight = parse_size_unchecked (op->data.gtk_box.height, env); - gtk_paint_box (style_gtk, - drawable, + meta_paint_box (style_gtk, + cr, op->data.gtk_box.state, op->data.gtk_box.shadow, - (GdkRectangle*) clip, widget, "metacity", rx, ry, rwidth, rheight); @@ -3757,13 +3749,12 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op, ry1 = parse_y_position_unchecked (op->data.gtk_vline.y1, env); ry2 = parse_y_position_unchecked (op->data.gtk_vline.y2, env); - gtk_paint_vline (style_gtk, - drawable, - op->data.gtk_vline.state, - (GdkRectangle*) clip, - widget, - "metacity", - ry1, ry2, rx); + meta_paint_vline (style_gtk, + cr, + op->data.gtk_vline.state, + widget, + "metacity", + ry1, ry2, rx); } break; @@ -3855,7 +3846,7 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op, d_rect.height = parse_size_unchecked (op->data.op_list.height, env); meta_draw_op_list_draw_with_style (op->data.op_list.op_list, - style_gtk, widget, drawable, clip, info, + style_gtk, widget, cr, info, d_rect); } break; @@ -3864,7 +3855,6 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op, { int rx, ry, rwidth, rheight; int tile_xoffset, tile_yoffset; - GdkRectangle new_clip; MetaRectangle tile; rx = parse_x_position_unchecked (op->data.tile.x, env); @@ -3872,63 +3862,58 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op, rwidth = parse_size_unchecked (op->data.tile.width, env); rheight = parse_size_unchecked (op->data.tile.height, env); - new_clip.x = rx; - new_clip.y = ry; - new_clip.width = rwidth; - new_clip.height = rheight; + cairo_save (cr); - if (clip == NULL || gdk_rectangle_intersect ((GdkRectangle*)clip, &new_clip, - &new_clip)) - { - tile_xoffset = parse_x_position_unchecked (op->data.tile.tile_xoffset, env); - tile_yoffset = parse_y_position_unchecked (op->data.tile.tile_yoffset, env); - /* tile offset should not include x/y */ - tile_xoffset -= rect.x; - tile_yoffset -= rect.y; - - tile.width = parse_size_unchecked (op->data.tile.tile_width, env); - tile.height = parse_size_unchecked (op->data.tile.tile_height, env); + cairo_rectangle (cr, rx, ry, rwidth, rheight); + cairo_clip (cr); - tile.x = rx - tile_xoffset; + tile_xoffset = parse_x_position_unchecked (op->data.tile.tile_xoffset, env); + tile_yoffset = parse_y_position_unchecked (op->data.tile.tile_yoffset, env); + /* tile offset should not include x/y */ + tile_xoffset -= rect.x; + tile_yoffset -= rect.y; - while (tile.x < (rx + rwidth)) + tile.width = parse_size_unchecked (op->data.tile.tile_width, env); + tile.height = parse_size_unchecked (op->data.tile.tile_height, env); + + tile.x = rx - tile_xoffset; + + while (tile.x < (rx + rwidth)) + { + tile.y = ry - tile_yoffset; + while (tile.y < (ry + rheight)) { - tile.y = ry - tile_yoffset; - while (tile.y < (ry + rheight)) - { - meta_draw_op_list_draw_with_style (op->data.tile.op_list, - style_gtk, widget, drawable, &new_clip, info, - tile); + meta_draw_op_list_draw_with_style (op->data.tile.op_list, + style_gtk, widget, cr, info, + tile); - tile.y += tile.height; - } - - tile.x += tile.width; + tile.y += tile.height; } + + tile.x += tile.width; } + cairo_restore (cr); + } break; } - cairo_destroy (cr); + cairo_restore (cr); } void meta_draw_op_draw_with_style (const MetaDrawOp *op, GtkStyle *style_gtk, GtkWidget *widget, - GdkDrawable *drawable, - const GdkRectangle *clip, + cairo_t *cr, const MetaDrawInfo *info, MetaRectangle logical_region) { MetaPositionExprEnv env; - g_return_if_fail (style_gtk->colormap == gdk_drawable_get_colormap (drawable)); - fill_env (&env, info, logical_region); - meta_draw_op_draw_with_env (op, style_gtk, widget, drawable, clip, + meta_draw_op_draw_with_env (op, style_gtk, widget, cr, info, logical_region, &env); @@ -3937,13 +3922,12 @@ meta_draw_op_draw_with_style (const MetaDrawOp *op, void meta_draw_op_draw (const MetaDrawOp *op, GtkWidget *widget, - GdkDrawable *drawable, - const GdkRectangle *clip, + cairo_t *cr, const MetaDrawInfo *info, MetaRectangle logical_region) { meta_draw_op_draw_with_style (op, gtk_widget_get_style (widget), widget, - drawable, clip, info, logical_region); + cr, info, logical_region); } /** @@ -4001,18 +3985,13 @@ void meta_draw_op_list_draw_with_style (const MetaDrawOpList *op_list, GtkStyle *style_gtk, GtkWidget *widget, - GdkDrawable *drawable, - const GdkRectangle *clip, + cairo_t *cr, const MetaDrawInfo *info, MetaRectangle rect) { int i; - GdkRectangle active_clip; - GdkRectangle orig_clip; MetaPositionExprEnv env; - g_return_if_fail (style_gtk->colormap == gdk_drawable_get_colormap (drawable)); - if (op_list->n_ops == 0) return; @@ -4029,19 +4008,8 @@ meta_draw_op_list_draw_with_style (const MetaDrawOpList *op_list, * evaluated), we make an array of those, and then fold * adjacent items when possible. */ - if (clip) - { - orig_clip = *clip; - } - else - { - orig_clip.x = rect.x; - orig_clip.y = rect.y; - orig_clip.width = rect.width; - orig_clip.height = rect.height; - } - active_clip = orig_clip; + cairo_save (cr); for (i = 0; i < op_list->n_ops; i++) { @@ -4049,35 +4017,39 @@ meta_draw_op_list_draw_with_style (const MetaDrawOpList *op_list, if (op->type == META_DRAW_CLIP) { - active_clip.x = parse_x_position_unchecked (op->data.clip.x, &env); - active_clip.y = parse_y_position_unchecked (op->data.clip.y, &env); - active_clip.width = parse_size_unchecked (op->data.clip.width, &env); - active_clip.height = parse_size_unchecked (op->data.clip.height, &env); + cairo_restore (cr); + + cairo_rectangle (cr, + parse_x_position_unchecked (op->data.clip.x, &env), + parse_y_position_unchecked (op->data.clip.y, &env), + parse_size_unchecked (op->data.clip.width, &env), + parse_size_unchecked (op->data.clip.height, &env)); + cairo_clip (cr); - gdk_rectangle_intersect (&orig_clip, &active_clip, &active_clip); + cairo_save (cr); } - else if (active_clip.width > 0 && - active_clip.height > 0) + else if (gdk_cairo_get_clip_rectangle (cr, NULL)) { meta_draw_op_draw_with_env (op, - style_gtk, widget, drawable, &active_clip, info, + style_gtk, widget, cr, info, rect, &env); } } + + cairo_restore (cr); } void meta_draw_op_list_draw (const MetaDrawOpList *op_list, GtkWidget *widget, - GdkDrawable *drawable, - const GdkRectangle *clip, + cairo_t *cr, const MetaDrawInfo *info, MetaRectangle rect) { meta_draw_op_list_draw_with_style (op_list, gtk_widget_get_style (widget), widget, - drawable, clip, info, rect); + cr, info, rect); } void @@ -4385,10 +4357,9 @@ void meta_frame_style_draw_with_style (MetaFrameStyle *style, GtkStyle *style_gtk, GtkWidget *widget, - GdkDrawable *drawable, + cairo_t *cr, int x_offset, int y_offset, - const GdkRectangle *clip, const MetaFrameGeometry *fgeom, int client_width, int client_height, @@ -4408,8 +4379,6 @@ meta_frame_style_draw_with_style (MetaFrameStyle *style, PangoRectangle logical_rect; MetaDrawInfo draw_info; - g_return_if_fail (style_gtk->colormap == gdk_drawable_get_colormap (drawable)); - titlebar_rect.x = 0; titlebar_rect.y = 0; titlebar_rect.width = fgeom->width; @@ -4466,7 +4435,6 @@ meta_frame_style_draw_with_style (MetaFrameStyle *style, while (i < META_FRAME_PIECE_LAST) { GdkRectangle rect; - GdkRectangle combined_clip; switch ((MetaFramePiece) i) { @@ -4533,17 +4501,12 @@ meta_frame_style_draw_with_style (MetaFrameStyle *style, break; } - rect.x += x_offset; - rect.y += y_offset; + cairo_save (cr); - if (clip == NULL) - combined_clip = rect; - else - gdk_rectangle_intersect ((GdkRectangle*) clip, /* const cast */ - &rect, - &combined_clip); + gdk_cairo_rectangle (cr, &rect); + cairo_clip (cr); - if (combined_clip.width > 0 && combined_clip.height > 0) + if (gdk_cairo_get_clip_rectangle (cr, NULL)) { MetaDrawOpList *op_list; MetaFrameStyle *parent; @@ -4563,17 +4526,18 @@ meta_frame_style_draw_with_style (MetaFrameStyle *style, meta_draw_op_list_draw_with_style (op_list, style_gtk, widget, - drawable, - &combined_clip, + cr, &draw_info, m_rect); } } + cairo_restore (cr); /* Draw buttons just before overlay */ if ((i + 1) == META_FRAME_PIECE_OVERLAY) { + MetaDrawOpList *op_list; int middle_bg_offset; middle_bg_offset = 0; @@ -4585,32 +4549,30 @@ meta_frame_style_draw_with_style (MetaFrameStyle *style, rect.x += x_offset; rect.y += y_offset; - if (clip == NULL) - combined_clip = rect; - else - gdk_rectangle_intersect ((GdkRectangle*) clip, /* const cast */ - &rect, - &combined_clip); + op_list = get_button (style, j, button_states[j]); - if (combined_clip.width > 0 && combined_clip.height > 0) + if (op_list) { - MetaDrawOpList *op_list; - - op_list = get_button (style, j, button_states[j]); - - if (op_list) + cairo_save (cr); + gdk_cairo_rectangle (cr, &rect); + cairo_clip (cr); + + if (gdk_cairo_get_clip_rectangle (cr, NULL)) { MetaRectangle m_rect; + m_rect = meta_rect (rect.x, rect.y, rect.width, rect.height); + meta_draw_op_list_draw_with_style (op_list, style_gtk, - widget, - drawable, - &combined_clip, - &draw_info, - m_rect); + widget, + cr, + &draw_info, + m_rect); } + + cairo_restore (cr); } /* MIDDLE_BACKGROUND type may get drawn more than once */ @@ -4627,7 +4589,7 @@ meta_frame_style_draw_with_style (MetaFrameStyle *style, } } } - + ++i; } } @@ -4635,10 +4597,9 @@ meta_frame_style_draw_with_style (MetaFrameStyle *style, void meta_frame_style_draw (MetaFrameStyle *style, GtkWidget *widget, - GdkDrawable *drawable, + cairo_t *cr, int x_offset, int y_offset, - const GdkRectangle *clip, const MetaFrameGeometry *fgeom, int client_width, int client_height, @@ -4649,8 +4610,8 @@ meta_frame_style_draw (MetaFrameStyle *style, GdkPixbuf *icon) { meta_frame_style_draw_with_style (style, gtk_widget_get_style (widget), widget, - drawable, x_offset, y_offset, - clip, fgeom, client_width, client_height, + cr, x_offset, y_offset, + fgeom, client_width, client_height, title_layout, text_height, button_states, mini_icon, icon); } @@ -5219,8 +5180,7 @@ void meta_theme_draw_frame_with_style (MetaTheme *theme, GtkStyle *style_gtk, GtkWidget *widget, - GdkDrawable *drawable, - const GdkRectangle *clip, + cairo_t *cr, int x_offset, int y_offset, MetaFrameType type, @@ -5256,9 +5216,8 @@ meta_theme_draw_frame_with_style (MetaTheme *theme, meta_frame_style_draw_with_style (style, style_gtk, widget, - drawable, + cr, x_offset, y_offset, - clip, &fgeom, client_width, client_height, title_layout, @@ -5270,8 +5229,7 @@ meta_theme_draw_frame_with_style (MetaTheme *theme, void meta_theme_draw_frame (MetaTheme *theme, GtkWidget *widget, - GdkDrawable *drawable, - const GdkRectangle *clip, + cairo_t *cr, int x_offset, int y_offset, MetaFrameType type, @@ -5286,7 +5244,7 @@ meta_theme_draw_frame (MetaTheme *theme, GdkPixbuf *icon) { meta_theme_draw_frame_with_style (theme, gtk_widget_get_style (widget), widget, - drawable, clip, x_offset, y_offset, type,flags, + cr, x_offset, y_offset, type,flags, client_width, client_height, title_layout, text_height, button_layout, button_states, @@ -5296,8 +5254,7 @@ meta_theme_draw_frame (MetaTheme *theme, void meta_theme_draw_frame_by_name (MetaTheme *theme, GtkWidget *widget, - GdkDrawable *drawable, - const GdkRectangle *clip, + cairo_t *cr, int x_offset, int y_offset, const gchar *style_name, @@ -5330,9 +5287,8 @@ meta_theme_draw_frame_by_name (MetaTheme *theme, meta_frame_style_draw (style, widget, - drawable, + cr, x_offset, y_offset, - clip, &fgeom, client_width, client_height, title_layout, diff --git a/src/ui/theme.h b/src/ui/theme.h index 7558ccdfb..cedbc122e 100644 --- a/src/ui/theme.h +++ b/src/ui/theme.h @@ -955,8 +955,7 @@ MetaDrawOp* meta_draw_op_new (MetaDrawType type); void meta_draw_op_free (MetaDrawOp *op); void meta_draw_op_draw (const MetaDrawOp *op, GtkWidget *widget, - GdkDrawable *drawable, - const GdkRectangle *clip, + cairo_t *cr, const MetaDrawInfo *info, /* logical region being drawn */ MetaRectangle logical_region); @@ -964,8 +963,7 @@ void meta_draw_op_draw (const MetaDrawOp *op, void meta_draw_op_draw_with_style (const MetaDrawOp *op, GtkStyle *style_gtk, GtkWidget *widget, - GdkDrawable *drawable, - const GdkRectangle *clip, + cairo_t *cr, const MetaDrawInfo *info, /* logical region being drawn */ MetaRectangle logical_region); @@ -975,15 +973,13 @@ void meta_draw_op_list_ref (MetaDrawOpList *op_list); void meta_draw_op_list_unref (MetaDrawOpList *op_list); void meta_draw_op_list_draw (const MetaDrawOpList *op_list, GtkWidget *widget, - GdkDrawable *drawable, - const GdkRectangle *clip, + cairo_t *cr, const MetaDrawInfo *info, MetaRectangle rect); void meta_draw_op_list_draw_with_style (const MetaDrawOpList *op_list, GtkStyle *style_gtk, GtkWidget *widget, - GdkDrawable *drawable, - const GdkRectangle *clip, + cairo_t *cr, const MetaDrawInfo *info, MetaRectangle rect); void meta_draw_op_list_append (MetaDrawOpList *op_list, @@ -1013,10 +1009,9 @@ void meta_frame_style_unref (MetaFrameStyle *style); void meta_frame_style_draw (MetaFrameStyle *style, GtkWidget *widget, - GdkDrawable *drawable, + cairo_t *cr, int x_offset, int y_offset, - const GdkRectangle *clip, const MetaFrameGeometry *fgeom, int client_width, int client_height, @@ -1030,10 +1025,9 @@ void meta_frame_style_draw (MetaFrameStyle *style, void meta_frame_style_draw_with_style (MetaFrameStyle *style, GtkStyle *style_gtk, GtkWidget *widget, - GdkDrawable *drawable, + cairo_t *cr, int x_offset, int y_offset, - const GdkRectangle *clip, const MetaFrameGeometry *fgeom, int client_width, int client_height, @@ -1078,8 +1072,7 @@ double meta_theme_get_title_scale (MetaTheme *theme, void meta_theme_draw_frame (MetaTheme *theme, GtkWidget *widget, - GdkDrawable *drawable, - const GdkRectangle *clip, + cairo_t *cr, int x_offset, int y_offset, MetaFrameType type, @@ -1095,8 +1088,7 @@ void meta_theme_draw_frame (MetaTheme *theme, void meta_theme_draw_frame_by_name (MetaTheme *theme, GtkWidget *widget, - GdkDrawable *drawable, - const GdkRectangle *clip, + cairo_t *cr, int x_offset, int y_offset, const gchar *style_name, @@ -1113,8 +1105,7 @@ void meta_theme_draw_frame_by_name (MetaTheme *theme, void meta_theme_draw_frame_with_style (MetaTheme *theme, GtkStyle *style_gtk, GtkWidget *widget, - GdkDrawable *drawable, - const GdkRectangle *clip, + cairo_t *cr, int x_offset, int y_offset, MetaFrameType type,