michael@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ michael@0: /* vim:expandtab:shiftwidth=4:tabstop=4: michael@0: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef __nsWindow_h__ michael@0: #define __nsWindow_h__ michael@0: michael@0: #include michael@0: michael@0: #include "nsAutoPtr.h" michael@0: #include "nsBaseWidget.h" michael@0: #include "mozilla/EventForwards.h" michael@0: michael@0: #include "nsWeakReference.h" michael@0: michael@0: #include "nsGkAtoms.h" michael@0: #include "nsIIdleServiceInternal.h" michael@0: #include "nsIRunnable.h" michael@0: #include "nsThreadUtils.h" michael@0: michael@0: #ifdef MOZ_LOGGING michael@0: michael@0: // make sure that logging is enabled before including prlog.h michael@0: #define FORCE_PR_LOG michael@0: michael@0: #include "prlog.h" michael@0: #include "nsTArray.h" michael@0: michael@0: extern PRLogModuleInfo *gWidgetLog; michael@0: extern PRLogModuleInfo *gWidgetFocusLog; michael@0: extern PRLogModuleInfo *gWidgetIMLog; michael@0: extern PRLogModuleInfo *gWidgetDrawLog; michael@0: michael@0: #define LOG(args) PR_LOG(gWidgetLog, 4, args) michael@0: #define LOGFOCUS(args) PR_LOG(gWidgetFocusLog, 4, args) michael@0: #define LOGIM(args) PR_LOG(gWidgetIMLog, 4, args) michael@0: #define LOGDRAW(args) PR_LOG(gWidgetDrawLog, 4, args) michael@0: michael@0: #else michael@0: michael@0: #ifdef DEBUG_WIDGETS michael@0: michael@0: #define PR_LOG2(_args) \ michael@0: PR_BEGIN_MACRO \ michael@0: qDebug _args; \ michael@0: PR_END_MACRO michael@0: michael@0: #define LOG(args) PR_LOG2(args) michael@0: #define LOGFOCUS(args) PR_LOG2(args) michael@0: #define LOGIM(args) PR_LOG2(args) michael@0: #define LOGDRAW(args) PR_LOG2(args) michael@0: michael@0: #else michael@0: michael@0: #define LOG(args) michael@0: #define LOGFOCUS(args) michael@0: #define LOGIM(args) michael@0: #define LOGDRAW(args) michael@0: michael@0: #endif michael@0: michael@0: #endif /* MOZ_LOGGING */ michael@0: michael@0: class nsIdleService; michael@0: class QCloseEvent; michael@0: class QFocusEvent; michael@0: class QHideEvent; michael@0: class QKeyEvent; michael@0: class QMouseEvent; michael@0: class QMoveEvent; michael@0: class QResizeEvent; michael@0: class QShowEvent; michael@0: class QTabletEvent; michael@0: class QTouchEvent; michael@0: class QWheelEvent; michael@0: michael@0: namespace mozilla { michael@0: namespace widget { michael@0: class MozQWidget; michael@0: class nsWindow : public nsBaseWidget, michael@0: public nsSupportsWeakReference michael@0: { michael@0: public: michael@0: nsWindow(); michael@0: virtual ~nsWindow(); michael@0: michael@0: NS_DECL_ISUPPORTS_INHERITED michael@0: michael@0: // michael@0: // nsIWidget michael@0: // michael@0: NS_IMETHOD Create(nsIWidget *aParent, michael@0: nsNativeWidget aNativeParent, michael@0: const nsIntRect &aRect, michael@0: nsDeviceContext *aContext, michael@0: nsWidgetInitData *aInitData); michael@0: NS_IMETHOD Destroy(void); michael@0: michael@0: NS_IMETHOD Show(bool aState); michael@0: virtual bool IsVisible() const; michael@0: NS_IMETHOD ConstrainPosition(bool aAllowSlop, michael@0: int32_t *aX, michael@0: int32_t *aY); michael@0: NS_IMETHOD Move(double aX, michael@0: double aY); michael@0: NS_IMETHOD Resize(double aWidth, michael@0: double aHeight, michael@0: bool aRepaint); michael@0: NS_IMETHOD Resize(double aX, michael@0: double aY, michael@0: double aWidth, michael@0: double aHeight, michael@0: bool aRepaint); michael@0: NS_IMETHOD Enable(bool aState); michael@0: // Some of the nsIWidget methods michael@0: virtual bool IsEnabled() const; michael@0: NS_IMETHOD SetFocus(bool aRaise = false); michael@0: NS_IMETHOD ConfigureChildren(const nsTArray&); michael@0: NS_IMETHOD Invalidate(const nsIntRect &aRect); michael@0: virtual void* GetNativeData(uint32_t aDataType); michael@0: NS_IMETHOD SetTitle(const nsAString& aTitle); michael@0: NS_IMETHOD SetCursor(nsCursor aCursor); michael@0: NS_IMETHOD SetCursor(imgIContainer* aCursor, michael@0: uint32_t aHotspotX, uint32_t aHotspotY) michael@0: { michael@0: return NS_OK; michael@0: } michael@0: virtual nsIntPoint WidgetToScreenOffset(); michael@0: NS_IMETHOD DispatchEvent(mozilla::WidgetGUIEvent* aEvent, michael@0: nsEventStatus& aStatus); michael@0: NS_IMETHOD CaptureRollupEvents(nsIRollupListener *aListener, michael@0: bool aDoCapture) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: NS_IMETHOD ReparentNativeWidget(nsIWidget* aNewParent); michael@0: michael@0: NS_IMETHOD MakeFullScreen(bool aFullScreen); michael@0: virtual mozilla::layers::LayerManager* michael@0: GetLayerManager(PLayerTransactionChild* aShadowManager = nullptr, michael@0: LayersBackend aBackendHint = mozilla::layers::LayersBackend::LAYERS_NONE, michael@0: LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT, michael@0: bool* aAllowRetaining = nullptr); michael@0: michael@0: NS_IMETHOD_(void) SetInputContext(const InputContext& aContext, michael@0: const InputContextAction& aAction); michael@0: NS_IMETHOD_(InputContext) GetInputContext(); michael@0: michael@0: virtual uint32_t GetGLFrameBufferFormat() MOZ_OVERRIDE; michael@0: michael@0: // Widget notifications michael@0: virtual void OnPaint(); michael@0: virtual nsEventStatus focusInEvent(QFocusEvent* aEvent); michael@0: virtual nsEventStatus focusOutEvent(QFocusEvent* aEvent); michael@0: virtual nsEventStatus hideEvent(QHideEvent* aEvent); michael@0: virtual nsEventStatus showEvent(QShowEvent* aEvent); michael@0: virtual nsEventStatus keyPressEvent(QKeyEvent* aEvent); michael@0: virtual nsEventStatus keyReleaseEvent(QKeyEvent* aEvent); michael@0: virtual nsEventStatus mouseDoubleClickEvent(QMouseEvent* aEvent); michael@0: virtual nsEventStatus mouseMoveEvent(QMouseEvent* aEvent); michael@0: virtual nsEventStatus mousePressEvent(QMouseEvent* aEvent); michael@0: virtual nsEventStatus mouseReleaseEvent(QMouseEvent* aEvent); michael@0: virtual nsEventStatus moveEvent(QMoveEvent* aEvent); michael@0: virtual nsEventStatus resizeEvent(QResizeEvent* aEvent); michael@0: virtual nsEventStatus touchEvent(QTouchEvent* aEvent); michael@0: virtual nsEventStatus wheelEvent(QWheelEvent* aEvent); michael@0: virtual nsEventStatus tabletEvent(QTabletEvent* event); michael@0: michael@0: protected: michael@0: nsWindow* mParent; michael@0: bool mVisible; michael@0: InputContext mInputContext; michael@0: nsCOMPtr mIdleService; michael@0: MozQWidget* mWidget; michael@0: michael@0: private: michael@0: void InitButtonEvent(mozilla::WidgetMouseEvent& event, michael@0: QMouseEvent* aEvent, michael@0: int aClickCount = 1); michael@0: michael@0: // event handling code michael@0: nsEventStatus DispatchEvent(mozilla::WidgetGUIEvent* aEvent); michael@0: void DispatchActivateEvent(void); michael@0: void DispatchDeactivateEvent(void); michael@0: void DispatchActivateEventOnTopLevelWindow(void); michael@0: void DispatchDeactivateEventOnTopLevelWindow(void); michael@0: void DispatchResizeEvent(nsIntRect &aRect, nsEventStatus &aStatus); michael@0: michael@0: // Remember the last sizemode so that we can restore it when michael@0: // leaving fullscreen michael@0: nsSizeMode mLastSizeMode; michael@0: // is this widget enabled? michael@0: bool mEnabled; michael@0: michael@0: // Call this function when the users activity is the direct cause of an michael@0: // event (like a keypress or mouse click). michael@0: void UserActivity(); michael@0: MozQWidget* createQWidget(MozQWidget* parent, michael@0: nsWidgetInitData* aInitData); michael@0: michael@0: public: michael@0: // Old QtWidget only michael@0: NS_IMETHOD SetParent(nsIWidget* aNewParent); michael@0: virtual nsIWidget *GetParent(void); michael@0: virtual float GetDPI(); michael@0: NS_IMETHOD SetModal(bool aModal); michael@0: NS_IMETHOD PlaceBehind(nsTopLevelWidgetZPlacement aPlacement, michael@0: nsIWidget *aWidget, michael@0: bool aActivate); michael@0: NS_IMETHOD SetSizeMode(int32_t aMode); michael@0: NS_IMETHOD GetScreenBounds(nsIntRect &aRect); michael@0: NS_IMETHOD SetHasTransparentBackground(bool aTransparent); michael@0: NS_IMETHOD GetHasTransparentBackground(bool& aTransparent); michael@0: NS_IMETHOD HideWindowChrome(bool aShouldHide); michael@0: NS_IMETHOD SetIcon(const nsAString& aIconSpec); michael@0: NS_IMETHOD CaptureMouse(bool aCapture); michael@0: NS_IMETHOD SetWindowClass(const nsAString& xulWinType); michael@0: NS_IMETHOD GetAttention(int32_t aCycleCount); michael@0: NS_IMETHOD_(bool) HasGLContext(); michael@0: michael@0: // michael@0: // utility methods michael@0: // michael@0: void QWidgetDestroyed(); michael@0: // called when we are destroyed michael@0: void OnDestroy(void); michael@0: // called to check and see if a widget's dimensions are sane michael@0: bool AreBoundsSane(void); michael@0: private: michael@0: // Is this a toplevel window? michael@0: bool mIsTopLevel; michael@0: // Has this widget been destroyed yet? michael@0: bool mIsDestroyed; michael@0: // This flag tracks if we're hidden or shown. michael@0: bool mIsShown; michael@0: // Has anyone set an x/y location for this widget yet? Toplevels michael@0: // shouldn't be automatically set to 0,0 for first show. michael@0: bool mPlaced; michael@0: /** michael@0: * Event handlers (proxied from the actual qwidget). michael@0: * They follow normal Qt widget semantics. michael@0: */ michael@0: void Initialize(MozQWidget *widget); michael@0: virtual nsEventStatus OnCloseEvent(QCloseEvent *); michael@0: void NativeResize(int32_t aWidth, michael@0: int32_t aHeight, michael@0: bool aRepaint); michael@0: void NativeResize(int32_t aX, michael@0: int32_t aY, michael@0: int32_t aWidth, michael@0: int32_t aHeight, michael@0: bool aRepaint); michael@0: void NativeShow (bool aAction); michael@0: michael@0: private: michael@0: typedef struct { michael@0: QPointF pos; michael@0: Qt::KeyboardModifiers modifiers; michael@0: bool needDispatch; michael@0: } MozCachedMoveEvent; michael@0: michael@0: bool CheckForRollup(double aMouseX, double aMouseY, bool aIsWheel); michael@0: void* SetupPluginPort(void); michael@0: nsresult SetWindowIconList(const nsTArray &aIconList); michael@0: void SetDefaultIcon(void); michael@0: michael@0: nsEventStatus DispatchCommandEvent(nsIAtom* aCommand); michael@0: nsEventStatus DispatchContentCommandEvent(int32_t aMsg); michael@0: void SetSoftwareKeyboardState(bool aOpen, const InputContextAction& aAction); michael@0: void ClearCachedResources(); michael@0: michael@0: uint32_t mActivatePending : 1; michael@0: int32_t mSizeState; michael@0: michael@0: bool mIsTransparent; michael@0: michael@0: // all of our DND stuff michael@0: // this is the last window that had a drag event happen on it. michael@0: void InitDragEvent(mozilla::WidgetMouseEvent& aEvent); michael@0: michael@0: // this is everything we need to be able to fire motion events michael@0: // repeatedly michael@0: uint32_t mKeyDownFlags[8]; michael@0: michael@0: /* Helper methods for DOM Key Down event suppression. */ michael@0: uint32_t* GetFlagWord32(uint32_t aKeyCode, uint32_t* aMask) { michael@0: /* Mozilla DOM Virtual Key Code is from 0 to 224. */ michael@0: NS_ASSERTION((aKeyCode <= 0xFF), "Invalid DOM Key Code"); michael@0: aKeyCode &= 0xFF; michael@0: michael@0: /* 32 = 2^5 = 0x20 */ michael@0: *aMask = uint32_t(1) << (aKeyCode & 0x1F); michael@0: return &mKeyDownFlags[(aKeyCode >> 5)]; michael@0: } michael@0: michael@0: bool IsKeyDown(uint32_t aKeyCode) { michael@0: uint32_t mask; michael@0: uint32_t* flag = GetFlagWord32(aKeyCode, &mask); michael@0: return ((*flag) & mask) != 0; michael@0: } michael@0: michael@0: void SetKeyDownFlag(uint32_t aKeyCode) { michael@0: uint32_t mask; michael@0: uint32_t* flag = GetFlagWord32(aKeyCode, &mask); michael@0: *flag |= mask; michael@0: } michael@0: michael@0: void ClearKeyDownFlag(uint32_t aKeyCode) { michael@0: uint32_t mask; michael@0: uint32_t* flag = GetFlagWord32(aKeyCode, &mask); michael@0: *flag &= ~mask; michael@0: } michael@0: int32_t mQCursor; michael@0: michael@0: michael@0: void ProcessMotionEvent(); michael@0: michael@0: void DispatchMotionToMainThread() { michael@0: if (!mTimerStarted) { michael@0: nsCOMPtr event = michael@0: NS_NewRunnableMethod(this, &nsWindow::ProcessMotionEvent); michael@0: NS_DispatchToMainThread(event); michael@0: mTimerStarted = true; michael@0: } michael@0: } michael@0: michael@0: bool mNeedsResize; michael@0: bool mNeedsMove; michael@0: bool mListenForResizes; michael@0: bool mNeedsShow; michael@0: MozCachedMoveEvent mMoveEvent; michael@0: bool mTimerStarted; michael@0: }; michael@0: michael@0: }} michael@0: michael@0: #endif /* __nsWindow_h__ */