diff --git a/src/main.cpp b/src/main.cpp index b3d16248..718b13d8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,6 @@ #include "mainwindow.h" #include "qvapplication.h" +#include "qvwin32functions.h" #include @@ -15,7 +16,18 @@ int main(int argc, char *argv[]) parser.addHelpOption(); parser.addVersionOption(); parser.addPositionalArgument(QObject::tr("file"), QObject::tr("The file to open.")); +#if defined Q_OS_WIN && WIN32_LOADED + // Workaround for unicode characters getting mangled in certain cases. To support unicode arguments on + // Windows, QCoreApplication normally ignores argv and gets them from the Windows API instead. But this + // only happens if it thinks argv hasn't been modified prior to being passed into QCoreApplication's + // constructor. Certain characters like U+2033 (double prime) get converted differently in argv versus + // the value Qt is comparing with (__argv). This makes Qt incorrectly think the data was changed, and + // it skips fetching unicode arguments from the API. + // https://bugreports.qt.io/browse/QTBUG-125380 + parser.process(QVWin32Functions::getCommandLineArgs()); +#else parser.process(app); +#endif auto *window = QVApplication::newWindow(); if (!parser.positionalArguments().isEmpty()) diff --git a/src/qvwin32functions.cpp b/src/qvwin32functions.cpp index 33c2b1a5..056651e1 100644 --- a/src/qvwin32functions.cpp +++ b/src/qvwin32functions.cpp @@ -145,6 +145,22 @@ void QVWin32Functions::showOpenWithDialog(const QString &filePath, const QWindow qDebug() << "Failed launching open with dialog"; } +// Logic borrowed from Qt's private qWinCmdArgs function +QStringList QVWin32Functions::getCommandLineArgs() +{ + const QString cmdLine = QString::fromWCharArray(GetCommandLine()); + QStringList result; + int size; + if (wchar_t **argv = CommandLineToArgvW((const wchar_t *)cmdLine.utf16(), &size)) { + result.reserve(size); + wchar_t **argvEnd = argv + size; + for (wchar_t **a = argv; a < argvEnd; ++a) + result.append(QString::fromWCharArray(*a)); + LocalFree(argv); + } + return result; +} + QByteArray QVWin32Functions::getIccProfileForWindow(const QWindow *window) { QByteArray result; diff --git a/src/qvwin32functions.h b/src/qvwin32functions.h index 86faf78a..fee6163e 100644 --- a/src/qvwin32functions.h +++ b/src/qvwin32functions.h @@ -14,6 +14,8 @@ class QVWin32Functions static void showOpenWithDialog(const QString &filePath, const QWindow *parent); + static QStringList getCommandLineArgs(); + static QByteArray getIccProfileForWindow(const QWindow *window); };