|
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/. */ |
|
7 |
|
8 #ifndef __nsWindow_h__ |
|
9 #define __nsWindow_h__ |
|
10 |
|
11 #include "mozilla/ipc/SharedMemorySysV.h" |
|
12 |
|
13 #include "nsAutoPtr.h" |
|
14 |
|
15 #include "mozcontainer.h" |
|
16 #include "nsWeakReference.h" |
|
17 |
|
18 #include "nsIDragService.h" |
|
19 #include "nsITimer.h" |
|
20 #include "nsGkAtoms.h" |
|
21 |
|
22 #include "nsBaseWidget.h" |
|
23 #include <gdk/gdk.h> |
|
24 #include <gtk/gtk.h> |
|
25 |
|
26 #ifdef MOZ_X11 |
|
27 #include <gdk/gdkx.h> |
|
28 #endif /* MOZ_X11 */ |
|
29 |
|
30 #ifdef ACCESSIBILITY |
|
31 #include "mozilla/a11y/Accessible.h" |
|
32 #endif |
|
33 #include "mozilla/EventForwards.h" |
|
34 |
|
35 #include "nsGtkIMModule.h" |
|
36 |
|
37 #undef LOG |
|
38 #ifdef MOZ_LOGGING |
|
39 |
|
40 // make sure that logging is enabled before including prlog.h |
|
41 #define FORCE_PR_LOG |
|
42 |
|
43 #include "prlog.h" |
|
44 #include "nsTArray.h" |
|
45 |
|
46 extern PRLogModuleInfo *gWidgetLog; |
|
47 extern PRLogModuleInfo *gWidgetFocusLog; |
|
48 extern PRLogModuleInfo *gWidgetDragLog; |
|
49 extern PRLogModuleInfo *gWidgetDrawLog; |
|
50 |
|
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) |
|
55 |
|
56 #else |
|
57 |
|
58 #define LOG(args) |
|
59 #define LOGFOCUS(args) |
|
60 #define LOGDRAG(args) |
|
61 #define LOGDRAW(args) |
|
62 |
|
63 #endif /* MOZ_LOGGING */ |
|
64 |
|
65 class gfxASurface; |
|
66 class gfxPattern; |
|
67 class nsDragService; |
|
68 #if defined(MOZ_X11) && defined(MOZ_HAVE_SHAREDMEMORYSYSV) |
|
69 # define MOZ_HAVE_SHMIMAGE |
|
70 |
|
71 class nsShmImage; |
|
72 #endif |
|
73 |
|
74 class nsWindow : public nsBaseWidget, public nsSupportsWeakReference |
|
75 { |
|
76 public: |
|
77 nsWindow(); |
|
78 virtual ~nsWindow(); |
|
79 |
|
80 static void ReleaseGlobals(); |
|
81 |
|
82 NS_DECL_ISUPPORTS_INHERITED |
|
83 |
|
84 void CommonCreate(nsIWidget *aParent, bool aListenForResizes); |
|
85 |
|
86 virtual nsresult DispatchEvent(mozilla::WidgetGUIEvent* aEvent, |
|
87 nsEventStatus& aStatus); |
|
88 |
|
89 // called when we are destroyed |
|
90 void OnDestroy(void); |
|
91 |
|
92 // called to check and see if a widget's dimensions are sane |
|
93 bool AreBoundsSane(void); |
|
94 |
|
95 // nsIWidget |
|
96 NS_IMETHOD Create(nsIWidget *aParent, |
|
97 nsNativeWidget aNativeParent, |
|
98 const nsIntRect &aRect, |
|
99 nsDeviceContext *aContext, |
|
100 nsWidgetInitData *aInitData); |
|
101 NS_IMETHOD Destroy(void); |
|
102 virtual nsIWidget *GetParent(); |
|
103 virtual float GetDPI(); |
|
104 virtual nsresult SetParent(nsIWidget* aNewParent); |
|
105 NS_IMETHOD SetModal(bool aModal); |
|
106 virtual bool IsVisible() const; |
|
107 NS_IMETHOD ConstrainPosition(bool aAllowSlop, |
|
108 int32_t *aX, |
|
109 int32_t *aY); |
|
110 virtual void SetSizeConstraints(const SizeConstraints& aConstraints); |
|
111 NS_IMETHOD Move(double aX, |
|
112 double aY); |
|
113 NS_IMETHOD Show (bool aState); |
|
114 NS_IMETHOD Resize (double aWidth, |
|
115 double aHeight, |
|
116 bool aRepaint); |
|
117 NS_IMETHOD Resize (double aX, |
|
118 double aY, |
|
119 double aWidth, |
|
120 double aHeight, |
|
121 bool aRepaint); |
|
122 virtual bool IsEnabled() const; |
|
123 |
|
124 |
|
125 NS_IMETHOD PlaceBehind(nsTopLevelWidgetZPlacement aPlacement, |
|
126 nsIWidget *aWidget, |
|
127 bool aActivate); |
|
128 void SetZIndex(int32_t aZIndex); |
|
129 NS_IMETHOD SetSizeMode(int32_t aMode); |
|
130 NS_IMETHOD Enable(bool aState); |
|
131 NS_IMETHOD SetFocus(bool aRaise = false); |
|
132 NS_IMETHOD GetScreenBounds(nsIntRect &aRect); |
|
133 NS_IMETHOD GetClientBounds(nsIntRect &aRect); |
|
134 virtual nsIntPoint GetClientOffset(); |
|
135 NS_IMETHOD SetCursor(nsCursor aCursor); |
|
136 NS_IMETHOD SetCursor(imgIContainer* aCursor, |
|
137 uint32_t aHotspotX, uint32_t aHotspotY); |
|
138 NS_IMETHOD Invalidate(const nsIntRect &aRect); |
|
139 virtual void* GetNativeData(uint32_t aDataType); |
|
140 NS_IMETHOD SetTitle(const nsAString& aTitle); |
|
141 NS_IMETHOD SetIcon(const nsAString& aIconSpec); |
|
142 NS_IMETHOD SetWindowClass(const nsAString& xulWinType); |
|
143 virtual nsIntPoint WidgetToScreenOffset(); |
|
144 NS_IMETHOD EnableDragDrop(bool aEnable); |
|
145 NS_IMETHOD CaptureMouse(bool aCapture); |
|
146 NS_IMETHOD CaptureRollupEvents(nsIRollupListener *aListener, |
|
147 bool aDoCapture); |
|
148 NS_IMETHOD GetAttention(int32_t aCycleCount); |
|
149 |
|
150 virtual bool HasPendingInputEvent(); |
|
151 |
|
152 NS_IMETHOD MakeFullScreen(bool aFullScreen); |
|
153 NS_IMETHOD HideWindowChrome(bool aShouldHide); |
|
154 |
|
155 /** |
|
156 * GetLastUserInputTime returns a timestamp for the most recent user input |
|
157 * event. This is intended for pointer grab requests (including drags). |
|
158 */ |
|
159 static guint32 GetLastUserInputTime(); |
|
160 |
|
161 // utility method, -1 if no change should be made, otherwise returns a |
|
162 // value that can be passed to gdk_window_set_decorations |
|
163 gint ConvertBorderStyles(nsBorderStyle aStyle); |
|
164 |
|
165 // event callbacks |
|
166 #if (MOZ_WIDGET_GTK == 2) |
|
167 gboolean OnExposeEvent(GdkEventExpose *aEvent); |
|
168 #else |
|
169 gboolean OnExposeEvent(cairo_t *cr); |
|
170 #endif |
|
171 gboolean OnConfigureEvent(GtkWidget *aWidget, |
|
172 GdkEventConfigure *aEvent); |
|
173 void OnContainerUnrealize(); |
|
174 void OnSizeAllocate(GtkAllocation *aAllocation); |
|
175 void OnDeleteEvent(); |
|
176 void OnEnterNotifyEvent(GdkEventCrossing *aEvent); |
|
177 void OnLeaveNotifyEvent(GdkEventCrossing *aEvent); |
|
178 void OnMotionNotifyEvent(GdkEventMotion *aEvent); |
|
179 void OnButtonPressEvent(GdkEventButton *aEvent); |
|
180 void OnButtonReleaseEvent(GdkEventButton *aEvent); |
|
181 void OnContainerFocusInEvent(GdkEventFocus *aEvent); |
|
182 void OnContainerFocusOutEvent(GdkEventFocus *aEvent); |
|
183 gboolean OnKeyPressEvent(GdkEventKey *aEvent); |
|
184 gboolean OnKeyReleaseEvent(GdkEventKey *aEvent); |
|
185 void OnScrollEvent(GdkEventScroll *aEvent); |
|
186 void OnVisibilityNotifyEvent(GdkEventVisibility *aEvent); |
|
187 void OnWindowStateEvent(GtkWidget *aWidget, |
|
188 GdkEventWindowState *aEvent); |
|
189 void OnDragDataReceivedEvent(GtkWidget *aWidget, |
|
190 GdkDragContext *aDragContext, |
|
191 gint aX, |
|
192 gint aY, |
|
193 GtkSelectionData*aSelectionData, |
|
194 guint aInfo, |
|
195 guint aTime, |
|
196 gpointer aData); |
|
197 |
|
198 mozilla::TemporaryRef<mozilla::gfx::DrawTarget> StartRemoteDrawing() MOZ_OVERRIDE; |
|
199 |
|
200 private: |
|
201 void UpdateAlpha(gfxPattern* aPattern, nsIntRect aBoundsRect); |
|
202 |
|
203 void NativeResize(int32_t aWidth, |
|
204 int32_t aHeight, |
|
205 bool aRepaint); |
|
206 |
|
207 void NativeResize(int32_t aX, |
|
208 int32_t aY, |
|
209 int32_t aWidth, |
|
210 int32_t aHeight, |
|
211 bool aRepaint); |
|
212 |
|
213 void NativeShow (bool aAction); |
|
214 void SetHasMappedToplevel(bool aState); |
|
215 nsIntSize GetSafeWindowSize(nsIntSize aSize); |
|
216 |
|
217 void EnsureGrabs (void); |
|
218 void GrabPointer (guint32 aTime); |
|
219 void ReleaseGrabs (void); |
|
220 |
|
221 public: |
|
222 enum PluginType { |
|
223 PluginType_NONE = 0, /* do not have any plugin */ |
|
224 PluginType_XEMBED, /* the plugin support xembed */ |
|
225 PluginType_NONXEMBED /* the plugin does not support xembed */ |
|
226 }; |
|
227 |
|
228 void SetPluginType(PluginType aPluginType); |
|
229 #ifdef MOZ_X11 |
|
230 void SetNonXEmbedPluginFocus(void); |
|
231 void LoseNonXEmbedPluginFocus(void); |
|
232 #endif /* MOZ_X11 */ |
|
233 |
|
234 void ThemeChanged(void); |
|
235 |
|
236 #ifdef MOZ_X11 |
|
237 Window mOldFocusWindow; |
|
238 #endif /* MOZ_X11 */ |
|
239 |
|
240 static guint32 sLastButtonPressTime; |
|
241 |
|
242 NS_IMETHOD BeginResizeDrag(mozilla::WidgetGUIEvent* aEvent, |
|
243 int32_t aHorizontal, |
|
244 int32_t aVertical); |
|
245 NS_IMETHOD BeginMoveDrag(mozilla::WidgetMouseEvent* aEvent); |
|
246 |
|
247 MozContainer* GetMozContainer() { return mContainer; } |
|
248 // GetMozContainerWidget returns the MozContainer even for undestroyed |
|
249 // descendant windows |
|
250 GtkWidget* GetMozContainerWidget(); |
|
251 GdkWindow* GetGdkWindow() { return mGdkWindow; } |
|
252 bool IsDestroyed() { return mIsDestroyed; } |
|
253 |
|
254 void DispatchDragEvent(uint32_t aMsg, |
|
255 const nsIntPoint& aRefPoint, |
|
256 guint aTime); |
|
257 static void UpdateDragStatus (GdkDragContext *aDragContext, |
|
258 nsIDragService *aDragService); |
|
259 // If this dispatched the keydown event actually, this returns TRUE, |
|
260 // otherwise, FALSE. |
|
261 bool DispatchKeyDownEvent(GdkEventKey *aEvent, |
|
262 bool *aIsCancelled); |
|
263 |
|
264 NS_IMETHOD NotifyIME(const IMENotification& aIMENotification) MOZ_OVERRIDE; |
|
265 NS_IMETHOD_(void) SetInputContext(const InputContext& aContext, |
|
266 const InputContextAction& aAction); |
|
267 NS_IMETHOD_(InputContext) GetInputContext(); |
|
268 NS_IMETHOD_(bool) ExecuteNativeKeyBinding( |
|
269 NativeKeyBindingsType aType, |
|
270 const mozilla::WidgetKeyboardEvent& aEvent, |
|
271 DoCommandCallback aCallback, |
|
272 void* aCallbackData) MOZ_OVERRIDE; |
|
273 NS_IMETHOD GetToggledKeyState(uint32_t aKeyCode, bool* aLEDState); |
|
274 |
|
275 // These methods are for toplevel windows only. |
|
276 void ResizeTransparencyBitmap(); |
|
277 void ApplyTransparencyBitmap(); |
|
278 void ClearTransparencyBitmap(); |
|
279 |
|
280 virtual void SetTransparencyMode(nsTransparencyMode aMode); |
|
281 virtual nsTransparencyMode GetTransparencyMode(); |
|
282 virtual nsresult ConfigureChildren(const nsTArray<Configuration>& aConfigurations); |
|
283 nsresult UpdateTranslucentWindowAlphaInternal(const nsIntRect& aRect, |
|
284 uint8_t* aAlphas, int32_t aStride); |
|
285 |
|
286 #if (MOZ_WIDGET_GTK == 2) |
|
287 gfxASurface *GetThebesSurface(); |
|
288 |
|
289 static already_AddRefed<gfxASurface> GetSurfaceForGdkDrawable(GdkDrawable* aDrawable, |
|
290 const nsIntSize& aSize); |
|
291 #else |
|
292 gfxASurface *GetThebesSurface(cairo_t *cr); |
|
293 #endif |
|
294 NS_IMETHOD ReparentNativeWidget(nsIWidget* aNewParent); |
|
295 |
|
296 virtual nsresult SynthesizeNativeMouseEvent(nsIntPoint aPoint, |
|
297 uint32_t aNativeMessage, |
|
298 uint32_t aModifierFlags); |
|
299 |
|
300 virtual nsresult SynthesizeNativeMouseMove(nsIntPoint aPoint) |
|
301 { return SynthesizeNativeMouseEvent(aPoint, GDK_MOTION_NOTIFY, 0); } |
|
302 |
|
303 protected: |
|
304 // event handling code |
|
305 void DispatchActivateEvent(void); |
|
306 void DispatchDeactivateEvent(void); |
|
307 void DispatchResized(int32_t aWidth, int32_t aHeight); |
|
308 |
|
309 // Helper for SetParent and ReparentNativeWidget. |
|
310 void ReparentNativeWidgetInternal(nsIWidget* aNewParent, |
|
311 GtkWidget* aNewContainer, |
|
312 GdkWindow* aNewParentWindow, |
|
313 GtkWidget* aOldContainer); |
|
314 nsCOMPtr<nsIWidget> mParent; |
|
315 // Is this a toplevel window? |
|
316 bool mIsTopLevel; |
|
317 // Has this widget been destroyed yet? |
|
318 bool mIsDestroyed; |
|
319 |
|
320 // This is a flag that tracks if we need to resize a widget or |
|
321 // window when we show it. |
|
322 bool mNeedsResize; |
|
323 // This is a flag that tracks if we need to move a widget or |
|
324 // window when we show it. |
|
325 bool mNeedsMove; |
|
326 // Should we send resize events on all resizes? |
|
327 bool mListenForResizes; |
|
328 // This flag tracks if we're hidden or shown. |
|
329 bool mIsShown; |
|
330 bool mNeedsShow; |
|
331 // is this widget enabled? |
|
332 bool mEnabled; |
|
333 // has the native window for this been created yet? |
|
334 bool mCreated; |
|
335 |
|
336 private: |
|
337 void DestroyChildWindows(); |
|
338 GtkWidget *GetToplevelWidget(); |
|
339 nsWindow *GetContainerWindow(); |
|
340 void SetUrgencyHint(GtkWidget *top_window, bool state); |
|
341 void *SetupPluginPort(void); |
|
342 void SetDefaultIcon(void); |
|
343 void InitButtonEvent(mozilla::WidgetMouseEvent& aEvent, |
|
344 GdkEventButton* aGdkEvent); |
|
345 bool DispatchCommandEvent(nsIAtom* aCommand); |
|
346 bool DispatchContentCommandEvent(int32_t aMsg); |
|
347 void SetWindowClipRegion(const nsTArray<nsIntRect>& aRects, |
|
348 bool aIntersectWithExisting); |
|
349 bool CheckForRollup(gdouble aMouseX, gdouble aMouseY, |
|
350 bool aIsWheel, bool aAlwaysRollup); |
|
351 bool GetDragInfo(mozilla::WidgetMouseEvent* aMouseEvent, |
|
352 GdkWindow** aWindow, gint* aButton, |
|
353 gint* aRootX, gint* aRootY); |
|
354 void ClearCachedResources(); |
|
355 |
|
356 GtkWidget *mShell; |
|
357 MozContainer *mContainer; |
|
358 GdkWindow *mGdkWindow; |
|
359 |
|
360 uint32_t mHasMappedToplevel : 1, |
|
361 mIsFullyObscured : 1, |
|
362 mRetryPointerGrab : 1; |
|
363 nsSizeMode mSizeState; |
|
364 PluginType mPluginType; |
|
365 |
|
366 int32_t mTransparencyBitmapWidth; |
|
367 int32_t mTransparencyBitmapHeight; |
|
368 |
|
369 #ifdef MOZ_HAVE_SHMIMAGE |
|
370 // If we're using xshm rendering, mThebesSurface wraps mShmImage |
|
371 nsRefPtr<nsShmImage> mShmImage; |
|
372 #endif |
|
373 nsRefPtr<gfxASurface> mThebesSurface; |
|
374 |
|
375 #ifdef ACCESSIBILITY |
|
376 nsRefPtr<mozilla::a11y::Accessible> mRootAccessible; |
|
377 |
|
378 /** |
|
379 * Request to create the accessible for this window if it is top level. |
|
380 */ |
|
381 void CreateRootAccessible(); |
|
382 |
|
383 /** |
|
384 * Dispatch accessible event for the top level window accessible. |
|
385 * |
|
386 * @param aEventType [in] the accessible event type to dispatch |
|
387 */ |
|
388 void DispatchEventToRootAccessible(uint32_t aEventType); |
|
389 |
|
390 /** |
|
391 * Dispatch accessible window activate event for the top level window |
|
392 * accessible. |
|
393 */ |
|
394 void DispatchActivateEventAccessible(); |
|
395 |
|
396 /** |
|
397 * Dispatch accessible window deactivate event for the top level window |
|
398 * accessible. |
|
399 */ |
|
400 void DispatchDeactivateEventAccessible(); |
|
401 |
|
402 /** |
|
403 * Dispatch accessible window maximize event for the top level window |
|
404 * accessible. |
|
405 */ |
|
406 void DispatchMaximizeEventAccessible(); |
|
407 |
|
408 /** |
|
409 * Dispatch accessible window minize event for the top level window |
|
410 * accessible. |
|
411 */ |
|
412 void DispatchMinimizeEventAccessible(); |
|
413 |
|
414 /** |
|
415 * Dispatch accessible window restore event for the top level window |
|
416 * accessible. |
|
417 */ |
|
418 void DispatchRestoreEventAccessible(); |
|
419 #endif |
|
420 |
|
421 // The cursor cache |
|
422 static GdkCursor *gsGtkCursorCache[eCursorCount]; |
|
423 |
|
424 // Transparency |
|
425 bool mIsTransparent; |
|
426 // This bitmap tracks which pixels are transparent. We don't support |
|
427 // full translucency at this time; each pixel is either fully opaque |
|
428 // or fully transparent. |
|
429 gchar* mTransparencyBitmap; |
|
430 |
|
431 // all of our DND stuff |
|
432 void InitDragEvent(mozilla::WidgetDragEvent& aEvent); |
|
433 |
|
434 float mLastMotionPressure; |
|
435 |
|
436 // Remember the last sizemode so that we can restore it when |
|
437 // leaving fullscreen |
|
438 nsSizeMode mLastSizeMode; |
|
439 |
|
440 static bool DragInProgress(void); |
|
441 |
|
442 void DispatchMissedButtonReleases(GdkEventCrossing *aGdkEvent); |
|
443 |
|
444 // nsBaseWidget |
|
445 virtual LayerManager* GetLayerManager(PLayerTransactionChild* aShadowManager = nullptr, |
|
446 LayersBackend aBackendHint = mozilla::layers::LayersBackend::LAYERS_NONE, |
|
447 LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT, |
|
448 bool* aAllowRetaining = nullptr) MOZ_OVERRIDE; |
|
449 |
|
450 void CleanLayerManagerRecursive(); |
|
451 |
|
452 /** |
|
453 * |mIMModule| takes all IME related stuff. |
|
454 * |
|
455 * This is owned by the top-level nsWindow or the topmost child |
|
456 * nsWindow embedded in a non-Gecko widget. |
|
457 * |
|
458 * The instance is created when the top level widget is created. And when |
|
459 * the widget is destroyed, it's released. All child windows refer its |
|
460 * ancestor widget's instance. So, one set of IM contexts is created for |
|
461 * all windows in a hierarchy. If the children are released after the top |
|
462 * level window is released, the children still have a valid pointer, |
|
463 * however, IME doesn't work at that time. |
|
464 */ |
|
465 nsRefPtr<nsGtkIMModule> mIMModule; |
|
466 }; |
|
467 |
|
468 class nsChildWindow : public nsWindow { |
|
469 public: |
|
470 nsChildWindow(); |
|
471 ~nsChildWindow(); |
|
472 }; |
|
473 |
|
474 #endif /* __nsWindow_h__ */ |