Merge pull request #4245 from ctrlaltdavid/20301

CR for Job #20301 - Windows: If I'm running Interface go to a place via hifi://, don't start another instance of the app
This commit is contained in:
Brad Hefta-Gaub 2015-02-06 14:19:10 -08:00
commit a4541758cf
3 changed files with 90 additions and 0 deletions

View file

@ -23,6 +23,7 @@
// include this before QGLWidget, which includes an earlier version of OpenGL
#include "InterfaceConfig.h"
#include <QAbstractNativeEventFilter>
#include <QActionGroup>
#include <QColorDialog>
#include <QDesktopWidget>
@ -144,6 +145,37 @@ const QString SKIP_FILENAME = QStandardPaths::writableLocation(QStandardPaths::D
const QString DEFAULT_SCRIPTS_JS_URL = "http://s3.amazonaws.com/hifi-public/scripts/defaultScripts.js";
#ifdef Q_OS_WIN
class MyNativeEventFilter : public QAbstractNativeEventFilter {
public:
static MyNativeEventFilter& getInstance() {
static MyNativeEventFilter staticInstance;
return staticInstance;
}
bool nativeEventFilter(const QByteArray &eventType, void* msg, long* result) Q_DECL_OVERRIDE {
if (eventType == "windows_generic_MSG") {
MSG* message = (MSG*)msg;
if (message->message == UWM_IDENTIFY_INSTANCES) {
*result = UWM_IDENTIFY_INSTANCES;
return true;
}
if (message->message == WM_SHOWWINDOW) {
Application::getInstance()->getWindow()->showNormal();
}
if (message->message == WM_COPYDATA) {
COPYDATASTRUCT* pcds = (COPYDATASTRUCT*)(message->lParam);
QUrl url = QUrl((const char*)(pcds->lpData));
if (url.isValid() && url.scheme() == HIFI_URL_SCHEME) {
DependencyManager::get<AddressManager>()->handleLookupString(url.toString());
}
}
}
return false;
}
};
#endif
void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) {
QString logMessage = LogHandler::getInstance().printMessage((LogMsgType) type, context, message);
@ -244,6 +276,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
_aboutToQuit(false),
_notifiedPacketVersionMismatchThisDomain(false)
{
#ifdef Q_OS_WIN
installNativeEventFilter(&MyNativeEventFilter::getInstance());
#endif
_logger = new FileLogger(this); // After setting organization name in order to get correct directory
qInstallMessageHandler(messageHandler);

View file

@ -114,6 +114,11 @@ static const quint64 TOO_LONG_SINCE_LAST_SEND_DOWNSTREAM_AUDIO_STATS = 1 * USECS
static const QString INFO_HELP_PATH = "html/interface-welcome-allsvg.html";
static const QString INFO_EDIT_ENTITIES_PATH = "html/edit-entities-commands.html";
#ifdef Q_OS_WIN
static const UINT UWM_IDENTIFY_INSTANCES =
RegisterWindowMessage("UWM_IDENTIFY_INSTANCES_{8AB82783-B74A-4258-955B-8188C22AA0D6}");
#endif
class Application;
#if defined(qApp)
#undef qApp

View file

@ -15,9 +15,53 @@
#include <SharedUtil.h>
#include "AddressManager.h"
#include "Application.h"
#ifdef Q_OS_WIN
static BOOL CALLBACK enumWindowsCallback(HWND hWnd, LPARAM lParam) {
const UINT TIMEOUT = 200; // ms
DWORD response;
LRESULT result = SendMessageTimeout(hWnd, UWM_IDENTIFY_INSTANCES, 0, 0, SMTO_BLOCK | SMTO_ABORTIFHUNG, TIMEOUT, &response);
if (result == 0) { // Timeout; continue search.
return TRUE;
}
if (response == UWM_IDENTIFY_INSTANCES) {
HWND* target = (HWND*)lParam;
*target = hWnd;
return FALSE; // Found; terminate search.
}
return TRUE; // Not found; continue search.
}
#endif
int main(int argc, const char * argv[]) {
#ifdef Q_OS_WIN
// Run only one instance of Interface at a time.
HANDLE mutex = CreateMutex(NULL, FALSE, "High Fidelity Interface");
DWORD result = GetLastError();
if (result == ERROR_ALREADY_EXISTS || result == ERROR_ACCESS_DENIED) {
// Interface is already running.
HWND otherInstance = NULL;
EnumWindows(enumWindowsCallback, (LPARAM)&otherInstance);
if (otherInstance) {
ShowWindow(otherInstance, SW_RESTORE);
SetForegroundWindow(otherInstance);
QUrl url = QUrl(argv[1]);
if (url.isValid() && url.scheme() == HIFI_URL_SCHEME) {
COPYDATASTRUCT cds;
cds.cbData = strlen(argv[1]) + 1;
cds.lpData = (PVOID)argv[1];
SendMessage(otherInstance, WM_COPYDATA, 0, (LPARAM)&cds);
}
}
return 0;
}
#endif
QElapsedTimer startupTime;
startupTime.start();
@ -44,6 +88,11 @@ int main(int argc, const char * argv[]) {
qDebug( "Created QT Application.");
exitCode = app.exec();
}
#ifdef Q_OS_WIN
ReleaseMutex(mutex);
#endif
qDebug("Normal exit.");
return exitCode;
}