Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build with Qt6 #532

Merged
merged 24 commits into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
b1fa777
Builds with qt6.
Feb 24, 2024
b40b77b
Fixed some warnings.
Feb 24, 2024
f288547
Fixed another warning.
Feb 24, 2024
184c9fe
Fix the final warnings.
Feb 24, 2024
c880ab2
Fix issue cursor positioning issues
marcusbritanicus Feb 26, 2024
7052dc2
Merge pull request #1 from marcusbritanicus/Qt6Update
doug1234 Feb 26, 2024
f085cd8
Removed tab
Mar 5, 2024
08fc85c
Fix the example.
doug1234 Mar 7, 2024
c5e5f1f
Tab to space in terminal display.
doug1234 Mar 11, 2024
94ee191
Remove chagnes that were accidently reverted.
doug1234 Mar 11, 2024
975be81
Updated README comments to reflect move to qt6.
doug1234 Mar 26, 2024
bcd4ff7
Remove ChildProcessSetup and directly call onsetupChildProcess.
doug1234 Mar 26, 2024
faee531
Try CI
yan12125 Mar 10, 2024
a3d5546
Use PyQt6
yan12125 Mar 28, 2024
d20c815
Merge branch 'lxqt:master' into Qt6Update
doug1234 Mar 28, 2024
40cbc8d
Made change suggested by marcusbritanicus
doug1234 Mar 28, 2024
c4cedb9
Temporary CI workaround suggested by marcusbritanicus.
doug1234 Mar 28, 2024
0f2cbfe
Removed all the qt5 compatibility code. Also removed codec support.
doug1234 Apr 4, 2024
651d0bf
Removed codec function from sip file.
doug1234 Apr 4, 2024
3cbbb16
Improved CI fix by marcusbritanicus
doug1234 Apr 5, 2024
a968c1c
Attempting to fix warning.
doug1234 Apr 5, 2024
3daf2c6
Fixed deprecated function warning.
doug1234 Apr 5, 2024
75fa735
Bumped the version to 2.0.0.
doug1234 Apr 6, 2024
a760241
Removed anchored pattern for email and url. URL underlining is now w…
doug1234 Apr 15, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .ci/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ set -ex
source shared-ci/prepare-archlinux.sh

# See *depends in https://github.com/archlinuxcn/repo/blob/master/archlinuxcn/qtermwidget-git/PKGBUILD
pacman -S --noconfirm --needed git cmake lxqt-build-tools-git qt5-tools python-pyqt5 pyqt-builder sip
pacman -S --noconfirm --needed git cmake lxqt-build-tools-git qt6-5compat qt6-tools python-pyqt6 pyqt-builder sip

cmake -B build -S . \
-DBUILD_EXAMPLE=ON \
-DQTERMWIDGET_USE_UTEMPTER=ON
make -C build

