From de42f53d68cfdb3d5fe9399061bd7d82e13d79ad Mon Sep 17 00:00:00 2001 From: sithlord48 Date: Wed, 3 Sep 2025 23:22:58 -0400 Subject: [PATCH] refactor: new LogDock, handle hiding and float correctly' --- src/apps/res/deskflow.qrc | 18 ++++ .../deskflow-dark/actions/16/view-close.svg | 8 ++ .../actions/16/window-minimize-pip.svg | 8 ++ .../actions/16/window-restore-pip.svg | 8 ++ .../deskflow-dark/actions/22/view-close.svg | 8 ++ .../actions/22/window-minimize-pip.svg | 8 ++ .../actions/22/window-restore-pip.svg | 8 ++ .../deskflow-dark/actions/24/view-close.svg | 9 ++ .../actions/24/window-minimize-pip.svg | 9 ++ .../actions/24/window-restore-pip.svg | 9 ++ .../deskflow-light/actions/16/view-close.svg | 21 +++++ .../actions/16/window-minimize-pip.svg | 9 ++ .../actions/16/window-restore-pip.svg | 9 ++ .../deskflow-light/actions/22/view-close.svg | 21 +++++ .../actions/22/window-minimize-pip.svg | 9 ++ .../actions/22/window-restore-pip.svg | 9 ++ .../deskflow-light/actions/24/view-close.svg | 16 ++++ .../actions/24/window-minimize-pip.svg | 11 +++ .../actions/24/window-restore-pip.svg | 11 +++ src/lib/gui/CMakeLists.txt | 2 + src/lib/gui/MainWindow.cpp | 35 +++++--- src/lib/gui/MainWindow.h | 4 +- src/lib/gui/MainWindow.ui | 23 ----- src/lib/gui/widgets/LogDock.cpp | 85 +++++++++++++++++++ src/lib/gui/widgets/LogDock.h | 31 +++++++ 25 files changed, 350 insertions(+), 39 deletions(-) create mode 100644 src/apps/res/icons/deskflow-dark/actions/16/view-close.svg create mode 100644 src/apps/res/icons/deskflow-dark/actions/16/window-minimize-pip.svg create mode 100644 src/apps/res/icons/deskflow-dark/actions/16/window-restore-pip.svg create mode 100644 src/apps/res/icons/deskflow-dark/actions/22/view-close.svg create mode 100644 src/apps/res/icons/deskflow-dark/actions/22/window-minimize-pip.svg create mode 100644 src/apps/res/icons/deskflow-dark/actions/22/window-restore-pip.svg create mode 100644 src/apps/res/icons/deskflow-dark/actions/24/view-close.svg create mode 100644 src/apps/res/icons/deskflow-dark/actions/24/window-minimize-pip.svg create mode 100644 src/apps/res/icons/deskflow-dark/actions/24/window-restore-pip.svg create mode 100644 src/apps/res/icons/deskflow-light/actions/16/view-close.svg create mode 100644 src/apps/res/icons/deskflow-light/actions/16/window-minimize-pip.svg create mode 100644 src/apps/res/icons/deskflow-light/actions/16/window-restore-pip.svg create mode 100644 src/apps/res/icons/deskflow-light/actions/22/view-close.svg create mode 100644 src/apps/res/icons/deskflow-light/actions/22/window-minimize-pip.svg create mode 100644 src/apps/res/icons/deskflow-light/actions/22/window-restore-pip.svg create mode 100644 src/apps/res/icons/deskflow-light/actions/24/view-close.svg create mode 100644 src/apps/res/icons/deskflow-light/actions/24/window-minimize-pip.svg create mode 100644 src/apps/res/icons/deskflow-light/actions/24/window-restore-pip.svg create mode 100644 src/lib/gui/widgets/LogDock.cpp create mode 100644 src/lib/gui/widgets/LogDock.h diff --git a/src/apps/res/deskflow.qrc b/src/apps/res/deskflow.qrc index b013d52f1..c81ec246d 100644 --- a/src/apps/res/deskflow.qrc +++ b/src/apps/res/deskflow.qrc @@ -11,7 +11,10 @@ icons/deskflow-dark/actions/16/process-stop.svg icons/deskflow-dark/actions/16/system-run.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 + icons/deskflow-dark/actions/16/window-minimize-pip.svg + icons/deskflow-dark/actions/16/window-restore-pip.svg icons/deskflow-dark/actions/22/configure.svg icons/deskflow-dark/actions/22/edit-copy.svg icons/deskflow-dark/actions/22/document-edit.svg @@ -24,7 +27,10 @@ icons/deskflow-dark/actions/22/process-stop.svg icons/deskflow-dark/actions/22/system-run.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 + icons/deskflow-dark/actions/22/window-minimize-pip.svg + icons/deskflow-dark/actions/22/window-restore-pip.svg icons/deskflow-dark/actions/24/configure.svg icons/deskflow-dark/actions/24/edit-copy.svg icons/deskflow-dark/actions/24/document-edit.svg @@ -38,7 +44,10 @@ icons/deskflow-dark/actions/24/process-stop.svg icons/deskflow-dark/actions/24/system-run.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 + icons/deskflow-dark/actions/24/window-minimize-pip.svg + icons/deskflow-dark/actions/24/window-restore-pip.svg icons/deskflow-dark/actions/32/configure.svg icons/deskflow-dark/actions/32/application-exit.svg icons/deskflow-dark/actions/32/dialog-cancel.svg @@ -74,7 +83,10 @@ icons/deskflow-light/actions/16/process-stop.svg icons/deskflow-light/actions/16/system-run.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 + icons/deskflow-light/actions/16/window-minimize-pip.svg + icons/deskflow-light/actions/16/window-restore-pip.svg icons/deskflow-light/actions/22/configure.svg icons/deskflow-light/actions/22/edit-clear-all.svg icons/deskflow-light/actions/22/edit-copy.svg @@ -88,7 +100,10 @@ icons/deskflow-light/actions/22/process-stop.svg icons/deskflow-light/actions/22/system-run.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 + icons/deskflow-light/actions/22/window-minimize-pip.svg + icons/deskflow-light/actions/22/window-restore-pip.svg icons/deskflow-light/actions/24/configure.svg icons/deskflow-light/actions/24/edit-clear-all.svg icons/deskflow-light/actions/24/edit-copy.svg @@ -102,7 +117,10 @@ icons/deskflow-light/actions/24/process-stop.svg icons/deskflow-light/actions/24/system-run.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 + icons/deskflow-light/actions/24/window-minimize-pip.svg + icons/deskflow-light/actions/24/window-restore-pip.svg icons/deskflow-light/actions/32/configure.svg icons/deskflow-light/actions/32/application-exit.svg icons/deskflow-light/actions/32/dialog-cancel.svg diff --git a/src/apps/res/icons/deskflow-dark/actions/16/view-close.svg b/src/apps/res/icons/deskflow-dark/actions/16/view-close.svg new file mode 100644 index 000000000..85fc1a802 --- /dev/null +++ b/src/apps/res/icons/deskflow-dark/actions/16/view-close.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/apps/res/icons/deskflow-dark/actions/16/window-minimize-pip.svg b/src/apps/res/icons/deskflow-dark/actions/16/window-minimize-pip.svg new file mode 100644 index 000000000..c0806971a --- /dev/null +++ b/src/apps/res/icons/deskflow-dark/actions/16/window-minimize-pip.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/apps/res/icons/deskflow-dark/actions/16/window-restore-pip.svg b/src/apps/res/icons/deskflow-dark/actions/16/window-restore-pip.svg new file mode 100644 index 000000000..737fa4916 --- /dev/null +++ b/src/apps/res/icons/deskflow-dark/actions/16/window-restore-pip.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/apps/res/icons/deskflow-dark/actions/22/view-close.svg b/src/apps/res/icons/deskflow-dark/actions/22/view-close.svg new file mode 100644 index 000000000..79787ec99 --- /dev/null +++ b/src/apps/res/icons/deskflow-dark/actions/22/view-close.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/apps/res/icons/deskflow-dark/actions/22/window-minimize-pip.svg b/src/apps/res/icons/deskflow-dark/actions/22/window-minimize-pip.svg new file mode 100644 index 000000000..47940038f --- /dev/null +++ b/src/apps/res/icons/deskflow-dark/actions/22/window-minimize-pip.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/apps/res/icons/deskflow-dark/actions/22/window-restore-pip.svg b/src/apps/res/icons/deskflow-dark/actions/22/window-restore-pip.svg new file mode 100644 index 000000000..967a3cfa6 --- /dev/null +++ b/src/apps/res/icons/deskflow-dark/actions/22/window-restore-pip.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/apps/res/icons/deskflow-dark/actions/24/view-close.svg b/src/apps/res/icons/deskflow-dark/actions/24/view-close.svg new file mode 100644 index 000000000..ce152e0b8 --- /dev/null +++ b/src/apps/res/icons/deskflow-dark/actions/24/view-close.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/apps/res/icons/deskflow-dark/actions/24/window-minimize-pip.svg b/src/apps/res/icons/deskflow-dark/actions/24/window-minimize-pip.svg new file mode 100644 index 000000000..5f8abd67d --- /dev/null +++ b/src/apps/res/icons/deskflow-dark/actions/24/window-minimize-pip.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/apps/res/icons/deskflow-dark/actions/24/window-restore-pip.svg b/src/apps/res/icons/deskflow-dark/actions/24/window-restore-pip.svg new file mode 100644 index 000000000..01933edf6 --- /dev/null +++ b/src/apps/res/icons/deskflow-dark/actions/24/window-restore-pip.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/apps/res/icons/deskflow-light/actions/16/view-close.svg b/src/apps/res/icons/deskflow-light/actions/16/view-close.svg new file mode 100644 index 000000000..96b3c53bb --- /dev/null +++ b/src/apps/res/icons/deskflow-light/actions/16/view-close.svg @@ -0,0 +1,21 @@ + + + + + + + diff --git a/src/apps/res/icons/deskflow-light/actions/16/window-minimize-pip.svg b/src/apps/res/icons/deskflow-light/actions/16/window-minimize-pip.svg new file mode 100644 index 000000000..b55f8fe6b --- /dev/null +++ b/src/apps/res/icons/deskflow-light/actions/16/window-minimize-pip.svg @@ -0,0 +1,9 @@ + + + + + + + diff --git a/src/apps/res/icons/deskflow-light/actions/16/window-restore-pip.svg b/src/apps/res/icons/deskflow-light/actions/16/window-restore-pip.svg new file mode 100644 index 000000000..f458f0728 --- /dev/null +++ b/src/apps/res/icons/deskflow-light/actions/16/window-restore-pip.svg @@ -0,0 +1,9 @@ + + + + + + + diff --git a/src/apps/res/icons/deskflow-light/actions/22/view-close.svg b/src/apps/res/icons/deskflow-light/actions/22/view-close.svg new file mode 100644 index 000000000..f543cdffe --- /dev/null +++ b/src/apps/res/icons/deskflow-light/actions/22/view-close.svg @@ -0,0 +1,21 @@ + + + + + + + diff --git a/src/apps/res/icons/deskflow-light/actions/22/window-minimize-pip.svg b/src/apps/res/icons/deskflow-light/actions/22/window-minimize-pip.svg new file mode 100644 index 000000000..ebe604512 --- /dev/null +++ b/src/apps/res/icons/deskflow-light/actions/22/window-minimize-pip.svg @@ -0,0 +1,9 @@ + + + + + + + diff --git a/src/apps/res/icons/deskflow-light/actions/22/window-restore-pip.svg b/src/apps/res/icons/deskflow-light/actions/22/window-restore-pip.svg new file mode 100644 index 000000000..6377c2057 --- /dev/null +++ b/src/apps/res/icons/deskflow-light/actions/22/window-restore-pip.svg @@ -0,0 +1,9 @@ + + + + + + + diff --git a/src/apps/res/icons/deskflow-light/actions/24/view-close.svg b/src/apps/res/icons/deskflow-light/actions/24/view-close.svg new file mode 100644 index 000000000..91ef19982 --- /dev/null +++ b/src/apps/res/icons/deskflow-light/actions/24/view-close.svg @@ -0,0 +1,16 @@ + + + + + + + + + diff --git a/src/apps/res/icons/deskflow-light/actions/24/window-minimize-pip.svg b/src/apps/res/icons/deskflow-light/actions/24/window-minimize-pip.svg new file mode 100644 index 000000000..8196d5dca --- /dev/null +++ b/src/apps/res/icons/deskflow-light/actions/24/window-minimize-pip.svg @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/src/apps/res/icons/deskflow-light/actions/24/window-restore-pip.svg b/src/apps/res/icons/deskflow-light/actions/24/window-restore-pip.svg new file mode 100644 index 000000000..7766a6154 --- /dev/null +++ b/src/apps/res/icons/deskflow-light/actions/24/window-restore-pip.svg @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/src/lib/gui/CMakeLists.txt b/src/lib/gui/CMakeLists.txt index f5c86ad34..1aabcda25 100644 --- a/src/lib/gui/CMakeLists.txt +++ b/src/lib/gui/CMakeLists.txt @@ -114,6 +114,8 @@ add_library(${target} STATIC widgets/FingerprintPreview.h widgets/KeySequenceWidget.cpp widgets/KeySequenceWidget.h + widgets/LogDock.cpp + widgets/LogDock.h widgets/LogWidget.h widgets/LogWidget.cpp widgets/NewScreenWidget.cpp diff --git a/src/lib/gui/MainWindow.cpp b/src/lib/gui/MainWindow.cpp index 093d0b202..8116b4a6d 100644 --- a/src/lib/gui/MainWindow.cpp +++ b/src/lib/gui/MainWindow.cpp @@ -25,7 +25,7 @@ #include "gui/Styles.h" #include "gui/core/CoreProcess.h" #include "gui/ipc/DaemonIpcClient.h" -#include "gui/widgets/LogWidget.h" +#include "gui/widgets/LogDock.h" #include "net/FingerprintDatabase.h" #include "platform/Wayland.h" @@ -71,7 +71,7 @@ MainWindow::MainWindow() m_trayIcon{new QSystemTrayIcon(this)}, m_guiDupeChecker{new QLocalServer(this)}, m_daemonIpcClient{new ipc::DaemonIpcClient(this)}, - m_logWidget{new LogWidget(this)}, + m_logDock{new LogDock(this)}, m_lblSecurityStatus{new QLabel(this)}, m_lblStatus{new QLabel(this)}, m_btnFingerprint{new QToolButton(this)}, @@ -92,9 +92,7 @@ MainWindow::MainWindow() setWindowIcon(QIcon::fromTheme(QStringLiteral("deskflow"))); - auto dockLayout = new QVBoxLayout(); - dockLayout->addWidget(m_logWidget); - ui->dockLogContents->setLayout(dockLayout); + addDockWidget(Qt::BottomDockWidgetArea, m_logDock); // Setup Actions m_actionAbout->setText(tr("About %1...").arg(kAppName)); @@ -211,7 +209,7 @@ void MainWindow::setupControls() } if (!Settings::value(Settings::Gui::LogExpanded).toBool()) { - ui->dockLog->hide(); + m_logDock->hide(); } ui->serverOptions->setVisible(false); @@ -327,7 +325,7 @@ void MainWindow::connectSlots() connect(ui->rbModeServer, &QRadioButton::toggled, this, &MainWindow::coreModeToggled); connect(ui->rbModeClient, &QRadioButton::toggled, this, &MainWindow::coreModeToggled); - connect(ui->dockLog->toggleViewAction(), &QAction::toggled, this, &MainWindow::toggleLogVisible); + connect(m_logDock->toggleViewAction(), &QAction::toggled, this, &MainWindow::toggleLogVisible); connect(m_btnUpdate, &QPushButton::clicked, this, &MainWindow::openGetNewVersionUrl); @@ -350,11 +348,20 @@ void MainWindow::toggleLogVisible(bool visible) setFixedSize(16777215, 16777215); Settings::setValue(Settings::Gui::LogExpanded, visible); if (visible) { - setGeometry(x(), y(), m_expandedSize.width(), m_expandedSize.height()); + if (m_logDock->isFloating()) { + adjustSize(); + setFixedSize(size()); + } else { + QTimer::singleShot(15, this, [&] { resize(m_expandedSize); }); + } } else { - m_expandedSize = geometry().size(); - ui->dockLog->hide(); - adjustSize(); + if (!m_logDock->isFloating()) { + m_expandedSize = geometry().size(); + } + m_logDock->hide(); + if (!m_logDock->isFloating()) { + adjustSize(); + } setFixedSize(size()); } Settings::setValue(Settings::Gui::WindowGeometry, geometry()); @@ -705,7 +712,7 @@ void MainWindow::createMenuBar() menuEdit->addAction(m_actionSettings); auto menuView = new QMenu(tr("&View"), this); - menuView->addAction(ui->dockLog->toggleViewAction()); + menuView->addAction(m_logDock->toggleViewAction()); auto menuHelp = new QMenu(tr("&Help"), this); menuHelp->addAction(m_actionAbout); @@ -785,7 +792,7 @@ void MainWindow::setIcon() void MainWindow::handleLogLine(const QString &line) { - m_logWidget->appendLine(line); + m_logDock->appendLine(line); updateFromLogLine(line); } @@ -882,7 +889,7 @@ void MainWindow::closeEvent(QCloseEvent *event) // any connected dock view acitons will be triggered // disconnect them before accepting the event - disconnect(ui->dockLog->toggleViewAction(), &QAction::toggled, nullptr, nullptr); + disconnect(m_logDock->toggleViewAction(), &QAction::toggled, nullptr, nullptr); event->accept(); QApplication::quit(); diff --git a/src/lib/gui/MainWindow.h b/src/lib/gui/MainWindow.h index bb3fcf57b..79fbcf2d4 100644 --- a/src/lib/gui/MainWindow.h +++ b/src/lib/gui/MainWindow.h @@ -46,7 +46,7 @@ class QAbstractButton; class QLocalServer; class DeskflowApplication; -class LogWidget; +class LogDock; namespace Ui { class MainWindow; @@ -185,7 +185,7 @@ private: QLocalServer *m_guiDupeChecker = nullptr; deskflow::gui::ipc::DaemonIpcClient *m_daemonIpcClient = nullptr; - LogWidget *m_logWidget = nullptr; + LogDock *m_logDock; QLabel *m_lblSecurityStatus = nullptr; QLabel *m_lblStatus = nullptr; QToolButton *m_btnFingerprint = nullptr; diff --git a/src/lib/gui/MainWindow.ui b/src/lib/gui/MainWindow.ui index 4c75ca3d0..485868fe6 100644 --- a/src/lib/gui/MainWindow.ui +++ b/src/lib/gui/MainWindow.ui @@ -2,14 +2,6 @@ MainWindow - - - 0 - 0 - 758 - 305 - - Deskflow @@ -468,21 +460,6 @@ - - - QDockWidget::DockWidgetFeature::DockWidgetClosable - - - Qt::DockWidgetArea::BottomDockWidgetArea - - - Log - - - 8 - - - diff --git a/src/lib/gui/widgets/LogDock.cpp b/src/lib/gui/widgets/LogDock.cpp new file mode 100644 index 000000000..82c978f7d --- /dev/null +++ b/src/lib/gui/widgets/LogDock.cpp @@ -0,0 +1,85 @@ +/* + * Deskflow -- mouse and keyboard sharing utility + * SPDX-FileCopyrightText: (C) 2025 Chris Rizzitello + * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception + */ + +#include "LogDock.h" +#include "LogWidget.h" +#include "gui/Styles.h" + +#include +#include +#include +#include +#include + +LogDock::LogDock(QWidget *parent) + : QDockWidget(tr("Log"), parent), + m_textLog{new LogWidget(this)}, + m_btnClose{new QToolButton(this)}, + m_btnFloat{new QToolButton(this)}, + m_lblTitle{new QLabel(tr("Log"), this)} +{ + const auto iconSize = QSize(fontMetrics().height() - 2, fontMetrics().height() - 2); + + m_btnFloat->setStyleSheet(deskflow::gui::kStyleFlatButtonHoverable); + m_btnFloat->setCheckable(true); + m_btnFloat->setIcon(QIcon::fromTheme(QStringLiteral("window-minimize-pip"))); + m_btnFloat->setIconSize(iconSize); + m_btnFloat->setToolTip(tr("Detach from window")); + connect(m_btnFloat, &QToolButton::toggled, this, &LogDock::setFloating); + + m_btnClose->setStyleSheet(deskflow::gui::kStyleFlatButtonHoverable); + m_btnClose->setIcon(QIcon::fromTheme(QStringLiteral("view-close"))); + m_btnClose->setIconSize(iconSize); + m_btnClose->setToolTip(tr("Close Log")); + connect(m_btnClose, &QToolButton::clicked, this, &QDockWidget::hide); + + auto titleWidget = new QWidget(this); + titleWidget->installEventFilter(this); + + 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_btnFloat, Qt::AlignRight | Qt::AlignVCenter); + titleLayout->addWidget(m_btnClose, Qt::AlignRight | Qt::AlignVCenter); + setTitleBarWidget(titleWidget); + + auto bodyWidget = new QWidget(this); + auto bodyLayout = new QVBoxLayout(bodyWidget); + bodyLayout->addWidget(m_textLog); + setWidget(bodyWidget); + + setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetFloatable); + setAllowedAreas(Qt::BottomDockWidgetArea); +} + +void LogDock::appendLine(const QString &msg) +{ + m_textLog->appendLine(msg); +} + +void LogDock::setFloating(bool floating) +{ + if (floating) { + m_btnFloat->setToolTip(tr("Attach to window")); + m_btnFloat->setIcon(QIcon::fromTheme(QStringLiteral("window-restore-pip"))); + setWindowFlags(Qt::Dialog); + } else { + m_btnFloat->setToolTip(tr("Detach from window")); + m_btnFloat->setIcon(QIcon::fromTheme(QStringLiteral("window-minimize-pip"))); + setWindowFlags(Qt::Widget); + } + m_lblTitle->setVisible(!floating); + m_btnClose->setVisible(!floating); + show(); +} + +bool LogDock::eventFilter(QObject *watched, QEvent *event) +{ + // Filter out doubleclick on the titlebar, we only want the dock to float if the user users the button on the dock + if (watched == titleBarWidget() && event->type() == QEvent::MouseButtonDblClick) + return true; + return false; +} diff --git a/src/lib/gui/widgets/LogDock.h b/src/lib/gui/widgets/LogDock.h new file mode 100644 index 000000000..2d952bc74 --- /dev/null +++ b/src/lib/gui/widgets/LogDock.h @@ -0,0 +1,31 @@ +/* + * Deskflow -- mouse and keyboard sharing utility + * SPDX-FileCopyrightText: (C) 2025 Chris Rizzitello + * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception + */ + +#pragma once + +#include + +class LogWidget; +class QLabel; +class QToolButton; + +class LogDock : public QDockWidget +{ + Q_OBJECT +public: + explicit LogDock(QWidget *parent = nullptr); + void appendLine(const QString &msg); + void setFloating(bool floating); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + +private: + LogWidget *m_textLog = nullptr; + QToolButton *m_btnClose = nullptr; + QToolButton *m_btnFloat = nullptr; + QLabel *m_lblTitle = nullptr; +};