Bug 924911 - Change View on Desktop feature to be switch to Desktop feature. r=bbondy

This commit is contained in:
Marina Samuel 2013-11-19 12:47:23 -05:00
parent 5b674e0d13
commit 9698960f17
9 changed files with 150 additions and 77 deletions

View File

@ -126,16 +126,7 @@ var Appbar = {
if (!Services.metro.immersive)
typesArray.push("open-jsshell");
try {
// If we have a valid http or https URI then show the view on desktop
// menu item.
let uri = Services.io.newURI(Browser.selectedBrowser.currentURI.spec,
null, null);
if (uri.schemeIs('http') || uri.schemeIs('https')) {
typesArray.push("view-on-desktop");
}
} catch(ex) {
}
typesArray.push("view-on-desktop");
var x = this.menuButton.getBoundingClientRect().left;
var y = Elements.toolbar.getBoundingClientRect().top;
@ -153,16 +144,11 @@ var Appbar = {
},
onViewOnDesktop: function() {
try {
// Make sure we have a valid URI so Windows doesn't prompt
// with an unrecognized command, select default program window
var uri = Services.io.newURI(Browser.selectedBrowser.currentURI.spec,
null, null);
if (uri.schemeIs('http') || uri.schemeIs('https')) {
Services.metro.launchInDesktop(Browser.selectedBrowser.currentURI.spec, "");
}
} catch(ex) {
}
let appStartup = Components.classes["@mozilla.org/toolkit/app-startup;1"].
getService(Components.interfaces.nsIAppStartup);
appStartup.quit(Components.interfaces.nsIAppStartup.eAttemptQuit |
Components.interfaces.nsIAppStartup.eRestart);
},
onAutocompleteCloseButton: function () {

View File

@ -784,7 +784,7 @@
<label value="&appbarFindInPage2.label;"/>
</richlistitem>
<richlistitem id="context-viewondesktop" type="view-on-desktop" onclick="ContextCommands.viewOnDesktop();">
<label value="&appbarViewOnDesktop2.label;"/>
<label value="&appbarRelaunchInDesktop.label;"/>
</richlistitem>
<richlistitem id="context-msmetadata" type="ms-meta-data" onclick="ContextCommands.openWindowsStoreLink();">
<label value="&appbarMSMetaData2.label;"/>

View File

@ -279,7 +279,7 @@ appUpdater.prototype =
}
appStartup.quit(Components.interfaces.nsIAppStartup.eAttemptQuit |
Components.interfaces.nsIAppStartup.eRestart);
Components.interfaces.nsIAppStartup.eRestartTouchEnvironment);
return;
}

View File

@ -13,12 +13,12 @@
<!ENTITY autocompleteResultsHeader.label "Your Results">
<!ENTITY appbarErrorConsole.label "Open error console">
<!ENTITY appbarJSShell.label "Open JavaScript shell">
<!ENTITY appbarFindInPage2.label "Find in page">
<!ENTITY appbarViewOnDesktop2.label "View on desktop">
<!ENTITY appbarMSMetaData2.label "Get app for this site">
<!ENTITY appbarViewPageSource.label "View page source">
<!ENTITY appbarErrorConsole.label "Open error console">
<!ENTITY appbarJSShell.label "Open JavaScript shell">
<!ENTITY appbarFindInPage2.label "Find in page">
<!ENTITY appbarRelaunchInDesktop.label "Relaunch in Desktop">
<!ENTITY appbarMSMetaData2.label "Get app for this site">
<!ENTITY appbarViewPageSource.label "View page source">
<!ENTITY topSitesHeader.label "Top Sites">
<!ENTITY bookmarksHeader.label "Bookmarks">

View File

@ -44,6 +44,7 @@ static const WCHAR* kFirefoxExe = L"firefox.exe";
static const WCHAR* kMetroFirefoxExe = L"firefox.exe";
static const WCHAR* kDefaultMetroBrowserIDPathKey = L"FirefoxURL";
static const WCHAR* kMetroRestartCmdLine = L"--metro-restart";
static const WCHAR* kDesktopRestartCmdLine = L"--desktop-restart";
static bool GetDefaultBrowserPath(CStringW& aPathBuffer);
@ -104,7 +105,9 @@ public:
mTargetIsBrowser(false),
mIsDesktopRequest(true),
mIsRestartMetroRequest(false),
mRequestMet(false)
mIsRestartDesktopRequest(false),
mRequestMet(false),
mVerb(L"open")
{
}
@ -152,6 +155,8 @@ public:
if (_wcsicmp(aParameters, kMetroRestartCmdLine) == 0) {
mIsRestartMetroRequest = true;
} else if (_wcsicmp(aParameters, kDesktopRestartCmdLine) == 0) {
mIsRestartDesktopRequest = true;
} else {
mParameters = aParameters;
}
@ -265,6 +270,11 @@ public:
return S_OK;
}
if (mIsRestartDesktopRequest) {
Log(L"Restarting in desktop host environment.");
return S_OK;
}
HRESULT hr;
IServiceProvider* pSvcProvider = nullptr;
hr = mUnkSite->QueryInterface(IID_IServiceProvider, (void**)&pSvcProvider);
@ -416,6 +426,7 @@ private:
DWORD mKeyState;
bool mIsDesktopRequest;
bool mIsRestartMetroRequest;
bool mIsRestartDesktopRequest;
bool mRequestMet;
};
@ -574,6 +585,48 @@ bool CExecuteCommandVerb::SetTargetPath(IShellItem* aItem)
* Desktop launch - Launch the destop browser to display the current
* target using shellexecute.
*/
void LaunchDesktopBrowserWithParams(CStringW& aBrowserPath, CStringW& aVerb, CStringW& aTarget, CStringW& aParameters,
bool aTargetIsDefaultBrowser, bool aTargetIsBrowser)
{
// If a taskbar shortcut, link or local file is clicked, the target will
// be the browser exe or file. Don't pass in -url for the target if the
// target is known to be a browser. Otherwise, one instance of Firefox
// will try to open another instance.
CStringW params;
if (!aTargetIsDefaultBrowser && !aTargetIsBrowser && !aTarget.IsEmpty()) {
// Fallback to the module path if it failed to get the default browser.
GetDefaultBrowserPath(aBrowserPath);
params += "-url ";
params += "\"";
params += aTarget;
params += "\"";
}
// Tack on any extra parameters we received (for example -profilemanager)
if (!aParameters.IsEmpty()) {
params += " ";
params += aParameters;
}
Log(L"Desktop Launch: verb:%s exe:%s params:%s", aVerb, aBrowserPath, params);
SHELLEXECUTEINFOW seinfo;
memset(&seinfo, 0, sizeof(seinfo));
seinfo.cbSize = sizeof(SHELLEXECUTEINFOW);
seinfo.fMask = SEE_MASK_FLAG_LOG_USAGE;
seinfo.lpVerb = aVerb;
seinfo.lpFile = aBrowserPath;
seinfo.nShow = SW_SHOWNORMAL;
// Relaunch in Desktop mode uses a special URL to trick Windows into
// switching environments. We shouldn't actually try to open this URL
if (_wcsicmp(aTarget, L"http://-desktop/") != 0) {
seinfo.lpParameters = params;
}
ShellExecuteEx(&seinfo);
}
void CExecuteCommandVerb::LaunchDesktopBrowser()
{
CStringW browserPath;
@ -581,40 +634,7 @@ void CExecuteCommandVerb::LaunchDesktopBrowser()
return;
}
// If a taskbar shortcut, link or local file is clicked, the target will
// be the browser exe or file. Don't pass in -url for the target if the
// target is known to be a browser. Otherwise, one instance of Firefox
// will try to open another instance.
CStringW params;
if (!mTargetIsDefaultBrowser && !mTargetIsBrowser && !mTarget.IsEmpty()) {
// Fallback to the module path if it failed to get the default browser.
GetDefaultBrowserPath(browserPath);
params += "-url ";
params += "\"";
params += mTarget;
params += "\"";
}
// Tack on any extra parameters we received (for example -profilemanager)
if (!mParameters.IsEmpty()) {
params += " ";
params += mParameters;
}
Log(L"Desktop Launch: verb:%s exe:%s params:%s", mVerb, browserPath, params);
SHELLEXECUTEINFOW seinfo;
memset(&seinfo, 0, sizeof(seinfo));
seinfo.cbSize = sizeof(SHELLEXECUTEINFOW);
seinfo.fMask = 0;
seinfo.hwnd = nullptr;
seinfo.lpVerb = nullptr;
seinfo.lpFile = browserPath;
seinfo.lpParameters = params;
seinfo.lpDirectory = nullptr;
seinfo.nShow = SW_SHOWNORMAL;
ShellExecuteExW(&seinfo);
LaunchDesktopBrowserWithParams(browserPath, mVerb, mTarget, mParameters, mTargetIsDefaultBrowser, mTargetIsBrowser);
}
class AutoSetRequestMet
@ -705,6 +725,21 @@ IFACEMETHODIMP CExecuteCommandVerb::Execute()
return S_OK;
}
if (mIsRestartDesktopRequest) {
CStringW browserPath;
if (!GetDesktopBrowserPath(browserPath)) {
return E_FAIL;
}
LaunchDesktopBrowserWithParams(browserPath,
mVerb,
mTarget,
mParameters,
mTargetIsDefaultBrowser,
mTargetIsBrowser);
return S_OK;
}
// We shut down when this flips to true
AutoSetRequestMet asrm(&mRequestMet);
@ -728,8 +763,7 @@ IFACEMETHODIMP CExecuteCommandVerb::Execute()
return S_OK;
}
Log(L"Metro Launch: verb:%s appid:%s params:%s", mVerb, appModelID, mTarget);
Log(L"Metro Launch: verb:%s appid:%s params:%s", mVerb, appModelID, mTarget);
// shortcuts to the application
DWORD processID;

