Backed out changeset 2450366cf7ca (bug 1891629) for causing win msix mochitest failures
[gecko.git] / widget / windows / WinUtils.h
blobdaef5ff4bc37614cf26d525d628784e5d87f79e6
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/. */
6 #ifndef mozilla_widget_WinUtils_h__
7 #define mozilla_widget_WinUtils_h__
9 #include "nscore.h"
10 #include <windows.h>
11 #include <shobjidl.h>
12 #include <uxtheme.h>
13 #include <dwmapi.h>
14 #include <unordered_map>
15 #include <utility>
17 // Undo the windows.h damage
18 #undef GetMessage
19 #undef CreateEvent
20 #undef GetClassName
21 #undef GetBinaryType
22 #undef RemoveDirectory
24 #include "nsString.h"
25 #include "nsRegion.h"
26 #include "nsRect.h"
28 #include "nsIRunnable.h"
29 #include "nsICryptoHash.h"
30 #ifdef MOZ_PLACES
31 # include "nsIFaviconService.h"
32 #endif
33 #include "nsIDownloader.h"
34 #include "nsIURI.h"
35 #include "nsIWidget.h"
36 #include "nsIThread.h"
38 #include "mozilla/Attributes.h"
39 #include "mozilla/EventForwards.h"
40 #include "mozilla/HalScreenConfiguration.h"
41 #include "mozilla/HashTable.h"
42 #include "mozilla/LazyIdleThread.h"
43 #include "mozilla/UniquePtr.h"
44 #include "mozilla/Vector.h"
45 #include "mozilla/WindowsDpiAwareness.h"
46 #include "mozilla/WindowsProcessMitigations.h"
47 #include "mozilla/gfx/2D.h"
49 /**
50 * NS_INLINE_DECL_IUNKNOWN_REFCOUNTING should be used for defining and
51 * implementing AddRef() and Release() of IUnknown interface.
52 * This depends on xpcom/base/nsISupportsImpl.h.
55 #define NS_INLINE_DECL_IUNKNOWN_REFCOUNTING(_class) \
56 public: \
57 STDMETHODIMP_(ULONG) AddRef() { \
58 MOZ_ASSERT_TYPE_OK_FOR_REFCOUNTING(_class) \
59 MOZ_ASSERT(int32_t(mRefCnt) >= 0, "illegal refcnt"); \
60 NS_ASSERT_OWNINGTHREAD(_class); \
61 ++mRefCnt; \
62 NS_LOG_ADDREF(this, mRefCnt, #_class, sizeof(*this)); \
63 return static_cast<ULONG>(mRefCnt.get()); \
64 } \
65 STDMETHODIMP_(ULONG) Release() { \
66 MOZ_ASSERT(int32_t(mRefCnt) > 0, \
67 "Release called on object that has already been released!"); \
68 NS_ASSERT_OWNINGTHREAD(_class); \
69 --mRefCnt; \
70 NS_LOG_RELEASE(this, mRefCnt, #_class); \
71 if (mRefCnt == 0) { \
72 NS_ASSERT_OWNINGTHREAD(_class); \
73 mRefCnt = 1; /* stabilize */ \
74 delete this; \
75 return 0; \
76 } \
77 return static_cast<ULONG>(mRefCnt.get()); \
78 } \
80 protected: \
81 nsAutoRefCnt mRefCnt; \
82 NS_DECL_OWNINGTHREAD \
83 public:
85 class nsWindow;
86 struct KeyPair;
88 namespace mozilla {
89 enum class PointerCapabilities : uint8_t;
90 #if defined(ACCESSIBILITY)
91 namespace a11y {
92 class LocalAccessible;
93 } // namespace a11y
94 #endif // defined(ACCESSIBILITY)
96 // Helper function: enumerate all the toplevel HWNDs attached to the current
97 // thread via ::EnumThreadWindows().
99 // Note that this use of ::EnumThreadWindows() is, unfortunately, not an
100 // abstract implementation detail.
101 template <typename F>
102 void EnumerateThreadWindows(F&& f)
103 // requires requires(F f, HWND h) { f(h); }
105 class Impl {
106 public:
107 F f;
108 explicit Impl(F&& f) : f(std::forward<F>(f)) {}
110 void invoke() {
111 WNDENUMPROC proc = &Impl::Callback;
112 ::EnumThreadWindows(::GetCurrentThreadId(), proc,
113 reinterpret_cast<LPARAM>(&f));
116 private:
117 static BOOL CALLBACK Callback(HWND hwnd, LPARAM lp) {
118 (*reinterpret_cast<F*>(lp))(hwnd);
119 return TRUE;
123 Impl(std::forward<F>(f)).invoke();
126 namespace widget {
128 // More complete QS definitions for MsgWaitForMultipleObjects() and
129 // GetQueueStatus() that include newer win8 specific defines.
131 #ifndef QS_RAWINPUT
132 # define QS_RAWINPUT 0x0400
133 #endif
135 #ifndef QS_TOUCH
136 # define QS_TOUCH 0x0800
137 # define QS_POINTER 0x1000
138 #endif
140 #define MOZ_QS_ALLEVENT \
141 (QS_KEY | QS_MOUSEMOVE | QS_MOUSEBUTTON | QS_POSTMESSAGE | QS_TIMER | \
142 QS_PAINT | QS_SENDMESSAGE | QS_HOTKEY | QS_ALLPOSTMESSAGE | QS_RAWINPUT | \
143 QS_TOUCH | QS_POINTER)
145 // Logging macros
146 #define LogFunction() mozilla::widget::WinUtils::Log(__FUNCTION__)
147 #define LogThread() \
148 mozilla::widget::WinUtils::Log("%s: IsMainThread:%d ThreadId:%X", \
149 __FUNCTION__, NS_IsMainThread(), \
150 GetCurrentThreadId())
151 #define LogThis() mozilla::widget::WinUtils::Log("[%X] %s", this, __FUNCTION__)
152 #define LogException(e) \
153 mozilla::widget::WinUtils::Log("%s Exception:%s", __FUNCTION__, \
154 e->ToString()->Data())
155 #define LogHRESULT(hr) \
156 mozilla::widget::WinUtils::Log("%s hr=%X", __FUNCTION__, hr)
158 #ifdef MOZ_PLACES
159 class myDownloadObserver final : public nsIDownloadObserver {
160 ~myDownloadObserver() {}
162 public:
163 NS_DECL_ISUPPORTS
164 NS_DECL_NSIDOWNLOADOBSERVER
166 #endif
168 class WinUtils {
169 // Function pointers for APIs that may not be available depending on
170 // the Win10 update version -- will be set up in Initialize().
171 static SetThreadDpiAwarenessContextProc sSetThreadDpiAwarenessContext;
172 static EnableNonClientDpiScalingProc sEnableNonClientDpiScaling;
173 static GetSystemMetricsForDpiProc sGetSystemMetricsForDpi;
175 // Set on Initialize().
176 static bool sHasPackageIdentity;
178 public:
179 class AutoSystemDpiAware {
180 public:
181 AutoSystemDpiAware() {
182 MOZ_DIAGNOSTIC_ASSERT(!IsWin32kLockedDown());
184 if (sSetThreadDpiAwarenessContext) {
185 mPrevContext =
186 sSetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE);
190 ~AutoSystemDpiAware() {
191 if (sSetThreadDpiAwarenessContext) {
192 sSetThreadDpiAwarenessContext(mPrevContext);
196 private:
197 DPI_AWARENESS_CONTEXT mPrevContext;
200 // Wrapper for DefWindowProc that will enable non-client dpi scaling on the
201 // window during creation.
202 static LRESULT WINAPI NonClientDpiScalingDefWindowProcW(HWND hWnd, UINT msg,
203 WPARAM wParam,
204 LPARAM lParam);
207 * Get the system's default logical-to-physical DPI scaling factor,
208 * which is based on the primary display. Note however that unlike
209 * LogToPhysFactor(GetPrimaryMonitor()), this will not change during
210 * a session even if the displays are reconfigured. This scale factor
211 * is used by Windows theme metrics etc, which do not fully support
212 * dynamic resolution changes but are only updated on logout.
214 static double SystemScaleFactor();
216 static bool IsPerMonitorDPIAware();
218 * Get the DPI of the given monitor if it's per-monitor DPI aware, otherwise
219 * return the system DPI.
221 static float MonitorDPI(HMONITOR aMonitor);
222 static float SystemDPI();
224 * Functions to convert between logical pixels as used by most Windows APIs
225 * and physical (device) pixels.
227 static double LogToPhysFactor(HMONITOR aMonitor);
228 static double LogToPhysFactor(HWND aWnd);
229 static double LogToPhysFactor(HDC aDC) {
230 return LogToPhysFactor(::WindowFromDC(aDC));
232 static int32_t LogToPhys(HMONITOR aMonitor, double aValue);
233 static HMONITOR GetPrimaryMonitor();
234 static HMONITOR MonitorFromRect(const gfx::Rect& rect);
236 static bool HasSystemMetricsForDpi();
237 static int GetSystemMetricsForDpi(int nIndex, UINT dpi);
240 * @param msg Windows event message
241 * @return User-friendly event name, or nullptr if no
242 * match is found.
244 static const char* WinEventToEventName(UINT msg);
247 * @param aHdc HDC for printer
248 * @return unwritable margins for currently set page on aHdc or empty margins
249 * if aHdc is null
251 static gfx::MarginDouble GetUnwriteableMarginsForDeviceInInches(HDC aHdc);
253 static bool HasPackageIdentity() { return sHasPackageIdentity; }
256 * The "family name" of a Windows app package is the full name without any of
257 * the components that might change during the life cycle of the app (such as
258 * the version number, or the architecture). This leaves only those properties
259 * which together serve to uniquely identify the app within one Windows
260 * installation, namely the base name and the publisher name. Meaning, this
261 * string is safe to use anywhere that a string uniquely identifying an app
262 * installation is called for (because multiple copies of the same app on the
263 * same system is not a supported feature in the app framework).
265 static nsString GetPackageFamilyName();
268 * Logging helpers that dump output to prlog module 'Widget', console, and
269 * OutputDebugString. Note these output in both debug and release builds.
271 static void Log(const char* fmt, ...);
272 static void LogW(const wchar_t* fmt, ...);
275 * PeekMessage() and GetMessage() are wrapper methods for PeekMessageW(),
276 * GetMessageW(), ITfMessageMgr::PeekMessageW() and
277 * ITfMessageMgr::GetMessageW().
278 * Don't call the native APIs directly. You MUST use these methods instead.
280 static bool PeekMessage(LPMSG aMsg, HWND aWnd, UINT aFirstMessage,
281 UINT aLastMessage, UINT aOption);
282 static bool GetMessage(LPMSG aMsg, HWND aWnd, UINT aFirstMessage,
283 UINT aLastMessage);
286 * Wait until a message is ready to be processed.
287 * Prefer using this method to directly calling ::WaitMessage since
288 * ::WaitMessage will wait if there is an unread message in the queue.
289 * That can cause freezes until another message enters the queue if the
290 * message is marked read by a call to PeekMessage which the caller is
291 * not aware of (e.g., from a different thread).
292 * Note that this method may cause sync dispatch of sent (as opposed to
293 * posted) messages.
294 * @param aTimeoutMs Timeout for waiting in ms, defaults to INFINITE
296 static void WaitForMessage(DWORD aTimeoutMs = INFINITE);
299 * GetTopLevelHWND() returns a window handle of the top level window which
300 * aWnd belongs to. Note that the result may not be our window, i.e., it
301 * may not be managed by nsWindow.
303 * See follwing table for the detail of the result window type.
305 * +-------------------------+-----------------------------------------------+
306 * | | aStopIfNotPopup |
307 * +-------------------------+-----------------------+-----------------------+
308 * | | TRUE | FALSE |
309 + +-----------------+-------+-----------------------+-----------------------+
310 * | | | * an independent top level window |
311 * | | TRUE | * a pupup window (WS_POPUP) |
312 * | | | * an owned top level window (like dialog) |
313 * | aStopIfNotChild +-------+-----------------------+-----------------------+
314 * | | | * independent window | * only an independent |
315 * | | FALSE | * non-popup-owned- | top level window |
316 * | | | window like dialog | |
317 * +-----------------+-------+-----------------------+-----------------------+
319 static HWND GetTopLevelHWND(HWND aWnd, bool aStopIfNotChild = false,
320 bool aStopIfNotPopup = true);
323 * SetNSWindowPtr() associates aWindow with aWnd. If aWidget is nullptr, it
324 * instead dissociates any nsWindow from aWnd.
326 * No AddRef is performed. May not be used off of the main thread.
328 static void SetNSWindowPtr(HWND aWnd, nsWindow* aWindow);
330 * GetNSWindowPtr() returns a pointer to the associated nsWindow pointer, if
331 * one exists, or nullptr, if not.
333 * No AddRef is performed. May not be used off of the main thread.
335 static nsWindow* GetNSWindowPtr(HWND aWnd);
338 * IsOurProcessWindow() returns TRUE if aWnd belongs our process.
339 * Otherwise, FALSE.
341 static bool IsOurProcessWindow(HWND aWnd);
344 * FindOurProcessWindow() returns the nearest ancestor window which
345 * belongs to our process. If it fails to find our process's window by the
346 * top level window, returns nullptr. And note that this is using
347 * ::GetParent() for climbing the window hierarchy, therefore, it gives
348 * up at an owned top level window except popup window (e.g., dialog).
350 static HWND FindOurProcessWindow(HWND aWnd);
353 * FindOurWindowAtPoint() returns the topmost child window which belongs to
354 * our process's top level window.
356 * NOTE: the topmost child window may NOT be our process's window like a
357 * plugin's window.
359 static HWND FindOurWindowAtPoint(const POINT& aPointInScreen);
362 * InitMSG() returns an MSG struct which was initialized by the params.
363 * Don't trust the other members in the result.
365 static MSG InitMSG(UINT aMessage, WPARAM wParam, LPARAM lParam, HWND aWnd);
368 * GetScanCode() returns a scan code for the LPARAM of WM_KEYDOWN, WM_KEYUP,
369 * WM_CHAR and WM_UNICHAR.
372 static WORD GetScanCode(LPARAM aLParam) { return (aLParam >> 16) & 0xFF; }
375 * IsExtendedScanCode() returns TRUE if the LPARAM indicates the key message
376 * is an extended key event.
378 static bool IsExtendedScanCode(LPARAM aLParam) {
379 return (aLParam & 0x1000000) != 0;
383 * GetInternalMessage() converts a native message to an internal message.
384 * If there is no internal message for the given native message, returns
385 * the native message itself.
387 static UINT GetInternalMessage(UINT aNativeMessage);
390 * GetNativeMessage() converts an internal message to a native message.
391 * If aInternalMessage is a native message, returns the native message itself.
393 static UINT GetNativeMessage(UINT aInternalMessage);
396 * GetMouseInputSource() returns a pointing device information. The value is
397 * one of MouseEvent_Binding::MOZ_SOURCE_*. This method MUST be called during
398 * mouse message handling.
400 static uint16_t GetMouseInputSource();
403 * Windows also fires mouse window messages for pens and touches, so we should
404 * retrieve their pointer ID on receiving mouse events as well. Please refer
405 * to
406 * https://msdn.microsoft.com/en-us/library/windows/desktop/ms703320(v=vs.85).aspx
408 static uint16_t GetMousePointerID();
410 static bool GetIsMouseFromTouch(EventMessage aEventType);
413 * ConvertHRGNToRegion converts a Windows HRGN to an LayoutDeviceIntRegion.
415 * aRgn the HRGN to convert.
416 * returns the LayoutDeviceIntRegion.
418 static LayoutDeviceIntRegion ConvertHRGNToRegion(HRGN aRgn);
421 * ToIntRect converts a Windows RECT to a LayoutDeviceIntRect.
423 * aRect the RECT to convert.
424 * returns the LayoutDeviceIntRect.
426 static LayoutDeviceIntRect ToIntRect(const RECT& aRect);
429 * Returns true if the context or IME state is enabled. Otherwise, false.
431 static bool IsIMEEnabled(const InputContext& aInputContext);
432 static bool IsIMEEnabled(IMEEnabled aIMEState);
435 * Returns modifier key array for aModifiers. This is for
436 * nsIWidget::SynthethizeNative*Event().
438 static void SetupKeyModifiersSequence(nsTArray<KeyPair>* aArray,
439 uint32_t aModifiers, UINT aMessage);
442 * Does device have touch support
444 static uint32_t IsTouchDeviceSupportPresent();
447 * The maximum number of simultaneous touch contacts supported by the device.
448 * In the case of devices with multiple digitizers (e.g. multiple touch
449 * screens), the value will be the maximum of the set of maximum supported
450 * contacts by each individual digitizer.
452 static uint32_t GetMaxTouchPoints();
455 * Returns the windows power platform role, which is useful for detecting
456 * tablets.
458 static POWER_PLATFORM_ROLE GetPowerPlatformRole();
460 // For pointer and hover media queries features.
461 static PointerCapabilities GetPrimaryPointerCapabilities();
462 // For any-pointer and any-hover media queries features.
463 static PointerCapabilities GetAllPointerCapabilities();
464 // Returns a string containing a comma-separated list of Fluent IDs
465 // representing the currently active pointing devices
466 static void GetPointerExplanation(nsAString* aExplanation);
469 * Fully resolves a path to its final path name. So if path contains
470 * junction points or symlinks to other folders, we'll resolve the path
471 * fully to the actual path that the links target.
473 * @param aPath path to be resolved.
474 * @return true if successful, including if nothing needs to be changed.
475 * false if something failed or aPath does not exist, aPath will
476 * remain unchanged.
478 static bool ResolveJunctionPointsAndSymLinks(std::wstring& aPath);
479 static bool ResolveJunctionPointsAndSymLinks(nsIFile* aPath);
482 * Returns true if executable's path is on a network drive.
484 static bool RunningFromANetworkDrive();
486 static void Initialize();
488 static nsresult WriteBitmap(nsIFile* aFile,
489 mozilla::gfx::SourceSurface* surface);
490 // This function is a helper, but it cannot be called from the main thread.
491 // Use the one above!
492 static nsresult WriteBitmap(nsIFile* aFile, imgIContainer* aImage);
495 * Wrapper for PathCanonicalize().
496 * Upon success, the resulting output string length is <= MAX_PATH.
497 * @param aPath [in,out] The path to transform.
498 * @return true on success, false on failure.
500 static bool CanonicalizePath(nsAString& aPath);
503 * Converts short paths (e.g. "C:\\PROGRA~1\\XYZ") to full paths.
504 * Upon success, the resulting output string length is <= MAX_PATH.
505 * @param aPath [in,out] The path to transform.
506 * @return true on success, false on failure.
508 static bool MakeLongPath(nsAString& aPath);
511 * Wrapper for PathUnExpandEnvStringsW().
512 * Upon success, the resulting output string length is <= MAX_PATH.
513 * @param aPath [in,out] The path to transform.
514 * @return true on success, false on failure.
516 static bool UnexpandEnvVars(nsAString& aPath);
519 * Retrieve a semicolon-delimited list of DLL files derived from AppInit_DLLs
521 static bool GetAppInitDLLs(nsAString& aOutput);
523 enum class PathTransformFlags : uint32_t {
524 Canonicalize = 1,
525 Lengthen = 2,
526 UnexpandEnvVars = 4,
527 RequireFilePath = 8,
529 Default = 7, // Default omits RequireFilePath
533 * Given a path, transforms it in preparation to be reported via telemetry.
534 * That can include canonicalization, converting short to long paths,
535 * unexpanding environment strings, and removing potentially sensitive data
536 * from the path.
538 * @param aPath [in,out] The path to transform.
539 * @param aFlags [in] Specifies which transformations to perform, allowing
540 * the caller to skip operations they know have already been
541 * performed.
542 * @return true on success, false on failure.
544 static bool PreparePathForTelemetry(
545 nsAString& aPath,
546 PathTransformFlags aFlags = PathTransformFlags::Default);
548 static const size_t kMaxWhitelistedItems = 3;
549 using WhitelistVec =
550 Vector<std::pair<nsString, nsDependentString>, kMaxWhitelistedItems>;
552 static const WhitelistVec& GetWhitelistedPaths();
554 static bool GetClassName(HWND aHwnd, nsAString& aName);
556 static void EnableWindowOcclusion(const bool aEnable);
558 static bool GetTimezoneName(wchar_t* aBuffer);
560 #ifdef DEBUG
561 static nsresult SetHiDPIMode(bool aHiDPI);
562 static nsresult RestoreHiDPIMode();
563 #endif
565 static bool GetAutoRotationState(AR_STATE* aRotationState);
567 static void GetClipboardFormatAsString(UINT aFormat, nsAString& aOutput);
569 private:
570 static WhitelistVec BuildWhitelist();
572 public:
573 #ifdef ACCESSIBILITY
574 static a11y::LocalAccessible* GetRootAccessibleForHWND(HWND aHwnd);
575 #endif
578 #ifdef MOZ_PLACES
579 class AsyncFaviconDataReady final : public nsIFaviconDataCallback {
580 public:
581 NS_DECL_ISUPPORTS
582 NS_DECL_NSIFAVICONDATACALLBACK
584 AsyncFaviconDataReady(nsIURI* aNewURI, RefPtr<LazyIdleThread>& aIOThread,
585 const bool aURLShortcut,
586 already_AddRefed<nsIRunnable> aRunnable);
587 nsresult OnFaviconDataNotAvailable(void);
589 private:
590 ~AsyncFaviconDataReady() {}
592 nsCOMPtr<nsIURI> mNewURI;
593 RefPtr<LazyIdleThread> mIOThread;
594 nsCOMPtr<nsIRunnable> mRunnable;
595 const bool mURLShortcut;
597 #endif
600 * Asynchronously tries add the list to the build
602 class AsyncEncodeAndWriteIcon : public nsIRunnable {
603 public:
604 NS_DECL_THREADSAFE_ISUPPORTS
605 NS_DECL_NSIRUNNABLE
607 // Warning: AsyncEncodeAndWriteIcon assumes ownership of the aData buffer
608 // passed in
609 AsyncEncodeAndWriteIcon(const nsAString& aIconPath,
610 UniquePtr<uint8_t[]> aData, uint32_t aStride,
611 uint32_t aWidth, uint32_t aHeight,
612 already_AddRefed<nsIRunnable> aRunnable);
614 private:
615 virtual ~AsyncEncodeAndWriteIcon();
617 nsAutoString mIconPath;
618 UniquePtr<uint8_t[]> mBuffer;
619 nsCOMPtr<nsIRunnable> mRunnable;
620 uint32_t mStride;
621 uint32_t mWidth;
622 uint32_t mHeight;
625 class AsyncDeleteAllFaviconsFromDisk : public nsIRunnable {
626 public:
627 NS_DECL_THREADSAFE_ISUPPORTS
628 NS_DECL_NSIRUNNABLE
630 explicit AsyncDeleteAllFaviconsFromDisk(bool aIgnoreRecent = false);
632 private:
633 virtual ~AsyncDeleteAllFaviconsFromDisk();
635 int32_t mIcoNoDeleteSeconds;
636 bool mIgnoreRecent;
637 nsCOMPtr<nsIFile> mJumpListCacheDir;
640 class FaviconHelper {
641 public:
642 static const char kJumpListCacheDir[];
643 static const char kShortcutCacheDir[];
644 static nsresult ObtainCachedIconFile(
645 nsCOMPtr<nsIURI> aFaviconPageURI, nsString& aICOFilePath,
646 RefPtr<LazyIdleThread>& aIOThread, bool aURLShortcut,
647 already_AddRefed<nsIRunnable> aRunnable = nullptr);
649 static nsresult GetOutputIconPath(nsCOMPtr<nsIURI> aFaviconPageURI,
650 nsCOMPtr<nsIFile>& aICOFile,
651 bool aURLShortcut);
653 static nsresult CacheIconFileFromFaviconURIAsync(
654 nsCOMPtr<nsIURI> aFaviconPageURI, nsCOMPtr<nsIFile> aICOFile,
655 RefPtr<LazyIdleThread>& aIOThread, bool aURLShortcut,
656 already_AddRefed<nsIRunnable> aRunnable);
658 static int32_t GetICOCacheSecondsTimeout();
661 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(WinUtils::PathTransformFlags);
663 // RTL shim windows are temporary child windows of our nsWindows created to
664 // address RTL issues in picker dialogs. (See bug 588735.)
665 class ScopedRtlShimWindow {
666 public:
667 explicit ScopedRtlShimWindow(nsIWidget* aParent);
668 ~ScopedRtlShimWindow();
670 ScopedRtlShimWindow(const ScopedRtlShimWindow&) = delete;
671 ScopedRtlShimWindow(ScopedRtlShimWindow&& that) noexcept : mWnd(that.mWnd) {
672 that.mWnd = nullptr;
675 HWND get() const { return mWnd; }
677 private:
678 HWND mWnd;
681 } // namespace widget
682 } // namespace mozilla
684 #endif // mozilla_widget_WinUtils_h__