diff --git a/src/ui/frames.c b/src/ui/frames.c index b98744b26..e1216239b 100644 --- a/src/ui/frames.c +++ b/src/ui/frames.c @@ -2398,20 +2398,6 @@ meta_frames_paint (MetaFrames *frames, default: break; } - - /* Map button function states to button position states */ - button_states[META_BUTTON_TYPE_LEFT_LEFT_BACKGROUND] = - button_states[META_BUTTON_TYPE_MENU]; - button_states[META_BUTTON_TYPE_LEFT_MIDDLE_BACKGROUND] = - META_BUTTON_STATE_NORMAL; - button_states[META_BUTTON_TYPE_LEFT_RIGHT_BACKGROUND] = - META_BUTTON_STATE_NORMAL; - button_states[META_BUTTON_TYPE_RIGHT_LEFT_BACKGROUND] = - button_states[META_BUTTON_TYPE_MINIMIZE]; - button_states[META_BUTTON_TYPE_RIGHT_MIDDLE_BACKGROUND] = - button_states[META_BUTTON_TYPE_MAXIMIZE]; - button_states[META_BUTTON_TYPE_RIGHT_RIGHT_BACKGROUND] = - button_states[META_BUTTON_TYPE_CLOSE]; meta_core_get (display, frame->xwindow, META_CORE_GET_FRAME_FLAGS, &flags, diff --git a/src/ui/theme-private.h b/src/ui/theme-private.h index ba5f64d09..b7f05c963 100644 --- a/src/ui/theme-private.h +++ b/src/ui/theme-private.h @@ -256,6 +256,11 @@ struct _MetaFrameGeometry GdkRectangle right_middle_backgrounds[MAX_MIDDLE_BACKGROUNDS]; GdkRectangle right_right_background; /* End of button rects (if changed adjust memset hack) */ + + /* Saved button layout */ + MetaButtonLayout button_layout; + int n_left_buttons; + int n_right_buttons; /* Round corners */ guint top_left_corner_rounded_radius; diff --git a/src/ui/theme.c b/src/ui/theme.c index 1de6b6282..f688b9589 100644 --- a/src/ui/theme.c +++ b/src/ui/theme.c @@ -452,6 +452,38 @@ meta_frame_layout_get_borders (const MetaFrameLayout *layout, } } +static MetaButtonType +map_button_function_to_type (MetaButtonFunction function) +{ + switch (function) + { + case META_BUTTON_FUNCTION_SHADE: + return META_BUTTON_TYPE_SHADE; + case META_BUTTON_FUNCTION_ABOVE: + return META_BUTTON_TYPE_ABOVE; + case META_BUTTON_FUNCTION_STICK: + return META_BUTTON_TYPE_STICK; + case META_BUTTON_FUNCTION_UNSHADE: + return META_BUTTON_TYPE_UNSHADE; + case META_BUTTON_FUNCTION_UNABOVE: + return META_BUTTON_TYPE_UNABOVE; + case META_BUTTON_FUNCTION_UNSTICK: + return META_BUTTON_TYPE_UNSTICK; + case META_BUTTON_FUNCTION_MENU: + return META_BUTTON_TYPE_MENU; + case META_BUTTON_FUNCTION_MINIMIZE: + return META_BUTTON_TYPE_MINIMIZE; + case META_BUTTON_FUNCTION_MAXIMIZE: + return META_BUTTON_TYPE_MAXIMIZE; + case META_BUTTON_FUNCTION_CLOSE: + return META_BUTTON_TYPE_CLOSE; + case META_BUTTON_FUNCTION_LAST: + return META_BUTTON_TYPE_LAST; + } + + return META_BUTTON_TYPE_LAST; +} + static MetaButtonSpace* rect_for_function (MetaFrameGeometry *fgeom, MetaFrameFlags flags, @@ -808,6 +840,11 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout *layout, n_left, n_right); } } + + /* Save the button layout */ + fgeom->button_layout = *button_layout; + fgeom->n_left_buttons = n_left; + fgeom->n_right_buttons = n_right; /* center buttons vertically */ button_y = (fgeom->top_height - @@ -4198,6 +4235,64 @@ meta_frame_style_unref (MetaFrameStyle *style) } } +static MetaButtonState +map_button_state (MetaButtonType button_type, + const MetaFrameGeometry *fgeom, + int middle_bg_offset, + MetaButtonState button_states[META_BUTTON_TYPE_LAST]) +{ + MetaButtonFunction function = META_BUTTON_FUNCTION_LAST; + + switch (button_type) + { + /* First hande functions, which map directly */ + case META_BUTTON_TYPE_SHADE: + case META_BUTTON_TYPE_ABOVE: + case META_BUTTON_TYPE_STICK: + case META_BUTTON_TYPE_UNSHADE: + case META_BUTTON_TYPE_UNABOVE: + case META_BUTTON_TYPE_UNSTICK: + case META_BUTTON_TYPE_MENU: + case META_BUTTON_TYPE_MINIMIZE: + case META_BUTTON_TYPE_MAXIMIZE: + case META_BUTTON_TYPE_CLOSE: + return button_states[button_type]; + + /* Map position buttons to the corresponding function */ + case META_BUTTON_TYPE_RIGHT_LEFT_BACKGROUND: + if (fgeom->n_right_buttons > 0) + function = fgeom->button_layout.right_buttons[0]; + break; + case META_BUTTON_TYPE_RIGHT_RIGHT_BACKGROUND: + if (fgeom->n_right_buttons > 0) + function = fgeom->button_layout.right_buttons[fgeom->n_right_buttons - 1]; + break; + case META_BUTTON_TYPE_RIGHT_MIDDLE_BACKGROUND: + if (middle_bg_offset + 1 < fgeom->n_right_buttons) + function = fgeom->button_layout.right_buttons[middle_bg_offset + 1]; + break; + case META_BUTTON_TYPE_LEFT_LEFT_BACKGROUND: + if (fgeom->n_left_buttons > 0) + function = fgeom->button_layout.left_buttons[0]; + break; + case META_BUTTON_TYPE_LEFT_RIGHT_BACKGROUND: + if (fgeom->n_left_buttons > 0) + function = fgeom->button_layout.left_buttons[fgeom->n_left_buttons - 1]; + break; + case META_BUTTON_TYPE_LEFT_MIDDLE_BACKGROUND: + if (middle_bg_offset + 1 < fgeom->n_left_buttons) + function = fgeom->button_layout.left_buttons[middle_bg_offset + 1]; + break; + case META_BUTTON_TYPE_LAST: + break; + } + + if (function != META_BUTTON_FUNCTION_LAST) + return button_states[map_button_function_to_type (function)]; + + return META_BUTTON_STATE_LAST; +} + static MetaDrawOpList* get_button (MetaFrameStyle *style, MetaButtonType type, @@ -4540,9 +4635,13 @@ meta_frame_style_draw_with_style (MetaFrameStyle *style, j = 0; while (j < META_BUTTON_TYPE_LAST) { + MetaButtonState button_state; + button_rect (j, fgeom, middle_bg_offset, &rect); - op_list = get_button (style, j, button_states[j]); + button_state = map_button_state (j, fgeom, middle_bg_offset, button_states); + + op_list = get_button (style, j, button_state); if (op_list) {