cd pyqt
CXXFLAGS="-I$PWD/../lib -I$PWD/../build/lib" LDFLAGS="-L$PWD/../build" sip-wheel --verbose
CXXFLAGS="-I$PWD/../lib -I$PWD/../build/lib" LDFLAGS="-L$PWD/../build" sip-wheel --verbose --qmake=/usr/bin/qmake6
22 changes: 11 additions & 11 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ option(USE_UTF8PROC "Use libutf8proc for better Unicode support. Default OFF" OF

# just change version for releases
# keep this in sync with the version in pyqt/pyproject.toml
set(QTERMWIDGET_VERSION_MAJOR "1")
set(QTERMWIDGET_VERSION_MINOR "4")
set(QTERMWIDGET_VERSION_MAJOR "2")
set(QTERMWIDGET_VERSION_MINOR "0")
set(QTERMWIDGET_VERSION_PATCH "0")

set(QTERMWIDGET_VERSION "${QTERMWIDGET_VERSION_MAJOR}.${QTERMWIDGET_VERSION_MINOR}.${QTERMWIDGET_VERSION_PATCH}")
Expand All @@ -32,12 +32,12 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake")
set(CMAKE_INCLUDE_CURRENT_DIR ON)

# Minimum Versions
set(QT_MINIMUM_VERSION "5.15.0")
set(QT_MINIMUM_VERSION "6.1.0")
set(LXQTBT_MINIMUM_VERSION "0.13.0")

find_package(Qt5Widgets "${QT_MINIMUM_VERSION}" REQUIRED)
find_package(Qt5LinguistTools "${QT_MINIMUM_VERSION}" REQUIRED)
find_package(lxqt-build-tools ${LXQTBT_MINIMUM_VERSION} REQUIRED)
find_package(Qt6Widgets "${QT_MINIMUM_VERSION}" REQUIRED)
find_package(Qt6LinguistTools "${QT_MINIMUM_VERSION}" REQUIRED)
find_package(lxqt2-build-tools ${LXQTBT_MINIMUM_VERSION} REQUIRED)

if(USE_UTF8PROC)
find_package(Utf8Proc REQUIRED)
Expand All @@ -55,7 +55,7 @@ if(APPLE)
endif()
endif()

set(QTERMWIDGET_LIBRARY_NAME qtermwidget5)
set(QTERMWIDGET_LIBRARY_NAME qtermwidget6)


# main library
Expand Down Expand Up @@ -130,9 +130,9 @@ set(QTERMWIDGET_INCLUDE_DIR "${CMAKE_INSTALL_FULL_INCLUDEDIR}/${QTERMWIDGET_LIBR

CHECK_FUNCTION_EXISTS(updwtmpx HAVE_UPDWTMPX)

qt5_wrap_cpp(MOCS ${HDRS})
qt5_wrap_ui(UI_SRCS ${UI})
set(PKG_CONFIG_REQ "Qt5Widgets")
qt6_wrap_cpp(MOCS ${HDRS})
qt6_wrap_ui(UI_SRCS ${UI})
set(PKG_CONFIG_REQ "Qt6Widgets")

lxqt_translate_ts(QTERMWIDGET_QM
TRANSLATION_DIR "lib/translations"
Expand All @@ -147,7 +147,7 @@ lxqt_translate_ts(QTERMWIDGET_QM
)

add_library(${QTERMWIDGET_LIBRARY_NAME} SHARED ${SRCS} ${MOCS} ${UI_SRCS} ${QTERMWIDGET_QM})
target_link_libraries(${QTERMWIDGET_LIBRARY_NAME} Qt5::Widgets)
target_link_libraries(${QTERMWIDGET_LIBRARY_NAME} Qt6::Widgets)
set_target_properties( ${QTERMWIDGET_LIBRARY_NAME} PROPERTIES
SOVERSION ${QTERMWIDGET_VERSION_MAJOR}
VERSION ${QTERMWIDGET_VERSION}
Expand Down
8 changes: 2 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Overview

A terminal emulator widget for Qt 5.
A terminal emulator widget for Qt 6.

QTermWidget is an open-source project originally based on the KDE4 Konsole application, but it took its own direction later on.
The main goal of this project is to provide a Unicode-enabled, embeddable Qt widget for using as a built-in console (or terminal emulation widget).
Expand Down Expand Up @@ -45,7 +45,7 @@ License: BSD-3-clause

### Compiling sources

The only runtime dependency is qtbase ≥ 5.12.0.
The only runtime dependency is qtbase ≥ 6.6.0.
Build dependencies are as follows:
- CMake ≥ 3.1.0 serves as the build system and therefore needs to be present to compile.
- The latest [lxqt-build-tools](https://github.com/lxqt/lxqt-build-tools/) is also needed for compilation.
Expand Down Expand Up @@ -124,7 +124,6 @@ void | setSilenceTimeout(int _seconds_)
void | setTerminalFont(QFont &_font_)
void | setTerminalOpacity(qreal _level_)
void | setTerminalSizeHint(bool _enabled_)
void | setTextCodec(QTextCodec *_codec_)
void | setWorkingDirectory(const QString &_dir_)
void | startShellProgram()
void | startTerminalTeletype()
Expand Down Expand Up @@ -325,9 +324,6 @@ Sets terminal font. Default is application font with family Monospace, size 10.
__void setTerminalSizeHint(bool _enabled_)__\
Exposes TerminalDisplay::TerminalSizeHint.

__void setTextCodec(QTextCodec *_codec_)__\
Sets text codec, default is UTF-8.

<!--__void setWorkingDirectory(const QString &_dir_)__\-->
<!--__void silence()__\-->

Expand Down
File renamed without changes.
12 changes: 6 additions & 6 deletions examples/cpp/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ int main(int argc, char *argv[])
QMenuBar *menuBar = new QMenuBar(mainWindow);
QMenu *actionsMenu = new QMenu(QStringLiteral("Actions"), menuBar);
menuBar->addMenu(actionsMenu);
actionsMenu->addAction(QStringLiteral("Find..."), console, &QTermWidget::toggleShowSearchBar,
QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_F));
actionsMenu->addAction(QStringLiteral("Copy"), console, &QTermWidget::copyClipboard,
QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_C));
actionsMenu->addAction(QStringLiteral("Paste"), console, &QTermWidget::pasteClipboard,
QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_V));
actionsMenu->addAction(QStringLiteral("Find..."), QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_F),
console, &QTermWidget::toggleShowSearchBar);
actionsMenu->addAction(QStringLiteral("Copy"), QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_C),
console, &QTermWidget::copyClipboard);
actionsMenu->addAction(QStringLiteral("Paste"), QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_V),
console, &QTermWidget::pasteClipboard);
doug1234 marked this conversation as resolved.
Show resolved Hide resolved
actionsMenu->addAction(QStringLiteral("About Qt"), &app, &QApplication::aboutQt);
mainWindow->setMenuBar(menuBar);

Expand Down
8 changes: 4 additions & 4 deletions lib/ColorScheme.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ void ColorScheme::readColorEntry(QSettings * s , int index)
bool ok = false;
// XXX: Undocumented(?) QSettings behavior: values with commas are parsed
// as QStringList and others QString
if (colorValue.type() == QVariant::StringList)
if (colorValue.typeId() == QVariant::StringList)
{
QStringList rgbList = colorValue.toStringList();
colorStr = rgbList.join(QLatin1Char(','));
Expand All @@ -364,9 +364,9 @@ void ColorScheme::readColorEntry(QSettings * s , int index)
if (hexColorPattern.match(colorStr).hasMatch())
{
// Parsing is always ok as already matched by the regexp
r = colorStr.midRef(1, 2).toInt(nullptr, 16);
g = colorStr.midRef(3, 2).toInt(nullptr, 16);
b = colorStr.midRef(5, 2).toInt(nullptr, 16);
r = colorStr.mid(1, 2).toInt(nullptr, 16);
g = colorStr.mid(3, 2).toInt(nullptr, 16);
b = colorStr.mid(5, 2).toInt(nullptr, 16);
ok = true;
}
}
Expand Down
36 changes: 7 additions & 29 deletions lib/Emulation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
#include <QClipboard>
#include <QHash>
#include <QKeyEvent>
#include <QRegExp>
#include <QRegularExpression>
#include <QTextStream>
#include <QThread>

Expand All @@ -49,11 +49,10 @@ using namespace Konsole;

Emulation::Emulation() :
_currentScreen(nullptr),
_codec(nullptr),
_decoder(nullptr),
_keyTranslator(nullptr),
_usesMouse(false),
_bracketedPasteMode(false)
_bracketedPasteMode(false),
_fromUtf8(QStringEncoder::Utf16)
{
// create screens with a default size
_screen[0] = new Screen(40,80);
Expand Down Expand Up @@ -126,7 +125,6 @@ Emulation::~Emulation()

delete _screen[0];
delete _screen[1];
delete _decoder;
}

void Emulation::setScreen(int n)
Expand All @@ -136,7 +134,7 @@ void Emulation::setScreen(int n)
if (_currentScreen != old)
{
// tell all windows onto this emulation to switch to the newly active screen
for(ScreenWindow* window : qAsConst(_windows))
for(ScreenWindow* window : std::as_const(_windows))
window->setScreen(_currentScreen);
}
}
Expand All @@ -157,27 +155,6 @@ const HistoryType& Emulation::history() const
return _screen[0]->getScroll();
}

