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/. */
7 /* rendering objects for replaced elements implemented by a plugin */
9 #ifndef nsPluginFrame_h___
10 #define nsPluginFrame_h___
12 #include "mozilla/Attributes.h"
13 #include "mozilla/EventForwards.h"
14 #include "mozilla/UniquePtr.h"
15 #include "nsIObjectFrame.h"
18 #include "nsDisplayList.h"
19 #include "nsIReflowCallback.h"
21 #include "mozilla/layers/StackingContextHelper.h"
22 #include "mozilla/webrender/WebRenderAPI.h"
25 # include <windows.h> // For HWND :(
26 // Undo the windows.h damage
31 # undef RemoveDirectory
38 class nsRootPresContext
;
39 class nsDisplayPlugin
;
40 class PluginBackgroundSink
;
41 class nsPluginInstanceOwner
;
50 } // namespace mozilla
52 class PluginFrameDidCompositeObserver
;
54 class nsPluginFrame final
: public nsFrame
,
55 public nsIObjectFrame
,
56 public nsIReflowCallback
{
58 typedef mozilla::LayerState LayerState
;
59 typedef mozilla::LayoutDeviceIntPoint LayoutDeviceIntPoint
;
60 typedef mozilla::LayoutDeviceIntRect LayoutDeviceIntRect
;
61 typedef mozilla::LayoutDeviceIntRegion LayoutDeviceIntRegion
;
62 typedef mozilla::layers::Layer Layer
;
63 typedef mozilla::layers::LayerManager LayerManager
;
64 typedef mozilla::layers::ImageContainer ImageContainer
;
65 typedef mozilla::layers::StackingContextHelper StackingContextHelper
;
66 typedef mozilla::layers::RenderRootStateManager RenderRootStateManager
;
67 typedef mozilla::layers::WebRenderParentCommand WebRenderParentCommand
;
68 typedef mozilla::ContainerLayerParameters ContainerLayerParameters
;
70 NS_DECL_FRAMEARENA_HELPERS(nsPluginFrame
)
73 friend nsIFrame
* NS_NewObjectFrame(mozilla::PresShell
* aPresShell
,
74 ComputedStyle
* aStyle
);
76 virtual void Init(nsIContent
* aContent
, nsContainerFrame
* aParent
,
77 nsIFrame
* aPrevInFlow
) override
;
78 virtual nscoord
GetMinISize(gfxContext
* aRenderingContext
) override
;
79 virtual nscoord
GetPrefISize(gfxContext
* aRenderingContext
) override
;
80 virtual void Reflow(nsPresContext
* aPresContext
, ReflowOutput
& aDesiredSize
,
81 const ReflowInput
& aReflowInput
,
82 nsReflowStatus
& aStatus
) override
;
83 virtual void DidReflow(nsPresContext
* aPresContext
,
84 const ReflowInput
* aReflowInput
) override
;
85 virtual void BuildDisplayList(nsDisplayListBuilder
* aBuilder
,
86 const nsDisplayListSet
& aLists
) override
;
88 virtual nsresult
HandleEvent(nsPresContext
* aPresContext
,
89 mozilla::WidgetGUIEvent
* aEvent
,
90 nsEventStatus
* aEventStatus
) override
;
92 virtual bool IsFrameOfType(uint32_t aFlags
) const override
{
93 return nsFrame::IsFrameOfType(
94 aFlags
& ~(nsIFrame::eReplaced
| nsIFrame::eReplacedSizing
));
97 #ifdef DEBUG_FRAME_DUMP
98 virtual nsresult
GetFrameName(nsAString
& aResult
) const override
;
101 virtual void DestroyFrom(nsIFrame
* aDestructRoot
,
102 PostDestroyData
& aPostDestroyData
) override
;
104 virtual void DidSetComputedStyle(ComputedStyle
* aOldComputedStyle
) override
;
106 nsNPAPIPluginInstance
* GetPluginInstance() override
;
108 virtual void SetIsDocumentActive(bool aIsActive
) override
;
110 mozilla::Maybe
<Cursor
> GetCursor(const nsPoint
&) override
;
112 // APIs used by nsRootPresContext to set up the widget position/size/clip
115 * Set the next widget configuration for the plugin to the desired
116 * position of the plugin's widget, on the assumption that it is not visible
117 * (clipped out or covered by opaque content).
118 * This will only be called for plugins which have been registered
119 * with the root pres context for geometry updates.
120 * If there is no widget associated with the plugin, this will have no effect.
122 void SetEmptyWidgetConfiguration() {
123 mNextConfigurationBounds
= LayoutDeviceIntRect(0, 0, 0, 0);
124 mNextConfigurationClipRegion
.Clear();
127 * Append the desired widget configuration to aConfigurations.
129 void GetWidgetConfiguration(
130 nsTArray
<nsIWidget::Configuration
>* aConfigurations
);
132 LayoutDeviceIntRect
GetWidgetlessClipRect() {
133 return RegionFromArray(mNextConfigurationClipRegion
).GetBounds();
137 * Called after all widget position/size/clip regions have been changed
138 * (even if there isn't a widget for this plugin).
140 void DidSetWidgetGeometry();
142 // accessibility support
144 virtual mozilla::a11y::AccType
AccessibleType() override
;
146 NS_IMETHOD
GetPluginPort(HWND
* aPort
);
151 nsresult
PrepForDrawing(nsIWidget
* aWidget
);
153 // for a given aRoot, this walks the frame tree looking for the next outFrame
154 static nsIObjectFrame
* GetNextObjectFrame(nsPresContext
* aPresContext
,
158 virtual bool ReflowFinished() override
;
159 virtual void ReflowCallbackCanceled() override
;
162 * Builds either an ImageLayer or a ReadbackLayer, depending on the type
163 * of aItem (TYPE_PLUGIN or TYPE_PLUGIN_READBACK respectively).
165 already_AddRefed
<Layer
> BuildLayer(
166 nsDisplayListBuilder
* aBuilder
, LayerManager
* aManager
,
167 nsDisplayItem
* aItem
,
168 const ContainerLayerParameters
& aContainerParameters
);
170 LayerState
GetLayerState(nsDisplayListBuilder
* aBuilder
,
171 LayerManager
* aManager
);
174 * Get the rectangle (relative to this frame) which it will paint. Normally
175 * the frame's content-box but may be smaller if the plugin is rendering
176 * asynchronously and has a different-sized image temporarily.
178 nsRect
GetPaintedRect(const nsDisplayPlugin
* aItem
) const;
181 * If aSupports has a nsPluginFrame, then prepare it for a DocShell swap.
182 * @see nsSubDocumentFrame::BeginSwapDocShells.
183 * There will be a call to EndSwapDocShells after we were moved to the
186 static void BeginSwapDocShells(nsISupports
* aSupports
, void*);
188 * If aSupports has a nsPluginFrame, then set it up after a DocShell swap.
189 * @see nsSubDocumentFrame::EndSwapDocShells.
191 static void EndSwapDocShells(nsISupports
* aSupports
, void*);
193 nsIWidget
* GetWidget() override
{
201 * Adjust the plugin's idea of its size, using aSize as its new size.
202 * (aSize must be in twips)
204 void FixupWindow(const nsSize
& aSize
);
207 * Sets up the plugin window and calls SetWindow on the plugin.
209 nsresult
CallSetWindow(bool aCheckIsHidden
= true);
211 void SetInstanceOwner(nsPluginInstanceOwner
* aOwner
);
214 * HandleWheelEventAsDefaultAction() handles eWheel event as default action.
215 * This should be called only when WantsToHandleWheelEventAsDefaultAction()
218 void HandleWheelEventAsDefaultAction(mozilla::WidgetWheelEvent
* aEvent
);
221 * WantsToHandleWheelEventAsDefaultAction() returns true if the plugin
222 * may want to handle wheel events as default action.
224 bool WantsToHandleWheelEventAsDefaultAction() const;
226 bool CreateWebRenderCommands(
227 nsDisplayItem
* aItem
, mozilla::wr::DisplayListBuilder
& aBuilder
,
228 mozilla::wr::IpcResourceUpdateQueue
& aResources
,
229 const StackingContextHelper
& aSc
,
230 mozilla::layers::RenderRootStateManager
* aManager
,
231 nsDisplayListBuilder
* aDisplayListBuilder
);
234 explicit nsPluginFrame(ComputedStyle
* aStyle
, nsPresContext
* aPresContext
);
235 virtual ~nsPluginFrame();
237 // NOTE: This frame class does not inherit from |nsLeafFrame|, so
238 // this is not a virtual method implementation.
239 void GetDesiredSize(nsPresContext
* aPresContext
,
240 const ReflowInput
& aReflowInput
,
241 ReflowOutput
& aDesiredSize
);
243 bool IsFocusable(int32_t* aTabIndex
= nullptr,
244 bool aWithMouse
= false) override
;
246 // check attributes and optionally CSS to see if we should display anything
247 bool IsHidden(bool aCheckVisibilityStyle
= true) const;
249 bool IsOpaque() const;
250 bool IsTransparentMode() const;
251 bool IsPaintedByGecko() const;
253 nsIntPoint
GetWindowOriginInPixels(bool aWindowless
);
256 * If this frame is in a remote tab, return the tab offset to
257 * the origin of the chrome window. In non-e10s, this return 0,0.
258 * This api sends a sync ipc request so be careful about use.
260 LayoutDeviceIntPoint
GetRemoteTabChromeOffset();
262 static void PaintPrintPlugin(nsIFrame
* aFrame
, gfxContext
* aRenderingContext
,
263 const nsRect
& aDirtyRect
, nsPoint aPt
);
264 void PrintPlugin(gfxContext
& aRenderingContext
, const nsRect
& aDirtyRect
);
265 void PaintPlugin(nsDisplayListBuilder
* aBuilder
,
266 gfxContext
& aRenderingContext
, const nsRect
& aDirtyRect
,
267 const nsRect
& aPluginRect
);
269 void NotifyPluginReflowObservers();
271 friend class nsPluginInstanceOwner
;
272 friend class nsDisplayPlugin
;
273 friend class PluginBackgroundSink
;
275 nsView
* GetViewInternal() const override
{ return mOuterView
; }
276 void SetViewInternal(nsView
* aView
) override
{ mOuterView
= aView
; }
277 bool GetBounds(nsDisplayItem
* aItem
, mozilla::gfx::IntSize
& aSize
,
281 // Registers the plugin for a geometry update, and requests a geometry
282 // update. This caches the root pres context in
283 // mRootPresContextRegisteredWith, so that we can be sure we unregister
284 // from the right root prest context in UnregisterPluginForGeometryUpdates.
285 void RegisterPluginForGeometryUpdates();
287 // Unregisters the plugin for geometry updated with the root pres context
288 // stored in mRootPresContextRegisteredWith.
289 void UnregisterPluginForGeometryUpdates();
291 static const LayoutDeviceIntRegion
RegionFromArray(
292 const nsTArray
<LayoutDeviceIntRect
>& aRects
) {
293 LayoutDeviceIntRegion region
;
294 for (uint32_t i
= 0; i
< aRects
.Length(); ++i
) {
295 region
.Or(region
, aRects
[i
]);
300 class PluginEventNotifier
: public mozilla::Runnable
{
302 explicit PluginEventNotifier(const nsString
& aEventType
)
303 : mozilla::Runnable("nsPluginFrame::PluginEventNotifier"),
304 mEventType(aEventType
) {}
306 NS_IMETHOD
Run() override
;
312 nsPluginInstanceOwner
* mInstanceOwner
; // WEAK
315 nsCOMPtr
<nsIWidget
> mWidget
;
316 nsIntRect mWindowlessRect
;
318 * This is owned by the ReadbackLayer for this nsPluginFrame. It is
319 * automatically cleared if the PluginBackgroundSink is destroyed.
321 PluginBackgroundSink
* mBackgroundSink
;
324 * Bounds that we should set the plugin's widget to in the next composite,
325 * for plugins with widgets. For plugins without widgets, bounds in device
326 * pixels relative to the nearest frame that's a display list reference frame.
328 LayoutDeviceIntRect mNextConfigurationBounds
;
330 * Clip region that we should set the plugin's widget to
331 * in the next composite. Only meaningful for plugins with widgets.
333 nsTArray
<LayoutDeviceIntRect
> mNextConfigurationClipRegion
;
335 bool mReflowCallbackPosted
;
337 // We keep this reference to ensure we can always unregister the
338 // plugins we register on the root PresContext.
339 // This is only non-null while we have a plugin registered for geometry
341 RefPtr
<nsRootPresContext
> mRootPresContextRegisteredWith
;
343 mozilla::UniquePtr
<PluginFrameDidCompositeObserver
> mDidCompositeObserver
;
346 class nsDisplayPluginGeometry
: public nsDisplayItemGenericGeometry
{
348 nsDisplayPluginGeometry(nsDisplayItem
* aItem
, nsDisplayListBuilder
* aBuilder
)
349 : nsDisplayItemGenericGeometry(aItem
, aBuilder
) {}
351 // Plugins MozPaintWait event depends on sync decode, so we always want
352 // to rebuild the display list when sync decoding.
353 virtual bool InvalidateForSyncDecodeImages() const override
{ return true; }
356 class nsDisplayPlugin final
: public nsPaintedDisplayItem
{
358 nsDisplayPlugin(nsDisplayListBuilder
* aBuilder
, nsIFrame
* aFrame
)
359 : nsPaintedDisplayItem(aBuilder
, aFrame
) {
360 MOZ_COUNT_CTOR(nsDisplayPlugin
);
361 aBuilder
->SetContainsPluginItem();
363 #ifdef NS_BUILD_REFCNT_LOGGING
364 virtual ~nsDisplayPlugin() { MOZ_COUNT_DTOR(nsDisplayPlugin
); }
367 virtual nsRect
GetBounds(nsDisplayListBuilder
* aBuilder
,
368 bool* aSnap
) const override
;
369 virtual nsRegion
GetOpaqueRegion(nsDisplayListBuilder
* aBuilder
,
370 bool* aSnap
) const override
;
371 virtual void Paint(nsDisplayListBuilder
* aBuilder
, gfxContext
* aCtx
) override
;
372 virtual bool ComputeVisibility(nsDisplayListBuilder
* aBuilder
,
373 nsRegion
* aVisibleRegion
) override
;
375 NS_DISPLAY_DECL_NAME("Plugin", TYPE_PLUGIN
)
377 virtual already_AddRefed
<Layer
> BuildLayer(
378 nsDisplayListBuilder
* aBuilder
, LayerManager
* aManager
,
379 const ContainerLayerParameters
& aContainerParameters
) override
{
380 return static_cast<nsPluginFrame
*>(mFrame
)->BuildLayer(
381 aBuilder
, aManager
, this, aContainerParameters
);
384 virtual LayerState
GetLayerState(
385 nsDisplayListBuilder
* aBuilder
, LayerManager
* aManager
,
386 const ContainerLayerParameters
& aParameters
) override
{
387 return static_cast<nsPluginFrame
*>(mFrame
)->GetLayerState(aBuilder
,
391 virtual nsDisplayItemGeometry
* AllocateGeometry(
392 nsDisplayListBuilder
* aBuilder
) override
{
393 return new nsDisplayPluginGeometry(this, aBuilder
);
396 virtual bool CreateWebRenderCommands(
397 mozilla::wr::DisplayListBuilder
& aBuilder
,
398 mozilla::wr::IpcResourceUpdateQueue
& aResources
,
399 const StackingContextHelper
& aSc
,
400 mozilla::layers::RenderRootStateManager
* aManager
,
401 nsDisplayListBuilder
* aDisplayListBuilder
) override
;
404 #endif /* nsPluginFrame_h___ */