mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-01 14:45:29 +00:00
202e1980aa
This changes compositor creation so that we can specify an initial size and makes sure the local variable in nsWindow reflects that the compositor starts unpaused.
419 lines
17 KiB
C++
419 lines
17 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
#ifndef nsBaseWidget_h__
|
|
#define nsBaseWidget_h__
|
|
|
|
#include "mozilla/WidgetUtils.h"
|
|
#include "nsRect.h"
|
|
#include "nsIWidget.h"
|
|
#include "nsWidgetsCID.h"
|
|
#include "nsIFile.h"
|
|
#include "nsString.h"
|
|
#include "nsCOMPtr.h"
|
|
#include "nsGUIEvent.h"
|
|
#include "nsAutoPtr.h"
|
|
#include "nsIRollupListener.h"
|
|
#include <algorithm>
|
|
class nsIContent;
|
|
class nsAutoRollup;
|
|
class gfxContext;
|
|
|
|
namespace mozilla {
|
|
#ifdef ACCESSIBILITY
|
|
namespace a11y {
|
|
class Accessible;
|
|
}
|
|
#endif
|
|
|
|
namespace layers {
|
|
class BasicLayerManager;
|
|
class CompositorChild;
|
|
class CompositorParent;
|
|
}
|
|
}
|
|
|
|
namespace base {
|
|
class Thread;
|
|
}
|
|
|
|
/**
|
|
* Common widget implementation used as base class for native
|
|
* or crossplatform implementations of Widgets.
|
|
* All cross-platform behavior that all widgets need to implement
|
|
* should be placed in this class.
|
|
* (Note: widget implementations are not required to use this
|
|
* class, but it gives them a head start.)
|
|
*/
|
|
|
|
class nsBaseWidget : public nsIWidget
|
|
{
|
|
friend class nsAutoRollup;
|
|
|
|
protected:
|
|
typedef base::Thread Thread;
|
|
typedef mozilla::layers::BasicLayerManager BasicLayerManager;
|
|
typedef mozilla::layers::BufferMode BufferMode;
|
|
typedef mozilla::layers::CompositorChild CompositorChild;
|
|
typedef mozilla::layers::CompositorParent CompositorParent;
|
|
typedef mozilla::ScreenRotation ScreenRotation;
|
|
|
|
public:
|
|
nsBaseWidget();
|
|
virtual ~nsBaseWidget();
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
// nsIWidget interface
|
|
NS_IMETHOD CaptureMouse(bool aCapture);
|
|
virtual nsIWidgetListener* GetWidgetListener();
|
|
virtual void SetWidgetListener(nsIWidgetListener* alistener);
|
|
NS_IMETHOD Destroy();
|
|
NS_IMETHOD SetParent(nsIWidget* aNewParent);
|
|
virtual nsIWidget* GetParent(void);
|
|
virtual nsIWidget* GetTopLevelWidget();
|
|
virtual nsIWidget* GetSheetWindowParent(void);
|
|
virtual float GetDPI();
|
|
virtual void AddChild(nsIWidget* aChild);
|
|
virtual void RemoveChild(nsIWidget* aChild);
|
|
|
|
NS_IMETHOD SetZIndex(int32_t aZIndex);
|
|
NS_IMETHOD GetZIndex(int32_t* aZIndex);
|
|
NS_IMETHOD PlaceBehind(nsTopLevelWidgetZPlacement aPlacement,
|
|
nsIWidget *aWidget, bool aActivate);
|
|
|
|
NS_IMETHOD SetSizeMode(int32_t aMode);
|
|
NS_IMETHOD GetSizeMode(int32_t* aMode);
|
|
|
|
virtual nscolor GetForegroundColor(void);
|
|
NS_IMETHOD SetForegroundColor(const nscolor &aColor);
|
|
virtual nscolor GetBackgroundColor(void);
|
|
NS_IMETHOD SetBackgroundColor(const nscolor &aColor);
|
|
virtual nsCursor GetCursor();
|
|
NS_IMETHOD SetCursor(nsCursor aCursor);
|
|
NS_IMETHOD SetCursor(imgIContainer* aCursor,
|
|
uint32_t aHotspotX, uint32_t aHotspotY);
|
|
NS_IMETHOD GetWindowType(nsWindowType& aWindowType);
|
|
virtual void SetTransparencyMode(nsTransparencyMode aMode);
|
|
virtual nsTransparencyMode GetTransparencyMode();
|
|
virtual void GetWindowClipRegion(nsTArray<nsIntRect>* aRects);
|
|
NS_IMETHOD SetWindowShadowStyle(int32_t aStyle);
|
|
virtual void SetShowsToolbarButton(bool aShow) {}
|
|
virtual void SetShowsFullScreenButton(bool aShow) {}
|
|
virtual void SetWindowAnimationType(WindowAnimationType aType) {}
|
|
NS_IMETHOD HideWindowChrome(bool aShouldHide);
|
|
NS_IMETHOD MakeFullScreen(bool aFullScreen);
|
|
virtual nsDeviceContext* GetDeviceContext();
|
|
virtual LayerManager* GetLayerManager(PLayersChild* aShadowManager = nullptr,
|
|
LayersBackend aBackendHint = mozilla::layers::LAYERS_NONE,
|
|
LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT,
|
|
bool* aAllowRetaining = nullptr);
|
|
|
|
virtual void CreateCompositor();
|
|
virtual void CreateCompositor(int aWidth, int aHeight);
|
|
virtual void DrawWindowUnderlay(LayerManager* aManager, nsIntRect aRect) {}
|
|
virtual void DrawWindowOverlay(LayerManager* aManager, nsIntRect aRect) {}
|
|
virtual void UpdateThemeGeometries(const nsTArray<ThemeGeometry>& aThemeGeometries) {}
|
|
virtual gfxASurface* GetThebesSurface();
|
|
NS_IMETHOD SetModal(bool aModal);
|
|
NS_IMETHOD SetWindowClass(const nsAString& xulWinType);
|
|
NS_IMETHOD MoveClient(double aX, double aY);
|
|
NS_IMETHOD ResizeClient(double aWidth, double aHeight, bool aRepaint);
|
|
NS_IMETHOD ResizeClient(double aX, double aY, double aWidth, double aHeight, bool aRepaint);
|
|
NS_IMETHOD GetBounds(nsIntRect &aRect);
|
|
NS_IMETHOD GetClientBounds(nsIntRect &aRect);
|
|
NS_IMETHOD GetScreenBounds(nsIntRect &aRect);
|
|
NS_IMETHOD GetNonClientMargins(nsIntMargin &margins);
|
|
NS_IMETHOD SetNonClientMargins(nsIntMargin &margins);
|
|
virtual nsIntPoint GetClientOffset();
|
|
NS_IMETHOD EnableDragDrop(bool aEnable);
|
|
NS_IMETHOD GetAttention(int32_t aCycleCount);
|
|
virtual bool HasPendingInputEvent();
|
|
NS_IMETHOD SetIcon(const nsAString &anIconSpec);
|
|
NS_IMETHOD BeginSecureKeyboardInput();
|
|
NS_IMETHOD EndSecureKeyboardInput();
|
|
NS_IMETHOD SetWindowTitlebarColor(nscolor aColor, bool aActive);
|
|
virtual void SetDrawsInTitlebar(bool aState) {}
|
|
virtual bool ShowsResizeIndicator(nsIntRect* aResizerRect);
|
|
virtual void FreeNativeData(void * data, uint32_t aDataType) {}
|
|
NS_IMETHOD BeginResizeDrag(nsGUIEvent* aEvent, int32_t aHorizontal, int32_t aVertical);
|
|
NS_IMETHOD BeginMoveDrag(nsMouseEvent* aEvent);
|
|
virtual nsresult ActivateNativeMenuItemAt(const nsAString& indexString) { return NS_ERROR_NOT_IMPLEMENTED; }
|
|
virtual nsresult ForceUpdateNativeMenuAt(const nsAString& indexString) { return NS_ERROR_NOT_IMPLEMENTED; }
|
|
NS_IMETHOD NotifyIME(NotificationToIME aNotification) MOZ_OVERRIDE { return NS_ERROR_NOT_IMPLEMENTED; }
|
|
NS_IMETHOD SetLayersAcceleration(bool aEnabled);
|
|
virtual bool GetLayersAcceleration() { return mUseLayersAcceleration; }
|
|
virtual bool ComputeShouldAccelerate(bool aDefault);
|
|
NS_IMETHOD GetToggledKeyState(uint32_t aKeyCode, bool* aLEDState) { return NS_ERROR_NOT_IMPLEMENTED; }
|
|
NS_IMETHOD NotifyIMEOfTextChange(uint32_t aStart, uint32_t aOldEnd, uint32_t aNewEnd) MOZ_OVERRIDE { return NS_ERROR_NOT_IMPLEMENTED; }
|
|
virtual nsIMEUpdatePreference GetIMEUpdatePreference() { return nsIMEUpdatePreference(false, false); }
|
|
NS_IMETHOD OnDefaultButtonLoaded(const nsIntRect &aButtonRect) { return NS_ERROR_NOT_IMPLEMENTED; }
|
|
NS_IMETHOD OverrideSystemMouseScrollSpeed(double aOriginalDeltaX,
|
|
double aOriginalDeltaY,
|
|
double& aOverriddenDeltaX,
|
|
double& aOverriddenDeltaY);
|
|
virtual already_AddRefed<nsIWidget>
|
|
CreateChild(const nsIntRect &aRect,
|
|
nsDeviceContext *aContext,
|
|
nsWidgetInitData *aInitData = nullptr,
|
|
bool aForceUseIWidgetParent = false);
|
|
NS_IMETHOD AttachViewToTopLevel(bool aUseAttachedEvents, nsDeviceContext *aContext);
|
|
virtual nsIWidgetListener* GetAttachedWidgetListener();
|
|
virtual void SetAttachedWidgetListener(nsIWidgetListener* aListener);
|
|
NS_IMETHOD RegisterTouchWindow();
|
|
NS_IMETHOD UnregisterTouchWindow();
|
|
|
|
void NotifyWindowDestroyed();
|
|
void NotifySizeMoveDone();
|
|
|
|
// Should be called by derived implementations to notify on system color and
|
|
// theme changes.
|
|
void NotifySysColorChanged();
|
|
void NotifyThemeChanged();
|
|
void NotifyUIStateChanged(UIStateChangeType aShowAccelerators,
|
|
UIStateChangeType aShowFocusRings);
|
|
|
|
#ifdef ACCESSIBILITY
|
|
// Get the accessible for the window.
|
|
mozilla::a11y::Accessible* GetAccessible();
|
|
#endif
|
|
|
|
nsPopupLevel PopupLevel() { return mPopupLevel; }
|
|
|
|
virtual nsIntSize ClientToWindowSize(const nsIntSize& aClientSize)
|
|
{
|
|
return aClientSize;
|
|
}
|
|
|
|
// return true if this is a popup widget with a native titlebar
|
|
bool IsPopupWithTitleBar() const
|
|
{
|
|
return (mWindowType == eWindowType_popup &&
|
|
mBorderStyle != eBorderStyle_default &&
|
|
mBorderStyle & eBorderStyle_title);
|
|
}
|
|
|
|
NS_IMETHOD ReparentNativeWidget(nsIWidget* aNewParent) = 0;
|
|
|
|
virtual uint32_t GetGLFrameBufferFormat() MOZ_OVERRIDE;
|
|
|
|
virtual const SizeConstraints& GetSizeConstraints() const;
|
|
virtual void SetSizeConstraints(const SizeConstraints& aConstraints);
|
|
|
|
/**
|
|
* Use this when GetLayerManager() returns a BasicLayerManager
|
|
* (nsBaseWidget::GetLayerManager() does). This sets up the widget's
|
|
* layer manager to temporarily render into aTarget.
|
|
*
|
|
* |aNaturalWidgetBounds| is the un-rotated bounds of |aWidget|.
|
|
* |aRotation| is the "virtual rotation" to apply when rendering to
|
|
* the target. When |aRotation| is ROTATION_0,
|
|
* |aNaturalWidgetBounds| is not used.
|
|
*/
|
|
class AutoLayerManagerSetup {
|
|
public:
|
|
AutoLayerManagerSetup(nsBaseWidget* aWidget, gfxContext* aTarget,
|
|
BufferMode aDoubleBuffering,
|
|
ScreenRotation aRotation = mozilla::ROTATION_0);
|
|
~AutoLayerManagerSetup();
|
|
private:
|
|
nsBaseWidget* mWidget;
|
|
nsRefPtr<BasicLayerManager> mLayerManager;
|
|
};
|
|
friend class AutoLayerManagerSetup;
|
|
|
|
class AutoUseBasicLayerManager {
|
|
public:
|
|
AutoUseBasicLayerManager(nsBaseWidget* aWidget);
|
|
~AutoUseBasicLayerManager();
|
|
private:
|
|
nsBaseWidget* mWidget;
|
|
bool mPreviousTemporarilyUseBasicLayerManager;
|
|
};
|
|
friend class AutoUseBasicLayerManager;
|
|
|
|
nsWindowType GetWindowType() { return mWindowType; }
|
|
|
|
virtual bool ShouldUseOffMainThreadCompositing();
|
|
|
|
static nsIRollupListener* GetActiveRollupListener();
|
|
|
|
protected:
|
|
|
|
virtual void ResolveIconName(const nsAString &aIconName,
|
|
const nsAString &aIconSuffix,
|
|
nsIFile **aResult);
|
|
virtual void OnDestroy();
|
|
virtual void BaseCreate(nsIWidget *aParent,
|
|
const nsIntRect &aRect,
|
|
nsDeviceContext *aContext,
|
|
nsWidgetInitData *aInitData);
|
|
|
|
virtual nsIContent* GetLastRollup()
|
|
{
|
|
return mLastRollup;
|
|
}
|
|
|
|
virtual nsresult SynthesizeNativeKeyEvent(int32_t aNativeKeyboardLayout,
|
|
int32_t aNativeKeyCode,
|
|
uint32_t aModifierFlags,
|
|
const nsAString& aCharacters,
|
|
const nsAString& aUnmodifiedCharacters)
|
|
{ return NS_ERROR_UNEXPECTED; }
|
|
|
|
virtual nsresult SynthesizeNativeMouseEvent(nsIntPoint aPoint,
|
|
uint32_t aNativeMessage,
|
|
uint32_t aModifierFlags)
|
|
{ return NS_ERROR_UNEXPECTED; }
|
|
|
|
virtual nsresult SynthesizeNativeMouseMove(nsIntPoint aPoint)
|
|
{ return NS_ERROR_UNEXPECTED; }
|
|
|
|
virtual nsresult SynthesizeNativeMouseScrollEvent(nsIntPoint aPoint,
|
|
uint32_t aNativeMessage,
|
|
double aDeltaX,
|
|
double aDeltaY,
|
|
double aDeltaZ,
|
|
uint32_t aModifierFlags,
|
|
uint32_t aAdditionalFlags)
|
|
{ return NS_ERROR_UNEXPECTED; }
|
|
|
|
// Stores the clip rectangles in aRects into mClipRects. Returns true
|
|
// if the new rectangles are different from the old rectangles.
|
|
bool StoreWindowClipRegion(const nsTArray<nsIntRect>& aRects);
|
|
|
|
virtual already_AddRefed<nsIWidget>
|
|
AllocateChildPopupWidget()
|
|
{
|
|
static NS_DEFINE_IID(kCPopUpCID, NS_CHILD_CID);
|
|
nsCOMPtr<nsIWidget> widget = do_CreateInstance(kCPopUpCID);
|
|
return widget.forget();
|
|
}
|
|
|
|
BasicLayerManager* CreateBasicLayerManager();
|
|
|
|
nsPopupType PopupType() const { return mPopupType; }
|
|
|
|
void NotifyRollupGeometryChange()
|
|
{
|
|
// XULPopupManager isn't interested in this notification, so only
|
|
// send it if gRollupListener is set.
|
|
if (gRollupListener) {
|
|
gRollupListener->NotifyGeometryChange();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Apply the current size constraints to the given size.
|
|
*
|
|
* @param aWidth width to constrain
|
|
* @param aHeight height to constrain
|
|
*/
|
|
void ConstrainSize(int32_t* aWidth, int32_t* aHeight) const
|
|
{
|
|
*aWidth = std::max(mSizeConstraints.mMinSize.width,
|
|
std::min(mSizeConstraints.mMaxSize.width, *aWidth));
|
|
*aHeight = std::max(mSizeConstraints.mMinSize.height,
|
|
std::min(mSizeConstraints.mMaxSize.height, *aHeight));
|
|
}
|
|
|
|
virtual CompositorChild* GetRemoteRenderer() MOZ_OVERRIDE;
|
|
|
|
protected:
|
|
/**
|
|
* Starts the OMTC compositor destruction sequence.
|
|
*
|
|
* When this function returns, the compositor should not be
|
|
* able to access the opengl context anymore.
|
|
* It is safe to call it several times if platform implementations
|
|
* require the compositor to be destroyed before ~nsBaseWidget is
|
|
* reached (This is the case with gtk2 for instance).
|
|
*/
|
|
void DestroyCompositor();
|
|
|
|
nsIWidgetListener* mWidgetListener;
|
|
nsIWidgetListener* mAttachedWidgetListener;
|
|
nsDeviceContext* mContext;
|
|
nsRefPtr<LayerManager> mLayerManager;
|
|
nsRefPtr<LayerManager> mBasicLayerManager;
|
|
nsRefPtr<CompositorChild> mCompositorChild;
|
|
nsRefPtr<CompositorParent> mCompositorParent;
|
|
nscolor mBackground;
|
|
nscolor mForeground;
|
|
nsCursor mCursor;
|
|
nsWindowType mWindowType;
|
|
nsBorderStyle mBorderStyle;
|
|
bool mUseLayersAcceleration;
|
|
bool mForceLayersAcceleration;
|
|
bool mTemporarilyUseBasicLayerManager;
|
|
bool mUseAttachedEvents;
|
|
bool mContextInitialized;
|
|
nsIntRect mBounds;
|
|
nsIntRect* mOriginalBounds;
|
|
// When this pointer is null, the widget is not clipped
|
|
nsAutoArrayPtr<nsIntRect> mClipRects;
|
|
uint32_t mClipRectCount;
|
|
int32_t mZIndex;
|
|
nsSizeMode mSizeMode;
|
|
nsPopupLevel mPopupLevel;
|
|
nsPopupType mPopupType;
|
|
SizeConstraints mSizeConstraints;
|
|
|
|
static nsIRollupListener* gRollupListener;
|
|
|
|
// the last rolled up popup. Only set this when an nsAutoRollup is in scope,
|
|
// so it can be cleared automatically.
|
|
static nsIContent* mLastRollup;
|
|
|
|
#ifdef DEBUG
|
|
protected:
|
|
static nsAutoString debug_GuiEventToString(nsGUIEvent * aGuiEvent);
|
|
static bool debug_WantPaintFlashing();
|
|
|
|
static void debug_DumpInvalidate(FILE * aFileOut,
|
|
nsIWidget * aWidget,
|
|
const nsIntRect * aRect,
|
|
const nsAutoCString & aWidgetName,
|
|
int32_t aWindowID);
|
|
|
|
static void debug_DumpEvent(FILE * aFileOut,
|
|
nsIWidget * aWidget,
|
|
nsGUIEvent * aGuiEvent,
|
|
const nsAutoCString & aWidgetName,
|
|
int32_t aWindowID);
|
|
|
|
static void debug_DumpPaintEvent(FILE * aFileOut,
|
|
nsIWidget * aWidget,
|
|
const nsIntRegion & aPaintEvent,
|
|
const nsAutoCString & aWidgetName,
|
|
int32_t aWindowID);
|
|
|
|
static bool debug_GetCachedBoolPref(const char* aPrefName);
|
|
#endif
|
|
};
|
|
|
|
// A situation can occur when a mouse event occurs over a menu label while the
|
|
// menu popup is already open. The expected behaviour is to close the popup.
|
|
// This happens by calling nsIRollupListener::Rollup before the mouse event is
|
|
// processed. However, in cases where the mouse event is not consumed, this
|
|
// event will then get targeted at the menu label causing the menu to open
|
|
// again. To prevent this, we store in mLastRollup a reference to the popup
|
|
// that was closed during the Rollup call, and prevent this popup from
|
|
// reopening while processing the mouse event.
|
|
// mLastRollup should only be set while an nsAutoRollup is in scope;
|
|
// when it goes out of scope mLastRollup is cleared automatically.
|
|
// As mLastRollup is static, it can be retrieved by calling
|
|
// nsIWidget::GetLastRollup on any widget.
|
|
class nsAutoRollup
|
|
{
|
|
bool wasClear;
|
|
|
|
public:
|
|
|
|
nsAutoRollup();
|
|
~nsAutoRollup();
|
|
};
|
|
|
|
#endif // nsBaseWidget_h__
|