diff options
Diffstat (limited to 'libmetacity/meta-theme-metacity.c')
-rw-r--r-- | libmetacity/meta-theme-metacity.c | 750 |
1 files changed, 288 insertions, 462 deletions
diff --git a/libmetacity/meta-theme-metacity.c b/libmetacity/meta-theme-metacity.c index 7d41ec20..d39a2ddb 100644 --- a/libmetacity/meta-theme-metacity.c +++ b/libmetacity/meta-theme-metacity.c @@ -4697,57 +4697,28 @@ meta_theme_metacity_get_frame_borders (MetaThemeImpl *impl, scale_border (&borders->total, scale); } -static MetaButtonSpace * -rect_for_type (MetaThemeMetacity *metacity, - MetaFrameGeometry *fgeom, - MetaFrameFlags flags, - MetaButtonType type) +static gboolean +is_button_allowed (MetaThemeMetacity *metacity, + MetaButtonType type) { if (theme_allows (metacity, META_THEME_SHADE_STICK_ABOVE_BUTTONS)) { switch (type) { case META_BUTTON_TYPE_SHADE: - if ((flags & META_FRAME_ALLOWS_SHADE) && !(flags & META_FRAME_SHADED)) - return &fgeom->shade_rect; - else - return NULL; - case META_BUTTON_TYPE_ABOVE: - if (!(flags & META_FRAME_ABOVE)) - return &fgeom->above_rect; - else - return NULL; - case META_BUTTON_TYPE_STICK: - if (!(flags & META_FRAME_STUCK)) - return &fgeom->stick_rect; - else - return NULL; - case META_BUTTON_TYPE_UNSHADE: - if ((flags & META_FRAME_ALLOWS_SHADE) && (flags & META_FRAME_SHADED)) - return &fgeom->unshade_rect; - else - return NULL; - case META_BUTTON_TYPE_UNABOVE: - if (flags & META_FRAME_ABOVE) - return &fgeom->unabove_rect; - else - return NULL; - case META_BUTTON_TYPE_UNSTICK: - if (flags & META_FRAME_STUCK) - return &fgeom->unstick_rect; - else - return NULL; + return TRUE; case META_BUTTON_TYPE_MENU: case META_BUTTON_TYPE_APPMENU: case META_BUTTON_TYPE_MINIMIZE: case META_BUTTON_TYPE_MAXIMIZE: case META_BUTTON_TYPE_CLOSE: + case META_BUTTON_TYPE_SPACER: case META_BUTTON_TYPE_LAST: default: break; @@ -4758,34 +4729,12 @@ rect_for_type (MetaThemeMetacity *metacity, switch (type) { case META_BUTTON_TYPE_MENU: - if (flags & META_FRAME_ALLOWS_MENU) - return &fgeom->menu_rect; - else - return NULL; - case META_BUTTON_TYPE_APPMENU: - if (flags & META_FRAME_ALLOWS_APPMENU) - return &fgeom->appmenu_rect; - else - return NULL; - case META_BUTTON_TYPE_MINIMIZE: - if (flags & META_FRAME_ALLOWS_MINIMIZE) - return &fgeom->min_rect; - else - return NULL; - case META_BUTTON_TYPE_MAXIMIZE: - if (flags & META_FRAME_ALLOWS_MAXIMIZE) - return &fgeom->max_rect; - else - return NULL; - case META_BUTTON_TYPE_CLOSE: - if (flags & META_FRAME_ALLOWS_DELETE) - return &fgeom->close_rect; - else - return NULL; + case META_BUTTON_TYPE_SPACER: + return TRUE; case META_BUTTON_TYPE_STICK: case META_BUTTON_TYPE_SHADE: @@ -4798,50 +4747,14 @@ rect_for_type (MetaThemeMetacity *metacity, * therefore, we don't show the button. return NULL and all will * be well. */ - return NULL; + break; case META_BUTTON_TYPE_LAST: default: break; } - return NULL; -} - -static gboolean -strip_button (MetaButtonSpace *func_rects[META_BUTTON_TYPE_LAST], - GdkRectangle *bg_rects[META_BUTTON_TYPE_LAST], - int *n_rects, - MetaButtonSpace *to_strip) -{ - int i; - - i = 0; - while (i < *n_rects) - { - if (func_rects[i] == to_strip) - { - *n_rects -= 1; - - /* shift the other rects back in the array */ - while (i < *n_rects) - { - func_rects[i] = func_rects[i+1]; - bg_rects[i] = bg_rects[i+1]; - - ++i; - } - - func_rects[i] = NULL; - bg_rects[i] = NULL; - - return TRUE; - } - - ++i; - } - - return FALSE; /* did not strip anything */ + return FALSE; } static void @@ -4867,16 +4780,6 @@ meta_theme_metacity_calc_geometry (MetaThemeImpl *impl, int min_size_for_rounding; int scale; - /* the left/right rects in order; the max # of rects - * is the number of button functions - */ - MetaButtonSpace *left_func_rects[META_BUTTON_TYPE_LAST]; - MetaButtonSpace *right_func_rects[META_BUTTON_TYPE_LAST]; - GdkRectangle *left_bg_rects[META_BUTTON_TYPE_LAST]; - gboolean left_buttons_has_spacer[META_BUTTON_TYPE_LAST]; - GdkRectangle *right_bg_rects[META_BUTTON_TYPE_LAST]; - gboolean right_buttons_has_spacer[META_BUTTON_TYPE_LAST]; - META_THEME_IMPL_GET_CLASS (impl)->get_frame_borders (impl, layout, style_info, text_height, flags, type, &borders); @@ -4914,16 +4817,6 @@ meta_theme_metacity_calc_geometry (MetaThemeImpl *impl, break; } - /* FIXME all this code sort of pretends that duplicate buttons - * with the same function are allowed, but that breaks the - * code in frames.c, so isn't really allowed right now. - * Would need left_close_rect, right_close_rect, etc. - */ - - /* Init all button rects to 0, lame hack */ - memset (ADDRESS_OF_BUTTON_RECTS (fgeom), '\0', - LENGTH_OF_BUTTON_RECTS); - n_left = 0; n_right = 0; n_left_spacers = 0; @@ -4933,64 +4826,45 @@ meta_theme_metacity_calc_geometry (MetaThemeImpl *impl, if (!layout->hide_buttons) { - /* Try to fill in rects */ - for (i = 0; i < META_BUTTON_TYPE_LAST && button_layout->left_buttons[i] != META_BUTTON_TYPE_LAST; i++) + MetaButton *button; + + for (i = 0; i < button_layout->n_left_buttons; i++) { - left_func_rects[n_left] = rect_for_type (metacity, fgeom, flags, - button_layout->left_buttons[i]); - if (left_func_rects[n_left] != NULL) - { - left_buttons_has_spacer[n_left] = button_layout->left_buttons_has_spacer[i]; - if (button_layout->left_buttons_has_spacer[i]) - ++n_left_spacers; + button = &button_layout->left_buttons[i]; + button->visible = is_button_visible (button, flags) && + is_button_allowed (metacity, button->type); - ++n_left; + if (button->visible) + { + if (button->type != META_BUTTON_TYPE_SPACER) + n_left++; + else + n_left_spacers++; } } - for (i = 0; i < META_BUTTON_TYPE_LAST && button_layout->right_buttons[i] != META_BUTTON_TYPE_LAST; i++) + for (i = 0; i < button_layout->n_right_buttons; i++) { - right_func_rects[n_right] = rect_for_type (metacity, fgeom, flags, - button_layout->right_buttons[i]); - if (right_func_rects[n_right] != NULL) - { - right_buttons_has_spacer[n_right] = button_layout->right_buttons_has_spacer[i]; - if (button_layout->right_buttons_has_spacer[i]) - ++n_right_spacers; + button = &button_layout->right_buttons[i]; + button->visible = is_button_visible (button, flags) && + is_button_allowed (metacity, button->type); - ++n_right; + if (button->visible) + { + if (button->type != META_BUTTON_TYPE_SPACER) + n_left++; + else + n_left_spacers++; } } } - - for (i = 0; i < META_BUTTON_TYPE_LAST; i++) + else { - left_bg_rects[i] = NULL; - right_bg_rects[i] = NULL; - } + for (i = 0; i < button_layout->n_left_buttons; i++) + button_layout->left_buttons[i].visible = FALSE; - for (i = 0; i < n_left; i++) - { - if (n_left == 1) - left_bg_rects[i] = &fgeom->left_single_background; - else if (i == 0) - left_bg_rects[i] = &fgeom->left_left_background; - else if (i == (n_left - 1)) - left_bg_rects[i] = &fgeom->left_right_background; - else - left_bg_rects[i] = &fgeom->left_middle_backgrounds[i - 1]; - } - - for (i = 0; i < n_right; i++) - { - if (n_right == 1) - right_bg_rects[i] = &fgeom->right_single_background; - else if (i == (n_right - 1)) - right_bg_rects[i] = &fgeom->right_right_background; - else if (i == 0) - right_bg_rects[i] = &fgeom->right_left_background; - else - right_bg_rects[i] = &fgeom->right_middle_backgrounds[i - 1]; + for (i = 0; i < button_layout->n_right_buttons; i++) + button_layout->right_buttons[i].visible = FALSE; } /* Be sure buttons fit */ @@ -5021,67 +4895,41 @@ meta_theme_metacity_calc_geometry (MetaThemeImpl *impl, /* First try to remove separators */ if (n_left_spacers > 0) { - left_buttons_has_spacer[--n_left_spacers] = FALSE; - continue; + if (strip_button (button_layout->left_buttons, + button_layout->n_left_buttons, + META_BUTTON_TYPE_SPACER)) + { + n_left_spacers--; + continue; + } + else + { + g_assert_not_reached (); + } } else if (n_right_spacers > 0) { - right_buttons_has_spacer[--n_right_spacers] = FALSE; - continue; + if (strip_button (button_layout->right_buttons, + button_layout->n_right_buttons, + META_BUTTON_TYPE_SPACER)) + { + n_right_spacers--; + continue; + } + else + { + g_assert_not_reached (); + } } /* Otherwise we need to shave out a button. Shave * above, stick, shade, min, max, close, then menu (menu is most useful); * prefer the default button locations. */ - if (strip_button (left_func_rects, left_bg_rects, - &n_left, &fgeom->above_rect)) - continue; - else if (strip_button (right_func_rects, right_bg_rects, - &n_right, &fgeom->above_rect)) - continue; - else if (strip_button (left_func_rects, left_bg_rects, - &n_left, &fgeom->stick_rect)) - continue; - else if (strip_button (right_func_rects, right_bg_rects, - &n_right, &fgeom->stick_rect)) - continue; - else if (strip_button (left_func_rects, left_bg_rects, - &n_left, &fgeom->shade_rect)) - continue; - else if (strip_button (right_func_rects, right_bg_rects, - &n_right, &fgeom->shade_rect)) - continue; - else if (strip_button (left_func_rects, left_bg_rects, - &n_left, &fgeom->min_rect)) - continue; - else if (strip_button (right_func_rects, right_bg_rects, - &n_right, &fgeom->min_rect)) - continue; - else if (strip_button (left_func_rects, left_bg_rects, - &n_left, &fgeom->max_rect)) - continue; - else if (strip_button (right_func_rects, right_bg_rects, - &n_right, &fgeom->max_rect)) - continue; - else if (strip_button (left_func_rects, left_bg_rects, - &n_left, &fgeom->close_rect)) - continue; - else if (strip_button (right_func_rects, right_bg_rects, - &n_right, &fgeom->close_rect)) - continue; - else if (strip_button (right_func_rects, right_bg_rects, - &n_right, &fgeom->menu_rect)) - continue; - else if (strip_button (left_func_rects, left_bg_rects, - &n_left, &fgeom->menu_rect)) - continue; - else if (strip_button (right_func_rects, right_bg_rects, - &n_right, &fgeom->appmenu_rect)) - continue; - else if (strip_button (left_func_rects, left_bg_rects, - &n_left, &fgeom->appmenu_rect)) - continue; + if (strip_buttons (button_layout, &n_left, &n_right)) + { + continue; + } else { g_error ("Could not find a button to strip. n_left = %d n_right = %d", @@ -5089,10 +4937,6 @@ meta_theme_metacity_calc_geometry (MetaThemeImpl *impl, } } - /* Save the button layout */ - button_layout->n_left_buttons = n_left; - button_layout->n_right_buttons = n_right; - /* center buttons vertically */ button_y = (borders.visible.top - (button_height + layout->button_border.top * scale + layout->button_border.bottom * scale)) / 2 + layout->button_border.top * scale + borders.invisible.top; @@ -5100,45 +4944,56 @@ meta_theme_metacity_calc_geometry (MetaThemeImpl *impl, /* right edge of farthest-right button */ x = width - layout->metacity.right_titlebar_edge * scale - borders.invisible.right; - i = n_right - 1; - while (i >= 0) + for (i = button_layout->n_right_buttons - 1; i >= 0; i--) { - MetaButtonSpace *rect; + MetaButton *button; + GdkRectangle rect; - if (x < 0) /* if we go negative, leave the buttons we don't get to as 0-width */ - break; + button = &button_layout->right_buttons[i]; + + if (button->visible == FALSE) + continue; - rect = right_func_rects[i]; - rect->visible.x = x - layout->button_border.right * scale - button_width; - if (right_buttons_has_spacer[i]) - rect->visible.x -= (button_width * 0.75); + /* if we go negative, leave the buttons we don't get to as 0 - width */ + if (x < 0) + break; - rect->visible.y = button_y; - rect->visible.width = button_width; - rect->visible.height = button_height; + rect.y = button_y; + rect.width = button_width; + rect.height = button_height; - if (flags & META_FRAME_MAXIMIZED || - flags & META_FRAME_TILED_LEFT || - flags & META_FRAME_TILED_RIGHT) + if (button->type == META_BUTTON_TYPE_SPACER) { - rect->clickable.x = rect->visible.x; - rect->clickable.y = rect->visible.y; - rect->clickable.width = button_width; - rect->clickable.height = button_height; - - if (i == n_right - 1) - rect->clickable.width += layout->metacity.right_titlebar_edge * scale + - layout->metacity.right_width * scale + - layout->button_border.right * scale; + rect.x = x - button_width * 0.75; + rect.width *= 0.75; } else - g_memmove (&(rect->clickable), &(rect->visible), sizeof(rect->clickable)); + { + rect.x = x - layout->button_border.right * scale - button_width; + } + + button->rect.visible = rect; + button->rect.clickable = rect; - *(right_bg_rects[i]) = rect->visible; + if ((flags & META_FRAME_MAXIMIZED || flags & META_FRAME_TILED_RIGHT) && + i == button_layout->n_right_buttons - 1) + { + gint extra_width; + gint extra_height; + + extra_width = layout->metacity.right_titlebar_edge * scale + + layout->metacity.right_width * scale + + layout->button_border.right * scale; - x = rect->visible.x - layout->button_border.left * scale; + /* FIXME: */ + extra_height = 0; + + button->rect.clickable.y -= extra_height; + button->rect.clickable.width += extra_width; + button->rect.clickable.height += extra_height; + } - --i; + x = rect.x - layout->button_border.left * scale; } /* save right edge of titlebar for later use */ @@ -5148,32 +5003,48 @@ meta_theme_metacity_calc_geometry (MetaThemeImpl *impl, * the left-side buttons */ x = layout->metacity.left_titlebar_edge * scale + borders.invisible.left; - for (i = 0; i < n_left; i++) + + for (i = 0; i < button_layout->n_left_buttons; i++) { - MetaButtonSpace *rect; + MetaButton *button; + GdkRectangle rect; + + button = &button_layout->left_buttons[i]; + + if (button->visible == FALSE) + continue; - rect = left_func_rects[i]; + rect.x = x + layout->button_border.left * scale;; + rect.y = button_y; + rect.width = button_width; + rect.height = button_height; - rect->visible.x = x + layout->button_border.left * scale; - rect->visible.y = button_y; - rect->visible.width = button_width; - rect->visible.height = button_height; + if (button->type == META_BUTTON_TYPE_SPACER) + rect.width *= 0.75; - if (flags & META_FRAME_MAXIMIZED) + button->rect.visible = rect; + button->rect.clickable = rect; + + if ((flags & META_FRAME_MAXIMIZED || flags & META_FRAME_TILED_LEFT) && + i == 0) { - rect->clickable.x = rect->visible.x; - rect->clickable.y = rect->visible.y; - rect->clickable.width = button_width; - rect->clickable.height = button_height; - } - else - g_memmove (&(rect->clickable), &(rect->visible), sizeof(rect->clickable)); + gint extra_width; + gint extra_height; + + extra_width = layout->metacity.left_titlebar_edge * scale + + layout->metacity.left_width * scale + + layout->button_border.left * scale; - x = rect->visible.x + rect->visible.width + layout->button_border.right * scale; - if (left_buttons_has_spacer[i]) - x += (button_width * 0.75); + /* FIXME: */ + extra_height = 0; - *(left_bg_rects[i]) = rect->visible; + button->rect.clickable.x -= extra_width; + button->rect.clickable.y -= extra_height; + button->rect.clickable.width += extra_width; + button->rect.clickable.height += extra_height; + } + + x = rect.x + rect.width + layout->button_border.right * scale; } /* We always fill as much vertical space as possible with title rect, @@ -5286,179 +5157,111 @@ clip_to_rounded_corners (cairo_t *cr, cairo_clip (cr); } -static void -get_button_rect (MetaButtonFunction function, - const MetaFrameGeometry *fgeom, - gint middle_background_offset, - GdkRectangle *rect) +static MetaButtonFunction +get_button_function (MetaButtonType type, + gboolean background, + gint button, + gint n_buttons, + gint side) { - switch (function) + if (background) { - case META_BUTTON_FUNCTION_LEFT_LEFT_BACKGROUND: - *rect = fgeom->left_left_background; - break; - - case META_BUTTON_FUNCTION_LEFT_MIDDLE_BACKGROUND: - *rect = fgeom->left_middle_backgrounds[middle_background_offset]; - break; - - case META_BUTTON_FUNCTION_LEFT_RIGHT_BACKGROUND: - *rect = fgeom->left_right_background; - break; - - case META_BUTTON_FUNCTION_LEFT_SINGLE_BACKGROUND: - *rect = fgeom->left_single_background; - break; - - case META_BUTTON_FUNCTION_RIGHT_LEFT_BACKGROUND: - *rect = fgeom->right_left_background; - break; - - case META_BUTTON_FUNCTION_RIGHT_MIDDLE_BACKGROUND: - *rect = fgeom->right_middle_backgrounds[middle_background_offset]; - break; - - case META_BUTTON_FUNCTION_RIGHT_RIGHT_BACKGROUND: - *rect = fgeom->right_right_background; - break; - - case META_BUTTON_FUNCTION_RIGHT_SINGLE_BACKGROUND: - *rect = fgeom->right_single_background; - break; - - case META_BUTTON_FUNCTION_CLOSE: - *rect = fgeom->close_rect.visible; - break; - - case META_BUTTON_FUNCTION_SHADE: - *rect = fgeom->shade_rect.visible; - break; - - case META_BUTTON_FUNCTION_UNSHADE: - *rect = fgeom->unshade_rect.visible; - break; - - case META_BUTTON_FUNCTION_ABOVE: - *rect = fgeom->above_rect.visible; - break; + if (side == 0) /* left */ + { + if (n_buttons == 1) + { + return META_BUTTON_FUNCTION_LEFT_SINGLE_BACKGROUND; + } + else if (n_buttons == 2) + { + if (button == 0) + return META_BUTTON_FUNCTION_LEFT_LEFT_BACKGROUND; + else + return META_BUTTON_FUNCTION_LEFT_RIGHT_BACKGROUND; + } + else if (n_buttons > 2) + { + if (button == 0) + return META_BUTTON_FUNCTION_LEFT_LEFT_BACKGROUND; + else if (button == n_buttons - 1) + return META_BUTTON_FUNCTION_LEFT_RIGHT_BACKGROUND; + else + return META_BUTTON_FUNCTION_LEFT_MIDDLE_BACKGROUND; + } + } + else if (side == 1) /* right */ + { + if (n_buttons == 1) + { + return META_BUTTON_FUNCTION_RIGHT_SINGLE_BACKGROUND; + } + else if (n_buttons == 2) + { + if (button == 0) + return META_BUTTON_FUNCTION_RIGHT_LEFT_BACKGROUND; + else + return META_BUTTON_FUNCTION_RIGHT_RIGHT_BACKGROUND; + } + else if (n_buttons > 2) + { + if (button == 0) + return META_BUTTON_FUNCTION_RIGHT_LEFT_BACKGROUND; + else if (button == n_buttons - 1) + return META_BUTTON_FUNCTION_RIGHT_RIGHT_BACKGROUND; + else + return META_BUTTON_FUNCTION_RIGHT_MIDDLE_BACKGROUND; + } + } + else + { + g_assert_not_reached (); + } + } + else + { + switch (type) + { + case META_BUTTON_TYPE_SHADE: + return META_BUTTON_FUNCTION_SHADE; - case META_BUTTON_FUNCTION_UNABOVE: - *rect = fgeom->unabove_rect.visible; - break; + case META_BUTTON_TYPE_UNSHADE: + return META_BUTTON_FUNCTION_UNSHADE; - case META_BUTTON_FUNCTION_STICK: - *rect = fgeom->stick_rect.visible; - break; + case META_BUTTON_TYPE_ABOVE: + return META_BUTTON_FUNCTION_ABOVE; - case META_BUTTON_FUNCTION_UNSTICK: - *rect = fgeom->unstick_rect.visible; - break; + case META_BUTTON_TYPE_UNABOVE: + return META_BUTTON_FUNCTION_UNABOVE; - case META_BUTTON_FUNCTION_MAXIMIZE: - *rect = fgeom->max_rect.visible; - break; + case META_BUTTON_TYPE_STICK: + return META_BUTTON_FUNCTION_STICK; - case META_BUTTON_FUNCTION_MINIMIZE: - *rect = fgeom->min_rect.visible; - break; + case META_BUTTON_TYPE_UNSTICK: + return META_BUTTON_FUNCTION_UNSTICK; - case META_BUTTON_FUNCTION_MENU: - *rect = fgeom->menu_rect.visible; - break; + case META_BUTTON_TYPE_MENU: + return META_BUTTON_FUNCTION_MENU; - case META_BUTTON_FUNCTION_APPMENU: - *rect = fgeom->appmenu_rect.visible; - break; + case META_BUTTON_TYPE_APPMENU: + return META_BUTTON_FUNCTION_APPMENU; - case META_BUTTON_FUNCTION_LAST: - default: - g_assert_not_reached (); - break; - } -} + case META_BUTTON_TYPE_MINIMIZE: + return META_BUTTON_FUNCTION_MINIMIZE; -static MetaButtonState -map_button_state (MetaButtonFunction button_function, - const MetaFrameGeometry *fgeom, - gint middle_bg_offset, - const MetaButtonLayout *button_layout) -{ - MetaButtonType type = META_BUTTON_TYPE_LAST; + case META_BUTTON_TYPE_MAXIMIZE: + return META_BUTTON_FUNCTION_MAXIMIZE; - switch (button_function) - { - /* First handle types, which map directly */ - case META_BUTTON_FUNCTION_SHADE: - type = META_BUTTON_TYPE_SHADE; - break; - case META_BUTTON_FUNCTION_ABOVE: - type = META_BUTTON_TYPE_ABOVE; - break; - case META_BUTTON_FUNCTION_STICK: - type = META_BUTTON_TYPE_STICK; - break; - case META_BUTTON_FUNCTION_UNSHADE: - type = META_BUTTON_TYPE_UNSHADE; - break; - case META_BUTTON_FUNCTION_UNABOVE: - type = META_BUTTON_TYPE_UNABOVE; - break;; - case META_BUTTON_FUNCTION_UNSTICK: - type = META_BUTTON_TYPE_UNSTICK; - break; - case META_BUTTON_FUNCTION_MENU: - type = META_BUTTON_TYPE_MENU; - break; - case META_BUTTON_FUNCTION_APPMENU: - type = META_BUTTON_TYPE_APPMENU; - break; - case META_BUTTON_FUNCTION_MINIMIZE: - type = META_BUTTON_TYPE_MINIMIZE; - break; - case META_BUTTON_FUNCTION_MAXIMIZE: - type = META_BUTTON_TYPE_MAXIMIZE; - break; - case META_BUTTON_FUNCTION_CLOSE: - type = META_BUTTON_TYPE_CLOSE; - break; + case META_BUTTON_TYPE_CLOSE: + return META_BUTTON_FUNCTION_CLOSE; - /* Map position buttons to the corresponding type */ - case META_BUTTON_FUNCTION_RIGHT_LEFT_BACKGROUND: - case META_BUTTON_FUNCTION_RIGHT_SINGLE_BACKGROUND: - if (button_layout->n_right_buttons > 0) - type = button_layout->right_buttons[0]; - break; - case META_BUTTON_FUNCTION_RIGHT_RIGHT_BACKGROUND: - if (button_layout->n_right_buttons > 0) - type = button_layout->right_buttons[button_layout->n_right_buttons - 1]; - break; - case META_BUTTON_FUNCTION_RIGHT_MIDDLE_BACKGROUND: - if (middle_bg_offset + 1 < button_layout->n_right_buttons) - type = button_layout->right_buttons[middle_bg_offset + 1]; - break; - case META_BUTTON_FUNCTION_LEFT_LEFT_BACKGROUND: - case META_BUTTON_FUNCTION_LEFT_SINGLE_BACKGROUND: - if (button_layout->n_left_buttons > 0) - type = button_layout->left_buttons[0]; - break; - case META_BUTTON_FUNCTION_LEFT_RIGHT_BACKGROUND: - if (button_layout->n_left_buttons > 0) - type = button_layout->left_buttons[button_layout->n_left_buttons - 1]; - break; - case META_BUTTON_FUNCTION_LEFT_MIDDLE_BACKGROUND: - if (middle_bg_offset + 1 < button_layout->n_left_buttons) - type = button_layout->left_buttons[middle_bg_offset + 1]; - break; - case META_BUTTON_FUNCTION_LAST: - break; - default: - break; + case META_BUTTON_TYPE_SPACER: + case META_BUTTON_TYPE_LAST: + default: + break; + } } - if (type != META_BUTTON_TYPE_LAST) - return button_layout->button_states[type]; - - return META_BUTTON_STATE_LAST; + return META_BUTTON_FUNCTION_LAST; } static void @@ -5474,7 +5277,7 @@ meta_theme_metacity_draw_frame (MetaThemeImpl *impl, GdkPixbuf *icon) { gdouble scale; - int i, j; + gint i; MetaRectangleDouble visible_rect; MetaRectangleDouble titlebar_rect; MetaRectangleDouble left_titlebar_edge; @@ -5685,55 +5488,78 @@ meta_theme_metacity_draw_frame (MetaThemeImpl *impl, /* Draw buttons just before overlay */ if ((i + 1) == META_FRAME_PIECE_OVERLAY) { - MetaDrawOpList *op_list; - int middle_bg_offset; + gint side; - middle_bg_offset = 0; - j = 0; - while (j < META_BUTTON_FUNCTION_LAST) + for (side = 0; side < 2; side++) { - GdkRectangle tmp_rect; - MetaButtonState button_state; + MetaButton *buttons; + gint n_buttons; + gint j; - get_button_rect (j, fgeom, middle_bg_offset, &tmp_rect); - - rect.x = tmp_rect.x / scale; - rect.y = tmp_rect.y / scale; - rect.width = tmp_rect.width / scale; - rect.height = tmp_rect.height / scale; - - button_state = map_button_state (j, fgeom, middle_bg_offset, - button_layout); - - op_list = meta_frame_style_get_button (style, j, button_state); + if (side == 0) + { + buttons = button_layout->left_buttons; + n_buttons = button_layout->n_left_buttons; + } + else if (side == 1) + { + buttons = button_layout->right_buttons; + n_buttons = button_layout->n_right_buttons; + } + else + { + g_assert_not_reached (); + } - if (op_list) + for (j = 0; j < n_buttons; j++) { - cairo_save (cr); + MetaButton *button; + gint op; - cairo_rectangle (cr, rect.x, rect.y, rect.width, rect.height); - cairo_clip (cr); + button = &buttons[j]; - if (gdk_cairo_get_clip_rectangle (cr, NULL)) + rect.x = button->rect.visible.x / scale; + rect.y = button->rect.visible.y / scale; + rect.width = button->rect.visible.width / scale; + rect.height = button->rect.visible.height / scale; + + if (!button->visible || + button->type == META_BUTTON_TYPE_SPACER || + rect.width <= 0 || rect.height <= 0) { - meta_draw_op_list_draw_with_style (op_list, context, cr, - &draw_info, rect); + continue; } - cairo_restore (cr); - } + for (op = 0; op < 2; op++) + { + MetaButtonFunction function; + MetaDrawOpList *op_list; - /* MIDDLE_BACKGROUND type may get drawn more than once */ - if ((j == META_BUTTON_FUNCTION_RIGHT_MIDDLE_BACKGROUND || - j == META_BUTTON_FUNCTION_LEFT_MIDDLE_BACKGROUND) && - (middle_bg_offset < (MAX_MIDDLE_BACKGROUNDS - 1))) - { - ++middle_bg_offset; - } - else - { - middle_bg_offset = 0; - ++j; + function = get_button_function (button->type, op == 0, + j, n_buttons, op); + + op_list = meta_frame_style_get_button (style, function, + button->state); + + if (op_list) + { + cairo_save (cr); + + cairo_rectangle (cr, rect.x, rect.y, + rect.width, rect.height); + cairo_clip (cr); + + if (gdk_cairo_get_clip_rectangle (cr, NULL)) + { + meta_draw_op_list_draw_with_style (op_list, + context, cr, + &draw_info, + rect); + } + + cairo_restore (cr); + } + } } } } |