From a78a284ca2668e058fdc8bcb63682b6f8fe11296 Mon Sep 17 00:00:00 2001
From: Sergey Fedorov <barracuda@macos-powerpc.org>
Date: Wed, 12 Aug 2026 19:11:10 +0000
Subject: [PATCH 2/2] Qt4: replace QFileSelector, QIcon::setIsMask(), and
 qsizetype

Three more Qt5/6-only APIs surfaced by the build:

- QFileSelector (the whole class) was added in Qt 5.2 and has no Qt4
  equivalent. Since Qt4 is only ever built for macOS in this project,
  replace its use for tray-icon theming with a small platformTrayIcon()
  helper: under Qt5.2+ it behaves exactly as before (QFileSelector), and
  under Qt4 it hand-resolves the same "+mac" selector this codebase
  already ships resources for (src/images/+mac/, openconnect-gui.qrc)
  by string-inserting "+mac/" before the filename -- the only two paths
  ever passed here both have +mac variants.
- QIcon::setIsMask() was added in Qt 5.15; folded into the same helper,
  version-gated so it's skipped pre-5.15 (including Qt4). Purely
  cosmetic (menu-bar icon auto-recoloring), so skipping it is harmless.
- qsizetype is a Qt6-only typedef (containers/QString returned plain
  int before Qt6). Replaced the 3 uses with `auto`, which picks up
  whatever the actual return type is on each Qt version, avoiding both
  the missing-type error on Qt4/5 and a narrowing-conversion error in
  brace-init if hardcoded to `int` instead.
---
 src/dialog/mainwindow.cpp | 53 ++++++++++++++++++++++++++-------------
 src/logger.cpp            |  7 ++++--
 src/vpninfo.cpp           |  2 +-
 3 files changed, 42 insertions(+), 20 deletions(-)

diff --git a/src/dialog/mainwindow.cpp b/src/dialog/mainwindow.cpp
index c826a6a..eef1742 100644
--- a/src/dialog/mainwindow.cpp
+++ b/src/dialog/mainwindow.cpp
@@ -39,7 +39,11 @@ extern "C" {
 #include <QDesktopServices>
 #include <QDialog>
 #include <QEventTransition>
+#if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
+/* QFileSelector doesn't exist before Qt 5.2; Qt4 falls back to a
+ * hand-rolled "+mac" resolver below (platformTrayIcon()). */
 #include <QFileSelector>
+#endif
 #include <QFutureWatcher>
 #include <QIcon>
 #include <QLineEdit>
@@ -95,6 +99,33 @@ static int app_loglevel_rtab[] = {
     PRG_TRACE  // [3]
 };
 
+/* Resolves a themed tray icon resource path and marks it as a template
+ * ("mask") icon so macOS can recolor it for the menu bar. */
+static QIcon platformTrayIcon(const QString& path)
+{
+#if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
+    QFileSelector selector;
+    QIcon icon(selector.select(path));
+#else
+    /* Qt4 has no QFileSelector; hand-resolve the "+mac" selector this
+     * codebase ships under src/images/+mac/ (see openconnect-gui.qrc)
+     * for the two icons ever passed here, since Qt4 is only ever built
+     * for macOS in this project. */
+    QString macPath = path;
+    int slash = macPath.lastIndexOf(QLatin1Char('/'));
+    if (slash != -1) {
+        macPath.insert(slash + 1, QLatin1String("+mac/"));
+    }
+    QIcon icon(macPath);
+#endif
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
+    /* QIcon::setIsMask() was added in Qt 5.15; skip it on older Qt
+     * (including Qt4) -- the icon still displays fine, just without
+     * automatic light/dark menu-bar recoloring. */
+    icon.setIsMask(true);
+#endif
+    return icon;
+}
 
 MainWindow::MainWindow(QWidget* parent, bool useTray, const QString profileName)
     : QMainWindow(parent)
@@ -145,10 +176,7 @@ MainWindow::MainWindow(QWidget* parent, bool useTray, const QString profileName)
         connect(m_trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
             this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));
 
