Add support for "spacer" as a button type which adds some empty space.

2008-02-29  Andrea Del Signore  <sejerpz@tin.it>

	Add support for "spacer" as a button type which adds some
	empty space. Closes #509165.

        * src/ui/theme.c (meta_frame_layout_calc_geometry),
          src/include/common.h (MetaButtonLayout),
          src/core/prefs.c (update_button_layout, button_layout_equal),
          src/metacity.schemas.in: add spacer support


svn path=/trunk/; revision=3615
This commit is contained in:
Andrea Del Signore 2008-02-29 20:41:07 +00:00 committed by Thomas James Alexander Thurman
parent 8c6f3853b0
commit e021e06178
5 changed files with 123 additions and 28 deletions

View File

@ -1,3 +1,13 @@
2008-02-29 Andrea Del Signore <sejerpz@tin.it>
Add support for "spacer" as a button type which adds some
empty space. Closes #509165.
* src/ui/theme.c (meta_frame_layout_calc_geometry),
src/include/common.h (MetaButtonLayout),
src/core/prefs.c (update_button_layout, button_layout_equal),
src/metacity.schemas.in: add spacer support
2008-02-28 Thomas Thurman <tthurman@gnome.org> 2008-02-28 Thomas Thurman <tthurman@gnome.org>
* src/core/compositor.h: removed unnecessary #include which * src/core/compositor.h: removed unnecessary #include which

View File

@ -1346,6 +1346,10 @@ button_layout_equal (const MetaButtonLayout *a,
return FALSE; return FALSE;
if (a->right_buttons[i] != b->right_buttons[i]) if (a->right_buttons[i] != b->right_buttons[i])
return FALSE; return FALSE;
if (a->left_buttons_has_spacer[i] != b->left_buttons_has_spacer[i])
return FALSE;
if (a->right_buttons_has_spacer[i] != b->right_buttons_has_spacer[i])
return FALSE;
++i; ++i;
} }
@ -1426,6 +1430,7 @@ update_button_layout (const char *value)
while (i < META_BUTTON_FUNCTION_LAST) while (i < META_BUTTON_FUNCTION_LAST)
{ {
used[i] = FALSE; used[i] = FALSE;
new_layout.left_buttons_has_spacer[i] = FALSE;
++i; ++i;
} }
@ -1435,28 +1440,42 @@ update_button_layout (const char *value)
while (buttons[b] != NULL) while (buttons[b] != NULL)
{ {
MetaButtonFunction f = button_function_from_string (buttons[b]); MetaButtonFunction f = button_function_from_string (buttons[b]);
if (i > 0 && strcmp("spacer", buttons[b]) == 0)
if (f != META_BUTTON_FUNCTION_LAST && !used[f])
{ {
new_layout.left_buttons[i] = f; new_layout.left_buttons_has_spacer[i-1] = TRUE;
used[f] = TRUE;
++i;
f = button_opposite_function (f); f = button_opposite_function (f);
if (f != META_BUTTON_FUNCTION_LAST) if (f != META_BUTTON_FUNCTION_LAST)
new_layout.left_buttons[i++] = f; {
new_layout.left_buttons_has_spacer[i-2] = TRUE;
}
} }
else else
{ {
meta_topic (META_DEBUG_PREFS, "Ignoring unknown or already-used button name \"%s\"\n", if (f != META_BUTTON_FUNCTION_LAST && !used[f])
buttons[b]); {
new_layout.left_buttons[i] = f;
used[f] = TRUE;
++i;
f = button_opposite_function (f);
if (f != META_BUTTON_FUNCTION_LAST)
new_layout.left_buttons[i++] = f;
}
else
{
meta_topic (META_DEBUG_PREFS, "Ignoring unknown or already-used button name \"%s\"\n",
buttons[b]);
}
} }
++b; ++b;
} }
new_layout.left_buttons[i] = META_BUTTON_FUNCTION_LAST; new_layout.left_buttons[i] = META_BUTTON_FUNCTION_LAST;
new_layout.left_buttons_has_spacer[i] = FALSE;
g_strfreev (buttons); g_strfreev (buttons);
} }
@ -1471,6 +1490,7 @@ update_button_layout (const char *value)
while (i < META_BUTTON_FUNCTION_LAST) while (i < META_BUTTON_FUNCTION_LAST)
{ {
used[i] = FALSE; used[i] = FALSE;
new_layout.right_buttons_has_spacer[i] = FALSE;
++i; ++i;
} }
@ -1480,28 +1500,41 @@ update_button_layout (const char *value)
while (buttons[b] != NULL) while (buttons[b] != NULL)
{ {
MetaButtonFunction f = button_function_from_string (buttons[b]); MetaButtonFunction f = button_function_from_string (buttons[b]);
if (i > 0 && strcmp("spacer", buttons[b]) == 0)
if (f != META_BUTTON_FUNCTION_LAST && !used[f])
{ {
new_layout.right_buttons[i] = f; new_layout.right_buttons_has_spacer[i-1] = TRUE;
used[f] = TRUE;
++i;
f = button_opposite_function (f); f = button_opposite_function (f);
if (f != META_BUTTON_FUNCTION_LAST) if (f != META_BUTTON_FUNCTION_LAST)
new_layout.right_buttons[i++] = f; {
} new_layout.right_buttons_has_spacer[i-2] = TRUE;
}
}
else else
{ {
meta_topic (META_DEBUG_PREFS, "Ignoring unknown or already-used button name \"%s\"\n", if (f != META_BUTTON_FUNCTION_LAST && !used[f])
buttons[b]); {
new_layout.right_buttons[i] = f;
used[f] = TRUE;
++i;
f = button_opposite_function (f);
if (f != META_BUTTON_FUNCTION_LAST)
new_layout.right_buttons[i++] = f;
}
else
{
meta_topic (META_DEBUG_PREFS, "Ignoring unknown or already-used button name \"%s\"\n",
buttons[b]);
}
} }
++b; ++b;
} }
new_layout.right_buttons[i] = META_BUTTON_FUNCTION_LAST; new_layout.right_buttons[i] = META_BUTTON_FUNCTION_LAST;
new_layout.right_buttons_has_spacer[i] = FALSE;
g_strfreev (buttons); g_strfreev (buttons);
} }
@ -1516,13 +1549,27 @@ update_button_layout (const char *value)
for (i = 0; new_layout.left_buttons[i] != META_BUTTON_FUNCTION_LAST; i++); for (i = 0; new_layout.left_buttons[i] != META_BUTTON_FUNCTION_LAST; i++);
for (j = 0; j < i; j++) for (j = 0; j < i; j++)
rtl_layout.right_buttons[j] = new_layout.left_buttons[i - j - 1]; {
rtl_layout.right_buttons[j] = new_layout.left_buttons[i - j - 1];
if (j == 0)
rtl_layout.right_buttons_has_spacer[i - 1] = new_layout.left_buttons_has_spacer[i - j - 1];
else
rtl_layout.right_buttons_has_spacer[j - 1] = new_layout.left_buttons_has_spacer[i - j - 1];
}
rtl_layout.right_buttons[j] = META_BUTTON_FUNCTION_LAST; rtl_layout.right_buttons[j] = META_BUTTON_FUNCTION_LAST;
rtl_layout.right_buttons_has_spacer[j] = FALSE;
for (i = 0; new_layout.right_buttons[i] != META_BUTTON_FUNCTION_LAST; i++); for (i = 0; new_layout.right_buttons[i] != META_BUTTON_FUNCTION_LAST; i++);
for (j = 0; j < i; j++) for (j = 0; j < i; j++)
rtl_layout.left_buttons[j] = new_layout.right_buttons[i - j - 1]; {
rtl_layout.left_buttons[j] = new_layout.right_buttons[i - j - 1];
if (j == 0)
rtl_layout.left_buttons_has_spacer[i - 1] = new_layout.right_buttons_has_spacer[i - j - 1];
else
rtl_layout.left_buttons_has_spacer[j - 1] = new_layout.right_buttons_has_spacer[i - j - 1];
}
rtl_layout.left_buttons[j] = META_BUTTON_FUNCTION_LAST; rtl_layout.left_buttons[j] = META_BUTTON_FUNCTION_LAST;
rtl_layout.left_buttons_has_spacer[j] = FALSE;
new_layout = rtl_layout; new_layout = rtl_layout;
} }

