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/. */
11 #include "mozilla/ipc/SharedMemorySysV.h"
13 #include "nsAutoPtr.h"
15 #include "mozcontainer.h"
16 #include "nsWeakReference.h"
18 #include "nsIDragService.h"
20 #include "nsGkAtoms.h"
22 #include "nsBaseWidget.h"
31 #include "mozilla/a11y/Accessible.h"
33 #include "mozilla/EventForwards.h"
35 #include "nsGtkIMModule.h"
40 // make sure that logging is enabled before including prlog.h
46 extern PRLogModuleInfo
*gWidgetLog
;
47 extern PRLogModuleInfo
*gWidgetFocusLog
;
48 extern PRLogModuleInfo
*gWidgetDragLog
;
49 extern PRLogModuleInfo
*gWidgetDrawLog
;
51 #define LOG(args) PR_LOG(gWidgetLog, 4, args)
52 #define LOGFOCUS(args) PR_LOG(gWidgetFocusLog, 4, args)
53 #define LOGDRAG(args) PR_LOG(gWidgetDragLog, 4, args)
54 #define LOGDRAW(args) PR_LOG(gWidgetDrawLog, 4, args)
59 #define LOGFOCUS(args)
63 #endif /* MOZ_LOGGING */
68 #if defined(MOZ_X11) && defined(MOZ_HAVE_SHAREDMEMORYSYSV)
69 # define MOZ_HAVE_SHMIMAGE
74 class nsWindow
: public nsBaseWidget
, public nsSupportsWeakReference
79 static void ReleaseGlobals();
81 NS_DECL_ISUPPORTS_INHERITED
83 void CommonCreate(nsIWidget
*aParent
, bool aListenForResizes
);
85 virtual nsresult
DispatchEvent(mozilla::WidgetGUIEvent
* aEvent
,
86 nsEventStatus
& aStatus
);
88 // called when we are destroyed
91 // called to check and see if a widget's dimensions are sane
92 bool AreBoundsSane(void);
95 NS_IMETHOD
Create(nsIWidget
*aParent
,
96 nsNativeWidget aNativeParent
,
97 const nsIntRect
&aRect
,
98 nsDeviceContext
*aContext
,
99 nsWidgetInitData
*aInitData
);
100 NS_IMETHOD
Destroy(void);
101 virtual nsIWidget
*GetParent();
102 virtual float GetDPI();
103 virtual nsresult
SetParent(nsIWidget
* aNewParent
);
104 NS_IMETHOD
SetModal(bool aModal
);
105 virtual bool IsVisible() const;
106 NS_IMETHOD
ConstrainPosition(bool aAllowSlop
,
109 virtual void SetSizeConstraints(const SizeConstraints
& aConstraints
);
110 NS_IMETHOD
Move(double aX
,
112 NS_IMETHOD
Show (bool aState
);
113 NS_IMETHOD
Resize (double aWidth
,
116 NS_IMETHOD
Resize (double aX
,
121 virtual bool IsEnabled() const;
124 NS_IMETHOD
PlaceBehind(nsTopLevelWidgetZPlacement aPlacement
,
127 void SetZIndex(int32_t aZIndex
);
128 NS_IMETHOD
SetSizeMode(int32_t aMode
);
129 NS_IMETHOD
Enable(bool aState
);
130 NS_IMETHOD
SetFocus(bool aRaise
= false);
131 NS_IMETHOD
GetScreenBounds(nsIntRect
&aRect
);
132 NS_IMETHOD
GetClientBounds(nsIntRect
&aRect
);
133 virtual nsIntPoint
GetClientOffset();
134 NS_IMETHOD
SetCursor(nsCursor aCursor
);
135 NS_IMETHOD
SetCursor(imgIContainer
* aCursor
,
136 uint32_t aHotspotX
, uint32_t aHotspotY
);
137 NS_IMETHOD
Invalidate(const nsIntRect
&aRect
);
138 virtual void* GetNativeData(uint32_t aDataType
);
139 NS_IMETHOD
SetTitle(const nsAString
& aTitle
);
140 NS_IMETHOD
SetIcon(const nsAString
& aIconSpec
);
141 NS_IMETHOD
SetWindowClass(const nsAString
& xulWinType
);
142 virtual nsIntPoint
WidgetToScreenOffset();
143 NS_IMETHOD
EnableDragDrop(bool aEnable
);
144 NS_IMETHOD
CaptureMouse(bool aCapture
);
145 NS_IMETHOD
CaptureRollupEvents(nsIRollupListener
*aListener
,
147 NS_IMETHOD
GetAttention(int32_t aCycleCount
);
149 virtual bool HasPendingInputEvent();
151 NS_IMETHOD
MakeFullScreen(bool aFullScreen
);
152 NS_IMETHOD
HideWindowChrome(bool aShouldHide
);
155 * GetLastUserInputTime returns a timestamp for the most recent user input
156 * event. This is intended for pointer grab requests (including drags).
158 static guint32
GetLastUserInputTime();
160 // utility method, -1 if no change should be made, otherwise returns a
161 // value that can be passed to gdk_window_set_decorations
162 gint
ConvertBorderStyles(nsBorderStyle aStyle
);
165 #if (MOZ_WIDGET_GTK == 2)
166 gboolean
OnExposeEvent(GdkEventExpose
*aEvent
);
168 gboolean
OnExposeEvent(cairo_t
*cr
);
170 gboolean
OnConfigureEvent(GtkWidget
*aWidget
,
171 GdkEventConfigure
*aEvent
);
172 void OnContainerUnrealize();
173 void OnSizeAllocate(GtkAllocation
*aAllocation
);
174 void OnDeleteEvent();
175 void OnEnterNotifyEvent(GdkEventCrossing
*aEvent
);
176 void OnLeaveNotifyEvent(GdkEventCrossing
*aEvent
);
177 void OnMotionNotifyEvent(GdkEventMotion
*aEvent
);
178 void OnButtonPressEvent(GdkEventButton
*aEvent
);
179 void OnButtonReleaseEvent(GdkEventButton
*aEvent
);
180 void OnContainerFocusInEvent(GdkEventFocus
*aEvent
);
181 void OnContainerFocusOutEvent(GdkEventFocus
*aEvent
);
182 gboolean
OnKeyPressEvent(GdkEventKey
*aEvent
);
183 gboolean
OnKeyReleaseEvent(GdkEventKey
*aEvent
);
184 void OnScrollEvent(GdkEventScroll
*aEvent
);
185 void OnVisibilityNotifyEvent(GdkEventVisibility
*aEvent
);
186 void OnWindowStateEvent(GtkWidget
*aWidget
,
187 GdkEventWindowState
*aEvent
);
188 void OnDragDataReceivedEvent(GtkWidget
*aWidget
,
189 GdkDragContext
*aDragContext
,
192 GtkSelectionData
*aSelectionData
,
197 mozilla::TemporaryRef
<mozilla::gfx::DrawTarget
> StartRemoteDrawing() MOZ_OVERRIDE
;
200 void UpdateAlpha(gfxPattern
* aPattern
, nsIntRect aBoundsRect
);
202 void NativeResize(int32_t aWidth
,
206 void NativeResize(int32_t aX
,
212 void NativeShow (bool aAction
);
213 void SetHasMappedToplevel(bool aState
);
214 nsIntSize
GetSafeWindowSize(nsIntSize aSize
);
216 void EnsureGrabs (void);
217 void GrabPointer (guint32 aTime
);
218 void ReleaseGrabs (void);
222 PluginType_NONE
= 0, /* do not have any plugin */
223 PluginType_XEMBED
, /* the plugin support xembed */
224 PluginType_NONXEMBED
/* the plugin does not support xembed */
227 void SetPluginType(PluginType aPluginType
);
229 void SetNonXEmbedPluginFocus(void);
230 void LoseNonXEmbedPluginFocus(void);
233 void ThemeChanged(void);
236 Window mOldFocusWindow
;
239 static guint32 sLastButtonPressTime
;
241 NS_IMETHOD
BeginResizeDrag(mozilla::WidgetGUIEvent
* aEvent
,
244 NS_IMETHOD
BeginMoveDrag(mozilla::WidgetMouseEvent
* aEvent
);
246 MozContainer
* GetMozContainer() { return mContainer
; }
247 // GetMozContainerWidget returns the MozContainer even for undestroyed
248 // descendant windows
249 GtkWidget
* GetMozContainerWidget();
250 GdkWindow
* GetGdkWindow() { return mGdkWindow
; }
251 bool IsDestroyed() { return mIsDestroyed
; }
253 void DispatchDragEvent(uint32_t aMsg
,
254 const nsIntPoint
& aRefPoint
,
256 static void UpdateDragStatus (GdkDragContext
*aDragContext
,
257 nsIDragService
*aDragService
);
258 // If this dispatched the keydown event actually, this returns TRUE,
260 bool DispatchKeyDownEvent(GdkEventKey
*aEvent
,
263 NS_IMETHOD
NotifyIME(const IMENotification
& aIMENotification
) MOZ_OVERRIDE
;
264 NS_IMETHOD_(void) SetInputContext(const InputContext
& aContext
,
265 const InputContextAction
& aAction
);
266 NS_IMETHOD_(InputContext
) GetInputContext();
267 NS_IMETHOD_(bool) ExecuteNativeKeyBinding(
268 NativeKeyBindingsType aType
,
269 const mozilla::WidgetKeyboardEvent
& aEvent
,
270 DoCommandCallback aCallback
,
271 void* aCallbackData
) MOZ_OVERRIDE
;
272 NS_IMETHOD
GetToggledKeyState(uint32_t aKeyCode
, bool* aLEDState
);
274 // These methods are for toplevel windows only.
275 void ResizeTransparencyBitmap();
276 void ApplyTransparencyBitmap();
277 void ClearTransparencyBitmap();
279 virtual void SetTransparencyMode(nsTransparencyMode aMode
);
280 virtual nsTransparencyMode
GetTransparencyMode();
281 virtual nsresult
ConfigureChildren(const nsTArray
<Configuration
>& aConfigurations
);
282 nsresult
UpdateTranslucentWindowAlphaInternal(const nsIntRect
& aRect
,
283 uint8_t* aAlphas
, int32_t aStride
);
284 virtual gfxASurface
*GetThebesSurface();
286 #if (MOZ_WIDGET_GTK == 2)
287 static already_AddRefed
<gfxASurface
> GetSurfaceForGdkDrawable(GdkDrawable
* aDrawable
,
288 const nsIntSize
& aSize
);
290 NS_IMETHOD
ReparentNativeWidget(nsIWidget
* aNewParent
);
292 virtual nsresult
SynthesizeNativeMouseEvent(nsIntPoint aPoint
,
293 uint32_t aNativeMessage
,
294 uint32_t aModifierFlags
);
296 virtual nsresult
SynthesizeNativeMouseMove(nsIntPoint aPoint
)
297 { return SynthesizeNativeMouseEvent(aPoint
, GDK_MOTION_NOTIFY
, 0); }
302 // event handling code
303 void DispatchActivateEvent(void);
304 void DispatchDeactivateEvent(void);
305 void DispatchResized(int32_t aWidth
, int32_t aHeight
);
307 // Helper for SetParent and ReparentNativeWidget.
308 void ReparentNativeWidgetInternal(nsIWidget
* aNewParent
,
309 GtkWidget
* aNewContainer
,
310 GdkWindow
* aNewParentWindow
,
311 GtkWidget
* aOldContainer
);
312 nsCOMPtr
<nsIWidget
> mParent
;
313 // Is this a toplevel window?
315 // Has this widget been destroyed yet?
318 // This is a flag that tracks if we need to resize a widget or
319 // window when we show it.
321 // This is a flag that tracks if we need to move a widget or
322 // window when we show it.
324 // Should we send resize events on all resizes?
325 bool mListenForResizes
;
326 // This flag tracks if we're hidden or shown.
329 // is this widget enabled?
331 // has the native window for this been created yet?
335 void DestroyChildWindows();
336 GtkWidget
*GetToplevelWidget();
337 nsWindow
*GetContainerWindow();
338 void SetUrgencyHint(GtkWidget
*top_window
, bool state
);
339 void *SetupPluginPort(void);
340 void SetDefaultIcon(void);
341 void InitButtonEvent(mozilla::WidgetMouseEvent
& aEvent
,
342 GdkEventButton
* aGdkEvent
);
343 bool DispatchCommandEvent(nsIAtom
* aCommand
);
344 bool DispatchContentCommandEvent(int32_t aMsg
);
345 void SetWindowClipRegion(const nsTArray
<nsIntRect
>& aRects
,
346 bool aIntersectWithExisting
);
347 bool CheckForRollup(gdouble aMouseX
, gdouble aMouseY
,
348 bool aIsWheel
, bool aAlwaysRollup
);
349 bool GetDragInfo(mozilla::WidgetMouseEvent
* aMouseEvent
,
350 GdkWindow
** aWindow
, gint
* aButton
,
351 gint
* aRootX
, gint
* aRootY
);
352 void ClearCachedResources();
355 MozContainer
*mContainer
;
356 GdkWindow
*mGdkWindow
;
358 uint32_t mHasMappedToplevel
: 1,
359 mIsFullyObscured
: 1,
360 mRetryPointerGrab
: 1;
361 nsSizeMode mSizeState
;
362 PluginType mPluginType
;
364 int32_t mTransparencyBitmapWidth
;
365 int32_t mTransparencyBitmapHeight
;
367 #if GTK_CHECK_VERSION(3,4,0)
368 // This field omits duplicate scroll events caused by GNOME bug 726878.
369 guint32 mLastScrollEventTime
;
372 #ifdef MOZ_HAVE_SHMIMAGE
373 // If we're using xshm rendering, mThebesSurface wraps mShmImage
374 nsRefPtr
<nsShmImage
> mShmImage
;
376 nsRefPtr
<gfxASurface
> mThebesSurface
;
379 nsRefPtr
<mozilla::a11y::Accessible
> mRootAccessible
;
382 * Request to create the accessible for this window if it is top level.
384 void CreateRootAccessible();
387 * Dispatch accessible event for the top level window accessible.
389 * @param aEventType [in] the accessible event type to dispatch
391 void DispatchEventToRootAccessible(uint32_t aEventType
);
394 * Dispatch accessible window activate event for the top level window
397 void DispatchActivateEventAccessible();
400 * Dispatch accessible window deactivate event for the top level window
403 void DispatchDeactivateEventAccessible();
406 * Dispatch accessible window maximize event for the top level window
409 void DispatchMaximizeEventAccessible();
412 * Dispatch accessible window minize event for the top level window
415 void DispatchMinimizeEventAccessible();
418 * Dispatch accessible window restore event for the top level window
421 void DispatchRestoreEventAccessible();
425 static GdkCursor
*gsGtkCursorCache
[eCursorCount
];
429 // This bitmap tracks which pixels are transparent. We don't support
430 // full translucency at this time; each pixel is either fully opaque
431 // or fully transparent.
432 gchar
* mTransparencyBitmap
;
434 // all of our DND stuff
435 void InitDragEvent(mozilla::WidgetDragEvent
& aEvent
);
437 float mLastMotionPressure
;
439 // Remember the last sizemode so that we can restore it when
440 // leaving fullscreen
441 nsSizeMode mLastSizeMode
;
443 static bool DragInProgress(void);
445 void DispatchMissedButtonReleases(GdkEventCrossing
*aGdkEvent
);
448 virtual LayerManager
* GetLayerManager(PLayerTransactionChild
* aShadowManager
= nullptr,
449 LayersBackend aBackendHint
= mozilla::layers::LayersBackend::LAYERS_NONE
,
450 LayerManagerPersistence aPersistence
= LAYER_MANAGER_CURRENT
,
451 bool* aAllowRetaining
= nullptr) MOZ_OVERRIDE
;
452 #if (MOZ_WIDGET_GTK == 3)
453 gfxASurface
* GetThebesSurface(cairo_t
*cr
);
456 void CleanLayerManagerRecursive();
459 * |mIMModule| takes all IME related stuff.
461 * This is owned by the top-level nsWindow or the topmost child
462 * nsWindow embedded in a non-Gecko widget.
464 * The instance is created when the top level widget is created. And when
465 * the widget is destroyed, it's released. All child windows refer its
466 * ancestor widget's instance. So, one set of IM contexts is created for
467 * all windows in a hierarchy. If the children are released after the top
468 * level window is released, the children still have a valid pointer,
469 * however, IME doesn't work at that time.
471 nsRefPtr
<nsGtkIMModule
> mIMModule
;
474 class nsChildWindow
: public nsWindow
{
480 #endif /* __nsWindow_h__ */