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>
* src/core/compositor.h: removed unnecessary #include which

View File

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

View File

@ -263,9 +263,11 @@ struct _MetaButtonLayout
{
/* buttons in the group on the left side */
MetaButtonFunction left_buttons[MAX_BUTTONS_PER_CORNER];
gboolean left_buttons_has_spacer[MAX_BUTTONS_PER_CORNER];
/* buttons in the group on the right side */
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 */

View File

@ -37,12 +37,14 @@
<long>
Arrangement of buttons on the titlebar. The
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
the button names are comma-separated. Duplicate buttons
are not allowed. Unknown button names are silently ignored
so that buttons can be added in future metacity versions
without breaking older versions.
A special spacer tag can be used to insert some space between
two adjacent buttons.
</long>
</locale>
</schema>

View File

@ -592,7 +592,7 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout *layout,
MetaFrameGeometry *fgeom,
MetaTheme *theme)
{
int i, n_left, n_right;
int i, n_left, n_right, n_left_spacers, n_right_spacers;
int x;
int button_y;
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 *right_func_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];
gboolean right_buttons_has_spacer[MAX_BUTTONS_PER_CORNER];
meta_frame_layout_get_borders (layout, text_height,
flags,
@ -659,6 +661,8 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout *layout,
n_left = 0;
n_right = 0;
n_left_spacers = 0;
n_right_spacers = 0;
if (!layout->hide_buttons)
{
@ -669,7 +673,13 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout *layout,
button_layout->left_buttons[i],
theme);
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++)
@ -678,7 +688,13 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout *layout,
button_layout->right_buttons[i],
theme);
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 += 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.right * n_left;
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.right * n_right;
if (space_used_by_buttons <= space_available)
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
* above, stick, shade, min, max, close, then menu (menu is most useful);
* prefer the default button locations.
@ -799,8 +829,10 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout *layout,
break;
rect = right_func_rects[i];
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.width = button_width;
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;
if (left_buttons_has_spacer[i])
x += (button_width * 0.75);
*(left_bg_rects[i]) = rect->visible;
}