disable custom log handler and fatal mask for now

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

	* src/main.c (main): disable custom log handler and fatal mask for
	now

	* src/theme.c (meta_draw_op_list_draw):
	Add META_DRAW_CLIP

	* src/main.c: load theme, monitor current theme setting

	* src/prefs.c: add "current theme" setting

	* src/stack.c (meta_stack_free): don't try to free
	last_root_children_stacked if it doesn't exist

	* src/themewidget.c: pluggable GtkMisc subclass to use
	for menu icons

	* src/screen.c (meta_screen_manage_all_windows): fix
	signed/unsigned warning

	* src/frames.c: port to theme system
	(meta_frames_style_set): chain up

	* theme-format.txt: new file

	* configure.in: add more compiler warnings

	* src/theme.c: add various stuff needed to get theme parser
	working. Remove the "spacer" concept from FrameLayout object.
	Add draw op that references a draw op list.

	* configure.in: require GTK 1.3.13

	* src/Makefile.am: add theme-parser.[hc], implement loading a
	theme

	* src/theme.c: add "draw title" and "draw window icon" operations
	(meta_draw_op_draw): put object_width/object_height in expression
	environment before computing x/y. Handle out-of-memory when
	creating pixbufs. Assorted other cleanups.
This commit is contained in:
Havoc Pennington
2002-02-07 03:07:56 +00:00
committed by Havoc Pennington
parent 2be2d8ccbe
commit 8ae714eeae
36 changed files with 8395 additions and 1514 deletions

View File

