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 
6 #ifndef WIDGET_WINDOWS_NSWINDOW_H_
7 #define WIDGET_WINDOWS_NSWINDOW_H_
8 
9 /*
10  * nsWindow - Native window management and event handling.
11  */
12 
13 #include "mozilla/RefPtr.h"
14 #include "nsBaseWidget.h"
15 #include "CompositorWidget.h"
16 #include "mozilla/EventForwards.h"
17 #include "nsClassHashtable.h"
18 #include <windows.h>
19 #include "touchinjection_sdk80.h"
20 #include "nsdefs.h"
21 #include "nsUserIdleService.h"
22 #include "nsToolkit.h"
23 #include "nsString.h"
24 #include "nsTArray.h"
25 #include "gfxWindowsPlatform.h"
26 #include "gfxWindowsSurface.h"
27 #include "nsWindowDbg.h"
28 #include "cairo.h"
29 #include "nsRegion.h"
30 #include "mozilla/EnumeratedArray.h"
31 #include "mozilla/Maybe.h"
32 #include "mozilla/MouseEvents.h"
33 #include "mozilla/TimeStamp.h"
34 #include "mozilla/webrender/WebRenderTypes.h"
35 #include "mozilla/dom/MouseEventBinding.h"
36 #include "mozilla/UniquePtr.h"
37 #include "nsMargin.h"
38 #include "nsRegionFwd.h"
39 
40 #include "nsWinGesture.h"
41 #include "WinPointerEvents.h"
42 #include "WinUtils.h"
43 #include "WindowHook.h"
44 #include "TaskbarWindowPreview.h"
45 
46 #ifdef ACCESSIBILITY
47 #  include "oleacc.h"
48 #  include "mozilla/a11y/LocalAccessible.h"
49 #endif
50 
51 #include "nsUXThemeData.h"
52 #include "nsIUserIdleServiceInternal.h"
53 
54 #include "IMMHandler.h"
55 
56 /**
57  * Forward class definitions
58  */
59 
60 class nsNativeDragTarget;
61 class nsIRollupListener;
62 class imgIContainer;
63 
64 namespace mozilla {
65 namespace widget {
66 class NativeKey;
67 class InProcessWinCompositorWidget;
68 struct MSGResult;
69 class DirectManipulationOwner;
70 }  // namespace widget
71 }  // namespace mozilla
72 
73 /**
74  * Forward Windows-internal definitions of otherwise incomplete ones provided by
75  * the SDK.
76  */
77 const CLSID CLSID_ImmersiveShell = {
78     0xC2F03A33,
79     0x21F5,
80     0x47FA,
81     {0xB4, 0xBB, 0x15, 0x63, 0x62, 0xA2, 0xF2, 0x39}};
82 
83 // Virtual Desktop.
84 
85 EXTERN_C const IID IID_IVirtualDesktopManager;
86 MIDL_INTERFACE("a5cd92ff-29be-454c-8d04-d82879fb3f1b")
87 IVirtualDesktopManager : public IUnknown {
88  public:
89   virtual HRESULT STDMETHODCALLTYPE IsWindowOnCurrentVirtualDesktop(
90       __RPC__in HWND topLevelWindow, __RPC__out BOOL * onCurrentDesktop) = 0;
91   virtual HRESULT STDMETHODCALLTYPE GetWindowDesktopId(
92       __RPC__in HWND topLevelWindow, __RPC__out GUID * desktopId) = 0;
93   virtual HRESULT STDMETHODCALLTYPE MoveWindowToDesktop(
94       __RPC__in HWND topLevelWindow, __RPC__in REFGUID desktopId) = 0;
95 };
96 
97 /**
98  * Native WIN32 window wrapper.
99  */
100 
101 class nsWindow final : public nsBaseWidget {
102  public:
103   using WindowHook = mozilla::widget::WindowHook;
104   using IMEContext = mozilla::widget::IMEContext;
105   using WidgetEventTime = mozilla::WidgetEventTime;
106 
107   NS_INLINE_DECL_REFCOUNTING_INHERITED(nsWindow, nsBaseWidget)
108 
109   explicit nsWindow(bool aIsChildWindow = false);
110 
111   void SendAnAPZEvent(mozilla::InputData& aEvent);
112 
113   /*
114    * Init a standard gecko event for this widget.
115    * @param aEvent the event to initialize.
116    * @param aPoint message position in physical coordinates.
117    */
118   void InitEvent(mozilla::WidgetGUIEvent& aEvent,
119                  LayoutDeviceIntPoint* aPoint = nullptr);
120 
121   /*
122    * Returns WidgetEventTime instance which is initialized with current message
123    * time.
124    */
125   WidgetEventTime CurrentMessageWidgetEventTime() const;
126 
127   /*
128    * Dispatch a gecko keyboard event for this widget. This
129    * is called by KeyboardLayout to dispatch gecko events.
130    * Returns true if it's consumed.  Otherwise, false.
131    */
132   bool DispatchKeyboardEvent(mozilla::WidgetKeyboardEvent* aEvent);
133 
134   /*
135    * Dispatch a gecko wheel event for this widget. This
136    * is called by ScrollHandler to dispatch gecko events.
137    * Returns true if it's consumed.  Otherwise, false.
138    */
139   bool DispatchWheelEvent(mozilla::WidgetWheelEvent* aEvent);
140 
141   /*
142    * Dispatch a gecko content command event for this widget. This
143    * is called by ScrollHandler to dispatch gecko events.
144    * Returns true if it's consumed.  Otherwise, false.
145    */
146   bool DispatchContentCommandEvent(mozilla::WidgetContentCommandEvent* aEvent);
147 
148   /*
149    * Return the parent window, if it exists.
150    */
151   nsWindow* GetParentWindowBase(bool aIncludeOwner);
152 
153   /*
154    * Return true if this is a top level widget.
155    */
IsTopLevelWidget()156   bool IsTopLevelWidget() { return mIsTopWidgetWindow; }
157 
158   // nsIWidget interface
159   using nsBaseWidget::Create;  // for Create signature not overridden here
160   [[nodiscard]] nsresult Create(nsIWidget* aParent,
161                                 nsNativeWidget aNativeParent,
162                                 const LayoutDeviceIntRect& aRect,
163                                 nsWidgetInitData* aInitData = nullptr) override;
164   void Destroy() override;
165   void SetParent(nsIWidget* aNewParent) override;
166   nsIWidget* GetParent(void) override;
167   float GetDPI() override;
168   double GetDefaultScaleInternal() override;
169   int32_t LogToPhys(double aValue);
GetDesktopToDeviceScale()170   mozilla::DesktopToLayoutDeviceScale GetDesktopToDeviceScale() override {
171     if (mozilla::widget::WinUtils::IsPerMonitorDPIAware()) {
172       return mozilla::DesktopToLayoutDeviceScale(1.0);
173     } else {
174       return mozilla::DesktopToLayoutDeviceScale(GetDefaultScaleInternal());
175     }
176   }
177 
178   void Show(bool aState) override;
179   bool IsVisible() const override;
180   void ConstrainPosition(bool aAllowSlop, int32_t* aX, int32_t* aY) override;
181   void SetSizeConstraints(const SizeConstraints& aConstraints) override;
182   void LockAspectRatio(bool aShouldLock) override;
183   const SizeConstraints GetSizeConstraints() override;
184   void SetWindowMouseTransparent(bool aIsTransparent) override;
185   void Move(double aX, double aY) override;
186   void Resize(double aWidth, double aHeight, bool aRepaint) override;
187   void Resize(double aX, double aY, double aWidth, double aHeight,
188               bool aRepaint) override;
189   mozilla::Maybe<bool> IsResizingNativeWidget() override;
190   [[nodiscard]] nsresult BeginResizeDrag(mozilla::WidgetGUIEvent* aEvent,
191                                          int32_t aHorizontal,
192                                          int32_t aVertical) override;
193   void PlaceBehind(nsTopLevelWidgetZPlacement aPlacement, nsIWidget* aWidget,
194                    bool aActivate) override;
195   void SetSizeMode(nsSizeMode aMode) override;
196   void GetWorkspaceID(nsAString& workspaceID) override;
197   void MoveToWorkspace(const nsAString& workspaceID) override;
198   void SuppressAnimation(bool aSuppress) override;
199   void Enable(bool aState) override;
200   bool IsEnabled() const override;
201   void SetFocus(Raise, mozilla::dom::CallerType aCallerType) override;
202   LayoutDeviceIntRect GetBounds() override;
203   LayoutDeviceIntRect GetScreenBounds() override;
204   [[nodiscard]] nsresult GetRestoredBounds(LayoutDeviceIntRect& aRect) override;
205   LayoutDeviceIntRect GetClientBounds() override;
206   LayoutDeviceIntPoint GetClientOffset() override;
207   void SetBackgroundColor(const nscolor& aColor) override;
208   void SetCursor(const Cursor&) override;
209   bool PrepareForFullscreenTransition(nsISupports** aData) override;
210   void PerformFullscreenTransition(FullscreenTransitionStage aStage,
211                                    uint16_t aDuration, nsISupports* aData,
212                                    nsIRunnable* aCallback) override;
213   void CleanupFullscreenTransition() override;
214   nsresult MakeFullScreen(bool aFullScreen) override;
215   void HideWindowChrome(bool aShouldHide) override;
216   void Invalidate(bool aEraseBackground = false, bool aUpdateNCArea = false,
217                   bool aIncludeChildren = false);
218   void Invalidate(const LayoutDeviceIntRect& aRect) override;
219   void* GetNativeData(uint32_t aDataType) override;
220   void SetNativeData(uint32_t aDataType, uintptr_t aVal) override;
221   void FreeNativeData(void* data, uint32_t aDataType) override;
222   nsresult SetTitle(const nsAString& aTitle) override;
223   void SetIcon(const nsAString& aIconSpec) override;
224   LayoutDeviceIntPoint WidgetToScreenOffset() override;
225   LayoutDeviceIntSize ClientToWindowSize(
226       const LayoutDeviceIntSize& aClientSize) override;
227   nsresult DispatchEvent(mozilla::WidgetGUIEvent* aEvent,
228                          nsEventStatus& aStatus) override;
229   void EnableDragDrop(bool aEnable) override;
230   void CaptureMouse(bool aCapture) override;
231   void CaptureRollupEvents(nsIRollupListener* aListener,
232                            bool aDoCapture) override;
233   [[nodiscard]] nsresult GetAttention(int32_t aCycleCount) override;
234   bool HasPendingInputEvent() override;
235   WindowRenderer* GetWindowRenderer() override;
236   void SetCompositorWidgetDelegate(CompositorWidgetDelegate* delegate) override;
237   [[nodiscard]] nsresult OnDefaultButtonLoaded(
238       const LayoutDeviceIntRect& aButtonRect) override;
239   nsresult SynthesizeNativeKeyEvent(int32_t aNativeKeyboardLayout,
240                                     int32_t aNativeKeyCode,
241                                     uint32_t aModifierFlags,
242                                     const nsAString& aCharacters,
243                                     const nsAString& aUnmodifiedCharacters,
244                                     nsIObserver* aObserver) override;
245   nsresult SynthesizeNativeMouseEvent(LayoutDeviceIntPoint aPoint,
246                                       NativeMouseMessage aNativeMessage,
247                                       mozilla::MouseButton aButton,
248                                       nsIWidget::Modifiers aModifierFlags,
249                                       nsIObserver* aObserver) override;
250 
SynthesizeNativeMouseMove(LayoutDeviceIntPoint aPoint,nsIObserver * aObserver)251   nsresult SynthesizeNativeMouseMove(LayoutDeviceIntPoint aPoint,
252                                      nsIObserver* aObserver) override {
253     return SynthesizeNativeMouseEvent(
254         aPoint, NativeMouseMessage::Move, mozilla::MouseButton::eNotPressed,
255         nsIWidget::Modifiers::NO_MODIFIERS, aObserver);
256   }
257 
258   nsresult SynthesizeNativeMouseScrollEvent(
259       LayoutDeviceIntPoint aPoint, uint32_t aNativeMessage, double aDeltaX,
260       double aDeltaY, double aDeltaZ, uint32_t aModifierFlags,
261       uint32_t aAdditionalFlags, nsIObserver* aObserver) override;
262 
263   nsresult SynthesizeNativeTouchpadPan(TouchpadGesturePhase aEventPhase,
264                                        LayoutDeviceIntPoint aPoint,
265                                        double aDeltaX, double aDeltaY,
266                                        int32_t aModifierFlags) override;
267 
268   void SetInputContext(const InputContext& aContext,
269                        const InputContextAction& aAction) override;
270   InputContext GetInputContext() override;
271   TextEventDispatcherListener* GetNativeTextEventDispatcherListener() override;
272   void SetTransparencyMode(nsTransparencyMode aMode) override;
273   nsTransparencyMode GetTransparencyMode() override;
274   void UpdateOpaqueRegion(const LayoutDeviceIntRegion& aOpaqueRegion) override;
275   nsresult SetNonClientMargins(LayoutDeviceIntMargin& aMargins) override;
276   void SetResizeMargin(mozilla::LayoutDeviceIntCoord aResizeMargin) override;
277   void SetDrawsInTitlebar(bool aState) override;
278   void UpdateWindowDraggingRegion(
279       const LayoutDeviceIntRegion& aRegion) override;
280 
281   void UpdateThemeGeometries(
282       const nsTArray<ThemeGeometry>& aThemeGeometries) override;
283   uint32_t GetMaxTouchPoints() const override;
284   void SetWindowClass(const nsAString& xulWinType) override;
285 
286   /**
287    * Event helpers
288    */
289   bool DispatchMouseEvent(mozilla::EventMessage aEventMessage, WPARAM wParam,
290                           LPARAM lParam, bool aIsContextMenuKey,
291                           int16_t aButton, uint16_t aInputSource,
292                           WinPointerInfo* aPointerInfo = nullptr,
293                           bool aIgnoreAPZ = false);
294   void DispatchPendingEvents();
295   void DispatchCustomEvent(const nsString& eventName);
296 
297 #ifdef ACCESSIBILITY
298   /**
299    * Return an accessible associated with the window.
300    */
301   mozilla::a11y::LocalAccessible* GetAccessible();
302 #endif  // ACCESSIBILITY
303 
304   /**
305    * Window utilities
306    */
307   nsWindow* GetTopLevelWindow(bool aStopOnDialogOrPopup);
GetPrevWindowProc()308   WNDPROC GetPrevWindowProc() { return mPrevWndProc; }
GetWindowHook()309   WindowHook& GetWindowHook() { return mWindowHook; }
310   nsWindow* GetParentWindow(bool aIncludeOwner);
311   // Get an array of all nsWindow*s on the main thread.
312   static nsTArray<nsWindow*> EnumAllWindows();
313 
314   /**
315    * Misc.
316    */
317   bool AutoErase(HDC dc);
318   bool WidgetTypeSupportsAcceleration() override;
319 
320   void ForcePresent();
321   bool TouchEventShouldStartDrag(mozilla::EventMessage aEventMessage,
322                                  LayoutDeviceIntPoint aEventPoint);
323 
324   void SetSmallIcon(HICON aIcon);
325   void SetBigIcon(HICON aIcon);
326   void SetSmallIconNoData();
327   void SetBigIconNoData();
328 
SetIsRestoringSession(const bool aIsRestoringSession)329   static void SetIsRestoringSession(const bool aIsRestoringSession) {
330     sIsRestoringSession = aIsRestoringSession;
331   }
332 
333   /**
334    * AssociateDefaultIMC() associates or disassociates the default IMC for
335    * the window.
336    *
337    * @param aAssociate    TRUE, associates the default IMC with the window.
338    *                      Otherwise, disassociates the default IMC from the
339    *                      window.
340    * @return              TRUE if this method associated the default IMC with
341    *                      disassociated window or disassociated the default IMC
342    *                      from associated window.
343    *                      Otherwise, i.e., if this method did nothing actually,
344    *                      FALSE.
345    */
346   bool AssociateDefaultIMC(bool aAssociate);
347 
HasTaskbarIconBeenCreated()348   bool HasTaskbarIconBeenCreated() { return mHasTaskbarIconBeenCreated; }
349   // Called when either the nsWindow or an nsITaskbarTabPreview receives the
350   // noticiation that this window has its icon placed on the taskbar.
351   void SetHasTaskbarIconBeenCreated(bool created = true) {
352     mHasTaskbarIconBeenCreated = created;
353   }
354 
355   // Getter/setter for the nsITaskbarWindowPreview for this nsWindow
GetTaskbarPreview()356   already_AddRefed<nsITaskbarWindowPreview> GetTaskbarPreview() {
357     nsCOMPtr<nsITaskbarWindowPreview> preview(
358         do_QueryReferent(mTaskbarPreview));
359     return preview.forget();
360   }
SetTaskbarPreview(nsITaskbarWindowPreview * preview)361   void SetTaskbarPreview(nsITaskbarWindowPreview* preview) {
362     mTaskbarPreview = do_GetWeakReference(preview);
363   }
364 
365   void ReparentNativeWidget(nsIWidget* aNewParent) override;
366 
367   // Open file picker tracking
368   void PickerOpen();
369   void PickerClosed();
370 
DestroyCalled()371   bool const DestroyCalled() { return mDestroyCalled; }
372 
373   bool IsPopup();
374   bool ShouldUseOffMainThreadCompositing() override;
375 
DefaultIMC()376   const IMEContext& DefaultIMC() const { return mDefaultIMC; }
377 
378   void GetCompositorWidgetInitData(
379       mozilla::widget::CompositorWidgetInitData* aInitData) override;
IsTouchWindow()380   bool IsTouchWindow() const { return mTouchWindow; }
381   bool SynchronouslyRepaintOnResize() override;
382   void MaybeDispatchInitialFocusEvent() override;
383 
384   void LocalesChanged() override;
385 
386   void NotifyOcclusionState(mozilla::widget::OcclusionState aState) override;
387   void MaybeEnableWindowOcclusion(bool aEnable);
388 
389   /*
390    * Return the HWND or null for this widget.
391    */
GetWindowHandle()392   HWND GetWindowHandle() {
393     return static_cast<HWND>(GetNativeData(NS_NATIVE_WINDOW));
394   }
395 
396   /*
397    * Touch input injection apis
398    */
399   nsresult SynthesizeNativeTouchPoint(uint32_t aPointerId,
400                                       TouchPointerState aPointerState,
401                                       LayoutDeviceIntPoint aPoint,
402                                       double aPointerPressure,
403                                       uint32_t aPointerOrientation,
404                                       nsIObserver* aObserver) override;
405   nsresult ClearNativeTouchSequence(nsIObserver* aObserver) override;
406 
407   nsresult SynthesizeNativePenInput(uint32_t aPointerId,
408                                     TouchPointerState aPointerState,
409                                     LayoutDeviceIntPoint aPoint,
410                                     double aPressure, uint32_t aRotation,
411                                     int32_t aTiltX, int32_t aTiltY,
412                                     int32_t aButton,
413                                     nsIObserver* aObserver) override;
414 
415   /*
416    * WM_APPCOMMAND common handler.
417    * Sends events via NativeKey::HandleAppCommandMessage().
418    */
419   bool HandleAppCommandMsg(const MSG& aAppCommandMsg, LRESULT* aRetValue);
420 
InputContextRef()421   const InputContext& InputContextRef() const { return mInputContext; }
422 
423  private:
424   using TimeStamp = mozilla::TimeStamp;
425   using TimeDuration = mozilla::TimeDuration;
426   using TaskbarWindowPreview = mozilla::widget::TaskbarWindowPreview;
427   using NativeKey = mozilla::widget::NativeKey;
428   using MSGResult = mozilla::widget::MSGResult;
429   using PlatformCompositorWidgetDelegate =
430       mozilla::widget::PlatformCompositorWidgetDelegate;
431 
432   struct Desktop {
433     // Cached GUID of the virtual desktop this window should be on.
434     // This value may be stale.
435     nsString mID;
436     bool mUpdateIsQueued = false;
437   };
438 
439   class PointerInfo {
440    public:
441     enum class PointerType : uint8_t {
442       TOUCH,
443       PEN,
444     };
445 
PointerInfo(int32_t aPointerId,LayoutDeviceIntPoint & aPoint,PointerType aType)446     PointerInfo(int32_t aPointerId, LayoutDeviceIntPoint& aPoint,
447                 PointerType aType)
448         : mPointerId(aPointerId), mPosition(aPoint), mType(aType) {}
449 
450     int32_t mPointerId;
451     LayoutDeviceIntPoint mPosition;
452     PointerType mType;
453   };
454 
455   // A magic number to identify the FAKETRACKPOINTSCROLLABLE window created
456   // when the trackpoint hack is enabled.
457   enum { eFakeTrackPointScrollableID = 0x46545053 };
458 
459   // Used for displayport suppression during window resize
460   enum ResizeState { NOT_RESIZING, IN_SIZEMOVE, RESIZING, MOVING };
461 
462   ~nsWindow() override;
463 
464   void WindowUsesOMTC() override;
465   void RegisterTouchWindow() override;
466 
467   /**
468    * Callbacks
469    */
470   static LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam,
471                                      LPARAM lParam);
472   static LRESULT CALLBACK WindowProcInternal(HWND hWnd, UINT msg, WPARAM wParam,
473                                              LPARAM lParam);
474 
475   static BOOL CALLBACK BroadcastMsgToChildren(HWND aWnd, LPARAM aMsg);
476   static BOOL CALLBACK BroadcastMsg(HWND aTopWindow, LPARAM aMsg);
477   static BOOL CALLBACK DispatchStarvedPaints(HWND aTopWindow, LPARAM aMsg);
478   static BOOL CALLBACK RegisterTouchForDescendants(HWND aTopWindow,
479                                                    LPARAM aMsg);
480   static BOOL CALLBACK UnregisterTouchForDescendants(HWND aTopWindow,
481                                                      LPARAM aMsg);
482   static LRESULT CALLBACK MozSpecialMsgFilter(int code, WPARAM wParam,
483                                               LPARAM lParam);
484   static LRESULT CALLBACK MozSpecialWndProc(int code, WPARAM wParam,
485                                             LPARAM lParam);
486   static LRESULT CALLBACK MozSpecialMouseProc(int code, WPARAM wParam,
487                                               LPARAM lParam);
488   static VOID CALLBACK HookTimerForPopups(HWND hwnd, UINT uMsg, UINT idEvent,
489                                           DWORD dwTime);
490   static BOOL CALLBACK EnumAllChildWindProc(HWND aWnd, LPARAM aParam);
491   static BOOL CALLBACK EnumAllThreadWindowProc(HWND aWnd, LPARAM aParam);
492 
493   /**
494    * Window utilities
495    */
496   LPARAM lParamToScreen(LPARAM lParam);
497   LPARAM lParamToClient(LPARAM lParam);
498 
499   WPARAM wParamFromGlobalMouseState();
500 
501   void SubclassWindow(BOOL bState);
502   bool CanTakeFocus();
503   bool UpdateNonClientMargins(int32_t aSizeMode = -1,
504                               bool aReflowWindow = true);
505   void UpdateDarkModeToolbar();
506   void UpdateGetWindowInfoCaptionStatus(bool aActiveCaption);
507   void ResetLayout();
508   void InvalidateNonClientRegion();
509   HRGN ExcludeNonClientFromPaintRegion(HRGN aRegion);
510   static const wchar_t* GetMainWindowClass();
HasGlass()511   bool HasGlass() const {
512     return mTransparencyMode == eTransparencyGlass ||
513            mTransparencyMode == eTransparencyBorderlessGlass;
514   }
GetOwnerWnd()515   HWND GetOwnerWnd() const { return ::GetWindow(mWnd, GW_OWNER); }
IsOwnerForegroundWindow()516   bool IsOwnerForegroundWindow() const {
517     HWND owner = GetOwnerWnd();
518     return owner && owner == ::GetForegroundWindow();
519   }
IsPopup()520   bool IsPopup() const { return mWindowType == eWindowType_popup; }
521 
522   /**
523    * Event processing helpers
524    */
525   HWND GetTopLevelForFocus(HWND aCurWnd);
526   void DispatchFocusToTopLevelWindow(bool aIsActivate);
527   bool DispatchStandardEvent(mozilla::EventMessage aMsg);
528   void RelayMouseEvent(UINT aMsg, WPARAM wParam, LPARAM lParam);
529   bool ProcessMessage(UINT msg, WPARAM& wParam, LPARAM& lParam,
530                       LRESULT* aRetValue);
531   bool ExternalHandlerProcessMessage(UINT aMessage, WPARAM& aWParam,
532                                      LPARAM& aLParam, MSGResult& aResult);
533   LRESULT ProcessCharMessage(const MSG& aMsg, bool* aEventDispatched);
534   LRESULT ProcessKeyUpMessage(const MSG& aMsg, bool* aEventDispatched);
535   LRESULT ProcessKeyDownMessage(const MSG& aMsg, bool* aEventDispatched);
536   static bool EventIsInsideWindow(
537       nsWindow* aWindow,
538       mozilla::Maybe<POINT> aEventPoint = mozilla::Nothing());
539   static void PostSleepWakeNotification(const bool aIsSleepMode);
540   int32_t ClientMarginHitTestPoint(int32_t mx, int32_t my);
SetWindowButtonRect(WindowButtonType aButtonType,const LayoutDeviceIntRect & aClientRect)541   void SetWindowButtonRect(WindowButtonType aButtonType,
542                            const LayoutDeviceIntRect& aClientRect) override {
543     mWindowBtnRect[aButtonType] = aClientRect;
544   }
545   TimeStamp GetMessageTimeStamp(LONG aEventTime) const;
546   static void UpdateFirstEventTime(DWORD aEventTime);
547   void FinishLiveResizing(ResizeState aNewState);
548   mozilla::Maybe<mozilla::PanGestureInput> ConvertTouchToPanGesture(
549       const mozilla::MultiTouchInput& aTouchInput, PTOUCHINPUT aOriginalEvent);
550   void DispatchTouchOrPanGestureInput(mozilla::MultiTouchInput& aTouchInput,
551                                       PTOUCHINPUT aOSEvent);
552 
553   /**
554    * Event handlers
555    */
556   void OnDestroy() override;
557   bool OnResize(const LayoutDeviceIntSize& aSize);
558   void OnSizeModeChange(nsSizeMode aSizeMode);
559   bool OnGesture(WPARAM wParam, LPARAM lParam);
560   bool OnTouch(WPARAM wParam, LPARAM lParam);
561   bool OnHotKey(WPARAM wParam, LPARAM lParam);
562   bool OnPaint(HDC aDC, uint32_t aNestingLevel);
563   void OnWindowPosChanged(WINDOWPOS* wp);
564   void OnWindowPosChanging(LPWINDOWPOS& info);
565   void OnSysColorChanged();
566   void OnDPIChanged(int32_t x, int32_t y, int32_t width, int32_t height);
567   bool OnPointerEvents(UINT msg, WPARAM wParam, LPARAM lParam);
568 
569   /**
570    * Function that registers when the user has been active (used for detecting
571    * when the user is idle).
572    */
573   void UserActivity();
574 
575   int32_t GetHeight(int32_t aProposedHeight);
576   const wchar_t* GetWindowClass() const;
577   const wchar_t* GetWindowPopupClass() const;
578   DWORD WindowStyle();
579   DWORD WindowExStyle();
580 
581   // This method registers the given window class, and returns the class name.
582   const wchar_t* RegisterWindowClass(const wchar_t* aClassName,
583                                      UINT aExtraStyle, LPWSTR aIconID) const;
584 
585   /**
586    * XP and Vista theming support for windows with rounded edges
587    */
588   void ClearThemeRegion();
589   void SetThemeRegion();
590 
591   /**
592    * Popup hooks
593    */
594   static void ScheduleHookTimer(HWND aWnd, UINT aMsgId);
595   static void RegisterSpecialDropdownHooks();
596   static void UnregisterSpecialDropdownHooks();
597   static bool GetPopupsToRollup(
598       nsIRollupListener* aRollupListener, uint32_t* aPopupsToRollup,
599       mozilla::Maybe<POINT> aEventPoint = mozilla::Nothing());
600   static bool NeedsToHandleNCActivateDelayed(HWND aWnd);
601   static bool DealWithPopups(HWND inWnd, UINT inMsg, WPARAM inWParam,
602                              LPARAM inLParam, LRESULT* outResult);
603 
604   /**
605    * Window transparency helpers
606    */
607   void SetWindowTranslucencyInner(nsTransparencyMode aMode);
GetWindowTranslucencyInner()608   nsTransparencyMode GetWindowTranslucencyInner() const {
609     return mTransparencyMode;
610   }
611   void UpdateGlass();
612   bool IsSimulatedClientArea(int32_t clientX, int32_t clientY);
613   bool IsWindowButton(int32_t hitTestResult);
614 
615   bool DispatchTouchEventFromWMPointer(UINT msg, LPARAM aLParam,
616                                        const WinPointerInfo& aPointerInfo,
617                                        mozilla::MouseButton aButton);
618 
619   void SetSizeModeInternal(nsSizeMode aMode);
620 
621   static bool IsAsyncResponseEvent(UINT aMsg, LRESULT& aResult);
622   void IPCWindowProcHandler(UINT& msg, WPARAM& wParam, LPARAM& lParam);
623 
624   /**
625    * Misc.
626    */
627   void StopFlashing();
628   static HWND WindowAtMouse();
629   static bool IsTopLevelMouseExit(HWND aWnd);
630   LayoutDeviceIntRegion GetRegionToPaint(bool aForceFullRepaint, PAINTSTRUCT ps,
631                                          HDC aDC);
632   nsIWidgetListener* GetPaintListener();
633 
634   void AddWindowOverlayWebRenderCommands(
635       mozilla::layers::WebRenderBridgeChild* aWrBridge,
636       mozilla::wr::DisplayListBuilder& aBuilder,
637       mozilla::wr::IpcResourceUpdateQueue& aResourceUpdates) override;
638 
639   void CreateCompositor() override;
640   void DestroyCompositor() override;
641   void RequestFxrOutput() override;
642 
643   void RecreateDirectManipulationIfNeeded();
644   void ResizeDirectManipulationViewport();
645   void DestroyDirectManipulation();
646 
647   bool NeedsToTrackWindowOcclusionState();
648 
649   void AsyncUpdateWorkspaceID(Desktop& aDesktop);
650 
651   static bool HasBogusPopupsDropShadowOnMultiMonitor();
652 
653   static void InitMouseWheelScrollData();
654 
655   void ChangedDPI();
656 
657   static bool InitTouchInjection();
658 
659   bool InjectTouchPoint(uint32_t aId, LayoutDeviceIntPoint& aPoint,
660                         POINTER_FLAGS aFlags, uint32_t aPressure = 1024,
661                         uint32_t aOrientation = 90);
662 
663   static bool sTouchInjectInitialized;
664   static InjectTouchInputPtr sInjectTouchFuncPtr;
665   static bool sDropShadowEnabled;
666   static uint32_t sInstanceCount;
667   static TriStateBool sCanQuit;
668   static nsWindow* sCurrentWindow;
669   static BOOL sIsOleInitialized;
670   static HCURSOR sCustomHCursor;
671   static Cursor sCurrentCursor;
672   static bool sSwitchKeyboardLayout;
673   static bool sJustGotDeactivate;
674   static bool sJustGotActivate;
675   static bool sIsInMouseCapture;
676   static bool sHaveInitializedPrefs;
677   static bool sIsRestoringSession;
678   static bool sFirstTopLevelWindowCreated;
679 
680   // Always use the helper method to read this property.  See bug 603793.
681   static TriStateBool sHasBogusPopupsDropShadowOnMultiMonitor;
682 
683   // Hook Data Memebers for Dropdowns. sProcessHook Tells the
684   // hook methods whether they should be processing the hook
685   // messages.
686   static HHOOK sMsgFilterHook;
687   static HHOOK sCallProcHook;
688   static HHOOK sCallMouseHook;
689   static bool sProcessHook;
690   static UINT sRollupMsgId;
691   static HWND sRollupMsgWnd;
692   static UINT sHookTimerId;
693 
694   // Mouse Clicks - static variable definitions for figuring
695   // out 1 - 3 Clicks.
696   static POINT sLastMousePoint;
697   static POINT sLastMouseMovePoint;
698   static LONG sLastMouseDownTime;
699   static LONG sLastClickCount;
700   static BYTE sLastMouseButton;
701 
702   static bool sNeedsToInitMouseWheelSettings;
703 
704   nsClassHashtable<nsUint32HashKey, PointerInfo> mActivePointers;
705 
706   // This is used by SynthesizeNativeTouchPoint to maintain state between
707   // multiple synthesized points, in the case where we can't call InjectTouch
708   // directly.
709   mozilla::UniquePtr<mozilla::MultiTouchInput> mSynthesizedTouchInput;
710 
711   InputContext mInputContext;
712 
713   nsCOMPtr<nsIWidget> mParent;
714   nsIntSize mLastSize = nsIntSize(0, 0);
715   nsIntPoint mLastPoint;
716   HWND mWnd = nullptr;
717   HWND mTransitionWnd = nullptr;
718   WNDPROC mPrevWndProc = nullptr;
719   HBRUSH mBrush;
720   IMEContext mDefaultIMC;
721   HDEVNOTIFY mDeviceNotifyHandle = nullptr;
722   bool mIsTopWidgetWindow = false;
723   bool mInDtor = false;
724   bool mIsVisible = false;
725   bool mPainting = false;
726   bool mTouchWindow = false;
727   bool mDisplayPanFeedback = false;
728   bool mHideChrome = false;
729   bool mIsRTL;
730   bool mFullscreenMode = false;
731   bool mMousePresent = false;
732   bool mSimulatedClientArea = false;
733   bool mDestroyCalled = false;
734   bool mOpeningAnimationSuppressed;
735   bool mAlwaysOnTop;
736   bool mIsEarlyBlankWindow = false;
737   bool mIsShowingPreXULSkeletonUI = false;
738   bool mResizable = false;
739   DWORD_PTR mOldStyle = 0;
740   DWORD_PTR mOldExStyle = 0;
741   nsNativeDragTarget* mNativeDragTarget = nullptr;
742   HKL mLastKeyboardLayout = 0;
743   nsSizeMode mOldSizeMode = nsSizeMode_Normal;
744   nsSizeMode mLastSizeMode = nsSizeMode_Normal;
745   WindowHook mWindowHook;
746   uint32_t mPickerDisplayCount = 0;
747   HICON mIconSmall = nullptr;
748   HICON mIconBig = nullptr;
749   HWND mLastKillFocusWindow = nullptr;
750   PlatformCompositorWidgetDelegate* mCompositorWidgetDelegate = nullptr;
751 
752   // Non-client margin settings
753   // Pre-calculated outward offset applied to default frames
754   LayoutDeviceIntMargin mNonClientOffset;
755   // Margins set by the owner
756   LayoutDeviceIntMargin mNonClientMargins;
757   // Margins we'd like to set once chrome is reshown:
758   LayoutDeviceIntMargin mFutureMarginsOnceChromeShows;
759   // Indicates we need to apply margins once toggling chrome into showing:
760   bool mFutureMarginsToUse = false;
761 
762   // Indicates custom frames are enabled
763   bool mCustomNonClient = false;
764   // Indicates custom resize margins are in effect
765   bool mUseResizeMarginOverrides = false;
766   // Width of the left and right portions of the resize region
767   int32_t mHorResizeMargin;
768   // Height of the top and bottom portions of the resize region
769   int32_t mVertResizeMargin;
770   // Height of the caption plus border
771   int32_t mCaptionHeight;
772 
773   // not yet set, will be calculated on first use
774   double mDefaultScale = -1.0;
775 
776   // not yet set, will be calculated on first use
777   float mAspectRatio = 0.0;
778 
779   nsCOMPtr<nsIUserIdleServiceInternal> mIdleService;
780 
781   // Draggable titlebar region maintained by UpdateWindowDraggingRegion
782   LayoutDeviceIntRegion mDraggableRegion;
783 
784   // Graphics
785   HDC mPaintDC = nullptr;  // only set during painting
786 
787   LayoutDeviceIntRect mLastPaintBounds;
788 
789   ResizeState mResizeState = NOT_RESIZING;
790 
791   // Transparency
792   nsTransparencyMode mTransparencyMode = eTransparencyOpaque;
793   nsIntRegion mPossiblyTransparentRegion;
794   MARGINS mGlassMargins = {0, 0, 0, 0};
795 
796   // Win7 Gesture processing and management
797   nsWinGesture mGesture;
798 
799   // Weak ref to the nsITaskbarWindowPreview associated with this window
800   nsWeakPtr mTaskbarPreview = nullptr;
801   // True if the taskbar (possibly through the tab preview) tells us that the
802   // icon has been created on the taskbar.
803   bool mHasTaskbarIconBeenCreated = false;
804 
805   // Indicates that mouse events should be ignored and pass through to the
806   // window below. This is currently only used for popups.
807   bool mMouseTransparent = false;
808 
809   // Whether we're in the process of sending a WM_SETTEXT ourselves
810   bool mSendingSetText = false;
811 
812   // Whether we we're created as a child window (aka ChildWindow) or not.
813   bool mIsChildWindow : 1;
814 
815   int32_t mCachedHitTestResult = 0;
816 
817   // The point in time at which the last paint completed. We use this to avoid
818   //  painting too rapidly in response to frequent input events.
819   TimeStamp mLastPaintEndTime;
820 
821   // The location of the window buttons in the window.
822   mozilla::Maybe<LayoutDeviceIntRect> mWindowButtonsRect;
823 
824   // Caching for hit test results
825   POINT mCachedHitTestPoint = {0, 0};
826   TimeStamp mCachedHitTestTime;
827 
828   RefPtr<mozilla::widget::InProcessWinCompositorWidget> mBasicLayersSurface;
829 
830   double mSizeConstraintsScale;  // scale in effect when setting constraints
831 
832   // Will be calculated when layer manager is created.
833   int32_t mMaxTextureSize = -1;
834 
835   // Pointer events processing and management
836   WinPointerEvents mPointerEvents;
837 
838   ScreenPoint mLastPanGestureFocus;
839 
840   // When true, used to indicate an async call to RequestFxrOutput to the GPU
841   // process after the Compositor is created
842   bool mRequestFxrOutputPending = false;
843 
844   mozilla::UniquePtr<mozilla::widget::DirectManipulationOwner> mDmOwner;
845 
846   // Client rect for minimize, maximize and close buttons.
847   mozilla::EnumeratedArray<WindowButtonType, WindowButtonType::Count,
848                            LayoutDeviceIntRect>
849       mWindowBtnRect;
850 
851   mozilla::DataMutex<Desktop> mDesktopId;
852 
853   friend class nsWindowGfx;
854 };
855 
856 #endif  // WIDGET_WINDOWS_NSWINDOW_H_
857