diff --git a/src/st/st-scroll-view.c b/src/st/st-scroll-view.c index e452900d3..9ea394b05 100644 --- a/src/st/st-scroll-view.c +++ b/src/st/st-scroll-view.c @@ -101,6 +101,7 @@ struct _StScrollViewPrivate gboolean row_size_set : 1; gboolean column_size_set : 1; guint mouse_scroll : 1; + guint overlay_scrollbars : 1; guint hscrollbar_visible : 1; guint vscrollbar_visible : 1; }; @@ -115,6 +116,7 @@ enum { PROP_HSCROLLBAR_VISIBLE, PROP_VSCROLLBAR_VISIBLE, PROP_MOUSE_SCROLL, + PROP_OVERLAY_SCROLLBARS, }; static void @@ -148,6 +150,9 @@ st_scroll_view_get_property (GObject *object, case PROP_MOUSE_SCROLL: g_value_set_boolean (value, priv->mouse_scroll); break; + case PROP_OVERLAY_SCROLLBARS: + g_value_set_boolean (value, priv->overlay_scrollbars); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } @@ -212,6 +217,10 @@ st_scroll_view_set_property (GObject *object, st_scroll_view_set_mouse_scrolling (self, g_value_get_boolean (value)); break; + case PROP_OVERLAY_SCROLLBARS: + st_scroll_view_set_overlay_scrollbars (self, + g_value_get_boolean (value)); + break; case PROP_HSCROLLBAR_POLICY: st_scroll_view_set_policy (self, g_value_get_enum (value), @@ -376,14 +385,14 @@ st_scroll_view_get_preferred_width (ClutterActor *actor, account_for_vscrollbar = FALSE; break; case GTK_POLICY_ALWAYS: - account_for_vscrollbar = TRUE; + account_for_vscrollbar = !priv->overlay_scrollbars; break; case GTK_POLICY_AUTOMATIC: /* For automatic scrollbars, we always request space for the vertical * scrollbar; we won't know whether we actually need one until our * height is assigned in allocate(). */ - account_for_vscrollbar = TRUE; + account_for_vscrollbar = !priv->overlay_scrollbars; break; } @@ -448,14 +457,14 @@ st_scroll_view_get_preferred_height (ClutterActor *actor, account_for_hscrollbar = FALSE; break; case GTK_POLICY_ALWAYS: - account_for_hscrollbar = TRUE; + account_for_hscrollbar = !priv->overlay_scrollbars; break; case GTK_POLICY_AUTOMATIC: /* For automatic scrollbars, we always request space for the horizontal * scrollbar; we won't know whether we actually need one until our * width is assigned in allocate(). */ - account_for_hscrollbar = TRUE; + account_for_hscrollbar = !priv->overlay_scrollbars; break; } @@ -626,14 +635,15 @@ st_scroll_view_allocate (ClutterActor *actor, clutter_actor_allocate (priv->hscroll, &child_box, flags); } - /* In case the scrollbar policy is NEVER, we don't trim the content - * box allocation by the scrollbar size. + /* In case the scrollbar policy is NEVER or scrollbars should be + * overlayed, we don't trim the content box allocation by the + * scrollbar size. * Fold this into the scrollbar sizes to simplify the rest of the * computations. */ - if (priv->hscrollbar_policy == GTK_POLICY_NEVER) + if (priv->hscrollbar_policy == GTK_POLICY_NEVER || priv->overlay_scrollbars) sb_height = 0; - if (priv->vscrollbar_policy == GTK_POLICY_NEVER) + if (priv->vscrollbar_policy == GTK_POLICY_NEVER || priv->overlay_scrollbars) sb_width = 0; /* Child */ @@ -828,6 +838,14 @@ st_scroll_view_class_init (StScrollViewClass *klass) PROP_MOUSE_SCROLL, pspec); + pspec = g_param_spec_boolean ("overlay-scrollbars", + "Use Overlay Scrollbars", + "Overlay scrollbars over the content", + FALSE, + G_PARAM_READWRITE); + g_object_class_install_property (object_class, + PROP_OVERLAY_SCROLLBARS, + pspec); } static void @@ -1090,6 +1108,49 @@ st_scroll_view_get_mouse_scrolling (StScrollView *scroll) return priv->mouse_scroll; } +/** + * st_scroll_view_set_overlay_scrollbars: + * @scroll: A #StScrollView + * @enabled: Whether to enable overlay scrollbars + * + * Sets whether scrollbars are painted on top of the content. + */ +void +st_scroll_view_set_overlay_scrollbars (StScrollView *scroll, + gboolean enabled) +{ + StScrollViewPrivate *priv; + + g_return_if_fail (ST_IS_SCROLL_VIEW (scroll)); + + priv = ST_SCROLL_VIEW (scroll)->priv; + + if (priv->overlay_scrollbars != enabled) + { + priv->overlay_scrollbars = enabled; + g_object_notify (G_OBJECT (scroll), "overlay-scrollbars"); + clutter_actor_queue_relayout (CLUTTER_ACTOR (scroll)); + } +} + +/** + * st_scroll_view_get_overlay_scrollbars: + * @scroll: A #StScrollView + * + * Gets the value set by st_scroll_view_set_overlay_scrollbars(). + */ +gboolean +st_scroll_view_get_overlay_scrollbars (StScrollView *scroll) +{ + StScrollViewPrivate *priv; + + g_return_val_if_fail (ST_IS_SCROLL_VIEW (scroll), FALSE); + + priv = ST_SCROLL_VIEW (scroll)->priv; + + return priv->overlay_scrollbars; +} + /** * st_scroll_view_set_policy: * @scroll: A #StScrollView diff --git a/src/st/st-scroll-view.h b/src/st/st-scroll-view.h index c00d16e28..517e7dc21 100644 --- a/src/st/st-scroll-view.h +++ b/src/st/st-scroll-view.h @@ -80,6 +80,10 @@ void st_scroll_view_set_mouse_scrolling (StScrollView *scroll, gboolean enabled); gboolean st_scroll_view_get_mouse_scrolling (StScrollView *scroll); +void st_scroll_view_set_overlay_scrollbars (StScrollView *scroll, + gboolean enabled); +gboolean st_scroll_view_get_overlay_scrollbars (StScrollView *scroll); + void st_scroll_view_set_policy (StScrollView *scroll, GtkPolicyType hscroll, GtkPolicyType vscroll); diff --git a/tests/interactive/scroll-view-sizing.js b/tests/interactive/scroll-view-sizing.js index 967c9cdcc..26039d664 100644 --- a/tests/interactive/scroll-view-sizing.js +++ b/tests/interactive/scroll-view-sizing.js @@ -339,6 +339,10 @@ function test() { let vfade = new St.Button({ label: 'No', style: 'text-decoration: underline; color: #4444ff;' }); fadeBox.add(vfade); + fadeBox.add(new St.Label({ text: 'Overlay scrollbars: '})); + let overlay = new St.Button({ label: 'No', style: 'text-decoration: underline; color: #4444ff;' }); + fadeBox.add(overlay); + function togglePadding(button) { switch(button.label) { case 'No': @@ -388,6 +392,20 @@ function test() { vfade.connect('clicked', function() { toggleFade(vfade); }); toggleFade(vfade); + function toggleOverlay(button) { + switch(button.label) { + case 'No': + button.label = 'Yes'; + break; + case 'Yes': + button.label = 'No'; + break; + } + scrollView.overlay_scrollbars = (button.label == 'Yes'); + } + + overlay.connect('clicked', function() { toggleOverlay(overlay); }); + UI.main(stage); } test();