From e021e06178627cb2cb05c8937c14f69b6e1fa614 Mon Sep 17 00:00:00 2001 From: Andrea Del Signore Date: Fri, 29 Feb 2008 20:41:07 +0000 Subject: [PATCH] Add support for "spacer" as a button type which adds some empty space. 2008-02-29 Andrea Del Signore 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 --- ChangeLog | 10 +++++ src/core/prefs.c | 91 +++++++++++++++++++++++++++++++---------- src/include/common.h | 4 +- src/metacity.schemas.in | 4 +- src/ui/theme.c | 42 +++++++++++++++++-- 5 files changed, 123 insertions(+), 28 deletions(-) diff --git a/ChangeLog b/ChangeLog index bcfc20e8e..8eb37151b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2008-02-29 Andrea Del Signore + + 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 * src/core/compositor.h: removed unnecessary #include which diff --git a/src/core/prefs.c b/src/core/prefs.c index a407321d5..5f5a3e4c8 100644 --- a/src/core/prefs.c +++ b/src/core/prefs.c @@ -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; } diff --git a/src/include/common.h b/src/include/common.h index 8bdce9d37..41ec797f1 100644 --- a/src/include/common.h +++ b/src/include/common.h @@ -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 */ diff --git a/src/metacity.schemas.in b/src/metacity.schemas.in index dd87b1025..4c2416d74 100644 --- a/src/metacity.schemas.in +++ b/src/metacity.schemas.in @@ -37,12 +37,14 @@ 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. diff --git a/src/ui/theme.c b/src/ui/theme.c index 57375a04d..485572123 100644 --- a/src/ui/theme.c +++ b/src/ui/theme.c @@ -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; }