From 5bc48be5d05a65dcc550529deb507ea37914abaa Mon Sep 17 00:00:00 2001 From: Le Tan Date: Fri, 15 Oct 2021 20:55:09 +0800 Subject: [PATCH] introduce FramelessMainWindow --- src/core/notebook/notebooktagmgr.cpp | 4 + src/data/core/icons/scan_import.svg | 2 +- .../framelessmainwindow.cpp | 47 ++++ .../framelessmainwindow/framelessmainwindow.h | 47 ++++ .../framelessmainwindowimpl.h | 15 ++ .../framelessmainwindowwin.cpp | 217 ++++++++++++++++++ .../framelessmainwindowwin.h | 41 ++++ src/widgets/mainwindow.cpp | 19 +- src/widgets/mainwindow.h | 5 +- src/widgets/tagexplorer.cpp | 4 +- src/widgets/titletoolbar.cpp | 48 ---- src/widgets/titletoolbar.h | 17 +- src/widgets/toolbarhelper.cpp | 8 - src/widgets/widgets.pri | 5 + 14 files changed, 390 insertions(+), 89 deletions(-) create mode 100644 src/widgets/framelessmainwindow/framelessmainwindow.cpp create mode 100644 src/widgets/framelessmainwindow/framelessmainwindow.h create mode 100644 src/widgets/framelessmainwindow/framelessmainwindowimpl.h create mode 100644 src/widgets/framelessmainwindow/framelessmainwindowwin.cpp create mode 100644 src/widgets/framelessmainwindow/framelessmainwindowwin.h diff --git a/src/core/notebook/notebooktagmgr.cpp b/src/core/notebook/notebooktagmgr.cpp index 30232e85..617a0a7c 100644 --- a/src/core/notebook/notebooktagmgr.cpp +++ b/src/core/notebook/notebooktagmgr.cpp @@ -21,6 +21,10 @@ QVector NotebookTagMgr::stringToTagGraph(const QSt QVector tagGraph; auto pairs = p_text.split(QLatin1Char(';')); for (const auto &pa : pairs) { + if (pa.isEmpty()) { + continue; + } + auto paCh = pa.split(QLatin1Char('>')); if (paCh.size() != 2 || paCh[0].isEmpty() || paCh[1].isEmpty()) { qWarning() << "ignore invalid tag pair" << pa; diff --git a/src/data/core/icons/scan_import.svg b/src/data/core/icons/scan_import.svg index 7d38bbc1..67775537 100644 --- a/src/data/core/icons/scan_import.svg +++ b/src/data/core/icons/scan_import.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/widgets/framelessmainwindow/framelessmainwindow.cpp b/src/widgets/framelessmainwindow/framelessmainwindow.cpp new file mode 100644 index 00000000..b1d07dd0 --- /dev/null +++ b/src/widgets/framelessmainwindow/framelessmainwindow.cpp @@ -0,0 +1,47 @@ +#include "framelessmainwindow.h" + +#include + +using namespace vnotex; + +FramelessMainWindow::FramelessMainWindow(bool p_frameless, QWidget *p_parent) + : QMainWindow(p_parent), + m_frameless(p_frameless), + m_defaultFlags(windowFlags()) +{ + if (m_frameless) { + m_resizeAreaWidth *= devicePixelRatio(); + + setWindowFlags(m_defaultFlags | Qt::FramelessWindowHint); + } +} + + +bool FramelessMainWindow::isFrameless() const +{ + return m_frameless; +} + +void FramelessMainWindow::setTitleBar(QWidget *p_titleBar) +{ + Q_ASSERT(!m_titleBar && m_frameless); + + m_titleBar = p_titleBar; + m_titleBar->installEventFilter(this); +} + +void FramelessMainWindow::changeEvent(QEvent *p_event) +{ + QMainWindow::changeEvent(p_event); + + if (p_event->type() == QEvent::WindowStateChange) { + m_windowStates = windowState(); + m_resizable = m_movable = m_windowStates == Qt::WindowNoState; + emit windowStateChanged(m_windowStates); + } +} + +bool FramelessMainWindow::isMaximized() const +{ + return (m_windowStates & Qt::WindowMaximized) && !(m_windowStates & Qt::WindowFullScreen); +} diff --git a/src/widgets/framelessmainwindow/framelessmainwindow.h b/src/widgets/framelessmainwindow/framelessmainwindow.h new file mode 100644 index 00000000..0a8ad5e4 --- /dev/null +++ b/src/widgets/framelessmainwindow/framelessmainwindow.h @@ -0,0 +1,47 @@ +#ifndef FRAMELESSMAINWINDOW_H +#define FRAMELESSMAINWINDOW_H + +#include +#include + +class QTimer; + +namespace vnotex +{ + // Base class. Use FramelessMainWindowImpl instead. + class FramelessMainWindow : public QMainWindow + { + Q_OBJECT + public: + FramelessMainWindow(bool p_frameless, QWidget *p_parent); + + bool isFrameless() const; + + void setTitleBar(QWidget *p_titleBar); + + signals: + void windowStateChanged(Qt::WindowStates p_state); + + protected: + void changeEvent(QEvent *p_event) Q_DECL_OVERRIDE; + + protected: + bool isMaximized() const; + + const bool m_frameless = true; + + int m_resizeAreaWidth = 5; + + bool m_movable = true; + + bool m_resizable = true; + + const Qt::WindowFlags m_defaultFlags; + + QWidget *m_titleBar = nullptr; + + Qt::WindowStates m_windowStates = Qt::WindowNoState; + }; +} + +#endif // FRAMELESSMAINWINDOW_H diff --git a/src/widgets/framelessmainwindow/framelessmainwindowimpl.h b/src/widgets/framelessmainwindow/framelessmainwindowimpl.h new file mode 100644 index 00000000..93ad51b7 --- /dev/null +++ b/src/widgets/framelessmainwindow/framelessmainwindowimpl.h @@ -0,0 +1,15 @@ +#ifndef FRAMELESSMAINWINDOWIMPL_H +#define FRAMELESSMAINWINDOWIMPL_H + +#include "framelessmainwindowwin.h" + +namespace vnotex +{ +#ifdef Q_OS_WIN + typedef FramelessMainWindowWin FramelessMainWindowImpl; +#else + typedef FramelessMainWindow FramelessMainWindowImpl; +#endif +} + +#endif // FRAMELESSMAINWINDOWIMPL_H diff --git a/src/widgets/framelessmainwindow/framelessmainwindowwin.cpp b/src/widgets/framelessmainwindow/framelessmainwindowwin.cpp new file mode 100644 index 00000000..8236c346 --- /dev/null +++ b/src/widgets/framelessmainwindow/framelessmainwindowwin.cpp @@ -0,0 +1,217 @@ +#include "framelessmainwindowwin.h" + +#ifdef Q_OS_WIN + +#include +#include +#include + +#include +#include +#include +#pragma comment (lib,"dwmapi.lib") +#pragma comment (lib, "user32.lib") + +using namespace vnotex; + +FramelessMainWindowWin::FramelessMainWindowWin(bool p_frameless, QWidget *p_parent) + : FramelessMainWindow(p_frameless, p_parent) +{ + if (m_frameless) { + m_redrawTimer = new QTimer(this); + m_redrawTimer->setSingleShot(true); + m_redrawTimer->setInterval(500); + connect(m_redrawTimer, &QTimer::timeout, + this, &FramelessMainWindowWin::forceRedraw); + + connect(this, &FramelessMainWindow::windowStateChanged, + this, &FramelessMainWindowWin::updateMargins); + + // Enable some window effects on Win, such as snap and maximizing. + // It will activate the title bar again. Need to remove it in WM_NCCALCSIZE msg. + HWND hwnd = reinterpret_cast(winId()); + DWORD style = ::GetWindowLong(hwnd, GWL_STYLE); + ::SetWindowLong(hwnd, GWL_STYLE, style | WS_MAXIMIZEBOX | WS_THICKFRAME | WS_CAPTION); + + // Leave 1 pixel width of border so OS will draw a window shadow. + const MARGINS shadow = {1, 1, 1, 1}; + DwmExtendFrameIntoClientArea(hwnd, &shadow); + } +} + +#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0)) +bool FramelessMainWindowWin::nativeEvent(const QByteArray &p_eventType, void *p_message, qintptr *p_result) +#else +bool FramelessMainWindowWin::nativeEvent(const QByteArray &p_eventType, void *p_message, long *p_result) +#endif +{ + if (!m_frameless) { + return FramelessMainWindow::nativeEvent(p_eventType, p_message, p_result); + } + + if (p_eventType == QStringLiteral("windows_generic_MSG")) { + MSG *msg = static_cast(p_message); + + switch (msg->message) { + case WM_NCCALCSIZE: + *p_result = 0; + return true; + + case WM_NCHITTEST: + { + if (m_windowStates & Qt::WindowFullScreen) { + *p_result = HTCLIENT; + return true; + } + + RECT windowRect; + ::GetWindowRect(msg->hwnd, &windowRect); + + // x and y could not be compared with width() and height() in hidpi case. + int x = static_cast(GET_X_LPARAM(msg->lParam) - windowRect.left); + int y = static_cast(GET_Y_LPARAM(msg->lParam) - windowRect.top); + + bool onLeft = x < m_resizeAreaWidth; + bool onRight = x > windowRect.right - windowRect.left - m_resizeAreaWidth; + bool onTop = y < m_resizeAreaWidth; + bool onBottom = y > windowRect.bottom - windowRect.top - m_resizeAreaWidth; + + *p_result = 0; + if (m_resizable) { + if (onLeft && onTop) { + *p_result = HTTOPLEFT; + } else if (onLeft && onBottom) { + *p_result = HTBOTTOMLEFT; + } else if (onRight && onTop) { + *p_result = HTTOPRIGHT; + } else if (onRight && onBottom) { + *p_result = HTBOTTOMRIGHT; + } else if (onLeft) { + *p_result = HTLEFT; + } else if (onRight) { + *p_result = HTRIGHT; + } else if (onTop) { + *p_result = HTTOP; + } else if (onBottom) { + *p_result = HTBOTTOM; + } + } + + if (0 != *p_result) { + return true; + } + + if (m_titleBar) { + if (m_titleBarHeight == 0) { + m_titleBarHeight = m_titleBar->height() * devicePixelRatio(); + } + + if (y < m_titleBarHeight) { + QWidget *child = m_titleBar->childAt(m_titleBar->mapFromGlobal(QCursor::pos())); + if (!child) { + *p_result = HTCAPTION; + if (::GetAsyncKeyState(VK_LBUTTON) < 0 || ::GetAsyncKeyState(VK_RBUTTON) < 0) { + m_sizeBeforeMove = size(); + } + return true; + } + } + } + + break; + } + + case WM_POWERBROADCAST: + { + if (msg->wParam == PBT_APMSUSPEND) { + // Minimize when system is going to sleep to avoid bugs. + showMinimized(); + } + break; + } + + case WM_GETMINMAXINFO: + { + // When maximized, OS will expand the content area. To avoid missing the real contents, set extra margins. + if (::IsZoomed(msg->hwnd)) { + RECT frame = {0, 0, 0, 0}; + ::AdjustWindowRectEx(&frame, WS_OVERLAPPEDWINDOW, false, 0); + const int dpiScale = devicePixelRatio(); + m_maximizedMargins.setLeft(qAbs(frame.left) / dpiScale); + // Use bottom as top. + m_maximizedMargins.setTop(qAbs(frame.bottom) / dpiScale); + m_maximizedMargins.setRight(frame.right / dpiScale); + m_maximizedMargins.setBottom(frame.bottom / dpiScale); + } + break; + } + + default: + if (msg->wParam == PBT_APMRESUMESUSPEND) { + // Show after resuming from sleep. + showNormal(); + } + break; + } + } + + return FramelessMainWindow::nativeEvent(p_eventType, p_message, p_result); +} + +void FramelessMainWindowWin::moveEvent(QMoveEvent *p_event) +{ + FramelessMainWindow::moveEvent(p_event); + + if (m_frameless) { + if (m_windowStates & Qt::WindowMaximized) { + m_redrawTimer->stop(); + } else { + m_redrawTimer->start(); + } + } +} + +void FramelessMainWindowWin::updateMargins() +{ + if (!m_frameless) { + return; + } + + int topMargin = 0; + if (isMaximized()) { + setContentsMargins(m_maximizedMargins); + topMargin = m_maximizedMargins.top(); + } else { + setContentsMargins(0, 0, 0, 0); + } + + if (m_titleBar) { + m_titleBarHeight = (m_titleBar->height() + topMargin) * devicePixelRatio(); + } +} + +void FramelessMainWindowWin::forceRedraw() +{ + Q_ASSERT(m_frameless); + if (m_windowStates & Qt::WindowMaximized) { + return; + } + + const QSize sz = size(); + RECT frame; + ::GetWindowRect((HWND)winId(), &frame); + const int clientWidth = (frame.right - frame.left) / devicePixelRatio(); + const int clientHeight = (frame.bottom - frame.top) / devicePixelRatio(); + if (clientWidth != sz.width() || clientHeight != sz.height()) { + // resize() may result to "unable to set geometry" warning. + // adjustsize() or resize() to another size before could solve this. + resize(sz.width() + 1, sz.height() + 1); + if (m_sizeBeforeMove.isEmpty()) { + resize(clientWidth, clientHeight); + } else { + resize(m_sizeBeforeMove); + } + } +} + +#endif diff --git a/src/widgets/framelessmainwindow/framelessmainwindowwin.h b/src/widgets/framelessmainwindow/framelessmainwindowwin.h new file mode 100644 index 00000000..d4f04e80 --- /dev/null +++ b/src/widgets/framelessmainwindow/framelessmainwindowwin.h @@ -0,0 +1,41 @@ +#ifndef FRAMELESSMAINWINDOWWIN_H +#define FRAMELESSMAINWINDOWWIN_H + +#include "framelessmainwindow.h" + +namespace vnotex +{ +#ifdef Q_OS_WIN + class FramelessMainWindowWin : public FramelessMainWindow + { + Q_OBJECT + public: + FramelessMainWindowWin(bool p_frameless = true, QWidget *p_parent = nullptr); + + protected: +#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0)) + bool nativeEvent(const QByteArray &p_eventType, void *p_message, qintptr *p_result); +#else + bool nativeEvent(const QByteArray &p_eventType, void *p_message, long *p_result); +#endif + + void moveEvent(QMoveEvent *p_event) Q_DECL_OVERRIDE; + + private: + // To fix some unkonwn bugs of the interface. + void forceRedraw(); + + void updateMargins(); + + QTimer *m_redrawTimer = nullptr; + + QSize m_sizeBeforeMove; + + QMargins m_maximizedMargins; + + int m_titleBarHeight = 0; + }; +#endif +} + +#endif // FRAMELESSMAINWINDOWWIN_H diff --git a/src/widgets/mainwindow.cpp b/src/widgets/mainwindow.cpp index dd0dc329..8eff33a9 100644 --- a/src/widgets/mainwindow.cpp +++ b/src/widgets/mainwindow.cpp @@ -58,7 +58,7 @@ using namespace vnotex; MainWindow::MainWindow(QWidget *p_parent) - : QMainWindow(p_parent), + : FramelessMainWindowImpl(!ConfigMgr::getInst().getSessionConfig().getSystemTitleBarEnabled(), p_parent), m_toolBarHelper(this), m_statusBarHelper(this), m_dockWidgetHelper(this) @@ -393,7 +393,7 @@ void MainWindow::closeEvent(QCloseEvent *p_event) m_trayIcon->hide(); - QMainWindow::closeEvent(p_event); + FramelessMainWindowImpl::closeEvent(p_event); qApp->exit(exitCode > -1 ? exitCode : 0); } else { hide(); @@ -521,16 +521,8 @@ void MainWindow::setupToolBar() { const int sz = ConfigMgr::getInst().getCoreConfig().getToolBarIconSize(); const QSize iconSize(sz, sz); - if (!ConfigMgr::getInst().getSessionConfig().getSystemTitleBarEnabled()) { - // Use unified tool bar as title bar. - auto framelessFlags = Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint - | Qt::WindowCloseButtonHint | Qt::WindowFullscreenButtonHint; - - auto winFlags = windowFlags(); - winFlags |= Qt::CustomizeWindowHint | Qt::FramelessWindowHint; - winFlags &= ~framelessFlags; - setWindowFlags(winFlags); + if (isFrameless()) { auto toolBar = new TitleToolBar(tr("Global"), this); toolBar->setIconSize(iconSize); m_toolBarHelper.setupToolBars(toolBar); @@ -538,6 +530,9 @@ void MainWindow::setupToolBar() ToolBarHelper::generateIcon(QStringLiteral("maximize.svg")), ToolBarHelper::generateIcon(QStringLiteral("maximize_restore.svg")), ToolBarHelper::generateDangerousIcon(QStringLiteral("close.svg"))); + setTitleBar(toolBar); + connect(this, &FramelessMainWindowImpl::windowStateChanged, + toolBar, &TitleToolBar::updateMaximizeAct); } else { auto toolBar = new QToolBar(tr("Global"), this); toolBar->setIconSize(iconSize); @@ -594,7 +589,7 @@ void MainWindow::changeEvent(QEvent *p_event) m_windowOldState = eve->oldState(); } - QMainWindow::changeEvent(p_event); + FramelessMainWindowImpl::changeEvent(p_event); } void MainWindow::showMainWindow() diff --git a/src/widgets/mainwindow.h b/src/widgets/mainwindow.h index e951f6bd..bcceea63 100644 --- a/src/widgets/mainwindow.h +++ b/src/widgets/mainwindow.h @@ -1,7 +1,8 @@ #ifndef MAINWINDOW_H #define MAINWINDOW_H -#include +#include "framelessmainwindow/framelessmainwindowimpl.h" + #include #include #include @@ -30,7 +31,7 @@ namespace vnotex enum { RESTART_EXIT_CODE = 1000 }; - class MainWindow : public QMainWindow + class MainWindow : public FramelessMainWindowImpl { Q_OBJECT public: diff --git a/src/widgets/tagexplorer.cpp b/src/widgets/tagexplorer.cpp index fea13cc1..91549ca8 100644 --- a/src/widgets/tagexplorer.cpp +++ b/src/widgets/tagexplorer.cpp @@ -106,9 +106,9 @@ void TagExplorer::setupTagTree(QWidget *p_parent) TreeWidget::showHorizontalScrollbar(m_tagTree); m_tagTree->setDragDropMode(QAbstractItemView::InternalMove); connect(m_tagTree, &QTreeWidget::currentItemChanged, - timer, QOverload::of(&QTimer::start)); + timer, QOverload<>::of(&QTimer::start)); connect(m_tagTree, &QTreeWidget::itemClicked, - timer, QOverload::of(&QTimer::start)); + timer, QOverload<>::of(&QTimer::start)); connect(m_tagTree, &QTreeWidget::customContextMenuRequested, this, &TagExplorer::handleTagTreeContextMenuRequested); connect(m_tagTree, &TreeWidget::itemMoved, diff --git a/src/widgets/titletoolbar.cpp b/src/widgets/titletoolbar.cpp index d15e7a6a..45315451 100644 --- a/src/widgets/titletoolbar.cpp +++ b/src/widgets/titletoolbar.cpp @@ -1,8 +1,5 @@ #include "titletoolbar.h" -#include -#include -#include #include #include "propertydefs.h" @@ -14,7 +11,6 @@ TitleToolBar::TitleToolBar(QWidget *p_parent) m_window(p_parent) { setupUI(); - m_window->installEventFilter(this); } TitleToolBar::TitleToolBar(const QString &p_title, QWidget *p_parent) @@ -22,51 +18,17 @@ TitleToolBar::TitleToolBar(const QString &p_title, QWidget *p_parent) m_window(p_parent) { setupUI(); - m_window->installEventFilter(this); } void TitleToolBar::setupUI() { } -void TitleToolBar::mousePressEvent(QMouseEvent *p_event) -{ - QToolBar::mousePressEvent(p_event); - m_lastPos = p_event->pos(); -} - -void TitleToolBar::mouseDoubleClickEvent(QMouseEvent *p_event) -{ - QToolBar::mouseDoubleClickEvent(p_event); - m_ignoreNextMove = true; - maximizeRestoreWindow(); -} - void TitleToolBar::maximizeRestoreWindow() { m_window->isMaximized() ? m_window->showNormal() : m_window->showMaximized(); } -void TitleToolBar::mouseMoveEvent(QMouseEvent *p_event) -{ - auto delta = p_event->pos() - m_lastPos; - if (!m_ignoreNextMove && !m_lastPos.isNull() && (qAbs(delta.x()) > 10 || qAbs(delta.y()) > 10)) { - if (m_window->isMaximized()) { - m_window->showNormal(); - } else { - m_window->move(p_event->globalPos() - m_lastPos); - } - } - QToolBar::mouseMoveEvent(p_event); -} - -void TitleToolBar::mouseReleaseEvent(QMouseEvent *p_event) -{ - QToolBar::mouseReleaseEvent(p_event); - m_ignoreNextMove = false; - m_lastPos = QPoint(); -} - void TitleToolBar::addTitleBarIcons(const QIcon &p_minimizeIcon, const QIcon &p_maximizeIcon, const QIcon &p_restoreIcon, @@ -98,16 +60,6 @@ void TitleToolBar::addTitleBarIcons(const QIcon &p_minimizeIcon, updateMaximizeAct(); } -bool TitleToolBar::eventFilter(QObject *p_obj, QEvent *p_event) -{ - if (p_obj == m_window) { - if (p_event->type() == QEvent::WindowStateChange) { - updateMaximizeAct(); - } - } - return QToolBar::eventFilter(p_obj, p_event); -} - void TitleToolBar::updateMaximizeAct() { if (m_window->isMaximized()) { diff --git a/src/widgets/titletoolbar.h b/src/widgets/titletoolbar.h index f1c1d73d..b4231614 100644 --- a/src/widgets/titletoolbar.h +++ b/src/widgets/titletoolbar.h @@ -19,28 +19,13 @@ namespace vnotex const QIcon &p_restoreIcon, const QIcon &p_closeIcon); - protected: - void mousePressEvent(QMouseEvent *p_event) Q_DECL_OVERRIDE; - - void mouseReleaseEvent(QMouseEvent *p_event) Q_DECL_OVERRIDE; - - void mouseMoveEvent(QMouseEvent *p_event) Q_DECL_OVERRIDE; - - void mouseDoubleClickEvent(QMouseEvent *p_event) Q_DECL_OVERRIDE; - - bool eventFilter(QObject *p_obj, QEvent *p_event) Q_DECL_OVERRIDE; + void updateMaximizeAct(); private: void setupUI(); void maximizeRestoreWindow(); - void updateMaximizeAct(); - - QPoint m_lastPos; - - bool m_ignoreNextMove = false; - QWidget *m_window = nullptr; QAction *m_maximizeAct = nullptr; diff --git a/src/widgets/toolbarhelper.cpp b/src/widgets/toolbarhelper.cpp index f4b12fc0..efff237c 100644 --- a/src/widgets/toolbarhelper.cpp +++ b/src/widgets/toolbarhelper.cpp @@ -167,8 +167,6 @@ QToolBar *ToolBarHelper::setupFileToolBar(MainWindow *p_win, QToolBar *p_toolBar auto act = tb->addAction(generateIcon("import_menu.svg"), MainWindow::tr("Import")); auto btn = dynamic_cast(tb->widgetForAction(act)); - Q_ASSERT(btn); - btn->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); btn->setPopupMode(QToolButton::InstantPopup); btn->setProperty(PropertyDefs::c_toolButtonWithoutMenuIndicator, true); @@ -200,12 +198,6 @@ QToolBar *ToolBarHelper::setupFileToolBar(MainWindow *p_win, QToolBar *p_toolBar WidgetUtils::addActionShortcut(exportAct, coreConfig.getShortcut(CoreConfig::Shortcut::Export)); - - // To hide the shortcut text shown in button. - auto toolBtn = dynamic_cast(tb->widgetForAction(exportAct)); - Q_ASSERT(toolBtn); - toolBtn->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - toolBtn->setText(MainWindow::tr("Export")); } return tb; diff --git a/src/widgets/widgets.pri b/src/widgets/widgets.pri index ecb61cde..7f60c4fb 100644 --- a/src/widgets/widgets.pri +++ b/src/widgets/widgets.pri @@ -58,6 +58,8 @@ SOURCES += \ $$PWD/dialogs/folderfilesfilterwidget.cpp \ $$PWD/findandreplacewidget.cpp \ $$PWD/floatingwidget.cpp \ + $$PWD/framelessmainwindow/framelessmainwindow.cpp \ + $$PWD/framelessmainwindow/framelessmainwindowwin.cpp \ $$PWD/fullscreentoggleaction.cpp \ $$PWD/historypanel.cpp \ $$PWD/itemproxystyle.cpp \ @@ -181,6 +183,9 @@ HEADERS += \ $$PWD/dialogs/folderfilesfilterwidget.h \ $$PWD/findandreplacewidget.h \ $$PWD/floatingwidget.h \ + $$PWD/framelessmainwindow/framelessmainwindow.h \ + $$PWD/framelessmainwindow/framelessmainwindowimpl.h \ + $$PWD/framelessmainwindow/framelessmainwindowwin.h \ $$PWD/fullscreentoggleaction.h \ $$PWD/historypanel.h \ $$PWD/itemproxystyle.h \