/*
 * The following is assumed:
 *   (hadj && vadj) || (!hadj && !vadj)
 */
void ScrollView::setGtkAdjustments(GtkAdjustment* hadj, GtkAdjustment* vadj)
{
    ASSERT(!hadj == !vadj);

    if (m_horizontalAdjustment) {
        g_signal_handlers_disconnect_by_func(G_OBJECT(m_horizontalAdjustment), (gpointer)adjustmentChanged, this);
        g_signal_handlers_disconnect_by_func(G_OBJECT(m_verticalAdjustment), (gpointer)adjustmentChanged, this);
        g_object_unref(m_horizontalAdjustment);
        g_object_unref(m_verticalAdjustment);
    }

    m_horizontalAdjustment = hadj;
    m_verticalAdjustment = vadj;

    if (m_horizontalAdjustment) {
        g_signal_connect(m_horizontalAdjustment, "value-changed", G_CALLBACK(adjustmentChanged), this);
        g_signal_connect(m_verticalAdjustment, "value-changed", G_CALLBACK(adjustmentChanged), this);

        /*
         * disable the scrollbars (if we have any) as the GtkAdjustment over
         */
        setHasVerticalScrollbar(false);
        setHasHorizontalScrollbar(false);

        g_object_ref(m_horizontalAdjustment);
        g_object_ref(m_verticalAdjustment);
    }

    updateScrollbars(m_scrollOffset);
}
void RenderLayerScrollableArea::updateAfterStyleChange(const RenderStyle* oldStyle)
{
    if (!canHaveOverflowScrollbars(box()))
        return;

    if (!m_scrollDimensionsDirty)
        updateScrollableAreaSet(hasScrollableHorizontalOverflow() || hasScrollableVerticalOverflow());

    EOverflow overflowX = box().style()->overflowX();
    EOverflow overflowY = box().style()->overflowY();

    // To avoid doing a relayout in updateScrollbarsAfterLayout, we try to keep any automatic scrollbar that was already present.
    bool needsHorizontalScrollbar = (hasHorizontalScrollbar() && overflowDefinesAutomaticScrollbar(overflowX)) || overflowRequiresScrollbar(overflowX);
    bool needsVerticalScrollbar = (hasVerticalScrollbar() && overflowDefinesAutomaticScrollbar(overflowY)) || overflowRequiresScrollbar(overflowY);
    setHasHorizontalScrollbar(needsHorizontalScrollbar);
    setHasVerticalScrollbar(needsVerticalScrollbar);

    // With overflow: scroll, scrollbars are always visible but may be disabled.
    // When switching to another value, we need to re-enable them (see bug 11985).
    if (needsHorizontalScrollbar && oldStyle && oldStyle->overflowX() == OSCROLL && overflowX != OSCROLL) {
        ASSERT(hasHorizontalScrollbar());
        m_hBar->setEnabled(true);
    }

    if (needsVerticalScrollbar && oldStyle && oldStyle->overflowY() == OSCROLL && overflowY != OSCROLL) {
        ASSERT(hasVerticalScrollbar());
        m_vBar->setEnabled(true);
    }
}
Beispiel #3
0
/*
 * The following is assumed:
 *   (hadj && vadj) || (!hadj && !vadj)
 */
