mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-13 19:49:51 +01:00
feat: add option to change the top-most status of a window (#5135)
* feat: add option to pin a popup * chore: add changelog entry * chore: change changelog entry
This commit is contained in:
parent
8e9aa87a08
commit
af8eba0323
|
@ -31,6 +31,7 @@
|
|||
- Minor: Added the `--incognito/--no-incognito` options to the `/openurl` command, allowing you to override the "Open links in incognito/private mode" setting. (#5149)
|
||||
- Minor: Added support for the `{input.text}` placeholder in the **Split** -> **Run a command** hotkey. (#5130)
|
||||
- Minor: Add a new Channel API for experimental plugins feature. (#5141)
|
||||
- Minor: Added the ability to change the top-most status of a window regardless of the _Always on top_ setting (right click the notebook). (#5135)
|
||||
- Bugfix: Fixed an issue where certain emojis did not send to Twitch chat correctly. (#4840)
|
||||
- Bugfix: Fixed capitalized channel names in log inclusion list not being logged. (#4848)
|
||||
- Bugfix: Trimmed custom streamlink paths on all platforms making sure you don't accidentally add spaces at the beginning or end of its path. (#4834)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "widgets/BaseWindow.hpp"
|
||||
|
||||
#include "Application.hpp"
|
||||
#include "common/QLogging.hpp"
|
||||
#include "singletons/Settings.hpp"
|
||||
#include "singletons/Theme.hpp"
|
||||
#include "singletons/WindowManager.hpp"
|
||||
|
@ -207,37 +208,52 @@ void BaseWindow::init()
|
|||
// }
|
||||
#endif
|
||||
|
||||
#ifdef USEWINSDK
|
||||
// fourtf: don't ask me why we need to delay this
|
||||
if (!this->flags_.has(TopMost))
|
||||
{
|
||||
QTimer::singleShot(1, this, [this] {
|
||||
getSettings()->windowTopMost.connect(
|
||||
[this](bool topMost, auto) {
|
||||
::SetWindowPos(HWND(this->winId()),
|
||||
topMost ? HWND_TOPMOST : HWND_NOTOPMOST, 0,
|
||||
0, 0, 0,
|
||||
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
|
||||
},
|
||||
this->connections_);
|
||||
});
|
||||
}
|
||||
#else
|
||||
// TopMost flag overrides setting
|
||||
if (!this->flags_.has(TopMost))
|
||||
{
|
||||
getSettings()->windowTopMost.connect(
|
||||
[this](bool topMost, auto) {
|
||||
auto isVisible = this->isVisible();
|
||||
this->setWindowFlag(Qt::WindowStaysOnTopHint, topMost);
|
||||
if (isVisible)
|
||||
{
|
||||
this->show();
|
||||
}
|
||||
[this](bool topMost) {
|
||||
this->setTopMost(topMost);
|
||||
},
|
||||
this->connections_);
|
||||
}
|
||||
}
|
||||
|
||||
void BaseWindow::setTopMost(bool topMost)
|
||||
{
|
||||
if (this->flags_.has(TopMost))
|
||||
{
|
||||
qCWarning(chatterinoWidget)
|
||||
<< "Called setTopMost on a window with the `TopMost` flag set.";
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->isTopMost_ == topMost)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef USEWINSDK
|
||||
::SetWindowPos(reinterpret_cast<HWND>(this->winId()),
|
||||
topMost ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0,
|
||||
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
|
||||
|
||||
#else
|
||||
auto isVisible = this->isVisible();
|
||||
this->setWindowFlag(Qt::WindowStaysOnTopHint, topMost);
|
||||
if (isVisible)
|
||||
{
|
||||
this->show();
|
||||
}
|
||||
#endif
|
||||
|
||||
this->isTopMost_ = topMost;
|
||||
this->topMostChanged(this->isTopMost_);
|
||||
}
|
||||
|
||||
bool BaseWindow::isTopMost() const
|
||||
{
|
||||
return this->isTopMost_ || this->flags_.has(TopMost);
|
||||
}
|
||||
|
||||
void BaseWindow::setActionOnFocusLoss(ActionOnFocusLoss value)
|
||||
|
@ -559,6 +575,15 @@ void BaseWindow::showEvent(QShowEvent *)
|
|||
{
|
||||
this->moveTo(this->pos(), widgets::BoundsChecking::CursorPosition);
|
||||
}
|
||||
|
||||
if (!this->flags_.has(TopMost))
|
||||
{
|
||||
QTimer::singleShot(1, this, [this] {
|
||||
::SetWindowPos(reinterpret_cast<HWND>(this->winId()),
|
||||
this->isTopMost_ ? HWND_TOPMOST : HWND_NOTOPMOST, 0,
|
||||
0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
|
||||
});
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -68,10 +68,20 @@ public:
|
|||
float scale() const override;
|
||||
float qtFontScale() const;
|
||||
|
||||
/// @returns true if the window is the top-most window.
|
||||
/// Either #setTopMost was called or the `TopMost` flag is set which overrides this
|
||||
bool isTopMost() const;
|
||||
/// Updates the window's top-most status
|
||||
/// If the `TopMost` flag is set, this is a no-op
|
||||
void setTopMost(bool topMost);
|
||||
|
||||
pajlada::Signals::NoArgSignal closing;
|
||||
|
||||
static bool supportsCustomWindowFrame();
|
||||
|
||||
signals:
|
||||
void topMostChanged(bool topMost);
|
||||
|
||||
protected:
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
bool nativeEvent(const QByteArray &eventType, void *message,
|
||||
|
@ -131,6 +141,7 @@ private:
|
|||
FlagsEnum<Flags> flags_;
|
||||
float nativeScale_ = 1;
|
||||
bool isResizeFixing_ = false;
|
||||
bool isTopMost_ = false;
|
||||
|
||||
struct {
|
||||
QLayout *windowLayout = nullptr;
|
||||
|
|
|
@ -59,6 +59,28 @@ Notebook::Notebook(QWidget *parent)
|
|||
});
|
||||
this->updateTabVisibilityMenuAction();
|
||||
|
||||
this->toggleTopMostAction_ = new QAction("Top most window", this);
|
||||
this->toggleTopMostAction_->setCheckable(true);
|
||||
auto *window = dynamic_cast<BaseWindow *>(this->window());
|
||||
if (window)
|
||||
{
|
||||
auto updateTopMost = [this, window] {
|
||||
this->toggleTopMostAction_->setChecked(window->isTopMost());
|
||||
};
|
||||
updateTopMost();
|
||||
QObject::connect(this->toggleTopMostAction_, &QAction::triggered,
|
||||
window, [window] {
|
||||
window->setTopMost(!window->isTopMost());
|
||||
});
|
||||
QObject::connect(window, &BaseWindow::topMostChanged, this,
|
||||
updateTopMost);
|
||||
}
|
||||
else
|
||||
{
|
||||
qCWarning(chatterinoApp)
|
||||
<< "Notebook must be created within a BaseWindow";
|
||||
}
|
||||
|
||||
this->addNotebookActionsToMenu(&this->menu_);
|
||||
|
||||
// Manually resize the add button so the initial paint uses the correct
|
||||
|
@ -1181,6 +1203,8 @@ void Notebook::addNotebookActionsToMenu(QMenu *menu)
|
|||
menu->addAction(this->showTabsAction_);
|
||||
|
||||
menu->addAction(this->lockNotebookLayoutAction_);
|
||||
|
||||
menu->addAction(this->toggleTopMostAction_);
|
||||
}
|
||||
|
||||
NotebookButton *Notebook::getAddButton()
|
||||
|
|
|
@ -196,6 +196,7 @@ private:
|
|||
NotebookTabLocation tabLocation_ = NotebookTabLocation::Top;
|
||||
QAction *lockNotebookLayoutAction_;
|
||||
QAction *showTabsAction_;
|
||||
QAction *toggleTopMostAction_;
|
||||
|
||||
// This filter, if set, is used to figure out the visibility of
|
||||
// the tabs in this notebook.
|
||||
|
@ -224,7 +225,6 @@ private:
|
|||
|
||||
// Main window on Windows has basically a duplicate of this in Window
|
||||
NotebookButton *streamerModeIcon_{};
|
||||
|
||||
void updateStreamerModeIcon();
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue