Skip to content

Commit

Permalink
Add "Window On Top" item in View menu
Browse files Browse the repository at this point in the history
  • Loading branch information
jdpurcell committed Dec 8, 2024
1 parent 3296bae commit 1e1b757
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 19 deletions.
10 changes: 10 additions & 0 deletions i18n/qview_de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,11 @@
<source>Reset &amp;Transformation</source>
<translation type="unfinished">&amp;Transformation zurücksetzen</translation>
</message>
<message>
<location filename="../src/actionmanager.cpp" line="826"/>
<source>Window On To&amp;p</source>
<translation type="unfinished">Fenster im Vordergrund</translation>
</message>
<message>
<location filename="../src/actionmanager.cpp" line="826"/>
<source>Hide Title&amp;bar</source>
Expand Down Expand Up @@ -1881,6 +1886,11 @@ Keine Schreibberechtigung oder Datei ist schreibgeschützt.</translation>
<source>Reset Transformation</source>
<translation type="unfinished">Transformation zurücksetzen</translation>
</message>
<message>
<location filename="../src/shortcutmanager.cpp" line="97"/>
<source>Window On Top</source>
<translation type="unfinished">Fenster im Vordergrund</translation>
</message>
<message>
<location filename="../src/shortcutmanager.cpp" line="97"/>
<source>Toggle Titlebar Hidden</source>
Expand Down
8 changes: 8 additions & 0 deletions src/actionmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ QMenu *ActionManager::buildViewMenu(bool addIcon, QWidget *parent)
addCloneOfAction(viewMenu, "flip");
addCloneOfAction(viewMenu, "resettransformation");
viewMenu->addSeparator();
addCloneOfAction(viewMenu, "windowontop");
addCloneOfAction(viewMenu, "toggletitlebar");
addCloneOfAction(viewMenu, "fullscreen");

Expand Down Expand Up @@ -665,6 +666,8 @@ void ActionManager::actionTriggered(QAction *triggeredAction, MainWindow *releva
relevantWindow->flip();
} else if (key == "resettransformation") {
relevantWindow->resetTransformation();
} else if (key == "windowontop") {
relevantWindow->toggleWindowOnTop();
} else if (key == "toggletitlebar") {
relevantWindow->toggleTitlebarHidden();
} else if (key == "fullscreen") {
Expand Down Expand Up @@ -823,6 +826,11 @@ void ActionManager::initializeActionLibrary()
resetTransformationAction->setData({"disable"});
actionLibrary.insert("resettransformation", resetTransformationAction);

auto *windowOnTopAction = new QAction(tr("Window On To&p"));
windowOnTopAction->setData({"windowdisable"});
windowOnTopAction->setCheckable(true);
actionLibrary.insert("windowontop", windowOnTopAction);

auto *toggleTitlebarAction = new QAction(tr("Hide Title&bar"));
toggleTitlebarAction->setData({"windowdisable"});
actionLibrary.insert("toggletitlebar", toggleTitlebarAction);
Expand Down
37 changes: 35 additions & 2 deletions src/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,12 @@ void MainWindow::updateMenuBarVisible()
menuBar()->setVisible(alwaysVisible || (menuBarEnabled && !(hideWhenImmersive && isImmersive())));
}

bool MainWindow::getWindowOnTop() const
{
const QWindow *winHandle = windowHandle();
return winHandle && winHandle->flags().testFlag(Qt::WindowStaysOnTopHint);
}

bool MainWindow::getTitlebarHidden() const
{
if (!windowHandle())
Expand Down Expand Up @@ -806,6 +812,8 @@ const QJsonObject MainWindow::getSessionState() const

state["geometry"] = QString(saveGeometry().toBase64());

state["windowOnTop"] = getWindowOnTop();

state["titlebarHidden"] = getTitlebarHidden();

if (getCurrentFileDetails().isPixmapLoaded)
Expand All @@ -827,6 +835,9 @@ void MainWindow::loadSessionState(const QJsonObject &state, const bool isInitial
return;
}

if (state["windowOnTop"].toBool() != getWindowOnTop())
toggleWindowOnTop();

if (state["titlebarHidden"].toBool() != getTitlebarHidden())
toggleTitlebarHidden();

Expand Down Expand Up @@ -1298,8 +1309,17 @@ void MainWindow::toggleSlideshow()
slideshowAction->setText(isStarting ? tr("Stop S&lideshow") : tr("Start S&lideshow"));
slideshowAction->setIcon(QIcon::fromTheme(isStarting ? "media-playback-stop" : "media-playback-start"));
}
if (qvApp->getSlideshowKeepsWindowOnTop())
windowHandle()->setFlag(Qt::WindowStaysOnTopHint, isStarting);
if (isStarting)
{
slideshowSetOnTopFlag = qvApp->getSettingsManager().getBoolean("slideshowkeepswindowontop") && !getWindowOnTop();
if (slideshowSetOnTopFlag)
toggleWindowOnTop();
}
else
{
if (slideshowSetOnTopFlag && getWindowOnTop())
toggleWindowOnTop();
}
}

