Skip to content

Commit 8a0825c

Browse files
committed
Bug 1863636 - Folded shortcut creation required for taskbar tabs into nsWindowsShellService r=mhughes
Differential Revision: https://phabricator.services.mozilla.com/D192998
1 parent 2b372da commit 8a0825c

File tree

3 files changed

+94
-18
lines changed

3 files changed

+94
-18
lines changed

browser/components/BrowserGlue.sys.mjs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,9 @@ const PREF_PRIVATE_BROWSING_SHORTCUT_CREATED =
162162
// Whether this launch was initiated by the OS. A launch-on-login will contain
163163
// the "os-autostart" flag in the initial launch command line.
164164
let gThisInstanceIsLaunchOnLogin = false;
165+
// Whether this launch was initiated by a taskbar tab shortcut. A launch from
166+
// a taskbar tab shortcut will contain the "taskbar-tab" flag.
167+
let gThisInstanceIsTaskbarTab = false;
165168

166169
/**
167170
* Fission-compatible JSProcess implementations.
@@ -1223,6 +1226,7 @@ BrowserGlue.prototype = {
12231226
break;
12241227
case "app-startup":
12251228
this._earlyBlankFirstPaint(subject);
1229+
gThisInstanceIsTaskbarTab = subject.handleFlag("taskbar-tab", false);
12261230
gThisInstanceIsLaunchOnLogin = subject.handleFlag(
12271231
"os-autostart",
12281232
false
@@ -2601,7 +2605,11 @@ BrowserGlue.prototype = {
26012605
classification = "Other";
26022606
}
26032607
}
2604-
2608+
// Because of how taskbar tabs work, it may be classifed as a taskbar
2609+
// shortcut, in which case we want to overwrite it.
2610+
if (gThisInstanceIsTaskbarTab) {
2611+
classification = "TaskbarTab";
2612+
}
26052613
Services.telemetry.scalarSet(
26062614
"os.environment.launch_method",
26072615
classification

browser/components/shell/nsIWindowsShellService.idl

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,46 @@ interface nsIWindowsShellService : nsISupports
126126
[implicit_jscontext]
127127
Promise isCurrentAppPinnedToTaskbarAsync(in AString aumid);
128128

129+
/*
130+
* Similar to createShortcut except it removes most of the checking in that
131+
* function that ensures we are pinning a Firefox executable instead allowing
132+
* any shortcut to be pinned.
133+
*
134+
* This function should not be called unless it is certain that it's
135+
* necessary given how few checks there are within.
136+
* @param aShortcutPath
137+
* A path to the .lnk file that should be pinned to the taskbar.
138+
* @throws NS_ERROR_FAILURE
139+
* If the COM service could not be initialized
140+
* @throws NS_ERROR_FILE_NOT_FOUND
141+
* If aShortcutPath cannot be found
142+
* @throws NS_ERROR_NOT_AVAILABLE
143+
* If the taskbar pinning service cannot be initialized
144+
* @throws NS_ERROR_FILE_ACCESS_DENIED
145+
* If the taskbar pins cannot be modified
146+
*/
147+
void pinShortcutToTaskbar(in AString aShortcutPath);
148+
149+
/*
150+
* This function is a counterpart to pinShortcutToTaskbar and allows
151+
* the unpinning of any shortcut, including non-Firefox executables,
152+
* without the checks of createShortcut.
153+
*
154+
* This function should not be called unless it is certain that it's
155+
* necessary given how few checks there are within.
156+
* @param aShortcutPath
157+
* A path to the .lnk file that should be pinned to the taskbar.
158+
* @throws NS_ERROR_FAILURE
159+
* If the COM service could not be initialized
160+
* @throws NS_ERROR_FILE_NOT_FOUND
161+
* If aShortcutPath cannot be found
162+
* @throws NS_ERROR_NOT_AVAILABLE
163+
* If the taskbar pinning service cannot be initialized
164+
* @throws NS_ERROR_FILE_ACCESS_DENIED
165+
* If the taskbar pins cannot be modified
166+
*/
167+
void unpinShortcutFromTaskbar(in AString aShortcutPath);
168+
129169
/*
130170
* Determine where a given shortcut likely appears in the shell.
131171
*

browser/components/shell/nsWindowsShellService.cpp

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1278,9 +1278,8 @@ static bool IsCurrentAppPinnedToTaskbarSync(const nsAString& aumid) {
12781278
return isPinned;
12791279
}
12801280

1281-
static nsresult PinCurrentAppToTaskbarWin10(bool aCheckOnly,
1282-
const nsAString& aAppUserModelId,
1283-
nsAutoString aShortcutPath) {
1281+
static nsresult ManageShortcutTaskbarPins(bool aCheckOnly, bool aPinType,
1282+
const nsAString& aShortcutPath) {
12841283
// This enum is likely only used for Windows telemetry, INT_MAX is chosen to
12851284
// avoid confusion with existing uses.
12861285
enum PINNEDLISTMODIFYCALLER { PLMC_INT_MAX = INT_MAX };
@@ -1325,36 +1324,65 @@ static nsresult PinCurrentAppToTaskbarWin10(bool aCheckOnly,
13251324
}
13261325
};
13271326

1327+
HRESULT hr = CoInitialize(nullptr);
1328+
if (FAILED(hr)) {
1329+
return NS_ERROR_FAILURE;
1330+
}
1331+
const struct ComUninitializer {
1332+
~ComUninitializer() { CoUninitialize(); }
1333+
} kCUi;
1334+
13281335
mozilla::UniquePtr<__unaligned ITEMIDLIST, ILFreeDeleter> path(
1329-
ILCreateFromPathW(aShortcutPath.get()));
1336+
ILCreateFromPathW(nsString(aShortcutPath).get()));
13301337
if (NS_WARN_IF(!path)) {
1331-
return NS_ERROR_FAILURE;
1338+
return NS_ERROR_FILE_NOT_FOUND;
13321339
}
13331340

13341341
IPinnedList3* pinnedList = nullptr;
1335-
HRESULT hr =
1336-
CoCreateInstance(CLSID_TaskbandPin, nullptr, CLSCTX_INPROC_SERVER,
1337-
IID_IPinnedList3, (void**)&pinnedList);
1342+
hr = CoCreateInstance(CLSID_TaskbandPin, NULL, CLSCTX_INPROC_SERVER,
1343+
IID_IPinnedList3, (void**)&pinnedList);
13381344
if (FAILED(hr) || !pinnedList) {
13391345
return NS_ERROR_NOT_AVAILABLE;
13401346
}
13411347

13421348
if (!aCheckOnly) {
1343-
bool isPinned = false;
1344-
isPinned = IsCurrentAppPinnedToTaskbarSync(aAppUserModelId);
1345-
if (!isPinned) {
1346-
hr = pinnedList->vtbl->Modify(pinnedList, nullptr, path.get(),
1347-
PLMC_INT_MAX);
1348-
}
1349+
hr = pinnedList->vtbl->Modify(pinnedList, aPinType ? NULL : path.get(),
1350+
aPinType ? path.get() : NULL, PLMC_INT_MAX);
13491351
}
13501352

13511353
pinnedList->vtbl->Release(pinnedList);
13521354

13531355
if (FAILED(hr)) {
1354-
return NS_ERROR_FAILURE;
1355-
} else {
1356-
return NS_OK;
1356+
return NS_ERROR_FILE_ACCESS_DENIED;
1357+
}
1358+
return NS_OK;
1359+
}
1360+
1361+
NS_IMETHODIMP
1362+
nsWindowsShellService::PinShortcutToTaskbar(const nsAString& aShortcutPath) {
1363+
const bool pinType = true; // true means pin
1364+
const bool runInTestMode = false;
1365+
return ManageShortcutTaskbarPins(runInTestMode, pinType, aShortcutPath);
1366+
}
1367+
1368+
NS_IMETHODIMP
1369+
nsWindowsShellService::UnpinShortcutFromTaskbar(
1370+
const nsAString& aShortcutPath) {
1371+
const bool pinType = false; // false means unpin
1372+
const bool runInTestMode = false;
1373+
return ManageShortcutTaskbarPins(runInTestMode, pinType, aShortcutPath);
1374+
}
1375+
1376+
static nsresult PinCurrentAppToTaskbarWin10(bool aCheckOnly,
1377+
const nsAString& aAppUserModelId,
1378+
nsAutoString aShortcutPath) {
1379+
// The behavior here is identical if we're only checking or if we try to pin
1380+
// but the app is already pinned so we update the variable accordingly.
1381+
if (!aCheckOnly) {
1382+
aCheckOnly = !IsCurrentAppPinnedToTaskbarSync(aAppUserModelId);
13571383
}
1384+
const bool pinType = true; // true means pin
1385+
return ManageShortcutTaskbarPins(aCheckOnly, pinType, aShortcutPath);
13581386
}
13591387

13601388
static nsresult PinCurrentAppToTaskbarImpl(

0 commit comments

Comments
 (0)