Skip to content

Commit

Permalink
don't re-activate existing instances for .Rproj files
Browse files Browse the repository at this point in the history
  • Loading branch information
jjallaire committed Oct 21, 2011
1 parent c75d44d commit d27933a
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 9 deletions.
49 changes: 42 additions & 7 deletions src/cpp/desktop/DesktopMain.cpp
Expand Up @@ -11,6 +11,21 @@
*
*/

// TODO: test on other platforms

// TODO: open -a RStudio on the Mac

// TODO: file-system project double-click doesn't activate new one
// (this is because it is sending the message to the other?).
// I think we have a change for this -- must activate explicitly!

// TODO: no longer possible for projects to come in through file
// associations. nix that codepath

// TODO: click on project self should open options

// TODO: consider whether .Rdata should also not re-activate existing

#include <QtGui>
#include <QtWebKit>

Expand Down Expand Up @@ -172,6 +187,15 @@ QString verifyAndNormalizeFilename(QString filename)
return QString();
}

bool isNonProjectFilename(QString filename)
{
if (filename.isNull() || filename.isEmpty())
return false;

FilePath filePath(filename.toUtf8().constData());
return filePath.exists() && filePath.extensionLowerCase() != ".rproj";
}

bool dummy(const FileInfo& file)
{
return true;
Expand Down Expand Up @@ -212,15 +236,26 @@ int main(int argc, char* argv[])
pApp->processEvents();
filename = verifyAndNormalizeFilename(
pAppLaunch->startupOpenFileRequest());
#else
// get filename from command line arguments
if (pApp->arguments().size() > 1)
filename = verifyAndNormalizeFilename(pApp->arguments().last());
#endif
// allow all platforms (including OSX) to check the command line.
// we include OSX because the way Qt handles apple events is to
// re-route them to the first instance to register for events. in
// this case (for projects) we use this to initiate a launch
// of the application with the project filename on the command line
if (filename.isEmpty())
{
// get filename from command line arguments
if (pApp->arguments().size() > 1)
filename = verifyAndNormalizeFilename(pApp->arguments().last());
}

// try to activate existing instance...exit if we do
if (pAppLaunch->sendMessage(filename))
return 0;
// if we have a filename and it is NOT a project file then see
// if we can open it within an existing instance
if (isNonProjectFilename(filename))
{
if (pAppLaunch->sendMessage(filename))
return 0;
}

pApp->setAttribute(Qt::AA_MacDontSwapCtrlAndMeta);

Expand Down
12 changes: 12 additions & 0 deletions src/cpp/desktop/DesktopOptions.cpp
Expand Up @@ -190,6 +190,18 @@ void Options::setPreferR64(bool preferR64)
}
#endif

FilePath Options::executablePath() const
{
if (executablePath_.empty())
{
Error error = core::system::executablePath(QApplication::argc(),
QApplication::argv(),
&executablePath_);
if (error)
LOG_ERROR(error);
}
return executablePath_;
}

FilePath Options::supportingFilePath() const
{
Expand Down
2 changes: 2 additions & 0 deletions src/cpp/desktop/DesktopOptions.hpp
Expand Up @@ -53,6 +53,7 @@ class Options : boost::noncopyable
void setPreferR64(bool preferR64);
#endif

core::FilePath executablePath() const;
core::FilePath supportingFilePath() const;

QStringList ignoredUpdateVersions() const;
Expand All @@ -72,6 +73,7 @@ class Options : boost::noncopyable
friend Options& options();

QSettings settings_;
mutable core::FilePath executablePath_;
mutable core::FilePath supportingFilePath_;
mutable QString portNumber_;
};
Expand Down
31 changes: 29 additions & 2 deletions src/cpp/desktop/DesktopPosixApplication.cpp
Expand Up @@ -13,9 +13,15 @@

#include "DesktopPosixApplication.hpp"

#include <core/FilePath.hpp>

#include <QProcess>
#include <QFileOpenEvent>

#include "DesktopOptions.hpp"

using namespace core;

namespace desktop {

bool PosixApplication::event(QEvent* pEvent)
Expand All @@ -37,7 +43,29 @@ bool PosixApplication::event(QEvent* pEvent)
{
// otherwise we are already running so this is an apple event
// targeted at opening a file in an existing instance
openFileRequest(filename);

// if this is a project then re-post the request back to
// another instance using the command line (this is to
// circumvent the fact that the first RStudio application
// launched on OSX gets all of the apple events). note that
// we don't make this code conditional for __APPLE__ because
// we'd need the same logic if other platforms started posting
// FileOpen back to existing instances (e.g. via DDE)

FilePath filePath(filename.toUtf8().constData());
if (filePath.exists() && filePath.extensionLowerCase() == ".rproj")
{
// launch the new instance
QStringList args;
args.append(filename);
QString exePath = QString::fromUtf8(
desktop::options().executablePath().absolutePath().c_str());
QProcess::startDetached(exePath, args);
}
else
{
openFileRequest(filename);
}
}

return true;
Expand All @@ -48,5 +76,4 @@ bool PosixApplication::event(QEvent* pEvent)
}
}


} // namespace desktop

0 comments on commit d27933a

Please sign in to comment.