View File

@ -263,9 +263,11 @@ struct _MetaButtonLayout
{ {
/* buttons in the group on the left side */ /* buttons in the group on the left side */
MetaButtonFunction left_buttons[MAX_BUTTONS_PER_CORNER]; MetaButtonFunction left_buttons[MAX_BUTTONS_PER_CORNER];
gboolean left_buttons_has_spacer[MAX_BUTTONS_PER_CORNER];
/* buttons in the group on the right side */ /* buttons in the group on the right side */
MetaButtonFunction right_buttons[MAX_BUTTONS_PER_CORNER]; MetaButtonFunction right_buttons[MAX_BUTTONS_PER_CORNER];
gboolean right_buttons_has_spacer[MAX_BUTTONS_PER_CORNER];
}; };
/* should investigate changing these to whatever most apps use */ /* should investigate changing these to whatever most apps use */

View File

@ -37,12 +37,14 @@
<long> <long>
Arrangement of buttons on the titlebar. The Arrangement of buttons on the titlebar. The
value should be a string, such as value should be a string, such as
"menu:minimize,maximize,close"; the colon separates the "menu:minimize,maximize,spacer,close"; the colon separates the
left corner of the window from the right corner, and left corner of the window from the right corner, and
the button names are comma-separated. Duplicate buttons the button names are comma-separated. Duplicate buttons
are not allowed. Unknown button names are silently ignored are not allowed. Unknown button names are silently ignored
so that buttons can be added in future metacity versions so that buttons can be added in future metacity versions
without breaking older versions. without breaking older versions.
A special spacer tag can be used to insert some space between
two adjacent buttons.
</long> </long>
</locale> </locale>
</schema> </schema>

View File

