summaryrefslogtreecommitdiff
path: root/libmetacity/meta-theme-metacity.c
diff options
context:
space:
mode:
Diffstat (limited to 'libmetacity/meta-theme-metacity.c')
-rw-r--r--libmetacity/meta-theme-metacity.c750
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);
+ }
+ }
}
}
}