diff --git a/src/apps/res/deskflow.qrc b/src/apps/res/deskflow.qrc
index e6ea98f1d..a1a62c517 100644
--- a/src/apps/res/deskflow.qrc
+++ b/src/apps/res/deskflow.qrc
@@ -5,11 +5,14 @@
icons/deskflow-dark/actions/16/document-edit.svg
icons/deskflow-dark/actions/16/document-open.svg
icons/deskflow-dark/actions/16/document-save-as.svg
+ icons/deskflow-dark/actions/16/go-down.svg
+ icons/deskflow-dark/actions/16/go-up.svg
icons/deskflow-dark/actions/16/help-about.svg
icons/deskflow-dark/actions/16/network-connect.svg
icons/deskflow-dark/actions/16/network-disconnect.svg
icons/deskflow-dark/actions/16/process-stop.svg
icons/deskflow-dark/actions/16/system-run.svg
+ icons/deskflow-dark/actions/16/system-search.svg
icons/deskflow-dark/actions/16/tools-report-bug.svg
icons/deskflow-dark/actions/16/view-close.svg
icons/deskflow-dark/actions/16/view-refresh.svg
@@ -21,11 +24,14 @@
icons/deskflow-dark/actions/22/document-open.svg
icons/deskflow-dark/actions/22/document-save-as.svg
icons/deskflow-dark/actions/22/fingerprint.svg
+ icons/deskflow-dark/actions/22/go-down.svg
+ icons/deskflow-dark/actions/22/go-up.svg
icons/deskflow-dark/actions/22/help-about.svg
icons/deskflow-dark/actions/22/network-connect.svg
icons/deskflow-dark/actions/22/network-disconnect.svg
icons/deskflow-dark/actions/22/process-stop.svg
icons/deskflow-dark/actions/22/system-run.svg
+ icons/deskflow-dark/actions/22/system-search.svg
icons/deskflow-dark/actions/22/tools-report-bug.svg
icons/deskflow-dark/actions/22/view-close.svg
icons/deskflow-dark/actions/22/view-refresh.svg
@@ -36,6 +42,8 @@
icons/deskflow-dark/actions/24/document-edit.svg
icons/deskflow-dark/actions/24/document-open.svg
icons/deskflow-dark/actions/24/document-save-as.svg
+ icons/deskflow-dark/actions/24/go-down.svg
+ icons/deskflow-dark/actions/24/go-up.svg
icons/deskflow-dark/actions/24/edit-clear-all.svg
icons/deskflow-dark/actions/24/fingerprint.svg
icons/deskflow-dark/actions/24/help-about.svg
@@ -43,6 +51,7 @@
icons/deskflow-dark/actions/24/network-disconnect.svg
icons/deskflow-dark/actions/24/process-stop.svg
icons/deskflow-dark/actions/24/system-run.svg
+ icons/deskflow-dark/actions/24/system-search.svg
icons/deskflow-dark/actions/24/tools-report-bug.svg
icons/deskflow-dark/actions/24/view-close.svg
icons/deskflow-dark/actions/24/view-refresh.svg
@@ -55,8 +64,11 @@
icons/deskflow-dark/actions/32/dialog-ok-apply.svg
icons/deskflow-dark/actions/32/document-open.svg
icons/deskflow-dark/actions/32/document-save-as.svg
+ icons/deskflow-dark/actions/32/go-down.svg
+ icons/deskflow-dark/actions/32/go-up.svg
icons/deskflow-dark/actions/32/help-about.svg
icons/deskflow-dark/actions/32/view-refresh.svg
+ icons/deskflow-dark/actions/32/system-search.svg
icons/deskflow-dark/apps/64/org.deskflow.deskflow.svg
icons/deskflow-dark/apps/64/org.deskflow.deskflow-symbolic.svg
icons/deskflow-dark/devices/64/video-display.svg
@@ -77,11 +89,14 @@
icons/deskflow-light/actions/16/document-edit.svg
icons/deskflow-light/actions/16/document-open.svg
icons/deskflow-light/actions/16/document-save-as.svg
+ icons/deskflow-light/actions/16/go-down.svg
+ icons/deskflow-light/actions/16/go-up.svg
icons/deskflow-light/actions/16/help-about.svg
icons/deskflow-light/actions/16/network-connect.svg
icons/deskflow-light/actions/16/network-disconnect.svg
icons/deskflow-light/actions/16/process-stop.svg
icons/deskflow-light/actions/16/system-run.svg
+ icons/deskflow-light/actions/16/system-search.svg
icons/deskflow-light/actions/16/tools-report-bug.svg
icons/deskflow-light/actions/16/view-close.svg
icons/deskflow-light/actions/16/view-refresh.svg
@@ -94,11 +109,14 @@
icons/deskflow-light/actions/22/document-open.svg
icons/deskflow-light/actions/22/document-save-as.svg
icons/deskflow-light/actions/22/fingerprint.svg
+ icons/deskflow-light/actions/22/go-down.svg
+ icons/deskflow-light/actions/22/go-up.svg
icons/deskflow-light/actions/22/network-connect.svg
icons/deskflow-light/actions/22/network-disconnect.svg
icons/deskflow-light/actions/22/help-about.svg
icons/deskflow-light/actions/22/process-stop.svg
icons/deskflow-light/actions/22/system-run.svg
+ icons/deskflow-light/actions/22/system-search.svg
icons/deskflow-light/actions/22/tools-report-bug.svg
icons/deskflow-light/actions/22/view-close.svg
icons/deskflow-light/actions/22/view-refresh.svg
@@ -111,11 +129,14 @@
icons/deskflow-light/actions/24/document-edit.svg
icons/deskflow-light/actions/24/document-open.svg
icons/deskflow-light/actions/24/document-save-as.svg
+ icons/deskflow-light/actions/24/go-down.svg
+ icons/deskflow-light/actions/24/go-up.svg
icons/deskflow-light/actions/24/help-about.svg
icons/deskflow-light/actions/24/network-connect.svg
icons/deskflow-light/actions/24/network-disconnect.svg
icons/deskflow-light/actions/24/process-stop.svg
icons/deskflow-light/actions/24/system-run.svg
+ icons/deskflow-light/actions/24/system-search.svg
icons/deskflow-light/actions/24/tools-report-bug.svg
icons/deskflow-light/actions/24/view-close.svg
icons/deskflow-light/actions/24/view-refresh.svg
@@ -128,8 +149,11 @@
icons/deskflow-light/actions/32/dialog-ok-apply.svg
icons/deskflow-light/actions/32/document-open.svg
icons/deskflow-light/actions/32/document-save-as.svg
+ icons/deskflow-light/actions/32/go-down.svg
+ icons/deskflow-light/actions/32/go-up.svg
icons/deskflow-light/actions/32/help-about.svg
icons/deskflow-light/actions/32/view-refresh.svg
+ icons/deskflow-light/actions/32/system-search.svg
icons/deskflow-light/apps/64/org.deskflow.deskflow.svg
icons/deskflow-light/apps/64/org.deskflow.deskflow-symbolic.svg
icons/deskflow-light/devices/64/video-display.svg
diff --git a/src/apps/res/icons/deskflow-dark/actions/16/go-down.svg b/src/apps/res/icons/deskflow-dark/actions/16/go-down.svg
new file mode 100644
index 000000000..27562ff16
--- /dev/null
+++ b/src/apps/res/icons/deskflow-dark/actions/16/go-down.svg
@@ -0,0 +1,5 @@
+
+
diff --git a/src/apps/res/icons/deskflow-dark/actions/16/go-up.svg b/src/apps/res/icons/deskflow-dark/actions/16/go-up.svg
new file mode 100644
index 000000000..12dafd4f4
--- /dev/null
+++ b/src/apps/res/icons/deskflow-dark/actions/16/go-up.svg
@@ -0,0 +1,5 @@
+
+
diff --git a/src/apps/res/icons/deskflow-dark/actions/16/system-search.svg b/src/apps/res/icons/deskflow-dark/actions/16/system-search.svg
new file mode 100644
index 000000000..b506f9922
--- /dev/null
+++ b/src/apps/res/icons/deskflow-dark/actions/16/system-search.svg
@@ -0,0 +1,7 @@
+
+
diff --git a/src/apps/res/icons/deskflow-dark/actions/22/go-down.svg b/src/apps/res/icons/deskflow-dark/actions/22/go-down.svg
new file mode 100644
index 000000000..2d6f605c0
--- /dev/null
+++ b/src/apps/res/icons/deskflow-dark/actions/22/go-down.svg
@@ -0,0 +1,7 @@
+
+
diff --git a/src/apps/res/icons/deskflow-dark/actions/22/go-up.svg b/src/apps/res/icons/deskflow-dark/actions/22/go-up.svg
new file mode 100644
index 000000000..5426f099a
--- /dev/null
+++ b/src/apps/res/icons/deskflow-dark/actions/22/go-up.svg
@@ -0,0 +1,5 @@
+
+
diff --git a/src/apps/res/icons/deskflow-dark/actions/22/system-search.svg b/src/apps/res/icons/deskflow-dark/actions/22/system-search.svg
new file mode 100644
index 000000000..33d165de9
--- /dev/null
+++ b/src/apps/res/icons/deskflow-dark/actions/22/system-search.svg
@@ -0,0 +1,7 @@
+
+
diff --git a/src/apps/res/icons/deskflow-dark/actions/24/go-down.svg b/src/apps/res/icons/deskflow-dark/actions/24/go-down.svg
new file mode 100644
index 000000000..e3e315cf0
--- /dev/null
+++ b/src/apps/res/icons/deskflow-dark/actions/24/go-down.svg
@@ -0,0 +1,9 @@
+
+
diff --git a/src/apps/res/icons/deskflow-dark/actions/24/go-up.svg b/src/apps/res/icons/deskflow-dark/actions/24/go-up.svg
new file mode 100644
index 000000000..2d62ad000
--- /dev/null
+++ b/src/apps/res/icons/deskflow-dark/actions/24/go-up.svg
@@ -0,0 +1,7 @@
+
+
diff --git a/src/apps/res/icons/deskflow-dark/actions/24/system-search.svg b/src/apps/res/icons/deskflow-dark/actions/24/system-search.svg
new file mode 100644
index 000000000..11428d1c2
--- /dev/null
+++ b/src/apps/res/icons/deskflow-dark/actions/24/system-search.svg
@@ -0,0 +1,9 @@
+
+
diff --git a/src/apps/res/icons/deskflow-dark/actions/32/go-down.svg b/src/apps/res/icons/deskflow-dark/actions/32/go-down.svg
new file mode 100644
index 000000000..e92a9e54b
--- /dev/null
+++ b/src/apps/res/icons/deskflow-dark/actions/32/go-down.svg
@@ -0,0 +1,5 @@
+
+
diff --git a/src/apps/res/icons/deskflow-dark/actions/32/go-up.svg b/src/apps/res/icons/deskflow-dark/actions/32/go-up.svg
new file mode 100644
index 000000000..e7fef713c
--- /dev/null
+++ b/src/apps/res/icons/deskflow-dark/actions/32/go-up.svg
@@ -0,0 +1,5 @@
+
+
diff --git a/src/apps/res/icons/deskflow-dark/actions/32/system-search.svg b/src/apps/res/icons/deskflow-dark/actions/32/system-search.svg
new file mode 100644
index 000000000..6f1385b84
--- /dev/null
+++ b/src/apps/res/icons/deskflow-dark/actions/32/system-search.svg
@@ -0,0 +1,8 @@
+
+
diff --git a/src/apps/res/icons/deskflow-light/actions/16/go-down.svg b/src/apps/res/icons/deskflow-light/actions/16/go-down.svg
new file mode 100644
index 000000000..1a159aaa8
--- /dev/null
+++ b/src/apps/res/icons/deskflow-light/actions/16/go-down.svg
@@ -0,0 +1,10 @@
+
diff --git a/src/apps/res/icons/deskflow-light/actions/16/go-up.svg b/src/apps/res/icons/deskflow-light/actions/16/go-up.svg
new file mode 100644
index 000000000..31950bea6
--- /dev/null
+++ b/src/apps/res/icons/deskflow-light/actions/16/go-up.svg
@@ -0,0 +1,10 @@
+
diff --git a/src/apps/res/icons/deskflow-light/actions/16/system-search.svg b/src/apps/res/icons/deskflow-light/actions/16/system-search.svg
new file mode 100644
index 000000000..92646c0c1
--- /dev/null
+++ b/src/apps/res/icons/deskflow-light/actions/16/system-search.svg
@@ -0,0 +1,13 @@
+
diff --git a/src/apps/res/icons/deskflow-light/actions/22/go-down.svg b/src/apps/res/icons/deskflow-light/actions/22/go-down.svg
new file mode 100644
index 000000000..bebae569b
--- /dev/null
+++ b/src/apps/res/icons/deskflow-light/actions/22/go-down.svg
@@ -0,0 +1,14 @@
+
diff --git a/src/apps/res/icons/deskflow-light/actions/22/go-up.svg b/src/apps/res/icons/deskflow-light/actions/22/go-up.svg
new file mode 100644
index 000000000..21f77e91b
--- /dev/null
+++ b/src/apps/res/icons/deskflow-light/actions/22/go-up.svg
@@ -0,0 +1,10 @@
+
diff --git a/src/apps/res/icons/deskflow-light/actions/22/system-search.svg b/src/apps/res/icons/deskflow-light/actions/22/system-search.svg
new file mode 100644
index 000000000..c46b0c7c3
--- /dev/null
+++ b/src/apps/res/icons/deskflow-light/actions/22/system-search.svg
@@ -0,0 +1,14 @@
+
diff --git a/src/apps/res/icons/deskflow-light/actions/24/go-down.svg b/src/apps/res/icons/deskflow-light/actions/24/go-down.svg
new file mode 100644
index 000000000..06abd4508
--- /dev/null
+++ b/src/apps/res/icons/deskflow-light/actions/24/go-down.svg
@@ -0,0 +1,12 @@
+
diff --git a/src/apps/res/icons/deskflow-light/actions/24/go-up.svg b/src/apps/res/icons/deskflow-light/actions/24/go-up.svg
new file mode 100644
index 000000000..ed26f6b0f
--- /dev/null
+++ b/src/apps/res/icons/deskflow-light/actions/24/go-up.svg
@@ -0,0 +1,10 @@
+
diff --git a/src/apps/res/icons/deskflow-light/actions/24/system-search.svg b/src/apps/res/icons/deskflow-light/actions/24/system-search.svg
new file mode 100644
index 000000000..7a16405ca
--- /dev/null
+++ b/src/apps/res/icons/deskflow-light/actions/24/system-search.svg
@@ -0,0 +1,12 @@
+
diff --git a/src/apps/res/icons/deskflow-light/actions/32/go-down.svg b/src/apps/res/icons/deskflow-light/actions/32/go-down.svg
new file mode 100644
index 000000000..839120539
--- /dev/null
+++ b/src/apps/res/icons/deskflow-light/actions/32/go-down.svg
@@ -0,0 +1,10 @@
+
diff --git a/src/apps/res/icons/deskflow-light/actions/32/go-up.svg b/src/apps/res/icons/deskflow-light/actions/32/go-up.svg
new file mode 100644
index 000000000..68d5c0357
--- /dev/null
+++ b/src/apps/res/icons/deskflow-light/actions/32/go-up.svg
@@ -0,0 +1,10 @@
+
diff --git a/src/apps/res/icons/deskflow-light/actions/32/system-search.svg b/src/apps/res/icons/deskflow-light/actions/32/system-search.svg
new file mode 100644
index 000000000..daed5fda7
--- /dev/null
+++ b/src/apps/res/icons/deskflow-light/actions/32/system-search.svg
@@ -0,0 +1,12 @@
+
+
diff --git a/src/lib/gui/CMakeLists.txt b/src/lib/gui/CMakeLists.txt
index 070c163a0..bc78360a5 100644
--- a/src/lib/gui/CMakeLists.txt
+++ b/src/lib/gui/CMakeLists.txt
@@ -116,6 +116,8 @@ add_library(${target} STATIC
widgets/NewScreenWidget.h
widgets/ScreenSetupView.cpp
widgets/ScreenSetupView.h
+ widgets/SearchWidget.h
+ widgets/SearchWidget.cpp
widgets/TrashScreenWidget.cpp
widgets/TrashScreenWidget.h
)
diff --git a/src/lib/gui/widgets/LogDock.cpp b/src/lib/gui/widgets/LogDock.cpp
index beac5a0db..0a1570ba3 100644
--- a/src/lib/gui/widgets/LogDock.cpp
+++ b/src/lib/gui/widgets/LogDock.cpp
@@ -1,11 +1,12 @@
/*
* Deskflow -- mouse and keyboard sharing utility
- * SPDX-FileCopyrightText: (C) 2025 Chris Rizzitello
+ * SPDX-FileCopyrightText: (C) 2025 - 2026 Chris Rizzitello
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
*/
#include "LogDock.h"
#include "LogWidget.h"
+#include "SearchWidget.h"
#include
#include
@@ -18,8 +19,12 @@ LogDock::LogDock(QWidget *parent)
m_textLog{new LogWidget(this)},
m_btnClose{new QPushButton(this)},
m_btnFloat{new QPushButton(this)},
- m_lblTitle{new QLabel(tr("Log"), this)}
+ m_lblTitle{new QLabel(tr("Log"), this)},
+ m_searchWidget{new SearchWidget(this)}
{
+ connect(m_searchWidget, &SearchWidget::findNext, m_textLog, &LogWidget::findNext);
+ connect(m_searchWidget, &SearchWidget::findPrevious, m_textLog, &LogWidget::findPrevious);
+
const auto iconSize = QSize(fontMetrics().height() - 2, fontMetrics().height() - 2);
const auto maxBtnSize = QSize(fontMetrics().height() + 2, fontMetrics().height() + 2);
@@ -44,6 +49,7 @@ LogDock::LogDock(QWidget *parent)
auto titleLayout = new QHBoxLayout(titleWidget);
titleLayout->addWidget(m_lblTitle, Qt::AlignLeft | Qt::AlignVCenter);
titleLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Fixed));
+ titleLayout->addWidget(m_searchWidget, Qt::AlignRight | Qt::AlignVCenter);
titleLayout->addWidget(m_btnFloat, Qt::AlignRight | Qt::AlignVCenter);
titleLayout->addWidget(m_btnClose, Qt::AlignRight | Qt::AlignVCenter);
setTitleBarWidget(titleWidget);
diff --git a/src/lib/gui/widgets/LogDock.h b/src/lib/gui/widgets/LogDock.h
index afd6b9527..b8ed69e3d 100644
--- a/src/lib/gui/widgets/LogDock.h
+++ b/src/lib/gui/widgets/LogDock.h
@@ -1,6 +1,6 @@
/*
* Deskflow -- mouse and keyboard sharing utility
- * SPDX-FileCopyrightText: (C) 2025 Chris Rizzitello
+ * SPDX-FileCopyrightText: (C) 2025 - 2026 Chris Rizzitello
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
*/
@@ -11,6 +11,7 @@
class LogWidget;
class QLabel;
class QPushButton;
+class SearchWidget;
class LogDock : public QDockWidget
{
@@ -29,4 +30,5 @@ private:
QPushButton *m_btnClose = nullptr;
QPushButton *m_btnFloat = nullptr;
QLabel *m_lblTitle = nullptr;
+ SearchWidget *m_searchWidget = nullptr;
};
diff --git a/src/lib/gui/widgets/LogWidget.cpp b/src/lib/gui/widgets/LogWidget.cpp
index a197a3204..9e19ad958 100644
--- a/src/lib/gui/widgets/LogWidget.cpp
+++ b/src/lib/gui/widgets/LogWidget.cpp
@@ -1,6 +1,6 @@
/*
* Deskflow -- mouse and keyboard sharing utility
- * SPDX-FileCopyrightText: (C) 2025 Chris Rizzitello
+ * SPDX-FileCopyrightText: (C) 2025 - 2026 Chris Rizzitello
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
*/
@@ -41,3 +41,25 @@ void LogWidget::appendLine(const QString &msg)
{
m_textLog->appendPlainText(msg);
}
+
+void LogWidget::findNext(const QString &text)
+{
+ if (text.isEmpty())
+ return;
+
+ if (!m_textLog->find(text)) {
+ m_textLog->moveCursor(QTextCursor::Start);
+ m_textLog->find(text);
+ }
+}
+
+void LogWidget::findPrevious(const QString &text)
+{
+ if (text.isEmpty())
+ return;
+
+ if (!m_textLog->find(text, QTextDocument::FindBackward)) {
+ m_textLog->moveCursor(QTextCursor::End);
+ m_textLog->find(text, QTextDocument::FindBackward);
+ }
+}
diff --git a/src/lib/gui/widgets/LogWidget.h b/src/lib/gui/widgets/LogWidget.h
index e94ca4bef..63db7c0c7 100644
--- a/src/lib/gui/widgets/LogWidget.h
+++ b/src/lib/gui/widgets/LogWidget.h
@@ -1,6 +1,6 @@
/*
* Deskflow -- mouse and keyboard sharing utility
- * SPDX-FileCopyrightText: (C) 2025 Chris Rizzitello
+ * SPDX-FileCopyrightText: (C) 2025 - 2026 Chris Rizzitello
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
*/
@@ -18,6 +18,8 @@ class LogWidget : public QWidget
public:
explicit LogWidget(QWidget *parent = nullptr);
void appendLine(const QString &msg);
+ void findNext(const QString &text);
+ void findPrevious(const QString &text);
private:
QPlainTextEdit *m_textLog = nullptr;
diff --git a/src/lib/gui/widgets/SearchWidget.cpp b/src/lib/gui/widgets/SearchWidget.cpp
new file mode 100644
index 000000000..4425acd2e
--- /dev/null
+++ b/src/lib/gui/widgets/SearchWidget.cpp
@@ -0,0 +1,93 @@
+/*
+ * Deskflow -- mouse and keyboard sharing utility
+ * SPDX-FileCopyrightText: (C) 2026 Chris Rizzitello
+ * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
+ */
+
+#include "SearchWidget.h"
+
+#include
+#include
+#include
+#include
+
+SearchWidget::SearchWidget(QWidget *parent)
+ : QWidget{parent},
+ m_btnToggle{new QPushButton(this)},
+ m_btnNext{new QPushButton(this)},
+ m_btnPrev{new QPushButton(this)},
+ m_searchLine{new QLineEdit(this)}
+{
+ setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
+
+ const auto iconSize = QSize(fontMetrics().height() - 2, fontMetrics().height() - 2);
+ const auto maxBtnSize = QSize(fontMetrics().height() + 2, fontMetrics().height() + 2);
+
+ m_btnToggle->setFixedSize(maxBtnSize);
+ m_btnToggle->setCheckable(true);
+ m_btnToggle->setChecked(false);
+ m_btnToggle->setFlat(true);
+ m_btnToggle->setIcon(QIcon::fromTheme(QIcon::ThemeIcon::SystemSearch));
+ m_btnToggle->setIconSize(iconSize);
+
+ m_btnNext->setFixedSize(maxBtnSize);
+ m_btnNext->setFlat(true);
+ m_btnNext->setIcon(QIcon::fromTheme(QIcon::ThemeIcon::GoDown));
+ m_btnNext->setIconSize(iconSize);
+
+ m_btnPrev->setFixedSize(maxBtnSize);
+ m_btnPrev->setFlat(true);
+ m_btnPrev->setIcon(QIcon::fromTheme(QIcon::ThemeIcon::GoUp));
+ m_btnPrev->setIconSize(iconSize);
+
+ m_searchLine->setMaximumHeight(maxBtnSize.height());
+
+ connect(m_btnToggle, &QPushButton::toggled, this, &SearchWidget::toggleVisible);
+ connect(m_btnNext, &QPushButton::clicked, this, &SearchWidget::next);
+ connect(m_btnPrev, &QPushButton::clicked, this, &SearchWidget::previous);
+ connect(m_searchLine, &QLineEdit::editingFinished, this, &SearchWidget::next);
+
+ setText();
+
+ auto mainLayout = new QHBoxLayout;
+ mainLayout->addWidget(m_btnToggle);
+ mainLayout->addWidget(m_searchLine);
+ mainLayout->addWidget(m_btnNext);
+ mainLayout->addWidget(m_btnPrev);
+
+ setLayout(mainLayout);
+ toggleVisible();
+ adjustSize();
+}
+
+void SearchWidget::changeEvent(QEvent *e)
+{
+ QWidget::changeEvent(e);
+ if (e->type() == QEvent::LanguageChange)
+ setText();
+}
+
+void SearchWidget::toggleVisible(bool visible)
+{
+ m_searchLine->setVisible(visible);
+ m_btnNext->setVisible(visible);
+ m_btnPrev->setVisible(visible);
+}
+
+void SearchWidget::setText()
+{
+ m_btnToggle->setToolTip(tr("Search"));
+ m_btnNext->setToolTip(tr("Find next"));
+ m_btnPrev->setToolTip(tr("Find previous"));
+ m_searchLine->setPlaceholderText(tr("Find..."));
+}
+
+void SearchWidget::next()
+{
+ Q_EMIT findNext(m_searchLine->text());
+}
+
+void SearchWidget::previous()
+{
+ Q_EMIT findPrevious(m_searchLine->text());
+}
diff --git a/src/lib/gui/widgets/SearchWidget.h b/src/lib/gui/widgets/SearchWidget.h
new file mode 100644
index 000000000..d0263562f
--- /dev/null
+++ b/src/lib/gui/widgets/SearchWidget.h
@@ -0,0 +1,36 @@
+/*
+ * Deskflow -- mouse and keyboard sharing utility
+ * SPDX-FileCopyrightText: (C) 2026 Chris Rizzitello
+ * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
+ */
+
+#pragma once
+
+#include
+
+class QPushButton;
+class QLineEdit;
+
+class SearchWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit SearchWidget(QWidget *parent = nullptr);
+
+Q_SIGNALS:
+ void findNext(const QString &text);
+ void findPrevious(const QString &text);
+
+protected:
+ void changeEvent(QEvent *e) override;
+
+private:
+ void toggleVisible(bool visible = false);
+ void setText();
+ void next();
+ void previous();
+ QPushButton *m_btnToggle = nullptr;
+ QPushButton *m_btnNext = nullptr;
+ QPushButton *m_btnPrev = nullptr;
+ QLineEdit *m_searchLine = nullptr;
+};
diff --git a/translations/deskflow_es.ts b/translations/deskflow_es.ts
index 14a53d035..ac62f8e75 100644
--- a/translations/deskflow_es.ts
+++ b/translations/deskflow_es.ts
@@ -883,6 +883,25 @@ Nombres válidos:
<center>Pantalla: <b>%1</b></center><br>Haga doble clic para editar la configuración<br>Arrastre la pantalla a la papelera para eliminarla
+
+ SearchWidget
+
+ Search
+ Buscar
+
+
+ Find next
+ Buscar siguiente
+
+
+ Find previous
+ Buscar anterior
+
+
+ Find...
+ Buscar...
+
+
ServerConfigDialog
diff --git a/translations/deskflow_it.ts b/translations/deskflow_it.ts
index 1c5ba2255..1f0641c63 100644
--- a/translations/deskflow_it.ts
+++ b/translations/deskflow_it.ts
@@ -883,6 +883,25 @@ Nomi validi:
<center>Schermo: <b>%1</b></center><br>Fai doppio clic per modificare le impostazioni<br>Trascina lo schermo nel cestino per rimuoverlo
+
+ SearchWidget
+
+ Search
+ Ricerca
+
+
+ Find next
+ Trova successivo
+
+
+ Find previous
+ Trova precedente
+
+
+ Find...
+ Trova...
+
+
ServerConfigDialog
diff --git a/translations/deskflow_ja.ts b/translations/deskflow_ja.ts
index 8a0a6f2cd..f8dcc2cb7 100644
--- a/translations/deskflow_ja.ts
+++ b/translations/deskflow_ja.ts
@@ -884,6 +884,25 @@ Valid names:
<center>コンピューター: <b>%1</b></center><br>ダブルクリックで設定<br>ゴミ箱にドラッグして削除
+
+ SearchWidget
+
+ Search
+ 検索
+
+
+ Find next
+ 次を検索
+
+
+ Find previous
+ 前を検索
+
+
+ Find...
+ 検索...
+
+
ServerConfigDialog
diff --git a/translations/deskflow_ru.ts b/translations/deskflow_ru.ts
index dd630031f..a5b55c7dd 100644
--- a/translations/deskflow_ru.ts
+++ b/translations/deskflow_ru.ts
@@ -881,6 +881,25 @@ Valid names:
<center>Экран: <b>%1</b></center><br>Двойной клик для настроек<br>Перетащите экран в корзину для удаления
+
+ SearchWidget
+
+ Search
+ Поиск
+
+
+ Find next
+ Найти следующее
+
+
+ Find previous
+ Найти предыдущее
+
+
+ Find...
+ Поиск...
+
+
ServerConfigDialog
diff --git a/translations/deskflow_zh_CN.ts b/translations/deskflow_zh_CN.ts
index 7e03d6123..e330d7353 100644
--- a/translations/deskflow_zh_CN.ts
+++ b/translations/deskflow_zh_CN.ts
@@ -884,6 +884,25 @@ Valid names:
<center>屏幕:<b>%1</b></center><br>双击编辑设置<br>将屏幕拖到垃圾桶以移除
+
+ SearchWidget
+
+ Search
+ 搜索
+
+
+ Find next
+ 查找下一个
+
+
+ Find previous
+ 查找上一个
+
+
+ Find...
+ 寻找...
+
+
ServerConfigDialog