зеркало из https://github.com/mozilla/gecko-dev.git
926 строки
33 KiB
C++
926 строки
33 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#ifndef WIDGET_WINDOWS_NSWINDOW_H_
|
|
#define WIDGET_WINDOWS_NSWINDOW_H_
|
|
|
|
/*
|
|
* nsWindow - Native window management and event handling.
|
|
*/
|
|
|
|
#include "mozilla/RefPtr.h"
|
|
#include "nsBaseWidget.h"
|
|
#include "CompositorWidget.h"
|
|
#include "mozilla/EventForwards.h"
|
|
#include "nsClassHashtable.h"
|
|
#include <windows.h>
|
|
#include "touchinjection_sdk80.h"
|
|
#include "nsdefs.h"
|
|
#include "nsUserIdleService.h"
|
|
#include "nsToolkit.h"
|
|
#include "nsString.h"
|
|
#include "nsTArray.h"
|
|
#include "gfxWindowsPlatform.h"
|
|
#include "gfxWindowsSurface.h"
|
|
#include "nsWindowDbg.h"
|
|
#include "cairo.h"
|
|
#include "nsRegion.h"
|
|
#include "mozilla/EnumeratedArray.h"
|
|
#include "mozilla/Maybe.h"
|
|
#include "mozilla/MouseEvents.h"
|
|
#include "mozilla/TimeStamp.h"
|
|
#include "mozilla/webrender/WebRenderTypes.h"
|
|
#include "mozilla/dom/MouseEventBinding.h"
|
|
#include "mozilla/DataMutex.h"
|
|
#include "mozilla/UniquePtr.h"
|
|
#include "nsMargin.h"
|
|
#include "nsRegionFwd.h"
|
|
|
|
#include "nsWinGesture.h"
|
|
#include "WinPointerEvents.h"
|
|
#include "WinUtils.h"
|
|
#include "WindowHook.h"
|
|
#include "TaskbarWindowPreview.h"
|
|
|
|
#ifdef ACCESSIBILITY
|
|
# include "oleacc.h"
|
|
# include "mozilla/a11y/LocalAccessible.h"
|
|
#endif
|
|
|
|
#include "nsUXThemeData.h"
|
|
#include "nsIUserIdleServiceInternal.h"
|
|
|
|
#include "IMMHandler.h"
|
|
#include "CheckInvariantWrapper.h"
|
|
|
|
/**
|
|
* Forward class definitions
|
|
*/
|
|
|
|
class nsNativeDragTarget;
|
|
class nsIRollupListener;
|
|
class imgIContainer;
|
|
|
|
namespace mozilla {
|
|
class WidgetMouseEvent;
|
|
namespace widget {
|
|
class NativeKey;
|
|
class InProcessWinCompositorWidget;
|
|
struct MSGResult;
|
|
class DirectManipulationOwner;
|
|
} // namespace widget
|
|
} // namespace mozilla
|
|
|
|
/**
|
|
* Forward Windows-internal definitions of otherwise incomplete ones provided by
|
|
* the SDK.
|
|
*/
|
|
const CLSID CLSID_ImmersiveShell = {
|
|
0xC2F03A33,
|
|
0x21F5,
|
|
0x47FA,
|
|
{0xB4, 0xBB, 0x15, 0x63, 0x62, 0xA2, 0xF2, 0x39}};
|
|
|
|
// Virtual Desktop.
|
|
|
|
EXTERN_C const IID IID_IVirtualDesktopManager;
|
|
MIDL_INTERFACE("a5cd92ff-29be-454c-8d04-d82879fb3f1b")
|
|
IVirtualDesktopManager : public IUnknown {
|
|
public:
|
|
virtual HRESULT STDMETHODCALLTYPE IsWindowOnCurrentVirtualDesktop(
|
|
__RPC__in HWND topLevelWindow, __RPC__out BOOL * onCurrentDesktop) = 0;
|
|
virtual HRESULT STDMETHODCALLTYPE GetWindowDesktopId(
|
|
__RPC__in HWND topLevelWindow, __RPC__out GUID * desktopId) = 0;
|
|
virtual HRESULT STDMETHODCALLTYPE MoveWindowToDesktop(
|
|
__RPC__in HWND topLevelWindow, __RPC__in REFGUID desktopId) = 0;
|
|
};
|
|
|
|
#ifdef __MINGW32__
|
|
__CRT_UUID_DECL(IVirtualDesktopManager, 0xa5cd92ff, 0x29be, 0x454c, 0x8d, 0x04,
|
|
0xd8, 0x28, 0x79, 0xfb, 0x3f, 0x1b)
|
|
#endif
|
|
|
|
/**
|
|
* Native WIN32 window wrapper.
|
|
*/
|
|
|
|
class nsWindow final : public nsBaseWidget {
|
|
public:
|
|
using WindowHook = mozilla::widget::WindowHook;
|
|
using IMEContext = mozilla::widget::IMEContext;
|
|
using WidgetEventTime = mozilla::WidgetEventTime;
|
|
|
|
NS_INLINE_DECL_REFCOUNTING_INHERITED(nsWindow, nsBaseWidget)
|
|
|
|
explicit nsWindow(bool aIsChildWindow = false);
|
|
|
|
void SendAnAPZEvent(mozilla::InputData& aEvent);
|
|
|
|
/*
|
|
* Init a standard gecko event for this widget.
|
|
* @param aEvent the event to initialize.
|
|
* @param aPoint message position in physical coordinates.
|
|
*/
|
|
void InitEvent(mozilla::WidgetGUIEvent& aEvent,
|
|
LayoutDeviceIntPoint* aPoint = nullptr);
|
|
|
|
/*
|
|
* Returns WidgetEventTime instance which is initialized with current message
|
|
* time.
|
|
*/
|
|
WidgetEventTime CurrentMessageWidgetEventTime() const;
|
|
|
|
/*
|
|
* Dispatch a gecko keyboard event for this widget. This
|
|
* is called by KeyboardLayout to dispatch gecko events.
|
|
* Returns true if it's consumed. Otherwise, false.
|
|
*/
|
|
bool DispatchKeyboardEvent(mozilla::WidgetKeyboardEvent* aEvent);
|
|
|
|
/*
|
|
* Dispatch a gecko wheel event for this widget. This
|
|
* is called by ScrollHandler to dispatch gecko events.
|
|
* Returns true if it's consumed. Otherwise, false.
|
|
*/
|
|
bool DispatchWheelEvent(mozilla::WidgetWheelEvent* aEvent);
|
|
|
|
/*
|
|
* Dispatch a gecko content command event for this widget. This
|
|
* is called by ScrollHandler to dispatch gecko events.
|
|
* Returns true if it's consumed. Otherwise, false.
|
|
*/
|
|
bool DispatchContentCommandEvent(mozilla::WidgetContentCommandEvent* aEvent);
|
|
|
|
/*
|
|
* Return the parent window, if it exists.
|
|
*/
|
|
nsWindow* GetParentWindowBase(bool aIncludeOwner);
|
|
|
|
/*
|
|
* Return true if this is a top level widget.
|
|
*/
|
|
bool IsTopLevelWidget() { return mIsTopWidgetWindow; }
|
|
|
|
// nsIWidget interface
|
|
using nsBaseWidget::Create; // for Create signature not overridden here
|
|
[[nodiscard]] nsresult Create(nsIWidget* aParent,
|
|
nsNativeWidget aNativeParent,
|
|
const LayoutDeviceIntRect& aRect,
|
|
InitData* aInitData = nullptr) override;
|
|
void Destroy() override;
|
|
void SetParent(nsIWidget* aNewParent) override;
|
|
nsIWidget* GetParent(void) override;
|
|
float GetDPI() override;
|
|
double GetDefaultScaleInternal() override;
|
|
int32_t LogToPhys(double aValue);
|
|
mozilla::DesktopToLayoutDeviceScale GetDesktopToDeviceScale() override {
|
|
if (mozilla::widget::WinUtils::IsPerMonitorDPIAware()) {
|
|
return mozilla::DesktopToLayoutDeviceScale(1.0);
|
|
} else {
|
|
return mozilla::DesktopToLayoutDeviceScale(GetDefaultScaleInternal());
|
|
}
|
|
}
|
|
|
|
void Show(bool aState) override;
|
|
bool IsVisible() const override;
|
|
void ConstrainPosition(DesktopIntPoint&) override;
|
|
void SetSizeConstraints(const SizeConstraints& aConstraints) override;
|
|
void LockAspectRatio(bool aShouldLock) override;
|
|
const SizeConstraints GetSizeConstraints() override;
|
|
void SetInputRegion(const InputRegion&) override;
|
|
void Move(double aX, double aY) override;
|
|
void Resize(double aWidth, double aHeight, bool aRepaint) override;
|
|
void Resize(double aX, double aY, double aWidth, double aHeight,
|
|
bool aRepaint) override;
|
|
mozilla::Maybe<bool> IsResizingNativeWidget() override;
|
|
void PlaceBehind(nsTopLevelWidgetZPlacement aPlacement, nsIWidget* aWidget,
|
|
bool aActivate) override;
|
|
void SetSizeMode(nsSizeMode aMode) override;
|
|
nsSizeMode SizeMode() override;
|
|
void GetWorkspaceID(nsAString& workspaceID) override;
|
|
void MoveToWorkspace(const nsAString& workspaceID) override;
|
|
void SuppressAnimation(bool aSuppress) override;
|
|
void Enable(bool aState) override;
|
|
bool IsEnabled() const override;
|
|
void SetFocus(Raise, mozilla::dom::CallerType aCallerType) override;
|
|
LayoutDeviceIntRect GetBounds() override;
|
|
LayoutDeviceIntRect GetScreenBounds() override;
|
|
[[nodiscard]] nsresult GetRestoredBounds(LayoutDeviceIntRect& aRect) override;
|
|
LayoutDeviceIntRect GetClientBounds() override;
|
|
LayoutDeviceIntPoint GetClientOffset() override;
|
|
void SetBackgroundColor(const nscolor& aColor) override;
|
|
void SetCursor(const Cursor&) override;
|
|
bool PrepareForFullscreenTransition(nsISupports** aData) override;
|
|
void PerformFullscreenTransition(FullscreenTransitionStage aStage,
|
|
uint16_t aDuration, nsISupports* aData,
|
|
nsIRunnable* aCallback) override;
|
|
void CleanupFullscreenTransition() override;
|
|
nsresult MakeFullScreen(bool aFullScreen) override;
|
|
void HideWindowChrome(bool aShouldHide) override;
|
|
void Invalidate(bool aEraseBackground = false, bool aUpdateNCArea = false,
|
|
bool aIncludeChildren = false);
|
|
void Invalidate(const LayoutDeviceIntRect& aRect) override;
|
|
void* GetNativeData(uint32_t aDataType) override;
|
|
void FreeNativeData(void* data, uint32_t aDataType) override;
|
|
nsresult SetTitle(const nsAString& aTitle) override;
|
|
void SetIcon(const nsAString& aIconSpec) override;
|
|
LayoutDeviceIntPoint WidgetToScreenOffset() override;
|
|
LayoutDeviceIntMargin ClientToWindowMargin() override;
|
|
nsresult DispatchEvent(mozilla::WidgetGUIEvent* aEvent,
|
|
nsEventStatus& aStatus) override;
|
|
void EnableDragDrop(bool aEnable) override;
|
|
void CaptureMouse(bool aCapture);
|
|
void CaptureRollupEvents(bool aDoCapture) override;
|
|
[[nodiscard]] nsresult GetAttention(int32_t aCycleCount) override;
|
|
bool HasPendingInputEvent() override;
|
|
WindowRenderer* GetWindowRenderer() override;
|
|
void SetCompositorWidgetDelegate(CompositorWidgetDelegate* delegate) override;
|
|
[[nodiscard]] nsresult OnDefaultButtonLoaded(
|
|
const LayoutDeviceIntRect& aButtonRect) override;
|
|
nsresult SynthesizeNativeKeyEvent(int32_t aNativeKeyboardLayout,
|
|
int32_t aNativeKeyCode,
|
|
uint32_t aModifierFlags,
|
|
const nsAString& aCharacters,
|
|
const nsAString& aUnmodifiedCharacters,
|
|
nsIObserver* aObserver) override;
|
|
nsresult SynthesizeNativeMouseEvent(LayoutDeviceIntPoint aPoint,
|
|
NativeMouseMessage aNativeMessage,
|
|
mozilla::MouseButton aButton,
|
|
nsIWidget::Modifiers aModifierFlags,
|
|
nsIObserver* aObserver) override;
|
|
|
|
nsresult SynthesizeNativeMouseMove(LayoutDeviceIntPoint aPoint,
|
|
nsIObserver* aObserver) override {
|
|
return SynthesizeNativeMouseEvent(
|
|
aPoint, NativeMouseMessage::Move, mozilla::MouseButton::eNotPressed,
|
|
nsIWidget::Modifiers::NO_MODIFIERS, aObserver);
|
|
}
|
|
|
|
nsresult SynthesizeNativeMouseScrollEvent(
|
|
LayoutDeviceIntPoint aPoint, uint32_t aNativeMessage, double aDeltaX,
|
|
double aDeltaY, double aDeltaZ, uint32_t aModifierFlags,
|
|
uint32_t aAdditionalFlags, nsIObserver* aObserver) override;
|
|
|
|
nsresult SynthesizeNativeTouchpadPan(TouchpadGesturePhase aEventPhase,
|
|
LayoutDeviceIntPoint aPoint,
|
|
double aDeltaX, double aDeltaY,
|
|
int32_t aModifierFlagsn,
|
|
nsIObserver* aObserver) override;
|
|
|
|
void SetInputContext(const InputContext& aContext,
|
|
const InputContextAction& aAction) override;
|
|
InputContext GetInputContext() override;
|
|
TextEventDispatcherListener* GetNativeTextEventDispatcherListener() override;
|
|
void SetTransparencyMode(TransparencyMode aMode) override;
|
|
TransparencyMode GetTransparencyMode() override;
|
|
nsresult SetNonClientMargins(const LayoutDeviceIntMargin&) override;
|
|
void SetResizeMargin(mozilla::LayoutDeviceIntCoord aResizeMargin) override;
|
|
void UpdateWindowDraggingRegion(
|
|
const LayoutDeviceIntRegion& aRegion) override;
|
|
|
|
uint32_t GetMaxTouchPoints() const override;
|
|
void SetWindowClass(const nsAString& xulWinType, const nsAString& xulWinClass,
|
|
const nsAString& xulWinName) override;
|
|
|
|
/**
|
|
* Event helpers
|
|
*/
|
|
bool DispatchMouseEvent(mozilla::EventMessage aEventMessage, WPARAM wParam,
|
|
LPARAM lParam, bool aIsContextMenuKey,
|
|
int16_t aButton, uint16_t aInputSource,
|
|
WinPointerInfo* aPointerInfo = nullptr,
|
|
bool aIgnoreAPZ = false);
|
|
void DispatchPendingEvents();
|
|
void DispatchCustomEvent(const nsString& eventName);
|
|
|
|
#ifdef ACCESSIBILITY
|
|
/**
|
|
* Return an accessible associated with the window.
|
|
*/
|
|
mozilla::a11y::LocalAccessible* GetAccessible();
|
|
#endif // ACCESSIBILITY
|
|
|
|
/**
|
|
* Window utilities
|
|
*/
|
|
nsWindow* GetTopLevelWindow(bool aStopOnDialogOrPopup);
|
|
WNDPROC GetPrevWindowProc() { return mPrevWndProc.valueOr(nullptr); }
|
|
WindowHook& GetWindowHook() { return mWindowHook; }
|
|
nsWindow* GetParentWindow(bool aIncludeOwner);
|
|
|
|
/**
|
|
* Misc.
|
|
*/
|
|
bool WidgetTypeSupportsAcceleration() override;
|
|
|
|
void ForcePresent();
|
|
bool TouchEventShouldStartDrag(mozilla::EventMessage aEventMessage,
|
|
LayoutDeviceIntPoint aEventPoint);
|
|
|
|
void SetSmallIcon(HICON aIcon);
|
|
void SetBigIcon(HICON aIcon);
|
|
void SetSmallIconNoData();
|
|
void SetBigIconNoData();
|
|
|
|
static void SetIsRestoringSession(const bool aIsRestoringSession) {
|
|
sIsRestoringSession = aIsRestoringSession;
|
|
}
|
|
|
|
bool IsRTL() const { return mIsRTL; }
|
|
|
|
/**
|
|
* AssociateDefaultIMC() associates or disassociates the default IMC for
|
|
* the window.
|
|
*
|
|
* @param aAssociate TRUE, associates the default IMC with the window.
|
|
* Otherwise, disassociates the default IMC from the
|
|
* window.
|
|
* @return TRUE if this method associated the default IMC with
|
|
* disassociated window or disassociated the default IMC
|
|
* from associated window.
|
|
* Otherwise, i.e., if this method did nothing actually,
|
|
* FALSE.
|
|
*/
|
|
bool AssociateDefaultIMC(bool aAssociate);
|
|
|
|
bool HasTaskbarIconBeenCreated() { return mHasTaskbarIconBeenCreated; }
|
|
// Called when either the nsWindow or an nsITaskbarTabPreview receives the
|
|
// noticiation that this window has its icon placed on the taskbar.
|
|
void SetHasTaskbarIconBeenCreated(bool created = true) {
|
|
mHasTaskbarIconBeenCreated = created;
|
|
}
|
|
|
|
// Getter/setter for the nsITaskbarWindowPreview for this nsWindow
|
|
already_AddRefed<nsITaskbarWindowPreview> GetTaskbarPreview() {
|
|
nsCOMPtr<nsITaskbarWindowPreview> preview(
|
|
do_QueryReferent(mTaskbarPreview));
|
|
return preview.forget();
|
|
}
|
|
void SetTaskbarPreview(nsITaskbarWindowPreview* preview) {
|
|
mTaskbarPreview = do_GetWeakReference(preview);
|
|
}
|
|
|
|
void ReparentNativeWidget(nsIWidget* aNewParent) override;
|
|
|
|
// Open file picker tracking
|
|
void PickerOpen();
|
|
void PickerClosed();
|
|
|
|
bool DestroyCalled() { return mDestroyCalled; }
|
|
|
|
bool IsPopup();
|
|
bool ShouldUseOffMainThreadCompositing() override;
|
|
|
|
const IMEContext& DefaultIMC() const { return mDefaultIMC; }
|
|
|
|
void GetCompositorWidgetInitData(
|
|
mozilla::widget::CompositorWidgetInitData* aInitData) override;
|
|
bool IsTouchWindow() const { return mTouchWindow; }
|
|
bool SynchronouslyRepaintOnResize() override;
|
|
void MaybeDispatchInitialFocusEvent() override;
|
|
|
|
void LocalesChanged() override;
|
|
|
|
void NotifyOcclusionState(mozilla::widget::OcclusionState aState) override;
|
|
void MaybeEnableWindowOcclusion(bool aEnable);
|
|
|
|
/*
|
|
* Return the HWND or null for this widget.
|
|
*/
|
|
HWND GetWindowHandle() {
|
|
return static_cast<HWND>(GetNativeData(NS_NATIVE_WINDOW));
|
|
}
|
|
|
|
/*
|
|
* Touch input injection apis
|
|
*/
|
|
nsresult SynthesizeNativeTouchPoint(uint32_t aPointerId,
|
|
TouchPointerState aPointerState,
|
|
LayoutDeviceIntPoint aPoint,
|
|
double aPointerPressure,
|
|
uint32_t aPointerOrientation,
|
|
nsIObserver* aObserver) override;
|
|
nsresult ClearNativeTouchSequence(nsIObserver* aObserver) override;
|
|
|
|
nsresult SynthesizeNativePenInput(uint32_t aPointerId,
|
|
TouchPointerState aPointerState,
|
|
LayoutDeviceIntPoint aPoint,
|
|
double aPressure, uint32_t aRotation,
|
|
int32_t aTiltX, int32_t aTiltY,
|
|
int32_t aButton,
|
|
nsIObserver* aObserver) override;
|
|
|
|
/*
|
|
* WM_APPCOMMAND common handler.
|
|
* Sends events via NativeKey::HandleAppCommandMessage().
|
|
*/
|
|
bool HandleAppCommandMsg(const MSG& aAppCommandMsg, LRESULT* aRetValue);
|
|
|
|
const InputContext& InputContextRef() const { return mInputContext; }
|
|
|
|
private:
|
|
using TimeStamp = mozilla::TimeStamp;
|
|
using TimeDuration = mozilla::TimeDuration;
|
|
using TaskbarWindowPreview = mozilla::widget::TaskbarWindowPreview;
|
|
using NativeKey = mozilla::widget::NativeKey;
|
|
using MSGResult = mozilla::widget::MSGResult;
|
|
using PlatformCompositorWidgetDelegate =
|
|
mozilla::widget::PlatformCompositorWidgetDelegate;
|
|
|
|
struct Desktop {
|
|
// Cached GUID of the virtual desktop this window should be on.
|
|
// This value may be stale.
|
|
nsString mID;
|
|
bool mUpdateIsQueued = false;
|
|
};
|
|
|
|
class PointerInfo {
|
|
public:
|
|
enum class PointerType : uint8_t {
|
|
TOUCH,
|
|
PEN,
|
|
};
|
|
|
|
PointerInfo(int32_t aPointerId, LayoutDeviceIntPoint& aPoint,
|
|
PointerType aType)
|
|
: mPointerId(aPointerId), mPosition(aPoint), mType(aType) {}
|
|
|
|
int32_t mPointerId;
|
|
LayoutDeviceIntPoint mPosition;
|
|
PointerType mType;
|
|
};
|
|
|
|
class FrameState {
|
|
public:
|
|
explicit FrameState(nsWindow* aWindow);
|
|
|
|
void ConsumePreXULSkeletonState(bool aWasMaximized);
|
|
|
|
// Whether we should call ShowWindow with the relevant size mode if needed.
|
|
// We want to avoid that when Windows is already performing the change for
|
|
// us (via the SWP_FRAMECHANGED messages).
|
|
enum class DoShowWindow : bool { No, Yes };
|
|
|
|
void EnsureSizeMode(nsSizeMode, DoShowWindow = DoShowWindow::Yes);
|
|
void EnsureFullscreenMode(bool, DoShowWindow = DoShowWindow::Yes);
|
|
void OnFrameChanging();
|
|
void OnFrameChanged();
|
|
|
|
nsSizeMode GetSizeMode() const;
|
|
|
|
void CheckInvariant() const;
|
|
|
|
private:
|
|
void SetSizeModeInternal(nsSizeMode, DoShowWindow);
|
|
|
|
nsSizeMode mSizeMode = nsSizeMode_Normal;
|
|
// XXX mLastSizeMode is rather bizarre and needs some documentation.
|
|
nsSizeMode mLastSizeMode = nsSizeMode_Normal;
|
|
// The old size mode before going into fullscreen mode. This should never
|
|
// be nsSizeMode_Fullscreen.
|
|
nsSizeMode mPreFullscreenSizeMode = nsSizeMode_Normal;
|
|
// Whether we're in fullscreen. We need to keep this state out of band,
|
|
// rather than just using mSizeMode, because a window can be minimized
|
|
// while fullscreen, and we don't store the fullscreen state anywhere else.
|
|
bool mFullscreenMode = false;
|
|
nsWindow* mWindow;
|
|
};
|
|
|
|
// Manager for taskbar-hiding. No persistent state.
|
|
class TaskbarConcealer;
|
|
|
|
// A magic number to identify the FAKETRACKPOINTSCROLLABLE window created
|
|
// when the trackpoint hack is enabled.
|
|
enum { eFakeTrackPointScrollableID = 0x46545053 };
|
|
|
|
// Used for displayport suppression during window resize
|
|
enum ResizeState { NOT_RESIZING, IN_SIZEMOVE, RESIZING, MOVING };
|
|
|
|
~nsWindow() override;
|
|
|
|
void WindowUsesOMTC() override;
|
|
void RegisterTouchWindow() override;
|
|
|
|
/**
|
|
* Callbacks
|
|
*/
|
|
static LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam,
|
|
LPARAM lParam);
|
|
static LRESULT CALLBACK WindowProcInternal(HWND hWnd, UINT msg, WPARAM wParam,
|
|
LPARAM lParam);
|
|
|
|
static BOOL CALLBACK DispatchStarvedPaints(HWND aTopWindow, LPARAM aMsg);
|
|
static BOOL CALLBACK RegisterTouchForDescendants(HWND aTopWindow,
|
|
LPARAM aMsg);
|
|
static BOOL CALLBACK UnregisterTouchForDescendants(HWND aTopWindow,
|
|
LPARAM aMsg);
|
|
static LRESULT CALLBACK MozSpecialMsgFilter(int code, WPARAM wParam,
|
|
LPARAM lParam);
|
|
static LRESULT CALLBACK MozSpecialWndProc(int code, WPARAM wParam,
|
|
LPARAM lParam);
|
|
static LRESULT CALLBACK MozSpecialMouseProc(int code, WPARAM wParam,
|
|
LPARAM lParam);
|
|
static VOID CALLBACK HookTimerForPopups(HWND hwnd, UINT uMsg, UINT idEvent,
|
|
DWORD dwTime);
|
|
|
|
/**
|
|
* Window utilities
|
|
*/
|
|
LPARAM lParamToScreen(LPARAM lParam);
|
|
LPARAM lParamToClient(LPARAM lParam);
|
|
|
|
WPARAM wParamFromGlobalMouseState();
|
|
|
|
bool AssociateWithNativeWindow();
|
|
void DissociateFromNativeWindow();
|
|
bool CanTakeFocus();
|
|
bool UpdateNonClientMargins(bool aReflowWindow = true);
|
|
void UpdateDarkModeToolbar();
|
|
void UpdateGetWindowInfoCaptionStatus(bool aActiveCaption);
|
|
void ResetLayout();
|
|
void InvalidateNonClientRegion();
|
|
static const wchar_t* GetMainWindowClass();
|
|
HWND GetOwnerWnd() const { return ::GetWindow(mWnd, GW_OWNER); }
|
|
bool IsOwnerForegroundWindow() const {
|
|
HWND owner = GetOwnerWnd();
|
|
return owner && owner == ::GetForegroundWindow();
|
|
}
|
|
bool IsForegroundWindow() const { return mWnd == ::GetForegroundWindow(); }
|
|
bool IsPopup() const { return mWindowType == WindowType::Popup; }
|
|
bool IsCloaked() const { return mIsCloaked; }
|
|
|
|
/**
|
|
* Event processing helpers
|
|
*/
|
|
HWND GetTopLevelForFocus(HWND aCurWnd);
|
|
void DispatchFocusToTopLevelWindow(bool aIsActivate);
|
|
bool DispatchStandardEvent(mozilla::EventMessage aMsg);
|
|
void RelayMouseEvent(UINT aMsg, WPARAM wParam, LPARAM lParam);
|
|
bool ProcessMessage(UINT msg, WPARAM& wParam, LPARAM& lParam,
|
|
LRESULT* aRetValue);
|
|
// We wrap this in ProcessMessage so we can log the return value
|
|
bool ProcessMessageInternal(UINT msg, WPARAM& wParam, LPARAM& lParam,
|
|
LRESULT* aRetValue);
|
|
bool ExternalHandlerProcessMessage(UINT aMessage, WPARAM& aWParam,
|
|
LPARAM& aLParam, MSGResult& aResult);
|
|
LRESULT ProcessCharMessage(const MSG& aMsg, bool* aEventDispatched);
|
|
LRESULT ProcessKeyUpMessage(const MSG& aMsg, bool* aEventDispatched);
|
|
LRESULT ProcessKeyDownMessage(const MSG& aMsg, bool* aEventDispatched);
|
|
static bool EventIsInsideWindow(
|
|
nsWindow* aWindow,
|
|
mozilla::Maybe<POINT> aEventPoint = mozilla::Nothing());
|
|
static void PostSleepWakeNotification(const bool aIsSleepMode);
|
|
int32_t ClientMarginHitTestPoint(int32_t mx, int32_t my);
|
|
void SetWindowButtonRect(WindowButtonType aButtonType,
|
|
const LayoutDeviceIntRect& aClientRect) override {
|
|
mWindowBtnRect[aButtonType] = aClientRect;
|
|
}
|
|
TimeStamp GetMessageTimeStamp(LONG aEventTime) const;
|
|
static void UpdateFirstEventTime(DWORD aEventTime);
|
|
void FinishLiveResizing(ResizeState aNewState);
|
|
mozilla::Maybe<mozilla::PanGestureInput> ConvertTouchToPanGesture(
|
|
const mozilla::MultiTouchInput& aTouchInput, PTOUCHINPUT aOriginalEvent);
|
|
void DispatchTouchOrPanGestureInput(mozilla::MultiTouchInput& aTouchInput,
|
|
PTOUCHINPUT aOSEvent);
|
|
|
|
/**
|
|
* Event handlers
|
|
*/
|
|
void OnDestroy() override;
|
|
bool OnResize(const LayoutDeviceIntSize& aSize);
|
|
void OnSizeModeChange();
|
|
bool OnGesture(WPARAM wParam, LPARAM lParam);
|
|
bool OnTouch(WPARAM wParam, LPARAM lParam);
|
|
bool OnHotKey(WPARAM wParam, LPARAM lParam);
|
|
bool OnPaint(HDC aDC, uint32_t aNestingLevel);
|
|
void OnWindowPosChanging(WINDOWPOS* info);
|
|
void OnWindowPosChanged(WINDOWPOS* wp);
|
|
void OnSysColorChanged();
|
|
void OnDPIChanged(int32_t x, int32_t y, int32_t width, int32_t height);
|
|
bool OnPointerEvents(UINT msg, WPARAM wParam, LPARAM lParam);
|
|
|
|
/**
|
|
* Function that registers when the user has been active (used for detecting
|
|
* when the user is idle).
|
|
*/
|
|
void UserActivity();
|
|
|
|
int32_t GetHeight(int32_t aProposedHeight);
|
|
|
|
DWORD WindowStyle();
|
|
DWORD WindowExStyle();
|
|
|
|
static const wchar_t* ChooseWindowClass(WindowType, bool aForMenupopupFrame);
|
|
// This method registers the given window class, and returns the class name.
|
|
static const wchar_t* RegisterWindowClass(const wchar_t* aClassName,
|
|
UINT aExtraStyle, LPWSTR aIconID);
|
|
|
|
/**
|
|
* XP and Vista theming support for windows with rounded edges
|
|
*/
|
|
void ClearThemeRegion();
|
|
|
|
/**
|
|
* Popup hooks
|
|
*/
|
|
static void ScheduleHookTimer(HWND aWnd, UINT aMsgId);
|
|
static void RegisterSpecialDropdownHooks();
|
|
static void UnregisterSpecialDropdownHooks();
|
|
static bool GetPopupsToRollup(
|
|
nsIRollupListener* aRollupListener, uint32_t* aPopupsToRollup,
|
|
mozilla::Maybe<POINT> aEventPoint = mozilla::Nothing());
|
|
static bool NeedsToHandleNCActivateDelayed(HWND aWnd);
|
|
static bool DealWithPopups(HWND inWnd, UINT inMsg, WPARAM inWParam,
|
|
LPARAM inLParam, LRESULT* outResult);
|
|
|
|
/**
|
|
* Window transparency helpers
|
|
*/
|
|
void SetWindowTranslucencyInner(TransparencyMode aMode);
|
|
TransparencyMode GetWindowTranslucencyInner() const {
|
|
return mTransparencyMode;
|
|
}
|
|
bool IsSimulatedClientArea(int32_t clientX, int32_t clientY);
|
|
bool IsWindowButton(int32_t hitTestResult);
|
|
|
|
bool DispatchTouchEventFromWMPointer(UINT msg, LPARAM aLParam,
|
|
const WinPointerInfo& aPointerInfo,
|
|
mozilla::MouseButton aButton);
|
|
|
|
static bool IsAsyncResponseEvent(UINT aMsg, LRESULT& aResult);
|
|
void IPCWindowProcHandler(UINT& msg, WPARAM& wParam, LPARAM& lParam);
|
|
|
|
/**
|
|
* Misc.
|
|
*/
|
|
void StopFlashing();
|
|
static HWND WindowAtMouse();
|
|
static bool IsTopLevelMouseExit(HWND aWnd);
|
|
LayoutDeviceIntRegion GetRegionToPaint(bool aForceFullRepaint, PAINTSTRUCT ps,
|
|
HDC aDC);
|
|
nsIWidgetListener* GetPaintListener();
|
|
|
|
void CreateCompositor() override;
|
|
void DestroyCompositor() override;
|
|
void RequestFxrOutput() override;
|
|
|
|
void RecreateDirectManipulationIfNeeded();
|
|
void ResizeDirectManipulationViewport();
|
|
void DestroyDirectManipulation();
|
|
|
|
bool NeedsToTrackWindowOcclusionState();
|
|
|
|
void AsyncUpdateWorkspaceID(Desktop& aDesktop);
|
|
|
|
// See bug 603793
|
|
static bool HasBogusPopupsDropShadowOnMultiMonitor();
|
|
|
|
static void InitMouseWheelScrollData();
|
|
|
|
void ChangedDPI();
|
|
|
|
static bool InitTouchInjection();
|
|
|
|
bool InjectTouchPoint(uint32_t aId, LayoutDeviceIntPoint& aPoint,
|
|
POINTER_FLAGS aFlags, uint32_t aPressure = 1024,
|
|
uint32_t aOrientation = 90);
|
|
|
|
void OnFullscreenChanged(nsSizeMode aOldSizeMode, bool aFullScreen);
|
|
void TryDwmResizeHack();
|
|
|
|
static void OnCloakEvent(HWND aWnd, bool aCloaked);
|
|
void OnCloakChanged(bool aCloaked);
|
|
|
|
#ifdef DEBUG
|
|
virtual nsresult SetHiDPIMode(bool aHiDPI) override;
|
|
virtual nsresult RestoreHiDPIMode() override;
|
|
#endif
|
|
|
|
// Get the orientation of the hidden taskbar, on the screen that this window
|
|
// is on, or Nothing if taskbar isn't hidden.
|
|
mozilla::Maybe<UINT> GetHiddenTaskbarEdge();
|
|
|
|
static bool sTouchInjectInitialized;
|
|
static InjectTouchInputPtr sInjectTouchFuncPtr;
|
|
static uint32_t sInstanceCount;
|
|
static nsWindow* sCurrentWindow;
|
|
static bool sIsOleInitialized;
|
|
static Cursor sCurrentCursor;
|
|
static bool sJustGotDeactivate;
|
|
static bool sJustGotActivate;
|
|
static bool sIsInMouseCapture;
|
|
static bool sIsRestoringSession;
|
|
|
|
// Message postponement hack. See the definition-site of
|
|
// WndProcUrgentInvocation::sDepth for details.
|
|
struct MOZ_STACK_CLASS WndProcUrgentInvocation {
|
|
struct Marker {
|
|
Marker() { ++sDepth; }
|
|
~Marker() { --sDepth; }
|
|
};
|
|
inline static bool IsActive() { return sDepth > 0; }
|
|
static size_t sDepth;
|
|
};
|
|
|
|
// Hook Data Members for Dropdowns. sProcessHook Tells the
|
|
// hook methods whether they should be processing the hook
|
|
// messages.
|
|
static HHOOK sMsgFilterHook;
|
|
static HHOOK sCallProcHook;
|
|
static HHOOK sCallMouseHook;
|
|
static bool sProcessHook;
|
|
static UINT sRollupMsgId;
|
|
static HWND sRollupMsgWnd;
|
|
static UINT sHookTimerId;
|
|
|
|
// Used to prevent dispatching mouse events that do not originate from user
|
|
// input.
|
|
static POINT sLastMouseMovePoint;
|
|
|
|
nsClassHashtable<nsUint32HashKey, PointerInfo> mActivePointers;
|
|
|
|
// This is used by SynthesizeNativeTouchPoint to maintain state between
|
|
// multiple synthesized points, in the case where we can't call InjectTouch
|
|
// directly.
|
|
mozilla::UniquePtr<mozilla::MultiTouchInput> mSynthesizedTouchInput;
|
|
|
|
InputContext mInputContext;
|
|
|
|
nsCOMPtr<nsIWidget> mParent;
|
|
nsIntSize mLastSize = nsIntSize(0, 0);
|
|
nsIntPoint mLastPoint;
|
|
HWND mWnd = nullptr;
|
|
HWND mTransitionWnd = nullptr;
|
|
mozilla::Maybe<WNDPROC> mPrevWndProc;
|
|
HBRUSH mBrush;
|
|
IMEContext mDefaultIMC;
|
|
HDEVNOTIFY mDeviceNotifyHandle = nullptr;
|
|
bool mIsTopWidgetWindow = false;
|
|
bool mInDtor = false;
|
|
bool mIsVisible = false;
|
|
bool mIsCloaked = false;
|
|
bool mTouchWindow = false;
|
|
bool mDisplayPanFeedback = false;
|
|
bool mHideChrome = false;
|
|
bool mIsRTL;
|
|
bool mMousePresent = false;
|
|
bool mSimulatedClientArea = false;
|
|
bool mDestroyCalled = false;
|
|
bool mOpeningAnimationSuppressed;
|
|
bool mAlwaysOnTop;
|
|
bool mIsEarlyBlankWindow = false;
|
|
bool mIsShowingPreXULSkeletonUI = false;
|
|
bool mResizable = false;
|
|
bool mForMenupopupFrame = false;
|
|
bool mIsPerformingDwmFlushHack = false;
|
|
DWORD_PTR mOldStyle = 0;
|
|
DWORD_PTR mOldExStyle = 0;
|
|
nsNativeDragTarget* mNativeDragTarget = nullptr;
|
|
HKL mLastKeyboardLayout = 0;
|
|
mozilla::CheckInvariantWrapper<FrameState> mFrameState;
|
|
WindowHook mWindowHook;
|
|
uint32_t mPickerDisplayCount = 0;
|
|
HICON mIconSmall = nullptr;
|
|
HICON mIconBig = nullptr;
|
|
HWND mLastKillFocusWindow = nullptr;
|
|
PlatformCompositorWidgetDelegate* mCompositorWidgetDelegate = nullptr;
|
|
|
|
LayoutDeviceIntMargin NonClientSizeMargin() const {
|
|
return NonClientSizeMargin(mNonClientOffset);
|
|
}
|
|
LayoutDeviceIntMargin NonClientSizeMargin(
|
|
const LayoutDeviceIntMargin& aNonClientOffset) const;
|
|
LayoutDeviceIntMargin NormalWindowNonClientOffset() const;
|
|
|
|
// Non-client margin settings
|
|
// Pre-calculated outward offset applied to default frames
|
|
LayoutDeviceIntMargin mNonClientOffset;
|
|
// Margins set by the owner
|
|
LayoutDeviceIntMargin mNonClientMargins;
|
|
// Margins we'd like to set once chrome is reshown:
|
|
LayoutDeviceIntMargin mFutureMarginsOnceChromeShows;
|
|
// Indicates we need to apply margins once toggling chrome into showing:
|
|
bool mFutureMarginsToUse = false;
|
|
|
|
// Indicates custom frames are enabled
|
|
bool mCustomNonClient = false;
|
|
// Indicates custom resize margins are in effect
|
|
bool mUseResizeMarginOverrides = false;
|
|
// Width of the left and right portions of the resize region
|
|
mozilla::LayoutDeviceIntCoord mHorResizeMargin;
|
|
// Height of the top and bottom portions of the resize region
|
|
mozilla::LayoutDeviceIntCoord mVertResizeMargin;
|
|
// Height of the caption plus border
|
|
mozilla::LayoutDeviceIntCoord mCaptionHeight;
|
|
|
|
// not yet set, will be calculated on first use
|
|
double mDefaultScale = -1.0;
|
|
|
|
// not yet set, will be calculated on first use
|
|
float mAspectRatio = 0.0;
|
|
|
|
nsCOMPtr<nsIUserIdleServiceInternal> mIdleService;
|
|
|
|
// Draggable titlebar region maintained by UpdateWindowDraggingRegion
|
|
LayoutDeviceIntRegion mDraggableRegion;
|
|
|
|
// Graphics
|
|
LayoutDeviceIntRect mLastPaintBounds;
|
|
|
|
ResizeState mResizeState = NOT_RESIZING;
|
|
|
|
// Transparency
|
|
TransparencyMode mTransparencyMode = TransparencyMode::Opaque;
|
|
nsIntRegion mPossiblyTransparentRegion;
|
|
|
|
// Win7 Gesture processing and management
|
|
nsWinGesture mGesture;
|
|
|
|
// Weak ref to the nsITaskbarWindowPreview associated with this window
|
|
nsWeakPtr mTaskbarPreview = nullptr;
|
|
|
|
// The input region that determines whether mouse events should be ignored
|
|
// and pass through to the window below. This is currently only used for
|
|
// popups.
|
|
InputRegion mInputRegion;
|
|
|
|
// True if the taskbar (possibly through the tab preview) tells us that the
|
|
// icon has been created on the taskbar.
|
|
bool mHasTaskbarIconBeenCreated = false;
|
|
|
|
// Whether we're in the process of sending a WM_SETTEXT ourselves
|
|
bool mSendingSetText = false;
|
|
|
|
// Whether we we're created as a child window (aka ChildWindow) or not.
|
|
bool mIsChildWindow : 1;
|
|
|
|
int32_t mCachedHitTestResult = 0;
|
|
|
|
// The point in time at which the last paint completed. We use this to avoid
|
|
// painting too rapidly in response to frequent input events.
|
|
TimeStamp mLastPaintEndTime;
|
|
|
|
// Caching for hit test results (in client coordinates)
|
|
LayoutDeviceIntPoint mCachedHitTestPoint;
|
|
TimeStamp mCachedHitTestTime;
|
|
|
|
RefPtr<mozilla::widget::InProcessWinCompositorWidget> mBasicLayersSurface;
|
|
|
|
double mSizeConstraintsScale; // scale in effect when setting constraints
|
|
|
|
// Will be calculated when layer manager is created.
|
|
int32_t mMaxTextureSize = -1;
|
|
|
|
// Pointer events processing and management
|
|
WinPointerEvents mPointerEvents;
|
|
|
|
ScreenPoint mLastPanGestureFocus;
|
|
|
|
// When true, used to indicate an async call to RequestFxrOutput to the GPU
|
|
// process after the Compositor is created
|
|
bool mRequestFxrOutputPending = false;
|
|
|
|
// A stack based class used in DispatchMouseEvent() to tell whether we should
|
|
// NOT open context menu when we receives WM_CONTEXTMENU after the
|
|
// DispatchMouseEvent calls.
|
|
// This class now works only in the case where a mouse up event happened in
|
|
// the overscroll gutter.
|
|
class MOZ_STACK_CLASS ContextMenuPreventer final {
|
|
public:
|
|
explicit ContextMenuPreventer(nsWindow* aWindow)
|
|
: mWindow(aWindow), mNeedsToPreventContextMenu(false){};
|
|
~ContextMenuPreventer() {
|
|
mWindow->mNeedsToPreventContextMenu = mNeedsToPreventContextMenu;
|
|
}
|
|
void Update(const mozilla::WidgetMouseEvent& aEvent,
|
|
const nsIWidget::ContentAndAPZEventStatus& aEventStatus);
|
|
|
|
private:
|
|
nsWindow* mWindow;
|
|
bool mNeedsToPreventContextMenu = false;
|
|
};
|
|
friend class ContextMenuPreventer;
|
|
bool mNeedsToPreventContextMenu = false;
|
|
|
|
mozilla::UniquePtr<mozilla::widget::DirectManipulationOwner> mDmOwner;
|
|
|
|
// Client rect for minimize, maximize and close buttons.
|
|
mozilla::EnumeratedArray<WindowButtonType, WindowButtonType::Count,
|
|
LayoutDeviceIntRect>
|
|
mWindowBtnRect;
|
|
|
|
mozilla::DataMutex<Desktop> mDesktopId;
|
|
|
|
// If set, indicates the edge of the NC region we should clear to black
|
|
// on next paint. One of: ABE_TOP, ABE_BOTTOM, ABE_LEFT or ABE_RIGHT.
|
|
mozilla::Maybe<UINT> mClearNCEdge;
|
|
|
|
friend class nsWindowGfx;
|
|
|
|
static constexpr int kHiddenTaskbarSize = 2;
|
|
};
|
|
|
|
#endif // WIDGET_WINDOWS_NSWINDOW_H_
|