void MainWindow::cancelSlideshow()
Expand Down Expand Up @@ -1376,6 +1396,19 @@ void MainWindow::toggleFullScreen()
setUpdatesEnabled(true);
}

void MainWindow::toggleWindowOnTop()
{
if (!windowHandle())
return;

const bool targetValue = !getWindowOnTop();
windowHandle()->setFlag(Qt::WindowStaysOnTopHint, targetValue);
for (const auto &action : qvApp->getActionManager().getAllClonesOfAction("windowontop", this))
action->setChecked(targetValue);

emit qvApp->windowOnTopChanged();
}

void MainWindow::toggleTitlebarHidden()
{
if (windowState().testFlag(Qt::WindowFullScreen))
Expand Down
5 changes: 5 additions & 0 deletions src/mainwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ class MainWindow : public QMainWindow

void updateMenuBarVisible();

bool getWindowOnTop() const;

bool getTitlebarHidden() const;

void setTitlebarHidden(const bool shouldHide);
Expand Down Expand Up @@ -129,6 +131,8 @@ class MainWindow : public QMainWindow

void toggleFullScreen();

void toggleWindowOnTop();

void toggleTitlebarHidden();

int getTitlebarOverlap() const;
Expand Down Expand Up @@ -201,6 +205,7 @@ protected slots:

Qt::WindowStates storedWindowState {Qt::WindowNoState};
bool storedTitlebarHidden {false};
bool slideshowSetOnTopFlag {false};

QNetworkAccessManager networkAccessManager;

Expand Down
14 changes: 11 additions & 3 deletions src/qvapplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ QVApplication::QVApplication(int &argc, char **argv) : QApplication(argc, argv)
updateChecker.check();

showSubmenuIcons = getSettingsManager().getBoolean("submenuicons");
slideshowKeepsWindowOnTop = getSettingsManager().getBoolean("slideshowkeepswindowontop");

// Block any erroneous icons from showing up on mac and windows
// (this is overridden in some cases)
Expand Down Expand Up @@ -225,22 +224,31 @@ void QVApplication::deleteFromActiveWindows(MainWindow *window)

bool QVApplication::foundLoadedImage() const
{
for (MainWindow *window : std::as_const(activeWindows))
for (const MainWindow *window : activeWindows)
{
if (window->getIsPixmapLoaded())
return true;
}
return false;
}

bool QVApplication::foundOnTopWindow() const
{
for (const MainWindow *window : activeWindows)
{
if (window->getWindowOnTop())
return true;
}
return false;
}

void QVApplication::openOptionsDialog(QWidget *parent)
{
#ifdef Q_OS_MACOS
// On macOS, the dialog should not be dependent on any window
parent = nullptr;
#endif


if (optionsDialog)
{
optionsDialog->raise();
Expand Down
8 changes: 5 additions & 3 deletions src/qvapplication.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ class QVApplication : public QApplication

bool foundLoadedImage() const;

bool foundOnTopWindow() const;

void openOptionsDialog(QWidget *parent = nullptr);

void openWelcomeDialog(QWidget *parent = nullptr);
Expand Down Expand Up @@ -92,8 +94,6 @@ class QVApplication : public QApplication

bool getShowSubmenuIcons() const { return showSubmenuIcons; }

bool getSlideshowKeepsWindowOnTop() const { return slideshowKeepsWindowOnTop; }

void ensureFontLoaded(const QString &path);

static QIcon iconFromFont(const QString &fontFamily, const QChar &codePoint, const int pixelSize, const qreal pixelRatio);
Expand All @@ -116,6 +116,9 @@ class QVApplication : public QApplication

void addClosedWindowSessionState(const QJsonObject &state, const qint64 lastActivatedTimestamp);

signals:
void windowOnTopChanged();

protected slots:
void onCommitDataRequest(QSessionManager &manager);

Expand Down Expand Up @@ -145,7 +148,6 @@ protected slots:
QPointer<QVAboutDialog> aboutDialog;

bool showSubmenuIcons {true};
bool slideshowKeepsWindowOnTop {false};

UpdateChecker updateChecker;

Expand Down
31 changes: 20 additions & 11 deletions src/qvoptionsdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <QScreen>
#include <QMessageBox>
#include <QSettings>
#include <QWindow>

#include <QDebug>

Expand All @@ -27,7 +28,6 @@ QVOptionsDialog::QVOptionsDialog(QWidget *parent) :
connect(ui->shortcutsTable, &QTableWidget::cellDoubleClicked, this, &QVOptionsDialog::shortcutCellDoubleClicked);
connect(ui->bgColorCheckbox, &QCheckBox::stateChanged, this, &QVOptionsDialog::bgColorCheckboxStateChanged);
connect(ui->submenuIconsCheckbox, &QCheckBox::stateChanged, this, [this](int state) { restartNotifyForCheckbox("submenuicons", state); });
connect(ui->slideshowKeepsWindowOnTopCheckbox, &QCheckBox::stateChanged, this, [this](int state) { restartNotifyForCheckbox("slideshowkeepswindowontop", state); });
connect(ui->smoothScalingLimitCheckbox, &QCheckBox::stateChanged, this, &QVOptionsDialog::smoothScalingLimitCheckboxStateChanged);
connect(ui->fitZoomLimitCheckbox, &QCheckBox::stateChanged, this, &QVOptionsDialog::fitZoomLimitCheckboxStateChanged);
connect(ui->constrainImagePositionCheckbox, &QCheckBox::stateChanged, this, &QVOptionsDialog::constrainImagePositionCheckboxStateChanged);
Expand All @@ -47,22 +47,17 @@ QVOptionsDialog::QVOptionsDialog(QWidget *parent) :
populateComboBoxes();
populateLanguages();

// Platform specific behaviors
#ifdef Q_OS_MACOS
if (qvApp->getSlideshowKeepsWindowOnTop())
setWindowModality(Qt::ApplicationModal);
#else
setWindowModality(Qt::WindowModal);
#endif

#ifdef Q_OS_MACOS
// Load window geometry
restoreGeometry(settings.value("optionsgeometry").toByteArray());
#endif

if (QOperatingSystemVersion::current() < QOperatingSystemVersion(QOperatingSystemVersion::MacOS, 13))
setWindowTitle(tr("Preferences"));
#else
setWindowModality(Qt::WindowModal);
#endif

// Platform specific settings
// Platform specific settings
#ifdef Q_OS_MACOS
ui->menubarCheckbox->hide();
#else
Expand Down Expand Up @@ -105,6 +100,20 @@ void QVOptionsDialog::done(int r)
QDialog::done(r);
}

void QVOptionsDialog::showEvent(QShowEvent *event)
{
#ifdef Q_OS_MACOS
// On macOS, we don't make this dialog modal, so make sure it doesn't get covered by on top windows
const auto updateWindowOnTop = [this]() {
windowHandle()->setFlag(Qt::WindowStaysOnTopHint, qvApp->foundOnTopWindow());
};
updateWindowOnTop();
connect(qvApp, &QVApplication::windowOnTopChanged, this, updateWindowOnTop);
#endif

QDialog::showEvent(event);
}

void QVOptionsDialog::changeEvent(QEvent *event)
{
if (event->type() == QEvent::PaletteChange)
Expand Down
2 changes: 2 additions & 0 deletions src/qvoptionsdialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ class QVOptionsDialog : public QDialog
protected:
void done(int r) override;

void showEvent(QShowEvent *event) override;

void changeEvent(QEvent *event) override;

void modifySetting(QString key, QVariant value);
Expand Down
1 change: 1 addition & 0 deletions src/shortcutmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ void ShortcutManager::initializeShortcutsList()
shortcutsList.append({tr("Mirror"), "mirror", QStringList(QKeySequence(Qt::Key_F).toString()), {}});
shortcutsList.append({tr("Flip"), "flip", QStringList(QKeySequence(Qt::CTRL | Qt::Key_F).toString()), {}});
shortcutsList.append({tr("Reset Transformation"), "resettransformation", QStringList(QKeySequence(Qt::Key_T).toString()), {}});
shortcutsList.append({tr("Window On Top"), "windowontop", {}, {}});
shortcutsList.append({tr("Toggle Titlebar Hidden"), "toggletitlebar", {}, {}});
shortcutsList.append({tr("Full Screen"), "fullscreen", keyBindingsToStringList(QKeySequence::FullScreen), {}});
//Fixes alt+enter only working with numpad enter when using qt's standard keybinds
Expand Down

0 comments on commit 1e1b757

Please sign in to comment.