fixed tooltips not showing over topmost windows on windows

This commit is contained in:
fourtf 2018-05-24 10:03:07 +02:00
parent 59110ad4bd
commit abc2b9724f
7 changed files with 63 additions and 27 deletions

View file

@ -61,6 +61,7 @@ void Application::construct()
isAppConstructed = true; isAppConstructed = true;
// 1. Instantiate all classes // 1. Instantiate all classes
this->settings = new singletons::SettingManager;
this->paths = new singletons::PathManager(this->argc, this->argv); this->paths = new singletons::PathManager(this->argc, this->argv);
this->themes = new singletons::ThemeManager; this->themes = new singletons::ThemeManager;
this->windows = new singletons::WindowManager; this->windows = new singletons::WindowManager;
@ -70,7 +71,6 @@ void Application::construct()
this->ignores = new controllers::ignores::IgnoreController; this->ignores = new controllers::ignores::IgnoreController;
this->accounts = new singletons::AccountManager; this->accounts = new singletons::AccountManager;
this->emotes = new singletons::EmoteManager; this->emotes = new singletons::EmoteManager;
this->settings = new singletons::SettingManager;
this->fonts = new singletons::FontManager; this->fonts = new singletons::FontManager;
this->resources = new singletons::ResourceManager; this->resources = new singletons::ResourceManager;
@ -92,12 +92,12 @@ void Application::initialize()
// 2. Initialize/load classes // 2. Initialize/load classes
this->settings->initialize(); this->settings->initialize();
this->windows->initialize();
this->nativeMessaging->registerHost(); this->nativeMessaging->registerHost();
this->settings->load(); this->settings->load();
this->commands->load(); this->commands->load();
this->windows->initialize();
this->resources->initialize(); this->resources->initialize();

View file

@ -32,10 +32,12 @@
namespace chatterino { namespace chatterino {
namespace widgets { namespace widgets {
BaseWindow::BaseWindow(QWidget *parent, Flags flags) BaseWindow::BaseWindow(QWidget *parent, Flags _flags)
: BaseWidget(parent, Qt::Window) : BaseWidget(parent,
, enableCustomFrame(flags & EnableCustomFrame) Qt::Window | ((_flags & TopMost) ? Qt::WindowStaysOnTopHint : (Qt::WindowFlags)0))
, frameless(flags & FrameLess) , enableCustomFrame(_flags & EnableCustomFrame)
, frameless(_flags & FrameLess)
, flags(_flags)
{ {
if (this->frameless) { if (this->frameless) {
this->enableCustomFrame = false; this->enableCustomFrame = false;
@ -45,6 +47,11 @@ BaseWindow::BaseWindow(QWidget *parent, Flags flags)
this->init(); this->init();
} }
BaseWindow::Flags BaseWindow::getFlags()
{
return this->flags;
}
void BaseWindow::init() void BaseWindow::init()
{ {
auto app = getApp(); auto app = getApp();
@ -124,14 +131,19 @@ void BaseWindow::init()
#endif #endif
#ifdef USEWINSDK #ifdef USEWINSDK
app->settings->windowTopMost.connect([this](bool topMost, auto) { // fourtf: don't ask me why we need to delay this
::SetWindowPos((HWND)this->winId(), topMost ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, QTimer::singleShot(1, this, [this] {
SWP_NOMOVE | SWP_NOSIZE); if (!(this->flags & Flags::TopMost)) {
getApp()->settings->windowTopMost.connect([this](bool topMost, auto) {
::SetWindowPos((HWND)this->winId(), topMost ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0,
0, 0, SWP_NOMOVE | SWP_NOSIZE);
});
}
}); });
#else #else
if (app->settings->windowTopMost.getValue()) { // if (getApp()->settings->windowTopMost.getValue()) {
this->setWindowFlags(this->windowFlags() | Qt::WindowStaysOnTopHint); // this->setWindowFlag(Qt::WindowStaysOnTopHint);
} // }
#endif #endif
} }
@ -425,8 +437,9 @@ void BaseWindow::showEvent(QShowEvent *event)
{ {
if (!this->shown && this->isVisible() && this->hasCustomWindowFrame()) { if (!this->shown && this->isVisible() && this->hasCustomWindowFrame()) {
this->shown = true; this->shown = true;
SetWindowLongPtr((HWND)this->winId(), GWL_STYLE, // SetWindowLongPtr((HWND)this->winId(), GWL_STYLE,
WS_POPUP | WS_CAPTION | WS_THICKFRAME | WS_MAXIMIZEBOX | WS_MINIMIZEBOX); // WS_POPUP | WS_CAPTION | WS_THICKFRAME | WS_MAXIMIZEBOX |
// WS_MINIMIZEBOX);
const MARGINS shadow = {8, 8, 8, 8}; const MARGINS shadow = {8, 8, 8, 8};
DwmExtendFrameIntoClientArea((HWND)this->winId(), &shadow); DwmExtendFrameIntoClientArea((HWND)this->winId(), &shadow);

View file

@ -19,7 +19,7 @@ class BaseWindow : public BaseWidget
Q_OBJECT Q_OBJECT
public: public:
enum Flags { None = 0, EnableCustomFrame = 1, FrameLess = 2 }; enum Flags { None = 0, EnableCustomFrame = 1, FrameLess = 2, TopMost = 4 };
explicit BaseWindow(QWidget *parent = nullptr, Flags flags = None); explicit BaseWindow(QWidget *parent = nullptr, Flags flags = None);
@ -33,6 +33,8 @@ public:
void moveTo(QWidget *widget, QPoint point); void moveTo(QWidget *widget, QPoint point);
Flags getFlags();
protected: protected:
#ifdef USEWINSDK #ifdef USEWINSDK
void showEvent(QShowEvent *) override; void showEvent(QShowEvent *) override;
@ -56,6 +58,7 @@ private:
bool frameless; bool frameless;
bool stayInScreenRect = false; bool stayInScreenRect = false;
bool shown = false; bool shown = false;
Flags flags;
struct { struct {
QHBoxLayout *titlebarBox = nullptr; QHBoxLayout *titlebarBox = nullptr;

View file

@ -29,7 +29,7 @@
#define LAYOUT_WIDTH (this->width() - (this->scrollBar.isVisible() ? 16 : 4) * this->getScale()) #define LAYOUT_WIDTH (this->width() - (this->scrollBar.isVisible() ? 16 : 4) * this->getScale())
#define SELECTION_RESUME_SCROLLING_MSG_THRESHOLD 3 #define SELECTION_RESUME_SCROLLING_MSG_THRESHOLD 3
#define CHAT_HOVER_PAUSE_DURATION 300 #define CHAT_HOVER_PAUSE_DURATION 400
using namespace chatterino::messages; using namespace chatterino::messages;
using namespace chatterino::providers::twitch; using namespace chatterino::providers::twitch;
@ -800,6 +800,7 @@ void ChannelView::mouseMoveEvent(QMouseEvent *event)
tooltipWidget->moveTo(this, event->globalPos()); tooltipWidget->moveTo(this, event->globalPos());
tooltipWidget->setText(tooltip); tooltipWidget->setText(tooltip);
tooltipWidget->show(); tooltipWidget->show();
tooltipWidget->raise();
} }
// check if word has a link // check if word has a link

View file

@ -254,15 +254,18 @@ void SplitHeader::updateModes()
text = text.mid(0, text.size() - 2); text = text.mid(0, text.size() - 2);
} }
qDebug() << text; if (text.isEmpty()) {
this->modeButton->hide();
} else {
static QRegularExpression commaReplacement("^.+?, .+?,( ).+$");
QRegularExpressionMatch match = commaReplacement.match(text);
if (match.hasMatch()) {
text = text.mid(0, match.capturedStart(1)) + '\n' + text.mid(match.capturedEnd(1));
}
static QRegularExpression commaReplacement("^.+?, .+?,( ).+$"); this->modeButton->getLabel().setText(text);
QRegularExpressionMatch match = commaReplacement.match(text); this->modeButton->show();
if (match.hasMatch()) {
text = text.mid(0, match.capturedStart(1)) + '\n' + text.mid(match.capturedEnd(1));
} }
this->modeButton->getLabel().setText(text);
} }
void SplitHeader::paintEvent(QPaintEvent *) void SplitHeader::paintEvent(QPaintEvent *)
@ -326,6 +329,7 @@ void SplitHeader::mouseMoveEvent(QMouseEvent *event)
tooltipWidget->moveTo(this, event->globalPos()); tooltipWidget->moveTo(this, event->globalPos());
tooltipWidget->setText(tooltip); tooltipWidget->setText(tooltip);
tooltipWidget->show(); tooltipWidget->show();
tooltipWidget->raise();
} }
if (this->dragging) { if (this->dragging) {

View file

@ -9,11 +9,15 @@
#include <QStyle> #include <QStyle>
#include <QVBoxLayout> #include <QVBoxLayout>
#ifdef USEWINSDK
#include <Windows.h>
#endif
namespace chatterino { namespace chatterino {
namespace widgets { namespace widgets {
TooltipWidget::TooltipWidget(BaseWidget *parent) TooltipWidget::TooltipWidget(BaseWidget *parent)
: BaseWindow(parent) : BaseWindow(parent, BaseWindow::TopMost)
, displayText(new QLabel()) , displayText(new QLabel())
{ {
auto app = getApp(); auto app = getApp();
@ -24,9 +28,8 @@ TooltipWidget::TooltipWidget(BaseWidget *parent)
this->setStayInScreenRect(true); this->setStayInScreenRect(true);
this->setAttribute(Qt::WA_ShowWithoutActivating); this->setAttribute(Qt::WA_ShowWithoutActivating);
this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | this->setWindowFlags(Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint |
Qt::X11BypassWindowManagerHint | Qt::BypassWindowManagerHint | Qt::BypassWindowManagerHint);
Qt::SubWindow);
displayText->setAlignment(Qt::AlignHCenter); displayText->setAlignment(Qt::AlignHCenter);
displayText->setText("tooltip text"); displayText->setText("tooltip text");
@ -43,6 +46,14 @@ TooltipWidget::~TooltipWidget()
this->fontChangedConnection.disconnect(); this->fontChangedConnection.disconnect();
} }
#ifdef USEWINSDK
void TooltipWidget::raise()
{
::SetWindowPos((HWND)this->winId(), HWND_TOPMOST, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
}
#endif
void TooltipWidget::themeRefreshEvent() void TooltipWidget::themeRefreshEvent()
{ {
this->setStyleSheet("color: #fff; background: #000"); this->setStyleSheet("color: #fff; background: #000");

View file

@ -28,6 +28,10 @@ public:
return tooltipWidget; return tooltipWidget;
} }
#ifdef USEWINSDK
void raise();
#endif
protected: protected:
void changeEvent(QEvent *) override; void changeEvent(QEvent *) override;
void leaveEvent(QEvent *) override; void leaveEvent(QEvent *) override;