tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsSliderFrame.h (7666B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef nsSliderFrame_h__
      8 #define nsSliderFrame_h__
      9 
     10 #include "mozilla/Attributes.h"
     11 #include "nsAtom.h"
     12 #include "nsCOMPtr.h"
     13 #include "nsContainerFrame.h"
     14 #include "nsIDOMEventListener.h"
     15 #include "nsITimer.h"
     16 #include "nsRepeatService.h"
     17 
     18 class nsITimer;
     19 class nsScrollbarFrame;
     20 class nsSliderFrame;
     21 
     22 namespace mozilla {
     23 class nsDisplaySliderMarks;
     24 class PresShell;
     25 class ScrollContainerFrame;
     26 }  // namespace mozilla
     27 
     28 nsIFrame* NS_NewSliderFrame(mozilla::PresShell* aPresShell,
     29                            mozilla::ComputedStyle* aStyle);
     30 
     31 class nsSliderMediator final : public nsIDOMEventListener {
     32 public:
     33  NS_DECL_ISUPPORTS
     34 
     35  nsSliderFrame* mSlider;
     36 
     37  explicit nsSliderMediator(nsSliderFrame* aSlider) { mSlider = aSlider; }
     38 
     39  void SetSlider(nsSliderFrame* aSlider) { mSlider = aSlider; }
     40 
     41  NS_DECL_NSIDOMEVENTLISTENER
     42 
     43 protected:
     44  virtual ~nsSliderMediator() = default;
     45 };
     46 
     47 class nsSliderFrame final : public nsContainerFrame {
     48 public:
     49  NS_DECL_FRAMEARENA_HELPERS(nsSliderFrame)
     50  NS_DECL_QUERYFRAME
     51 
     52  friend class nsSliderMediator;
     53  friend class mozilla::nsDisplaySliderMarks;
     54 
     55  explicit nsSliderFrame(ComputedStyle* aStyle, nsPresContext* aPresContext);
     56  virtual ~nsSliderFrame();
     57 
     58  // Get the point associated with this event. Returns true if a single valid
     59  // point was found. Otherwise false.
     60  bool GetEventPoint(mozilla::WidgetGUIEvent* aEvent, nsPoint& aPoint);
     61  // Gets the event coordinates relative to the widget associated with this
     62  // frame. Return true if a single valid point was found.
     63  bool GetEventPoint(mozilla::WidgetGUIEvent* aEvent,
     64                     mozilla::LayoutDeviceIntPoint& aPoint);
     65 
     66 #ifdef DEBUG_FRAME_DUMP
     67  nsresult GetFrameName(nsAString& aResult) const override {
     68    return MakeFrameName(u"SliderFrame"_ns, aResult);
     69  }
     70 #endif
     71 
     72  void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize,
     73              const ReflowInput& aReflowInput,
     74              nsReflowStatus& aStatus) override;
     75 
     76  // nsIFrame overrides
     77  void Destroy(DestroyContext&) override;
     78 
     79  void BuildDisplayList(nsDisplayListBuilder* aBuilder,
     80                        const nsDisplayListSet& aLists) override;
     81 
     82  void BuildDisplayListForThumb(nsDisplayListBuilder* aBuilder,
     83                                nsIFrame* aThumb,
     84                                const nsDisplayListSet& aLists);
     85 
     86  void Init(nsIContent* aContent, nsContainerFrame* aParent,
     87            nsIFrame* aPrevInFlow) override;
     88 
     89  nsresult HandleEvent(nsPresContext* aPresContext,
     90                       mozilla::WidgetGUIEvent* aEvent,
     91                       nsEventStatus* aEventStatus) override;
     92 
     93  // nsContainerFrame overrides
     94  void SetInitialChildList(ChildListID aListID,
     95                           nsFrameList&& aChildList) override;
     96  void AppendFrames(ChildListID aListID, nsFrameList&& aFrameList) override;
     97  void InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame,
     98                    const nsLineList::iterator* aPrevFrameLine,
     99                    nsFrameList&& aFrameList) override;
    100  void RemoveFrame(DestroyContext&, ChildListID, nsIFrame*) override;
    101 
    102  nsresult StartDrag(mozilla::dom::Event* aEvent);
    103  nsresult StopDrag();
    104 
    105  void StartAPZDrag(mozilla::WidgetGUIEvent* aEvent);
    106 
    107  NS_IMETHOD HandlePress(nsPresContext* aPresContext,
    108                         mozilla::WidgetGUIEvent* aEvent,
    109                         nsEventStatus* aEventStatus) override;
    110 
    111  NS_IMETHOD HandleMultiplePress(nsPresContext* aPresContext,
    112                                 mozilla::WidgetGUIEvent* aEvent,
    113                                 nsEventStatus* aEventStatus,
    114                                 bool aControlHeld) override {
    115    return NS_OK;
    116  }
    117 
    118  MOZ_CAN_RUN_SCRIPT
    119  NS_IMETHOD HandleDrag(nsPresContext* aPresContext,
    120                        mozilla::WidgetGUIEvent* aEvent,
    121                        nsEventStatus* aEventStatus) override {
    122    return NS_OK;
    123  }
    124 
    125  NS_IMETHOD HandleRelease(nsPresContext* aPresContext,
    126                           mozilla::WidgetGUIEvent* aEvent,
    127                           nsEventStatus* aEventStatus) override;
    128 
    129  // Return the ratio the scrollbar thumb should move in proportion to the
    130  // scrolled frame.
    131  float GetThumbRatio() const;
    132 
    133  // Notify the slider frame that an async scrollbar drag was started on the
    134  // APZ side without consulting the main thread. The block id is the APZ
    135  // input block id of the mousedown that started the drag.
    136  void AsyncScrollbarDragInitiated(uint64_t aDragBlockId);
    137 
    138  // Notify the slider frame that an async scrollbar drag requested in
    139  // StartAPZDrag() was rejected by APZ, and the slider frame should
    140  // fall back to main-thread dragging.
    141  void AsyncScrollbarDragRejected();
    142 
    143  bool OnlySystemGroupDispatch(mozilla::EventMessage aMessage) const override;
    144 
    145  // Returns the associated scroll container frame that contains this slider if
    146  // any.
    147  mozilla::ScrollContainerFrame* GetScrollContainerFrame();
    148  void CurrentPositionChanged();
    149 
    150 private:
    151  bool GetScrollToClick();
    152  nsScrollbarFrame* Scrollbar() const;
    153  bool ShouldScrollForEvent(mozilla::WidgetGUIEvent* aEvent);
    154  bool ShouldScrollToClickForEvent(mozilla::WidgetGUIEvent* aEvent);
    155  bool IsEventOverThumb(mozilla::WidgetGUIEvent* aEvent);
    156 
    157  void SetCurrentThumbPosition(nscoord aNewPos);
    158 
    159  void DragThumb(bool aGrabMouseEvents);
    160  void AddListener();
    161  void RemoveListener();
    162  bool IsDraggingThumb() const;
    163 
    164  void SuppressDisplayport();
    165  void UnsuppressDisplayport();
    166 
    167  void StartRepeat() {
    168    nsRepeatService::GetInstance()->Start(Notify, this, mContent->OwnerDoc(),
    169                                          "nsSliderFrame"_ns);
    170  }
    171  void StopRepeat() {
    172    nsRepeatService::GetInstance()->Stop(Notify, this);
    173    mCurrentClickHoldDestination = Nothing();
    174  }
    175  void Notify();
    176  static void Notify(void* aData) {
    177    (static_cast<nsSliderFrame*>(aData))->Notify();
    178  }
    179  void PageScroll(bool aClickAndHold);
    180 
    181  void SetupDrag(mozilla::WidgetGUIEvent* aEvent, nsIFrame* aThumbFrame,
    182                 nscoord aPos, bool aIsHorizontal);
    183 
    184  nsPoint mDestinationPoint;
    185  // If we are in a scrollbar track click-and-hold, this is populated with
    186  // the destination of the scroll started at the most recent tick of the
    187  // repeat timer.
    188  Maybe<nsPoint> mCurrentClickHoldDestination;
    189  RefPtr<nsSliderMediator> mMediator;
    190 
    191  float mRatio;
    192 
    193  nscoord mDragStart;
    194  nscoord mThumbStart;
    195  nscoord mRepeatDirection;
    196 
    197  bool mDragInProgress = false;
    198 
    199  // true if we've handed off the scrolling to APZ. This means that we should
    200  // ignore scrolling events as the position will be updated by APZ. If we were
    201  // to process these events then the scroll position update would conflict
    202  // causing the scroll position to jump.
    203  bool mScrollingWithAPZ;
    204 
    205  // true if displayport suppression is active, for more performant
    206  // scrollbar-dragging behaviour.
    207  bool mSuppressionActive;
    208 
    209  // If APZ initiated a scrollbar drag without main-thread involvement, it
    210  // notifies us and this variable stores the input block id of the APZ input
    211  // block that started the drag. This lets us handle the corresponding
    212  // mousedown event properly, if it arrives after the scroll position has
    213  // been shifted due to async scrollbar drag.
    214  Maybe<uint64_t> mAPZDragInitiated;
    215 
    216  nscoord mThumbMinLength;
    217 
    218  static bool gMiddlePref;
    219 };  // class nsSliderFrame
    220 
    221 #endif