@ -592,7 +592,7 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout *layout,
MetaFrameGeometry *fgeom, MetaFrameGeometry *fgeom,
MetaTheme *theme) MetaTheme *theme)
{ {
int i, n_left, n_right; int i, n_left, n_right, n_left_spacers, n_right_spacers;
int x; int x;
int button_y; int button_y;
int title_right_edge; int title_right_edge;
@ -606,7 +606,9 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout *layout,
MetaButtonSpace *left_func_rects[MAX_BUTTONS_PER_CORNER]; MetaButtonSpace *left_func_rects[MAX_BUTTONS_PER_CORNER];
MetaButtonSpace *right_func_rects[MAX_BUTTONS_PER_CORNER]; MetaButtonSpace *right_func_rects[MAX_BUTTONS_PER_CORNER];
GdkRectangle *left_bg_rects[MAX_BUTTONS_PER_CORNER]; GdkRectangle *left_bg_rects[MAX_BUTTONS_PER_CORNER];
gboolean left_buttons_has_spacer[MAX_BUTTONS_PER_CORNER];
GdkRectangle *right_bg_rects[MAX_BUTTONS_PER_CORNER]; GdkRectangle *right_bg_rects[MAX_BUTTONS_PER_CORNER];
gboolean right_buttons_has_spacer[MAX_BUTTONS_PER_CORNER];
meta_frame_layout_get_borders (layout, text_height, meta_frame_layout_get_borders (layout, text_height,
flags, flags,
@ -659,6 +661,8 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout *layout,
n_left = 0; n_left = 0;
n_right = 0; n_right = 0;
n_left_spacers = 0;
n_right_spacers = 0;
if (!layout->hide_buttons) if (!layout->hide_buttons)
{ {
@ -669,7 +673,13 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout *layout,
button_layout->left_buttons[i], button_layout->left_buttons[i],
theme); theme);
if (left_func_rects[n_left] != NULL) if (left_func_rects[n_left] != NULL)
++n_left; {
left_buttons_has_spacer[n_left] = button_layout->left_buttons_has_spacer[i];
if (button_layout->left_buttons_has_spacer[i])
++n_left_spacers;
++n_left;
}
} }
for (i = 0; i < MAX_BUTTONS_PER_CORNER && button_layout->right_buttons[i] != META_BUTTON_FUNCTION_LAST; i++) for (i = 0; i < MAX_BUTTONS_PER_CORNER && button_layout->right_buttons[i] != META_BUTTON_FUNCTION_LAST; i++)
@ -678,7 +688,13 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout *layout,
button_layout->right_buttons[i], button_layout->right_buttons[i],
theme); theme);
if (right_func_rects[n_right] != NULL) if (right_func_rects[n_right] != NULL)
++n_right; {
right_buttons_has_spacer[n_right] = button_layout->right_buttons_has_spacer[i];
if (button_layout->right_buttons_has_spacer[i])
++n_right_spacers;
++n_right;
}
} }
} }
@ -720,16 +736,30 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout *layout,
space_used_by_buttons = 0; space_used_by_buttons = 0;
space_used_by_buttons += button_width * n_left; space_used_by_buttons += button_width * n_left;
space_used_by_buttons += (button_width * 0.75) * n_left_spacers;
space_used_by_buttons += layout->button_border.left * n_left; space_used_by_buttons += layout->button_border.left * n_left;
space_used_by_buttons += layout->button_border.right * n_left; space_used_by_buttons += layout->button_border.right * n_left;
space_used_by_buttons += button_width * n_right; space_used_by_buttons += button_width * n_right;
space_used_by_buttons += (button_width * 0.75) * n_right_spacers;
space_used_by_buttons += layout->button_border.left * n_right; space_used_by_buttons += layout->button_border.left * n_right;
space_used_by_buttons += layout->button_border.right * n_right; space_used_by_buttons += layout->button_border.right * n_right;
if (space_used_by_buttons <= space_available) if (space_used_by_buttons <= space_available)
break; /* Everything fits, bail out */ break; /* Everything fits, bail out */
/* First try to remove separators */
if (n_left_spacers > 0)
{
left_buttons_has_spacer[--n_left_spacers] = FALSE;
continue;
}
else if (n_right_spacers > 0)
{
right_buttons_has_spacer[--n_right_spacers] = FALSE;
continue;
}
/* Otherwise we need to shave out a button. Shave /* Otherwise we need to shave out a button. Shave
* above, stick, shade, min, max, close, then menu (menu is most useful); * above, stick, shade, min, max, close, then menu (menu is most useful);
* prefer the default button locations. * prefer the default button locations.
@ -799,8 +829,10 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout *layout,
break; break;
rect = right_func_rects[i]; rect = right_func_rects[i];
rect->visible.x = x - layout->button_border.right - button_width; rect->visible.x = x - layout->button_border.right - button_width;
if (right_buttons_has_spacer[i])
rect->visible.x -= (button_width * 0.75);
rect->visible.y = button_y; rect->visible.y = button_y;
rect->visible.width = button_width; rect->visible.width = button_width;
rect->visible.height = button_height; rect->visible.height = button_height;
@ -865,6 +897,8 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout *layout,
x = rect->visible.x + rect->visible.width + layout->button_border.right; x = rect->visible.x + rect->visible.width + layout->button_border.right;
if (left_buttons_has_spacer[i])
x += (button_width * 0.75);
*(left_bg_rects[i]) = rect->visible; *(left_bg_rects[i]) = rect->visible;
} }