From a6c951352fee59826edb68bbfbd80c96b75a3169 Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Wed, 28 Jan 2009 01:47:18 +0000 Subject: [PATCH] GtkStyle is specific to a particular colormap. Metacity uses different 2009-01-27 Owen Taylor GtkStyle is specific to a particular colormap. Metacity uses different colormaps for windows with different visuals, so it must specialize the GtkStyle. Closes #568365 and #513944. * src/ui/frames.[ch]: Keep a GtkStyle for each MetaUIFrame, which is obtained by calling gtk_style_attach() on the style for the MetaFrames. When the style of the MetaFrames changes, reattach everything. When we call gtk_style_set_background() pass in the right style. * src/ui/themes.[ch]: Create a _with_style() variant of functions that previously took the style from widget->style passed in, so we can draw with the right style for the colormap. svn path=/trunk/; revision=4092 --- ChangeLog | 18 ++++ src/ui/frames.c | 73 ++++++++++++--- src/ui/frames.h | 1 + src/ui/theme.c | 242 +++++++++++++++++++++++++++++++++--------------- src/ui/theme.h | 51 ++++++++++ 5 files changed, 293 insertions(+), 92 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0fdf6d3bc..d5cb66c9a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2009-01-27 Owen Taylor + + GtkStyle is specific to a particular colormap. Metacity + uses different colormaps for windows with different + visuals, so it must specialize the GtkStyle. + + Closes #568365 and #513944. + + * src/ui/frames.[ch]: Keep a GtkStyle for each MetaUIFrame, which is + obtained by calling gtk_style_attach() on the style for the + MetaFrames. When the style of the MetaFrames changes, reattach + everything. When we call gtk_style_set_background() pass in the + right style. + + * src/ui/themes.[ch]: Create a _with_style() variant of functions that + previously took the style from widget->style passed in, so we + can draw with the right style for the colormap. + 2009-01-27 Thomas Thurman Added a gconf key to swap the meanings of the right and diff --git a/src/ui/frames.c b/src/ui/frames.c index f4761d2a6..038380b85 100644 --- a/src/ui/frames.c +++ b/src/ui/frames.c @@ -68,6 +68,9 @@ static gboolean meta_frames_enter_notify_event (GtkWidget *widget, static gboolean meta_frames_leave_notify_event (GtkWidget *widget, GdkEventCrossing *event); +static void meta_frames_attach_style (MetaFrames *frames, + MetaUIFrame *frame); + static void meta_frames_paint_to_drawable (MetaFrames *frames, MetaUIFrame *frame, GdkDrawable *drawable, @@ -420,6 +423,18 @@ meta_frames_button_layout_changed (MetaFrames *frames) queue_draw_func, frames); } +static void +reattach_style_func (gpointer key, gpointer value, gpointer data) +{ + MetaUIFrame *frame; + MetaFrames *frames; + + frames = META_FRAMES (data); + frame = value; + + meta_frames_attach_style (frames, frame); +} + static void meta_frames_style_set (GtkWidget *widget, GtkStyle *prev_style) @@ -430,6 +445,9 @@ meta_frames_style_set (GtkWidget *widget, meta_frames_font_changed (frames); + g_hash_table_foreach (frames->frames, + reattach_style_func, frames); + GTK_WIDGET_CLASS (parent_class)->style_set (widget, prev_style); } @@ -561,6 +579,24 @@ meta_frames_new (int screen_number) NULL); } +/* In order to use a style with a window it has to be attached to that + * window. Actually, the colormaps just have to match, but since GTK+ + * already takes care of making sure that its cheap to attach a style + * to multiple windows with the same colormap, we can just go ahead + * and attach separately for each window. + */ +static void +meta_frames_attach_style (MetaFrames *frames, + MetaUIFrame *frame) +{ + if (frame->style != NULL) + gtk_style_detach (frame->style); + + /* Weirdly, gtk_style_attach() steals a reference count from the style passed in */ + gtk_style_ref (GTK_WIDGET (frames)->style); + frame->style = gtk_style_attach (GTK_WIDGET (frames)->style, frame->window); +} + void meta_frames_manage_window (MetaFrames *frames, Window xwindow, @@ -576,6 +612,9 @@ meta_frames_manage_window (MetaFrames *frames, gdk_window_set_user_data (frame->window, frames); + frame->style = NULL; + meta_frames_attach_style (frames, frame); + /* Don't set event mask here, it's in frame.c */ frame->xwindow = xwindow; @@ -626,6 +665,8 @@ meta_frames_unmanage_window (MetaFrames *frames, g_hash_table_remove (frames->frames, &frame->xwindow); + gtk_style_detach (frame->style); + gdk_window_destroy (frame->window); if (frame->layout) @@ -2435,7 +2476,8 @@ meta_frames_paint_to_drawable (MetaFrames *frames, gdk_window_begin_paint_rect (drawable, &areas[i]); - meta_theme_draw_frame (meta_theme_get_current (), + meta_theme_draw_frame_with_style (meta_theme_get_current (), + frame->style, widget, drawable, NULL, /* &areas[i], */ @@ -2460,19 +2502,20 @@ meta_frames_paint_to_drawable (MetaFrames *frames, { /* Not a window; happens about 1/3 of the time */ - meta_theme_draw_frame (meta_theme_get_current (), - widget, - drawable, - NULL, - x_offset, y_offset, - type, - flags, - w, h, - frame->layout, - frame->text_height, - &button_layout, - button_states, - mini_icon, icon); + meta_theme_draw_frame_with_style (meta_theme_get_current (), + frame->style, + widget, + drawable, + NULL, + x_offset, y_offset, + type, + flags, + w, h, + frame->layout, + frame->text_height, + &button_layout, + button_states, + mini_icon, icon); } } @@ -2525,7 +2568,7 @@ meta_frames_set_window_background (MetaFrames *frames, } else { - gtk_style_set_background (GTK_WIDGET (frames)->style, + gtk_style_set_background (frame->style, frame->window, GTK_STATE_NORMAL); } } diff --git a/src/ui/frames.h b/src/ui/frames.h index c4ad8bfb0..849c25844 100644 --- a/src/ui/frames.h +++ b/src/ui/frames.h @@ -75,6 +75,7 @@ struct _MetaUIFrame { Window xwindow; GdkWindow *window; + GtkStyle *style; MetaFrameStyle *cache_style; PangoLayout *layout; int text_height; diff --git a/src/ui/theme.c b/src/ui/theme.c index 1d822c82d..ccd3fc0d2 100644 --- a/src/ui/theme.c +++ b/src/ui/theme.c @@ -3457,6 +3457,7 @@ fill_env (MetaPositionExprEnv *env, static void meta_draw_op_draw_with_env (const MetaDrawOp *op, + GtkStyle *style_gtk, GtkWidget *widget, GdkDrawable *drawable, const GdkRectangle *clip, @@ -3649,7 +3650,7 @@ 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 (widget->style, + gtk_paint_arrow (style_gtk, drawable, op->data.gtk_arrow.state, op->data.gtk_arrow.shadow, @@ -3671,7 +3672,7 @@ 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 (widget->style, + gtk_paint_box (style_gtk, drawable, op->data.gtk_box.state, op->data.gtk_box.shadow, @@ -3690,7 +3691,7 @@ 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 (widget->style, + gtk_paint_vline (style_gtk, drawable, op->data.gtk_vline.state, (GdkRectangle*) clip, @@ -3752,9 +3753,9 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op, d_rect.width = parse_size_unchecked (op->data.op_list.width, env); d_rect.height = parse_size_unchecked (op->data.op_list.height, env); - meta_draw_op_list_draw (op->data.op_list.op_list, - widget, drawable, clip, info, - d_rect); + meta_draw_op_list_draw_with_style (op->data.op_list.op_list, + style_gtk, widget, drawable, clip, info, + d_rect); } break; @@ -3794,9 +3795,9 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op, tile.y = ry - tile_yoffset; while (tile.y < (ry + rheight)) { - meta_draw_op_list_draw (op->data.tile.op_list, - widget, drawable, &new_clip, info, - tile); + meta_draw_op_list_draw_with_style (op->data.tile.op_list, + style_gtk, widget, drawable, &new_clip, info, + tile); tile.y += tile.height; } @@ -3809,6 +3810,27 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op, } } +void +meta_draw_op_draw_with_style (const MetaDrawOp *op, + GtkStyle *style_gtk, + GtkWidget *widget, + GdkDrawable *drawable, + const GdkRectangle *clip, + 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, + info, logical_region, + &env); + +} + void meta_draw_op_draw (const MetaDrawOp *op, GtkWidget *widget, @@ -3817,14 +3839,8 @@ meta_draw_op_draw (const MetaDrawOp *op, const MetaDrawInfo *info, MetaRectangle logical_region) { - MetaPositionExprEnv env; - - fill_env (&env, info, logical_region); - - meta_draw_op_draw_with_env (op, widget, drawable, clip, - info, logical_region, - &env); - + meta_draw_op_draw_with_style (op, widget->style, widget, + drawable, clip, info, logical_region); } MetaDrawOpList* @@ -3875,18 +3891,21 @@ 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, - const MetaDrawInfo *info, - MetaRectangle rect) +meta_draw_op_list_draw_with_style (const MetaDrawOpList *op_list, + GtkStyle *style_gtk, + GtkWidget *widget, + GdkDrawable *drawable, + const GdkRectangle *clip, + 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; @@ -3934,13 +3953,26 @@ meta_draw_op_list_draw (const MetaDrawOpList *op_list, active_clip.height > 0) { meta_draw_op_draw_with_env (op, - widget, drawable, &active_clip, info, + style_gtk, widget, drawable, &active_clip, info, rect, &env); } } } +void +meta_draw_op_list_draw (const MetaDrawOpList *op_list, + GtkWidget *widget, + GdkDrawable *drawable, + const GdkRectangle *clip, + const MetaDrawInfo *info, + MetaRectangle rect) + +{ + meta_draw_op_list_draw_with_style (op_list, widget->style, widget, + drawable, clip, info, rect); +} + void meta_draw_op_list_append (MetaDrawOpList *op_list, MetaDrawOp *op) @@ -4243,20 +4275,21 @@ button_rect (MetaButtonType type, } void -meta_frame_style_draw (MetaFrameStyle *style, - GtkWidget *widget, - GdkDrawable *drawable, - int x_offset, - int y_offset, - const GdkRectangle *clip, - const MetaFrameGeometry *fgeom, - int client_width, - int client_height, - PangoLayout *title_layout, - int text_height, - MetaButtonState button_states[META_BUTTON_TYPE_LAST], - GdkPixbuf *mini_icon, - GdkPixbuf *icon) +meta_frame_style_draw_with_style (MetaFrameStyle *style, + GtkStyle *style_gtk, + GtkWidget *widget, + GdkDrawable *drawable, + int x_offset, + int y_offset, + const GdkRectangle *clip, + const MetaFrameGeometry *fgeom, + int client_width, + int client_height, + PangoLayout *title_layout, + int text_height, + MetaButtonState button_states[META_BUTTON_TYPE_LAST], + GdkPixbuf *mini_icon, + GdkPixbuf *icon) { int i, j; GdkRectangle titlebar_rect; @@ -4268,6 +4301,8 @@ meta_frame_style_draw (MetaFrameStyle *style, PangoRectangle extents; 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; @@ -4418,12 +4453,13 @@ meta_frame_style_draw (MetaFrameStyle *style, { MetaRectangle m_rect; m_rect = meta_rect (rect.x, rect.y, rect.width, rect.height); - meta_draw_op_list_draw (op_list, - widget, - drawable, - &combined_clip, - &draw_info, - m_rect); + meta_draw_op_list_draw_with_style (op_list, + style_gtk, + widget, + drawable, + &combined_clip, + &draw_info, + m_rect); } } @@ -4460,12 +4496,13 @@ meta_frame_style_draw (MetaFrameStyle *style, MetaRectangle m_rect; m_rect = meta_rect (rect.x, rect.y, rect.width, rect.height); - meta_draw_op_list_draw (op_list, - widget, - drawable, - &combined_clip, - &draw_info, - m_rect); + meta_draw_op_list_draw_with_style (op_list, + style_gtk, + widget, + drawable, + &combined_clip, + &draw_info, + m_rect); } } @@ -4488,6 +4525,29 @@ meta_frame_style_draw (MetaFrameStyle *style, } } +void +meta_frame_style_draw (MetaFrameStyle *style, + GtkWidget *widget, + GdkDrawable *drawable, + int x_offset, + int y_offset, + const GdkRectangle *clip, + const MetaFrameGeometry *fgeom, + int client_width, + int client_height, + PangoLayout *title_layout, + int text_height, + MetaButtonState button_states[META_BUTTON_TYPE_LAST], + GdkPixbuf *mini_icon, + GdkPixbuf *icon) +{ + meta_frame_style_draw_with_style (style, widget->style, widget, + drawable, x_offset, y_offset, + clip, fgeom, client_width, client_height, + title_layout, text_height, + button_states, mini_icon, icon); +} + MetaFrameStyleSet* meta_frame_style_set_new (MetaFrameStyleSet *parent) { @@ -5035,22 +5095,23 @@ meta_theme_get_title_scale (MetaTheme *theme, } void -meta_theme_draw_frame (MetaTheme *theme, - GtkWidget *widget, - GdkDrawable *drawable, - const GdkRectangle *clip, - int x_offset, - int y_offset, - MetaFrameType type, - MetaFrameFlags flags, - int client_width, - int client_height, - PangoLayout *title_layout, - int text_height, - const MetaButtonLayout *button_layout, - MetaButtonState button_states[META_BUTTON_TYPE_LAST], - GdkPixbuf *mini_icon, - GdkPixbuf *icon) +meta_theme_draw_frame_with_style (MetaTheme *theme, + GtkStyle *style_gtk, + GtkWidget *widget, + GdkDrawable *drawable, + const GdkRectangle *clip, + int x_offset, + int y_offset, + MetaFrameType type, + MetaFrameFlags flags, + int client_width, + int client_height, + PangoLayout *title_layout, + int text_height, + const MetaButtonLayout *button_layout, + MetaButtonState button_states[META_BUTTON_TYPE_LAST], + GdkPixbuf *mini_icon, + GdkPixbuf *icon) { MetaFrameGeometry fgeom; MetaFrameStyle *style; @@ -5071,17 +5132,44 @@ meta_theme_draw_frame (MetaTheme *theme, &fgeom, theme); - meta_frame_style_draw (style, - widget, - drawable, - x_offset, y_offset, - clip, - &fgeom, - client_width, client_height, - title_layout, - text_height, - button_states, - mini_icon, icon); + meta_frame_style_draw_with_style (style, + style_gtk, + widget, + drawable, + x_offset, y_offset, + clip, + &fgeom, + client_width, client_height, + title_layout, + text_height, + button_states, + mini_icon, icon); +} + +void +meta_theme_draw_frame (MetaTheme *theme, + GtkWidget *widget, + GdkDrawable *drawable, + const GdkRectangle *clip, + int x_offset, + int y_offset, + MetaFrameType type, + MetaFrameFlags flags, + int client_width, + int client_height, + PangoLayout *title_layout, + int text_height, + const MetaButtonLayout *button_layout, + MetaButtonState button_states[META_BUTTON_TYPE_LAST], + GdkPixbuf *mini_icon, + GdkPixbuf *icon) +{ + meta_theme_draw_frame_with_style (theme, widget->style, widget, + drawable, clip, x_offset, y_offset, type,flags, + client_width, client_height, + title_layout, text_height, + button_layout, button_states, + mini_icon, icon); } void diff --git a/src/ui/theme.h b/src/ui/theme.h index 737f30a88..ddf777d4d 100644 --- a/src/ui/theme.h +++ b/src/ui/theme.h @@ -901,6 +901,15 @@ void meta_draw_op_draw (const MetaDrawOp *op, /* logical region being drawn */ MetaRectangle logical_region); +void meta_draw_op_draw_with_style (const MetaDrawOp *op, + GtkStyle *style_gtk, + GtkWidget *widget, + GdkDrawable *drawable, + const GdkRectangle *clip, + const MetaDrawInfo *info, + /* logical region being drawn */ + MetaRectangle logical_region); + MetaDrawOpList* meta_draw_op_list_new (int n_preallocs); void meta_draw_op_list_ref (MetaDrawOpList *op_list); void meta_draw_op_list_unref (MetaDrawOpList *op_list); @@ -910,6 +919,13 @@ void meta_draw_op_list_draw (const MetaDrawOpList *op_list, const GdkRectangle *clip, 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, + const MetaDrawInfo *info, + MetaRectangle rect); void meta_draw_op_list_append (MetaDrawOpList *op_list, MetaDrawOp *op); gboolean meta_draw_op_list_validate (MetaDrawOpList *op_list, @@ -951,6 +967,23 @@ void meta_frame_style_draw (MetaFrameStyle *style, GdkPixbuf *icon); +void meta_frame_style_draw_with_style (MetaFrameStyle *style, + GtkStyle *style_gtk, + GtkWidget *widget, + GdkDrawable *drawable, + int x_offset, + int y_offset, + const GdkRectangle *clip, + const MetaFrameGeometry *fgeom, + int client_width, + int client_height, + PangoLayout *title_layout, + int text_height, + MetaButtonState button_states[META_BUTTON_TYPE_LAST], + GdkPixbuf *mini_icon, + GdkPixbuf *icon); + + gboolean meta_frame_style_validate (MetaFrameStyle *style, guint current_theme_version, GError **error); @@ -1017,6 +1050,24 @@ void meta_theme_draw_frame_by_name (MetaTheme *theme, GdkPixbuf *mini_icon, GdkPixbuf *icon); +void meta_theme_draw_frame_with_style (MetaTheme *theme, + GtkStyle *style_gtk, + GtkWidget *widget, + GdkDrawable *drawable, + const GdkRectangle *clip, + int x_offset, + int y_offset, + MetaFrameType type, + MetaFrameFlags flags, + int client_width, + int client_height, + PangoLayout *title_layout, + int text_height, + const MetaButtonLayout *button_layout, + MetaButtonState button_states[META_BUTTON_TYPE_LAST], + GdkPixbuf *mini_icon, + GdkPixbuf *icon); + void meta_theme_get_frame_borders (MetaTheme *theme, MetaFrameType type, int text_height,