From 9842761c1c301cccf28877d75e6ab79e40613d06 Mon Sep 17 00:00:00 2001 From: Xiao Yi Fang Date: Sat, 10 Aug 2024 17:02:38 +0800 Subject: [PATCH 1/6] fix: code smell ,remove while(1) --- src/decompress.cc | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/src/decompress.cc b/src/decompress.cc index 7217d4691..22a1f30a0 100644 --- a/src/decompress.cc +++ b/src/decompress.cc @@ -14,10 +14,9 @@ QByteArray zlibDecompress( const char * bufptr, unsigned length ) memset( &zs, 0, sizeof( zs ) ); zs.next_in = (Bytef *)bufptr; zs.avail_in = length; - while ( 1 ) { - res = inflateInit( &zs ); - if ( res != Z_OK ) - break; + res = inflateInit( &zs ); + + if ( res == Z_OK ) { while ( res != Z_STREAM_END ) { zs.next_out = (Bytef *)buf; zs.avail_out = CHUNK_SIZE; @@ -26,8 +25,8 @@ QByteArray zlibDecompress( const char * bufptr, unsigned length ) if ( res != Z_OK && res != Z_STREAM_END ) break; } - break; } + inflateEnd( &zs ); if ( res != Z_STREAM_END ) str.clear(); @@ -50,10 +49,8 @@ string decompressBzip2( const char * bufptr, unsigned length ) zs.next_in = (char *)bufptr; zs.avail_in = length; zs.total_in_lo32 = length; - while ( 1 ) { - res = BZ2_bzDecompressInit( &zs, 0, 0 ); - if ( res != BZ_OK ) - break; + res = BZ2_bzDecompressInit( &zs, 0, 0 ); + if ( res == BZ_OK ) { while ( res != BZ_STREAM_END ) { zs.next_out = buf; zs.avail_out = CHUNK_SIZE; @@ -63,7 +60,6 @@ string decompressBzip2( const char * bufptr, unsigned length ) if ( res != BZ_OK && res != BZ_STREAM_END ) break; } - break; } BZ2_bzDecompressEnd( &zs ); if ( res != BZ_STREAM_END ) @@ -92,14 +88,13 @@ string decompressLzma2( const char * bufptr, unsigned length, bool raw_decoder ) filters[ 1 ].id = LZMA_VLI_UNKNOWN; } - while ( 1 ) { - if ( raw_decoder ) - res = lzma_raw_decoder( &strm, filters ); - else - res = lzma_stream_decoder( &strm, UINT64_MAX, 0 ); - if ( res != LZMA_OK ) - break; + if ( raw_decoder ) + res = lzma_raw_decoder( &strm, filters ); + else + res = lzma_stream_decoder( &strm, UINT64_MAX, 0 ); + + if ( res == LZMA_OK ) { while ( res != LZMA_STREAM_END ) { strm.next_out = reinterpret_cast< uint8_t * >( buf ); @@ -112,8 +107,7 @@ string decompressLzma2( const char * bufptr, unsigned length, bool raw_decoder ) lzma_end( &strm ); if ( res != LZMA_STREAM_END ) str.clear(); - - break; } + return str; } From dc4647069d4bb302d574e8cc7bb0f844b23ebd90 Mon Sep 17 00:00:00 2001 From: Xiao Yi Fang Date: Mon, 12 Aug 2024 16:53:47 +0800 Subject: [PATCH 2/6] opt: webview history navigation --- src/ui/articleview.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ui/articleview.cc b/src/ui/articleview.cc index 8e30bfaf5..d5d871f64 100644 --- a/src/ui/articleview.cc +++ b/src/ui/articleview.cc @@ -1430,7 +1430,8 @@ QString ArticleView::getTitle() QString ArticleView::getWord() const { - return currentWord; + return webview->history()->currentItem().title(); + // return currentWord; } void ArticleView::print( QPrinter * printer ) const From 5147c8c03666f3f8e125d3d458387ea7a8dc46fe Mon Sep 17 00:00:00 2001 From: Xiao Yi Fang Date: Tue, 13 Aug 2024 16:43:10 +0800 Subject: [PATCH 3/6] opt: default and plaintext are the same ,remove one --- src/fulltextsearch.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/fulltextsearch.cc b/src/fulltextsearch.cc index 5f81b4711..34a9c80f0 100644 --- a/src/fulltextsearch.cc +++ b/src/fulltextsearch.cc @@ -217,10 +217,9 @@ FullTextSearchDialog::FullTextSearchDialog( QWidget * parent, &FullTextSearchDialog::setNewIndexingName ); ui.searchMode->addItem( tr( "Default" ), WholeWords ); - ui.searchMode->addItem( tr( "Plain text" ), PlainText ); ui.searchMode->addItem( tr( "Wildcards" ), Wildcards ); - ui.searchLine->setToolTip( tr( "support xapian search syntax,such as AND OR +/- etc" ) ); + ui.searchLine->setToolTip( tr( "Support xapian search syntax, such as AND OR +/- etc." ) ); ui.searchMode->setCurrentIndex( cfg.preferences.fts.searchMode ); From 51701ce4aa5812c1ddaf13704626fbfd27adb0f4 Mon Sep 17 00:00:00 2001 From: Xiao Yi Fang Date: Tue, 20 Aug 2024 10:48:31 +0800 Subject: [PATCH 4/6] opt: double click in welcome page --- src/ui/articleview.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/ui/articleview.cc b/src/ui/articleview.cc index d5d871f64..45722dce1 100644 --- a/src/ui/articleview.cc +++ b/src/ui/articleview.cc @@ -2005,12 +2005,16 @@ void ArticleView::doubleClicked( QPoint pos ) else { QUrl const & ref = webview->url(); + auto groupId = getGroup( ref ); + if ( groupId == 0 || groupId == Instances::Group::HelpGroupId ) { + groupId = currentGroupId; + } if ( Utils::Url::hasQueryItem( ref, "dictionaries" ) ) { QStringList dictsList = Utils::Url::queryItemValue( ref, "dictionaries" ).split( ",", Qt::SkipEmptyParts ); - showDefinition( selectedText, dictsList, getGroup( ref ), false ); + showDefinition( selectedText, dictsList, groupId, false ); } else - showDefinition( selectedText, getGroup( ref ), getCurrentArticle() ); + showDefinition( selectedText, groupId, getCurrentArticle() ); } } } From 9332763f6722a93da01f812f91f34ff131265280 Mon Sep 17 00:00:00 2001 From: xiaoyifang <105986+xiaoyifang@users.noreply.github.com> Date: Wed, 21 Aug 2024 13:42:56 +0800 Subject: [PATCH 5/6] fix: prioritize the manual set full text index option per dictionary (#1730) * fix: prioritize the manual set full text index option per dictionary --- src/dict/aard.cc | 9 +++++++-- src/dict/bgl.cc | 8 ++++++-- src/dict/dictdfiles.cc | 8 ++++++-- src/dict/dictionary.hh | 5 ++--- src/dict/dsl.cc | 9 ++++++--- src/dict/epwing.cc | 9 ++++++--- src/dict/gls.cc | 8 ++++++-- src/dict/mdx.cc | 9 ++++++--- src/dict/sdict.cc | 8 ++++++-- src/dict/slob.cc | 8 ++++++-- src/dict/stardict.cc | 8 ++++++-- src/dict/xdxf.cc | 8 ++++++-- src/dict/zim.cc | 8 ++++++-- 13 files changed, 75 insertions(+), 30 deletions(-) diff --git a/src/dict/aard.cc b/src/dict/aard.cc index e713b86d3..421f9595c 100644 --- a/src/dict/aard.cc +++ b/src/dict/aard.cc @@ -263,8 +263,13 @@ class AardDictionary: public BtreeIndexing::BtreeDictionary void setFTSParameters( Config::FullTextSearch const & fts ) override { - can_FTS = enable_FTS && fts.enabled && !fts.disabledTypes.contains( "AARD", Qt::CaseInsensitive ) - && ( fts.maxDictionarySize == 0 || getArticleCount() <= fts.maxDictionarySize ); + if ( metadata_enable_fts.has_value() ) { + can_FTS = fts.enabled && metadata_enable_fts.value(); + } + else { + can_FTS = fts.enabled && !fts.disabledTypes.contains( "AARD", Qt::CaseInsensitive ) + && ( fts.maxDictionarySize == 0 || getArticleCount() <= fts.maxDictionarySize ); + } } protected: diff --git a/src/dict/bgl.cc b/src/dict/bgl.cc index f2d7d1611..1435d9505 100644 --- a/src/dict/bgl.cc +++ b/src/dict/bgl.cc @@ -219,8 +219,12 @@ class BglDictionary: public BtreeIndexing::BtreeDictionary void setFTSParameters( Config::FullTextSearch const & fts ) override { - can_FTS = enable_FTS && fts.enabled && !fts.disabledTypes.contains( "BGL", Qt::CaseInsensitive ) - && ( fts.maxDictionarySize == 0 || getArticleCount() <= fts.maxDictionarySize ); + if ( metadata_enable_fts.has_value() ) { + can_FTS = fts.enabled && metadata_enable_fts.value(); + } + else + can_FTS = fts.enabled && !fts.disabledTypes.contains( "BGL", Qt::CaseInsensitive ) + && ( fts.maxDictionarySize == 0 || getArticleCount() <= fts.maxDictionarySize ); } protected: diff --git a/src/dict/dictdfiles.cc b/src/dict/dictdfiles.cc index 6f71130dd..60012101c 100644 --- a/src/dict/dictdfiles.cc +++ b/src/dict/dictdfiles.cc @@ -140,8 +140,12 @@ class DictdDictionary: public BtreeIndexing::BtreeDictionary void setFTSParameters( Config::FullTextSearch const & fts ) override { - can_FTS = enable_FTS && fts.enabled && !fts.disabledTypes.contains( "DICTD", Qt::CaseInsensitive ) - && ( fts.maxDictionarySize == 0 || getArticleCount() <= fts.maxDictionarySize ); + if ( metadata_enable_fts.has_value() ) { + can_FTS = fts.enabled && metadata_enable_fts.value(); + } + else + can_FTS = fts.enabled && !fts.disabledTypes.contains( "DICTD", Qt::CaseInsensitive ) + && ( fts.maxDictionarySize == 0 || getArticleCount() <= fts.maxDictionarySize ); } }; diff --git a/src/dict/dictionary.hh b/src/dict/dictionary.hh index 2fed491be..ef2ecdcc1 100644 --- a/src/dict/dictionary.hh +++ b/src/dict/dictionary.hh @@ -315,8 +315,7 @@ protected: QAtomicInt FTS_index_completed; bool synonymSearchEnabled; string dictionaryName; - //default to true; - bool enable_FTS = true; + std::optional< bool > metadata_enable_fts = std::nullopt; // Load user icon if it exist // By default set icon to empty @@ -376,7 +375,7 @@ public: void setFtsEnable( bool _enable_FTS ) { - enable_FTS = _enable_FTS; + metadata_enable_fts = _enable_FTS; } /// Returns all the available properties, like the author's name, copyright, diff --git a/src/dict/dsl.cc b/src/dict/dsl.cc index 91d81f7a2..88ee1d443 100644 --- a/src/dict/dsl.cc +++ b/src/dict/dsl.cc @@ -235,9 +235,12 @@ class DslDictionary: public BtreeIndexing::BtreeDictionary { if ( ensureInitDone().size() ) return; - - can_FTS = enable_FTS && fts.enabled && !fts.disabledTypes.contains( "DSL", Qt::CaseInsensitive ) - && ( fts.maxDictionarySize == 0 || getArticleCount() <= fts.maxDictionarySize ); + if ( metadata_enable_fts.has_value() ) { + can_FTS = fts.enabled && metadata_enable_fts.value(); + } + else + can_FTS = fts.enabled && !fts.disabledTypes.contains( "DSL", Qt::CaseInsensitive ) + && ( fts.maxDictionarySize == 0 || getArticleCount() <= fts.maxDictionarySize ); } uint32_t getFtsIndexVersion() override diff --git a/src/dict/epwing.cc b/src/dict/epwing.cc index 470f4b51f..ce3b26c04 100644 --- a/src/dict/epwing.cc +++ b/src/dict/epwing.cc @@ -154,9 +154,12 @@ class EpwingDictionary: public BtreeIndexing::BtreeDictionary { if ( ensureInitDone().size() ) return; - - can_FTS = enable_FTS && fts.enabled && !fts.disabledTypes.contains( "EPWING", Qt::CaseInsensitive ) - && ( fts.maxDictionarySize == 0 || getArticleCount() <= fts.maxDictionarySize ); + if ( metadata_enable_fts.has_value() ) { + can_FTS = fts.enabled && metadata_enable_fts.value(); + } + else + can_FTS = fts.enabled && !fts.disabledTypes.contains( "EPWING", Qt::CaseInsensitive ) + && ( fts.maxDictionarySize == 0 || getArticleCount() <= fts.maxDictionarySize ); } static int japaneseWriting( gd::wchar ch ); diff --git a/src/dict/gls.cc b/src/dict/gls.cc index 2b96ae500..03256a0f9 100644 --- a/src/dict/gls.cc +++ b/src/dict/gls.cc @@ -408,8 +408,12 @@ class GlsDictionary: public BtreeIndexing::BtreeDictionary void setFTSParameters( Config::FullTextSearch const & fts ) override { - can_FTS = enable_FTS && fts.enabled && !fts.disabledTypes.contains( "GLS", Qt::CaseInsensitive ) - && ( fts.maxDictionarySize == 0 || getArticleCount() <= fts.maxDictionarySize ); + if ( metadata_enable_fts.has_value() ) { + can_FTS = fts.enabled && metadata_enable_fts.value(); + } + else + can_FTS = fts.enabled && !fts.disabledTypes.contains( "GLS", Qt::CaseInsensitive ) + && ( fts.maxDictionarySize == 0 || getArticleCount() <= fts.maxDictionarySize ); } protected: diff --git a/src/dict/mdx.cc b/src/dict/mdx.cc index 4504a2e3c..665f3a724 100644 --- a/src/dict/mdx.cc +++ b/src/dict/mdx.cc @@ -260,9 +260,12 @@ class MdxDictionary: public BtreeIndexing::BtreeDictionary { if ( !ensureInitDone().empty() ) return; - - can_FTS = enable_FTS && fts.enabled && !fts.disabledTypes.contains( "MDICT", Qt::CaseInsensitive ) - && ( fts.maxDictionarySize == 0 || getArticleCount() <= fts.maxDictionarySize ); + if ( metadata_enable_fts.has_value() ) { + can_FTS = fts.enabled && metadata_enable_fts.value(); + } + else + can_FTS = fts.enabled && !fts.disabledTypes.contains( "MDICT", Qt::CaseInsensitive ) + && ( fts.maxDictionarySize == 0 || getArticleCount() <= fts.maxDictionarySize ); } QString getCachedFileName( QString name ); diff --git a/src/dict/sdict.cc b/src/dict/sdict.cc index d5cb74f71..207ffe23d 100644 --- a/src/dict/sdict.cc +++ b/src/dict/sdict.cc @@ -177,8 +177,12 @@ class SdictDictionary: public BtreeIndexing::BtreeDictionary void setFTSParameters( Config::FullTextSearch const & fts ) override { - can_FTS = enable_FTS && fts.enabled && !fts.disabledTypes.contains( "SDICT", Qt::CaseInsensitive ) - && ( fts.maxDictionarySize == 0 || getArticleCount() <= fts.maxDictionarySize ); + if ( metadata_enable_fts.has_value() ) { + can_FTS = fts.enabled && metadata_enable_fts.value(); + } + else + can_FTS = fts.enabled && !fts.disabledTypes.contains( "SDICT", Qt::CaseInsensitive ) + && ( fts.maxDictionarySize == 0 || getArticleCount() <= fts.maxDictionarySize ); } protected: diff --git a/src/dict/slob.cc b/src/dict/slob.cc index b1f5fa33d..c8e1b164b 100644 --- a/src/dict/slob.cc +++ b/src/dict/slob.cc @@ -640,8 +640,12 @@ class SlobDictionary: public BtreeIndexing::BtreeDictionary void setFTSParameters( Config::FullTextSearch const & fts ) override { - can_FTS = enable_FTS && fts.enabled && !fts.disabledTypes.contains( "SLOB", Qt::CaseInsensitive ) - && ( fts.maxDictionarySize == 0 || getArticleCount() <= fts.maxDictionarySize ); + if ( metadata_enable_fts.has_value() ) { + can_FTS = fts.enabled && metadata_enable_fts.value(); + } + else + can_FTS = fts.enabled && !fts.disabledTypes.contains( "SLOB", Qt::CaseInsensitive ) + && ( fts.maxDictionarySize == 0 || getArticleCount() <= fts.maxDictionarySize ); } uint32_t getFtsIndexVersion() override diff --git a/src/dict/stardict.cc b/src/dict/stardict.cc index 6a4b0f3c0..c5096aaa7 100644 --- a/src/dict/stardict.cc +++ b/src/dict/stardict.cc @@ -200,8 +200,12 @@ class StardictDictionary: public BtreeIndexing::BtreeDictionary void setFTSParameters( Config::FullTextSearch const & fts ) override { - can_FTS = enable_FTS && fts.enabled && !fts.disabledTypes.contains( "STARDICT", Qt::CaseInsensitive ) - && ( fts.maxDictionarySize == 0 || getArticleCount() <= fts.maxDictionarySize ); + if ( metadata_enable_fts.has_value() ) { + can_FTS = fts.enabled && metadata_enable_fts.value(); + } + else + can_FTS = fts.enabled && !fts.disabledTypes.contains( "STARDICT", Qt::CaseInsensitive ) + && ( fts.maxDictionarySize == 0 || getArticleCount() <= fts.maxDictionarySize ); } protected: diff --git a/src/dict/xdxf.cc b/src/dict/xdxf.cc index 79e01e218..bda3fd852 100644 --- a/src/dict/xdxf.cc +++ b/src/dict/xdxf.cc @@ -200,8 +200,12 @@ class XdxfDictionary: public BtreeIndexing::BtreeDictionary void setFTSParameters( Config::FullTextSearch const & fts ) override { - can_FTS = enable_FTS && fts.enabled && !fts.disabledTypes.contains( "XDXF", Qt::CaseInsensitive ) - && ( fts.maxDictionarySize == 0 || getArticleCount() <= fts.maxDictionarySize ); + if ( metadata_enable_fts.has_value() ) { + can_FTS = fts.enabled && metadata_enable_fts.value(); + } + else + can_FTS = fts.enabled && !fts.disabledTypes.contains( "XDXF", Qt::CaseInsensitive ) + && ( fts.maxDictionarySize == 0 || getArticleCount() <= fts.maxDictionarySize ); } uint32_t getFtsIndexVersion() override diff --git a/src/dict/zim.cc b/src/dict/zim.cc index 53e360789..61a13ab40 100644 --- a/src/dict/zim.cc +++ b/src/dict/zim.cc @@ -221,8 +221,12 @@ class ZimDictionary: public BtreeIndexing::BtreeDictionary void setFTSParameters( Config::FullTextSearch const & fts ) override { - can_FTS = enable_FTS && fts.enabled && !fts.disabledTypes.contains( "ZIM", Qt::CaseInsensitive ) - && ( fts.maxDictionarySize == 0 || getArticleCount() <= fts.maxDictionarySize ); + if ( metadata_enable_fts.has_value() ) { + can_FTS = fts.enabled && metadata_enable_fts.value(); + } + else + can_FTS = fts.enabled && !fts.disabledTypes.contains( "ZIM", Qt::CaseInsensitive ) + && ( fts.maxDictionarySize == 0 || getArticleCount() <= fts.maxDictionarySize ); } protected: From 3ca7c39e69e38123c774232826433ecba003f869 Mon Sep 17 00:00:00 2001 From: shenleban tongying Date: Wed, 21 Aug 2024 20:19:35 -0400 Subject: [PATCH 6/6] feat: properly handle Unix signals, like `SIGTERM`, for graceful exit (#1732) * feat: handle UNIX shutting down SIGNALS * Convey ksignalhandler from LGPLv2.1+ to GPLv3+ which allowed/required --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- src/main.cc | 7 +++ src/unix/ksignalhandler.cc | 99 ++++++++++++++++++++++++++++++++++++++ src/unix/ksignalhandler.hh | 68 ++++++++++++++++++++++++++ 3 files changed, 174 insertions(+) create mode 100644 src/unix/ksignalhandler.cc create mode 100644 src/unix/ksignalhandler.hh diff --git a/src/main.cc b/src/main.cc index b40656cf4..7415bc830 100644 --- a/src/main.cc +++ b/src/main.cc @@ -14,6 +14,7 @@ #if defined( Q_OS_UNIX ) #include + #include "unix/ksignalhandler.hh" #endif #ifdef Q_OS_WIN32 @@ -590,6 +591,12 @@ int main( int argc, char ** argv ) if ( gdcl.needTranslateWord() ) m.wordReceived( gdcl.wordToTranslate() ); +#ifdef Q_OS_UNIX + // handle Unix's shutdown signals for graceful exit + KSignalHandler::self()->watchSignal( SIGINT ); + KSignalHandler::self()->watchSignal( SIGTERM ); + QObject::connect( KSignalHandler::self(), &KSignalHandler::signalReceived, &m, &MainWindow::quitApp ); +#endif int r = app.exec(); app.removeDataCommiter( m ); diff --git a/src/unix/ksignalhandler.cc b/src/unix/ksignalhandler.cc new file mode 100644 index 000000000..c6c48c887 --- /dev/null +++ b/src/unix/ksignalhandler.cc @@ -0,0 +1,99 @@ +/* + SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez + + SPDX-License-Identifier: GPL-3.0-or-later + + Copied from KDE's KCoreAddons with minor modifications +*/ +#include +#ifdef Q_OS_UNIX + + #include "ksignalhandler.hh" + #include + #include + #include + #include + #include + #include + #include + #include + +class KSignalHandlerPrivate: public QObject +{ +public: + static void signalHandler( int signal ); + void handleSignal(); + + QSet< int > m_signalsRegistered; + static int signalFd[ 2 ]; + QSocketNotifier * m_handler = nullptr; + + KSignalHandler * q; +}; + +int KSignalHandlerPrivate::signalFd[ 2 ]; + +KSignalHandler::KSignalHandler(): + d( new KSignalHandlerPrivate ) +{ + d->q = this; + if ( ::socketpair( AF_UNIX, SOCK_STREAM, 0, KSignalHandlerPrivate::signalFd ) ) { + qDebug() << "Couldn't create a socketpair"; + return; + } + + // ensure the sockets are not leaked to child processes, SOCK_CLOEXEC not supported on macOS + fcntl( KSignalHandlerPrivate::signalFd[ 0 ], F_SETFD, FD_CLOEXEC ); + fcntl( KSignalHandlerPrivate::signalFd[ 1 ], F_SETFD, FD_CLOEXEC ); + + QTimer::singleShot( 0, [ this ] { + d->m_handler = new QSocketNotifier( KSignalHandlerPrivate::signalFd[ 1 ], QSocketNotifier::Read, this ); + connect( d->m_handler, &QSocketNotifier::activated, d.get(), &KSignalHandlerPrivate::handleSignal ); + } ); +} + +KSignalHandler::~KSignalHandler() +{ + for ( int sig : std::as_const( d->m_signalsRegistered ) ) { + signal( sig, nullptr ); + } + close( KSignalHandlerPrivate::signalFd[ 0 ] ); + close( KSignalHandlerPrivate::signalFd[ 1 ] ); +} + +void KSignalHandler::watchSignal( int signalToTrack ) +{ + d->m_signalsRegistered.insert( signalToTrack ); + signal( signalToTrack, KSignalHandlerPrivate::signalHandler ); +} + +void KSignalHandlerPrivate::signalHandler( int signal ) +{ + const int ret = ::write( signalFd[ 0 ], &signal, sizeof( signal ) ); + if ( ret != sizeof( signal ) ) { + qDebug() << "signalHandler couldn't write for signal" << strsignal( signal ) << " Got error:" << strerror( errno ); + } +} + +void KSignalHandlerPrivate::handleSignal() +{ + m_handler->setEnabled( false ); + int signal; + const int ret = ::read( KSignalHandlerPrivate::signalFd[ 1 ], &signal, sizeof( signal ) ); + if ( ret != sizeof( signal ) ) { + qDebug() << "handleSignal couldn't read signal for fd" << KSignalHandlerPrivate::signalFd[ 1 ] + << " Got error:" << strerror( errno ); + return; + } + m_handler->setEnabled( true ); + + Q_EMIT q->signalReceived( signal ); +} + +KSignalHandler * KSignalHandler::self() +{ + static KSignalHandler s_self; + return &s_self; +} + +#endif \ No newline at end of file diff --git a/src/unix/ksignalhandler.hh b/src/unix/ksignalhandler.hh new file mode 100644 index 000000000..c1de838b8 --- /dev/null +++ b/src/unix/ksignalhandler.hh @@ -0,0 +1,68 @@ +/* + SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez + + SPDX-License-Identifier: GPL-3.0-or-later + + Copied from KDE's KCoreAddons with minor modifications +*/ +#pragma once +#include +#ifdef Q_OS_UNIX + #include + #include + +class KSignalHandlerPrivate; + +/** + * Allows getting ANSI C signals and forward them onto the Qt eventloop. + * + * It's a singleton as it relies on static data getting defined. + * + * \code + * { + * KSignalHandler::self()->watchSignal(SIGTERM); + * connect(KSignalHandler::self(), &KSignalHandler::signalReceived, + * this, &SomeClass::handleSignal); + * job->start(); + * } + * \endcode + * + * @since 5.92 + */ +class KSignalHandler: public QObject +{ + Q_OBJECT + +public: + ~KSignalHandler() override; + + /** + * Adds @p signal to be watched for. Once the process is notified about this signal, @m signalReceived will be emitted with the same @p signal as an + * argument. + * + * @see signalReceived + */ + void watchSignal( int signal ); + + /** + * Fetches an instance we can use to register our signals. + */ + static KSignalHandler * self(); + +Q_SIGNALS: + /** + * Notifies that @p signal is emitted. + * + * To catch a signal, we need to make sure it's registered using @m watchSignal. + * + * @see watchSignal + */ + void signalReceived( int signal ); + +private: + KSignalHandler(); + + QScopedPointer< KSignalHandlerPrivate > d; +}; + +#endif \ No newline at end of file