1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #ifndef _GTK_NSNATIVETHEMEGTK_H_
7 #define _GTK_NSNATIVETHEMEGTK_H_
8 
9 #include "nsITheme.h"
10 #include "nsCOMPtr.h"
11 #include "nsAtom.h"
12 #include "nsNativeTheme.h"
13 #include "nsStyleConsts.h"
14 #include "nsNativeBasicThemeGTK.h"
15 
16 #include <gtk/gtk.h>
17 #include "gtkdrawing.h"
18 
19 class nsNativeThemeGTK final : public nsNativeBasicThemeGTK {
20  public:
21   // The nsITheme interface.
22   NS_IMETHOD DrawWidgetBackground(gfxContext* aContext, nsIFrame* aFrame,
23                                   StyleAppearance aAppearance,
24                                   const nsRect& aRect, const nsRect& aDirtyRect,
25                                   DrawOverflow) override;
26 
27   bool CreateWebRenderCommandsForWidget(
28       mozilla::wr::DisplayListBuilder& aBuilder,
29       mozilla::wr::IpcResourceUpdateQueue& aResources,
30       const mozilla::layers::StackingContextHelper& aSc,
31       mozilla::layers::RenderRootStateManager* aManager, nsIFrame*,
32       StyleAppearance, const nsRect& aRect) override;
33 
34   [[nodiscard]] LayoutDeviceIntMargin GetWidgetBorder(
35       nsDeviceContext* aContext, nsIFrame* aFrame,
36       StyleAppearance aAppearance) override;
37 
38   bool GetWidgetPadding(nsDeviceContext* aContext, nsIFrame* aFrame,
39                         StyleAppearance aAppearance,
40                         LayoutDeviceIntMargin* aResult) override;
41 
42   bool GetWidgetOverflow(nsDeviceContext* aContext, nsIFrame* aFrame,
43                          StyleAppearance aAppearance,
44                          nsRect* aOverflowRect) override;
45 
46   static bool IsNonNativeWidgetType(StyleAppearance aAppearance);
47 
48   NS_IMETHOD GetMinimumWidgetSize(nsPresContext* aPresContext, nsIFrame* aFrame,
49                                   StyleAppearance aAppearance,
50                                   mozilla::LayoutDeviceIntSize* aResult,
51                                   bool* aIsOverridable) override;
52 
53   NS_IMETHOD WidgetStateChanged(nsIFrame* aFrame, StyleAppearance aAppearance,
54                                 nsAtom* aAttribute, bool* aShouldRepaint,
55                                 const nsAttrValue* aOldValue) override;
56 
57   NS_IMETHOD ThemeChanged() override;
58 
59   NS_IMETHOD_(bool)
60   ThemeSupportsWidget(nsPresContext* aPresContext, nsIFrame* aFrame,
61                       StyleAppearance aAppearance) override;
62 
63   NS_IMETHOD_(bool) WidgetIsContainer(StyleAppearance aAppearance) override;
64 
65   NS_IMETHOD_(bool)
66   ThemeDrawsFocusForWidget(StyleAppearance aAppearance) override;
67 
68   bool ThemeNeedsComboboxDropmarker() override;
69   Transparency GetWidgetTransparency(nsIFrame*, StyleAppearance) override;
70   ScrollbarSizes GetScrollbarSizes(nsPresContext*, StyleScrollbarWidth,
71                                    Overlay) override;
72 
73   bool ThemeSupportsScrollbarButtons() override;
74 
75   nsNativeThemeGTK();
76 
77  protected:
78   virtual ~nsNativeThemeGTK();
79 
80  private:
81   GtkTextDirection GetTextDirection(nsIFrame* aFrame);
82   gint GetTabMarginPixels(nsIFrame* aFrame);
83   bool GetGtkWidgetAndState(StyleAppearance aAppearance, nsIFrame* aFrame,
84                             WidgetNodeType& aGtkWidgetType,
85                             GtkWidgetState* aState, gint* aWidgetFlags);
86   bool GetExtraSizeForWidget(nsIFrame* aFrame, StyleAppearance aAppearance,
87                              nsIntMargin* aExtra);
88   bool IsWidgetVisible(StyleAppearance aAppearance);
89 
90   void RefreshWidgetWindow(nsIFrame* aFrame);
91   WidgetNodeType NativeThemeToGtkTheme(StyleAppearance aAppearance,
92                                        nsIFrame* aFrame);
93 
94   uint8_t mDisabledWidgetTypes
95       [(static_cast<size_t>(mozilla::StyleAppearance::Count) + 7) / 8];
96   uint8_t
97       mSafeWidgetStates[static_cast<size_t>(mozilla::StyleAppearance::Count) *
98                         4];  // 32 bits per widget
99   static const char* sDisabledEngines[];
100 
101   // Because moz_gtk_get_widget_border can be slow, we cache its results
102   // by widget type.  Each bit in mBorderCacheValid says whether the
103   // corresponding entry in mBorderCache is valid.
104   void GetCachedWidgetBorder(nsIFrame* aFrame, StyleAppearance aAppearance,
105                              GtkTextDirection aDirection,
106                              LayoutDeviceIntMargin* aResult);
107   uint8_t mBorderCacheValid[(MOZ_GTK_WIDGET_NODE_COUNT + 7) / 8];
108   LayoutDeviceIntMargin mBorderCache[MOZ_GTK_WIDGET_NODE_COUNT];
109 };
110 
111 #endif
112