View File

@ -141,7 +141,8 @@ nsAppStartup::nsAppStartup() :
mRestart(false),
mInterrupted(false),
mIsSafeModeNecessary(false),
mStartupCrashTrackingEnded(false)
mStartupCrashTrackingEnded(false),
mRestartTouchEnvironment(false)
{ }
@ -269,7 +270,7 @@ nsAppStartup::Run(void)
return rv;
}
return mRestart ? NS_SUCCESS_RESTART_APP : NS_OK;
return (mRestart || mRestartTouchEnvironment) ? NS_SUCCESS_RESTART_APP : NS_OK;
}
@ -360,7 +361,12 @@ nsAppStartup::Quit(uint32_t aMode)
gRestartMode = (aMode & 0xF0);
}
if (mRestart) {
if (!mRestartTouchEnvironment) {
mRestartTouchEnvironment = (aMode & eRestartTouchEnvironment) != 0;
gRestartMode = (aMode & 0xF0);
}
if (mRestart || mRestartTouchEnvironment) {
// Mark the next startup as a restart.
PR_SetEnv("MOZ_APP_RESTART=1");
@ -430,7 +436,8 @@ nsAppStartup::Quit(uint32_t aMode)
NS_NAMED_LITERAL_STRING(shutdownStr, "shutdown");
NS_NAMED_LITERAL_STRING(restartStr, "restart");
obsService->NotifyObservers(nullptr, "quit-application",
mRestart ? restartStr.get() : shutdownStr.get());
(mRestart || mRestartTouchEnvironment) ?
restartStr.get() : shutdownStr.get());
}
if (!mRunning) {
@ -553,6 +560,14 @@ nsAppStartup::GetWasRestarted(bool *aResult)
return NS_OK;
}
NS_IMETHODIMP
nsAppStartup::GetRestartingTouchEnvironment(bool *aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
*aResult = mRestartTouchEnvironment;
return NS_OK;
}
NS_IMETHODIMP
nsAppStartup::SetInterrupted(bool aInterrupted)
{

View File

@ -62,6 +62,7 @@ private:
bool mInterrupted; // Was startup interrupted by an interactive prompt?
bool mIsSafeModeNecessary; // Whether safe mode is necessary
bool mStartupCrashTrackingEnded; // Whether startup crash tracking has already ended
bool mRestartTouchEnvironment; // Quit (eRestartTouchEnvironment)
#if defined(XP_WIN)
//Interaction with OS-provided profiling probes

View File

@ -7,7 +7,8 @@
interface nsICmdLineService;
[scriptable, uuid(9edef217-e664-4938-85a7-2fe84baa1755)]
[scriptable, uuid(bc0cb41f-4924-4c69-a65b-e35225a8650f)]
interface nsIAppStartup : nsISupports
{
/**
@ -121,6 +122,13 @@ interface nsIAppStartup : nsISupports
*/
const uint32_t eRestartx86_64 = 0x40;
/**
* Restart the application in a touch-optimized environment (such as Metro)
* after quitting. The application will be restarted with the same profile
* and an empty command line.
*/
const uint32_t eRestartTouchEnvironment = 0x80;
/**
* Exit the event loop, and shut down the app.
*
@ -160,6 +168,12 @@ interface nsIAppStartup : nsISupports
*/
readonly attribute boolean wasRestarted;
/**
* True if the application is being restarted in a touch-optimized
* environment (such as Metro).
*/
readonly attribute boolean restartingTouchEnvironment;
/**
* Returns an object with main, process, firstPaint, sessionRestored properties.
* Properties may not be available depending on platform or application

View File

@ -15,6 +15,7 @@
#include "WinUtils.h"
#include "nsIAppStartup.h"
#include "nsToolkitCompsCID.h"
#include <shellapi.h>
using namespace mozilla;
using namespace mozilla::widget;
@ -113,7 +114,7 @@ HRESULT SHCreateShellItemArrayFromShellItemDynamic(IShellItem *psi, REFIID riid,
}
BOOL
WinLaunchDeferredMetroFirefox()
WinLaunchDeferredMetroFirefox(bool aInMetro)
{
// Create an instance of the Firefox Metro DEH which is used to launch the browser
const CLSID CLSID_FirefoxMetroDEH = {0x5100FEC1,0x212B, 0x4BF5 ,{0x9B,0xF8, 0x3E,0x65, 0x0F,0xD7,0x94,0xA3}};
@ -159,7 +160,11 @@ WinLaunchDeferredMetroFirefox()
if (FAILED(hr))
return FALSE;
hr = executeCommand->SetParameters(L"--metro-restart");
if (aInMetro) {
hr = executeCommand->SetParameters(L"--metro-restart");
} else {
hr = executeCommand->SetParameters(L"--desktop-restart");
}
if (FAILED(hr))
return FALSE;
@ -195,17 +200,35 @@ MetroAppShell::Run(void)
mozilla::widget::StopAudioSession();
nsCOMPtr<nsIAppStartup> appStartup (do_GetService(NS_APPSTARTUP_CONTRACTID));
bool restarting;
if (appStartup && NS_SUCCEEDED(appStartup->GetRestarting(&restarting)) && restarting) {
if (!WinLaunchDeferredMetroFirefox()) {
NS_WARNING("Couldn't deferred launch Metro Firefox.");
}
bool restartingInMetro = false, restarting = false;
if (appStartup && NS_SUCCEEDED(appStartup->GetRestartingTouchEnvironment(&restartingInMetro)) &&
restartingInMetro) {
WinLaunchDeferredMetroFirefox(true);
}
if (!appStartup || NS_FAILED(appStartup->GetRestarting(&restarting))) {
WinUtils::Log("appStartup->GetRestarting() unsuccessful");
}
// This calls XRE_metroShutdown() in xre. This will also destroy
// MessagePump.
sMetroApp->ShutdownXPCOM();
if (restarting) {
SHELLEXECUTEINFOW sinfo;
memset(&sinfo, 0, sizeof(SHELLEXECUTEINFOW));
sinfo.cbSize = sizeof(SHELLEXECUTEINFOW);
// Per the Metro style enabled desktop browser, for some reason,
// SEE_MASK_FLAG_LOG_USAGE is needed to change from immersive mode
// to desktop.
sinfo.fMask = SEE_MASK_FLAG_LOG_USAGE;
sinfo.lpFile = L"http://-desktop";
sinfo.lpVerb = L"open";
sinfo.nShow = SW_SHOWNORMAL;
ShellExecuteEx(&sinfo);
}
// This will free the real main thread in CoreApplication::Run()
// once winrt cleans up this thread.
sMetroApp->CoreExit();