From c506b4862445dfa3b038eefd767499c715ccd4f6 Mon Sep 17 00:00:00 2001 From: rhp Date: Sun, 3 Jun 2001 21:39:57 +0000 Subject: [PATCH] ... --- src/api.c | 3 +- src/api.h | 3 +- src/display.c | 2 + src/frame.c | 136 +++++++++++++--- src/frame.h | 7 +- src/screen.c | 10 ++ src/screen.h | 5 + src/theme.c | 443 ++++++++++++++++++++++++++++++++++++++++++-------- src/theme.h | 8 +- 9 files changed, 516 insertions(+), 101 deletions(-) diff --git a/src/api.c b/src/api.c index da09db4ee..c6e5a74d4 100644 --- a/src/api.c +++ b/src/api.c @@ -25,8 +25,7 @@ PangoContext* meta_get_pango_context (Screen *xscreen, - const PangoFontDescription *desc, - Window frame) + const PangoFontDescription *desc) { MetaScreen *screen; diff --git a/src/api.h b/src/api.h index d2fa9c089..526af6bc7 100644 --- a/src/api.h +++ b/src/api.h @@ -55,8 +55,7 @@ struct _MetaUIColors }; PangoContext* meta_get_pango_context (Screen *xscreen, - const PangoFontDescription *desc, - Window frame); + const PangoFontDescription *desc); gulong meta_get_x_pixel (Screen *xscreen, const PangoColor *color); diff --git a/src/display.c b/src/display.c index 55e6aa609..037e43f0a 100644 --- a/src/display.c +++ b/src/display.c @@ -191,6 +191,8 @@ meta_display_close (MetaDisplay *display) /* If the next node doesn't contain this window * a second time, delete the window. */ + g_assert (tmp->data != NULL); + if (tmp->next == NULL || (tmp->next && tmp->next->data != tmp->data)) meta_window_free (tmp->data); diff --git a/src/frame.c b/src/frame.c index 3b211ab72..431e66d25 100644 --- a/src/frame.c +++ b/src/frame.c @@ -28,8 +28,14 @@ static void meta_frame_init_info (MetaFrame *frame, MetaFrameInfo *info) { - info->flags = 0; - info->frame = frame->xwindow; + info->flags = + META_FRAME_ALLOWS_DELETE | META_FRAME_ALLOWS_MENU | + META_FRAME_ALLOWS_ICONIFY | META_FRAME_ALLOWS_MAXIMIZE | + META_FRAME_ALLOWS_RESIZE; + + info->drawable = None; + info->xoffset = 0; + info->yoffset = 0; info->display = frame->window->display->xdisplay; info->screen = frame->window->screen->xscreen; info->visual = frame->window->xvisual; @@ -132,13 +138,39 @@ meta_frame_calc_geometry (MetaFrame *frame, frame->child_x = geom.left_width; frame->child_y = geom.top_height; - + frame->rect.width = frame->rect.width + geom.left_width + geom.right_width; frame->rect.height = frame->rect.height + geom.top_height + geom.bottom_height; + frame->bg_pixel = geom.background_pixel; + *geomp = geom; } +static void +set_background_none (MetaFrame *frame) +{ + XSetWindowAttributes attrs; + + attrs.background_pixmap = None; + XChangeWindowAttributes (frame->window->display->xdisplay, + frame->xwindow, + CWBackPixmap, + &attrs); +} + +static void +set_background_color (MetaFrame *frame) +{ + XSetWindowAttributes attrs; + + attrs.background_pixel = None; + XChangeWindowAttributes (frame->window->display->xdisplay, + frame->xwindow, + CWBackPixel, + &attrs); +} + void meta_window_ensure_frame (MetaWindow *window) { @@ -176,7 +208,7 @@ meta_window_ensure_frame (MetaWindow *window) frame->child_x, frame->child_y, window->size_hints.win_gravity); - attrs.background_pixel = geom.background_pixel; + attrs.background_pixel = frame->bg_pixel; attrs.event_mask = StructureNotifyMask | SubstructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | OwnerGrabButtonMask | @@ -308,13 +340,15 @@ meta_frame_child_configure_request (MetaFrame *frame) meta_frame_calc_initial_pos (frame, frame->window->size_hints.x, frame->window->size_hints.y); - + + set_background_none (frame); XMoveResizeWindow (frame->window->display->xdisplay, frame->xwindow, frame->rect.x, frame->rect.y, frame->rect.width, frame->rect.height); + set_background_color (frame); } void @@ -322,7 +356,6 @@ meta_frame_recalc_now (MetaFrame *frame) { int old_child_x, old_child_y; MetaFrameGeometry geom; - XSetWindowAttributes attrs; old_child_x = frame->child_x; old_child_y = frame->child_y; @@ -341,19 +374,15 @@ meta_frame_recalc_now (MetaFrame *frame) if (old_child_y != frame->child_y) frame->rect.y += (frame->child_y - old_child_y); + set_background_none (frame); XMoveResizeWindow (frame->window->display->xdisplay, frame->xwindow, frame->rect.x, frame->rect.y, frame->rect.width, frame->rect.height); - - attrs.background_pixel = geom.background_pixel; - XChangeWindowAttributes (frame->window->display->xdisplay, - frame->xwindow, - CWBackPixel, - &attrs); - + set_background_color (frame); + meta_verbose ("Frame of %s recalculated to %d,%d %d x %d child %d,%d\n", frame->window->desc, frame->rect.x, frame->rect.y, frame->rect.width, frame->rect.height, @@ -363,15 +392,73 @@ meta_frame_recalc_now (MetaFrame *frame) void meta_frame_queue_recalc (MetaFrame *frame) { - /* FIXME */ + /* FIXME, actually queue */ meta_frame_recalc_now (frame); } +static void +meta_frame_draw_now (MetaFrame *frame, + int x, int y, int width, int height) +{ + MetaFrameInfo info; + Pixmap p; + XGCValues vals; + + if (frame->xwindow == None) + return; + + meta_frame_init_info (frame, &info); + + if (width < 0) + width = frame->rect.width; + + if (height < 0) + height = frame->rect.height; + + if (width == 0 || height == 0) + return; + + p = XCreatePixmap (frame->window->display->xdisplay, + frame->xwindow, + width, height, + frame->window->screen->visual_info.depth); + + vals.foreground = frame->bg_pixel; + XChangeGC (frame->window->display->xdisplay, + frame->window->screen->scratch_gc, + GCForeground, + &vals); + + XFillRectangle (frame->window->display->xdisplay, + p, + frame->window->screen->scratch_gc, + 0, 0, + width, height); + + info.drawable = p; + info.xoffset = - x; + info.yoffset = - y; + frame->window->screen->engine->expose_frame (&info, + 0, 0, width, height, + frame->theme_data); + + + XCopyArea (frame->window->display->xdisplay, + p, frame->xwindow, + frame->window->screen->scratch_gc, + 0, 0, + width, height, + x, y); + + XFreePixmap (frame->window->display->xdisplay, + p); +} + void meta_frame_queue_draw (MetaFrame *frame) { - /* FIXME */ - + /* FIXME, actually queue */ + meta_frame_draw_now (frame, 0, 0, -1, -1); } static void @@ -523,10 +610,12 @@ meta_frame_event (MetaFrame *frame, break; case META_FRAME_ACTION_NONE: +#if 0 meta_ui_slave_show_tip (frame->window->screen->uislave, frame->rect.x, frame->rect.y, "Hi this is a tooltip"); +#endif break; default: break; @@ -543,16 +632,11 @@ meta_frame_event (MetaFrame *frame, case KeymapNotify: break; case Expose: - { - MetaFrameInfo info; - meta_frame_init_info (frame, &info); - frame->window->screen->engine->expose_frame (&info, - event->xexpose.x, - event->xexpose.y, - event->xexpose.width, - event->xexpose.height, - frame->theme_data); - } + meta_frame_draw_now (frame, + event->xexpose.x, + event->xexpose.y, + event->xexpose.width, + event->xexpose.height); break; case GraphicsExpose: break; diff --git a/src/frame.h b/src/frame.h index 739a74f74..cea1bb2ab 100644 --- a/src/frame.h +++ b/src/frame.h @@ -39,15 +39,16 @@ struct _MetaFrame /* reparent window */ Window xwindow; - /* This is trusted info from where we put the + /* This rect is trusted info from where we put the * frame, not the result of ConfigureNotify */ MetaRectangle rect; int child_x; int child_y; - + gpointer theme_data; - + gulong bg_pixel; + MetaFrameAction action; /* reference point for drags */ int last_x, last_y; diff --git a/src/screen.c b/src/screen.c index 6e1e0eb49..f47e650e3 100644 --- a/src/screen.c +++ b/src/screen.c @@ -46,6 +46,7 @@ meta_screen_new (MetaDisplay *display, Window xroot; Display *xdisplay; Cursor cursor; + XGCValues vals; /* Only display->name, display->xdisplay, and display->error_traps * can really be used in this function, since normally screens are @@ -101,6 +102,11 @@ meta_screen_new (MetaDisplay *display, meta_screen_init_visual_info (screen); meta_screen_init_ui_colors (screen); + + screen->scratch_gc = XCreateGC (screen->display->xdisplay, + screen->xroot, + 0, + &vals); screen->uislave = meta_ui_slave_new (screen->screen_name, ui_slave_func, @@ -116,6 +122,10 @@ void meta_screen_free (MetaScreen *screen) { meta_ui_slave_free (screen->uislave); + + XFreeGC (screen->display->xdisplay, + screen->scratch_gc); + if (screen->pango_context) g_object_unref (G_OBJECT (screen->pango_context)); g_free (screen->screen_name); diff --git a/src/screen.h b/src/screen.h index ba0e90407..42cca884d 100644 --- a/src/screen.h +++ b/src/screen.h @@ -41,6 +41,11 @@ struct _MetaScreen XVisualInfo visual_info; MetaUIColors colors; + + /* In screen's visual, no guarantees about colors, shouldn't be + * left with a clip. + */ + GC scratch_gc; /*< private >*/ diff --git a/src/theme.c b/src/theme.c index f0410dcb3..58561385c 100644 --- a/src/theme.c +++ b/src/theme.c @@ -21,14 +21,32 @@ #include "theme.h" #include "api.h" +#include "util.h" -typedef struct _DefaultFrameData DefaultFrameData; -typedef struct _DefaultScreenData DefaultScreenData; +typedef struct _DefaultFrameData DefaultFrameData; +typedef struct _DefaultScreenData DefaultScreenData; +typedef struct _DefaultFrameGeometry DefaultFrameGeometry; + +struct _DefaultFrameGeometry +{ + /* We recalculate this every time, to save RAM */ + int left_width; + int right_width; + int top_height; + int bottom_height; + + MetaRectangle close_rect; + MetaRectangle max_rect; + MetaRectangle min_rect; + MetaRectangle spacer_rect; + MetaRectangle menu_rect; + MetaRectangle title_rect; +}; struct _DefaultFrameData { PangoLayout *layout; - int title_height; + int layout_height; }; struct _DefaultScreenData @@ -84,13 +102,12 @@ default_acquire_frame (MetaFrameInfo *info) d = g_new (DefaultFrameData, 1); - desc = pango_font_description_from_string ("Sans 16"); + desc = pango_font_description_from_string ("Sans 12"); d->layout = pango_layout_new (meta_get_pango_context (info->screen, - desc, - info->frame)); + desc)); pango_font_description_free (desc); - d->title_height = 0; + d->layout_height = 0; return d; } @@ -109,11 +126,140 @@ default_release_frame (MetaFrameInfo *info, g_free (d); } -#define VERTICAL_TEXT_PAD 3 -#define LEFT_WIDTH 15 -#define RIGHT_WIDTH 15 -#define BOTTOM_HEIGHT 20 +#define VERTICAL_TITLE_PAD 2 +#define HORIZONTAL_TITLE_PAD 3 +#define VERTICAL_TEXT_PAD 2 +#define HORIZONTAL_TEXT_PAD 2 +#define LEFT_WIDTH 2 +#define RIGHT_WIDTH 2 +#define BOTTOM_HEIGHT 5 #define SPACER_SPACING 3 +#define SPACER_WIDTH 2 +#define SPACER_HEIGHT 10 +#define BUTTON_WIDTH 12 +#define BUTTON_HEIGHT 12 +#define BUTTON_PAD 2 +#define INNER_BUTTON_PAD 1 +static void +calc_geometry (MetaFrameInfo *info, + DefaultFrameData *d, + DefaultFrameGeometry *fgeom) +{ + int x; + int button_y; + int title_right_edge; + + fgeom->top_height = MAX (d->layout_height + VERTICAL_TITLE_PAD * 2 + VERTICAL_TEXT_PAD * 2, + BUTTON_HEIGHT + BUTTON_PAD * 2); + + fgeom->left_width = LEFT_WIDTH; + fgeom->right_width = RIGHT_WIDTH; + fgeom->bottom_height = BOTTOM_HEIGHT; + + x = info->width - fgeom->right_width; + button_y = (fgeom->top_height - BUTTON_HEIGHT) / 2; + + if (info->flags & META_FRAME_ALLOWS_DELETE) + { + fgeom->close_rect.x = x - BUTTON_PAD - BUTTON_WIDTH; + fgeom->close_rect.y = button_y; + fgeom->close_rect.width = BUTTON_WIDTH; + fgeom->close_rect.height = BUTTON_HEIGHT; + + x = fgeom->close_rect.x; + } + else + { + fgeom->close_rect.x = 0; + fgeom->close_rect.y = 0; + fgeom->close_rect.width = 0; + fgeom->close_rect.height = 0; + } + + if (info->flags & META_FRAME_ALLOWS_MAXIMIZE) + { + fgeom->max_rect.x = x - BUTTON_PAD - BUTTON_WIDTH; + fgeom->max_rect.y = button_y; + fgeom->max_rect.width = BUTTON_WIDTH; + fgeom->max_rect.height = BUTTON_HEIGHT; + + x = fgeom->max_rect.x; + } + else + { + fgeom->max_rect.x = 0; + fgeom->max_rect.y = 0; + fgeom->max_rect.width = 0; + fgeom->max_rect.height = 0; + } + + if (info->flags & META_FRAME_ALLOWS_ICONIFY) + { + fgeom->min_rect.x = x - BUTTON_PAD - BUTTON_WIDTH; + fgeom->min_rect.y = button_y; + fgeom->min_rect.width = BUTTON_WIDTH; + fgeom->min_rect.height = BUTTON_HEIGHT; + + x = fgeom->min_rect.x; + } + else + { + fgeom->min_rect.x = 0; + fgeom->min_rect.y = 0; + fgeom->min_rect.width = 0; + fgeom->min_rect.height = 0; + } + + if (fgeom->close_rect.width > 0 || + fgeom->max_rect.width > 0 || + fgeom->min_rect.width > 0) + { + fgeom->spacer_rect.x = x - SPACER_SPACING - SPACER_WIDTH; + fgeom->spacer_rect.y = (fgeom->top_height - SPACER_HEIGHT) / 2; + fgeom->spacer_rect.width = SPACER_WIDTH; + fgeom->spacer_rect.height = SPACER_HEIGHT; + + x = fgeom->spacer_rect.x; + } + else + { + fgeom->spacer_rect.x = 0; + fgeom->spacer_rect.y = 0; + fgeom->spacer_rect.width = 0; + fgeom->spacer_rect.height = 0; + } + + title_right_edge = x - HORIZONTAL_TITLE_PAD; + + /* Now x changes to be position from the left */ + x = fgeom->left_width; + + if (info->flags & META_FRAME_ALLOWS_MENU) + { + fgeom->menu_rect.x = x + BUTTON_PAD; + fgeom->menu_rect.y = button_y; + fgeom->menu_rect.width = BUTTON_WIDTH; + fgeom->menu_rect.height = BUTTON_HEIGHT; + + x = fgeom->menu_rect.x + fgeom->menu_rect.width; + } + else + { + fgeom->menu_rect.x = 0; + fgeom->menu_rect.y = 0; + fgeom->menu_rect.width = 0; + fgeom->menu_rect.height = 0; + } + + fgeom->title_rect.x = x + BUTTON_PAD; + fgeom->title_rect.y = VERTICAL_TITLE_PAD; + fgeom->title_rect.width = title_right_edge - fgeom->title_rect.x; + fgeom->title_rect.height = fgeom->top_height - VERTICAL_TITLE_PAD * 2; + + if (fgeom->title_rect.width < 0) + fgeom->title_rect.width = 0; +} + static void default_fill_frame_geometry (MetaFrameInfo *info, MetaFrameGeometry *geom, @@ -121,6 +267,7 @@ default_fill_frame_geometry (MetaFrameInfo *info, { DefaultFrameData *d; PangoRectangle rect; + DefaultFrameGeometry fgeom; d = frame_data; @@ -131,13 +278,14 @@ default_fill_frame_geometry (MetaFrameInfo *info, pango_layout_get_pixel_extents (d->layout, NULL, &rect); - d->title_height = rect.height + VERTICAL_TEXT_PAD * 2; - geom->top_height = d->title_height; - - geom->left_width = LEFT_WIDTH; - geom->right_width = RIGHT_WIDTH; - geom->bottom_height = BOTTOM_HEIGHT; - + d->layout_height = rect.height; + + calc_geometry (info, d, &fgeom); + geom->top_height = fgeom.top_height; + geom->left_width = fgeom.left_width; + geom->right_width = fgeom.right_width; + geom->bottom_height = fgeom.bottom_height; + geom->background_pixel = meta_get_x_pixel (info->screen, &info->colors->bg[META_STATE_NORMAL]); } @@ -151,6 +299,7 @@ draw_vline (MetaFrameInfo *info, int y2, int x) { + /* From GTK+ */ int thickness_light; int thickness_dark; int i; @@ -176,6 +325,76 @@ draw_vline (MetaFrameInfo *info, } } +static void +draw_varrow (MetaFrameInfo *info, + Drawable drawable, + GC gc, + gboolean down, + gint x, + gint y, + gint width, + gint height) +{ + gint steps, extra; + gint y_start, y_increment; + gint i; + + /* From GTK+ */ + + width = width + width % 2 - 1; /* Force odd */ + + steps = 1 + width / 2; + + extra = height - steps; + + if (down) + { + y_start = y; + y_increment = 1; + } + else + { + y_start = y + height - 1; + y_increment = -1; + } + + for (i = 0; i < extra; i++) + { + XDrawLine (info->display, drawable, + gc, + x, y_start + i * y_increment, + x + width - 1, y_start + i * y_increment); + } + for (; i < height; i++) + { + XDrawLine (info->display, drawable, + gc, + x + (i - extra), y_start + i * y_increment, + x + width - (i - extra) - 1, y_start + i * y_increment); + } +} + +static void +set_clip (Display *display, GC gc, MetaRectangle *rect) +{ + if (rect) + { + XRectangle xrect; + + xrect.x = rect->x; + xrect.y = rect->y; + xrect.width = rect->width; + xrect.height = rect->height; + + XSetClipRectangles (display, gc, 0, 0, + &xrect, 1, YXBanded); + } + else + { + XSetClipMask (display, gc, None); + } +} + static void default_expose_frame (MetaFrameInfo *info, int x, int y, @@ -183,56 +402,150 @@ default_expose_frame (MetaFrameInfo *info, gpointer frame_data) { DefaultFrameData *d; - int close_size; XGCValues vals; + int xoff, yoff; + DefaultFrameGeometry fgeom; d = frame_data; + + calc_geometry (info, d, &fgeom); - pango_x_render_layout (info->display, - info->frame, - screen_data->text_gc, - d->layout, - LEFT_WIDTH, - VERTICAL_TEXT_PAD); + xoff = info->xoffset; + yoff = info->yoffset; - close_size = d->title_height; + if (fgeom.title_rect.width > 0 && fgeom.title_rect.height > 0) + { + int layout_y; + MetaRectangle clip; - vals.line_width = 2; - XChangeGC (info->display, - screen_data->fg_gc, - GCLineWidth, - &vals); + /* center vertically */ + layout_y = fgeom.title_rect.y + + (fgeom.title_rect.height - d->layout_height) / 2; + + clip = fgeom.title_rect; + clip.x += xoff; + clip.y += yoff; + clip.width -= HORIZONTAL_TEXT_PAD; + + set_clip (info->display, screen_data->text_gc, &clip); + if (info->flags & META_FRAME_HAS_FOCUS) + { + /* FIXME use STATE_SELECTED */ + + } + + pango_x_render_layout (info->display, + info->drawable, + screen_data->text_gc, + d->layout, + xoff + fgeom.title_rect.x + HORIZONTAL_TEXT_PAD, + yoff + layout_y); + set_clip (info->display, screen_data->text_gc, NULL); + } + + if (fgeom.close_rect.width > 0 && fgeom.close_rect.height > 0) + { + XDrawLine (info->display, + info->drawable, + screen_data->fg_gc, + xoff + fgeom.close_rect.x + INNER_BUTTON_PAD, + yoff + fgeom.close_rect.y + INNER_BUTTON_PAD, + xoff + fgeom.close_rect.x + fgeom.close_rect.width - INNER_BUTTON_PAD, + yoff + fgeom.close_rect.y + fgeom.close_rect.height - INNER_BUTTON_PAD); + + + XDrawLine (info->display, + info->drawable, + screen_data->fg_gc, + xoff + fgeom.close_rect.x + INNER_BUTTON_PAD, + yoff + fgeom.close_rect.y + fgeom.close_rect.height - INNER_BUTTON_PAD, + xoff + fgeom.close_rect.x + fgeom.close_rect.width - INNER_BUTTON_PAD, + yoff + fgeom.close_rect.y + INNER_BUTTON_PAD); + } + + if (fgeom.max_rect.width > 0 && fgeom.max_rect.height > 0) + { + XDrawRectangle (info->display, + info->drawable, + screen_data->fg_gc, + xoff + fgeom.max_rect.x + INNER_BUTTON_PAD, + yoff + fgeom.max_rect.y + INNER_BUTTON_PAD, + fgeom.max_rect.width - INNER_BUTTON_PAD * 2, + fgeom.max_rect.height - INNER_BUTTON_PAD * 2); + + vals.line_width = 3; + XChangeGC (info->display, + screen_data->fg_gc, + GCLineWidth, + &vals); + + XDrawLine (info->display, + info->drawable, + screen_data->fg_gc, + xoff + fgeom.max_rect.x + INNER_BUTTON_PAD, + yoff + fgeom.max_rect.y + INNER_BUTTON_PAD + vals.line_width / 2, + xoff + fgeom.max_rect.x + fgeom.max_rect.width - INNER_BUTTON_PAD, + yoff + fgeom.max_rect.y + INNER_BUTTON_PAD + vals.line_width / 2); + + vals.line_width = 0; + XChangeGC (info->display, + screen_data->fg_gc, + GCLineWidth, + &vals); + } + + if (fgeom.min_rect.width > 0 && fgeom.min_rect.height > 0) + { + vals.line_width = 3; + XChangeGC (info->display, + screen_data->fg_gc, + GCLineWidth, + &vals); + + XDrawLine (info->display, + info->drawable, + screen_data->fg_gc, + xoff + fgeom.min_rect.x + INNER_BUTTON_PAD, + yoff + fgeom.min_rect.y + fgeom.min_rect.height - INNER_BUTTON_PAD - vals.line_width / 2, + xoff + fgeom.min_rect.x + fgeom.min_rect.width - INNER_BUTTON_PAD, + yoff + fgeom.min_rect.y + fgeom.min_rect.height - INNER_BUTTON_PAD - vals.line_width / 2); + + vals.line_width = 0; + XChangeGC (info->display, + screen_data->fg_gc, + GCLineWidth, + &vals); + } - XDrawLine (info->display, - info->frame, - screen_data->fg_gc, - info->width - RIGHT_WIDTH - close_size, - VERTICAL_TEXT_PAD, - info->width - RIGHT_WIDTH, - d->title_height - VERTICAL_TEXT_PAD); + if (fgeom.spacer_rect.width > 0 && fgeom.spacer_rect.height > 0) + { + draw_vline (info, info->drawable, + screen_data->light_gc, + screen_data->dark_gc, + yoff + fgeom.spacer_rect.y, + yoff + fgeom.spacer_rect.y + fgeom.spacer_rect.height, + xoff + fgeom.spacer_rect.x); + } - XDrawLine (info->display, - info->frame, - screen_data->fg_gc, - info->width - RIGHT_WIDTH, - VERTICAL_TEXT_PAD, - info->width - RIGHT_WIDTH - close_size, - d->title_height - VERTICAL_TEXT_PAD); - - vals.line_width = 0; - XChangeGC (info->display, - screen_data->fg_gc, - GCLineWidth, - &vals); - - draw_vline (info, info->frame, - screen_data->light_gc, - screen_data->dark_gc, - VERTICAL_TEXT_PAD, - d->title_height - VERTICAL_TEXT_PAD, - info->width - RIGHT_WIDTH - close_size - SPACER_SPACING); + if (fgeom.menu_rect.width > 0 && fgeom.menu_rect.height > 0) + { + int x, y; + x = fgeom.menu_rect.x; + y = fgeom.menu_rect.y; + x += (fgeom.menu_rect.width - 7) / 2; + y += (fgeom.menu_rect.height - 5) / 2; + + draw_varrow (info, info->drawable, screen_data->fg_gc, TRUE, + xoff + x, yoff + y, 7, 5); + } } +#define POINT_IN_RECT(xcoord, ycoord, rect) \ + ((xcoord) >= (rect).x && \ + (xcoord) < ((rect).x + (rect).width) && \ + (ycoord) >= (rect).y && \ + (ycoord) < ((rect).y + (rect).height)) + #define RESIZE_EXTENDS 10 static MetaFrameControl default_get_control (MetaFrameInfo *info, @@ -240,20 +553,20 @@ default_get_control (MetaFrameInfo *info, gpointer frame_data) { DefaultFrameData *d; - int close_size; + DefaultFrameGeometry fgeom; d = frame_data; - close_size = d->title_height; - if (y < d->title_height && - x > info->width - RIGHT_WIDTH - close_size) + calc_geometry (info, d, &fgeom); + + if (POINT_IN_RECT (x, y, fgeom.close_rect)) return META_FRAME_CONTROL_DELETE; - if (y < d->title_height) + if (POINT_IN_RECT (x, y, fgeom.title_rect)) return META_FRAME_CONTROL_TITLE; - if (y > (info->height - BOTTOM_HEIGHT - RESIZE_EXTENDS) && - x > (info->width - RIGHT_WIDTH - RESIZE_EXTENDS)) + if (y > (info->height - fgeom.bottom_height - RESIZE_EXTENDS) && + x > (info->width - fgeom.right_width - RESIZE_EXTENDS)) return META_FRAME_CONTROL_RESIZE_SE; return META_FRAME_CONTROL_NONE; diff --git a/src/theme.h b/src/theme.h index bfeaf34d6..5fdea6dba 100644 --- a/src/theme.h +++ b/src/theme.h @@ -40,7 +40,8 @@ typedef enum META_FRAME_ALLOWS_ICONIFY = 1 << 2, META_FRAME_ALLOWS_MAXIMIZE = 1 << 3, META_FRAME_ALLOWS_RESIZE = 1 << 4, - META_FRAME_TRANSIENT = 1 << 5 + META_FRAME_TRANSIENT = 1 << 5, + META_FRAME_HAS_FOCUS = 1 << 6 } MetaFrameFlags; typedef enum @@ -65,7 +66,8 @@ struct _MetaFrameInfo { /* These are read-only to engines */ MetaFrameFlags flags; - Window frame; /* == None in fill_frame_geometry */ + Window drawable; /* == None except in expose */ + int xoffset, yoffset; /* add to frame coords to get drawable coords */ Display *display; Screen *screen; Visual *visual; @@ -94,7 +96,7 @@ struct _MetaFrameGeometry unsigned long background_pixel; Pixmap shape_mask; - /* FIXME shape region */ + /* FIXME shape region? */ }; struct _MetaThemeEngine