2727#include " nsXULAppAPI.h"
2828#include " mozilla/WindowsVersion.h"
2929#include " mozilla/dom/Element.h"
30+ #include " mozilla/dom/Promise.h"
31+ #include " mozilla/ErrorResult.h"
3032#include " mozilla/gfx/2D.h"
3133#include " WindowsDefaultBrowser.h"
3234
@@ -883,26 +885,23 @@ nsWindowsShellService::CheckPinCurrentAppToTaskbar() {
883885 return PinCurrentAppToTaskbarImpl (/* aCheckOnly */ true );
884886}
885887
886- NS_IMETHODIMP
887- nsWindowsShellService::IsCurrentAppPinnedToTaskbar (/* out */ bool * aIsPinned) {
888- *aIsPinned = false ;
889-
888+ static bool IsCurrentAppPinnedToTaskbarSync () {
890889 wchar_t exePath[MAXPATHLEN ] = {};
891890 if (NS_WARN_IF (NS_FAILED (BinaryPath::GetLong (exePath)))) {
892- return NS_OK ;
891+ return false ;
893892 }
894893
895894 wchar_t folderChars[MAX_PATH ] = {};
896895 HRESULT hr = SHGetFolderPathW (nullptr , CSIDL_APPDATA , nullptr ,
897896 SHGFP_TYPE_CURRENT , folderChars);
898897 if (NS_WARN_IF (FAILED (hr))) {
899- return NS_OK ;
898+ return false ;
900899 }
901900
902901 nsAutoString folder;
903902 folder.Assign (folderChars);
904903 if (NS_WARN_IF (folder.IsEmpty ())) {
905- return NS_OK ;
904+ return false ;
906905 }
907906 if (folder[folder.Length () - 1 ] != ' \\ ' ) {
908907 folder.AppendLiteral (" \\ " );
@@ -917,12 +916,13 @@ nsWindowsShellService::IsCurrentAppPinnedToTaskbar(/* out */ bool* aIsPinned) {
917916 HANDLE hFindFile = FindFirstFileW (pattern.get (), &findData);
918917 if (hFindFile == INVALID_HANDLE_VALUE ) {
919918 Unused << NS_WARN_IF (GetLastError () != ERROR_FILE_NOT_FOUND );
920- return NS_OK ;
919+ return false ;
921920 }
922921 // Past this point we don't return until the end of the function,
923922 // when FindClose() is called.
924923
925924 // Check all shortcuts until a match is found
925+ bool isPinned = false ;
926926 do {
927927 nsAutoString fileName;
928928 fileName.Assign (folder);
@@ -965,13 +965,57 @@ nsWindowsShellService::IsCurrentAppPinnedToTaskbar(/* out */ bool* aIsPinned) {
965965 // NOTE: Because this compares the path directly, it is possible to
966966 // have a false negative mismatch.
967967 if (wcsnicmp (storedExePath, exePath, MAXPATHLEN ) == 0 ) {
968- *aIsPinned = true ;
968+ isPinned = true ;
969969 break ;
970970 }
971971 } while (FindNextFileW (hFindFile, &findData));
972972
973973 FindClose (hFindFile);
974974
975+ return isPinned;
976+ }
977+
978+ NS_IMETHODIMP
979+ nsWindowsShellService::IsCurrentAppPinnedToTaskbarAsync (
980+ JSContext* aCx, /* out */ dom::Promise** aPromise) {
981+ if (!NS_IsMainThread()) {
982+ return NS_ERROR_NOT_SAME_THREAD ;
983+ }
984+
985+ ErrorResult rv;
986+ RefPtr<dom::Promise> promise =
987+ dom::Promise::Create (xpc::CurrentNativeGlobal (aCx), rv);
988+ if (MOZ_UNLIKELY (rv.Failed ())) {
989+ return rv.StealNSResult ();
990+ }
991+
992+ // A holder to pass the promise through the background task and back to
993+ // the main thread when finished.
994+ auto promiseHolder = MakeRefPtr<nsMainThreadPtrHolder<dom::Promise>>(
995+ " IsCurrentAppPinnedToTaskbarAsync promise" , promise);
996+
997+ NS_DispatchBackgroundTask (
998+ NS_NewRunnableFunction (
999+ " IsCurrentAppPinnedToTaskbarAsync" ,
1000+ [promiseHolder = std::move(promiseHolder)] {
1001+ bool isPinned = false ;
1002+
1003+ HRESULT hr = CoInitialize (nullptr );
1004+ if (SUCCEEDED (hr)) {
1005+ isPinned = IsCurrentAppPinnedToTaskbarSync ();
1006+ CoUninitialize ();
1007+ }
1008+
1009+ // Dispatch back to the main thread to resolve the promise.
1010+ NS_DispatchToMainThread (NS_NewRunnableFunction(
1011+ " IsCurrentAppPinnedToTaskbarAsync callback" ,
1012+ [isPinned, promiseHolder = std::move(promiseHolder)] {
1013+ promiseHolder.get ()->get ()->MaybeResolve (isPinned);
1014+ }));
1015+ }),
1016+ NS_DISPATCH_EVENT_MAY_BLOCK);
1017+
1018+ promise.forget (aPromise);
9751019 return NS_OK ;
9761020}
9771021
0 commit comments