summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Thurman <tthurman@gnome.org>2009-10-28 13:41:16 -0400
committerThomas Thurman <tthurman@gnome.org>2009-10-28 13:41:16 -0400
commitd5b1a8c3426381c57db7af09e349d29f815f85bf (patch)
treeffcf86d8a09dbaa3c937363cd5240b806b92963d
parent0888e53080406e466348616d7dd27c6ceb28a8ae (diff)
downloadmetacity-d5b1a8c3426381c57db7af09e349d29f815f85bf.tar.gz
knock out buttons in priority order when there isn't enough space
-rw-r--r--src/ui/theme.c121
1 files changed, 110 insertions, 11 deletions
diff --git a/src/ui/theme.c b/src/ui/theme.c
index 8df39820..0bf4bc2e 100644
--- a/src/ui/theme.c
+++ b/src/ui/theme.c
@@ -92,6 +92,23 @@ char *cowbell_human_names[] =
NULL
};
+/**
+ * Sometimes there are too many buttons to show in the space
+ * on the titlebar; this is the order in which they should
+ * be removed. The menu button should be the last
+ * to go, since you can do any of the other operations using it.
+ */
+gint meta_theme_button_priorities[] = {
+ CC_ABOVE,
+ CC_STICK,
+ CC_SHADE,
+ CC_MINIMIZE,
+ CC_MAXIMIZE,
+ CC_CLOSE,
+ CC_MENU,
+ CC_LAST
+};
+
typedef struct
{
ccss_node_t basic;
@@ -845,6 +862,8 @@ meta_theme_calc_geometry (MetaTheme *theme,
const MetaButtonLayout *button_layout,
MetaFrameGeometry *fgeom)
{
+ const int allocated_left = -1;
+ const int allocated_right = -2;
int i;
int button_height, button_y;
int x;
@@ -955,6 +974,16 @@ meta_theme_calc_geometry (MetaTheme *theme,
fgeom->areas[CC_TITLEBAR].bottom_edge);
button_y = fgeom->areas[CC_TITLEBAR].y +
fgeom->areas[CC_TITLEBAR].top_edge;
+
+ /*
+ * We temporarily use two magic negative values
+ * for fgeom->areas[n].x:
+ *
+ * allocated_left -- allocated on the left
+ * allocated_right -- allocated on the right
+ * and zero means not allocated at all.
+ */
+
for (i=CC_BUTTON_FIRST; i<=CC_BUTTON_LAST; i++)
{
fgeom->areas[i].height = button_height;
@@ -968,23 +997,85 @@ meta_theme_calc_geometry (MetaTheme *theme,
* but we do not adjust the height; setting top and bottom
* margins on a button just compresses the button
*/
- fgeom->areas[i].x = -1; /* dummy value, to check
- * for when we haven't allocated it
- */
+ fgeom->areas[i].x = 0;
fgeom->areas[i].y = button_y;
}
- /* FIXME:
- * Here we need to nuke any buttons (and the title)
- * that make the contents of the titlebar wider than
- * it can be.
+ /*
+ * If the total width is too wide,
+ * knock out some of the buttons, in priority order.
*/
+ {
+ int total_width = 0;
+ int available_width =
+ fgeom->areas[CC_TITLEBAR].width -
+ (fgeom->areas[CC_TITLEBAR].left_edge +
+ fgeom->areas[CC_TITLEBAR].right_edge);
+
+ for (i=0; i<MAX_BUTTONS_PER_CORNER; i++)
+ {
+ int button = button_layout->left_buttons[i];
+ CopperClasses cc;
+
+ if (button == META_BUTTON_FUNCTION_LAST)
+ break;
+
+ cc = copper_class_for_button(button);
+ total_width += fgeom->areas[cc].width;
+ fgeom->areas[cc].x = allocated_left;
+ }
+
+ for (i=0; i<MAX_BUTTONS_PER_CORNER; i++)
+ {
+ int button = button_layout->right_buttons[i];
+ CopperClasses cc;
+
+ if (button == META_BUTTON_FUNCTION_LAST)
+ break;
+
+ cc = copper_class_for_button(button);
+ total_width += fgeom->areas[cc].width;
+ fgeom->areas[cc].x = allocated_right;
+ }
+
+ i=0;
+ while (total_width > available_width &&
+ meta_theme_button_priorities[i]!=CC_LAST)
+ {
+ CopperClasses button = meta_theme_button_priorities[i];
+
+ if (fgeom->areas[button].x < 0)
+ {
+ total_width -= fgeom->areas[button].width;
+
+ fgeom->areas[button].x =
+ fgeom->areas[button].y =
+ fgeom->areas[button].width =
+ fgeom->areas[button].height =
+ 0;
+ }
+
+ i++;
+ }
+ }
+
+
/* And now allocate the buttons as necessary. */
- /* FIXME: We are not honouring spacers.
+
+ /*
+ * We are not honouring spacers.
* They should possibly be removed anyway.
*/
+ /*
+ * It's probably a little silly to loop over button_layout again
+ * since we've already done it, but we do it this way at present
+ * to get the ordering right. TODO: Perhaps we need a separate array
+ * that holds 0 if a button isn't displayed, and descending/ascending
+ * +ve or -ve values for its ordering on the left or right side.
+ */
+
/* The left-hand side */
x = fgeom->areas[CC_TITLEBAR].x +
@@ -1000,6 +1091,10 @@ meta_theme_calc_geometry (MetaTheme *theme,
cc = copper_class_for_button(button);
+ if (fgeom->areas[cc].x==0)
+ /* must have been knocked out */
+ continue;
+
/* so allocate it */
fgeom->areas[cc].x = x;
x += fgeom->areas[cc].width;
@@ -1028,9 +1123,13 @@ meta_theme_calc_geometry (MetaTheme *theme,
cc = copper_class_for_button(button);
+ if (fgeom->areas[cc].x==0)
+ /* must have been knocked out */
+ continue;
+
/* so allocate it */
- x -= fgeom->areas[copper_class_for_button(button)].width;
- fgeom->areas[copper_class_for_button(button)].x = x;
+ x -= fgeom->areas[cc].width;
+ fgeom->areas[cc].x = x;
fgeom->areas[CC_TITLE].width -= fgeom->areas[cc].width;
}
@@ -1038,7 +1137,7 @@ meta_theme_calc_geometry (MetaTheme *theme,
/* Now find the ones we didn't use, and zero them out */
for (i=CC_BUTTON_FIRST; i<=CC_BUTTON_LAST; i++)
{
- if (fgeom->areas[i].x==-1)
+ if (fgeom->areas[i].x < 0)
{
fgeom->areas[i].x =
fgeom->areas[i].y =