mirror of
https://github.com/brl/mutter.git
synced 2025-07-05 10:31:18 +00:00
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:

committed by
Havoc Pennington

parent
2be2d8ccbe
commit
8ae714eeae
755
src/frames.c
755
src/frames.c
@ -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
|
||||
|
Reference in New Issue
Block a user