From df4155f6178b21f3d10e38fa12ff373dd522b3a1 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 2 Aug 2022 11:04:10 +0200 Subject: [PATCH] App: Use more local methods to trigger memory trim timer The global event filter function is executed often, for events originating deep in the widget hierarchy even multiple times. Triggering the timer only by mouse and key presses on the main application and on texteditor is less intrusive and still happens often enough (TM). Change-Id: I848d55a347bd62d12e8523965d1750c59da33116 Reviewed-by: Reviewed-by: Christian Kandeler --- src/app/main.cpp | 31 --------------------------- src/plugins/coreplugin/icore.cpp | 5 +++++ src/plugins/coreplugin/icore.h | 1 + src/plugins/coreplugin/mainwindow.cpp | 29 +++++++++++++++++++++++++ src/plugins/coreplugin/mainwindow.h | 6 ++++++ src/plugins/texteditor/texteditor.cpp | 4 ++++ 6 files changed, 45 insertions(+), 31 deletions(-) diff --git a/src/app/main.cpp b/src/app/main.cpp index 8b7b8d62944..f78cd20e402 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -84,10 +84,6 @@ #include "client/settings.h" #endif -#ifdef Q_OS_LINUX -#include -#endif - using namespace ExtensionSystem; enum { OptionIndent = 4, DescriptionIndent = 34 }; @@ -757,32 +753,5 @@ int main(int argc, char **argv) // shutdown plugin manager on the exit QObject::connect(&app, &QCoreApplication::aboutToQuit, &pluginManager, &PluginManager::shutdown); -#ifdef Q_OS_LINUX - class MemoryTrimmer : public QObject - { - public: - MemoryTrimmer() - { - m_trimTimer.setSingleShot(true); - m_trimTimer.setInterval(60000); - // glibc may not actually free memory in free(). - connect(&m_trimTimer, &QTimer::timeout, this, [] { malloc_trim(0); }); - } - - bool eventFilter(QObject *, QEvent *e) override - { - if ((e->type() == QEvent::MouseButtonPress || e->type() == QEvent::KeyPress) - && !m_trimTimer.isActive()) { - m_trimTimer.start(); - } - return false; - } - - QTimer m_trimTimer; - }; - MemoryTrimmer trimmer; - app.installEventFilter(&trimmer); -#endif - return restarter.restartOrExit(app.exec()); } diff --git a/src/plugins/coreplugin/icore.cpp b/src/plugins/coreplugin/icore.cpp index dc96efbd35a..4e65891c329 100644 --- a/src/plugins/coreplugin/icore.cpp +++ b/src/plugins/coreplugin/icore.cpp @@ -832,6 +832,11 @@ void ICore::registerWindow(QWidget *window, const Context &context) new WindowSupport(window, context); // deletes itself when widget is destroyed } +void ICore::restartTrimmer() +{ + m_mainwindow->restartTrimmer(); +} + /*! Opens files using \a filePaths and \a flags like it would be done if they were given to \QC on the command line, or diff --git a/src/plugins/coreplugin/icore.h b/src/plugins/coreplugin/icore.h index 518386b0aea..b1c9b5b39e5 100644 --- a/src/plugins/coreplugin/icore.h +++ b/src/plugins/coreplugin/icore.h @@ -124,6 +124,7 @@ public: static void removeContextObject(IContext *context); static void registerWindow(QWidget *window, const Context &context); + static void restartTrimmer(); enum OpenFilesFlags { None = 0, diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp index ae51062df2a..b2474d5a0ad 100644 --- a/src/plugins/coreplugin/mainwindow.cpp +++ b/src/plugins/coreplugin/mainwindow.cpp @@ -113,6 +113,10 @@ #include #include +#ifdef Q_OS_LINUX +#include +#endif + using namespace ExtensionSystem; using namespace Utils; @@ -228,6 +232,13 @@ MainWindow::MainWindow() }); connect(dropSupport, &DropSupport::filesDropped, this, &MainWindow::openDroppedFiles); + +#ifdef Q_OS_LINUX + m_trimTimer.setSingleShot(true); + m_trimTimer.setInterval(60000); + // glibc may not actually free memory in free(). + connect(&m_trimTimer, &QTimer::timeout, this, [] { malloc_trim(0); }); +#endif } NavigationWidget *MainWindow::navigationWidget(Side side) const @@ -367,6 +378,12 @@ void MainWindow::restart() exit(); } +void MainWindow::restartTrimmer() +{ + if (!m_trimTimer.isActive()) + m_trimTimer.start(); +} + void MainWindow::closeEvent(QCloseEvent *event) { const auto cancelClose = [event] { @@ -419,6 +436,18 @@ void MainWindow::closeEvent(QCloseEvent *event) alreadyClosed = true; } +void MainWindow::keyPressEvent(QKeyEvent *event) +{ + restartTrimmer(); + AppMainWindow::keyPressEvent(event); +} + +void MainWindow::mousePressEvent(QMouseEvent *event) +{ + restartTrimmer(); + AppMainWindow::mousePressEvent(event); +} + void MainWindow::openDroppedFiles(const QList &files) { raiseWindow(); diff --git a/src/plugins/coreplugin/mainwindow.h b/src/plugins/coreplugin/mainwindow.h index 674bebf5719..7947943f6c8 100644 --- a/src/plugins/coreplugin/mainwindow.h +++ b/src/plugins/coreplugin/mainwindow.h @@ -32,6 +32,7 @@ #include #include +#include #include #include @@ -118,12 +119,16 @@ public: void openFileFromDevice(); + void restartTrimmer(); + public slots: static void openFileWith(); void exit(); protected: void closeEvent(QCloseEvent *event) override; + void keyPressEvent(QKeyEvent *event) override; + void mousePressEvent(QMouseEvent *event) override; private: static void openFile(); @@ -153,6 +158,7 @@ private: void updateModeSelectorStyleMenu(); ICore *m_coreImpl = nullptr; + QTimer m_trimTimer; QStringList m_aboutInformation; Context m_highPrioAdditionalContexts; Context m_lowPrioAdditionalContexts; diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index aac38ac2dab..b70b214d190 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -2372,6 +2372,8 @@ static inline bool isPrintableText(const QString &text) void TextEditorWidget::keyPressEvent(QKeyEvent *e) { + ICore::restartTrimmer(); + ExecuteOnDestruction eod([&]() { d->clearBlockSelection(); }); if (!isModifier(e) && mouseHidingEnabled()) @@ -5460,6 +5462,8 @@ static bool handleForwardBackwardMouseButtons(QMouseEvent *e) void TextEditorWidget::mousePressEvent(QMouseEvent *e) { + ICore::restartTrimmer(); + if (e->button() == Qt::LeftButton) { MultiTextCursor multiCursor = multiTextCursor(); const QTextCursor &cursor = cursorForPosition(e->pos());