-        QFileSelector selector;
-        QIcon icon(selector.select(QStringLiteral(":/images/network-disconnected.png")));
-        icon.setIsMask(true);
-        m_trayIcon->setIcon(icon);
+        m_trayIcon->setIcon(platformTrayIcon(QStringLiteral(":/images/network-disconnected.png")));
         m_trayIcon->show();
     } else {
         Logger::instance().addMessage(QLatin1String("System doesn't support tray icon"));
@@ -484,7 +512,7 @@ void MainWindow::gotLatestVersion(QNetworkReply *reply)
     Logger::instance().addMessage(QObject::tr("Version location: %1").arg(version));
 
     if (version.isEmpty() != true) {
-        qsizetype n=version.lastIndexOf("/");
+        auto n = version.lastIndexOf("/"); // qsizetype doesn't exist before Qt6
         if (n != -1) {
             // skip '/v'
             this->latest_version = version.mid(n+2);
@@ -600,11 +628,8 @@ void MainWindow::changeStatus(int val)
         ui->connectionButton->setIcon(QIcon(":/images/process-stop.png"));
         ui->connectionButton->setText(tr("Disconnect"));
 
-        QFileSelector selector;
         if (m_trayIcon) {
-            QIcon icon(selector.select(QStringLiteral(":/images/network-connected.png")));
-            icon.setIsMask(true);
-            m_trayIcon->setIcon(icon);
+            m_trayIcon->setIcon(platformTrayIcon(QStringLiteral(":/images/network-connected.png")));
         }
 
         this->ui->ipV4Label->setText(ip);
@@ -632,10 +657,7 @@ void MainWindow::changeStatus(int val)
     } else if (val == STATUS_CONNECTING) {
 
         if (m_trayIcon) {
-            QFileSelector selector;
-            QIcon icon(selector.select(QStringLiteral(":/images/network-disconnected.png")));
-            icon.setIsMask(true);
-            m_trayIcon->setIcon(icon);
+            m_trayIcon->setIcon(platformTrayIcon(QStringLiteral(":/images/network-disconnected.png")));
             m_trayIcon->setToolTip(QLatin1String("Connecting to ") + ui->serverList->currentText());
         }
 
@@ -685,10 +707,7 @@ void MainWindow::changeStatus(int val)
         ui->connectionButton->setText(tr("Connect"));
 
         if (m_trayIcon) {
-            QFileSelector selector;
-            QIcon icon(selector.select(QStringLiteral(":/images/network-disconnected.png")));
-            icon.setIsMask(true);
-            m_trayIcon->setIcon(icon);
+            m_trayIcon->setIcon(platformTrayIcon(QStringLiteral(":/images/network-disconnected.png")));
 
             if (this->isHidden() == true)
                 m_trayIcon->showMessage(QLatin1String("Disconnected"), QLatin1String("You were disconnected from the VPN"),
diff --git a/src/logger.cpp b/src/logger.cpp
index ff527b5..25e30a2 100644
--- a/src/logger.cpp
+++ b/src/logger.cpp
@@ -26,8 +26,11 @@ QVector<Logger::Message> Logger::getMessages(int lastKnownId) const
 {
     QReadLocker lock(&m_lock);
 
-    qsizetype diff{ m_messageCounter - lastKnownId };
-    qsizetype size{ m_messages.size() };
+    /* qsizetype doesn't exist before Qt6; auto picks up whatever
+     * QVector::size() actually returns on each Qt version (int pre-Qt6,
+     * qsizetype from Qt6), avoiding a narrowing-conversion error either way. */
+    auto diff{ m_messageCounter - lastKnownId };
+    auto size{ m_messages.size() };
 
     if (lastKnownId == -1 || diff >= size) {
         return m_messages;
diff --git a/src/vpninfo.cpp b/src/vpninfo.cpp
index a02c9f7..62cd06c 100644
--- a/src/vpninfo.cpp
+++ b/src/vpninfo.cpp
@@ -721,7 +721,7 @@ QByteArray VpnInfo::generateUniqueInterfaceName()
 
 #ifdef _WIN32
     /* Reduce host so the total length (host + underscore + hash) fits in openconnect's buffer size */
-    qsizetype maxHostLen = OC_IFNAME_MAX_LENGTH - 1 - hash.length();
+    auto maxHostLen = OC_IFNAME_MAX_LENGTH - 1 - hash.length(); // qsizetype doesn't exist before Qt6
     host.truncate(maxHostLen);
 #endif /* _WIN32 */
     return host.append("_").append(hash).toUtf8();
-- 
2.43.0