void Emulation::setCodec(const QTextCodec * qtc)
{
if (qtc)
_codec = qtc;
else
setCodec(LocaleCodec);

delete _decoder;
_decoder = _codec->makeDecoder();

This comment was marked as resolved.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://doc.qt.io/qt-6/qstringencoder.html → "The encoder remembers any state that is required between calls,..."


emit useUtf8Request(utf8());
}

void Emulation::setCodec(EmulationCodec codec)
{
if ( codec == Utf8Codec )
setCodec( QTextCodec::codecForName("utf8") );
else if ( codec == LocaleCodec )
setCodec( QTextCodec::codecForLocale() );
}

void Emulation::setKeyBindings(const QString& name)
{
_keyTranslator = KeyboardTranslatorManager::instance()->findTranslator(name);
Expand Down Expand Up @@ -247,8 +224,9 @@ void Emulation::receiveData(const char* text, int length)
* U+10FFFF
* https://unicodebook.readthedocs.io/unicode_encodings.html#surrogates
*/
QString utf16Text = _decoder->toUnicode(text,length);
std::wstring unicodeText = utf16Text.toStdWString();
QString str = QString::fromUtf8(text, length);
auto encoded = _fromUtf8(str);
std::wstring unicodeText = encoded.data.toStdWString();

//send characters to terminal emulator
for (size_t i=0;i<unicodeText.length();i++)
Expand Down
22 changes: 2 additions & 20 deletions lib/Emulation.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@
// Qt
#include <QKeyEvent>
//#include <QPointer>
#include <QTextCodec>
#include <QTextStream>
#include <QTimer>
#include <QStringEncoder>

#include "qtermwidget_export.h"
#include "KeyboardTranslator.h"
Expand Down Expand Up @@ -190,20 +190,6 @@ Q_OBJECT
*/
virtual void writeToStream(TerminalCharacterDecoder* decoder,int startLine,int endLine);

/** Returns the codec used to decode incoming characters. See setCodec() */
const QTextCodec* codec() const { return _codec; }
/** Sets the codec used to decode incoming characters. */
void setCodec(const QTextCodec*);

/**
* Convenience method.
* Returns true if the current codec used to decode incoming
* characters is UTF-8
*/
bool utf8() const
{ Q_ASSERT(_codec); return _codec->mibEnum() == 106; }


/** TODO Document me */
virtual char eraseChar() const;

Expand Down Expand Up @@ -483,10 +469,6 @@ public slots:
// scrollbars are not enabled in this mode )


//decodes an incoming C-style character stream into a unicode QString using
//the current text codec. (this allows for rendering of non-ASCII characters in text files etc.)
const QTextCodec* _codec;
QTextDecoder* _decoder;
const KeyboardTranslator* _keyTranslator; // the keyboard layout

protected slots:
Expand All @@ -512,7 +494,7 @@ private slots:
bool _bracketedPasteMode;
QTimer _bulkTimer1{this};
QTimer _bulkTimer2{this};

QStringEncoder _fromUtf8;
};

}
Expand Down
67 changes: 36 additions & 31 deletions lib/Filter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -338,11 +338,11 @@ QStringList RegExpFilter::HotSpot::capturedTexts() const
return _capturedTexts;
}

void RegExpFilter::setRegExp(const QRegExp& regExp)
void RegExpFilter::setRegExp(const QRegularExpression& regExp)
{
_searchText = regExp;
}
QRegExp RegExpFilter::regExp() const
QRegularExpression RegExpFilter::regExp() const
{
return _searchText;
}
Expand All @@ -352,43 +352,48 @@ QRegExp RegExpFilter::regExp() const
}*/
void RegExpFilter::process()
{
int pos = 0;
const QString* text = buffer();

Q_ASSERT( text );

// ignore any regular expressions which match an empty string.
// otherwise the while loop below will run indefinitely
static const QString emptyString;
if ( _searchText.exactMatch(emptyString) )
return;

while(pos >= 0)
auto match = _searchText.match(emptyString, 0,
QRegularExpression::NormalMatch, QRegularExpression::AnchorAtOffsetMatchOption);
if (match.hasMatch())
{
pos = _searchText.indexIn(*text,pos);

if ( pos >= 0 )
{
int startLine = 0;
int endLine = 0;
int startColumn = 0;
int endColumn = 0;
return;
}

getLineColumn(pos,startLine,startColumn);
getLineColumn(pos + _searchText.matchedLength(),endLine,endColumn);
match = _searchText.match(*text);
while (match.hasMatch()) {
int startLine = 0;
int endLine = 0;
int startColumn = 0;
int endColumn = 0;

QStringList captureList;
for (int i = 0; i <= match.lastCapturedIndex(); i++) {
QString text = match.captured(i);
captureList.append(text);
}

getLineColumn(match.capturedStart(), startLine, startColumn);
getLineColumn(match.capturedEnd(), endLine, endColumn);

RegExpFilter::HotSpot* spot = newHotSpot(startLine,startColumn,
endLine,endColumn);
spot->setCapturedTexts(_searchText.capturedTexts());
RegExpFilter::HotSpot* spot = newHotSpot(startLine, startColumn, endLine, endColumn);
spot->setCapturedTexts(captureList);

addHotSpot( spot );
pos += _searchText.matchedLength();
addHotSpot(spot);

// if matchedLength == 0, the program will get stuck in an infinite loop
if ( _searchText.matchedLength() == 0 )
pos = -1;
// if capturedLength == 0, the program will get stuck in an infinite loop
if (match.capturedLength() == 0) {
break;
}
}

match = _searchText.match(*text, match.capturedEnd());
}
}

RegExpFilter::HotSpot* RegExpFilter::newHotSpot(int startLine,int startColumn,
Expand Down Expand Up @@ -417,9 +422,9 @@ UrlFilter::HotSpot::UrlType UrlFilter::HotSpot::urlType() const
{
QString url = capturedTexts().constFirst();

if ( FullUrlRegExp.exactMatch(url) )
if ( FullUrlRegExp.match(url).hasMatch() )
return StandardUrl;
else if ( EmailAddressRegExp.exactMatch(url) )
else if ( EmailAddressRegExp.match(url).hasMatch() )
return Email;
else
return Unknown;
Expand Down Expand Up @@ -465,13 +470,13 @@ void UrlFilter::HotSpot::activate(const QString& actionName)
//regexp matches:
// full url:
// protocolname:// or www. followed by anything other than whitespaces, <, >, ' or ", and ends before whitespaces, <, >, ', ", ], !, comma and dot
const QRegExp UrlFilter::FullUrlRegExp(QLatin1String("(www\\.(?!\\.)|[a-z][a-z0-9+.-]*://)[^\\s<>'\"]+[^!,\\.\\s<>'\"\\]]"));
const QRegularExpression UrlFilter::FullUrlRegExp(QLatin1String("(www\\.(?!\\.)|[a-z][a-z0-9+.-]*://)[^\\s<>'\"]+[^!,\\.\\s<>'\"\\]]"));
// email address:
// [word chars, dots or dashes]@[word chars, dots or dashes].[word chars]
const QRegExp UrlFilter::EmailAddressRegExp(QLatin1String("\\b(\\w|\\.|-)+@(\\w|\\.|-)+\\.\\w+\\b"));
const QRegularExpression UrlFilter::EmailAddressRegExp(QLatin1String("\\b(\\w|\\.|-)+@(\\w|\\.|-)+\\.\\w+\\b"));

// matches full url or email address
const QRegExp UrlFilter::CompleteUrlRegExp(QLatin1Char('(')+FullUrlRegExp.pattern()+QLatin1Char('|')+
const QRegularExpression UrlFilter::CompleteUrlRegExp(QLatin1Char('(')+FullUrlRegExp.pattern()+QLatin1Char('|')+
EmailAddressRegExp.pattern()+QLatin1Char(')'));

UrlFilter::UrlFilter()
Expand Down
Loading
Loading