forked from mirrors/gecko-dev
Bug 1863636 - Folded shortcut creation required for taskbar tabs into nsWindowsShellService r=mhughes
Differential Revision: https://phabricator.services.mozilla.com/D192998
This commit is contained in:
parent
2b372da017
commit
8a0825c269
3 changed files with 95 additions and 19 deletions
|
|
@ -162,6 +162,9 @@ const PREF_PRIVATE_BROWSING_SHORTCUT_CREATED =
|
|||
// Whether this launch was initiated by the OS. A launch-on-login will contain
|
||||
// the "os-autostart" flag in the initial launch command line.
|
||||
let gThisInstanceIsLaunchOnLogin = false;
|
||||
// Whether this launch was initiated by a taskbar tab shortcut. A launch from
|
||||
// a taskbar tab shortcut will contain the "taskbar-tab" flag.
|
||||
let gThisInstanceIsTaskbarTab = false;
|
||||
|
||||
/**
|
||||
* Fission-compatible JSProcess implementations.
|
||||
|
|
@ -1223,6 +1226,7 @@ BrowserGlue.prototype = {
|
|||
break;
|
||||
case "app-startup":
|
||||
this._earlyBlankFirstPaint(subject);
|
||||
gThisInstanceIsTaskbarTab = subject.handleFlag("taskbar-tab", false);
|
||||
gThisInstanceIsLaunchOnLogin = subject.handleFlag(
|
||||
"os-autostart",
|
||||
false
|
||||
|
|
@ -2601,7 +2605,11 @@ BrowserGlue.prototype = {
|
|||
classification = "Other";
|
||||
}
|
||||
}
|
||||
|
||||
// Because of how taskbar tabs work, it may be classifed as a taskbar
|
||||
// shortcut, in which case we want to overwrite it.
|
||||
if (gThisInstanceIsTaskbarTab) {
|
||||
classification = "TaskbarTab";
|
||||
}
|
||||
Services.telemetry.scalarSet(
|
||||
"os.environment.launch_method",
|
||||
classification
|
||||
|
|
|
|||
|
|
@ -126,6 +126,46 @@ interface nsIWindowsShellService : nsISupports
|
|||
[implicit_jscontext]
|
||||
Promise isCurrentAppPinnedToTaskbarAsync(in AString aumid);
|
||||
|
||||
/*
|
||||
* Similar to createShortcut except it removes most of the checking in that
|
||||
* function that ensures we are pinning a Firefox executable instead allowing
|
||||
* any shortcut to be pinned.
|
||||
*
|
||||
* This function should not be called unless it is certain that it's
|
||||
* necessary given how few checks there are within.
|
||||
* @param aShortcutPath
|
||||
* A path to the .lnk file that should be pinned to the taskbar.
|
||||
* @throws NS_ERROR_FAILURE
|
||||
* If the COM service could not be initialized
|
||||
* @throws NS_ERROR_FILE_NOT_FOUND
|
||||
* If aShortcutPath cannot be found
|
||||
* @throws NS_ERROR_NOT_AVAILABLE
|
||||
* If the taskbar pinning service cannot be initialized
|
||||
* @throws NS_ERROR_FILE_ACCESS_DENIED
|
||||
* If the taskbar pins cannot be modified
|
||||
*/
|
||||
void pinShortcutToTaskbar(in AString aShortcutPath);
|
||||
|
||||
/*
|
||||
* This function is a counterpart to pinShortcutToTaskbar and allows
|
||||
* the unpinning of any shortcut, including non-Firefox executables,
|
||||
* without the checks of createShortcut.
|
||||
*
|
||||
* This function should not be called unless it is certain that it's
|
||||
* necessary given how few checks there are within.
|
||||
* @param aShortcutPath
|
||||
* A path to the .lnk file that should be pinned to the taskbar.
|
||||
* @throws NS_ERROR_FAILURE
|
||||
* If the COM service could not be initialized
|
||||
* @throws NS_ERROR_FILE_NOT_FOUND
|
||||
* If aShortcutPath cannot be found
|
||||
* @throws NS_ERROR_NOT_AVAILABLE
|
||||
* If the taskbar pinning service cannot be initialized
|
||||
* @throws NS_ERROR_FILE_ACCESS_DENIED
|
||||
* If the taskbar pins cannot be modified
|
||||
*/
|
||||
void unpinShortcutFromTaskbar(in AString aShortcutPath);
|
||||
|
||||
/*
|
||||
* Determine where a given shortcut likely appears in the shell.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1278,9 +1278,8 @@ static bool IsCurrentAppPinnedToTaskbarSync(const nsAString& aumid) {
|
|||
return isPinned;
|
||||
}
|
||||
|
||||
static nsresult PinCurrentAppToTaskbarWin10(bool aCheckOnly,
|
||||
const nsAString& aAppUserModelId,
|
||||
nsAutoString aShortcutPath) {
|
||||
static nsresult ManageShortcutTaskbarPins(bool aCheckOnly, bool aPinType,
|
||||
const nsAString& aShortcutPath) {
|
||||
// This enum is likely only used for Windows telemetry, INT_MAX is chosen to
|
||||
// avoid confusion with existing uses.
|
||||
enum PINNEDLISTMODIFYCALLER { PLMC_INT_MAX = INT_MAX };
|
||||
|
|
@ -1325,36 +1324,65 @@ static nsresult PinCurrentAppToTaskbarWin10(bool aCheckOnly,
|
|||
}
|
||||
};
|
||||
|
||||
mozilla::UniquePtr<__unaligned ITEMIDLIST, ILFreeDeleter> path(
|
||||
ILCreateFromPathW(aShortcutPath.get()));
|
||||
if (NS_WARN_IF(!path)) {
|
||||
HRESULT hr = CoInitialize(nullptr);
|
||||
if (FAILED(hr)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
const struct ComUninitializer {
|
||||
~ComUninitializer() { CoUninitialize(); }
|
||||
} kCUi;
|
||||
|
||||
mozilla::UniquePtr<__unaligned ITEMIDLIST, ILFreeDeleter> path(
|
||||
ILCreateFromPathW(nsString(aShortcutPath).get()));
|
||||
if (NS_WARN_IF(!path)) {
|
||||
return NS_ERROR_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
IPinnedList3* pinnedList = nullptr;
|
||||
HRESULT hr =
|
||||
CoCreateInstance(CLSID_TaskbandPin, nullptr, CLSCTX_INPROC_SERVER,
|
||||
IID_IPinnedList3, (void**)&pinnedList);
|
||||
hr = CoCreateInstance(CLSID_TaskbandPin, NULL, CLSCTX_INPROC_SERVER,
|
||||
IID_IPinnedList3, (void**)&pinnedList);
|
||||
if (FAILED(hr) || !pinnedList) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
if (!aCheckOnly) {
|
||||
bool isPinned = false;
|
||||
isPinned = IsCurrentAppPinnedToTaskbarSync(aAppUserModelId);
|
||||
if (!isPinned) {
|
||||
hr = pinnedList->vtbl->Modify(pinnedList, nullptr, path.get(),
|
||||
PLMC_INT_MAX);
|
||||
}
|
||||
hr = pinnedList->vtbl->Modify(pinnedList, aPinType ? NULL : path.get(),
|
||||
aPinType ? path.get() : NULL, PLMC_INT_MAX);
|
||||
}
|
||||
|
||||
pinnedList->vtbl->Release(pinnedList);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
} else {
|
||||
return NS_OK;
|
||||
return NS_ERROR_FILE_ACCESS_DENIED;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowsShellService::PinShortcutToTaskbar(const nsAString& aShortcutPath) {
|
||||
const bool pinType = true; // true means pin
|
||||
const bool runInTestMode = false;
|
||||
return ManageShortcutTaskbarPins(runInTestMode, pinType, aShortcutPath);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowsShellService::UnpinShortcutFromTaskbar(
|
||||
const nsAString& aShortcutPath) {
|
||||
const bool pinType = false; // false means unpin
|
||||
const bool runInTestMode = false;
|
||||
return ManageShortcutTaskbarPins(runInTestMode, pinType, aShortcutPath);
|
||||
}
|
||||
|
||||
static nsresult PinCurrentAppToTaskbarWin10(bool aCheckOnly,
|
||||
const nsAString& aAppUserModelId,
|
||||
nsAutoString aShortcutPath) {
|
||||
// The behavior here is identical if we're only checking or if we try to pin
|
||||
// but the app is already pinned so we update the variable accordingly.
|
||||
if (!aCheckOnly) {
|
||||
aCheckOnly = !IsCurrentAppPinnedToTaskbarSync(aAppUserModelId);
|
||||
}
|
||||
const bool pinType = true; // true means pin
|
||||
return ManageShortcutTaskbarPins(aCheckOnly, pinType, aShortcutPath);
|
||||
}
|
||||
|
||||
static nsresult PinCurrentAppToTaskbarImpl(
|
||||
|
|
|
|||
Loading…
Reference in a new issue