Source/WebCore/ChangeLog

 12016-04-26 Carlos Garcia Campos <cgarcia@igalia.com>
 2
 3 [GTK] Overlay scrollbars with steppers enabled render incorrectly
 4 https://bugs.webkit.org/show_bug.cgi?id=156988
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 Fix rendering of scrollbars when using GTK+ themes having stepper buttons.
 9
 10 * platform/gtk/RenderThemeGadget.cpp:
 11 (WebCore::RenderThemeBoxGadget::RenderThemeBoxGadget): Receive the box orientation as constructor parameter.
 12 (WebCore::RenderThemeBoxGadget::preferredSize): Fix the preferred size calculation taking into account the box orientation.
 13 (WebCore::RenderThemeScrollbarGadget::renderStepper): New method to render scrollbar steppers.
 14 * platform/gtk/RenderThemeGadget.h:
 15 (WebCore::RenderThemeGadget::context): Make this public instead of protected.
 16 * platform/gtk/ScrollAnimatorGtk.cpp:
 17 (WebCore::ScrollAnimatorGtk::updateOverlayScrollbarsOpacity): Invalidate the whole scrollbars instead of just
 18 the thumb when opacity changes, because themes can actually render the trough or even stepper buttons when in
 19 indicator mode too.
 20 * platform/gtk/ScrollbarThemeGtk.cpp:
 21 (WebCore::ScrollbarThemeGtk::hasButtons): Properly implement this method instead of returning true unconditionally.
 22 (WebCore::contentsGadgetForLayout): Pass orientation to RenderThemeBoxGadget constructor.
 23 (WebCore::ScrollbarThemeGtk::trackRect): Fix the calculation of the track rect taking stepper buttons into account.
 24 (WebCore::ScrollbarThemeGtk::backButtonRect): Fix the calculation of the stepper button rectangle.
 25 (WebCore::ScrollbarThemeGtk::forwardButtonRect): Ditto.
 26 (WebCore::ScrollbarThemeGtk::paint): Use RenderThemeScrollbarGadget::renderStepper() to render the stepper
 27 buttons, and fix the calculation of the steppers button rectangle.
 28 (WebCore::ScrollbarThemeGtk::handleMousePressEvent): Handle clicks on stepper buttons.
 29 (WebCore::ScrollbarThemeGtk::scrollbarThickness): Fix the calculation of the scrollbar thickness.
 30 (WebCore::ScrollbarThemeGtk::minimumThumbLength): Pass orientation to RenderThemeBoxGadget constructor.
 31 * platform/gtk/ScrollbarThemeGtk.h:
 32 * rendering/RenderThemeGtk.cpp:
 33 (WebCore::menuListColor): Ditto.
 34 (WebCore::RenderThemeGtk::popupInternalPaddingBox): Ditto.
 35 (WebCore::RenderThemeGtk::paintMenuList): Ditto.
 36
1372016-04-25 Ryosuke Niwa <rniwa@webkit.org>
238
339 Remove the build flag for template elements

Source/WebCore/platform/gtk/RenderThemeGadget.cpp

@@void RenderThemeGadget::renderFocus(cairo_t* cr, const FloatRect& focusRect)
199199 gtk_render_focus(m_context.get(), cr, rect.x(), rect.y(), rect.width(), rect.height());
200200}
201201
202 RenderThemeBoxGadget::RenderThemeBoxGadget(const RenderThemeGadget::Info& info, const Vector<RenderThemeGadget::Info> children, RenderThemeGadget* parent)
 202RenderThemeBoxGadget::RenderThemeBoxGadget(const RenderThemeGadget::Info& info, GtkOrientation orientation, const Vector<RenderThemeGadget::Info> children, RenderThemeGadget* parent)
203203 : RenderThemeGadget(info, parent, Vector<RenderThemeGadget::Info>(), 0)
 204 , m_orientation(orientation)
204205{
205206 m_children.reserveCapacity(children.size());
206207 unsigned index = 0;

@@RenderThemeBoxGadget::RenderThemeBoxGadget(const RenderThemeGadget::Info& info,
210211
211212IntSize RenderThemeBoxGadget::preferredSize() const
212213{
213  IntSize minSize = RenderThemeGadget::preferredSize();
214  for (const auto& child : m_children)
215  minSize += child->preferredSize();
216  return minSize;
 214 IntSize childrenSize;
 215 for (const auto& child : m_children) {
 216 IntSize childSize = child->preferredSize();
 217 switch (m_orientation) {
 218 case GTK_ORIENTATION_HORIZONTAL:
 219 childrenSize.setWidth(childrenSize.width() + childSize.width());
 220 childrenSize.setHeight(std::max(childrenSize.height(), childSize.height()));
 221 break;
 222 case GTK_ORIENTATION_VERTICAL:
 223 childrenSize.setWidth(std::max(childrenSize.width(), childSize.width()));
 224 childrenSize.setHeight(childrenSize.height() + childSize.height());
 225 break;
 226 }
 227 }
 228 return RenderThemeGadget::preferredSize().expandedTo(childrenSize);
217229}
218230
219231RenderThemeTextFieldGadget::RenderThemeTextFieldGadget(const RenderThemeGadget::Info& info, RenderThemeGadget* parent, const Vector<RenderThemeGadget::Info> siblings, unsigned position)

@@RenderThemeScrollbarGadget::RenderThemeScrollbarGadget(const RenderThemeGadget::
348360 m_steppers |= Steppers::SecondaryForward;
349361}
350362
 363void RenderThemeScrollbarGadget::renderStepper(cairo_t* cr, const FloatRect& paintRect, RenderThemeGadget* stepperGadget, GtkOrientation orientation, Steppers stepper)
 364{
 365 FloatRect contentsRect;
 366 stepperGadget->render(cr, paintRect, &contentsRect);
 367 double angle;
 368 switch (stepper) {
 369 case Steppers::Backward:
 370 case Steppers::SecondaryBackward:
 371 angle = orientation == GTK_ORIENTATION_VERTICAL ? 0 : 3 * (G_PI / 2);
 372 break;
 373 case Steppers::Forward:
 374 case Steppers::SecondaryForward:
 375 angle = orientation == GTK_ORIENTATION_VERTICAL ? G_PI / 2 : G_PI;
 376 break;
 377 }
 378
 379 int stepperSize = std::max(contentsRect.width(), contentsRect.height());
 380 gtk_render_arrow(stepperGadget->context(), cr, angle, contentsRect.x() + (contentsRect.width() - stepperSize) / 2,
 381 contentsRect.y() + (contentsRect.height() - stepperSize) / 2, stepperSize);
 382}
 383
351384} // namespace WebCore
352385
353386#endif // GTK_CHECK_VERSION(3, 20, 0)

Source/WebCore/platform/gtk/RenderThemeGadget.h

@@public:
7575 Color backgroundColor() const;
7676 double opacity() const;
7777
78 protected:
7978 GtkStyleContext* context() const { return m_context.get(); }
 79
 80protected:
8081 GtkBorder marginBox() const;
8182 GtkBorder borderBox() const;
8283 GtkBorder paddingBox() const;

@@protected:
8687
8788class RenderThemeBoxGadget final : public RenderThemeGadget {
8889public:
89  RenderThemeBoxGadget(const RenderThemeGadget::Info&, const Vector<RenderThemeGadget::Info> children, RenderThemeGadget* parent = nullptr);
 90 RenderThemeBoxGadget(const RenderThemeGadget::Info&, GtkOrientation, const Vector<RenderThemeGadget::Info> children, RenderThemeGadget* parent = nullptr);
9091
9192 IntSize preferredSize() const override;
9293

@@public:
9495
9596private:
9697 Vector<std::unique_ptr<RenderThemeGadget>> m_children;
 98 GtkOrientation m_orientation { GTK_ORIENTATION_HORIZONTAL };
9799};
98100
99101class RenderThemeTextFieldGadget final : public RenderThemeGadget {

@@public:
159161 };
160162 OptionSet<Steppers> steppers() const { return m_steppers; };
161163
 164 void renderStepper(cairo_t*, const FloatRect&, RenderThemeGadget*, GtkOrientation, Steppers);
 165
162166private:
163167 OptionSet<Steppers> m_steppers;
164168};

Source/WebCore/platform/gtk/ScrollAnimatorGtk.cpp

@@void ScrollAnimatorGtk::updateOverlayScrollbarsOpacity()
153153 if (m_verticalOverlayScrollbar && m_overlayScrollbarAnimationCurrent != m_verticalOverlayScrollbar->opacity()) {
154154 m_verticalOverlayScrollbar->setOpacity(m_overlayScrollbarAnimationCurrent);
155155 if (m_verticalOverlayScrollbar->hoveredPart() == NoPart)
156  ScrollbarTheme::theme().invalidatePart(*m_verticalOverlayScrollbar, ThumbPart);
 156 m_verticalOverlayScrollbar->invalidate();
157157 }
158158
159159 if (m_horizontalOverlayScrollbar && m_overlayScrollbarAnimationCurrent != m_horizontalOverlayScrollbar->opacity()) {
160160 m_horizontalOverlayScrollbar->setOpacity(m_overlayScrollbarAnimationCurrent);
161161 if (m_horizontalOverlayScrollbar->hoveredPart() == NoPart)
162  ScrollbarTheme::theme().invalidatePart(*m_horizontalOverlayScrollbar, ThumbPart);
 162 m_horizontalOverlayScrollbar->invalidate();
163163 }
164164}
165165

Source/WebCore/platform/gtk/ScrollbarThemeGtk.cpp

@@void ScrollbarThemeGtk::updateThemeProperties()
129129}
130130#endif // GTK_CHECK_VERSION(3, 20, 0)
131131
 132bool ScrollbarThemeGtk::hasButtons(Scrollbar& scrollbar)
 133{
 134 return scrollbar.enabled() && (m_hasBackButtonStartPart || m_hasForwardButtonEndPart || m_hasBackButtonEndPart || m_hasForwardButtonStartPart);
 135}
 136
132137#if GTK_CHECK_VERSION(3, 20, 0)
133138static GtkStateFlags scrollbarPartStateFlags(Scrollbar& scrollbar, ScrollbarPart part, bool painting = false)
134139{

@@static std::unique_ptr<RenderThemeGadget> scrollbarGadgetForLayout(Scrollbar& sc
185190 return RenderThemeGadget::create(info);
186191}
187192
188 static std::unique_ptr<RenderThemeBoxGadget> contentsGadgetForLayout(Scrollbar& scrollbar, RenderThemeGadget* parent, IntRect& contentsRect, Vector<int, 4> steppersPosition)
 193static std::unique_ptr<RenderThemeBoxGadget> contentsGadgetForLayout(Scrollbar& scrollbar, RenderThemeGadget* parent, IntRect& contentsRect, Vector<int, 4>& steppersPosition)
189194{
190195 Vector<RenderThemeGadget::Info> children;
191196 auto steppers = static_cast<RenderThemeScrollbarGadget*>(parent)->steppers();

@@static std::unique_ptr<RenderThemeBoxGadget> contentsGadgetForLayout(Scrollbar&
207212 children.append({ RenderThemeGadget::Type::Generic, "button", scrollbarPartStateFlags(scrollbar, ForwardButtonEndPart), { "down" } });
208213 }
209214 RenderThemeGadget::Info info = { RenderThemeGadget::Type::Generic, "contents", GTK_STATE_FLAG_NORMAL, { } };
210  auto contentsGadget = std::make_unique<RenderThemeBoxGadget>(info, children, parent);
 215 auto contentsGadget = std::make_unique<RenderThemeBoxGadget>(info, scrollbar.orientation() == VerticalScrollbar ? GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL,
 216 children, parent);
211217
212218 GtkBorder scrollbarContentsBox = parent->contentsBox();
213219 GtkBorder contentsContentsBox = contentsGadget->contentsBox();

@@IntRect ScrollbarThemeGtk::trackRect(Scrollbar& scrollbar, bool /*painting*/)
230236 auto contentsGadget = contentsGadgetForLayout(scrollbar, scrollbarGadget.get(), rect, steppersPosition);
231237
232238 if (steppersPosition[0] != -1) {
233  if (scrollbar.orientation() == VerticalScrollbar)
234  rect.move(0, contentsGadget->child(steppersPosition[0])->preferredSize().height());
235  else
236  rect.move(contentsGadget->child(steppersPosition[0])->preferredSize().width(), 0);
 239 IntSize stepperSize = contentsGadget->child(steppersPosition[0])->preferredSize();
 240 if (scrollbar.orientation() == VerticalScrollbar) {
 241 rect.move(0, stepperSize.height());
 242 rect.contract(0, stepperSize.height());
 243 } else {
 244 rect.move(stepperSize.width(), 0);
 245 rect.contract(stepperSize.width(), 0);
 246 }
237247 }
238248 if (steppersPosition[1] != -1) {
239  if (scrollbar.orientation() == VerticalScrollbar)
240  rect.move(0, contentsGadget->child(steppersPosition[1])->preferredSize().height());
241  else
242  rect.move(contentsGadget->child(steppersPosition[1])->preferredSize().width(), 0);
 249 IntSize stepperSize = contentsGadget->child(steppersPosition[1])->preferredSize();
 250 if (scrollbar.orientation() == VerticalScrollbar) {
 251 rect.move(0, stepperSize.height());
 252 rect.contract(0, stepperSize.height());
 253 } else {
 254 rect.move(stepperSize.width(), 0);
 255 rect.contract(stepperSize.width(), 0);
 256 }
243257 }
244258 if (steppersPosition[2] != -1) {
245259 if (scrollbar.orientation() == VerticalScrollbar)

@@IntRect ScrollbarThemeGtk::backButtonRect(Scrollbar& scrollbar, ScrollbarPart pa
327341
328342 // Secondary back.
329343 if (steppersPosition[1] != -1) {
330  if (scrollbar.orientation() == VerticalScrollbar)
331  rect.move(0, contentsGadget->child(steppersPosition[1])->preferredSize().height());
332  else
333  rect.move(contentsGadget->child(steppersPosition[1])->preferredSize().width(), 0);
 344 IntSize preferredSize = contentsGadget->child(steppersPosition[1])->preferredSize();
 345 if (scrollbar.orientation() == VerticalScrollbar) {
 346 rect.move(0, preferredSize.height());
 347 rect.contract(0, preferredSize.height());
 348 } else {
 349 rect.move(preferredSize.width(), 0);
 350 rect.contract(0, preferredSize.width());
 351 }
334352 }
335353
336  IntSize preferredSize = contentsGadget->child(steppersPosition[2])->preferredSize();
337  if (scrollbar.orientation() == VerticalScrollbar)
338  rect.contract(0, preferredSize.height());
339  else
340  rect.contract(preferredSize.width(), 0);
341 
342354 if (steppersPosition[3] != -1) {
343355 if (scrollbar.orientation() == VerticalScrollbar)
344356 rect.contract(0, contentsGadget->child(steppersPosition[3])->preferredSize().height());

@@IntRect ScrollbarThemeGtk::backButtonRect(Scrollbar& scrollbar, ScrollbarPart pa
346358 rect.contract(contentsGadget->child(steppersPosition[3])->preferredSize().width(), 0);
347359 }
348360
 361 IntSize preferredSize = contentsGadget->child(steppersPosition[2])->preferredSize();
349362 if (scrollbar.orientation() == VerticalScrollbar)
350  rect.move(0, rect.height());
 363 rect.move(0, rect.height() - preferredSize.height());
351364 else
352  rect.move(rect.width(), 0);
 365 rect.move(rect.width() - preferredSize.width(), 0);
353366
354367 return IntRect(rect.location(), preferredSize);
355368}

@@IntRect ScrollbarThemeGtk::forwardButtonRect(Scrollbar& scrollbar, ScrollbarPart
366379 auto contentsGadget = contentsGadgetForLayout(scrollbar, scrollbarGadget.get(), rect, steppersPosition);
367380
368381 if (steppersPosition[0] != -1) {
369  if (scrollbar.orientation() == VerticalScrollbar)
370  rect.move(0, contentsGadget->child(steppersPosition[0])->preferredSize().height());
371  else
372  rect.move(contentsGadget->child(steppersPosition[0])->preferredSize().width(), 0);
 382 IntSize preferredSize = contentsGadget->child(steppersPosition[0])->preferredSize();
 383 if (scrollbar.orientation() == VerticalScrollbar) {
 384 rect.move(0, preferredSize.height());
 385 rect.contract(0, preferredSize.height());
 386 } else {
 387 rect.move(preferredSize.width(), 0);
 388 rect.contract(preferredSize.width(), 0);
 389 }
373390 }
374391
375  if (part == ForwardButtonStartPart)
376  return IntRect(rect.location(), contentsGadget->child(1)->preferredSize());
 392 if (steppersPosition[1] != -1) {
 393 IntSize preferredSize = contentsGadget->child(steppersPosition[1])->preferredSize();
 394 if (part == ForwardButtonStartPart)
 395 return IntRect(rect.location(), preferredSize);
 396
 397 if (scrollbar.orientation() == VerticalScrollbar) {
 398 rect.move(0, preferredSize.height());
 399 rect.contract(0, preferredSize.height());
 400 } else {
 401 rect.move(preferredSize.width(), 0);
 402 rect.contract(preferredSize.width(), 0);
 403 }
 404 }
377405
378406 // Forward button.
379407 IntSize preferredSize = contentsGadget->child(steppersPosition[3])->preferredSize();

@@bool ScrollbarThemeGtk::paint(Scrollbar& scrollbar, GraphicsContext& graphicsCon
442470 if (graphicsContext.paintingDisabled())
443471 return false;
444472
 473 if (!scrollbar.enabled())
 474 return true;
 475
445476 double opacity = scrollbar.hoveredPart() == NoPart ? scrollbar.opacity() : 1;
446477 if (!opacity)
447478 return true;

@@bool ScrollbarThemeGtk::paint(Scrollbar& scrollbar, GraphicsContext& graphicsCon
495526 steppersPosition[3] = children.size();
496527 children.append({ RenderThemeGadget::Type::Generic, "button", scrollbarPartStateFlags(scrollbar, ForwardButtonEndPart), { "down" } });
497528 }
498  auto contentsGadget = std::make_unique<RenderThemeBoxGadget>(info, children, scrollbarGadget.get());
 529 auto contentsGadget = std::make_unique<RenderThemeBoxGadget>(info, scrollbar.orientation() == VerticalScrollbar ? GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL,
 530 children, scrollbarGadget.get());
499531 RenderThemeGadget* troughGadget = contentsGadget->child(troughPosition);
500532
501533 if (opacity != 1) {

@@bool ScrollbarThemeGtk::paint(Scrollbar& scrollbar, GraphicsContext& graphicsCon
507539 FloatRect contentsRect;
508540 scrollbarGadget->render(graphicsContext.platformContext()->cr(), rect, &contentsRect);
509541 contentsGadget->render(graphicsContext.platformContext()->cr(), contentsRect, &contentsRect);
510  troughGadget->render(graphicsContext.platformContext()->cr(), contentsRect, &contentsRect);
511  FloatRect buttonRect = contentsRect;
 542
512543 if (steppers.contains(RenderThemeScrollbarGadget::Steppers::Backward)) {
513544 RenderThemeGadget* buttonGadget = contentsGadget->child(steppersPosition[0]);
 545 FloatRect buttonRect = contentsRect;
514546 if (scrollbar.orientation() == VerticalScrollbar)
515547 buttonRect.setHeight(buttonGadget->preferredSize().height());
516548 else
517549 buttonRect.setWidth(buttonGadget->preferredSize().width());
518  buttonGadget->render(graphicsContext.platformContext()->cr(), buttonRect);
519  if (scrollbar.orientation() == VerticalScrollbar)
520  buttonRect.move(0, buttonRect.height());
521  else
522  buttonRect.move(buttonRect.width(), 0);
 550 static_cast<RenderThemeScrollbarGadget*>(scrollbarGadget.get())->renderStepper(graphicsContext.platformContext()->cr(), buttonRect, buttonGadget,
 551 scrollbar.orientation() == VerticalScrollbar ? GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL, RenderThemeScrollbarGadget::Steppers::Backward);
 552 if (scrollbar.orientation() == VerticalScrollbar) {
 553 contentsRect.move(0, buttonRect.height());
 554 contentsRect.contract(0, buttonRect.height());
 555 } else {
 556 contentsRect.move(buttonRect.width(), 0);
 557 contentsRect.contract(buttonRect.width(), 0);
 558 }
523559 }
524560 if (steppers.contains(RenderThemeScrollbarGadget::Steppers::SecondaryForward)) {
525561 RenderThemeGadget* buttonGadget = contentsGadget->child(steppersPosition[1]);
 562 FloatRect buttonRect = contentsRect;
526563 if (scrollbar.orientation() == VerticalScrollbar)
527564 buttonRect.setHeight(buttonGadget->preferredSize().height());
528565 else
529566 buttonRect.setWidth(buttonGadget->preferredSize().width());
530  buttonGadget->render(graphicsContext.platformContext()->cr(), buttonRect);
 567 static_cast<RenderThemeScrollbarGadget*>(scrollbarGadget.get())->renderStepper(graphicsContext.platformContext()->cr(), buttonRect, buttonGadget,
 568 scrollbar.orientation() == VerticalScrollbar ? GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL, RenderThemeScrollbarGadget::Steppers::SecondaryForward);
 569 if (scrollbar.orientation() == VerticalScrollbar) {
 570 contentsRect.move(0, buttonRect.height());
 571 contentsRect.contract(0, buttonRect.height());
 572 } else {
 573 contentsRect.move(buttonRect.width(), 0);
 574 contentsRect.contract(buttonRect.width(), 0);
 575 }
 576 }
 577
 578 if (steppers.contains(RenderThemeScrollbarGadget::Steppers::Forward)) {
 579 RenderThemeGadget* buttonGadget = contentsGadget->child(steppersPosition[3]);
 580 FloatRect buttonRect = contentsRect;
 581 if (scrollbar.orientation() == VerticalScrollbar) {
 582 buttonRect.setHeight(buttonGadget->preferredSize().height());
 583 buttonRect.move(0, contentsRect.height() - buttonRect.height());
 584 } else {
 585 buttonRect.setWidth(buttonGadget->preferredSize().width());
 586 buttonRect.move(contentsRect.width() - buttonRect.width(), 0);
 587 }
 588 static_cast<RenderThemeScrollbarGadget*>(scrollbarGadget.get())->renderStepper(graphicsContext.platformContext()->cr(), buttonRect, buttonGadget,
 589 scrollbar.orientation() == VerticalScrollbar ? GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL, RenderThemeScrollbarGadget::Steppers::Forward);
531590 if (scrollbar.orientation() == VerticalScrollbar)
532  buttonRect.move(0, contentsRect.height());
 591 contentsRect.contract(0, buttonRect.height());
533592 else
534  buttonRect.move(contentsRect.width(), 0);
 593 contentsRect.contract(buttonRect.width(), 0);
535594 }
536595 if (steppers.contains(RenderThemeScrollbarGadget::Steppers::SecondaryBackward)) {
537596 RenderThemeGadget* buttonGadget = contentsGadget->child(steppersPosition[2]);
538  if (scrollbar.orientation() == VerticalScrollbar)
 597 FloatRect buttonRect = contentsRect;
 598 if (scrollbar.orientation() == VerticalScrollbar) {
539599 buttonRect.setHeight(buttonGadget->preferredSize().height());
540  else
 600 buttonRect.move(0, contentsRect.height() - buttonRect.height());
 601 } else {
541602 buttonRect.setWidth(buttonGadget->preferredSize().width());
542  buttonGadget->render(graphicsContext.platformContext()->cr(), buttonRect);
543  if (scrollbar.orientation() == VerticalScrollbar)
544  buttonRect.move(0, buttonRect.height());
545  else
546  buttonRect.move(buttonRect.width(), 0);
547  }
548  if (steppers.contains(RenderThemeScrollbarGadget::Steppers::Forward)) {
549  RenderThemeGadget* buttonGadget = contentsGadget->child(steppersPosition[3]);
 603 buttonRect.move(contentsRect.width() - buttonRect.width(), 0);
 604 }
 605 static_cast<RenderThemeScrollbarGadget*>(scrollbarGadget.get())->renderStepper(graphicsContext.platformContext()->cr(), buttonRect, buttonGadget,
 606 scrollbar.orientation() == VerticalScrollbar ? GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL, RenderThemeScrollbarGadget::Steppers::SecondaryBackward);
550607 if (scrollbar.orientation() == VerticalScrollbar)
551  buttonRect.setHeight(buttonGadget->preferredSize().height());
 608 contentsRect.contract(0, buttonRect.height());
552609 else
553  buttonRect.setWidth(buttonGadget->preferredSize().width());
554  buttonGadget->render(graphicsContext.platformContext()->cr(), buttonRect);
 610 contentsRect.contract(buttonRect.width(), 0);
555611 }
 612
 613 troughGadget->render(graphicsContext.platformContext()->cr(), contentsRect, &contentsRect);
 614
556615 if (int thumbSize = thumbLength(scrollbar)) {
557616 info.name = "slider";
558617 info.state = scrollbarPartStateFlags(scrollbar, ThumbPart);

@@ScrollbarButtonPressAction ScrollbarThemeGtk::handleMousePressEvent(Scrollbar&,
758817 if (event.button() != RightButton)
759818 return ScrollbarButtonPressAction::StartDrag;
760819 break;
 820 case BackButtonStartPart:
 821 case ForwardButtonStartPart:
 822 case BackButtonEndPart:
 823 case ForwardButtonEndPart:
 824 return ScrollbarButtonPressAction::Scroll;
761825 default:
762826 break;
763827 }

@@int ScrollbarThemeGtk::scrollbarThickness(ScrollbarControlSize)
788852 children.append({ RenderThemeGadget::Type::Generic, "button", GTK_STATE_FLAG_NORMAL, { "up" } });
789853 if (steppers.contains(RenderThemeScrollbarGadget::Steppers::Forward))
790854 children.append({ RenderThemeGadget::Type::Generic, "button", GTK_STATE_FLAG_NORMAL, { "down" } });
791  auto contentsGadget = std::make_unique<RenderThemeBoxGadget>(info, children, scrollbarGadget.get());
 855 auto contentsGadget = std::make_unique<RenderThemeBoxGadget>(info, GTK_ORIENTATION_VERTICAL, children, scrollbarGadget.get());
792856 info.name = "slider";
793857 auto sliderGadget = RenderThemeGadget::create(info, contentsGadget->child(troughPositon));
794858 IntSize preferredSize = scrollbarGadget->preferredSize();
795  preferredSize += contentsGadget->preferredSize();
796  preferredSize += sliderGadget->preferredSize();
 859 IntSize contentsPreferredSize = contentsGadget->preferredSize();
 860 contentsPreferredSize = contentsPreferredSize.expandedTo(sliderGadget->preferredSize());
 861 preferredSize += contentsPreferredSize;
797862
798863 return preferredSize.width();
799864}

@@int ScrollbarThemeGtk::minimumThumbLength(Scrollbar& scrollbar)
818883 info.state = GTK_STATE_FLAG_NORMAL;
819884 info.classList.clear();
820885 Vector<RenderThemeGadget::Info> children = {{ RenderThemeGadget::Type::Generic, "trough", GTK_STATE_FLAG_PRELIGHT, { } } };
821  auto contentsGadget = std::make_unique<RenderThemeBoxGadget>(info, children, scrollbarGadget.get());
 886 auto contentsGadget = std::make_unique<RenderThemeBoxGadget>(info, GTK_ORIENTATION_VERTICAL, children, scrollbarGadget.get());
822887 info.name = "slider";
823888 IntSize minSize = RenderThemeGadget::create(info, contentsGadget->child(0))->minimumSize();
824889 return scrollbar.orientation() == VerticalScrollbar ? minSize.height() : minSize.width();

@@IntRect ScrollbarThemeGtk::trackRect(Scrollbar&, bool)
852917{
853918 return IntRect();
854919}
 920
 921bool ScrollbarThemeGtk::hasButtons(Scrollbar&)
 922{
 923 return false;
 924}
855925#endif // GTK_API_VERSION_2
856926
857927}

Source/WebCore/platform/gtk/ScrollbarThemeGtk.h

@@class ScrollbarThemeGtk final : public ScrollbarThemeComposite {
3737public:
3838 virtual ~ScrollbarThemeGtk();
3939
40  bool hasButtons(Scrollbar&) override { return true; }
 40 bool hasButtons(Scrollbar&) override;
4141 bool hasThumb(Scrollbar&) override;
4242 IntRect backButtonRect(Scrollbar&, ScrollbarPart, bool) override;
4343 IntRect forwardButtonRect(Scrollbar&, ScrollbarPart, bool) override;

Source/WebCore/rendering/RenderThemeGtk.cpp

@@static Color menuListColor(const Element* element)
783783 };
784784 info.name = "box";
785785 info.classList = { "horizontal", "linked" };
786  return RenderThemeBoxGadget(info, children, comboGadget.get()).child(0)->color();
 786 return RenderThemeBoxGadget(info, GTK_ORIENTATION_HORIZONTAL, children, comboGadget.get()).child(0)->color();
787787#else
788788 GRefPtr<GtkStyleContext> parentStyleContext = createStyleContext(ComboBox);
789789 GRefPtr<GtkStyleContext> buttonStyleContext = createStyleContext(ComboBoxButton, parentStyleContext.get());

@@LengthBox RenderThemeGtk::popupInternalPaddingBox(const RenderStyle& style) cons
835835 };
836836 info.name = "box";
837837 info.classList = { "horizontal", "linked" };
838  auto boxGadget = std::make_unique<RenderThemeBoxGadget>(info, children, comboGadget.get());
 838 auto boxGadget = std::make_unique<RenderThemeBoxGadget>(info, GTK_ORIENTATION_HORIZONTAL, children, comboGadget.get());
839839 RenderThemeGadget* buttonGadget = boxGadget->child(0);
840840 info.classList.removeLast();
841841 auto buttonBoxGadget = RenderThemeGadget::create(info, buttonGadget);

@@bool RenderThemeGtk::paintMenuList(const RenderObject& renderObject, const Paint
866866 };
867867 info.name = "box";
868868 info.classList = { "horizontal", "linked" };
869  auto boxGadget = std::make_unique<RenderThemeBoxGadget>(info, children, comboGadget.get());
 869 auto boxGadget = std::make_unique<RenderThemeBoxGadget>(info, GTK_ORIENTATION_HORIZONTAL, children, comboGadget.get());
870870 RenderThemeGadget* buttonGadget = boxGadget->child(0);
871871 info.classList.removeLast();
872872 auto buttonBoxGadget = RenderThemeGadget::create(info, buttonGadget);