1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* vim:expandtab:shiftwidth=4:tabstop=4:
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/. */
12 #include <QGestureEvent>
13 #include <qgraphicswidget.h>
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"
30 // make sure that logging is enabled before including prlog.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)
50 #define PR_LOG2(_args) \
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)
63 #define LOGFOCUS(args)
69 #endif /* MOZ_LOGGING */
78 class nsWindow
: public nsBaseWidget
,
79 public nsSupportsWeakReference
85 bool DoPaint( QPainter
* aPainter
, const QStyleOptionGraphicsItem
* aOption
, QWidget
* aWidget
);
87 static void ReleaseGlobals();
89 NS_DECL_ISUPPORTS_INHERITED
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
,
119 NS_IMETHOD
Move(double aX
,
121 NS_IMETHOD
Resize(double aWidth
,
124 NS_IMETHOD
Resize(double aX
,
129 NS_IMETHOD
PlaceBehind(nsTopLevelWidgetZPlacement aPlacement
,
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
,
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();
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
);
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
;
204 nsCOMPtr
<nsIWidget
> mParent
;
205 // Is this a toplevel window?
207 // Has this widget been destroyed yet?
210 // This flag tracks if we're hidden or shown.
212 // is this widget enabled?
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.
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
);
268 void NativeResize(int32_t aWidth
,
272 void NativeResize(int32_t aX
,
278 void NativeShow (bool aAction
);
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();
298 double startDistance
;
300 } MozCachedTouchEvent
;
304 Qt::KeyboardModifiers modifiers
;
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();
323 uint32_t mIsVisible
: 1,
324 mActivatePending
: 1;
326 PluginType mPluginType
;
328 nsRefPtr
<gfxASurface
> mThebesSurface
;
329 nsCOMPtr
<nsIIdleServiceInternal
> mIdleService
;
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
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");
347 /* 32 = 2^5 = 0x20 */
348 *aMask
= uint32_t(1) << (aKeyCode
& 0x1F);
349 return &mKeyDownFlags
[(aKeyCode
>> 5)];
352 bool IsKeyDown(uint32_t aKeyCode
) {
354 uint32_t* flag
= GetFlagWord32(aKeyCode
, &mask
);
355 return ((*flag
) & mask
) != 0;
358 void SetKeyDownFlag(uint32_t aKeyCode
) {
360 uint32_t* flag
= GetFlagWord32(aKeyCode
, &mask
);
364 void ClearKeyDownFlag(uint32_t aKeyCode
) {
366 uint32_t* flag
= GetFlagWord32(aKeyCode
, &mask
);
371 // Call this function when the users activity is the direct cause of an
372 // event (like a keypress or mouse click).
375 inline void ProcessMotionEvent() {
376 if (mPinchEvent
.needDispatch
) {
377 double distance
= DistanceBetweenPoints(mPinchEvent
.centerPoint
, mPinchEvent
.touchPoint
);
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
;
422 bool mListenForResizes
;
424 bool mGesturesCancelled
;
425 MozCachedTouchEvent mPinchEvent
;
426 MozCachedMoveEvent mMoveEvent
;
430 class nsChildWindow
: public nsWindow
439 class nsPopupWindow
: public nsWindow
447 #endif /* __nsWindow_h__ */