try to make more error message strings the same, easier for translators

2002-02-09  Havoc Pennington  <hp@pobox.com>

	* 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
This commit is contained in:
Havoc Pennington 2002-02-09 17:02:38 +00:00 committed by Havoc Pennington
parent 116fc5546f
commit 339bdf8dd2
10 changed files with 341 additions and 112 deletions

View File

@ -1,3 +1,29 @@
2002-02-09 Havoc Pennington <hp@pobox.com>
* 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 <hp@pobox.com> 2002-02-09 Havoc Pennington <hp@pobox.com>
* src/themes/Atlanta/metacity-theme-1.xml: put in some kind of * src/themes/Atlanta/metacity-theme-1.xml: put in some kind of

View File

@ -62,6 +62,9 @@ static void meta_frames_calc_geometry (MetaFrames *frames,
MetaUIFrame *frame, MetaUIFrame *frame,
MetaFrameGeometry *fgeom); MetaFrameGeometry *fgeom);
static void meta_frames_ensure_layout (MetaFrames *frames,
MetaUIFrame *frame);
static MetaUIFrame* meta_frames_lookup_window (MetaFrames *frames, static MetaUIFrame* meta_frames_lookup_window (MetaFrames *frames,
Window xwindow); Window xwindow);
@ -156,6 +159,8 @@ meta_frames_init (MetaFrames *frames)
{ {
GTK_WINDOW (frames)->type = GTK_WINDOW_POPUP; 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->frames = g_hash_table_new (unsigned_long_hash, unsigned_long_equal);
frames->tooltip_timeout = 0; frames->tooltip_timeout = 0;
@ -212,6 +217,8 @@ meta_frames_finalize (GObject *object)
frames = META_FRAMES (object); frames = META_FRAMES (object);
g_hash_table_destroy (frames->text_heights);
g_assert (g_hash_table_size (frames->frames) == 0); g_assert (g_hash_table_size (frames->frames) == 0);
g_hash_table_destroy (frames->frames); g_hash_table_destroy (frames->frames);
@ -238,17 +245,13 @@ queue_recalc_func (gpointer key, gpointer value, gpointer data)
frame->xwindow); frame->xwindow);
if (frame->layout) if (frame->layout)
{ {
/* recreate layout */ /* save title to recreate layout */
char *text; 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)); g_object_unref (G_OBJECT (frame->layout));
frame->layout = NULL;
frame->layout = gtk_widget_create_pango_layout (GTK_WIDGET (frames),
text);
g_free (text);
} }
} }
@ -260,13 +263,10 @@ meta_frames_style_set (GtkWidget *widget,
frames = META_FRAMES (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); g_hash_table_destroy (frames->text_heights);
} frames->text_heights = g_hash_table_new (g_int_hash, g_int_equal);
else
{
frames->text_height = 0;
} }
/* Queue a draw/resize on all frames */ /* 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); 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 static void
meta_frames_calc_geometry (MetaFrames *frames, meta_frames_calc_geometry (MetaFrames *frames,
MetaUIFrame *frame, MetaUIFrame *frame,
@ -291,9 +366,11 @@ meta_frames_calc_geometry (MetaFrames *frames,
flags = meta_core_get_frame_flags (gdk_display, frame->xwindow); flags = meta_core_get_frame_flags (gdk_display, frame->xwindow);
type = meta_core_get_frame_type (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 (), meta_theme_calc_geometry (meta_theme_get_current (),
type, type,
frames->text_height, frame->text_height,
flags, flags,
width, height, width, height,
fgeom); fgeom);
@ -328,6 +405,8 @@ meta_frames_manage_window (MetaFrames *frames,
frame->xwindow = xwindow; frame->xwindow = xwindow;
frame->layout = NULL; frame->layout = NULL;
frame->text_height = -1;
frame->title = NULL;
frame->expose_delayed = FALSE; frame->expose_delayed = FALSE;
meta_core_grab_buttons (gdk_display, frame->xwindow); meta_core_grab_buttons (gdk_display, frame->xwindow);
@ -359,6 +438,9 @@ meta_frames_unmanage_window (MetaFrames *frames,
if (frame->layout) if (frame->layout)
g_object_unref (G_OBJECT (frame->layout)); g_object_unref (G_OBJECT (frame->layout));
if (frame->title)
g_free (frame->title);
g_free (frame); g_free (frame);
} }
else else
@ -374,8 +456,6 @@ meta_frames_realize (GtkWidget *widget)
if (GTK_WIDGET_CLASS (parent_class)->realize) if (GTK_WIDGET_CLASS (parent_class)->realize)
GTK_WIDGET_CLASS (parent_class)->realize (widget); GTK_WIDGET_CLASS (parent_class)->realize (widget);
frames->text_height = meta_gtk_widget_get_text_height (widget);
} }
static void static void
@ -387,8 +467,6 @@ meta_frames_unrealize (GtkWidget *widget)
if (GTK_WIDGET_CLASS (parent_class)->unrealize) if (GTK_WIDGET_CLASS (parent_class)->unrealize)
GTK_WIDGET_CLASS (parent_class)->unrealize (widget); GTK_WIDGET_CLASS (parent_class)->unrealize (widget);
frames->text_height = 0;
} }
static MetaUIFrame* static MetaUIFrame*
@ -422,6 +500,8 @@ meta_frames_get_geometry (MetaFrames *frames,
g_return_if_fail (type < META_FRAME_TYPE_LAST); 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 /* We can't get the full geometry, because that depends on
* the client window size and probably we're being called * the client window size and probably we're being called
* by the core move/resize code to decide on the client * by the core move/resize code to decide on the client
@ -429,7 +509,7 @@ meta_frames_get_geometry (MetaFrames *frames,
*/ */
meta_theme_get_frame_borders (meta_theme_get_current (), meta_theme_get_frame_borders (meta_theme_get_current (),
type, type,
frames->text_height, frame->text_height,
flags, flags,
top_height, bottom_height, top_height, bottom_height,
left_width, right_width); left_width, right_width);
@ -513,11 +593,14 @@ meta_frames_set_title (MetaFrames *frames,
frame = meta_frames_lookup_window (frames, xwindow); frame = meta_frames_lookup_window (frames, xwindow);
if (frame->layout == NULL) g_free (frame->title);
frame->layout = gtk_widget_create_pango_layout (widget, frame->title = g_strdup (title);
title);
else if (frame->layout)
pango_layout_set_text (frame->layout, title, -1); {
g_object_unref (frame->layout);
frame->layout = NULL;
}
gdk_window_invalidate_rect (frame->window, NULL, FALSE); gdk_window_invalidate_rect (frame->window, NULL, FALSE);
} }
@ -1211,6 +1294,8 @@ meta_frames_paint_to_drawable (MetaFrames *frames,
meta_core_get_client_size (gdk_display, frame->xwindow, meta_core_get_client_size (gdk_display, frame->xwindow,
&w, &h); &w, &h);
meta_frames_ensure_layout (frames, frame);
meta_theme_draw_frame (meta_theme_get_current (), meta_theme_draw_frame (meta_theme_get_current (),
widget, widget,
drawable, drawable,
@ -1220,7 +1305,7 @@ meta_frames_paint_to_drawable (MetaFrames *frames,
flags, flags,
w, h, w, h,
frame->layout, frame->layout,
frames->text_height, frame->text_height,
button_states, button_states,
mini_icon, icon); mini_icon, icon);
} }

