mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-13 19:49:51 +01:00
Fix tooltip & popup positioning (#4740)
* Fix tooltip & popup positioning This tries to ensure the tooltip & popups are created on the correct monitor * Add changelog entry * Clean up debug output * Use the full frame geometry to figure out screen bound movements * Remove the now-unused `setStayInScreenRect` function * Change the UserInfoPopup offset to be based on its width & height instead * Remove more debug output
This commit is contained in:
parent
b98be3b0f3
commit
9e2eb0dd29
|
@ -28,6 +28,7 @@
|
|||
- Bugfix: Fix visual glitches with smooth scrolling. (#4501)
|
||||
- Bugfix: Fixed pings firing for the "Your username" highlight when not signed in. (#4698)
|
||||
- Bugfix: Fixed partially broken filters on Qt 6 builds. (#4702)
|
||||
- Bugfix: Fixed tooltips & popups sometimes showing up on the wrong monitor. (#4740)
|
||||
- Bugfix: Fixed some network errors having `0` as their HTTP status. (#4704)
|
||||
- Bugfix: Fixed crash that could occurr when closing the usercard too quickly after blocking or unblocking a user. (#4711)
|
||||
- Bugfix: Fixed highlights sometimes not working after changing sound device, or switching users in your operating system. (#4729)
|
||||
|
|
|
@ -923,7 +923,8 @@ void CommandController::initialize(Settings &, Paths &paths)
|
|||
static_cast<QWidget *>(&(getApp()->windows->getMainWindow())),
|
||||
currentSplit);
|
||||
userPopup->setData(userName, channel);
|
||||
userPopup->move(QCursor::pos());
|
||||
userPopup->moveTo(QCursor::pos(), false,
|
||||
BaseWindow::BoundsChecker::CursorPosition);
|
||||
userPopup->show();
|
||||
return "";
|
||||
});
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "widgets/helper/EffectLabel.hpp"
|
||||
#include "widgets/Label.hpp"
|
||||
#include "widgets/TooltipWidget.hpp"
|
||||
#include "widgets/Window.hpp"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QFont>
|
||||
|
@ -240,18 +241,6 @@ void BaseWindow::init()
|
|||
#endif
|
||||
}
|
||||
|
||||
void BaseWindow::setStayInScreenRect(bool value)
|
||||
{
|
||||
this->stayInScreenRect_ = value;
|
||||
|
||||
this->moveIntoDesktopRect(this->pos());
|
||||
}
|
||||
|
||||
bool BaseWindow::getStayInScreenRect() const
|
||||
{
|
||||
return this->stayInScreenRect_;
|
||||
}
|
||||
|
||||
void BaseWindow::setActionOnFocusLoss(ActionOnFocusLoss value)
|
||||
{
|
||||
this->actionOnFocusLoss_ = value;
|
||||
|
@ -514,7 +503,7 @@ void BaseWindow::leaveEvent(QEvent *)
|
|||
TooltipWidget::instance()->hide();
|
||||
}
|
||||
|
||||
void BaseWindow::moveTo(QWidget *parent, QPoint point, bool offset)
|
||||
void BaseWindow::moveTo(QPoint point, bool offset, BoundsChecker boundsChecker)
|
||||
{
|
||||
if (offset)
|
||||
{
|
||||
|
@ -522,7 +511,26 @@ void BaseWindow::moveTo(QWidget *parent, QPoint point, bool offset)
|
|||
point.ry() += 16;
|
||||
}
|
||||
|
||||
this->moveIntoDesktopRect(point);
|
||||
switch (boundsChecker)
|
||||
{
|
||||
case BoundsChecker::Off: {
|
||||
// The bounds checker is off, *just* move the window
|
||||
this->move(point);
|
||||
}
|
||||
break;
|
||||
|
||||
case BoundsChecker::CursorPosition: {
|
||||
// The bounds checker is on, use the cursor position as the origin
|
||||
this->moveWithinScreen(point, QCursor::pos());
|
||||
}
|
||||
break;
|
||||
|
||||
case BoundsChecker::DesiredPosition: {
|
||||
// The bounds checker is on, use the desired position as the origin
|
||||
this->moveWithinScreen(point, point);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void BaseWindow::resizeEvent(QResizeEvent *)
|
||||
|
@ -576,24 +584,13 @@ void BaseWindow::closeEvent(QCloseEvent *)
|
|||
|
||||
void BaseWindow::showEvent(QShowEvent *)
|
||||
{
|
||||
this->moveIntoDesktopRect(this->pos());
|
||||
if (this->frameless_)
|
||||
{
|
||||
QTimer::singleShot(30, this, [this] {
|
||||
this->moveIntoDesktopRect(this->pos());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void BaseWindow::moveIntoDesktopRect(QPoint point)
|
||||
void BaseWindow::moveWithinScreen(QPoint point, QPoint origin)
|
||||
{
|
||||
if (!this->stayInScreenRect_)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// move the widget into the screen geometry if it's not already in there
|
||||
auto *screen = QApplication::screenAt(point);
|
||||
auto *screen = QApplication::screenAt(origin);
|
||||
|
||||
if (screen == nullptr)
|
||||
{
|
||||
screen = QApplication::primaryScreen();
|
||||
|
@ -603,6 +600,9 @@ void BaseWindow::moveIntoDesktopRect(QPoint point)
|
|||
bool stickRight = false;
|
||||
bool stickBottom = false;
|
||||
|
||||
const auto w = this->frameGeometry().width();
|
||||
const auto h = this->frameGeometry().height();
|
||||
|
||||
if (point.x() < bounds.left())
|
||||
{
|
||||
point.setX(bounds.left());
|
||||
|
@ -611,15 +611,15 @@ void BaseWindow::moveIntoDesktopRect(QPoint point)
|
|||
{
|
||||
point.setY(bounds.top());
|
||||
}
|
||||
if (point.x() + this->width() > bounds.right())
|
||||
if (point.x() + w > bounds.right())
|
||||
{
|
||||
stickRight = true;
|
||||
point.setX(bounds.right() - this->width());
|
||||
point.setX(bounds.right() - w);
|
||||
}
|
||||
if (point.y() + this->height() > bounds.bottom())
|
||||
if (point.y() + h > bounds.bottom())
|
||||
{
|
||||
stickBottom = true;
|
||||
point.setY(bounds.bottom() - this->height());
|
||||
point.setY(bounds.bottom() - h);
|
||||
}
|
||||
|
||||
if (stickRight && stickBottom)
|
||||
|
|
|
@ -36,6 +36,17 @@ public:
|
|||
DisableLayoutSave = 128,
|
||||
};
|
||||
|
||||
enum class BoundsChecker {
|
||||
// Don't attempt to do any "stay in screen" stuff, just move me!
|
||||
Off,
|
||||
|
||||
// Attempt to keep the window within bounds of the screen the cursor is on
|
||||
CursorPosition,
|
||||
|
||||
// Attempt to keep the window within bounds of the screen the desired position is on
|
||||
DesiredPosition,
|
||||
};
|
||||
|
||||
enum ActionOnFocusLoss { Nothing, Delete, Close, Hide };
|
||||
|
||||
explicit BaseWindow(FlagsEnum<Flags> flags_ = None,
|
||||
|
@ -51,15 +62,12 @@ public:
|
|||
std::function<void()> onClicked);
|
||||
EffectLabel *addTitleBarLabel(std::function<void()> onClicked);
|
||||
|
||||
void setStayInScreenRect(bool value);
|
||||
bool getStayInScreenRect() const;
|
||||
|
||||
void setActionOnFocusLoss(ActionOnFocusLoss value);
|
||||
ActionOnFocusLoss getActionOnFocusLoss() const;
|
||||
|
||||
void moveTo(QWidget *widget, QPoint point, bool offset = true);
|
||||
void moveTo(QPoint point, bool offset, BoundsChecker boundsChecker);
|
||||
|
||||
virtual float scale() const override;
|
||||
float scale() const override;
|
||||
float qtFontScale() const;
|
||||
|
||||
pajlada::Signals::NoArgSignal closing;
|
||||
|
@ -101,7 +109,12 @@ protected:
|
|||
|
||||
private:
|
||||
void init();
|
||||
void moveIntoDesktopRect(QPoint point);
|
||||
|
||||
/**
|
||||
*
|
||||
**/
|
||||
void moveWithinScreen(QPoint point, QPoint origin);
|
||||
|
||||
void calcButtonsSizes();
|
||||
void drawCustomWindowFrame(QPainter &painter);
|
||||
void onFocusLost();
|
||||
|
@ -121,7 +134,6 @@ private:
|
|||
bool enableCustomFrame_;
|
||||
ActionOnFocusLoss actionOnFocusLoss_ = Nothing;
|
||||
bool frameless_;
|
||||
bool stayInScreenRect_ = false;
|
||||
bool shown_ = false;
|
||||
FlagsEnum<Flags> flags_;
|
||||
float nativeScale_ = 1;
|
||||
|
|
|
@ -27,8 +27,6 @@ TooltipWidget::TooltipWidget(BaseWidget *parent)
|
|||
this->setAttribute(Qt::WA_TranslucentBackground);
|
||||
this->setWindowFlag(Qt::WindowStaysOnTopHint, true);
|
||||
|
||||
this->setStayInScreenRect(true);
|
||||
|
||||
// Default to using vertical layout
|
||||
this->initializeVLayout();
|
||||
this->setLayout(this->vLayout_);
|
||||
|
|
|
@ -206,8 +206,9 @@ EmotePopup::EmotePopup(QWidget *parent)
|
|||
, search_(new QLineEdit())
|
||||
, notebook_(new Notebook(this))
|
||||
{
|
||||
this->setStayInScreenRect(true);
|
||||
this->moveTo(this, getApp()->windows->emotePopupPos(), false);
|
||||
// this->setStayInScreenRect(true);
|
||||
this->moveTo(getApp()->windows->emotePopupPos(), false,
|
||||
BaseWindow::BoundsChecker::DesiredPosition);
|
||||
|
||||
auto *layout = new QVBoxLayout();
|
||||
this->getLayoutContainer()->setLayout(layout);
|
||||
|
|
|
@ -29,7 +29,6 @@ ReplyThreadPopup::ReplyThreadPopup(bool closeAutomatically, QWidget *parent,
|
|||
, split_(split)
|
||||
{
|
||||
this->setWindowTitle(QStringLiteral("Reply Thread"));
|
||||
this->setStayInScreenRect(true);
|
||||
|
||||
HotkeyController::HotkeyMap actions{
|
||||
{"delete",
|
||||
|
|
|
@ -142,7 +142,6 @@ UserInfoPopup::UserInfoPopup(bool closeAutomatically, QWidget *parent,
|
|||
assert(split != nullptr &&
|
||||
"split being nullptr causes lots of bugs down the road");
|
||||
this->setWindowTitle("Usercard");
|
||||
this->setStayInScreenRect(true);
|
||||
|
||||
HotkeyController::HotkeyMap actions{
|
||||
{"delete",
|
||||
|
@ -715,9 +714,6 @@ void UserInfoPopup::setData(const QString &name,
|
|||
this->userStateChanged_.invoke();
|
||||
|
||||
this->updateLatestMessages();
|
||||
QTimer::singleShot(1, this, [this] {
|
||||
this->setStayInScreenRect(true);
|
||||
});
|
||||
}
|
||||
|
||||
void UserInfoPopup::updateLatestMessages()
|
||||
|
|
|
@ -46,7 +46,6 @@ QuickSwitcherPopup::QuickSwitcherPopup(QWidget *parent)
|
|||
|
||||
this->initWidgets();
|
||||
|
||||
this->setStayInScreenRect(true);
|
||||
const QRect geom = parent->geometry();
|
||||
// This places the popup in the middle of the parent widget
|
||||
this->setGeometry(QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter,
|
||||
|
|
|
@ -1810,7 +1810,8 @@ void ChannelView::mouseMoveEvent(QMouseEvent *event)
|
|||
}
|
||||
}
|
||||
|
||||
tooltipWidget->moveTo(this, event->globalPos());
|
||||
tooltipWidget->moveTo(event->globalPos(), true,
|
||||
BaseWindow::BoundsChecker::CursorPosition);
|
||||
tooltipWidget->setWordWrap(isLinkValid);
|
||||
tooltipWidget->show();
|
||||
}
|
||||
|
@ -2663,8 +2664,9 @@ void ChannelView::showUserInfoPopup(const QString &userName,
|
|||
: this->underlyingChannel_;
|
||||
userPopup->setData(userName, contextChannel, openingChannel);
|
||||
|
||||
QPoint offset(int(150 * this->scale()), int(70 * this->scale()));
|
||||
userPopup->move(QCursor::pos() - offset);
|
||||
QPoint offset(userPopup->width() / 3, userPopup->height() / 5);
|
||||
userPopup->moveTo(QCursor::pos() - offset, false,
|
||||
BaseWindow::BoundsChecker::CursorPosition);
|
||||
userPopup->show();
|
||||
}
|
||||
|
||||
|
|
|
@ -964,7 +964,7 @@ void SplitHeader::enterEvent(QEvent *event)
|
|||
auto pos = this->mapToGlobal(this->rect().bottomLeft()) +
|
||||
QPoint((this->width() - tooltip->width()) / 2, 1);
|
||||
|
||||
tooltip->moveTo(this, pos, false);
|
||||
tooltip->moveTo(pos, false, BaseWindow::BoundsChecker::CursorPosition);
|
||||
tooltip->show();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue