Compare commits

...
4 Commits
Author SHA1 Message Date
yyc12345 6fde9474ae revert: remove stay-on-top feature 2026-07-03 14:26:27 +08:00
yyc12345 c19fcaa560 revert: remove close window animation 2026-07-03 14:26:22 +08:00
yyc12345 602e2cccf8 revert: remove redundant close button 2026-07-03 14:26:16 +08:00
yyc12345 3c1a3c54a7 revert: restore system default window instead of custom one.
custom window is not the goal of this project.
we remove it and use system default window instead.
2026-07-03 14:26:09 +08:00
10 changed files with 1 additions and 242 deletions
-2
View File
@@ -62,7 +62,6 @@ void ActionManager::setupAction(MainWindow *mainWindow)
CREATE_NEW_ACTION(mainWindow, actionCopyFilePath);
CREATE_NEW_THEMEICON_ACTION(mainWindow, actionPaste, edit-paste);
CREATE_NEW_THEMEICON_ACTION(mainWindow, actionTrash, edit-delete);
CREATE_NEW_ACTION(mainWindow, actionToggleStayOnTop);
CREATE_NEW_ACTION(mainWindow, actionToggleProtectMode);
CREATE_NEW_ACTION(mainWindow, actionToggleAvoidResetTransform);
CREATE_NEW_ACTION(mainWindow, actionSettings);
@@ -105,7 +104,6 @@ void ActionManager::retranslateUi(MainWindow *mainWindow)
actionCopyFilePath->setText(QCoreApplication::translate("MainWindow", "Copy &File Path", nullptr));
actionPaste->setText(QCoreApplication::translate("MainWindow", "&Paste", nullptr));
actionTrash->setText(QCoreApplication::translate("MainWindow", "Move to Trash", nullptr));
actionToggleStayOnTop->setText(QCoreApplication::translate("MainWindow", "Stay on top", nullptr));
actionToggleProtectMode->setText(QCoreApplication::translate("MainWindow", "Protected mode", nullptr));
actionToggleAvoidResetTransform->setText(QCoreApplication::translate("MainWindow", "Keep transformation", "The 'transformation' means the flip/rotation status that currently applied to the image view"));
actionSettings->setText(QCoreApplication::translate("MainWindow", "Configure...", nullptr));
-1
View File
@@ -45,7 +45,6 @@ public:
QAction *actionCopyFilePath;
QAction *actionPaste;
QAction *actionTrash;
QAction *actionToggleStayOnTop;
QAction *actionToggleProtectMode;
QAction *actionToggleAvoidResetTransform;
QAction *actionSettings;
+1 -129
View File
@@ -11,32 +11,11 @@
#include <QVBoxLayout>
#include <QWindow>
#ifdef Q_OS_WIN
#include "windows.h"
void fixWindowStyle(QWidget * that)
{
HWND hwnd = (HWND)that->winId();
LONG style = GetWindowLong(hwnd, GWL_STYLE);
style |= WS_THICKFRAME | WS_CAPTION | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SYSMENU;
SetWindowLong(hwnd, GWL_STYLE, style);
SetWindowPos(hwnd, nullptr, 0, 0, 0, 0,
SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE |
SWP_NOZORDER | SWP_NOACTIVATE);
}
#endif
FramelessWindow::FramelessWindow(QWidget *parent)
: QWidget(parent)
, m_centralLayout(new QVBoxLayout(this))
, m_oldCursorShape(Qt::ArrowCursor)
, m_oldEdges()
{
this->setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowMinMaxButtonsHint);
this->setMouseTracking(true);
this->setAttribute(Qt::WA_Hover, true);
this->installEventFilter(this);
this->setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint);
m_centralLayout->setContentsMargins(QMargins());
}
@@ -51,110 +30,3 @@ void FramelessWindow::setCentralWidget(QWidget *widget)
m_centralLayout->addWidget(widget);
m_centralWidget = widget;
}
void FramelessWindow::installResizeCapture(QObject* widget)
{
widget->installEventFilter(this);
}
void FramelessWindow::showEvent(QShowEvent *event)
{
#ifdef Q_OS_WIN
fixWindowStyle(this);
#endif // Q_OS_WIN
return QWidget::showEvent(event);
}
bool FramelessWindow::eventFilter(QObject* o, QEvent* e)
{
switch (e->type()) {
case QEvent::HoverMove:
{
QWidget* wg = qobject_cast<QWidget*>(o);
if (wg != nullptr)
return mouseHover(static_cast<QHoverEvent*>(e), wg);
break;
}
case QEvent::MouseButtonPress:
return mousePress(static_cast<QMouseEvent*>(e));
}
return QWidget::eventFilter(o, e);
}
bool FramelessWindow::mouseHover(QHoverEvent* event, QWidget* wg)
{
if (!isMaximized() && !isFullScreen()) {
QWindow* win = window()->windowHandle();
Qt::Edges edges = this->getEdgesByPos(wg->mapToGlobal(event->oldPos()), win->frameGeometry());
// backup & restore cursor shape
if (edges && !m_oldEdges)
// entering the edge. backup cursor shape
m_oldCursorShape = win->cursor().shape();
if (!edges && m_oldEdges)
// leaving the edge. restore cursor shape
win->setCursor(m_oldCursorShape);
// save the latest edges status
m_oldEdges = edges;
// show resize cursor shape if cursor is within border
if (edges) {
win->setCursor(this->getCursorByEdge(edges, Qt::ArrowCursor));
return true;
}
}
return false;
}
bool FramelessWindow::mousePress(QMouseEvent* event)
{
if (event->buttons() & Qt::LeftButton && !isMaximized() && !isFullScreen()) {
QWindow* win = window()->windowHandle();
Qt::Edges edges = this->getEdgesByPos(event->globalPosition().toPoint(), win->frameGeometry());
if (edges) {
win->startSystemResize(edges);
return true;
}
}
return false;
}
Qt::CursorShape FramelessWindow::getCursorByEdge(const Qt::Edges& edges, Qt::CursorShape default_cursor)
{
if ((edges == (Qt::TopEdge | Qt::LeftEdge)) || (edges == (Qt::RightEdge | Qt::BottomEdge)))
return Qt::SizeFDiagCursor;
else if ((edges == (Qt::TopEdge | Qt::RightEdge)) || (edges == (Qt::LeftEdge | Qt::BottomEdge)))
return Qt::SizeBDiagCursor;
else if (edges & (Qt::TopEdge | Qt::BottomEdge))
return Qt::SizeVerCursor;
else if (edges & (Qt::LeftEdge | Qt::RightEdge))
return Qt::SizeHorCursor;
else
return default_cursor;
}
Qt::Edges FramelessWindow::getEdgesByPos(const QPoint gpos, const QRect& winrect)
{
const int borderWidth = 8;
Qt::Edges edges;
int x = gpos.x() - winrect.x();
int y = gpos.y() - winrect.y();
if (x < borderWidth)
edges |= Qt::LeftEdge;
if (x > (winrect.width() - borderWidth))
edges |= Qt::RightEdge;
if (y < borderWidth)
edges |= Qt::TopEdge;
if (y > (winrect.height() - borderWidth))
edges |= Qt::BottomEdge;
return edges;
}
-15
View File
@@ -18,23 +18,8 @@ public:
explicit FramelessWindow(QWidget *parent = nullptr);
void setCentralWidget(QWidget * widget);
void installResizeCapture(QObject* widget);
protected slots:
void showEvent(QShowEvent *event) override;
protected:
bool eventFilter(QObject *o, QEvent *e) override;
bool mouseHover(QHoverEvent* event, QWidget* wg);
bool mousePress(QMouseEvent* event);
private:
Qt::Edges m_oldEdges;
Qt::CursorShape m_oldCursorShape;
Qt::CursorShape getCursorByEdge(const Qt::Edges& edges, Qt::CursorShape default_cursor);
Qt::Edges getEdgesByPos(const QPoint pos, const QRect& winrect);
QVBoxLayout * m_centralLayout = nullptr;
QWidget * m_centralWidget = nullptr; // just a pointer, doesn't take the ownership.
};
-67
View File
@@ -52,10 +52,6 @@ MainWindow::MainWindow(QWidget *parent)
, m_pm(new PlaylistManager(this))
, m_fileSystemWatcher(new QFileSystemWatcher(this))
{
if (Settings::instance()->stayOnTop()) {
this->setWindowFlag(Qt::WindowStaysOnTopHint);
}
this->setAttribute(Qt::WA_TranslucentBackground, true);
this->setMinimumSize(350, 330);
this->setWindowIcon(QIcon(u":/icons/app-icon.svg"_s));
@@ -64,23 +60,6 @@ MainWindow::MainWindow(QWidget *parent)
m_pm->setAutoLoadFilterSuffixes(supportedImageFormats());
m_fadeOutAnimation = new QPropertyAnimation(this, "windowOpacity"_ba);
m_fadeOutAnimation->setDuration(300);
m_fadeOutAnimation->setStartValue(1);
m_fadeOutAnimation->setEndValue(0);
m_floatUpAnimation = new QPropertyAnimation(this, "geometry"_ba);
m_floatUpAnimation->setDuration(300);
m_floatUpAnimation->setEasingCurve(QEasingCurve::OutCirc);
m_exitAnimationGroup = new QParallelAnimationGroup(this);
m_exitAnimationGroup->addAnimation(m_fadeOutAnimation);
m_exitAnimationGroup->addAnimation(m_floatUpAnimation);
connect(m_exitAnimationGroup, &QParallelAnimationGroup::finished,
#ifdef Q_OS_MAC
this, &QWidget::hide);
#else
this, &QWidget::close);
#endif
GraphicsScene * scene = new GraphicsScene(this);
m_graphicsView = new GraphicsView(this);
@@ -104,14 +83,6 @@ MainWindow::MainWindow(QWidget *parent)
connect(m_graphicsView, &GraphicsView::viewportRectChanged,
m_gv, &NavigatorView::updateMainViewportRegion);
m_closeButton = new ToolButton(true, m_graphicsView);
m_closeButton->setIconSize(QSize(32, 32));
m_closeButton->setFixedSize(QSize(50, 50));
m_closeButton->setIconResourcePath(":/icons/window-close.svg");
connect(m_closeButton, &QAbstractButton::clicked,
this, &MainWindow::closeWindow);
m_prevButton = new ToolButton(false, m_graphicsView);
m_prevButton->setIconSize(QSize(75, 75));
m_prevButton->setIconResourcePath(":/icons/go-previous.svg");
@@ -141,7 +112,6 @@ MainWindow::MainWindow(QWidget *parent)
m_bottomButtonGroup->setOpacity(0, false);
m_gv->setOpacity(0, false);
m_closeButton->setOpacity(0, false);
connect(m_pm, &PlaylistManager::totalCountChanged, this, &MainWindow::updateGalleryButtonsVisibility);
@@ -163,12 +133,6 @@ MainWindow::MainWindow(QWidget *parent)
Settings::instance()->applyUserShortcuts(this);
});
// allow some mouse events can go through these widgets for resizing window.
installResizeCapture(m_closeButton);
installResizeCapture(m_graphicsView);
installResizeCapture(m_graphicsView->viewport());
installResizeCapture(m_gv);
installResizeCapture(m_gv->viewport());
}
MainWindow::~MainWindow()
@@ -327,7 +291,6 @@ void MainWindow::enterEvent(QEnterEvent *event)
m_bottomButtonGroup->setOpacity(1);
m_gv->setOpacity(1);
m_closeButton->setOpacity(1);
m_prevButton->setOpacity(1);
m_nextButton->setOpacity(1);
@@ -339,7 +302,6 @@ void MainWindow::leaveEvent(QEvent *event)
m_bottomButtonGroup->setOpacity(0);
m_gv->setOpacity(0);
m_closeButton->setOpacity(0);
m_prevButton->setOpacity(0);
m_nextButton->setOpacity(0);
@@ -479,10 +441,6 @@ void MainWindow::contextMenuEvent(QContextMenuEvent *event)
QAction * trash = m_am->actionTrash;
QAction * stayOnTopMode = m_am->actionToggleStayOnTop;
stayOnTopMode->setCheckable(true);
stayOnTopMode->setChecked(stayOnTop());
QAction * protectedMode = m_am->actionToggleProtectMode;
protectedMode->setCheckable(true);
protectedMode->setChecked(m_protectedMode);
@@ -517,7 +475,6 @@ void MainWindow::contextMenuEvent(QContextMenuEvent *event)
menu->addAction(m_am->actionFitByWidth);
#endif // 0
menu->addSeparator();
menu->addAction(stayOnTopMode);
menu->addAction(protectedMode);
menu->addAction(avoidResetTransform);
menu->addSeparator();
@@ -596,17 +553,10 @@ void MainWindow::centerWindow()
void MainWindow::closeWindow()
{
QRect windowRect(this->geometry());
m_floatUpAnimation->setStartValue(windowRect);
m_floatUpAnimation->setEndValue(windowRect.adjusted(0, -80, 0, 0));
m_floatUpAnimation->setStartValue(QRect(this->geometry().x(), this->geometry().y(), this->geometry().width(), this->geometry().height()));
m_floatUpAnimation->setEndValue(QRect(this->geometry().x(), this->geometry().y()-80, this->geometry().width(), this->geometry().height()));
m_exitAnimationGroup->start();
}
void MainWindow::updateWidgetsPosition()
{
m_closeButton->move(width() - m_closeButton->width(), 0);
m_prevButton->move(25, (height() - m_prevButton->sizeHint().height()) / 2);
m_nextButton->move(width() - m_nextButton->sizeHint().width() - 25,
(height() - m_prevButton->sizeHint().height()) / 2);
@@ -618,26 +568,14 @@ void MainWindow::updateWidgetsPosition()
void MainWindow::toggleProtectedMode()
{
m_protectedMode = !m_protectedMode;
m_closeButton->setVisible(!m_protectedMode);
updateGalleryButtonsVisibility();
}
void MainWindow::toggleStayOnTop()
{
setWindowFlag(Qt::WindowStaysOnTopHint, !stayOnTop());
show();
}
void MainWindow::toggleAvoidResetTransform()
{
m_graphicsView->setAvoidResetTransform(!m_graphicsView->avoidResetTransform());
}
bool MainWindow::stayOnTop() const
{
return windowFlags().testFlag(Qt::WindowStaysOnTopHint);
}
bool MainWindow::canPaste() const
{
const QMimeData * clipboardData = QApplication::clipboard()->mimeData();
@@ -842,11 +780,6 @@ void MainWindow::on_actionAnimationNextFrame_triggered()
m_graphicsView->scene()->skipAnimationFrame(1);
}
void MainWindow::on_actionToggleStayOnTop_triggered()
{
toggleStayOnTop();
}
void MainWindow::on_actionToggleProtectMode_triggered()
{
toggleProtectedMode();
-7
View File
@@ -62,9 +62,7 @@ protected slots:
void closeWindow();
void updateWidgetsPosition();
void toggleProtectedMode();
void toggleStayOnTop();
void toggleAvoidResetTransform();
bool stayOnTop() const;
bool canPaste() const;
void quitAppAction(bool force = false);
void toggleFullscreen();
@@ -97,7 +95,6 @@ private slots:
void on_actionCopyFilePath_triggered();
void on_actionPaste_triggered();
void on_actionTrash_triggered();
void on_actionToggleStayOnTop_triggered();
void on_actionToggleProtectMode_triggered();
void on_actionToggleAvoidResetTransform_triggered();
void on_actionSettings_triggered();
@@ -115,11 +112,7 @@ private:
PlaylistManager *m_pm;
QPoint m_oldMousePos;
QPropertyAnimation *m_fadeOutAnimation;
QPropertyAnimation *m_floatUpAnimation;
QParallelAnimationGroup *m_exitAnimationGroup;
QFileSystemWatcher *m_fileSystemWatcher;
ToolButton *m_closeButton;
ToolButton *m_prevButton;
ToolButton *m_nextButton;
GraphicsView *m_graphicsView;
-11
View File
@@ -45,11 +45,6 @@ Settings *Settings::instance()
return m_settings_instance;
}
bool Settings::stayOnTop() const
{
return m_qsettings->value("stay_on_top", true).toBool();
}
bool Settings::useLightCheckerboard() const
{
return m_qsettings->value("use_light_checkerboard", false).toBool();
@@ -101,12 +96,6 @@ Qt::HighDpiScaleFactorRoundingPolicy Settings::hiDpiScaleFactorBehavior() const
return QEnumHelper::fromString<Qt::HighDpiScaleFactorRoundingPolicy>(result, Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
}
void Settings::setStayOnTop(bool on)
{
m_qsettings->setValue("stay_on_top", on);
m_qsettings->sync();
}
void Settings::setUseLightCheckerboard(bool light)
{
m_qsettings->setValue("use_light_checkerboard", light);
-2
View File
@@ -34,7 +34,6 @@ public:
static Settings *instance();
bool stayOnTop() const;
bool useLightCheckerboard() const;
bool loopGallery() const;
bool svgTiny12Only() const;
@@ -43,7 +42,6 @@ public:
WindowSizeBehavior initWindowSizeBehavior() const;
Qt::HighDpiScaleFactorRoundingPolicy hiDpiScaleFactorBehavior() const;
void setStayOnTop(bool on);
void setUseLightCheckerboard(bool light);
void setLoopGallery(bool on);
void setSvgTiny12Only(bool on);
-7
View File
@@ -19,7 +19,6 @@
SettingsDialog::SettingsDialog(QWidget *parent)
: QDialog(parent)
, m_stayOnTop(new QCheckBox)
, m_useLightCheckerboard(new QCheckBox)
, m_loopGallery(new QCheckBox)
, m_svgTiny12Only(new QCheckBox)
@@ -119,7 +118,6 @@ SettingsDialog::SettingsDialog(QWidget *parent)
hidpiDropDown.append(hidpiOption.second);
}
settingsForm->addRow(tr("Stay on top when start-up"), m_stayOnTop);
settingsForm->addRow(tr("Use light-color checkerboard"), m_useLightCheckerboard);
settingsForm->addRow(tr("Loop the loaded gallery"), m_loopGallery);
settingsForm->addRow(tr("Limit SVG support to SVG Tiny 1.2"), m_svgTiny12Only);
@@ -128,7 +126,6 @@ SettingsDialog::SettingsDialog(QWidget *parent)
settingsForm->addRow(tr("Default window size"), m_initWindowSizeBehavior);
settingsForm->addRow(tr("HiDPI scale factor rounding policy"), m_hiDpiRoundingPolicyBehavior);
m_stayOnTop->setChecked(Settings::instance()->stayOnTop());
m_useLightCheckerboard->setChecked(Settings::instance()->useLightCheckerboard());
m_loopGallery->setChecked(Settings::instance()->loopGallery());
m_svgTiny12Only->setChecked(Settings::instance()->svgTiny12Only());
@@ -158,10 +155,6 @@ SettingsDialog::SettingsDialog(QWidget *parent)
# define QT_CHECKSTATE int
#endif // QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
connect(m_stayOnTop, &QCHECKBOX_CHECKSTATECHANGED, this, [ = ](QT_CHECKSTATE state){
Settings::instance()->setStayOnTop(state == Qt::Checked);
});
connect(m_useLightCheckerboard, &QCHECKBOX_CHECKSTATECHANGED, this, [ = ](QT_CHECKSTATE state){
Settings::instance()->setUseLightCheckerboard(state == Qt::Checked);
});
-1
View File
@@ -22,7 +22,6 @@ signals:
public slots:
private:
QCheckBox * m_stayOnTop = nullptr;
QCheckBox * m_useLightCheckerboard = nullptr;
QCheckBox * m_loopGallery = nullptr;
QCheckBox * m_svgTiny12Only = nullptr;