View File

@ -68,6 +68,8 @@ struct _MetaUIFrame
Window xwindow; Window xwindow;
GdkWindow *window; GdkWindow *window;
PangoLayout *layout; PangoLayout *layout;
int text_height;
char *title; /* NULL once we have a layout */
guint expose_delayed : 1; guint expose_delayed : 1;
}; };
@ -75,7 +77,7 @@ struct _MetaFrames
{ {
GtkWindow parent_instance; GtkWindow parent_instance;
int text_height; GHashTable *text_heights;
GHashTable *frames; GHashTable *frames;

View File

@ -715,7 +715,7 @@ meta_stack_sync_to_server (MetaStack *stack)
changes.stack_mode = Below; changes.stack_mode = Below;
meta_topic (META_DEBUG_STACK, "Placing window 0x%lx below 0x%lx\n", meta_topic (META_DEBUG_STACK, "Placing window 0x%lx below 0x%lx\n",
*newp, last_window); *newp, last_window);
XConfigureWindow (stack->screen->display->xdisplay, XConfigureWindow (stack->screen->display->xdisplay,
*newp, *newp,

View File

@ -533,6 +533,28 @@ parse_double (const char *str,
return TRUE; 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 static gboolean
parse_angle (const char *str, parse_angle (const char *str,
double *val, double *val,
@ -573,6 +595,41 @@ parse_alpha (const char *str,
return TRUE; 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 static void
parse_toplevel_element (GMarkupParseContext *context, parse_toplevel_element (GMarkupParseContext *context,
const gchar *element_name, const gchar *element_name,
@ -608,14 +665,16 @@ parse_toplevel_element (GMarkupParseContext *context,
if (name == NULL) if (name == NULL)
{ {
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, 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; return;
} }
if (value == NULL) if (value == NULL)
{ {
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, 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; return;
} }
@ -657,21 +716,23 @@ parse_toplevel_element (GMarkupParseContext *context,
const char *name = NULL; const char *name = NULL;
const char *parent = NULL; const char *parent = NULL;
const char *has_title = NULL; const char *has_title = NULL;
const char *title_scale = NULL;
gboolean has_title_val; gboolean has_title_val;
double title_scale_val;
MetaFrameLayout *parent_layout; MetaFrameLayout *parent_layout;
if (!locate_attributes (context, element_name, attribute_names, attribute_values, if (!locate_attributes (context, element_name, attribute_names, attribute_values,
error, error,
"name", &name, "parent", &parent, "name", &name, "parent", &parent,
"has_title", &has_title, "has_title", &has_title, "title_scale", &title_scale,
NULL)) NULL))
return; return;
if (name == NULL) if (name == NULL)
{ {
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
_("No \"name\" attribute on <%s> element"), _("No \"%s\" attribute on <%s> element"),
element_name); "name", element_name);
return; return;
} }
@ -679,6 +740,10 @@ parse_toplevel_element (GMarkupParseContext *context,
if (has_title && !parse_boolean (has_title, &has_title_val, context, error)) if (has_title && !parse_boolean (has_title, &has_title_val, context, error))
return; 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)) if (meta_theme_lookup_layout (info->theme, name))
{ {
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
@ -710,6 +775,9 @@ parse_toplevel_element (GMarkupParseContext *context,
if (has_title) /* only if explicit, otherwise inherit */ if (has_title) /* only if explicit, otherwise inherit */
info->layout->has_title = has_title_val; 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); meta_theme_insert_layout (info->theme, name, info->layout);
push_state (info, STATE_FRAME_GEOMETRY); push_state (info, STATE_FRAME_GEOMETRY);
@ -727,8 +795,8 @@ parse_toplevel_element (GMarkupParseContext *context,
if (name == NULL) if (name == NULL)
{ {
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
_("No \"name\" attribute on <%s> element"), _("No \"%s\" attribute on <%s> element"),
element_name); "name", element_name);
return; return;
} }
@ -765,8 +833,8 @@ parse_toplevel_element (GMarkupParseContext *context,
if (name == NULL) if (name == NULL)
{ {
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
_("No \"name\" attribute on <%s> element"), _("No \"%s\" attribute on <%s> element"),
element_name); "name", element_name);
return; return;
} }
@ -842,8 +910,8 @@ parse_toplevel_element (GMarkupParseContext *context,
if (name == NULL) if (name == NULL)
{ {
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
_("No \"name\" attribute on <%s> element"), _("No \"%s\" attribute on <%s> element"),
element_name); "name", element_name);
return; return;
} }
@ -892,16 +960,16 @@ parse_toplevel_element (GMarkupParseContext *context,
if (type_name == NULL) if (type_name == NULL)
{ {
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
_("No \"type\" attribute on <%s> element"), _("No \"%s\" attribute on <%s> element"),
element_name); "type", element_name);
return; return;
} }
if (style_set_name == NULL) if (style_set_name == NULL)
{ {
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
_("No \"style_set\" attribute on <%s> element"), _("No \"%s\" attribute on <%s> element"),
element_name); "style_set", element_name);
return; return;
} }
@ -956,16 +1024,16 @@ parse_toplevel_element (GMarkupParseContext *context,
if (function == NULL) if (function == NULL)
{ {
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
_("No \"function\" attribute on <%s> element"), _("No \"%s\" attribute on <%s> element"),
element_name); "function", element_name);
return; return;
} }
if (state == NULL) if (state == NULL)
{ {
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
_("No \"state\" attribute on <%s> element"), _("No \"%s\" attribute on <%s> element"),
element_name); "state", element_name);
return; return;
} }
@ -1022,8 +1090,8 @@ parse_toplevel_element (GMarkupParseContext *context,
{ {
set_error (error, context, set_error (error, context,
G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
_("Element <%s> is not allowed below <metacity_theme>"), _("Element <%s> is not allowed below <%s>"),
element_name); element_name, "metacity_theme");
} }
} }
@ -1086,8 +1154,8 @@ parse_info_element (GMarkupParseContext *context,
{ {
set_error (error, context, set_error (error, context,
G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
_("Element <%s> is not allowed below <info>"), _("Element <%s> is not allowed below <%s>"),
element_name); element_name, "info");
} }
} }
@ -1284,8 +1352,8 @@ parse_geometry_element (GMarkupParseContext *context,
{ {
set_error (error, context, set_error (error, context,
G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
_("Element <%s> is not allowed below <frame_geometry>"), _("Element <%s> is not allowed below <%s>"),
element_name); element_name, "frame_geometry");
} }
} }
@ -1354,28 +1422,6 @@ optimize_expression (MetaTheme *theme,
return meta_theme_replace_constants (theme, expr, NULL); 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 static void
parse_draw_op_element (GMarkupParseContext *context, parse_draw_op_element (GMarkupParseContext *context,
const gchar *element_name, const gchar *element_name,
@ -2655,8 +2701,8 @@ parse_draw_op_element (GMarkupParseContext *context,
{ {
set_error (error, context, set_error (error, context,
G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
_("Element <%s> is not allowed below <draw_ops>"), _("Element <%s> is not allowed below <%s>"),
element_name); element_name, "draw_ops");
} }
} }
@ -2709,8 +2755,8 @@ parse_gradient_element (GMarkupParseContext *context,
{ {
set_error (error, context, set_error (error, context,
G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
_("Element <%s> is not allowed below <gradient>"), _("Element <%s> is not allowed below <%s>"),
element_name); element_name, "gradient");
} }
} }
@ -2869,8 +2915,8 @@ parse_style_element (GMarkupParseContext *context,
{ {
set_error (error, context, set_error (error, context,
G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
_("Element <%s> is not allowed below <frame_style>"), _("Element <%s> is not allowed below <%s>"),
element_name); element_name, "frame_style");
} }
} }
@ -3046,8 +3092,8 @@ parse_style_set_element (GMarkupParseContext *context,
{ {
set_error (error, context, set_error (error, context,
G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
_("Element <%s> is not allowed below <frame_style_set>"), _("Element <%s> is not allowed below <%s>"),
element_name); element_name, "frame_style_set");
} }
} }
@ -3084,8 +3130,8 @@ parse_piece_element (GMarkupParseContext *context,
{ {
set_error (error, context, set_error (error, context,
G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
_("Element <%s> is not allowed below <piece>"), _("Element <%s> is not allowed below <%s>"),
element_name); element_name, "piece");
} }
} }
@ -3122,8 +3168,8 @@ parse_button_element (GMarkupParseContext *context,
{ {
set_error (error, context, set_error (error, context,
G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
_("Element <%s> is not allowed below <piece>"), _("Element <%s> is not allowed below <%s>"),
element_name); element_name, "button");
} }
} }
@ -3160,8 +3206,8 @@ parse_menu_icon_element (GMarkupParseContext *context,
{ {
set_error (error, context, set_error (error, context,
G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
_("Element <%s> is not allowed below <piece>"), _("Element <%s> is not allowed below <%s>"),
element_name); element_name, "menu_icon");
} }
} }
@ -3257,8 +3303,8 @@ start_element_handler (GMarkupParseContext *context,
break; break;
case STATE_COLOR: case STATE_COLOR:
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
_("Element <%s> is not allowed inside a <color> element"), _("Element <%s> is not allowed inside a <%s> element"),
element_name); element_name, "color");
break; break;
case STATE_FRAME_STYLE: case STATE_FRAME_STYLE:
parse_style_element (context, element_name, parse_style_element (context, element_name,
@ -3287,13 +3333,13 @@ start_element_handler (GMarkupParseContext *context,
break; break;
case STATE_FRAME: case STATE_FRAME:
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
_("Element <%s> is not allowed inside a <frame> element"), _("Element <%s> is not allowed inside a <%s> element"),
element_name); element_name, "frame");
break; break;
case STATE_WINDOW: case STATE_WINDOW:
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
_("Element <%s> is not allowed inside a <window> element"), _("Element <%s> is not allowed inside a <%s> element"),
element_name); element_name, "window");
break; break;
} }
} }

