Merge m-c to fx-team.
[gecko.git] / widget / qt / nsWindow.h
blobdfb0e8c525eef9d73e11fd12be8bd5202d4b5e33
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* vim:expandtab:shiftwidth=4:tabstop=4:
3 */
4 /* This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 #ifndef __nsWindow_h__
9 #define __nsWindow_h__
11 #include <QKeyEvent>
12 #include <QGestureEvent>
13 #include <qgraphicswidget.h>
14 #include <QTime>
16 #include "nsAutoPtr.h"
18 #include "nsBaseWidget.h"
19 #include "nsGUIEvent.h"
21 #include "nsWeakReference.h"
23 #include "nsGkAtoms.h"
24 #include "nsIIdleServiceInternal.h"
25 #include "nsIRunnable.h"
26 #include "nsThreadUtils.h"
28 #ifdef MOZ_LOGGING
30 // make sure that logging is enabled before including prlog.h
31 #define FORCE_PR_LOG
33 #include "prlog.h"
34 #include "nsTArray.h"
36 extern PRLogModuleInfo *gWidgetLog;
37 extern PRLogModuleInfo *gWidgetFocusLog;
38 extern PRLogModuleInfo *gWidgetIMLog;
39 extern PRLogModuleInfo *gWidgetDrawLog;
41 #define LOG(args) PR_LOG(gWidgetLog, 4, args)
42 #define LOGFOCUS(args) PR_LOG(gWidgetFocusLog, 4, args)
43 #define LOGIM(args) PR_LOG(gWidgetIMLog, 4, args)
44 #define LOGDRAW(args) PR_LOG(gWidgetDrawLog, 4, args)
46 #else
48 #ifdef DEBUG_WIDGETS
50 #define PR_LOG2(_args) \
51 PR_BEGIN_MACRO \
52 qDebug _args; \
53 PR_END_MACRO
55 #define LOG(args) PR_LOG2(args)
56 #define LOGFOCUS(args) PR_LOG2(args)
57 #define LOGIM(args) PR_LOG2(args)
58 #define LOGDRAW(args) PR_LOG2(args)
60 #else
62 #define LOG(args)
63 #define LOGFOCUS(args)
64 #define LOGIM(args)
65 #define LOGDRAW(args)
67 #endif
69 #endif /* MOZ_LOGGING */
71 class QEvent;
72 class QGraphicsView;
74 class MozQWidget;
76 class nsIdleService;
78 class nsWindow : public nsBaseWidget,
79 public nsSupportsWeakReference
81 public:
82 nsWindow();
83 virtual ~nsWindow();
85 bool DoPaint( QPainter* aPainter, const QStyleOptionGraphicsItem * aOption, QWidget* aWidget);
87 static void ReleaseGlobals();
89 NS_DECL_ISUPPORTS_INHERITED
92 // nsIWidget
95 NS_IMETHOD ConfigureChildren(const nsTArray<nsIWidget::Configuration>&);
97 NS_IMETHOD Create(nsIWidget *aParent,
98 nsNativeWidget aNativeParent,
99 const nsIntRect &aRect,
100 nsDeviceContext *aContext,
101 nsWidgetInitData *aInitData);
103 virtual already_AddRefed<nsIWidget>
104 CreateChild(const nsIntRect& aRect,
105 nsDeviceContext* aContext,
106 nsWidgetInitData* aInitData = nullptr,
107 bool aForceUseIWidgetParent = true);
109 NS_IMETHOD Destroy(void);
110 NS_IMETHOD SetParent(nsIWidget* aNewParent);
111 virtual nsIWidget *GetParent(void);
112 virtual float GetDPI();
113 NS_IMETHOD Show(bool aState);
114 NS_IMETHOD SetModal(bool aModal);
115 virtual bool IsVisible() const;
116 NS_IMETHOD ConstrainPosition(bool aAllowSlop,
117 int32_t *aX,
118 int32_t *aY);
119 NS_IMETHOD Move(double aX,
120 double aY);
121 NS_IMETHOD Resize(double aWidth,
122 double aHeight,
123 bool aRepaint);
124 NS_IMETHOD Resize(double aX,
125 double aY,
126 double aWidth,
127 double aHeight,
128 bool aRepaint);
129 NS_IMETHOD PlaceBehind(nsTopLevelWidgetZPlacement aPlacement,
130 nsIWidget *aWidget,
131 bool aActivate);
132 NS_IMETHOD SetSizeMode(int32_t aMode);
133 NS_IMETHOD Enable(bool aState);
134 NS_IMETHOD SetFocus(bool aRaise = false);
135 NS_IMETHOD GetScreenBounds(nsIntRect &aRect);
136 NS_IMETHOD SetForegroundColor(const nscolor &aColor);
137 NS_IMETHOD SetBackgroundColor(const nscolor &aColor);
138 NS_IMETHOD SetCursor(nsCursor aCursor);
139 NS_IMETHOD SetCursor(imgIContainer* aCursor,
140 uint32_t aHotspotX, uint32_t aHotspotY);
141 NS_IMETHOD SetHasTransparentBackground(bool aTransparent);
142 NS_IMETHOD GetHasTransparentBackground(bool& aTransparent);
143 NS_IMETHOD HideWindowChrome(bool aShouldHide);
144 NS_IMETHOD MakeFullScreen(bool aFullScreen);
145 NS_IMETHOD Invalidate(const nsIntRect &aRect);
147 virtual void* GetNativeData(uint32_t aDataType);
148 NS_IMETHOD SetTitle(const nsAString& aTitle);
149 NS_IMETHOD SetIcon(const nsAString& aIconSpec);
150 virtual nsIntPoint WidgetToScreenOffset();
151 NS_IMETHOD DispatchEvent(nsGUIEvent *aEvent, nsEventStatus &aStatus);
153 NS_IMETHOD EnableDragDrop(bool aEnable);
154 NS_IMETHOD CaptureMouse(bool aCapture);
155 NS_IMETHOD CaptureRollupEvents(nsIRollupListener *aListener,
156 bool aDoCapture);
158 NS_IMETHOD SetWindowClass(const nsAString& xulWinType);
160 NS_IMETHOD GetAttention(int32_t aCycleCount);
161 NS_IMETHOD BeginResizeDrag (nsGUIEvent* aEvent, int32_t aHorizontal, int32_t aVertical);
163 NS_IMETHOD_(void) SetInputContext(const InputContext& aContext,
164 const InputContextAction& aAction);
165 NS_IMETHOD_(InputContext) GetInputContext();
166 NS_IMETHOD_(bool) HasGLContext();
169 // utility methods
171 void QWidgetDestroyed();
173 /***** from CommonWidget *****/
175 // event handling code
177 void DispatchActivateEvent(void);
178 void DispatchDeactivateEvent(void);
179 void DispatchActivateEventOnTopLevelWindow(void);
180 void DispatchDeactivateEventOnTopLevelWindow(void);
181 void DispatchResizeEvent(nsIntRect &aRect, nsEventStatus &aStatus);
183 nsEventStatus DispatchEvent(nsGUIEvent *aEvent) {
184 nsEventStatus status;
185 DispatchEvent(aEvent, status);
186 return status;
189 // Some of the nsIWidget methods
190 virtual bool IsEnabled() const;
192 // called when we are destroyed
193 void OnDestroy(void);
195 // called to check and see if a widget's dimensions are sane
196 bool AreBoundsSane(void);
198 NS_IMETHOD ReparentNativeWidget(nsIWidget* aNewParent);
200 QWidget* GetViewWidget();
201 virtual uint32_t GetGLFrameBufferFormat() MOZ_OVERRIDE;
203 protected:
204 nsCOMPtr<nsIWidget> mParent;
205 // Is this a toplevel window?
206 bool mIsTopLevel;
207 // Has this widget been destroyed yet?
208 bool mIsDestroyed;
210 // This flag tracks if we're hidden or shown.
211 bool mIsShown;
212 // is this widget enabled?
213 bool mEnabled;
214 // Has anyone set an x/y location for this widget yet? Toplevels
215 // shouldn't be automatically set to 0,0 for first show.
216 bool mPlaced;
218 // Remember the last sizemode so that we can restore it when
219 // leaving fullscreen
220 nsSizeMode mLastSizeMode;
222 InputContext mInputContext;
225 * Event handlers (proxied from the actual qwidget).
226 * They follow normal Qt widget semantics.
228 void Initialize(MozQWidget *widget);
229 friend class nsQtEventDispatcher;
230 friend class InterceptContainer;
231 friend class MozQWidget;
233 virtual nsEventStatus OnMoveEvent(QGraphicsSceneHoverEvent *);
234 virtual nsEventStatus OnResizeEvent(QGraphicsSceneResizeEvent *);
235 virtual nsEventStatus OnCloseEvent(QCloseEvent *);
236 virtual nsEventStatus OnEnterNotifyEvent(QGraphicsSceneHoverEvent *);
237 virtual nsEventStatus OnLeaveNotifyEvent(QGraphicsSceneHoverEvent *);
238 virtual nsEventStatus OnMotionNotifyEvent(QPointF, Qt::KeyboardModifiers);
239 virtual nsEventStatus OnButtonPressEvent(QGraphicsSceneMouseEvent *);
240 virtual nsEventStatus OnButtonReleaseEvent(QGraphicsSceneMouseEvent *);
241 virtual nsEventStatus OnMouseDoubleClickEvent(QGraphicsSceneMouseEvent *);
242 virtual nsEventStatus OnFocusInEvent(QEvent *);
243 virtual nsEventStatus OnFocusOutEvent(QEvent *);
244 virtual nsEventStatus OnKeyPressEvent(QKeyEvent *);
245 virtual nsEventStatus OnKeyReleaseEvent(QKeyEvent *);
246 virtual nsEventStatus OnScrollEvent(QGraphicsSceneWheelEvent *);
248 virtual nsEventStatus contextMenuEvent(QGraphicsSceneContextMenuEvent *);
249 virtual nsEventStatus imComposeEvent(QInputMethodEvent *, bool &handled);
250 virtual nsEventStatus OnDragEnter (QGraphicsSceneDragDropEvent *);
251 virtual nsEventStatus OnDragMotionEvent(QGraphicsSceneDragDropEvent *);
252 virtual nsEventStatus OnDragLeaveEvent(QGraphicsSceneDragDropEvent *);
253 virtual nsEventStatus OnDragDropEvent (QGraphicsSceneDragDropEvent *);
254 virtual nsEventStatus showEvent(QShowEvent *);
255 virtual nsEventStatus hideEvent(QHideEvent *);
257 //Gestures are only supported in qt > 4.6
258 #if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 0))
259 virtual nsEventStatus OnTouchEvent(QTouchEvent *event, bool &handled);
261 virtual nsEventStatus OnGestureEvent(QGestureEvent *event, bool &handled);
262 nsEventStatus DispatchGestureEvent(uint32_t aMsg, uint32_t aDirection,
263 double aDelta, const nsIntPoint& aRefPoint);
265 double DistanceBetweenPoints(const QPointF &aFirstPoint, const QPointF &aSecondPoint);
266 #endif
268 void NativeResize(int32_t aWidth,
269 int32_t aHeight,
270 bool aRepaint);
272 void NativeResize(int32_t aX,
273 int32_t aY,
274 int32_t aWidth,
275 int32_t aHeight,
276 bool aRepaint);
278 void NativeShow (bool aAction);
280 enum PluginType {
281 PluginType_NONE = 0, /* do not have any plugin */
282 PluginType_XEMBED, /* the plugin support xembed */
283 PluginType_NONXEMBED /* the plugin does not support xembed */
286 void SetPluginType(PluginType aPluginType);
288 void ThemeChanged(void);
290 gfxASurface* GetThebesSurface();
292 private:
293 typedef struct {
294 QPointF centerPoint;
295 QPointF touchPoint;
296 double delta;
297 bool needDispatch;
298 double startDistance;
299 double prevDistance;
300 } MozCachedTouchEvent;
302 typedef struct {
303 QPointF pos;
304 Qt::KeyboardModifiers modifiers;
305 bool needDispatch;
306 } MozCachedMoveEvent;
308 bool CheckForRollup(double aMouseX, double aMouseY, bool aIsWheel);
309 void* SetupPluginPort(void);
310 nsresult SetWindowIconList(const nsTArray<nsCString> &aIconList);
311 void SetDefaultIcon(void);
312 void InitButtonEvent(nsMouseEvent &event, QGraphicsSceneMouseEvent *aEvent, int aClickCount = 1);
313 nsEventStatus DispatchCommandEvent(nsIAtom* aCommand);
314 nsEventStatus DispatchContentCommandEvent(int32_t aMsg);
315 MozQWidget* createQWidget(MozQWidget* parent,
316 nsNativeWidget nativeParent,
317 nsWidgetInitData* aInitData);
318 void SetSoftwareKeyboardState(bool aOpen, const InputContextAction& aAction);
319 void ClearCachedResources();
321 MozQWidget* mWidget;
323 uint32_t mIsVisible : 1,
324 mActivatePending : 1;
325 int32_t mSizeState;
326 PluginType mPluginType;
328 nsRefPtr<gfxASurface> mThebesSurface;
329 nsCOMPtr<nsIIdleServiceInternal> mIdleService;
331 bool mIsTransparent;
333 // all of our DND stuff
334 // this is the last window that had a drag event happen on it.
335 void InitDragEvent (nsMouseEvent &aEvent);
337 // this is everything we need to be able to fire motion events
338 // repeatedly
339 uint32_t mKeyDownFlags[8];
341 /* Helper methods for DOM Key Down event suppression. */
342 uint32_t* GetFlagWord32(uint32_t aKeyCode, uint32_t* aMask) {
343 /* Mozilla DOM Virtual Key Code is from 0 to 224. */
344 NS_ASSERTION((aKeyCode <= 0xFF), "Invalid DOM Key Code");
345 aKeyCode &= 0xFF;
347 /* 32 = 2^5 = 0x20 */
348 *aMask = uint32_t(1) << (aKeyCode & 0x1F);
349 return &mKeyDownFlags[(aKeyCode >> 5)];
352 bool IsKeyDown(uint32_t aKeyCode) {
353 uint32_t mask;
354 uint32_t* flag = GetFlagWord32(aKeyCode, &mask);
355 return ((*flag) & mask) != 0;
358 void SetKeyDownFlag(uint32_t aKeyCode) {
359 uint32_t mask;
360 uint32_t* flag = GetFlagWord32(aKeyCode, &mask);
361 *flag |= mask;
364 void ClearKeyDownFlag(uint32_t aKeyCode) {
365 uint32_t mask;
366 uint32_t* flag = GetFlagWord32(aKeyCode, &mask);
367 *flag &= ~mask;
369 int32_t mQCursor;
371 // Call this function when the users activity is the direct cause of an
372 // event (like a keypress or mouse click).
373 void UserActivity();
375 inline void ProcessMotionEvent() {
376 if (mPinchEvent.needDispatch) {
377 double distance = DistanceBetweenPoints(mPinchEvent.centerPoint, mPinchEvent.touchPoint);
378 distance *= 2;
379 mPinchEvent.delta = distance - mPinchEvent.prevDistance;
380 nsIntPoint centerPoint(mPinchEvent.centerPoint.x(), mPinchEvent.centerPoint.y());
381 DispatchGestureEvent(NS_SIMPLE_GESTURE_MAGNIFY_UPDATE,
382 0, mPinchEvent.delta, centerPoint);
383 mPinchEvent.prevDistance = distance;
385 if (mMoveEvent.needDispatch) {
386 nsMouseEvent event(true, NS_MOUSE_MOVE, this, nsMouseEvent::eReal);
388 event.refPoint.x = nscoord(mMoveEvent.pos.x());
389 event.refPoint.y = nscoord(mMoveEvent.pos.y());
391 event.InitBasicModifiers(mMoveEvent.modifiers & Qt::ControlModifier,
392 mMoveEvent.modifiers & Qt::AltModifier,
393 mMoveEvent.modifiers & Qt::ShiftModifier,
394 mMoveEvent.modifiers & Qt::MetaModifier);
395 event.clickCount = 0;
397 DispatchEvent(&event);
398 mMoveEvent.needDispatch = false;
401 mTimerStarted = false;
404 void DispatchMotionToMainThread() {
405 if (!mTimerStarted) {
406 nsCOMPtr<nsIRunnable> event =
407 NS_NewRunnableMethod(this, &nsWindow::ProcessMotionEvent);
408 NS_DispatchToMainThread(event);
409 mTimerStarted = true;
413 // Remember dirty area caused by ::Scroll
414 QRegion mDirtyScrollArea;
416 #if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 0))
417 QTime mLastMultiTouchTime;
418 #endif
420 bool mNeedsResize;
421 bool mNeedsMove;
422 bool mListenForResizes;
423 bool mNeedsShow;
424 bool mGesturesCancelled;
425 MozCachedTouchEvent mPinchEvent;
426 MozCachedMoveEvent mMoveEvent;
427 bool mTimerStarted;
430 class nsChildWindow : public nsWindow
432 public:
433 nsChildWindow();
434 ~nsChildWindow();
436 int32_t mChildID;
439 class nsPopupWindow : public nsWindow
441 public:
442 nsPopupWindow ();
443 ~nsPopupWindow ();
445 int32_t mChildID;
447 #endif /* __nsWindow_h__ */