diff --git a/ChangeLog b/ChangeLog index 449bc1f07..07f00f25e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,29 @@ +2002-02-09 Havoc Pennington + + * src/theme-parser.c: try to make more error message strings the + same, easier for translators + + * src/theme.c (meta_draw_op_free): free color spec for line op + (meta_theme_free): free the integer_constants hash + + * src/theme-parser.c (parse_boolean): move above first use + + * src/theme-viewer.c: fixes for theme.h changes + + * src/frames.c (queue_recalc_func): don't recreate layout + immediately, just save title text. should speed things up. + (meta_frames_set_title): just remove the layout here also, + and save title text. + + * src/theme-parser.c (parse_toplevel_element): parse title_scale + attribute on frame_geometry + + * src/theme.c: support setting the text size + + * src/frames.c: support setting the text size + + * theme-format.txt: updates + 2002-02-09 Havoc Pennington * src/themes/Atlanta/metacity-theme-1.xml: put in some kind of diff --git a/src/frames.c b/src/frames.c index bd5640825..5e0e5a457 100644 --- a/src/frames.c +++ b/src/frames.c @@ -62,6 +62,9 @@ static void meta_frames_calc_geometry (MetaFrames *frames, MetaUIFrame *frame, MetaFrameGeometry *fgeom); +static void meta_frames_ensure_layout (MetaFrames *frames, + MetaUIFrame *frame); + static MetaUIFrame* meta_frames_lookup_window (MetaFrames *frames, Window xwindow); @@ -156,6 +159,8 @@ meta_frames_init (MetaFrames *frames) { GTK_WINDOW (frames)->type = GTK_WINDOW_POPUP; + frames->text_heights = g_hash_table_new (g_int_hash, g_int_equal); + frames->frames = g_hash_table_new (unsigned_long_hash, unsigned_long_equal); frames->tooltip_timeout = 0; @@ -212,6 +217,8 @@ meta_frames_finalize (GObject *object) frames = META_FRAMES (object); + g_hash_table_destroy (frames->text_heights); + g_assert (g_hash_table_size (frames->frames) == 0); g_hash_table_destroy (frames->frames); @@ -238,17 +245,13 @@ queue_recalc_func (gpointer key, gpointer value, gpointer data) frame->xwindow); if (frame->layout) { - /* recreate layout */ - char *text; + /* save title to recreate layout */ + g_free (frame->title); - text = g_strdup (pango_layout_get_text (frame->layout)); + frame->title = g_strdup (pango_layout_get_text (frame->layout)); g_object_unref (G_OBJECT (frame->layout)); - - frame->layout = gtk_widget_create_pango_layout (GTK_WIDGET (frames), - text); - - g_free (text); + frame->layout = NULL; } } @@ -260,13 +263,10 @@ meta_frames_style_set (GtkWidget *widget, frames = META_FRAMES (widget); - if (GTK_WIDGET_REALIZED (widget)) + if (g_hash_table_size (frames->text_heights) > 0) { - frames->text_height = meta_gtk_widget_get_text_height (widget); - } - else - { - frames->text_height = 0; + g_hash_table_destroy (frames->text_heights); + frames->text_heights = g_hash_table_new (g_int_hash, g_int_equal); } /* Queue a draw/resize on all frames */ @@ -276,6 +276,81 @@ meta_frames_style_set (GtkWidget *widget, GTK_WIDGET_CLASS (parent_class)->style_set (widget, prev_style); } +static void +meta_frames_ensure_layout (MetaFrames *frames, + MetaUIFrame *frame) +{ + GtkWidget *widget; + + g_return_if_fail (GTK_WIDGET_REALIZED (frames)); + + widget = GTK_WIDGET (frames); + + if (frame->layout == NULL) + { + gpointer key, value; + PangoFontDescription *font_desc; + MetaFrameFlags flags; + MetaFrameType type; + double scale; + int size; + + flags = meta_core_get_frame_flags (gdk_display, frame->xwindow); + type = meta_core_get_frame_type (gdk_display, frame->xwindow); + + scale = meta_theme_get_title_scale (meta_theme_get_current (), + type, + flags); + + frame->layout = gtk_widget_create_pango_layout (widget, frame->title); + + font_desc = meta_gtk_widget_get_font_desc (widget, scale); + + size = pango_font_description_get_size (font_desc); + + if (g_hash_table_lookup_extended (frames->text_heights, + &size, + &key, &value)) + { + frame->text_height = GPOINTER_TO_INT (value); + } + else + { + frame->text_height = + meta_pango_font_desc_get_text_height (font_desc, + gtk_widget_get_pango_context (widget)); + + g_hash_table_insert (frames->text_heights, + &size, + GINT_TO_POINTER (frame->text_height)); + } + + if (pango_font_description_get_size (font_desc) != + pango_font_description_get_size (widget->style->font_desc)) + { + PangoAttrList *attrs; + PangoAttribute *attr; + + attrs = pango_attr_list_new (); + + attr = pango_attr_size_new (pango_font_description_get_size (font_desc)); + attr->start_index = 0; + attr->end_index = G_MAXINT; + + pango_attr_list_insert (attrs, attr); + + pango_layout_set_attributes (frame->layout, attrs); + + pango_attr_list_unref (attrs); + } + + pango_font_description_free (font_desc); + + g_free (frame->title); + frame->title = NULL; + } +} + static void meta_frames_calc_geometry (MetaFrames *frames, MetaUIFrame *frame, @@ -290,10 +365,12 @@ meta_frames_calc_geometry (MetaFrames *frames, flags = meta_core_get_frame_flags (gdk_display, frame->xwindow); type = meta_core_get_frame_type (gdk_display, frame->xwindow); + + meta_frames_ensure_layout (frames, frame); meta_theme_calc_geometry (meta_theme_get_current (), type, - frames->text_height, + frame->text_height, flags, width, height, fgeom); @@ -328,6 +405,8 @@ meta_frames_manage_window (MetaFrames *frames, frame->xwindow = xwindow; frame->layout = NULL; + frame->text_height = -1; + frame->title = NULL; frame->expose_delayed = FALSE; meta_core_grab_buttons (gdk_display, frame->xwindow); @@ -358,6 +437,9 @@ meta_frames_unmanage_window (MetaFrames *frames, if (frame->layout) g_object_unref (G_OBJECT (frame->layout)); + + if (frame->title) + g_free (frame->title); g_free (frame); } @@ -374,8 +456,6 @@ meta_frames_realize (GtkWidget *widget) if (GTK_WIDGET_CLASS (parent_class)->realize) GTK_WIDGET_CLASS (parent_class)->realize (widget); - - frames->text_height = meta_gtk_widget_get_text_height (widget); } static void @@ -387,8 +467,6 @@ meta_frames_unrealize (GtkWidget *widget) if (GTK_WIDGET_CLASS (parent_class)->unrealize) GTK_WIDGET_CLASS (parent_class)->unrealize (widget); - - frames->text_height = 0; } static MetaUIFrame* @@ -421,6 +499,8 @@ meta_frames_get_geometry (MetaFrames *frames, type = meta_core_get_frame_type (gdk_display, frame->xwindow); g_return_if_fail (type < META_FRAME_TYPE_LAST); + + meta_frames_ensure_layout (frames, frame); /* We can't get the full geometry, because that depends on * the client window size and probably we're being called @@ -429,7 +509,7 @@ meta_frames_get_geometry (MetaFrames *frames, */ meta_theme_get_frame_borders (meta_theme_get_current (), type, - frames->text_height, + frame->text_height, flags, top_height, bottom_height, left_width, right_width); @@ -512,12 +592,15 @@ meta_frames_set_title (MetaFrames *frames, widget = GTK_WIDGET (frames); frame = meta_frames_lookup_window (frames, xwindow); + + g_free (frame->title); + frame->title = g_strdup (title); - if (frame->layout == NULL) - frame->layout = gtk_widget_create_pango_layout (widget, - title); - else - pango_layout_set_text (frame->layout, title, -1); + if (frame->layout) + { + g_object_unref (frame->layout); + frame->layout = NULL; + } gdk_window_invalidate_rect (frame->window, NULL, FALSE); } @@ -1210,6 +1293,8 @@ meta_frames_paint_to_drawable (MetaFrames *frames, meta_core_get_client_size (gdk_display, frame->xwindow, &w, &h); + + meta_frames_ensure_layout (frames, frame); meta_theme_draw_frame (meta_theme_get_current (), widget, @@ -1220,7 +1305,7 @@ meta_frames_paint_to_drawable (MetaFrames *frames, flags, w, h, frame->layout, - frames->text_height, + frame->text_height, button_states, mini_icon, icon); } diff --git a/src/frames.h b/src/frames.h index e756ec5bc..66f27c7d9 100644 --- a/src/frames.h +++ b/src/frames.h @@ -68,6 +68,8 @@ struct _MetaUIFrame Window xwindow; GdkWindow *window; PangoLayout *layout; + int text_height; + char *title; /* NULL once we have a layout */ guint expose_delayed : 1; }; @@ -75,7 +77,7 @@ struct _MetaFrames { GtkWindow parent_instance; - int text_height; + GHashTable *text_heights; GHashTable *frames; diff --git a/src/stack.c b/src/stack.c index 37834aec0..813287ee4 100644 --- a/src/stack.c +++ b/src/stack.c @@ -715,7 +715,7 @@ meta_stack_sync_to_server (MetaStack *stack) changes.stack_mode = Below; meta_topic (META_DEBUG_STACK, "Placing window 0x%lx below 0x%lx\n", - *newp, last_window); + *newp, last_window); XConfigureWindow (stack->screen->display->xdisplay, *newp, diff --git a/src/theme-parser.c b/src/theme-parser.c index 331b565d1..d857be81d 100644 --- a/src/theme-parser.c +++ b/src/theme-parser.c @@ -533,6 +533,28 @@ parse_double (const char *str, return TRUE; } +static gboolean +parse_boolean (const char *str, + gboolean *val, + GMarkupParseContext *context, + GError **error) +{ + if (strcmp ("true", str) == 0) + *val = TRUE; + else if (strcmp ("false", str) == 0) + *val = FALSE; + else + { + set_error (error, context, G_MARKUP_ERROR, + G_MARKUP_ERROR_PARSE, + _("Boolean values must be \"true\" or \"false\" not \"%s\""), + str); + return FALSE; + } + + return TRUE; +} + static gboolean parse_angle (const char *str, double *val, @@ -573,6 +595,41 @@ parse_alpha (const char *str, return TRUE; } +static gboolean +parse_title_scale (const char *str, + double *val, + GMarkupParseContext *context, + GError **error) +{ + double factor; + + if (strcmp (str, "xx-small") == 0) + factor = PANGO_SCALE_XX_SMALL; + else if (strcmp (str, "x-small") == 0) + factor = PANGO_SCALE_X_SMALL; + else if (strcmp (str, "small") == 0) + factor = PANGO_SCALE_SMALL; + else if (strcmp (str, "medium") == 0) + factor = PANGO_SCALE_MEDIUM; + else if (strcmp (str, "large") == 0) + factor = PANGO_SCALE_LARGE; + else if (strcmp (str, "x-large") == 0) + factor = PANGO_SCALE_X_LARGE; + else if (strcmp (str, "xx-large") == 0) + factor = PANGO_SCALE_XX_LARGE; + else + { + set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, + _("Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium,large,x-large,xx-large)\n"), + str); + return FALSE; + } + + *val = factor; + + return TRUE; +} + static void parse_toplevel_element (GMarkupParseContext *context, const gchar *element_name, @@ -608,14 +665,16 @@ parse_toplevel_element (GMarkupParseContext *context, if (name == NULL) { set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("No \"name\" attribute on element <%s>"), element_name); + _("No \"%s\" attribute on element <%s>"), + "name", element_name); return; } - + if (value == NULL) { set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("No \"value\" attribute on element <%s>"), element_name); + _("No \"%s\" attribute on element <%s>"), + "value", element_name); return; } @@ -657,27 +716,33 @@ parse_toplevel_element (GMarkupParseContext *context, const char *name = NULL; const char *parent = NULL; const char *has_title = NULL; + const char *title_scale = NULL; gboolean has_title_val; + double title_scale_val; MetaFrameLayout *parent_layout; if (!locate_attributes (context, element_name, attribute_names, attribute_values, error, "name", &name, "parent", &parent, - "has_title", &has_title, + "has_title", &has_title, "title_scale", &title_scale, NULL)) return; if (name == NULL) { set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("No \"name\" attribute on <%s> element"), - element_name); + _("No \"%s\" attribute on <%s> element"), + "name", element_name); return; } has_title_val = TRUE; if (has_title && !parse_boolean (has_title, &has_title_val, context, error)) return; + + title_scale_val = 1.0; + if (title_scale && !parse_title_scale (title_scale, &title_scale_val, context, error)) + return; if (meta_theme_lookup_layout (info->theme, name)) { @@ -709,6 +774,9 @@ parse_toplevel_element (GMarkupParseContext *context, if (has_title) /* only if explicit, otherwise inherit */ info->layout->has_title = has_title_val; + + if (title_scale) + info->layout->title_scale = title_scale_val; meta_theme_insert_layout (info->theme, name, info->layout); @@ -727,8 +795,8 @@ parse_toplevel_element (GMarkupParseContext *context, if (name == NULL) { set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("No \"name\" attribute on <%s> element"), - element_name); + _("No \"%s\" attribute on <%s> element"), + "name", element_name); return; } @@ -765,8 +833,8 @@ parse_toplevel_element (GMarkupParseContext *context, if (name == NULL) { set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("No \"name\" attribute on <%s> element"), - element_name); + _("No \"%s\" attribute on <%s> element"), + "name", element_name); return; } @@ -842,8 +910,8 @@ parse_toplevel_element (GMarkupParseContext *context, if (name == NULL) { set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("No \"name\" attribute on <%s> element"), - element_name); + _("No \"%s\" attribute on <%s> element"), + "name", element_name); return; } @@ -892,16 +960,16 @@ parse_toplevel_element (GMarkupParseContext *context, if (type_name == NULL) { set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("No \"type\" attribute on <%s> element"), - element_name); + _("No \"%s\" attribute on <%s> element"), + "type", element_name); return; } if (style_set_name == NULL) { set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("No \"style_set\" attribute on <%s> element"), - element_name); + _("No \"%s\" attribute on <%s> element"), + "style_set", element_name); return; } @@ -956,16 +1024,16 @@ parse_toplevel_element (GMarkupParseContext *context, if (function == NULL) { set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("No \"function\" attribute on <%s> element"), - element_name); + _("No \"%s\" attribute on <%s> element"), + "function", element_name); return; } if (state == NULL) { set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("No \"state\" attribute on <%s> element"), - element_name); + _("No \"%s\" attribute on <%s> element"), + "state", element_name); return; } @@ -1022,8 +1090,8 @@ parse_toplevel_element (GMarkupParseContext *context, { set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Element <%s> is not allowed below "), - element_name); + _("Element <%s> is not allowed below <%s>"), + element_name, "metacity_theme"); } } @@ -1086,8 +1154,8 @@ parse_info_element (GMarkupParseContext *context, { set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Element <%s> is not allowed below "), - element_name); + _("Element <%s> is not allowed below <%s>"), + element_name, "info"); } } @@ -1284,8 +1352,8 @@ parse_geometry_element (GMarkupParseContext *context, { set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Element <%s> is not allowed below "), - element_name); + _("Element <%s> is not allowed below <%s>"), + element_name, "frame_geometry"); } } @@ -1354,28 +1422,6 @@ optimize_expression (MetaTheme *theme, return meta_theme_replace_constants (theme, expr, NULL); } -static gboolean -parse_boolean (const char *str, - gboolean *val, - GMarkupParseContext *context, - GError **error) -{ - if (strcmp ("true", str) == 0) - *val = TRUE; - else if (strcmp ("false", str) == 0) - *val = FALSE; - else - { - set_error (error, context, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("Boolean values must be \"true\" or \"false\" not \"%s\""), - str); - return FALSE; - } - - return TRUE; -} - static void parse_draw_op_element (GMarkupParseContext *context, const gchar *element_name, @@ -2655,8 +2701,8 @@ parse_draw_op_element (GMarkupParseContext *context, { set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Element <%s> is not allowed below "), - element_name); + _("Element <%s> is not allowed below <%s>"), + element_name, "draw_ops"); } } @@ -2709,8 +2755,8 @@ parse_gradient_element (GMarkupParseContext *context, { set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Element <%s> is not allowed below "), - element_name); + _("Element <%s> is not allowed below <%s>"), + element_name, "gradient"); } } @@ -2869,8 +2915,8 @@ parse_style_element (GMarkupParseContext *context, { set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Element <%s> is not allowed below "), - element_name); + _("Element <%s> is not allowed below <%s>"), + element_name, "frame_style"); } } @@ -3046,8 +3092,8 @@ parse_style_set_element (GMarkupParseContext *context, { set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Element <%s> is not allowed below "), - element_name); + _("Element <%s> is not allowed below <%s>"), + element_name, "frame_style_set"); } } @@ -3084,8 +3130,8 @@ parse_piece_element (GMarkupParseContext *context, { set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Element <%s> is not allowed below "), - element_name); + _("Element <%s> is not allowed below <%s>"), + element_name, "piece"); } } @@ -3122,8 +3168,8 @@ parse_button_element (GMarkupParseContext *context, { set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Element <%s> is not allowed below "), - element_name); + _("Element <%s> is not allowed below <%s>"), + element_name, "button"); } } @@ -3160,8 +3206,8 @@ parse_menu_icon_element (GMarkupParseContext *context, { set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Element <%s> is not allowed below "), - element_name); + _("Element <%s> is not allowed below <%s>"), + element_name, "menu_icon"); } } @@ -3257,8 +3303,8 @@ start_element_handler (GMarkupParseContext *context, break; case STATE_COLOR: set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Element <%s> is not allowed inside a element"), - element_name); + _("Element <%s> is not allowed inside a <%s> element"), + element_name, "color"); break; case STATE_FRAME_STYLE: parse_style_element (context, element_name, @@ -3287,13 +3333,13 @@ start_element_handler (GMarkupParseContext *context, break; case STATE_FRAME: set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Element <%s> is not allowed inside a element"), - element_name); + _("Element <%s> is not allowed inside a <%s> element"), + element_name, "frame"); break; case STATE_WINDOW: set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Element <%s> is not allowed inside a element"), - element_name); + _("Element <%s> is not allowed inside a <%s> element"), + element_name, "window"); break; } } diff --git a/src/theme-viewer.c b/src/theme-viewer.c index 0f8a24ad9..ef3ffc574 100644 --- a/src/theme-viewer.c +++ b/src/theme-viewer.c @@ -55,7 +55,8 @@ get_flags (GtkWidget *widget) static int get_text_height (GtkWidget *widget) { - return meta_gtk_widget_get_text_height (widget); + return meta_pango_font_desc_get_text_height (widget->style->font_desc, + gtk_widget_get_pango_context (widget)); } static PangoLayout* diff --git a/src/theme.c b/src/theme.c index 95bf0abb6..10090bec7 100644 --- a/src/theme.c +++ b/src/theme.c @@ -2302,6 +2302,8 @@ meta_draw_op_free (MetaDrawOp *op) switch (op->type) { case META_DRAW_LINE: + if (op->data.line.color_spec) + meta_color_spec_free (op->data.line.color_spec); g_free (op->data.line.x1); g_free (op->data.line.y1); g_free (op->data.line.x2); @@ -3973,6 +3975,7 @@ meta_theme_free (MetaTheme *theme) g_free (theme->author); g_free (theme->copyright); + g_hash_table_destroy (theme->integer_constants); g_hash_table_destroy (theme->images_by_filename); g_hash_table_destroy (theme->layouts_by_name); g_hash_table_destroy (theme->draw_op_lists_by_name); @@ -4208,6 +4211,24 @@ theme_get_style (MetaTheme *theme, return style; } +double +meta_theme_get_title_scale (MetaTheme *theme, + MetaFrameType type, + MetaFrameFlags flags) +{ + MetaFrameStyle *style; + + g_return_val_if_fail (type < META_FRAME_TYPE_LAST, 1.0); + + style = theme_get_style (theme, type, flags); + + /* Parser is not supposed to allow this currently */ + if (style == NULL) + return 1.0; + + return style->layout->title_scale; +} + void meta_theme_draw_frame (MetaTheme *theme, GtkWidget *widget, @@ -4542,19 +4563,33 @@ meta_theme_lookup_float_constant (MetaTheme *theme, } } +PangoFontDescription* +meta_gtk_widget_get_font_desc (GtkWidget *widget, + double scale) +{ + PangoFontDescription *font_desc; + + g_return_val_if_fail (GTK_WIDGET_REALIZED (widget), 0); + + font_desc = pango_font_description_copy (widget->style->font_desc); + + pango_font_description_set_size (font_desc, + MAX (pango_font_description_get_size (font_desc) * scale, 1)); + + return font_desc; +} + int -meta_gtk_widget_get_text_height (GtkWidget *widget) +meta_pango_font_desc_get_text_height (PangoFontDescription *font_desc, + PangoContext *context) { PangoFontMetrics *metrics; PangoFont *font; PangoLanguage *lang; int retval; - - g_return_val_if_fail (GTK_WIDGET_REALIZED (widget), 0); - font = pango_context_load_font (gtk_widget_get_pango_context (widget), - widget->style->font_desc); - lang = pango_context_get_language (gtk_widget_get_pango_context (widget)); + font = pango_context_load_font (context, font_desc); + lang = pango_context_get_language (context); metrics = pango_font_get_metrics (font, lang); g_object_unref (G_OBJECT (font)); @@ -4563,7 +4598,7 @@ meta_gtk_widget_get_text_height (GtkWidget *widget) pango_font_metrics_get_descent (metrics)); pango_font_metrics_unref (metrics); - + return retval; } diff --git a/src/theme.h b/src/theme.h index 8f9936f29..5ba1790a2 100644 --- a/src/theme.h +++ b/src/theme.h @@ -79,6 +79,9 @@ struct _MetaFrameLayout /* Space around buttons */ GtkBorder button_border; + /* scale factor for title text */ + double title_scale; + /* Whether title text will be displayed */ guint has_title : 1; }; @@ -632,6 +635,10 @@ GdkPixbuf* meta_theme_load_image (MetaTheme *theme, const char *filename, GError **error); +double meta_theme_get_title_scale (MetaTheme *theme, + MetaFrameType type, + MetaFrameFlags flags); + void meta_theme_draw_frame (MetaTheme *theme, GtkWidget *widget, GdkDrawable *drawable, @@ -716,7 +723,11 @@ char* meta_theme_replace_constants (MetaTheme *theme, /* random stuff */ -int meta_gtk_widget_get_text_height (GtkWidget *widget); +PangoFontDescription* meta_gtk_widget_get_font_desc (GtkWidget *widget, + double scale); +int meta_pango_font_desc_get_text_height (PangoFontDescription *font_desc, + PangoContext *context); + /* Enum converters */ MetaGtkColorComponent meta_color_component_from_string (const char *str); diff --git a/src/themes/Atlanta/metacity-theme-1.xml b/src/themes/Atlanta/metacity-theme-1.xml index 8913a6f35..6cfa13473 100644 --- a/src/themes/Atlanta/metacity-theme-1.xml +++ b/src/themes/Atlanta/metacity-theme-1.xml @@ -30,7 +30,7 @@ - + @@ -38,7 +38,7 @@ - + @@ -178,7 +178,7 @@ y2="height - (height-SpacerHeight)/2"/> - + </draw_ops> -<draw_ops name="title_text"> +<draw_ops name="title_text_focused_no_icon"> + <clip x="0" y="0" width="width-SpacerWidth" height="height"/> + <title color="gtk:fg[SELECTED]" + x="(0 `max` (width-title_width)) / 2" + y="((height - title_height) / 2) `max` 0"/> +</draw_ops> + +<draw_ops name="title_text_with_icon"> <clip x="0" y="0" width="width-SpacerWidth" height="height"/> <title color="gtk:fg[NORMAL]" x="(0 `max` (width-title_width-mini_icon_width-IconTitleSpacing)) / 2 + mini_icon_width + IconTitleSpacing" @@ -198,24 +205,33 @@ width="mini_icon_width" height="mini_icon_height"/> </draw_ops> +<draw_ops name="title_text_no_icon"> + <clip x="0" y="0" width="width-SpacerWidth" height="height"/> + <title color="gtk:fg[NORMAL]" + x="(0 `max` (width-title_width)) / 2" + y="((height - title_height) / 2) `max` 0"/> +</draw_ops> + <draw_ops name="title_normal"> <include name="title_spacer"/> - <include name="title_text"/> + <include name="title_text_with_icon"/> </draw_ops> <draw_ops name="title_focused"> <include name="title_gradient"/> <include name="title_spacer"/> - <include name="title_text_focused"/> + <include name="title_text_focused_with_icon"/> </draw_ops> <draw_ops name="title_utility"> <include name="title_spacer"/> + <include name="title_text_no_icon"/> </draw_ops> <draw_ops name="title_utility_focused"> <include name="title_gradient"/> <include name="title_spacer"/> + <include name="title_text_focused_no_icon"/> </draw_ops> <frame_style name="normal_unfocused" geometry="normal"> diff --git a/theme-format.txt b/theme-format.txt index 744f74a90..c54033428 100644 --- a/theme-format.txt +++ b/theme-format.txt @@ -14,7 +14,12 @@ Themes are in a simple XML-subset format. </info> <!-- define a frame geometry to be referenced later --> -<frame_geometry name="normal"> +<!-- frame_geometry has an optional has_title attribute which + determines whether the title text height is included in the + height calculation. if not specified, defaults to true. + It also has an optional text_size="medium" attribute + (same sizes as with Pango markup, xx-small thru medium thru xx-large) --> +<frame_geometry name="normal" has_title="true" title_size="medium"> <distance name="left_width" value="6"/> <distance name="right_width" value="6"/> <distance name="bottom_height" value="7"/> @@ -94,6 +99,8 @@ Themes are in a simple XML-subset format. <!-- color obtained by a 0.5 alpha composite of the second color onto the first --> <color value="blend/gtk:bg[SELECTED]/gtk:fg[SELECTED]/0.5"/> </gradient> + <!-- image has an optional colorize="#color" attribute to give the + image a certain color --> <image filename="foo.png" alpha="0.7" x="10" y="30" width="width / 3" height="height / 4"/> <gtk_arrow state="normal" shadow="in" arrow="up"