View File

@ -55,7 +55,8 @@ get_flags (GtkWidget *widget)
static int static int
get_text_height (GtkWidget *widget) 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* static PangoLayout*

View File

@ -2302,6 +2302,8 @@ meta_draw_op_free (MetaDrawOp *op)
switch (op->type) switch (op->type)
{ {
case META_DRAW_LINE: 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.x1);
g_free (op->data.line.y1); g_free (op->data.line.y1);
g_free (op->data.line.x2); g_free (op->data.line.x2);
@ -3973,6 +3975,7 @@ meta_theme_free (MetaTheme *theme)
g_free (theme->author); g_free (theme->author);
g_free (theme->copyright); g_free (theme->copyright);
g_hash_table_destroy (theme->integer_constants);
g_hash_table_destroy (theme->images_by_filename); g_hash_table_destroy (theme->images_by_filename);
g_hash_table_destroy (theme->layouts_by_name); g_hash_table_destroy (theme->layouts_by_name);
g_hash_table_destroy (theme->draw_op_lists_by_name); g_hash_table_destroy (theme->draw_op_lists_by_name);
@ -4208,6 +4211,24 @@ theme_get_style (MetaTheme *theme,
return style; 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 void
meta_theme_draw_frame (MetaTheme *theme, meta_theme_draw_frame (MetaTheme *theme,
GtkWidget *widget, 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 int
meta_gtk_widget_get_text_height (GtkWidget *widget) meta_pango_font_desc_get_text_height (PangoFontDescription *font_desc,
PangoContext *context)
{ {
PangoFontMetrics *metrics; PangoFontMetrics *metrics;
PangoFont *font; PangoFont *font;
PangoLanguage *lang; PangoLanguage *lang;
int retval; int retval;
g_return_val_if_fail (GTK_WIDGET_REALIZED (widget), 0); font = pango_context_load_font (context, font_desc);
lang = pango_context_get_language (context);
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));
metrics = pango_font_get_metrics (font, lang); metrics = pango_font_get_metrics (font, lang);
g_object_unref (G_OBJECT (font)); g_object_unref (G_OBJECT (font));

View File

@ -79,6 +79,9 @@ struct _MetaFrameLayout
/* Space around buttons */ /* Space around buttons */
GtkBorder button_border; GtkBorder button_border;
/* scale factor for title text */
double title_scale;
/* Whether title text will be displayed */ /* Whether title text will be displayed */
guint has_title : 1; guint has_title : 1;
}; };
@ -632,6 +635,10 @@ GdkPixbuf* meta_theme_load_image (MetaTheme *theme,
const char *filename, const char *filename,
GError **error); GError **error);
double meta_theme_get_title_scale (MetaTheme *theme,
MetaFrameType type,
MetaFrameFlags flags);
void meta_theme_draw_frame (MetaTheme *theme, void meta_theme_draw_frame (MetaTheme *theme,
GtkWidget *widget, GtkWidget *widget,
GdkDrawable *drawable, GdkDrawable *drawable,
@ -716,7 +723,11 @@ char* meta_theme_replace_constants (MetaTheme *theme,
/* random stuff */ /* 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 */ /* Enum converters */
MetaGtkColorComponent meta_color_component_from_string (const char *str); MetaGtkColorComponent meta_color_component_from_string (const char *str);

View File

@ -30,7 +30,7 @@
<distance name="right_titlebar_edge" value="4"/> <distance name="right_titlebar_edge" value="4"/>
</frame_geometry> </frame_geometry>
<frame_geometry name="utility" has_title="false"> <frame_geometry name="utility" title_scale="xx-small">
<distance name="left_width" value="3"/> <distance name="left_width" value="3"/>
<distance name="right_width" value="3"/> <distance name="right_width" value="3"/>
<distance name="bottom_height" value="4"/> <distance name="bottom_height" value="4"/>
@ -38,7 +38,7 @@
<distance name="right_titlebar_edge" value="3"/> <distance name="right_titlebar_edge" value="3"/>
<distance name="button_width" value="11"/> <distance name="button_width" value="11"/>
<distance name="button_height" value="11"/> <distance name="button_height" value="11"/>
<distance name="title_vertical_pad" value="11"/> <distance name="title_vertical_pad" value="1"/>
<border name="title_border" left="3" right="4" top="3" bottom="3"/> <border name="title_border" left="3" right="4" top="3" bottom="3"/>
<border name="button_border" left="0" right="0" top="1" bottom="1"/> <border name="button_border" left="0" right="0" top="1" bottom="1"/>
</frame_geometry> </frame_geometry>
@ -178,7 +178,7 @@
y2="height - (height-SpacerHeight)/2"/> y2="height - (height-SpacerHeight)/2"/>
</draw_ops> </draw_ops>
<draw_ops name="title_text_focused"> <draw_ops name="title_text_focused_with_icon">
<clip x="0" y="0" width="width-SpacerWidth" height="height"/> <clip x="0" y="0" width="width-SpacerWidth" height="height"/>
<title color="gtk:fg[SELECTED]" <title color="gtk:fg[SELECTED]"
x="(0 `max` (width-title_width-mini_icon_width-IconTitleSpacing)) / 2 + mini_icon_width + IconTitleSpacing" x="(0 `max` (width-title_width-mini_icon_width-IconTitleSpacing)) / 2 + mini_icon_width + IconTitleSpacing"
@ -188,7 +188,14 @@
width="mini_icon_width" height="mini_icon_height"/> width="mini_icon_width" height="mini_icon_height"/>
</draw_ops> </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"/> <clip x="0" y="0" width="width-SpacerWidth" height="height"/>
<title color="gtk:fg[NORMAL]" <title color="gtk:fg[NORMAL]"
x="(0 `max` (width-title_width-mini_icon_width-IconTitleSpacing)) / 2 + mini_icon_width + IconTitleSpacing" 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"/> width="mini_icon_width" height="mini_icon_height"/>
</draw_ops> </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"> <draw_ops name="title_normal">
<include name="title_spacer"/> <include name="title_spacer"/>
<include name="title_text"/> <include name="title_text_with_icon"/>
</draw_ops> </draw_ops>
<draw_ops name="title_focused"> <draw_ops name="title_focused">
<include name="title_gradient"/> <include name="title_gradient"/>
<include name="title_spacer"/> <include name="title_spacer"/>
<include name="title_text_focused"/> <include name="title_text_focused_with_icon"/>
</draw_ops> </draw_ops>
<draw_ops name="title_utility"> <draw_ops name="title_utility">
<include name="title_spacer"/> <include name="title_spacer"/>
<include name="title_text_no_icon"/>
</draw_ops> </draw_ops>
<draw_ops name="title_utility_focused"> <draw_ops name="title_utility_focused">
<include name="title_gradient"/> <include name="title_gradient"/>
<include name="title_spacer"/> <include name="title_spacer"/>
<include name="title_text_focused_no_icon"/>
</draw_ops> </draw_ops>
<frame_style name="normal_unfocused" geometry="normal"> <frame_style name="normal_unfocused" geometry="normal">

View File

@ -14,7 +14,12 @@ Themes are in a simple XML-subset format.
</info> </info>
<!-- define a frame geometry to be referenced later --> <!-- 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="left_width" value="6"/>
<distance name="right_width" value="6"/> <distance name="right_width" value="6"/>
<distance name="bottom_height" value="7"/> <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 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"/> <color value="blend/gtk:bg[SELECTED]/gtk:fg[SELECTED]/0.5"/>
</gradient> </gradient>
<!-- image has an optional colorize="#color" attribute to give the
image a certain color -->
<image filename="foo.png" alpha="0.7" <image filename="foo.png" alpha="0.7"
x="10" y="30" width="width / 3" height="height / 4"/> x="10" y="30" width="width / 3" height="height / 4"/>
<gtk_arrow state="normal" shadow="in" arrow="up" <gtk_arrow state="normal" shadow="in" arrow="up"