widget/xpwidgets/nsBaseWidget.h

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:02efac125dce
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #ifndef nsBaseWidget_h__
6 #define nsBaseWidget_h__
7
8 #include "mozilla/EventForwards.h"
9 #include "mozilla/WidgetUtils.h"
10 #include "nsRect.h"
11 #include "nsIWidget.h"
12 #include "nsWidgetsCID.h"
13 #include "nsIFile.h"
14 #include "nsString.h"
15 #include "nsCOMPtr.h"
16 #include "nsAutoPtr.h"
17 #include "nsIRollupListener.h"
18 #include "nsIObserver.h"
19 #include "nsIWidgetListener.h"
20 #include "nsPIDOMWindow.h"
21 #include <algorithm>
22 class nsIContent;
23 class nsAutoRollup;
24 class gfxContext;
25
26 namespace mozilla {
27 #ifdef ACCESSIBILITY
28 namespace a11y {
29 class Accessible;
30 }
31 #endif
32
33 namespace layers {
34 class BasicLayerManager;
35 class CompositorChild;
36 class CompositorParent;
37 }
38 }
39
40 namespace base {
41 class Thread;
42 }
43
44 // Windows specific constant indicating the maximum number of touch points the
45 // inject api will allow. This also sets the maximum numerical value for touch
46 // ids we can use when injecting touch points on Windows.
47 #define TOUCH_INJECT_MAX_POINTS 256
48
49 class nsBaseWidget;
50
51 class WidgetShutdownObserver MOZ_FINAL : public nsIObserver
52 {
53 public:
54 WidgetShutdownObserver(nsBaseWidget* aWidget)
55 : mWidget(aWidget)
56 { }
57
58 NS_DECL_ISUPPORTS
59 NS_DECL_NSIOBSERVER
60
61 nsBaseWidget *mWidget;
62 };
63
64 /**
65 * Common widget implementation used as base class for native
66 * or crossplatform implementations of Widgets.
67 * All cross-platform behavior that all widgets need to implement
68 * should be placed in this class.
69 * (Note: widget implementations are not required to use this
70 * class, but it gives them a head start.)
71 */
72
73 class nsBaseWidget : public nsIWidget
74 {
75 friend class nsAutoRollup;
76
77 protected:
78 typedef base::Thread Thread;
79 typedef mozilla::layers::BasicLayerManager BasicLayerManager;
80 typedef mozilla::layers::BufferMode BufferMode;
81 typedef mozilla::layers::CompositorChild CompositorChild;
82 typedef mozilla::layers::CompositorParent CompositorParent;
83 typedef mozilla::ScreenRotation ScreenRotation;
84
85 public:
86 nsBaseWidget();
87 virtual ~nsBaseWidget();
88
89 NS_DECL_ISUPPORTS
90
91 // nsIWidget interface
92 NS_IMETHOD CaptureMouse(bool aCapture);
93 virtual nsIWidgetListener* GetWidgetListener();
94 virtual void SetWidgetListener(nsIWidgetListener* alistener);
95 NS_IMETHOD Destroy();
96 NS_IMETHOD SetParent(nsIWidget* aNewParent);
97 virtual nsIWidget* GetParent(void);
98 virtual nsIWidget* GetTopLevelWidget();
99 virtual nsIWidget* GetSheetWindowParent(void);
100 virtual float GetDPI();
101 virtual void AddChild(nsIWidget* aChild);
102 virtual void RemoveChild(nsIWidget* aChild);
103
104 void SetZIndex(int32_t aZIndex);
105 NS_IMETHOD PlaceBehind(nsTopLevelWidgetZPlacement aPlacement,
106 nsIWidget *aWidget, bool aActivate);
107
108 NS_IMETHOD SetSizeMode(int32_t aMode);
109 virtual int32_t SizeMode() MOZ_OVERRIDE
110 {
111 return mSizeMode;
112 }
113
114 virtual nsCursor GetCursor();
115 NS_IMETHOD SetCursor(nsCursor aCursor);
116 NS_IMETHOD SetCursor(imgIContainer* aCursor,
117 uint32_t aHotspotX, uint32_t aHotspotY);
118 virtual void SetTransparencyMode(nsTransparencyMode aMode);
119 virtual nsTransparencyMode GetTransparencyMode();
120 virtual void GetWindowClipRegion(nsTArray<nsIntRect>* aRects);
121 NS_IMETHOD SetWindowShadowStyle(int32_t aStyle);
122 virtual void SetShowsToolbarButton(bool aShow) {}
123 virtual void SetShowsFullScreenButton(bool aShow) {}
124 virtual void SetWindowAnimationType(WindowAnimationType aType) {}
125 NS_IMETHOD HideWindowChrome(bool aShouldHide);
126 NS_IMETHOD MakeFullScreen(bool aFullScreen);
127 virtual nsDeviceContext* GetDeviceContext();
128 virtual LayerManager* GetLayerManager(PLayerTransactionChild* aShadowManager = nullptr,
129 LayersBackend aBackendHint = mozilla::layers::LayersBackend::LAYERS_NONE,
130 LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT,
131 bool* aAllowRetaining = nullptr);
132
133 virtual CompositorParent* NewCompositorParent(int aSurfaceWidth, int aSurfaceHeight);
134 virtual void CreateCompositor();
135 virtual void CreateCompositor(int aWidth, int aHeight);
136 virtual void PrepareWindowEffects() {}
137 virtual void CleanupWindowEffects() {}
138 virtual bool PreRender(LayerManagerComposite* aManager) { return true; }
139 virtual void PostRender(LayerManagerComposite* aManager) {}
140 virtual void DrawWindowUnderlay(LayerManagerComposite* aManager, nsIntRect aRect) {}
141 virtual void DrawWindowOverlay(LayerManagerComposite* aManager, nsIntRect aRect) {}
142 virtual mozilla::TemporaryRef<mozilla::gfx::DrawTarget> StartRemoteDrawing();
143 virtual void EndRemoteDrawing() { };
144 virtual void CleanupRemoteDrawing() { };
145 virtual void UpdateThemeGeometries(const nsTArray<ThemeGeometry>& aThemeGeometries) {}
146 virtual gfxASurface* GetThebesSurface();
147 NS_IMETHOD SetModal(bool aModal);
148 virtual uint32_t GetMaxTouchPoints() const;
149 NS_IMETHOD SetWindowClass(const nsAString& xulWinType);
150 // Return whether this widget interprets parameters to Move and Resize APIs
151 // as "global display pixels" rather than "device pixels", and therefore
152 // applies its GetDefaultScale() value to them before using them as mBounds
153 // etc (which are always stored in device pixels).
154 // Note that APIs that -get- the widget's position/size/bounds, rather than
155 // -setting- them (i.e. moving or resizing the widget) will always return
156 // values in the widget's device pixels.
157 bool BoundsUseDisplayPixels() const {
158 return mWindowType <= eWindowType_popup;
159 }
160 NS_IMETHOD MoveClient(double aX, double aY);
161 NS_IMETHOD ResizeClient(double aWidth, double aHeight, bool aRepaint);
162 NS_IMETHOD ResizeClient(double aX, double aY, double aWidth, double aHeight, bool aRepaint);
163 NS_IMETHOD GetBounds(nsIntRect &aRect);
164 NS_IMETHOD GetClientBounds(nsIntRect &aRect);
165 NS_IMETHOD GetScreenBounds(nsIntRect &aRect);
166 NS_IMETHOD GetNonClientMargins(nsIntMargin &margins);
167 NS_IMETHOD SetNonClientMargins(nsIntMargin &margins);
168 virtual nsIntPoint GetClientOffset();
169 NS_IMETHOD EnableDragDrop(bool aEnable);
170 NS_IMETHOD GetAttention(int32_t aCycleCount);
171 virtual bool HasPendingInputEvent();
172 NS_IMETHOD SetIcon(const nsAString &anIconSpec);
173 NS_IMETHOD SetWindowTitlebarColor(nscolor aColor, bool aActive);
174 virtual void SetDrawsInTitlebar(bool aState) {}
175 virtual bool ShowsResizeIndicator(nsIntRect* aResizerRect);
176 virtual void FreeNativeData(void * data, uint32_t aDataType) {}
177 NS_IMETHOD BeginResizeDrag(mozilla::WidgetGUIEvent* aEvent,
178 int32_t aHorizontal,
179 int32_t aVertical);
180 NS_IMETHOD BeginMoveDrag(mozilla::WidgetMouseEvent* aEvent);
181 virtual nsresult ActivateNativeMenuItemAt(const nsAString& indexString) { return NS_ERROR_NOT_IMPLEMENTED; }
182 virtual nsresult ForceUpdateNativeMenuAt(const nsAString& indexString) { return NS_ERROR_NOT_IMPLEMENTED; }
183 NS_IMETHOD NotifyIME(const IMENotification& aIMENotification) MOZ_OVERRIDE { return NS_ERROR_NOT_IMPLEMENTED; }
184 NS_IMETHOD AttachNativeKeyEvent(mozilla::WidgetKeyboardEvent& aEvent) MOZ_OVERRIDE { return NS_ERROR_NOT_IMPLEMENTED; }
185 NS_IMETHOD_(bool) ExecuteNativeKeyBinding(
186 NativeKeyBindingsType aType,
187 const mozilla::WidgetKeyboardEvent& aEvent,
188 DoCommandCallback aCallback,
189 void* aCallbackData) MOZ_OVERRIDE { return false; }
190 NS_IMETHOD SetLayersAcceleration(bool aEnabled);
191 virtual bool GetLayersAcceleration() { return mUseLayersAcceleration; }
192 virtual bool ComputeShouldAccelerate(bool aDefault);
193 NS_IMETHOD GetToggledKeyState(uint32_t aKeyCode, bool* aLEDState) { return NS_ERROR_NOT_IMPLEMENTED; }
194 virtual nsIMEUpdatePreference GetIMEUpdatePreference() MOZ_OVERRIDE { return nsIMEUpdatePreference(); }
195 NS_IMETHOD OnDefaultButtonLoaded(const nsIntRect &aButtonRect) { return NS_ERROR_NOT_IMPLEMENTED; }
196 NS_IMETHOD OverrideSystemMouseScrollSpeed(double aOriginalDeltaX,
197 double aOriginalDeltaY,
198 double& aOverriddenDeltaX,
199 double& aOverriddenDeltaY);
200 virtual already_AddRefed<nsIWidget>
201 CreateChild(const nsIntRect &aRect,
202 nsDeviceContext *aContext,
203 nsWidgetInitData *aInitData = nullptr,
204 bool aForceUseIWidgetParent = false);
205 NS_IMETHOD AttachViewToTopLevel(bool aUseAttachedEvents, nsDeviceContext *aContext);
206 virtual nsIWidgetListener* GetAttachedWidgetListener();
207 virtual void SetAttachedWidgetListener(nsIWidgetListener* aListener);
208 NS_IMETHOD RegisterTouchWindow();
209 NS_IMETHOD UnregisterTouchWindow();
210
211 void NotifyWindowDestroyed();
212 void NotifySizeMoveDone();
213 void NotifyWindowMoved(int32_t aX, int32_t aY);
214
215 // Should be called by derived implementations to notify on system color and
216 // theme changes.
217 void NotifySysColorChanged();
218 void NotifyThemeChanged();
219 void NotifyUIStateChanged(UIStateChangeType aShowAccelerators,
220 UIStateChangeType aShowFocusRings);
221
222 #ifdef ACCESSIBILITY
223 // Get the accessible for the window.
224 mozilla::a11y::Accessible* GetRootAccessible();
225 #endif
226
227 nsPopupLevel PopupLevel() { return mPopupLevel; }
228
229 virtual nsIntSize ClientToWindowSize(const nsIntSize& aClientSize)
230 {
231 return aClientSize;
232 }
233
234 // return true if this is a popup widget with a native titlebar
235 bool IsPopupWithTitleBar() const
236 {
237 return (mWindowType == eWindowType_popup &&
238 mBorderStyle != eBorderStyle_default &&
239 mBorderStyle & eBorderStyle_title);
240 }
241
242 NS_IMETHOD ReparentNativeWidget(nsIWidget* aNewParent) = 0;
243
244 virtual uint32_t GetGLFrameBufferFormat() MOZ_OVERRIDE;
245
246 virtual const SizeConstraints& GetSizeConstraints() const;
247 virtual void SetSizeConstraints(const SizeConstraints& aConstraints);
248
249 /**
250 * Use this when GetLayerManager() returns a BasicLayerManager
251 * (nsBaseWidget::GetLayerManager() does). This sets up the widget's
252 * layer manager to temporarily render into aTarget.
253 *
254 * |aNaturalWidgetBounds| is the un-rotated bounds of |aWidget|.
255 * |aRotation| is the "virtual rotation" to apply when rendering to
256 * the target. When |aRotation| is ROTATION_0,
257 * |aNaturalWidgetBounds| is not used.
258 */
259 class AutoLayerManagerSetup {
260 public:
261 AutoLayerManagerSetup(nsBaseWidget* aWidget, gfxContext* aTarget,
262 BufferMode aDoubleBuffering,
263 ScreenRotation aRotation = mozilla::ROTATION_0);
264 ~AutoLayerManagerSetup();
265 private:
266 nsBaseWidget* mWidget;
267 nsRefPtr<BasicLayerManager> mLayerManager;
268 };
269 friend class AutoLayerManagerSetup;
270
271 class AutoUseBasicLayerManager {
272 public:
273 AutoUseBasicLayerManager(nsBaseWidget* aWidget);
274 ~AutoUseBasicLayerManager();
275 private:
276 nsBaseWidget* mWidget;
277 bool mPreviousTemporarilyUseBasicLayerManager;
278 };
279 friend class AutoUseBasicLayerManager;
280
281 virtual bool ShouldUseOffMainThreadCompositing();
282
283 static nsIRollupListener* GetActiveRollupListener();
284
285 void Shutdown();
286
287 protected:
288
289 virtual void ResolveIconName(const nsAString &aIconName,
290 const nsAString &aIconSuffix,
291 nsIFile **aResult);
292 virtual void OnDestroy();
293 virtual void BaseCreate(nsIWidget *aParent,
294 const nsIntRect &aRect,
295 nsDeviceContext *aContext,
296 nsWidgetInitData *aInitData);
297
298 virtual nsIContent* GetLastRollup()
299 {
300 return mLastRollup;
301 }
302
303 virtual nsresult SynthesizeNativeKeyEvent(int32_t aNativeKeyboardLayout,
304 int32_t aNativeKeyCode,
305 uint32_t aModifierFlags,
306 const nsAString& aCharacters,
307 const nsAString& aUnmodifiedCharacters)
308 { return NS_ERROR_UNEXPECTED; }
309
310 virtual nsresult SynthesizeNativeMouseEvent(nsIntPoint aPoint,
311 uint32_t aNativeMessage,
312 uint32_t aModifierFlags)
313 { return NS_ERROR_UNEXPECTED; }
314
315 virtual nsresult SynthesizeNativeMouseMove(nsIntPoint aPoint)
316 { return NS_ERROR_UNEXPECTED; }
317
318 virtual nsresult SynthesizeNativeMouseScrollEvent(nsIntPoint aPoint,
319 uint32_t aNativeMessage,
320 double aDeltaX,
321 double aDeltaY,
322 double aDeltaZ,
323 uint32_t aModifierFlags,
324 uint32_t aAdditionalFlags)
325 { return NS_ERROR_UNEXPECTED; }
326
327 virtual nsresult SynthesizeNativeTouchPoint(uint32_t aPointerId,
328 TouchPointerState aPointerState,
329 nsIntPoint aPointerScreenPoint,
330 double aPointerPressure,
331 uint32_t aPointerOrientation)
332 { return NS_ERROR_UNEXPECTED; }
333
334 protected:
335 // Stores the clip rectangles in aRects into mClipRects. Returns true
336 // if the new rectangles are different from the old rectangles.
337 bool StoreWindowClipRegion(const nsTArray<nsIntRect>& aRects);
338
339 virtual already_AddRefed<nsIWidget>
340 AllocateChildPopupWidget()
341 {
342 static NS_DEFINE_IID(kCPopUpCID, NS_CHILD_CID);
343 nsCOMPtr<nsIWidget> widget = do_CreateInstance(kCPopUpCID);
344 return widget.forget();
345 }
346
347 LayerManager* CreateBasicLayerManager();
348
349 nsPopupType PopupType() const { return mPopupType; }
350
351 void NotifyRollupGeometryChange()
352 {
353 // XULPopupManager isn't interested in this notification, so only
354 // send it if gRollupListener is set.
355 if (gRollupListener) {
356 gRollupListener->NotifyGeometryChange();
357 }
358 }
359
360 /**
361 * Apply the current size constraints to the given size.
362 *
363 * @param aWidth width to constrain
364 * @param aHeight height to constrain
365 */
366 void ConstrainSize(int32_t* aWidth, int32_t* aHeight) const
367 {
368 *aWidth = std::max(mSizeConstraints.mMinSize.width,
369 std::min(mSizeConstraints.mMaxSize.width, *aWidth));
370 *aHeight = std::max(mSizeConstraints.mMinSize.height,
371 std::min(mSizeConstraints.mMaxSize.height, *aHeight));
372 }
373
374 virtual CompositorChild* GetRemoteRenderer() MOZ_OVERRIDE;
375
376 virtual void GetPreferredCompositorBackends(nsTArray<mozilla::layers::LayersBackend>& aHints);
377
378 /**
379 * Notify the widget that this window is being used with OMTC.
380 */
381 virtual void WindowUsesOMTC() {}
382
383 protected:
384 /**
385 * Starts the OMTC compositor destruction sequence.
386 *
387 * When this function returns, the compositor should not be
388 * able to access the opengl context anymore.
389 * It is safe to call it several times if platform implementations
390 * require the compositor to be destroyed before ~nsBaseWidget is
391 * reached (This is the case with gtk2 for instance).
392 */
393 void DestroyCompositor();
394
395 nsIWidgetListener* mWidgetListener;
396 nsIWidgetListener* mAttachedWidgetListener;
397 nsDeviceContext* mContext;
398 nsRefPtr<LayerManager> mLayerManager;
399 nsRefPtr<LayerManager> mBasicLayerManager;
400 nsRefPtr<CompositorChild> mCompositorChild;
401 nsRefPtr<CompositorParent> mCompositorParent;
402 nsRefPtr<WidgetShutdownObserver> mShutdownObserver;
403 nsCursor mCursor;
404 nsBorderStyle mBorderStyle;
405 bool mUseLayersAcceleration;
406 bool mForceLayersAcceleration;
407 bool mTemporarilyUseBasicLayerManager;
408 // Windows with out-of-process tabs always require OMTC. This flag designates
409 // such windows.
410 bool mRequireOffMainThreadCompositing;
411 bool mUseAttachedEvents;
412 bool mContextInitialized;
413 nsIntRect mBounds;
414 nsIntRect* mOriginalBounds;
415 // When this pointer is null, the widget is not clipped
416 nsAutoArrayPtr<nsIntRect> mClipRects;
417 uint32_t mClipRectCount;
418 nsSizeMode mSizeMode;
419 nsPopupLevel mPopupLevel;
420 nsPopupType mPopupType;
421 SizeConstraints mSizeConstraints;
422
423 static nsIRollupListener* gRollupListener;
424
425 // the last rolled up popup. Only set this when an nsAutoRollup is in scope,
426 // so it can be cleared automatically.
427 static nsIContent* mLastRollup;
428
429 #ifdef DEBUG
430 protected:
431 static nsAutoString debug_GuiEventToString(mozilla::WidgetGUIEvent* aGuiEvent);
432 static bool debug_WantPaintFlashing();
433
434 static void debug_DumpInvalidate(FILE * aFileOut,
435 nsIWidget * aWidget,
436 const nsIntRect * aRect,
437 const nsAutoCString & aWidgetName,
438 int32_t aWindowID);
439
440 static void debug_DumpEvent(FILE* aFileOut,
441 nsIWidget* aWidget,
442 mozilla::WidgetGUIEvent* aGuiEvent,
443 const nsAutoCString& aWidgetName,
444 int32_t aWindowID);
445
446 static void debug_DumpPaintEvent(FILE * aFileOut,
447 nsIWidget * aWidget,
448 const nsIntRegion & aPaintEvent,
449 const nsAutoCString & aWidgetName,
450 int32_t aWindowID);
451
452 static bool debug_GetCachedBoolPref(const char* aPrefName);
453 #endif
454 };
455
456 // A situation can occur when a mouse event occurs over a menu label while the
457 // menu popup is already open. The expected behaviour is to close the popup.
458 // This happens by calling nsIRollupListener::Rollup before the mouse event is
459 // processed. However, in cases where the mouse event is not consumed, this
460 // event will then get targeted at the menu label causing the menu to open
461 // again. To prevent this, we store in mLastRollup a reference to the popup
462 // that was closed during the Rollup call, and prevent this popup from
463 // reopening while processing the mouse event.
464 // mLastRollup should only be set while an nsAutoRollup is in scope;
465 // when it goes out of scope mLastRollup is cleared automatically.
466 // As mLastRollup is static, it can be retrieved by calling
467 // nsIWidget::GetLastRollup on any widget.
468 class nsAutoRollup
469 {
470 bool wasClear;
471
472 public:
473
474 nsAutoRollup();
475 ~nsAutoRollup();
476 };
477
478 #endif // nsBaseWidget_h__

mercurial