Skip to content

Commit

Permalink
Merge pull request #680 from jdpurcell/issue679
Browse files Browse the repository at this point in the history
Windows: Fix rare argument parsing bug
  • Loading branch information
jurplel authored May 19, 2024
2 parents 2784049 + 1ea42f1 commit bd62c7c
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 0 deletions.
12 changes: 12 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "mainwindow.h"
#include "qvapplication.h"
#include "qvwin32functions.h"

#include <QCommandLineParser>

Expand All @@ -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())
Expand Down
16 changes: 16 additions & 0 deletions src/qvwin32functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions src/qvwin32functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ class QVWin32Functions

static void showOpenWithDialog(const QString &filePath, const QWindow *parent);

static QStringList getCommandLineArgs();

static QByteArray getIccProfileForWindow(const QWindow *window);
};

Expand Down

0 comments on commit bd62c7c

Please sign in to comment.