diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml index eaf3013fcfa..68fe9052e6e 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build_cmake.yml @@ -7,7 +7,7 @@ on: - 'doc/**' env: - QT_VERSION: 6.5.1 + QT_VERSION: 6.5.2 MACOS_DEPLOYMENT_TARGET: 10.15 CLANG_VERSION: 16.0.2 ELFUTILS_VERSION: 0.175 diff --git a/coin/instructions/common_environment.yaml b/coin/instructions/common_environment.yaml index 1fec2c793a6..20d6247ea9c 100644 --- a/coin/instructions/common_environment.yaml +++ b/coin/instructions/common_environment.yaml @@ -10,7 +10,7 @@ instructions: variableValue: https://ci-files02-hki.ci.qt.io/packages/jenkins/qtcreator_libclang/libclang-release_16.0.2-based - type: EnvironmentVariable variableName: QTC_QT_BASE_URL - variableValue: "https://ci-files02-hki.ci.qt.io/packages/jenkins/archive/qt/6.5/6.5.1-released/Qt" + variableValue: "https://ci-files02-hki.ci.qt.io/packages/jenkins/archive/qt/6.5/6.5.2-released/Qt" - type: EnvironmentVariable variableName: QTC_QT_MODULES variableValue: "qt5compat qtbase qtdeclarative qtimageformats qtquick3d qtquickcontrols2 qtquicktimeline qtserialport qtshadertools qtsvg qttools qttranslations qtwebengine" diff --git a/share/qtcreator/debugger/libcpp_stdtypes.py b/share/qtcreator/debugger/libcpp_stdtypes.py index 1e0b852dc0b..28288bb89f3 100644 --- a/share/qtcreator/debugger/libcpp_stdtypes.py +++ b/share/qtcreator/debugger/libcpp_stdtypes.py @@ -163,8 +163,8 @@ def qdump__std____1__stack(d, value): d.putBetterType(value.type) -def GetChildMemberWithName(value: DumperBase.Value, name: str) -> DumperBase.Value: - members: list[DumperBase.Value] = value.members(True) +def GetChildMemberWithName(value, name): + members = value.members(True) for member in members: if member.name == name: @@ -172,8 +172,8 @@ def GetChildMemberWithName(value: DumperBase.Value, name: str) -> DumperBase.Val return None -def GetIndexOfChildWithName(value: DumperBase.Value, name: str) -> int: - members: list[DumperBase.Value] = value.members(True) +def GetIndexOfChildWithName(value, name): + members = value.members(True) for i, member in enumerate(members): if member.name == name: @@ -229,8 +229,8 @@ def std_1_string_dumper_v2(d, value): if not Short_Sp: raise Exception("Could not find __s") - Is_Long: DumperBase.Value = GetChildMemberWithName(Short_Sp, "__is_long_") - Size_Sp: DumperBase.Value = GetChildMemberWithName(Short_Sp, "__size_") + Is_Long = GetChildMemberWithName(Short_Sp, "__is_long_") + Size_Sp = GetChildMemberWithName(Short_Sp, "__size_") if not Size_Sp: raise Exception("Could not find __size_") diff --git a/share/qtcreator/translations/qtcreator_de.ts b/share/qtcreator/translations/qtcreator_de.ts index e80557112b0..3b7d11a5575 100644 --- a/share/qtcreator/translations/qtcreator_de.ts +++ b/share/qtcreator/translations/qtcreator_de.ts @@ -31686,48 +31686,48 @@ Hinweis: Dies macht Sie anfällig für Man-in-the-middle-Angriffe. QtC::Haskell Release - Release + Release General - Allgemein + Allgemein Build directory: - Build-Verzeichnis: + Build-Verzeichnis: GHCi - + GHCi Run GHCi - + GHCi ausführen Haskell SnippetProvider - + Haskell Executable - Ausführbare Datei + Ausführbare Datei Haskell - + Haskell Stack executable: - + Ausführbare Stack-Datei: Choose Stack Executable - + Ausführbare Datei für Stack auswählen Stack Build - + Erstellen mit Stack @@ -46082,7 +46082,7 @@ Are you sure? Checking that files can be created in %1... - + Überprüfe, ob Dateien in %1 erstellt werden können... Files can be created in /var/run. @@ -46090,11 +46090,11 @@ Are you sure? An error occurred while checking that files can be created in %1. - + Beim Überprüfen, ob Dateien in %1 erstellt werden können, ist ein Fehler aufgetreten. Files cannot be created in %1. - + In %1 können keine Dateien erstellt werden. Warning: "slog2info" is not found on the device, debug output not available. @@ -46173,34 +46173,34 @@ Möchten Sie fortfahren? No files need to be uploaded. - Es müssen keine Dateien hochgeladen werden. + Es müssen keine Dateien hochgeladen werden. %n file(s) need to be uploaded. - + Eine Datei muss hochgeladen werden. %n Dateien müssen hochgeladen werden. Local file "%1" does not exist. - Es gibt keine lokale Datei "%1". + Es gibt keine lokale Datei "%1". Remote chmod failed for file "%1": %2 - "chmod" für die entfernte Datei "%1" ist fehlgeschlagen: %2 + "chmod" für die entfernte Datei "%1" ist fehlgeschlagen: %2 No device configuration set. - Es ist keine Gerätekonfiguration eingestellt. + Es ist keine Gerätekonfiguration gesetzt. No deployment action necessary. Skipping. - Alle Dateien sind auf dem aktuellen Stand, es ist keine Installation erforderlich. + Alle Dateien sind auf dem aktuellen Stand, es ist keine Installation erforderlich. All files successfully deployed. - Alle Dateien erfolgreich versandt. + Deployment für alle Dateien erfolgreich. Deploy Qt to QNX Device @@ -46208,7 +46208,7 @@ Möchten Sie fortfahren? Create Kit for %1 - + Kit für %1 erstellen Configuration Information: @@ -46232,11 +46232,11 @@ Möchten Sie fortfahren? Compiler: - + Compiler: Architectures: - + Architekturen: Remove @@ -46252,11 +46252,11 @@ Möchten Sie fortfahren? Configuration already exists. - + Konfiguration existiert bereits. Configuration is not valid. - + Konfiguration ist ungültig. Remove QNX Configuration @@ -46957,7 +46957,7 @@ wirklich löschen? Key deployment failed. - + Deployment des Schlüssels fehlgeschlagen. Deployment finished successfully. @@ -47003,7 +47003,7 @@ Zusätzlich wird die Verbindung zum Gerät getestet. Uploading package to device... - + Lade Paket auf das Gerät hoch... Successfully uploaded package file. @@ -47015,19 +47015,19 @@ Zusätzlich wird die Verbindung zum Gerät getestet. Successfully installed package file. - + Die Paketdatei wurde erfolgreich installiert. Failed to start "stat": %1 - + "stat" konnte nicht gestartet werden: %1 "stat" crashed. - + "stat" ist abgestürzt. "stat" failed with exit code %1: %2 - + "stat" ist mit Rückgabewert %1 fehlgeschlagen: %2 Failed to retrieve remote timestamp for file "%1". Incremental deployment will not work. Error message was: %2 @@ -47066,7 +47066,7 @@ Zusätzlich wird die Verbindung zum Gerät getestet. Ignore missing files - + Fehlende Dateien ignorieren Upload files via SFTP @@ -47074,19 +47074,19 @@ Zusätzlich wird die Verbindung zum Gerät getestet. Sending echo to device... - + Sende Echo zum Gerät... echo failed: %1 - + Echo fehlgeschlagen: %1 echo failed. - + Echo fehlgeschlagen. Device replied to echo with expected contents. - + Das Gerät hat mit dem erwarteten Inhalt auf das Echo geantwortet. Checking kernel version... @@ -47110,7 +47110,7 @@ Zusätzlich wird die Verbindung zum Gerät getestet. Device replied to echo with unexpected contents: "%1" - + Das Gerät hat auf das Echo mit unerwartetem Inhalt geantwortet: "%1" The following specified ports are currently in use: %1 @@ -47119,56 +47119,62 @@ Zusätzlich wird die Verbindung zum Gerät getestet. Some tools will not work out of the box. - + Einige Werkzeuge werden nicht ohne weitere Einstellungen funktionieren. + Checking whether "%1" works... - + Überprüfe, ob "%1" funktioniert... Failed to start "%1": %2 - + "%1" konnte nicht gestartet werden: %2 + "%1" crashed. - + "%1" ist abgestürzt. + "%1" failed with exit code %2: %3 - + "%1" ist mit Rückgabewert %2 fehlgeschlagen: %3 + "%1" is functional. - + "%1" funktioniert. + "%1" will be used for deployment, because "%2" and "%3" are not available. - + "%1" wird für das Deployment benutzt, da "%2" und "%3" nicht verfügbar sind. + Checking if required commands are available... - + Überprüfe Verfügbarkeit der benötigten Kommandos... %1... - + %1... %1 found. - %1 gefunden. + %1 gefunden. An error occurred while checking for %1. - Bei der Prüfung von %1 trat ein Fehler auf. + Bei der Überprüfung von %1 trat ein Fehler auf. %1 not found. - %1 nicht gefunden. + %1 nicht gefunden. Deployment to this device will not work out of the box. @@ -47182,7 +47188,7 @@ Zusätzlich wird die Verbindung zum Gerät getestet. Deploy to Remote Linux Host - Auf Linux-Mobilgerät ausführen + Deployment auf entferntes Linuxgerät Installing package failed. @@ -47290,7 +47296,7 @@ Zusätzlich wird die Verbindung zum Gerät getestet. The device's SSH port number: - + SSH-Port des Geräts: The username to log into the device: @@ -47326,11 +47332,12 @@ Zusätzlich wird die Verbindung zum Gerät getestet. Source %1 and %2 - + Source (verb) /etc/profile and $HOME/.profile + %1 und %2 einbeziehen Direct - + Direkt &Username: @@ -47338,11 +47345,12 @@ Zusätzlich wird die Verbindung zum Gerät getestet. QML runtime executable: - + Ausführbare Datei der QML-Runtime: Access via: - + drop down with devices + Zugriff über: Physical Device @@ -47402,62 +47410,65 @@ Zusätzlich wird die Verbindung zum Gerät getestet. Cannot establish SSH connection: ssh binary "%1" does not exist. - SSH-Verbindung kann nicht aufgebaut werden: Eine ausführbare SSH-Datei "%1" existiert nicht. + SSH-Verbindung kann nicht hergestellt werden: Eine ausführbare SSH-Datei "%1" existiert nicht. Cannot establish SSH connection: Failed to create temporary directory for control socket: %1 - SSH-Verbindung kann nicht aufgebaut werden: Es konnte kein temporäres Verzeichnis für den Steuer-Socket angelegt werden: %1 + SSH-Verbindung kann nicht hergestellt werden: Es konnte kein temporäres Verzeichnis für den Steuer-Socket angelegt werden: %1 Cannot establish SSH connection. Control process failed to start. - + SSH-Verbindung kann nicht hergestellt werden. +Der Kontrollprozess konnte nicht gestartet werden. SSH connection failure. - SSH-Verbindungsfehler. + SSH-Verbindungsfehler. SSH connection failure: - + SSH-Verbindungsfehler: Remote Linux - + Entferntes Linuxgerät Failed: %1 - + Fehlgeschlagen: %1 Remote Linux Device - + Entferntes Linuxgerät "%1" failed to start: %2 - "%1" konnte nicht gestartet werden: %2 + "%1" konnte nicht gestartet werden: %2 "%1" crashed. - "%1" ist abgestürzt. + "%1" ist abgestürzt. "sftp" binary "%1" does not exist. - + Ausführbare "sftp"-Datei "%1" existiert nicht. Creating directory: %1 - + Erstelle Verzeichnis: %1 + Failed. - Fehlgeschlagen. + Fehlgeschlagen. Copying %1/%2: %3 -> %4 - + Kopiere %1/%2: %3 -> %4 + Clean Environment @@ -47559,7 +47570,7 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e Deploy via rsync: failed to create remote directories: - + Deployment über rsync: Erstellen von entfernten Verzeichnissen ist fehlgeschlagen: rsync failed to start: %1 @@ -47583,7 +47594,7 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e rsync is only supported for transfers between different devices. - + rsync wird nur für das Übertragen zwischen unterschiedlichen Geräten unterstützt. Deploy files via rsync @@ -47591,7 +47602,7 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e Command: - + Kommando: Install root: @@ -47599,43 +47610,43 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e Clean install root first: - + Install-Root zuerst bereinigen: Full command line: - + Vollständige Kommandozeile: Custom command line: - + Benutzerdefinierte Kommandozeile: Use custom command line instead: - + Benutzerdefinierte Kommandozeile verwenden: Install into temporary host directory - + In temporäres Host-Verzeichnis installieren You must provide an install root. - + Sie müssen ein Installationsverzeichnis angeben. The install root "%1" could not be cleaned. - + Das Installationsverzeichnis "%1" konnte nicht bereinigt werden. The install root "%1" could not be created. - + Das Installationsverzeichnis "%1" konnte nicht erstellt werden. The "make install" step should probably not be last in the list of deploy steps. Consider moving it up. - + Der "make install"-Schritt sollte wahrscheinlich nicht der letzte Deployment-Schritt sein. Ziehen Sie in Betracht, ihn nach oben zu verschieben. You need to add an install statement to your CMakeLists.txt file for deployment to work. - + Sie müssen zu Ihrer CMakeLists.txt-Datei eine "install"-Anweisung hinzufügen, damit das Deployment funktioniert. Executable on device: @@ -47651,59 +47662,59 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e New Remote Linux Device Configuration Setup - + Einrichtung der Konfiguration für neues entferntes Linuxgerät SSH Key Configuration - SSH-Schlüsselkonfiguration + SSH-Schlüsselkonfiguration &RSA - &RSA + &RSA ECDSA - ECDSA + ECDSA &Generate And Save Key Pair - &Erzeuge und speichere Schlüsselpaar + &Erzeuge und speichere Schlüsselpaar Options - Einstellungen + Einstellungen Key algorithm: - Schlüsselalgorithmus: + Schlüsselalgorithmus: Key &size: - Schlüssel&länge: + Schlüssel&länge: Public key file: - Öffentliche Schlüsseldatei: + Öffentliche Schlüsseldatei: The ssh-keygen tool was not found. - Das Programm "ssh-keygen" wurde nicht gefunden. + Das Programm "ssh-keygen" wurde nicht gefunden. Refusing to overwrite existing private key file "%1". - Die private Schlüsseldatei "%1" wird nicht überschrieben. + Die private Schlüsseldatei "%1" wird nicht überschrieben. The ssh-keygen tool at "%1" failed: %2 - Das Programm "ssh-keygen" in "%1" hat einen Fehler festgestellt: %2 + Das Programm "ssh-keygen" in "%1" hat einen Fehler festgestellt: %2 Choose Private Key File Name - Name der privaten Schlüsseldatei auswählen + Private Schlüsseldatei auswählen Key Generation Failed - Fehler bei Erzeugung der Schlüssel + Schlüsselerzeugung ist fehlgeschlagen @@ -48636,30 +48647,30 @@ Zeile: %4, Spalte: %5 None - Keine + Keine LF - LF + LF CR - CR + CR CRLF - CRLF + CRLF QtC::SilverSearcher Search Options (optional) - Sucheinstellungen (optional) + Sucheinstellungen (optional) Silver Searcher is not available on the system. - Silver Searcher ist auf dem System nicht verfügbar. + Silver Searcher ist auf dem System nicht verfügbar. @@ -55651,88 +55662,92 @@ should a repository require SSH-authentication (see documentation on SSH and the QtC::WebAssembly Web Browser - + Webbrowser WebAssembly Runtime - + WebAssembly-Runtime Emscripten SDK path: - + Pfad zum Emscripten-SDK: Select the root directory of an installed %1. Ensure that the activated SDK version is compatible with the %2 or %3 version that you plan to develop against. - + %1=Emscripten SDK, %2=Qt 5, %3=Qt 6 + Wählen Sie das Wurzelverzeichnis einer Installation von %1. Stellen Sie sicher, dass die eingestellte SDK-Version mit der von Ihnen für das Entwickeln geplanten %2- oder %3-Version kompatibel ist. Emscripten SDK environment: - + Umgebung für Emscripten-SDK: Note: %1 supports Qt %2 for WebAssembly and higher. Your installed lower Qt version(s) are not supported. - + %1=the QtC-Version, %2=minimumSupportedQtVersion + Hinweis: %1 unterstützt für WebAssembly nur Qt %2 und höher. Ihre älteren installierten Qt-Versionen werden nicht unterstützt. Adding directories to PATH: - + Füge Verzeichnisse zu PATH hinzu: Setting environment variables: - + Setze Umgebungsvariablen: The activated version %1 is not supported by %2. Activate version %3 or higher. - + %1=sdkVersion, %2=QtC-Version, %3=minVersion + Die aktivierte Version %1 wird von %2 nicht unterstützt. Benutzen Sie Version %3 oder höher. Activated version: %1 - + Aktivierte Version: %1 WebAssembly - + WebAssembly Setup Emscripten SDK for WebAssembly? To do it later, select Edit > Preferences > Devices > WebAssembly. - + Emscripten-SDK für WebAssembly einrichten? Dies geht auch später unter Bearbeiten > Einstellungen > Geräte > WebAssembly. Setup Emscripten SDK - + Emscripten-SDK einrichten WebAssembly Qt Version is meant for WebAssembly - + WebAssembly %1 does not support Qt for WebAssembly below version %2. - + %1=QtC-Version + %1 unterstützt Qt für WebAssembly nicht unter Version %2. Effective emrun call: - + Resultierender emrun-Aufruf: Default Browser - + Vorgabe-Browser Web browser: - + Webbrowser: Emscripten Compiler - + Emscripten-Compiler Emscripten Compiler %1 for %2 - + Emscripten-Compiler %1 für %2 Emscripten - + Emscripten @@ -58293,35 +58308,35 @@ Are you sure you want to remove the material? QtC::Vcpkg Search package... - + Paket suchen... Vcpkg Manifest Editor - + Vcpkg Manifest-Editor Name: - + Name: Version: - Version: + Version: License: - Lizenz: + Lizenz: Description: - Beschreibung: + Beschreibung: Homepage: - + Homepage: Vcpkg installation - + Vcpkg-Installation diff --git a/src/libs/3rdparty/libptyqt/unixptyprocess.cpp b/src/libs/3rdparty/libptyqt/unixptyprocess.cpp index 8c018daf8c0..4c67ee28fb0 100644 --- a/src/libs/3rdparty/libptyqt/unixptyprocess.cpp +++ b/src/libs/3rdparty/libptyqt/unixptyprocess.cpp @@ -54,6 +54,10 @@ bool UnixPtyProcess::startProcess(const QString &shellPath, int rc = 0; m_shellProcess.m_handleMaster = ::posix_openpt(O_RDWR | O_NOCTTY); + + int flags = fcntl(m_shellProcess.m_handleMaster, F_GETFL, 0); + fcntl(m_shellProcess.m_handleMaster, F_SETFL, flags | O_NONBLOCK); + if (m_shellProcess.m_handleMaster <= 0) { m_lastError = QString("UnixPty Error: unable to open master -> %1").arg(QLatin1String(strerror(errno))); kill(); @@ -308,10 +312,7 @@ QByteArray UnixPtyProcess::readAll() qint64 UnixPtyProcess::write(const QByteArray &byteArray) { - int result = ::write(m_shellProcess.m_handleMaster, byteArray.constData(), byteArray.size()); - Q_UNUSED(result) - - return byteArray.size(); + return ::write(m_shellProcess.m_handleMaster, byteArray.constData(), byteArray.size()); } bool UnixPtyProcess::isAvailable() diff --git a/src/libs/solutions/terminal/terminalsurface.cpp b/src/libs/solutions/terminal/terminalsurface.cpp index aedf8533d29..3f816670c34 100644 --- a/src/libs/solutions/terminal/terminalsurface.cpp +++ b/src/libs/solutions/terminal/terminalsurface.cpp @@ -10,6 +10,7 @@ #include #include +#include namespace TerminalSolution { @@ -20,6 +21,8 @@ QColor toQColor(const VTermColor &c) return QColor(qRgb(c.rgb.red, c.rgb.green, c.rgb.blue)); }; +constexpr int batchFlushSize = 256; + struct TerminalSurfacePrivate { TerminalSurfacePrivate(TerminalSurface *surface, const QSize &initialGridSize) @@ -29,13 +32,64 @@ struct TerminalSurfacePrivate , q(surface) {} + void flush() + { + if (m_writeBuffer.isEmpty()) + return; + + QByteArray data = m_writeBuffer.left(batchFlushSize); + qint64 result = m_writeToPty(data); + + if (result != data.size()) { + // Not all data was written, remove the unwritten data from the array + data.resize(qMax(0, result)); + } + + // Remove the written data from the buffer + if (data.size() > 0) + m_writeBuffer = m_writeBuffer.mid(data.size()); + + if (!m_writeBuffer.isEmpty()) + m_delayWriteTimer.start(); + } + void init() { + m_delayWriteTimer.setInterval(1); + m_delayWriteTimer.setSingleShot(true); + + QObject::connect(&m_delayWriteTimer, &QTimer::timeout, &m_delayWriteTimer, [this] { + flush(); + }); + vterm_set_utf8(m_vterm.get(), true); static auto writeToPty = [](const char *s, size_t len, void *user) { auto p = static_cast(user); - emit p->q->writeToPty(QByteArray(s, static_cast(len))); + QByteArray d(s, len); + + // If its just a couple of chars, or we already have data in the writeBuffer, + // add the new data to the write buffer and start the delay timer + if (d.size() < batchFlushSize || !p->m_writeBuffer.isEmpty()) { + p->m_writeBuffer.append(d); + p->m_delayWriteTimer.start(); + return; + } + + // Try to write the data ... + qint64 result = p->m_writeToPty(d); + + if (result != d.size()) { + // if writing failed, append the data to the writeBuffer and start the delay timer + + // Check if partial data may have already been written ... + if (result <= 0) + p->m_writeBuffer.append(d); + else + p->m_writeBuffer.append(d.mid(result)); + + p->m_delayWriteTimer.start(); + } }; vterm_output_set_callback(m_vterm.get(), writeToPty, this); @@ -319,6 +373,10 @@ struct TerminalSurfacePrivate SurfaceIntegration *m_surfaceIntegration{nullptr}; TerminalSurface *q; + QTimer m_delayWriteTimer; + QByteArray m_writeBuffer; + + TerminalSurface::WriteToPty m_writeToPty; }; TerminalSurface::TerminalSurface(QSize initialGridSize) @@ -393,7 +451,7 @@ void TerminalSurface::clearAll() vterm_input_write(d->m_vterm.get(), data.constData(), data.size()); // Send Ctrl+L which will clear the screen - emit writeToPty(QByteArray("\f")); + d->m_writeToPty(QByteArray("\f")); } void TerminalSurface::resize(QSize newSize) @@ -539,6 +597,11 @@ void TerminalSurface::mouseButton(Qt::MouseButton button, vterm_mouse_button(d->m_vterm.get(), btnIdx, pressed, qtModifierToVTerm(modifiers)); } +void TerminalSurface::setWriteToPty(WriteToPty writeToPty) +{ + d->m_writeToPty = writeToPty; +} + CellIterator TerminalSurface::begin() const { auto res = CellIterator(this, {0, 0}); diff --git a/src/libs/solutions/terminal/terminalsurface.h b/src/libs/solutions/terminal/terminalsurface.h index be20a4c0aa2..765e3a59402 100644 --- a/src/libs/solutions/terminal/terminalsurface.h +++ b/src/libs/solutions/terminal/terminalsurface.h @@ -98,10 +98,12 @@ public: SurfaceIntegration *surfaceIntegration() const; void setSurfaceIntegration(SurfaceIntegration *surfaceIntegration); + using WriteToPty = std::function; + void setWriteToPty(WriteToPty writeToPty); + void mouseMove(QPoint pos, Qt::KeyboardModifiers modifiers); void mouseButton(Qt::MouseButton button, bool pressed, Qt::KeyboardModifiers modifiers); signals: - void writeToPty(const QByteArray &data); void invalidated(QRect grid); void fullSizeChanged(QSize newSize); void cursorChanged(Cursor oldCursor, Cursor newCursor); diff --git a/src/libs/solutions/terminal/terminalview.cpp b/src/libs/solutions/terminal/terminalview.cpp index 3924f09d33a..3ccef4ab94f 100644 --- a/src/libs/solutions/terminal/terminalview.cpp +++ b/src/libs/solutions/terminal/terminalview.cpp @@ -170,7 +170,7 @@ void TerminalView::setupSurface() if (d->m_surfaceIntegration) d->m_surface->setSurfaceIntegration(d->m_surfaceIntegration); - connect(d->m_surface.get(), &TerminalSurface::writeToPty, this, &TerminalView::writeToPty); + d->m_surface->setWriteToPty([this](const QByteArray &data) { return writeToPty(data); }); connect(d->m_surface.get(), &TerminalSurface::fullSizeChanged, this, [this] { updateScrollBars(); diff --git a/src/libs/solutions/terminal/terminalview.h b/src/libs/solutions/terminal/terminalview.h index 7b0a2f7bc70..59b75c0e7ef 100644 --- a/src/libs/solutions/terminal/terminalview.h +++ b/src/libs/solutions/terminal/terminalview.h @@ -105,7 +105,11 @@ public: } }; - virtual void writeToPty(const QByteArray &data) { Q_UNUSED(data); } + virtual qint64 writeToPty(const QByteArray &data) + { + Q_UNUSED(data); + return 0; + } void writeToTerminal(const QByteArray &data, bool forceFlush); void restart(); diff --git a/src/libs/utils/process.cpp b/src/libs/utils/process.cpp index 43d57ded891..5f8e3612f7f 100644 --- a/src/libs/utils/process.cpp +++ b/src/libs/utils/process.cpp @@ -1564,9 +1564,11 @@ qint64 Process::writeRaw(const QByteArray &input) QTC_ASSERT(state() == QProcess::Running, return -1); QTC_ASSERT(QThread::currentThread() == thread(), return -1); qint64 result = -1; - QMetaObject::invokeMethod(d->m_process.get(), [this, input] { - d->m_process->write(input); - }, d->connectionType(), &result); + QMetaObject::invokeMethod( + d->m_process.get(), + [this, input] { return d->m_process->write(input); }, + d->connectionType(), + &result); return result; } diff --git a/src/plugins/coreplugin/actionmanager/commandsfile.cpp b/src/plugins/coreplugin/actionmanager/commandsfile.cpp index f4abce0eaa8..ccd551751e7 100644 --- a/src/plugins/coreplugin/actionmanager/commandsfile.cpp +++ b/src/plugins/coreplugin/actionmanager/commandsfile.cpp @@ -48,6 +48,36 @@ CommandsFile::CommandsFile(const FilePath &filename) } +// XML attributes cannot contain these characters, and +// QXmlStreamWriter just bails out with an error. +// QKeySequence::toString() should probably not result in these +// characters, but it currently does, see QTCREATORBUG-29431 +static bool containsInvalidCharacters(const QString &s) +{ + const auto end = s.constEnd(); + for (auto it = s.constBegin(); it != end; ++it) { + // from QXmlStreamWriterPrivate::writeEscaped + if (*it == u'\v' || *it == u'\f' || *it <= u'\x1F' || *it >= u'\uFFFE') { + return true; + } + } + return false; +} + +static QString toAttribute(const QString &s) +{ + if (containsInvalidCharacters(s)) + return "0x" + QString::fromUtf8(s.toUtf8().toHex()); + return s; +} + +static QString fromAttribute(const QStringView &s) +{ + if (s.startsWith(QLatin1String("0x"))) + return QString::fromUtf8(QByteArray::fromHex(s.sliced(2).toUtf8())); + return s.toString(); +} + /*! \internal */ @@ -76,7 +106,7 @@ QMap> CommandsFile::importCommands() const QTC_ASSERT(!currentId.isEmpty(), continue); const QXmlStreamAttributes attributes = r.attributes(); if (attributes.hasAttribute(ctx.valueAttribute)) { - const QString keyString = attributes.value(ctx.valueAttribute).toString(); + const QString keyString = fromAttribute(attributes.value(ctx.valueAttribute)); QList keys = result.value(currentId); result.insert(currentId, keys << QKeySequence(keyString)); } @@ -93,7 +123,6 @@ QMap> CommandsFile::importCommands() const /*! \internal */ - bool CommandsFile::exportCommands(const QList &items) { FileSaver saver(m_filePath, QIODevice::Text); @@ -118,7 +147,7 @@ bool CommandsFile::exportCommands(const QList &items) w.writeAttribute(ctx.idAttribute, id.toString()); for (const QKeySequence &k : item->m_keys) { w.writeEmptyElement(ctx.keyElement); - w.writeAttribute(ctx.valueAttribute, k.toString()); + w.writeAttribute(ctx.valueAttribute, toAttribute(k.toString())); } w.writeEndElement(); // Shortcut } @@ -126,7 +155,8 @@ bool CommandsFile::exportCommands(const QList &items) w.writeEndElement(); w.writeEndDocument(); - saver.setResult(&w); + if (!saver.setResult(&w)) + qWarning() << saver.errorString(); } return saver.finalize(); } diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp index 0196a8cee8f..536ae572d4a 100644 --- a/src/plugins/git/gitplugin.cpp +++ b/src/plugins/git/gitplugin.cpp @@ -426,6 +426,7 @@ public: QList m_projectActions; QList m_repositoryActions; ParameterAction *m_applyCurrentFilePatchAction = nullptr; + Gerrit::Internal::GerritPlugin m_gerritPlugin; QPointer m_stashDialog; diff --git a/src/plugins/mcusupport/mcupackage.cpp b/src/plugins/mcusupport/mcupackage.cpp index f41b1193387..1c079eebdfb 100644 --- a/src/plugins/mcusupport/mcupackage.cpp +++ b/src/plugins/mcusupport/mcupackage.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -447,7 +448,8 @@ static ToolChain *iarToolChain(const FilePath &path, Id language) == BareMetal::Constants::IAREW_TOOLCHAIN_TYPEID; }); if (iarFactory) { - Toolchains detected = iarFactory->autoDetect(ToolchainDetector({}, {}, {})); + Toolchains detected = iarFactory->autoDetect( + {{}, DeviceManager::defaultDesktopDevice(), {}}); if (detected.isEmpty()) detected = iarFactory->detectForImport({path, language}); for (auto tc : detected) { diff --git a/src/plugins/projectexplorer/toolchainoptionspage.cpp b/src/plugins/projectexplorer/toolchainoptionspage.cpp index 99ac9f87745..a0dc19392ed 100644 --- a/src/plugins/projectexplorer/toolchainoptionspage.cpp +++ b/src/plugins/projectexplorer/toolchainoptionspage.cpp @@ -3,10 +3,11 @@ #include "toolchainoptionspage.h" -#include "toolchain.h" #include "abi.h" +#include "devicesupport/devicemanager.h" #include "projectexplorerconstants.h" #include "projectexplorertr.h" +#include "toolchain.h" #include "toolchainconfigwidget.h" #include "toolchainmanager.h" @@ -407,7 +408,7 @@ void ToolChainOptionsWidget::redetectToolchains() QSet toDelete; ToolChainManager::resetBadToolchains(); for (ToolChainFactory *f : ToolChainFactory::allToolChainFactories()) { - const ToolchainDetector detector(knownTcs, {}, {}); // FIXME: Pass device and search paths + const ToolchainDetector detector(knownTcs, DeviceManager::defaultDesktopDevice(), {}); // FIXME: Pass search paths for (ToolChain * const tc : f->autoDetect(detector)) { if (knownTcs.contains(tc) || toDelete.contains(tc)) continue; diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp index 1562d13b0e4..7cac4c49349 100644 --- a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp +++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp @@ -1675,8 +1675,8 @@ void DesignerActionManager::createDefaultDesignerActions() setFlowStartDisplayName, {}, flowCategory, - 2, {}, + 2, &setFlowStartItem, &isFlowItem, &flowOptionVisible)); diff --git a/src/plugins/terminal/terminalwidget.cpp b/src/plugins/terminal/terminalwidget.cpp index bfb58ba708a..0a4607ce67d 100644 --- a/src/plugins/terminal/terminalwidget.cpp +++ b/src/plugins/terminal/terminalwidget.cpp @@ -260,10 +260,12 @@ void TerminalWidget::closeTerminal() deleteLater(); } -void TerminalWidget::writeToPty(const QByteArray &data) +qint64 TerminalWidget::writeToPty(const QByteArray &data) { if (m_process && m_process->isRunning()) - m_process->writeRaw(data); + return m_process->writeRaw(data); + + return data.size(); } void TerminalWidget::resizePty(QSize newSize) diff --git a/src/plugins/terminal/terminalwidget.h b/src/plugins/terminal/terminalwidget.h index c836c832b54..dd20b3dfc0a 100644 --- a/src/plugins/terminal/terminalwidget.h +++ b/src/plugins/terminal/terminalwidget.h @@ -71,7 +71,7 @@ protected: void linkActivated(const Link &link) override; void contextMenuRequested(const QPoint &pos) override; - void writeToPty(const QByteArray &data) override; + qint64 writeToPty(const QByteArray &data) override; void resizePty(QSize newSize) override; void setClipboard(const QString &text) override; std::optional toLink(const QString &text) override; diff --git a/tests/system/0001-Fix-build-on-macOS.patch b/tests/system/0001-Fix-build-on-macOS.patch new file mode 100644 index 00000000000..124a6b7a9c6 --- /dev/null +++ b/tests/system/0001-Fix-build-on-macOS.patch @@ -0,0 +1,33 @@ +From e5aec585120ca65b92e642b50b1552f75df26b93 Mon Sep 17 00:00:00 2001 +From: Christian Stenger +Date: Thu, 27 Jul 2023 08:49:30 +0200 +Subject: [PATCH] Fix build on macOS + +--- + src/CMakeLists.txt | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt +index 7be6aad..0cad721 100644 +--- a/src/CMakeLists.txt ++++ b/src/CMakeLists.txt +@@ -18,7 +18,6 @@ if(APPLE) + set(MACOSX_BUNDLE_SHORT_VERSION_STRING ${speedcrunch_VERSION}) + set(MACOSX_BUNDLE_VERSION ${speedcrunch_VERSION}) + set(MACOSX_BUNDLE_LONG_VERSION_STRING Version ${speedcrunch_VERSION}) +- set(CMAKE_OSX_ARCHITECTURES ppc;i386) + else(APPLE) + set(PROGNAME speedcrunch) + endif(APPLE) +@@ -71,7 +70,7 @@ if(APPLE) + set( speedcrunch_RESOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/${PROGNAME}.app/Contents/Resources ) + add_custom_command(TARGET ${PROGNAME} POST_BUILD + COMMAND mkdir ARGS -p ${speedcrunch_RESOURCE_DIR} +- COMMAND cp ARGS -f resources/${MACOSX_BUNDLE_ICON_FILE} ${speedcrunch_RESOURCE_DIR}) ++ COMMAND cp ARGS -f ${CMAKE_CURRENT_SOURCE_DIR}/resources/${MACOSX_BUNDLE_ICON_FILE} ${speedcrunch_RESOURCE_DIR}) + endif(APPLE) + + add_custom_target(confclean COMMAND rm -rf Makefile CMakeFiles/ CMakeCache.txt cmake_install.cmake DartTestfile.txt install_manifest.txt) +-- +2.32.0 (Apple Git-132) + diff --git a/tests/system/shared/debugger.py b/tests/system/shared/debugger.py index 7176afc8e59..b878f9efef6 100644 --- a/tests/system/shared/debugger.py +++ b/tests/system/shared/debugger.py @@ -238,7 +238,7 @@ def __logDebugResult__(): def verifyBreakPoint(bpToVerify): if isinstance(bpToVerify, dict): - fileName = list(bpToVerify.keys())[0] + fileName = next(iter(bpToVerify.keys())) editor = getEditorForFileSuffix(fileName) if editor: test.compare(waitForObject(":DebugModeWidget_QComboBox").toolTip, fileName, @@ -247,7 +247,7 @@ def verifyBreakPoint(bpToVerify): windowTitle = str(waitForObject(":Qt Creator_Core::Internal::MainWindow").windowTitle) test.verify(windowTitle.startswith(os.path.basename(fileName) + " "), "Verify that Creator's window title changed according to current file") - return test.compare(line, list(bpToVerify.values())[0], + return test.compare(line, next(iter(bpToVerify.values())), "Compare hit breakpoint to expected line number in %s" % fileName) else: test.fatal("Expected a dict for bpToVerify - got '%s'" % className(bpToVerify)) diff --git a/tests/system/shared/project.py b/tests/system/shared/project.py index d1e44102bcc..b39ef8060ee 100644 --- a/tests/system/shared/project.py +++ b/tests/system/shared/project.py @@ -248,11 +248,16 @@ def createProject_Qt_GUI(path, projectName, checks=True, addToVersionControl=" %s" % (category, template)): displayedPlatforms = __createProject__(category, template) if template.startswith("Qt Quick Application"): diff --git a/tests/system/suite_general/tst_default_settings/test.py b/tests/system/suite_general/tst_default_settings/test.py index ce026e98d36..57d7ae02cb1 100644 --- a/tests/system/suite_general/tst_default_settings/test.py +++ b/tests/system/suite_general/tst_default_settings/test.py @@ -311,15 +311,15 @@ def __compareCompilers__(foundCompilers, expectedCompilers): for currentExp in expectedCompilers: if isString(currentExp): continue - key = list(currentExp.keys())[0] + key = next(iter(currentExp.keys())) # the regex .*? is used for the different possible version strings of the WinSDK # if it's present a regex will be validated otherwise simple string comparison # same applies for [.0-9]+ which is used for minor/patch versions isRegex = ".*?" in key or "[.0-9]+" in key - if (((isRegex and re.match(key, list(currentFound.keys())[0], flags))) + if (((isRegex and re.match(key, next(iter(currentFound.keys())), flags))) or currentFound.keys() == currentExp.keys()): - if ((isWin and os.path.abspath(list(currentFound.values())[0].lower()) - == os.path.abspath(list(currentExp.values())[0].lower())) + if ((isWin and os.path.abspath(next(iter(currentFound.values())).lower()) + == os.path.abspath(next(iter(currentExp.values())).lower())) or currentFound.values() == currentExp.values()): foundExp = True break @@ -359,24 +359,22 @@ def __lowerStrs__(iterable): def __checkCreatedSettings__(settingsFolder): waitForCleanShutdown() qtProj = os.path.join(settingsFolder, "QtProject") - folders = [] - files = [{os.path.join(qtProj, "QtCreator.db"):0}, - {os.path.join(qtProj, "QtCreator.ini"):30}] - folders.append(os.path.join(qtProj, "qtcreator")) - files.extend([{os.path.join(folders[0], "debuggers.xml"):0}, - {os.path.join(folders[0], "devices.xml"):0}, - {os.path.join(folders[0], "helpcollection.qhc"):0}, - {os.path.join(folders[0], "profiles.xml"):0}, - {os.path.join(folders[0], "qtversion.xml"):0}, - {os.path.join(folders[0], "toolchains.xml"):0}]) - folders.extend([os.path.join(folders[0], "generic-highlighter"), - os.path.join(folders[0], "macros")]) + creatorFolder = os.path.join(qtProj, "qtcreator") + folders = [creatorFolder, + os.path.join(creatorFolder, "generic-highlighter"), + os.path.join(creatorFolder, "macros")] + files = {os.path.join(qtProj, "QtCreator.db"):0, + os.path.join(qtProj, "QtCreator.ini"):30, + os.path.join(creatorFolder, "debuggers.xml"):0, + os.path.join(creatorFolder, "devices.xml"):0, + os.path.join(creatorFolder, "helpcollection.qhc"):0, + os.path.join(creatorFolder, "profiles.xml"):0, + os.path.join(creatorFolder, "qtversion.xml"):0, + os.path.join(creatorFolder, "toolchains.xml"):0} for f in folders: test.verify(os.path.isdir(f), "Verifying whether folder '%s' has been created." % os.path.basename(f)) - for f in files: - fName = list(f.keys())[0] - fMinSize = list(f.values())[0] + for fName, fMinSize in files.items(): text = "created non-empty" if fMinSize > 0: text = "modified" diff --git a/tests/system/suite_general/tst_opencreator_qbs/test.py b/tests/system/suite_general/tst_opencreator_qbs/test.py index 6ff692d41cf..86c8f99e4da 100644 --- a/tests/system/suite_general/tst_opencreator_qbs/test.py +++ b/tests/system/suite_general/tst_opencreator_qbs/test.py @@ -8,7 +8,7 @@ def main(): if not neededFilePresent(pathCreator): return - startQC() + startQC(["-noload", "ClangCodeModel"]) if not startedWithoutPluginError(): return openQbsProject(pathCreator) @@ -24,7 +24,7 @@ def main(): else: test.warning("Parsing project timed out") compareProjectTree(rootNodeTemplate % "Qt Creator", "projecttree_creator.tsv") - buildIssuesTexts = map(lambda i: str(i[0]), getBuildIssues()) + buildIssuesTexts = map(lambda i: str(i[0]), getBuildIssues(False)) deprecationWarnings = "\n".join(set(filter(lambda s: "deprecated" in s, buildIssuesTexts))) if deprecationWarnings: test.warning("Creator claims that the .qbs file uses deprecated features.", diff --git a/tests/system/suite_general/tst_openqt_creator/test.py b/tests/system/suite_general/tst_openqt_creator/test.py index 257a32d8161..8bdb82e4e53 100644 --- a/tests/system/suite_general/tst_openqt_creator/test.py +++ b/tests/system/suite_general/tst_openqt_creator/test.py @@ -13,7 +13,7 @@ def main(): if not pathSpeedcrunch: test.fatal("Could not clone SpeedCrunch") return - startQC() + startQC(["-noload", "ClangCodeModel"]) if not startedWithoutPluginError(): return diff --git a/tests/system/suite_general/tst_openqt_creator/testdata/projecttree_creator.tsv b/tests/system/suite_general/tst_openqt_creator/testdata/projecttree_creator.tsv index e0e8060e7bd..662eb4fe255 100644 --- a/tests/system/suite_general/tst_openqt_creator/testdata/projecttree_creator.tsv +++ b/tests/system/suite_general/tst_openqt_creator/testdata/projecttree_creator.tsv @@ -4166,7 +4166,6 @@ "Headers" "5" "touchbar.h" "6" "Sources" "5" -"touchbar.cpp" "6" "Headers" "4" "optional" "6" "optional.hpp" "7" @@ -16895,21 +16894,6 @@ "qtc-askpass-main.cpp" "4" "Other files" "3" "qtc-askpass.qbs" "4" -"qtcreatortool" "3" -"qtcreatortool.pri" "4" -"qtcreator" "4" -"qtcreator.pri" "5" -"qtcreator_ide_branding" "5" -"qtcreator_ide_branding.pri" "6" -"qtcreator_testvars" "5" -"qtcreator_testvars.pri" "6" -"Other files" "5" -"CMakeLists.txt" "7" -"rpath" "4" -"rpath.pri" "5" -"Sources" "3" -"main.cpp" "4" -"Other files" "3" "qtpromaker" "2" "qtpromaker.pro" "3" "qtcreatortool" "3" @@ -20837,7 +20821,6 @@ "Headers" "5" "touchbar.h" "6" "Sources" "5" -"touchbar.cpp" "6" "Headers" "4" "optional" "6" "optional.hpp" "7" @@ -21758,7 +21741,6 @@ "Headers" "6" "touchbar.h" "7" "Sources" "6" -"touchbar.cpp" "7" "Headers" "5" "optional" "7" "optional.hpp" "8" diff --git a/tests/system/suite_tools/tst_git_local/test.py b/tests/system/suite_tools/tst_git_local/test.py index 9ce9a0b3164..aefdc07d9a1 100644 --- a/tests/system/suite_tools/tst_git_local/test.py +++ b/tests/system/suite_tools/tst_git_local/test.py @@ -86,12 +86,12 @@ def __clickCommit__(count): show = str(description.plainText) id = "Nobody " time = "\w{3} \w{3} \d{1,2} \d{2}:\d{2}:\d{2} \d{4}.* seconds ago\)" - expected = [{"commit %s" % commit:False}, - {"Author: %s, %s" % (id, time): True}, - {"Committer: %s, %s" % (id, time): True}] + expected = [["commit %s" % commit, False], + ["Author: %s, %s" % (id, time), True], + ["Committer: %s, %s" % (id, time), True]] for line, exp in zip(show.splitlines(), expected): - expLine = list(exp.keys())[0] - isRegex = list(exp.values())[0] + expLine = exp[0] + isRegex = exp[1] if isRegex: test.verify(re.match(expLine, line), "Verifying commit header line '%s'" % line) else: