/* * 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); } }
/* * 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()); }
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()); } }
~ScrollViewPrivate() { setHasHorizontalScrollbar(false); setHasVerticalScrollbar(false); }