void ScrollView::setGtkAdjustments(GtkAdjustment* hadj, GtkAdjustment* vadj, bool resetValues)
{
    ASSERT(!hadj == !vadj);

    m_horizontalAdjustment = hadj;
    m_verticalAdjustment = vadj;

    // Reset the adjustments to a sane default
    if (m_horizontalAdjustment) {
        ScrollbarGtk* hScrollbar = reinterpret_cast<ScrollbarGtk*>(horizontalScrollbar());
        if (hScrollbar)
            hScrollbar->attachAdjustment(m_horizontalAdjustment);

        ScrollbarGtk* vScrollbar = reinterpret_cast<ScrollbarGtk*>(verticalScrollbar());
        if (vScrollbar)
            vScrollbar->attachAdjustment(m_verticalAdjustment);

        // We used to reset everything to 0 here, but when page cache
        // is enabled we reuse FrameViews that are cached. Since their
        // size is not going to change when being restored, (which is
        // what would cause the upper limit in the adjusments to be
        // set in the normal case), we make sure they are up-to-date
        // here. This is needed for the parent scrolling widget to be
        // able to report correct values.
        m_horizontalAdjustment->lower = 0;
        m_horizontalAdjustment->upper = resetValues ? 0 : frameRect().width();
        m_horizontalAdjustment->value = resetValues ? 0 : scrollOffset().width();
        gtk_adjustment_changed(m_horizontalAdjustment);
        gtk_adjustment_value_changed(m_horizontalAdjustment);

        m_verticalAdjustment->lower = 0;
        m_verticalAdjustment->upper = resetValues ? 0 : frameRect().height();
        m_verticalAdjustment->value = resetValues ? 0 : scrollOffset().height();
        gtk_adjustment_changed(m_verticalAdjustment);
        gtk_adjustment_value_changed(m_verticalAdjustment);
    } else {
        ScrollbarGtk* hScrollbar = reinterpret_cast<ScrollbarGtk*>(horizontalScrollbar());
        if (hScrollbar)
            hScrollbar->detachAdjustment();

        ScrollbarGtk* vScrollbar = reinterpret_cast<ScrollbarGtk*>(verticalScrollbar());
        if (vScrollbar)
            vScrollbar->detachAdjustment();
    }

    /* reconsider having a scrollbar */
    setHasVerticalScrollbar(false);
    setHasHorizontalScrollbar(false);
}
void ScrollView::setHorizontalAdjustment(GtkAdjustment* hadj, bool resetValues)
{
    ASSERT(!parent() || !hadj);
    if (parent())
        return;

    m_horizontalAdjustment = hadj;

    if (!m_horizontalAdjustment) {
        MainFrameScrollbarGtk* hScrollbar = reinterpret_cast<MainFrameScrollbarGtk*>(horizontalScrollbar());
        if (hScrollbar)
            hScrollbar->detachAdjustment();

        return;
    }

    // We may be lacking scrollbars when returning to a cached
    // page, this kicks the page to recreate the scrollbars.
    setHasHorizontalScrollbar(true);

    MainFrameScrollbarGtk* hScrollbar = reinterpret_cast<MainFrameScrollbarGtk*>(horizontalScrollbar());
    hScrollbar->attachAdjustment(m_horizontalAdjustment.get());

    // We used to reset everything to 0 here, but when page cache
    // is enabled we reuse FrameViews that are cached. Since their
    // size is not going to change when being restored, (which is
    // what would cause the upper limit in the adjusments to be
    // set in the normal case), we make sure they are up-to-date
    // here. This is needed for the parent scrolling widget to be
    // able to report correct values.
    int horizontalPageStep = max(max<int>(frameRect().width() * Scrollbar::minFractionToStepWhenPaging(), frameRect().width() - Scrollbar::maxOverlapBetweenPages()), 1);
    gtk_adjustment_configure(m_horizontalAdjustment.get(),
                             resetValues ? 0 : scrollOffset().width(), 0,
                             resetValues ? 0 : contentsSize().width(),
                             resetValues ? 0 : Scrollbar::pixelsPerLineStep(),
                             resetValues ? 0 : horizontalPageStep,
                             resetValues ? 0 : frameRect().width());
}
Beispiel #5
0
FramelessScrollView::~FramelessScrollView()
{
    // Remove native scrollbars now before we lose the connection to the HostWindow.
    setHasHorizontalScrollbar(false);
    setHasVerticalScrollbar(false);
}
void RenderLayerScrollableArea::updateAfterLayout()
{
    m_scrollDimensionsDirty = true;
    IntSize originalScrollOffset = adjustedScrollOffset();

    computeScrollDimensions();

    // Layout may cause us to be at an invalid scroll position. In this case we need
    // to pull our scroll offsets back to the max (or push them up to the min).
    IntSize clampedScrollOffset = clampScrollOffset(adjustedScrollOffset());
    if (clampedScrollOffset != adjustedScrollOffset())
        scrollToOffset(clampedScrollOffset);

    if (originalScrollOffset != adjustedScrollOffset())
        scrollToOffsetWithoutAnimation(-scrollOrigin() + adjustedScrollOffset());

    bool hasHorizontalOverflow = this->hasHorizontalOverflow();
    bool hasVerticalOverflow = this->hasVerticalOverflow();

    {
        // Hits in compositing/overflow/automatically-opt-into-composited-scrolling-after-style-change.html.
        DisableCompositingQueryAsserts disabler;

        // overflow:scroll should just enable/disable.
        if (box().style()->overflowX() == OSCROLL)
            horizontalScrollbar()->setEnabled(hasHorizontalOverflow);
        if (box().style()->overflowY() == OSCROLL)
            verticalScrollbar()->setEnabled(hasVerticalOverflow);
    }

    // overflow:auto may need to lay out again if scrollbars got added/removed.
    bool autoHorizontalScrollBarChanged = box().hasAutoHorizontalScrollbar() && (hasHorizontalScrollbar() != hasHorizontalOverflow);
    bool autoVerticalScrollBarChanged = box().hasAutoVerticalScrollbar() && (hasVerticalScrollbar() != hasVerticalOverflow);

    if (autoHorizontalScrollBarChanged || autoVerticalScrollBarChanged) {
        if (box().hasAutoHorizontalScrollbar())
            setHasHorizontalScrollbar(hasHorizontalOverflow);
        if (box().hasAutoVerticalScrollbar())
            setHasVerticalScrollbar(hasVerticalOverflow);

        layer()->updateSelfPaintingLayer();

        if (box().style()->overflowX() == OAUTO || box().style()->overflowY() == OAUTO) {
            if (!m_inOverflowRelayout) {
                // Our proprietary overflow: overlay value doesn't trigger a layout.
                m_inOverflowRelayout = true;
                SubtreeLayoutScope layoutScope(box());
                layoutScope.setNeedsLayout(&box());
                if (box().isRenderBlock()) {
                    RenderBlock& block = toRenderBlock(box());
                    block.scrollbarsChanged(autoHorizontalScrollBarChanged, autoVerticalScrollBarChanged);
                    block.layoutBlock(true);
                } else {
                    box().layout();
                }
                m_inOverflowRelayout = false;
            }
        }
    }

    {
        // Hits in compositing/overflow/automatically-opt-into-composited-scrolling-after-style-change.html.
        DisableCompositingQueryAsserts disabler;

        // Set up the range (and page step/line step).
        if (Scrollbar* horizontalScrollbar = this->horizontalScrollbar()) {
            int clientWidth = box().pixelSnappedClientWidth();
            horizontalScrollbar->setProportion(clientWidth, overflowRect().width());
        }
        if (Scrollbar* verticalScrollbar = this->verticalScrollbar()) {
            int clientHeight = box().pixelSnappedClientHeight();
            verticalScrollbar->setProportion(clientHeight, overflowRect().height());
        }
    }

    bool hasOverflow = hasScrollableHorizontalOverflow() || hasScrollableVerticalOverflow();
    updateScrollableAreaSet(hasOverflow);

    if (hasOverflow) {
        DisableCompositingQueryAsserts disabler;
        positionOverflowControls(IntSize());
    }
}
Beispiel #7
0
 ~ScrollViewPrivate()
 {
     setHasHorizontalScrollbar(false);
     setHasVerticalScrollbar(false);
 }