@ -128,24 +128,6 @@ meta_frames_get_type (void)
return frames_type;
}
#define BORDER_PROPERTY(name, blurb, docs) \
gtk_widget_class_install_style_property (widget_class, \
g_param_spec_boxed (name, \
blurb, \
docs, \
GTK_TYPE_BORDER, \
G_PARAM_READABLE))
#define INT_PROPERTY(name, default, blurb, docs) \
gtk_widget_class_install_style_property (widget_class, \
g_param_spec_int (name, \
blurb, \
docs, \
0, \
G_MAXINT, \
default, \
G_PARAM_READABLE))
static void
meta_frames_class_init (MetaFramesClass *class)
{
@ -174,27 +156,6 @@ meta_frames_class_init (MetaFramesClass *class)
widget_class->button_release_event = meta_frames_button_release_event;
widget_class->motion_notify_event = meta_frames_motion_notify_event;
widget_class->leave_notify_event = meta_frames_leave_notify_event;
INT_PROPERTY ("left_width", 6, _("Left edge"), _("Left window edge width"));
INT_PROPERTY ("right_width", 6, _("Right edge"), _("Right window edge width"));
INT_PROPERTY ("bottom_height", 7, _("Bottom edge"), _("Bottom window edge height"));
BORDER_PROPERTY ("title_border", _("Title border"), _("Border around title area"));
BORDER_PROPERTY ("text_border", _("Text border"), _("Border around window title text"));
INT_PROPERTY ("spacer_padding", 3, _("Spacer padding"), _("Padding on either side of spacer"));
INT_PROPERTY ("spacer_width", 2, _("Spacer width"), _("Width of spacer"));
INT_PROPERTY ("spacer_height", 11, _("Spacer height"), _("Height of spacer"));
/* same as right_width left_width by default */
INT_PROPERTY ("right_inset", 6, _("Right inset"), _("Distance of buttons from right edge of frame"));
INT_PROPERTY ("left_inset", 6, _("Left inset"), _("Distance of menu button from left edge of frame"));
INT_PROPERTY ("button_width", 17, _("Button width"), _("Width of buttons"));
INT_PROPERTY ("button_height", 17, _("Button height"), _("Height of buttons"));
BORDER_PROPERTY ("button_border", _("Button border"), _("Border around buttons"));
BORDER_PROPERTY ("inner_button_border", _("Inner button border"), _("Border around the icon inside buttons"));
}
static gint
@ -222,8 +183,6 @@ meta_frames_init (MetaFrames *frames)
{
GTK_WINDOW (frames)->type = GTK_WINDOW_POPUP;
frames->layout = meta_frame_layout_new ();
frames->frames = g_hash_table_new (unsigned_long_hash, unsigned_long_equal);
frames->tooltip_timeout = 0;
@ -282,8 +241,6 @@ meta_frames_finalize (GObject *object)
g_assert (g_hash_table_size (frames->frames) == 0);
g_hash_table_destroy (frames->frames);
meta_frame_layout_free (frames->layout);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@ -327,107 +284,23 @@ meta_frames_style_set (GtkWidget *widget,
GtkStyle *prev_style)
{
MetaFrames *frames;
/* left, right, top, bottom */
static GtkBorder default_title_border = { 3, 4, 4, 3 };
static GtkBorder default_text_border = { 2, 2, 2, 2 };
static GtkBorder default_button_border = { 0, 0, 1, 1 };
static GtkBorder default_inner_button_border = {
DEFAULT_INNER_BUTTON_BORDER,
DEFAULT_INNER_BUTTON_BORDER,
DEFAULT_INNER_BUTTON_BORDER,
DEFAULT_INNER_BUTTON_BORDER
};
GtkBorder *title_border;
GtkBorder *text_border;
GtkBorder *button_border;
GtkBorder *inner_button_border;
MetaFrameLayout layout;
frames = META_FRAMES (widget);
if (GTK_WIDGET_REALIZED (widget))
{
frames->text_height = meta_gtk_widget_get_text_height (widget);
}
else
{
frames->text_height = 0;
}
gtk_widget_style_get (widget,
"left_width",
&layout.left_width,
"right_width",
&layout.right_width,
"bottom_height",
&layout.bottom_height,
"title_border",
&title_border,
"text_border",
&text_border,
"spacer_padding",
&layout.spacer_padding,
"spacer_width",
&layout.spacer_width,
"spacer_height",
&layout.spacer_height,
"right_inset",
&layout.right_inset,
"left_inset",
&layout.left_inset,
"button_width",
&layout.button_width,
"button_height",
&layout.button_height,
"button_border",
&button_border,
"inner_button_border",
&inner_button_border,
NULL);
if (title_border)
layout.title_border = *title_border;
else
layout.title_border = default_title_border;
g_free (title_border);
if (text_border)
layout.text_border = *text_border;
else
layout.text_border = default_text_border;
g_free (text_border);
if (button_border)
layout.button_border = *button_border;
else
layout.button_border = default_button_border;
g_free (button_border);
if (inner_button_border)
layout.inner_button_border = *inner_button_border;
else
layout.inner_button_border = default_inner_button_border;
g_free (inner_button_border);
*(frames->layout) = layout;
{
PangoFontMetrics *metrics;
PangoFont *font;
PangoLanguage *lang;
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);
g_object_unref (G_OBJECT (font));
frames->text_height =
PANGO_PIXELS (pango_font_metrics_get_ascent (metrics) +
pango_font_metrics_get_descent (metrics));
pango_font_metrics_unref (metrics);
}
/* Queue a draw/resize on all frames */
g_hash_table_foreach (frames->frames,
queue_recalc_func, frames);
GTK_WIDGET_CLASS (parent_class)->style_set (widget, prev_style);
}
static void
@ -437,18 +310,20 @@ meta_frames_calc_geometry (MetaFrames *frames,
{
int width, height;
MetaFrameFlags flags;
MetaFrameType type;
meta_core_get_client_size (gdk_display, frame->xwindow,
&width, &height);
flags = meta_core_get_frame_flags (gdk_display, frame->xwindow);
meta_frame_layout_calc_geometry (frames->layout,
GTK_WIDGET (frames),
frames->text_height,
flags,
width, height,
fgeom);
type = meta_core_get_frame_type (gdk_display, frame->xwindow);
meta_theme_calc_geometry (meta_theme_get_current (),
type,
frames->text_height,
flags,
width, height,
fgeom);
}
MetaFrames*
@ -526,6 +401,8 @@ 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
@ -537,6 +414,8 @@ 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*
@ -556,27 +435,31 @@ meta_frames_get_geometry (MetaFrames *frames,
int *top_height, int *bottom_height,
int *left_width, int *right_width)
{
MetaFrameFlags flags;
MetaFrameFlags flags;
MetaUIFrame *frame;
MetaFrameType type;
frame = meta_frames_lookup_window (frames, xwindow);
if (frame == NULL)
meta_bug ("No such frame 0x%lx\n", xwindow);
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);
g_return_if_fail (type < META_FRAME_TYPE_LAST);
/* We can't get the full geometry, because that depends on
* the client window size and probably we're being called
* by the core move/resize code to decide on the client
* window size
*/
meta_frame_layout_get_borders (frames->layout,
GTK_WIDGET (frames),
frames->text_height,
flags,
top_height, bottom_height,
left_width, right_width);
meta_theme_get_frame_borders (meta_theme_get_current (),
type,
frames->text_height,
flags,
top_height, bottom_height,
left_width, right_width);
}
void
@ -1082,7 +965,7 @@ meta_frames_button_release_event (GtkWidget *widget,
* frame are handled in the Xlib part of the code, display.c/window.c
*/
if (frame->xwindow == meta_core_get_grab_frame (gdk_display) &&
event->button == meta_core_get_grab_button (gdk_display))
((int) event->button) == meta_core_get_grab_button (gdk_display))
{
gboolean end_grab;
@ -1264,228 +1147,6 @@ meta_frames_destroy_event (GtkWidget *widget,
return TRUE;
}
#define THICK_LINE_WIDTH 3
static void
draw_mini_window (MetaFrames *frames,
GdkDrawable *drawable,
GdkGC *fg_gc,
GdkGC *bg_gc,
gboolean thin_title,
int x, int y, int width, int height)
{
GdkGCValues vals;
gdk_draw_rectangle (drawable,
bg_gc,
TRUE,
x, y, width - 1, height - 1);
gdk_draw_rectangle (drawable,
fg_gc,
FALSE,
x, y, width - 1, height - 1);
vals.line_width = thin_title ? THICK_LINE_WIDTH - 1 : THICK_LINE_WIDTH;
gdk_gc_set_values (fg_gc,
&vals,
GDK_GC_LINE_WIDTH);
gdk_draw_line (drawable,
fg_gc,
x, y + 1, x + width, y + 1);
vals.line_width = 0;
gdk_gc_set_values (fg_gc,
&vals,
GDK_GC_LINE_WIDTH);
}
static void
draw_control (MetaFrames *frames,
GdkDrawable *drawable,
GdkGC *fg_override,
GdkGC *bg_override,
MetaFrameControl control,
int x, int y, int width, int height)
{
GtkWidget *widget;
GdkGCValues vals;
GdkGC *fg_gc;
GdkGC *bg_gc;
widget = GTK_WIDGET (frames);
fg_gc = fg_override ? fg_override : widget->style->fg_gc[GTK_STATE_NORMAL];
bg_gc = bg_override ? bg_override : widget->style->bg_gc[GTK_STATE_NORMAL];
switch (control)
{
case META_FRAME_CONTROL_DELETE:
{
gdk_draw_line (drawable,
fg_gc,
x, y, x + width - 1, y + height - 1);
gdk_draw_line (drawable,
fg_gc,
x, y + height - 1, x + width - 1, y);
}
break;
case META_FRAME_CONTROL_MAXIMIZE:
{
draw_mini_window (frames, drawable, fg_gc, bg_gc, FALSE,
x, y, width, height);
}
break;
case META_FRAME_CONTROL_UNMAXIMIZE:
{
int w_delta = width * 0.3;
int h_delta = height * 0.3;
w_delta = MAX (w_delta, 3);
h_delta = MAX (h_delta, 3);
draw_mini_window (frames, drawable, fg_gc, bg_gc, TRUE,
x, y, width - w_delta, height - h_delta);
draw_mini_window (frames, drawable, fg_gc, bg_gc, TRUE,
x + w_delta, y + h_delta,
width - w_delta, height - h_delta);
}
break;
case META_FRAME_CONTROL_MINIMIZE:
{
vals.line_width = THICK_LINE_WIDTH;
gdk_gc_set_values (fg_gc,
&vals,
GDK_GC_LINE_WIDTH);
gdk_draw_line (drawable,
fg_gc,
x, y + height - THICK_LINE_WIDTH + 1,
x + width, y + height - THICK_LINE_WIDTH + 1);
vals.line_width = 0;
gdk_gc_set_values (fg_gc,
&vals,
GDK_GC_LINE_WIDTH);
}
break;
default:
break;
}
}
#undef THICK_LINE_WIDTH
void
meta_frames_get_pixmap_for_control (MetaFrames *frames,
MetaFrameControl control,
GdkPixmap **pixmapp,
GdkBitmap **maskp)
{
int w, h;
GdkPixmap *pix;
GdkBitmap *mask;
GtkWidget *widget;
GdkGC *mgc, *mgc_bg;
GdkColor color;
widget = GTK_WIDGET (frames);
gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &w, &h);
w -= DEFAULT_INNER_BUTTON_BORDER * 2;
h -= DEFAULT_INNER_BUTTON_BORDER * 2;
/* avoid crashing on bizarre icon sizes */
if (w < 1)
w = 1;
if (h < 1)
h = 1;
pix = gdk_pixmap_new (NULL, w, h, gtk_widget_get_visual (widget)->depth);
mask = gdk_pixmap_new (NULL, w, h, 1);
mgc = gdk_gc_new (mask);
mgc_bg = gdk_gc_new (mask);
color.pixel = 0;
gdk_gc_set_foreground (mgc_bg, &color);
color.pixel = 1;
gdk_gc_set_foreground (mgc, &color);
gdk_draw_rectangle (mask, mgc_bg, TRUE, 0, 0, -1, -1);
draw_control (frames, mask, mgc, mgc_bg, control, 0, 0, w, h);
gdk_gc_unref (mgc);
gdk_gc_unref (mgc_bg);
draw_control (frames, pix, NULL, NULL, control, 0, 0, w, h);
*pixmapp = pix;
*maskp = mask;
}
static void
draw_control_bg (MetaFrames *frames,
MetaUIFrame *frame,
GdkDrawable *drawable,
MetaFrameControl control,
MetaFrameGeometry *fgeom)
{
GdkRectangle *rect;
GtkWidget *widget;
gboolean draw = FALSE;
Window grab_frame;
widget = GTK_WIDGET (frames);
grab_frame = meta_core_get_grab_frame (gdk_display);
if (frame->xwindow == grab_frame)
{
switch (meta_core_get_grab_op (gdk_display))
{
case META_GRAB_OP_CLICKING_MENU:
draw = control == META_FRAME_CONTROL_MENU;
break;
case META_GRAB_OP_CLICKING_DELETE:
draw = control == META_FRAME_CONTROL_DELETE;
break;
case META_GRAB_OP_CLICKING_MAXIMIZE:
draw = control == META_FRAME_CONTROL_MAXIMIZE;
break;
case META_GRAB_OP_CLICKING_UNMAXIMIZE:
draw = control == META_FRAME_CONTROL_UNMAXIMIZE;
break;
case META_GRAB_OP_CLICKING_MINIMIZE:
draw = control == META_FRAME_CONTROL_MINIMIZE;
break;
default:
break;
}
}
if (draw)
{
rect = control_rect (control, fgeom);
if (rect == NULL)
return;
gtk_paint_box (widget->style, drawable,
GTK_STATE_ACTIVE,
GTK_SHADOW_IN, NULL,
widget, "button",
rect->x, rect->y, rect->width, rect->height);
}
}
static gboolean
meta_frames_expose_event (GtkWidget *widget,
GdkEventExpose *event)
@ -1518,285 +1179,77 @@ meta_frames_paint_to_drawable (MetaFrames *frames,
GdkRectangle *area)
{
GtkWidget *widget;
MetaFrameGeometry fgeom;
MetaFrameFlags flags;
int width, height;
GtkBorder inner;
MetaFrameType type;
GdkPixbuf *mini_icon;
GdkPixbuf *icon;
int w, h;
MetaButtonState button_states[META_BUTTON_TYPE_LAST];
Window grab_frame;
int i;
widget = GTK_WIDGET (frames);
/* note, prelight not implemented yet */
i = 0;
while (i < META_BUTTON_TYPE_LAST)
{
button_states[i] = META_BUTTON_STATE_NORMAL;
++i;
}
grab_frame = meta_core_get_grab_frame (gdk_display);
if (frame->xwindow == grab_frame)
{
switch (meta_core_get_grab_op (gdk_display))
{
case META_GRAB_OP_CLICKING_MENU:
button_states[META_BUTTON_TYPE_MENU] =
META_BUTTON_STATE_PRESSED;
break;
case META_GRAB_OP_CLICKING_DELETE:
button_states[META_BUTTON_TYPE_CLOSE] =
META_BUTTON_STATE_PRESSED;
break;
case META_GRAB_OP_CLICKING_MAXIMIZE:
button_states[META_BUTTON_TYPE_MAXIMIZE] =
META_BUTTON_STATE_PRESSED;
break;
case META_GRAB_OP_CLICKING_UNMAXIMIZE:
button_states[META_BUTTON_TYPE_MAXIMIZE] =
META_BUTTON_STATE_PRESSED;
break;
case META_GRAB_OP_CLICKING_MINIMIZE:
button_states[META_BUTTON_TYPE_MINIMIZE] =
META_BUTTON_STATE_PRESSED;
break;
default:
break;
}
}
meta_frames_calc_geometry (frames, frame, &fgeom);
flags = meta_core_get_frame_flags (gdk_display, frame->xwindow);
width = fgeom.width;
height = fgeom.height;
type = meta_core_get_frame_type (gdk_display, frame->xwindow);
mini_icon = meta_core_get_mini_icon (gdk_display, frame->xwindow);
icon = meta_core_get_icon (gdk_display, frame->xwindow);
meta_core_get_client_size (gdk_display, frame->xwindow,
&w, &h);
/* Black line around outside to give definition */
gdk_draw_rectangle (drawable,
widget->style->black_gc,
FALSE,
0, 0, width - 1, height - 1);
/* Light GC on top/left edges */
gdk_draw_line (drawable,
widget->style->light_gc[GTK_STATE_NORMAL],
1, 1,
1, height - 2);
gdk_draw_line (drawable,
widget->style->light_gc[GTK_STATE_NORMAL],
1, 1,
width - 2, 1);
/* Dark on bottom/right */
gdk_draw_line (drawable,
widget->style->dark_gc[GTK_STATE_NORMAL],
width - 2, 1,
width - 2, height - 2);
gdk_draw_line (drawable,
widget->style->dark_gc[GTK_STATE_NORMAL],
1, height - 2,
width - 2, height - 2);
if (flags & META_FRAME_HAS_FOCUS)
{
/* Black line around inside while we have focus */
gdk_draw_rectangle (drawable,
widget->style->black_gc,
FALSE,
fgeom.left_width - 1,
fgeom.top_height - 1,
width - fgeom.right_width - fgeom.left_width + 1,
height - fgeom.bottom_height - fgeom.top_height + 1);
}
if (area->y < fgeom.top_height &&
fgeom.title_rect.width > 0 && fgeom.title_rect.height > 0)
{
GdkRectangle clip;
GdkGC *layout_gc;
clip = fgeom.title_rect;
clip.x += frames->layout->text_border.left;
clip.width -= frames->layout->text_border.left +
frames->layout->text_border.right;
layout_gc = widget->style->fg_gc[GTK_STATE_NORMAL];
if (flags & META_FRAME_HAS_FOCUS)
{
GdkPixbuf *gradient;
GdkColor selected_faded;
const GdkColor *bg = &widget->style->bg[GTK_STATE_NORMAL];
/* alpha blend selection color into normal color */
#define ALPHA 25000
selected_faded = widget->style->bg[GTK_STATE_SELECTED];
selected_faded.red = selected_faded.red + (((bg->red - selected_faded.red) * ALPHA + 32768) >> 16);
selected_faded.green = selected_faded.green + (((bg->green - selected_faded.green) * ALPHA + 32768) >> 16);
selected_faded.blue = selected_faded.blue + (((bg->blue - selected_faded.blue) * ALPHA + 32768) >> 16);
layout_gc = widget->style->fg_gc[GTK_STATE_SELECTED];
gradient = meta_gradient_create_simple (fgeom.title_rect.width,
fgeom.title_rect.height,
&selected_faded,
&widget->style->bg[GTK_STATE_SELECTED],
META_GRADIENT_DIAGONAL);
if (gradient != NULL)
{
gdk_pixbuf_render_to_drawable (gradient,
drawable,
widget->style->bg_gc[GTK_STATE_SELECTED],
0, 0,
fgeom.title_rect.x,
fgeom.title_rect.y,
fgeom.title_rect.width,
fgeom.title_rect.height,
GDK_RGB_DITHER_MAX,
0, 0);
g_object_unref (G_OBJECT (gradient));
}
else
{
/* Fallback to plain selection color */
gdk_draw_rectangle (drawable,
widget->style->bg_gc[GTK_STATE_SELECTED],
TRUE,
fgeom.title_rect.x,
fgeom.title_rect.y,
fgeom.title_rect.width,
fgeom.title_rect.height);
}
}
if (frame->layout)
{
PangoRectangle layout_rect;
int x, y, icon_x, icon_y;
GdkPixbuf *icon;
int icon_w, icon_h;
int area_w, area_h;
#define ICON_TEXT_SPACING 2
icon = meta_core_get_mini_icon (gdk_display,
frame->xwindow);
icon_w = gdk_pixbuf_get_width (icon);
icon_h = gdk_pixbuf_get_height (icon);
pango_layout_get_pixel_extents (frame->layout,
NULL,
&layout_rect);
/* corner of whole title area */
x = fgeom.title_rect.x + frames->layout->text_border.left;
y = fgeom.title_rect.y + frames->layout->text_border.top;
area_w = fgeom.title_rect.width -
frames->layout->text_border.left -
frames->layout->text_border.right;
area_h = fgeom.title_rect.height -
frames->layout->text_border.top -
frames->layout->text_border.bottom;
/* center icon vertically */
icon_y = y + MAX ((area_h - icon_h) / 2, 0);
/* center text vertically */
y = y + MAX ((area_h - layout_rect.height) / 2, 0);
/* Center icon + text combo */
icon_x = x + MAX ((area_w - layout_rect.width - icon_w - ICON_TEXT_SPACING) / 2, 0);
x = icon_x + icon_w + ICON_TEXT_SPACING;
gdk_gc_set_clip_rectangle (layout_gc, &clip);
{
/* grumble, render_to_drawable_alpha does not accept a clip
* mask, so we have to go through some BS
*/
GdkRectangle pixbuf_rect;
GdkRectangle draw_rect;
pixbuf_rect.x = icon_x;
pixbuf_rect.y = icon_y;
pixbuf_rect.width = icon_w;
pixbuf_rect.height = icon_h;
if (gdk_rectangle_intersect (&clip, &pixbuf_rect, &draw_rect))
{
gdk_pixbuf_render_to_drawable_alpha (icon,
drawable,
draw_rect.x - pixbuf_rect.x,
draw_rect.y - pixbuf_rect.y,
draw_rect.x, draw_rect.y,
draw_rect.width,
draw_rect.height,
GDK_PIXBUF_ALPHA_FULL,
128,
GDK_RGB_DITHER_NORMAL,
0, 0);
}
}
gdk_draw_layout (drawable,
layout_gc,
x, y,
frame->layout);
gdk_gc_set_clip_rectangle (layout_gc, NULL);
}
}
inner = frames->layout->inner_button_border;
if (fgeom.close_rect.width > 0 && fgeom.close_rect.height > 0)
{
draw_control_bg (frames, frame, drawable,
META_FRAME_CONTROL_DELETE, &fgeom);
draw_control (frames, drawable,
NULL, NULL,
META_FRAME_CONTROL_DELETE,
fgeom.close_rect.x + inner.left,
fgeom.close_rect.y + inner.top,
fgeom.close_rect.width - inner.right - inner.left,
fgeom.close_rect.height - inner.bottom - inner.top);
}
if (fgeom.max_rect.width > 0 && fgeom.max_rect.height > 0)
{
MetaFrameControl ctrl;
if (flags & META_FRAME_MAXIMIZED)
ctrl = META_FRAME_CONTROL_UNMAXIMIZE;
else
ctrl = META_FRAME_CONTROL_MAXIMIZE;
draw_control_bg (frames, frame, drawable, ctrl, &fgeom);
draw_control (frames, drawable,
NULL, NULL,
ctrl,
fgeom.max_rect.x + inner.left,
fgeom.max_rect.y + inner.top,
fgeom.max_rect.width - inner.left - inner.right,
fgeom.max_rect.height - inner.top - inner.bottom);
}
if (fgeom.min_rect.width > 0 && fgeom.min_rect.height > 0)
{
draw_control_bg (frames, frame, drawable,
META_FRAME_CONTROL_MINIMIZE, &fgeom);
draw_control (frames, drawable,
NULL, NULL,
META_FRAME_CONTROL_MINIMIZE,
fgeom.min_rect.x + inner.left,
fgeom.min_rect.y + inner.top,
fgeom.min_rect.width - inner.left - inner.right,
fgeom.min_rect.height - inner.top - inner.bottom);
}
if (fgeom.spacer_rect.width > 0 && fgeom.spacer_rect.height > 0)
{
gtk_paint_vline (widget->style,
drawable,
GTK_STATE_NORMAL,
area,
widget,
"metacity_frame_spacer",
fgeom.spacer_rect.y,
fgeom.spacer_rect.y + fgeom.spacer_rect.height,
fgeom.spacer_rect.x + fgeom.spacer_rect.width / 2);
}
if (fgeom.menu_rect.width > 0 && fgeom.menu_rect.height > 0)
{
int x, y;
#define ARROW_WIDTH 7
#define ARROW_HEIGHT 5
draw_control_bg (frames, frame,
drawable,
META_FRAME_CONTROL_MENU, &fgeom);
x = fgeom.menu_rect.x;
y = fgeom.menu_rect.y;
x += (fgeom.menu_rect.width - ARROW_WIDTH) / 2;
y += (fgeom.menu_rect.height - ARROW_HEIGHT) / 2;
gtk_paint_arrow (widget->style,
drawable,
GTK_STATE_NORMAL,
GTK_SHADOW_OUT,
area,
widget,
"metacity_menu_button",
GTK_ARROW_DOWN,
TRUE,
x, y, ARROW_WIDTH, ARROW_HEIGHT);
}
meta_theme_draw_frame (meta_theme_get_current (),
widget,
drawable,
area,
0, 0,
type,
flags,
w, h,
frame->layout,
frames->text_height,
button_states,
mini_icon, icon);
}
static gboolean