Bug 1761003 [wpt PR 33324] - Add comment pointing to followup bug, and fix typos...
[gecko.git] / widget / windows / WindowsUIUtils.cpp
blob7ec67c607e44553400ac08b66d808e441b202799
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 #include <windows.h>
7 #include <winsdkver.h>
8 #include <wrl.h>
10 #include "nsServiceManagerUtils.h"
12 #include "WindowsUIUtils.h"
14 #include "nsIObserverService.h"
15 #include "nsIAppShellService.h"
16 #include "nsAppShellCID.h"
17 #include "mozilla/ResultVariant.h"
18 #include "mozilla/Services.h"
19 #include "mozilla/StaticPrefs_widget.h"
20 #include "mozilla/WidgetUtils.h"
21 #include "mozilla/WindowsVersion.h"
22 #include "mozilla/LookAndFeel.h"
23 #include "mozilla/ScopeExit.h"
24 #include "mozilla/media/MediaUtils.h"
25 #include "nsString.h"
26 #include "nsIWidget.h"
27 #include "nsIWindowMediator.h"
28 #include "nsPIDOMWindow.h"
29 #include "nsWindowGfx.h"
30 #include "Units.h"
32 /* mingw currently doesn't support windows.ui.viewmanagement.h, so we disable it
33 * until it's fixed. */
34 #ifndef __MINGW32__
36 # include <inspectable.h>
37 # include <roapi.h>
38 # include <windows.ui.viewmanagement.h>
40 # pragma comment(lib, "runtimeobject.lib")
42 using namespace ABI::Windows::UI;
43 using namespace ABI::Windows::UI::ViewManagement;
44 using namespace Microsoft::WRL;
45 using namespace Microsoft::WRL::Wrappers;
46 using namespace ABI::Windows::Foundation;
47 using namespace ABI::Windows::ApplicationModel::DataTransfer;
49 /* All of this is win10 stuff and we're compiling against win81 headers
50 * for now, so we may need to do some legwork: */
51 # if WINVER_MAXVER < 0x0A00
52 namespace ABI {
53 namespace Windows {
54 namespace UI {
55 namespace ViewManagement {
56 enum UserInteractionMode {
57 UserInteractionMode_Mouse = 0,
58 UserInteractionMode_Touch = 1
61 } // namespace UI
62 } // namespace Windows
63 } // namespace ABI
65 # endif
67 # ifndef RuntimeClass_Windows_UI_ViewManagement_UIViewSettings
68 # define RuntimeClass_Windows_UI_ViewManagement_UIViewSettings \
69 L"Windows.UI.ViewManagement.UIViewSettings"
70 # endif
72 # if WINVER_MAXVER < 0x0A00
73 namespace ABI {
74 namespace Windows {
75 namespace UI {
76 namespace ViewManagement {
77 interface IUIViewSettings;
78 MIDL_INTERFACE("C63657F6-8850-470D-88F8-455E16EA2C26")
79 IUIViewSettings : public IInspectable {
80 public:
81 virtual HRESULT STDMETHODCALLTYPE get_UserInteractionMode(
82 UserInteractionMode * value) = 0;
85 extern const __declspec(selectany) IID& IID_IUIViewSettings =
86 __uuidof(IUIViewSettings);
87 } // namespace ViewManagement
88 } // namespace UI
89 } // namespace Windows
90 } // namespace ABI
91 # endif
93 # ifndef IUIViewSettingsInterop
95 using IUIViewSettingsInterop = interface IUIViewSettingsInterop;
97 MIDL_INTERFACE("3694dbf9-8f68-44be-8ff5-195c98ede8a6")
98 IUIViewSettingsInterop : public IInspectable {
99 public:
100 virtual HRESULT STDMETHODCALLTYPE GetForWindow(HWND hwnd, REFIID riid,
101 void** ppv) = 0;
103 # endif
105 # ifndef __IDataTransferManagerInterop_INTERFACE_DEFINED__
106 # define __IDataTransferManagerInterop_INTERFACE_DEFINED__
108 using IDataTransferManagerInterop = interface IDataTransferManagerInterop;
110 MIDL_INTERFACE("3A3DCD6C-3EAB-43DC-BCDE-45671CE800C8")
111 IDataTransferManagerInterop : public IUnknown {
112 public:
113 virtual HRESULT STDMETHODCALLTYPE GetForWindow(
114 HWND appWindow, REFIID riid, void** dataTransferManager) = 0;
115 virtual HRESULT STDMETHODCALLTYPE ShowShareUIForWindow(HWND appWindow) = 0;
118 # endif
120 # if !defined( \
121 ____x_ABI_CWindows_CApplicationModel_CDataTransfer_CIDataPackage4_INTERFACE_DEFINED__)
122 # define ____x_ABI_CWindows_CApplicationModel_CDataTransfer_CIDataPackage4_INTERFACE_DEFINED__
124 MIDL_INTERFACE("13a24ec8-9382-536f-852a-3045e1b29a3b")
125 IDataPackage4 : public IInspectable {
126 public:
127 virtual HRESULT STDMETHODCALLTYPE add_ShareCanceled(
128 __FITypedEventHandler_2_Windows__CApplicationModel__CDataTransfer__CDataPackage_IInspectable *
129 handler,
130 EventRegistrationToken * token) = 0;
131 virtual HRESULT STDMETHODCALLTYPE remove_ShareCanceled(
132 EventRegistrationToken token) = 0;
135 # endif
137 # ifndef RuntimeClass_Windows_UI_ViewManagement_UISettings
138 # define RuntimeClass_Windows_UI_ViewManagement_UISettings \
139 L"Windows.UI.ViewManagement.UISettings"
140 # endif
141 # if WINDOWS_FOUNDATION_UNIVERSALAPICONTRACT_VERSION < 0x80000
142 namespace ABI {
143 namespace Windows {
144 namespace UI {
145 namespace ViewManagement {
147 class UISettings;
148 class UISettingsAutoHideScrollBarsChangedEventArgs;
149 interface IUISettingsAutoHideScrollBarsChangedEventArgs;
150 MIDL_INTERFACE("87afd4b2-9146-5f02-8f6b-06d454174c0f")
151 IUISettingsAutoHideScrollBarsChangedEventArgs : public IInspectable{};
153 } // namespace ViewManagement
154 } // namespace UI
155 } // namespace Windows
156 } // namespace ABI
158 namespace ABI {
159 namespace Windows {
160 namespace Foundation {
162 template <>
163 struct __declspec(uuid("808aef30-2660-51b0-9c11-f75dd42006b4"))
164 ITypedEventHandler<ABI::Windows::UI::ViewManagement::UISettings*,
165 ABI::Windows::UI::ViewManagement::
166 UISettingsAutoHideScrollBarsChangedEventArgs*>
167 : ITypedEventHandler_impl<
168 ABI::Windows::Foundation::Internal::AggregateType<
169 ABI::Windows::UI::ViewManagement::UISettings*,
170 ABI::Windows::UI::ViewManagement::IUISettings*>,
171 ABI::Windows::Foundation::Internal::AggregateType<
172 ABI::Windows::UI::ViewManagement::
173 UISettingsAutoHideScrollBarsChangedEventArgs*,
174 ABI::Windows::UI::ViewManagement::
175 IUISettingsAutoHideScrollBarsChangedEventArgs*>> {
176 static const wchar_t* z_get_rc_name_impl() {
177 return L"Windows.Foundation.TypedEventHandler`2<Windows.UI.ViewManagement."
178 L"UISettings, "
179 L"Windows.UI.ViewManagement."
180 L"UISettingsAutoHideScrollBarsChangedEventArgs>";
183 // Define a typedef for the parameterized interface specialization's mangled
184 // name. This allows code which uses the mangled name for the parameterized
185 // interface to access the correct parameterized interface specialization.
186 typedef ITypedEventHandler<ABI::Windows::UI::ViewManagement::UISettings*,
187 ABI::Windows::UI::ViewManagement::
188 UISettingsAutoHideScrollBarsChangedEventArgs*>
189 __FITypedEventHandler_2_Windows__CUI__CViewManagement__CUISettings_Windows__CUI__CViewManagement__CUISettingsAutoHideScrollBarsChangedEventArgs_t;
190 # define __FITypedEventHandler_2_Windows__CUI__CViewManagement__CUISettings_Windows__CUI__CViewManagement__CUISettingsAutoHideScrollBarsChangedEventArgs \
191 ABI::Windows::Foundation:: \
192 __FITypedEventHandler_2_Windows__CUI__CViewManagement__CUISettings_Windows__CUI__CViewManagement__CUISettingsAutoHideScrollBarsChangedEventArgs_t
194 } // namespace Foundation
195 } // namespace Windows
196 } // namespace ABI
198 namespace ABI {
199 namespace Windows {
200 namespace UI {
201 namespace ViewManagement {
202 class UISettings;
203 class UISettingsAutoHideScrollBarsChangedEventArgs;
204 interface IUISettings5;
205 MIDL_INTERFACE("5349d588-0cb5-5f05-bd34-706b3231f0bd")
206 IUISettings5 : public IInspectable {
207 public:
208 virtual HRESULT STDMETHODCALLTYPE get_AutoHideScrollBars(boolean * value) = 0;
209 virtual HRESULT STDMETHODCALLTYPE add_AutoHideScrollBarsChanged(
210 __FITypedEventHandler_2_Windows__CUI__CViewManagement__CUISettings_Windows__CUI__CViewManagement__CUISettingsAutoHideScrollBarsChangedEventArgs *
211 handler,
212 EventRegistrationToken * token) = 0;
213 virtual HRESULT STDMETHODCALLTYPE remove_AutoHideScrollBarsChanged(
214 EventRegistrationToken token) = 0;
216 } // namespace ViewManagement
217 } // namespace UI
218 } // namespace Windows
219 } // namespace ABI
220 # endif
221 #endif
223 using namespace mozilla;
225 enum class TabletModeState : uint8_t { Unknown, Off, On };
226 static TabletModeState sInTabletModeState;
228 WindowsUIUtils::WindowsUIUtils() = default;
229 WindowsUIUtils::~WindowsUIUtils() = default;
231 NS_IMPL_ISUPPORTS(WindowsUIUtils, nsIWindowsUIUtils)
233 NS_IMETHODIMP
234 WindowsUIUtils::GetSystemSmallIconSize(int32_t* aSize) {
235 NS_ENSURE_ARG(aSize);
237 mozilla::LayoutDeviceIntSize size =
238 nsWindowGfx::GetIconMetrics(nsWindowGfx::kSmallIcon);
239 *aSize = std::max(size.width, size.height);
240 return NS_OK;
243 NS_IMETHODIMP
244 WindowsUIUtils::GetSystemLargeIconSize(int32_t* aSize) {
245 NS_ENSURE_ARG(aSize);
247 mozilla::LayoutDeviceIntSize size =
248 nsWindowGfx::GetIconMetrics(nsWindowGfx::kRegularIcon);
249 *aSize = std::max(size.width, size.height);
250 return NS_OK;
253 NS_IMETHODIMP
254 WindowsUIUtils::SetWindowIcon(mozIDOMWindowProxy* aWindow,
255 imgIContainer* aSmallIcon,
256 imgIContainer* aBigIcon) {
257 NS_ENSURE_ARG(aWindow);
259 nsCOMPtr<nsIWidget> widget =
260 nsGlobalWindowOuter::Cast(aWindow)->GetMainWidget();
261 nsWindow* window = static_cast<nsWindow*>(widget.get());
263 nsresult rv;
265 if (aSmallIcon) {
266 HICON hIcon = nullptr;
267 rv = nsWindowGfx::CreateIcon(
268 aSmallIcon, false, mozilla::LayoutDeviceIntPoint(),
269 nsWindowGfx::GetIconMetrics(nsWindowGfx::kSmallIcon), &hIcon);
270 NS_ENSURE_SUCCESS(rv, rv);
272 window->SetSmallIcon(hIcon);
275 if (aBigIcon) {
276 HICON hIcon = nullptr;
277 rv = nsWindowGfx::CreateIcon(
278 aBigIcon, false, mozilla::LayoutDeviceIntPoint(),
279 nsWindowGfx::GetIconMetrics(nsWindowGfx::kRegularIcon), &hIcon);
280 NS_ENSURE_SUCCESS(rv, rv);
282 window->SetBigIcon(hIcon);
285 return NS_OK;
288 NS_IMETHODIMP
289 WindowsUIUtils::SetWindowIconFromExe(mozIDOMWindowProxy* aWindow,
290 const nsAString& aExe, uint16_t aIndex) {
291 NS_ENSURE_ARG(aWindow);
293 nsCOMPtr<nsIWidget> widget =
294 nsGlobalWindowOuter::Cast(aWindow)->GetMainWidget();
295 nsWindow* window = static_cast<nsWindow*>(widget.get());
297 HICON icon = ::LoadIconW(::GetModuleHandleW(PromiseFlatString(aExe).get()),
298 MAKEINTRESOURCEW(aIndex));
299 window->SetBigIcon(icon);
300 window->SetSmallIcon(icon);
302 return NS_OK;
305 NS_IMETHODIMP
306 WindowsUIUtils::SetWindowIconNoData(mozIDOMWindowProxy* aWindow) {
307 NS_ENSURE_ARG(aWindow);
309 nsCOMPtr<nsIWidget> widget =
310 nsGlobalWindowOuter::Cast(aWindow)->GetMainWidget();
311 nsWindow* window = static_cast<nsWindow*>(widget.get());
313 window->SetSmallIconNoData();
314 window->SetBigIconNoData();
316 return NS_OK;
319 bool WindowsUIUtils::GetInTabletMode() {
320 MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
321 if (sInTabletModeState == TabletModeState::Unknown) {
322 UpdateInTabletMode();
324 return sInTabletModeState == TabletModeState::On;
327 NS_IMETHODIMP
328 WindowsUIUtils::GetInTabletMode(bool* aResult) {
329 *aResult = GetInTabletMode();
330 return NS_OK;
333 bool WindowsUIUtils::ComputeOverlayScrollbars() {
334 MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
336 #ifndef __MINGW32__
337 // We need to keep this alive for ~ever so that change callbacks work as
338 // expected, sigh.
339 static ComPtr<IUISettings5> sUiSettings;
341 if (!IsWin11OrLater()) {
342 // While in theory Windows 10 supports overlay scrollbar settings, it's off
343 // by default and it's untested whether our Win10 scrollbar drawing code
344 // deals with it properly.
345 return false;
348 if (!StaticPrefs::widget_windows_overlay_scrollbars_enabled()) {
349 return false;
352 if (!sUiSettings) {
353 ComPtr<IInspectable> uiSettingsAsInspectable;
354 ::RoActivateInstance(
355 HStringReference(RuntimeClass_Windows_UI_ViewManagement_UISettings)
356 .Get(),
357 &uiSettingsAsInspectable);
358 if (NS_WARN_IF(!uiSettingsAsInspectable)) {
359 return false;
362 if (NS_WARN_IF(FAILED(uiSettingsAsInspectable.As(&sUiSettings)))) {
363 return false;
366 EventRegistrationToken unusedToken;
367 auto callback = Callback<ITypedEventHandler<
368 UISettings*, UISettingsAutoHideScrollBarsChangedEventArgs*>>(
369 [](auto...) {
370 // Scrollbar sizes change layout.
371 LookAndFeel::NotifyChangedAllWindows(
372 widget::ThemeChangeKind::StyleAndLayout);
373 return S_OK;
375 (void)NS_WARN_IF(FAILED(sUiSettings->add_AutoHideScrollBarsChanged(
376 callback.Get(), &unusedToken)));
379 boolean autoHide = false;
380 sUiSettings->get_AutoHideScrollBars(&autoHide);
381 return autoHide;
382 #endif
383 return false;
386 void WindowsUIUtils::UpdateInTabletMode() {
387 #ifndef __MINGW32__
388 if (!IsWin10OrLater()) {
389 return;
392 nsresult rv;
393 nsCOMPtr<nsIWindowMediator> winMediator(
394 do_GetService(NS_WINDOWMEDIATOR_CONTRACTID, &rv));
395 if (NS_FAILED(rv)) {
396 return;
399 nsCOMPtr<nsIWidget> widget;
400 nsCOMPtr<mozIDOMWindowProxy> navWin;
402 rv = winMediator->GetMostRecentWindow(u"navigator:browser",
403 getter_AddRefs(navWin));
404 if (NS_FAILED(rv) || !navWin) {
405 // Fall back to the hidden window
406 nsCOMPtr<nsIAppShellService> appShell(
407 do_GetService(NS_APPSHELLSERVICE_CONTRACTID));
409 rv = appShell->GetHiddenDOMWindow(getter_AddRefs(navWin));
410 if (NS_FAILED(rv) || !navWin) {
411 return;
415 nsPIDOMWindowOuter* win = nsPIDOMWindowOuter::From(navWin);
416 widget = widget::WidgetUtils::DOMWindowToWidget(win);
418 if (!widget) {
419 return;
422 HWND winPtr = (HWND)widget->GetNativeData(NS_NATIVE_WINDOW);
423 ComPtr<IUIViewSettingsInterop> uiViewSettingsInterop;
425 HRESULT hr = GetActivationFactory(
426 HStringReference(RuntimeClass_Windows_UI_ViewManagement_UIViewSettings)
427 .Get(),
428 &uiViewSettingsInterop);
429 if (FAILED(hr)) {
430 return;
432 ComPtr<IUIViewSettings> uiViewSettings;
433 hr = uiViewSettingsInterop->GetForWindow(winPtr,
434 IID_PPV_ARGS(&uiViewSettings));
435 if (FAILED(hr)) {
436 return;
438 UserInteractionMode mode;
439 hr = uiViewSettings->get_UserInteractionMode(&mode);
440 if (FAILED(hr)) {
441 return;
444 TabletModeState oldTabletModeState = sInTabletModeState;
445 sInTabletModeState = mode == UserInteractionMode_Touch ? TabletModeState::On
446 : TabletModeState::Off;
447 if (sInTabletModeState != oldTabletModeState) {
448 nsCOMPtr<nsIObserverService> observerService =
449 mozilla::services::GetObserverService();
450 observerService->NotifyObservers(nullptr, "tablet-mode-change",
451 sInTabletModeState == TabletModeState::On
452 ? u"tablet-mode"
453 : u"normal-mode");
455 #endif
458 #ifndef __MINGW32__
459 struct HStringDeleter {
460 using pointer = HSTRING;
461 void operator()(pointer aString) { WindowsDeleteString(aString); }
464 using HStringUniquePtr = UniquePtr<HSTRING, HStringDeleter>;
466 Result<HStringUniquePtr, HRESULT> ConvertToWindowsString(
467 const nsAString& aStr) {
468 HSTRING rawStr;
469 HRESULT hr = WindowsCreateString(PromiseFlatString(aStr).get(), aStr.Length(),
470 &rawStr);
471 if (FAILED(hr)) {
472 return Err(hr);
474 return HStringUniquePtr(rawStr);
477 static Result<Ok, nsresult> RequestShare(
478 const std::function<HRESULT(IDataRequestedEventArgs* pArgs)>& aCallback) {
479 if (!IsWin10OrLater()) {
480 return Err(NS_ERROR_FAILURE);
483 HWND hwnd = GetForegroundWindow();
484 if (!hwnd) {
485 return Err(NS_ERROR_FAILURE);
488 ComPtr<IDataTransferManagerInterop> dtmInterop;
489 ComPtr<IDataTransferManager> dtm;
491 HRESULT hr = RoGetActivationFactory(
492 HStringReference(
493 RuntimeClass_Windows_ApplicationModel_DataTransfer_DataTransferManager)
494 .Get(),
495 IID_PPV_ARGS(&dtmInterop));
496 if (FAILED(hr) ||
497 FAILED(dtmInterop->GetForWindow(hwnd, IID_PPV_ARGS(&dtm)))) {
498 return Err(NS_ERROR_FAILURE);
501 auto callback = Callback<
502 ITypedEventHandler<DataTransferManager*, DataRequestedEventArgs*>>(
503 [aCallback](IDataTransferManager*,
504 IDataRequestedEventArgs* pArgs) -> HRESULT {
505 return aCallback(pArgs);
508 EventRegistrationToken dataRequestedToken;
509 if (FAILED(dtm->add_DataRequested(callback.Get(), &dataRequestedToken)) ||
510 FAILED(dtmInterop->ShowShareUIForWindow(hwnd))) {
511 return Err(NS_ERROR_FAILURE);
514 return Ok();
517 static Result<Ok, nsresult> AddShareEventListeners(
518 const RefPtr<mozilla::media::Refcountable<MozPromiseHolder<SharePromise>>>&
519 aPromiseHolder,
520 const ComPtr<IDataPackage>& aDataPackage) {
521 ComPtr<IDataPackage3> spDataPackage3;
523 if (FAILED(aDataPackage.As(&spDataPackage3))) {
524 return Err(NS_ERROR_FAILURE);
527 auto completedCallback =
528 Callback<ITypedEventHandler<DataPackage*, ShareCompletedEventArgs*>>(
529 [aPromiseHolder](IDataPackage*,
530 IShareCompletedEventArgs*) -> HRESULT {
531 aPromiseHolder->Resolve(true, __func__);
532 return S_OK;
535 EventRegistrationToken dataRequestedToken;
536 if (FAILED(spDataPackage3->add_ShareCompleted(completedCallback.Get(),
537 &dataRequestedToken))) {
538 return Err(NS_ERROR_FAILURE);
541 ComPtr<IDataPackage4> spDataPackage4;
542 if (SUCCEEDED(aDataPackage.As(&spDataPackage4))) {
543 // Use SharedCanceled API only on supported versions of Windows
544 // So that the older ones can still use ShareUrl()
546 auto canceledCallback =
547 Callback<ITypedEventHandler<DataPackage*, IInspectable*>>(
548 [aPromiseHolder](IDataPackage*, IInspectable*) -> HRESULT {
549 aPromiseHolder->Reject(NS_ERROR_FAILURE, __func__);
550 return S_OK;
553 if (FAILED(spDataPackage4->add_ShareCanceled(canceledCallback.Get(),
554 &dataRequestedToken))) {
555 return Err(NS_ERROR_FAILURE);
559 return Ok();
561 #endif
563 RefPtr<SharePromise> WindowsUIUtils::Share(nsAutoString aTitle,
564 nsAutoString aText,
565 nsAutoString aUrl) {
566 auto promiseHolder = MakeRefPtr<
567 mozilla::media::Refcountable<MozPromiseHolder<SharePromise>>>();
568 RefPtr<SharePromise> promise = promiseHolder->Ensure(__func__);
570 #ifndef __MINGW32__
571 auto result = RequestShare([promiseHolder, title = std::move(aTitle),
572 text = std::move(aText), url = std::move(aUrl)](
573 IDataRequestedEventArgs* pArgs) {
574 ComPtr<IDataRequest> spDataRequest;
575 ComPtr<IDataPackage> spDataPackage;
576 ComPtr<IDataPackage2> spDataPackage2;
577 ComPtr<IDataPackagePropertySet> spDataPackageProperties;
579 if (FAILED(pArgs->get_Request(&spDataRequest)) ||
580 FAILED(spDataRequest->get_Data(&spDataPackage)) ||
581 FAILED(spDataPackage.As(&spDataPackage2)) ||
582 FAILED(spDataPackage->get_Properties(&spDataPackageProperties))) {
583 promiseHolder->Reject(NS_ERROR_FAILURE, __func__);
584 return E_FAIL;
588 * Windows always requires a title, and an empty string does not work.
589 * Thus we trick the API by passing a whitespace when we have no title.
590 * https://docs.microsoft.com/en-us/windows/uwp/app-to-app/share-data
592 auto wTitle = ConvertToWindowsString((title.IsVoid() || title.Length() == 0)
593 ? nsAutoString(u" "_ns)
594 : title);
595 if (wTitle.isErr() ||
596 FAILED(spDataPackageProperties->put_Title(wTitle.unwrap().get()))) {
597 promiseHolder->Reject(NS_ERROR_FAILURE, __func__);
598 return E_FAIL;
601 // Assign even if empty, as Windows requires some data to share
602 auto wText = ConvertToWindowsString(text);
603 if (wText.isErr() || FAILED(spDataPackage->SetText(wText.unwrap().get()))) {
604 promiseHolder->Reject(NS_ERROR_FAILURE, __func__);
605 return E_FAIL;
608 if (!url.IsVoid()) {
609 auto wUrl = ConvertToWindowsString(url);
610 if (wUrl.isErr()) {
611 promiseHolder->Reject(NS_ERROR_FAILURE, __func__);
612 return wUrl.unwrapErr();
615 ComPtr<IUriRuntimeClassFactory> uriFactory;
616 ComPtr<IUriRuntimeClass> uri;
618 auto hr = GetActivationFactory(
619 HStringReference(RuntimeClass_Windows_Foundation_Uri).Get(),
620 &uriFactory);
622 if (FAILED(hr) ||
623 FAILED(uriFactory->CreateUri(wUrl.unwrap().get(), &uri)) ||
624 FAILED(spDataPackage2->SetWebLink(uri.Get()))) {
625 promiseHolder->Reject(NS_ERROR_FAILURE, __func__);
626 return E_FAIL;
630 if (!StaticPrefs::widget_windows_share_wait_action_enabled()) {
631 promiseHolder->Resolve(true, __func__);
632 } else if (AddShareEventListeners(promiseHolder, spDataPackage).isErr()) {
633 promiseHolder->Reject(NS_ERROR_FAILURE, __func__);
634 return E_FAIL;
637 return S_OK;
639 if (result.isErr()) {
640 promiseHolder->Reject(result.unwrapErr(), __func__);
642 #else
643 promiseHolder->Reject(NS_ERROR_FAILURE, __func__);
644 #endif
646 return promise;
649 NS_IMETHODIMP
650 WindowsUIUtils::ShareUrl(const nsAString& aUrlToShare,
651 const nsAString& aShareTitle) {
652 nsAutoString text;
653 text.SetIsVoid(true);
654 WindowsUIUtils::Share(nsAutoString(aShareTitle), text,
655 nsAutoString(aUrlToShare));
656 return NS_OK;