mirror of https://github.com/procxx/kepka.git
Improve calls panel in macOS.
Use Qt::Dialog instead of Qt::Tool which works better with window activation / deactivation handling. Stop displaying the panel on all spaces when the call is established.
This commit is contained in:
parent
0cdac83f8a
commit
5f2e295d63
|
@ -184,7 +184,7 @@ void Panel::refreshCallbacks() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::initLayout() {
|
void Panel::initLayout() {
|
||||||
setWindowFlags(Qt::WindowFlags(Qt::FramelessWindowHint) | Qt::WindowStaysOnTopHint | Qt::BypassWindowManagerHint | Qt::NoDropShadowWindowHint | Qt::Tool);
|
setWindowFlags(Qt::WindowFlags(Qt::FramelessWindowHint) | Qt::WindowStaysOnTopHint | Qt::BypassWindowManagerHint | Qt::NoDropShadowWindowHint | Qt::Dialog);
|
||||||
setAttribute(Qt::WA_MacAlwaysShowToolWindow);
|
setAttribute(Qt::WA_MacAlwaysShowToolWindow);
|
||||||
setAttribute(Qt::WA_NoSystemBackground, true);
|
setAttribute(Qt::WA_NoSystemBackground, true);
|
||||||
setAttribute(Qt::WA_TranslucentBackground, true);
|
setAttribute(Qt::WA_TranslucentBackground, true);
|
||||||
|
@ -267,8 +267,9 @@ bool Panel::isGoodUserPhoto(PhotoData *photo) {
|
||||||
|
|
||||||
void Panel::initGeometry() {
|
void Panel::initGeometry() {
|
||||||
auto center = Messenger::Instance().getPointForCallPanelCenter();
|
auto center = Messenger::Instance().getPointForCallPanelCenter();
|
||||||
_useTransparency = Platform::TransparentWindowsSupported(center);
|
_useTransparency = Platform::TranslucentWindowsSupported(center);
|
||||||
_padding = _useTransparency ? st::callShadow.extend : style::margins();
|
setAttribute(Qt::WA_OpaquePaintEvent, !_useTransparency);
|
||||||
|
_padding = _useTransparency ? st::callShadow.extend : style::margins(st::lineWidth, st::lineWidth, st::lineWidth, st::lineWidth);
|
||||||
_contentTop = _padding.top() + st::callWidth;
|
_contentTop = _padding.top() + st::callWidth;
|
||||||
auto screen = QApplication::desktop()->screenGeometry(center);
|
auto screen = QApplication::desktop()->screenGeometry(center);
|
||||||
auto rect = QRect(0, 0, st::callWidth, st::callHeight);
|
auto rect = QRect(0, 0, st::callWidth, st::callHeight);
|
||||||
|
@ -359,10 +360,17 @@ void Panel::updateStatusGeometry() {
|
||||||
void Panel::paintEvent(QPaintEvent *e) {
|
void Panel::paintEvent(QPaintEvent *e) {
|
||||||
Painter p(this);
|
Painter p(this);
|
||||||
if (_useTransparency) {
|
if (_useTransparency) {
|
||||||
|
Platform::StartTranslucentPaint(p, e);
|
||||||
p.drawPixmapLeft(0, 0, width(), _cache);
|
p.drawPixmapLeft(0, 0, width(), _cache);
|
||||||
} else {
|
} else {
|
||||||
p.drawPixmapLeft(0, 0, width(), _userPhoto);
|
p.drawPixmapLeft(_padding.left(), _padding.top(), width(), _userPhoto);
|
||||||
p.fillRect(myrtlrect(0, st::callWidth, width(), height() - st::callWidth), st::callBg);
|
auto callBgOpaque = st::callBg->c;
|
||||||
|
callBgOpaque.setAlpha(255);
|
||||||
|
auto brush = QBrush(callBgOpaque);
|
||||||
|
p.fillRect(0, 0, width(), _padding.top(), brush);
|
||||||
|
p.fillRect(myrtlrect(0, _padding.top(), _padding.left(), _contentTop - _padding.top()), brush);
|
||||||
|
p.fillRect(myrtlrect(width() - _padding.right(), _padding.top(), _padding.right(), _contentTop - _padding.top()), brush);
|
||||||
|
p.fillRect(0, _contentTop, width(), height() - _contentTop, brush);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_fingerprint.empty()) {
|
if (!_fingerprint.empty()) {
|
||||||
|
@ -381,10 +389,16 @@ void Panel::paintEvent(QPaintEvent *e) {
|
||||||
|
|
||||||
void Panel::mousePressEvent(QMouseEvent *e) {
|
void Panel::mousePressEvent(QMouseEvent *e) {
|
||||||
auto dragArea = myrtlrect(_padding.left(), _padding.top(), st::callWidth, st::callWidth);
|
auto dragArea = myrtlrect(_padding.left(), _padding.top(), st::callWidth, st::callWidth);
|
||||||
if (e->button() == Qt::LeftButton && dragArea.contains(e->pos())) {
|
if (e->button() == Qt::LeftButton) {
|
||||||
|
if (dragArea.contains(e->pos())) {
|
||||||
_dragging = true;
|
_dragging = true;
|
||||||
_dragStartMousePosition = e->globalPos();
|
_dragStartMousePosition = e->globalPos();
|
||||||
_dragStartMyPosition = QPoint(x(), y());
|
_dragStartMyPosition = QPoint(x(), y());
|
||||||
|
} else if (!rect().contains(e->pos())) {
|
||||||
|
if (_call && _call->state() == State::Established) {
|
||||||
|
hideDeactivated();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -458,10 +472,17 @@ void Panel::stateChanged(State state) {
|
||||||
if (_fingerprint.empty() && _call && _call->isKeyShaForFingerprintReady()) {
|
if (_fingerprint.empty() && _call && _call->isKeyShaForFingerprintReady()) {
|
||||||
fillFingerprint();
|
fillFingerprint();
|
||||||
}
|
}
|
||||||
if (state == State::Established && !isActiveWindow()) {
|
if ((state == State::Starting) || (state == State::WaitingIncoming)) {
|
||||||
|
Platform::ReInitOnTopPanel(this);
|
||||||
|
} else {
|
||||||
|
Platform::DeInitOnTopPanel(this);
|
||||||
|
}
|
||||||
|
if (state == State::Established) {
|
||||||
|
if (!isActiveWindow()) {
|
||||||
hideDeactivated();
|
hideDeactivated();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Panel::fillFingerprint() {
|
void Panel::fillFingerprint() {
|
||||||
_fingerprint = ComputeEmojiFingerprint(_call.get());
|
_fingerprint = ComputeEmojiFingerprint(_call.get());
|
||||||
|
|
|
@ -377,10 +377,7 @@ void finish() {
|
||||||
_psEventFilter = nullptr;
|
_psEventFilter = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetWatchingMediaKeys(bool watching) {
|
bool TranslucentWindowsSupported(QPoint globalPosition) {
|
||||||
}
|
|
||||||
|
|
||||||
bool TransparentWindowsSupported(QPoint globalPosition) {
|
|
||||||
if (auto app = static_cast<QGuiApplication*>(QCoreApplication::instance())) {
|
if (auto app = static_cast<QGuiApplication*>(QCoreApplication::instance())) {
|
||||||
if (auto native = app->platformNativeInterface()) {
|
if (auto native = app->platformNativeInterface()) {
|
||||||
if (auto desktop = QApplication::desktop()) {
|
if (auto desktop = QApplication::desktop()) {
|
||||||
|
@ -405,9 +402,6 @@ bool TransparentWindowsSupported(QPoint globalPosition) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitOnTopPanel(QWidget *panel) {
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace ThirdParty {
|
namespace ThirdParty {
|
||||||
|
|
||||||
void start() {
|
void start() {
|
||||||
|
|
|
@ -20,6 +20,25 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include <execinfo.h>
|
#include <execinfo.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
|
namespace Platform {
|
||||||
|
|
||||||
|
inline void SetWatchingMediaKeys(bool watching) {
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void StartTranslucentPaint(QPainter &p, QPaintEvent *e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void InitOnTopPanel(QWidget *panel) {
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void DeInitOnTopPanel(QWidget *panel) {
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void ReInitOnTopPanel(QWidget *panel) {
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Platform
|
||||||
|
|
||||||
inline QString psServerPrefix() {
|
inline QString psServerPrefix() {
|
||||||
return qsl("/tmp/");
|
return qsl("/tmp/");
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,9 +48,6 @@ public:
|
||||||
return _customTitleHeight;
|
return _customTitleHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
// It is placed here while the window handles activeSpaceDidChange event.
|
|
||||||
void customNotificationCreated(QWidget *notification);
|
|
||||||
|
|
||||||
~MainWindow();
|
~MainWindow();
|
||||||
|
|
||||||
class Private;
|
class Private;
|
||||||
|
@ -104,16 +101,9 @@ private:
|
||||||
void updateTitleCounter();
|
void updateTitleCounter();
|
||||||
void updateIconCounters();
|
void updateIconCounters();
|
||||||
|
|
||||||
class CustomNotificationHandle;
|
|
||||||
friend class CustomNotificationHandle;
|
|
||||||
void customNotificationDestroyed(CustomNotificationHandle *handle);
|
|
||||||
void activateCustomNotifications();
|
|
||||||
|
|
||||||
friend class Private;
|
friend class Private;
|
||||||
std::unique_ptr<Private> _private;
|
std::unique_ptr<Private> _private;
|
||||||
|
|
||||||
std::set<CustomNotificationHandle*> _customNotifications;
|
|
||||||
|
|
||||||
mutable bool psIdle;
|
mutable bool psIdle;
|
||||||
mutable QTimer psIdleTimer;
|
mutable QTimer psIdleTimer;
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,6 @@ public:
|
||||||
|
|
||||||
void willEnterFullScreen();
|
void willEnterFullScreen();
|
||||||
void willExitFullScreen();
|
void willExitFullScreen();
|
||||||
void activateCustomNotifications();
|
|
||||||
|
|
||||||
void initCustomTitle(NSWindow *window, NSView *view);
|
void initCustomTitle(NSWindow *window, NSView *view);
|
||||||
|
|
||||||
|
@ -92,25 +91,6 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class MainWindow::CustomNotificationHandle : public QObject {
|
|
||||||
public:
|
|
||||||
CustomNotificationHandle(QWidget *parent) : QObject(parent) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void activate() {
|
|
||||||
auto widget = static_cast<QWidget*>(parent());
|
|
||||||
NSWindow *wnd = [reinterpret_cast<NSView *>(widget->winId()) window];
|
|
||||||
[wnd orderFront:wnd];
|
|
||||||
}
|
|
||||||
|
|
||||||
~CustomNotificationHandle() {
|
|
||||||
if (auto window = App::wnd()) {
|
|
||||||
window->customNotificationDestroyed(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Platform
|
} // namespace Platform
|
||||||
|
|
||||||
@implementation MainWindowObserver {
|
@implementation MainWindowObserver {
|
||||||
|
@ -126,7 +106,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) activeSpaceDidChange:(NSNotification *)aNotification {
|
- (void) activeSpaceDidChange:(NSNotification *)aNotification {
|
||||||
_private->activateCustomNotifications();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) darkModeChanged:(NSNotification *)aNotification {
|
- (void) darkModeChanged:(NSNotification *)aNotification {
|
||||||
|
@ -211,10 +190,6 @@ void MainWindow::Private::willExitFullScreen() {
|
||||||
_public->setTitleVisible(true);
|
_public->setTitleVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::Private::activateCustomNotifications() {
|
|
||||||
_public->activateCustomNotifications();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::Private::enableShadow(WId winId) {
|
void MainWindow::Private::enableShadow(WId winId) {
|
||||||
// [[(NSView*)winId window] setStyleMask:NSBorderlessWindowMask];
|
// [[(NSView*)winId window] setStyleMask:NSBorderlessWindowMask];
|
||||||
// [[(NSView*)winId window] setHasShadow:YES];
|
// [[(NSView*)winId window] setHasShadow:YES];
|
||||||
|
@ -527,20 +502,6 @@ void MainWindow::psUpdateSysMenu(Qt::WindowState state) {
|
||||||
void MainWindow::psUpdateMargins() {
|
void MainWindow::psUpdateMargins() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::customNotificationCreated(QWidget *notification) {
|
|
||||||
_customNotifications.insert(object_ptr<CustomNotificationHandle>(notification));
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::customNotificationDestroyed(CustomNotificationHandle *handle) {
|
|
||||||
_customNotifications.erase(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::activateCustomNotifications() {
|
|
||||||
for (auto handle : _customNotifications) {
|
|
||||||
handle->activate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::updateGlobalMenuHook() {
|
void MainWindow::updateGlobalMenuHook() {
|
||||||
if (!App::wnd() || !positionInited()) return;
|
if (!App::wnd() || !positionInited()) return;
|
||||||
|
|
||||||
|
|
|
@ -396,19 +396,14 @@ void finish() {
|
||||||
objc_finish();
|
objc_finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TransparentWindowsSupported(QPoint globalPosition) {
|
void StartTranslucentPaint(QPainter &p, QPaintEvent *e) {
|
||||||
return true;
|
#ifdef OS_MAC_OLD
|
||||||
|
p.setCompositionMode(QPainter::CompositionMode_Source);
|
||||||
|
p.fillRect(e->rect(), Qt::transparent);
|
||||||
|
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
||||||
|
#endif // OS_MAC_OLD
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ThirdParty {
|
|
||||||
|
|
||||||
void start() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void finish() {
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ThirdParty
|
|
||||||
} // namespace Platform
|
} // namespace Platform
|
||||||
|
|
||||||
void psNewVersion() {
|
void psNewVersion() {
|
||||||
|
|
|
@ -19,6 +19,23 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
#include "platform/mac/specific_mac_p.h"
|
#include "platform/mac/specific_mac_p.h"
|
||||||
|
|
||||||
|
namespace Platform {
|
||||||
|
|
||||||
|
inline bool TranslucentWindowsSupported(QPoint globalPosition) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace ThirdParty {
|
||||||
|
|
||||||
|
inline void start() {
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void finish() {
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ThirdParty
|
||||||
|
} // namespace Platform
|
||||||
|
|
||||||
inline QString psServerPrefix() {
|
inline QString psServerPrefix() {
|
||||||
#ifndef OS_MAC_STORE
|
#ifndef OS_MAC_STORE
|
||||||
return qsl("/tmp/");
|
return qsl("/tmp/");
|
||||||
|
|
|
@ -215,11 +215,25 @@ void InitOnTopPanel(QWidget *panel) {
|
||||||
[platformPanel setFloatingPanel:YES];
|
[platformPanel setFloatingPanel:YES];
|
||||||
[platformPanel setHidesOnDeactivate:NO];
|
[platformPanel setHidesOnDeactivate:NO];
|
||||||
|
|
||||||
if (auto window = App::wnd()) {
|
objc_ignoreApplicationActivationRightNow();
|
||||||
window->customNotificationCreated(panel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
objc_ignoreApplicationActivationRightNow();
|
void DeInitOnTopPanel(QWidget *panel) {
|
||||||
|
auto platformWindow = [reinterpret_cast<NSView*>(panel->winId()) window];
|
||||||
|
t_assert([platformWindow isKindOfClass:[NSPanel class]]);
|
||||||
|
|
||||||
|
auto platformPanel = static_cast<NSPanel*>(platformWindow);
|
||||||
|
auto newBehavior = ([platformPanel collectionBehavior] & (~NSWindowCollectionBehaviorCanJoinAllSpaces)) | NSWindowCollectionBehaviorMoveToActiveSpace;
|
||||||
|
[platformPanel setCollectionBehavior:newBehavior];
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReInitOnTopPanel(QWidget *panel) {
|
||||||
|
auto platformWindow = [reinterpret_cast<NSView*>(panel->winId()) window];
|
||||||
|
t_assert([platformWindow isKindOfClass:[NSPanel class]]);
|
||||||
|
|
||||||
|
auto platformPanel = static_cast<NSPanel*>(platformWindow);
|
||||||
|
auto newBehavior = ([platformPanel collectionBehavior] & (~NSWindowCollectionBehaviorMoveToActiveSpace)) | NSWindowCollectionBehaviorCanJoinAllSpaces;
|
||||||
|
[platformPanel setCollectionBehavior:newBehavior];
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Platform
|
} // namespace Platform
|
||||||
|
|
|
@ -34,9 +34,11 @@ void start();
|
||||||
void finish();
|
void finish();
|
||||||
|
|
||||||
void SetWatchingMediaKeys(bool watching);
|
void SetWatchingMediaKeys(bool watching);
|
||||||
bool TransparentWindowsSupported(QPoint globalPosition);
|
bool TranslucentWindowsSupported(QPoint globalPosition);
|
||||||
|
void StartTranslucentPaint(QPainter &p, QPaintEvent *e);
|
||||||
void InitOnTopPanel(QWidget *panel);
|
void InitOnTopPanel(QWidget *panel);
|
||||||
|
void DeInitOnTopPanel(QWidget *panel);
|
||||||
|
void ReInitOnTopPanel(QWidget *panel);
|
||||||
|
|
||||||
namespace ThirdParty {
|
namespace ThirdParty {
|
||||||
|
|
||||||
|
|
|
@ -527,16 +527,6 @@ void finish() {
|
||||||
EventFilter::destroy();
|
EventFilter::destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetWatchingMediaKeys(bool watching) {
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TransparentWindowsSupported(QPoint globalPosition) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitOnTopPanel(QWidget *panel) {
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace ThirdParty {
|
namespace ThirdParty {
|
||||||
|
|
||||||
void start() {
|
void start() {
|
||||||
|
|
|
@ -22,6 +22,29 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
|
namespace Platform {
|
||||||
|
|
||||||
|
inline void SetWatchingMediaKeys(bool watching) {
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool TranslucentWindowsSupported(QPoint globalPosition) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void StartTranslucentPaint(QPainter &p, QPaintEvent *e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void InitOnTopPanel(QWidget *panel) {
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void DeInitOnTopPanel(QWidget *panel) {
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void ReInitOnTopPanel(QWidget *panel) {
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Platform
|
||||||
|
|
||||||
inline QString psServerPrefix() {
|
inline QString psServerPrefix() {
|
||||||
return qsl("Global\\");
|
return qsl("Global\\");
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,11 +107,9 @@ PopupMenu::Actions &PopupMenu::actions() {
|
||||||
void PopupMenu::paintEvent(QPaintEvent *e) {
|
void PopupMenu::paintEvent(QPaintEvent *e) {
|
||||||
Painter p(this);
|
Painter p(this);
|
||||||
|
|
||||||
#ifdef OS_MAC_OLD
|
if (_useTransparency) {
|
||||||
p.setCompositionMode(QPainter::CompositionMode_Source);
|
Platform::StartTranslucentPaint(p, e);
|
||||||
p.fillRect(e->rect(), Qt::transparent);
|
}
|
||||||
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
|
||||||
#endif // OS_MAC_OLD
|
|
||||||
|
|
||||||
auto ms = getms();
|
auto ms = getms();
|
||||||
if (_a_show.animating(ms)) {
|
if (_a_show.animating(ms)) {
|
||||||
|
@ -425,7 +423,8 @@ void PopupMenu::showMenu(const QPoint &p, PopupMenu *parent, TriggeredSource sou
|
||||||
auto origin = PanelAnimation::Origin::TopLeft;
|
auto origin = PanelAnimation::Origin::TopLeft;
|
||||||
auto w = p - QPoint(0, _padding.top());
|
auto w = p - QPoint(0, _padding.top());
|
||||||
auto r = Sandbox::screenGeometry(p);
|
auto r = Sandbox::screenGeometry(p);
|
||||||
_useTransparency = Platform::TransparentWindowsSupported(p);
|
_useTransparency = Platform::TranslucentWindowsSupported(p);
|
||||||
|
setAttribute(Qt::WA_OpaquePaintEvent, !_useTransparency);
|
||||||
handleCompositingUpdate();
|
handleCompositingUpdate();
|
||||||
if (rtl()) {
|
if (rtl()) {
|
||||||
if (w.x() - width() < r.x() - _padding.left()) {
|
if (w.x() - width() < r.x() - _padding.left()) {
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "styles/style_widgets.h"
|
#include "styles/style_widgets.h"
|
||||||
|
#include "platform/platform_specific.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
|
||||||
|
@ -45,17 +46,17 @@ AbstractTooltipShower::~AbstractTooltipShower() {
|
||||||
Tooltip::Tooltip() : TWidget(nullptr) {
|
Tooltip::Tooltip() : TWidget(nullptr) {
|
||||||
TooltipInstance = this;
|
TooltipInstance = this;
|
||||||
|
|
||||||
setWindowFlags(Qt::WindowFlags(Qt::FramelessWindowHint) | Qt::BypassWindowManagerHint | Qt::ToolTip | Qt::NoDropShadowWindowHint);
|
setWindowFlags(Qt::WindowFlags(Qt::FramelessWindowHint) | Qt::BypassWindowManagerHint | Qt::NoDropShadowWindowHint | Qt::ToolTip);
|
||||||
setAttribute(Qt::WA_NoSystemBackground, true);
|
setAttribute(Qt::WA_NoSystemBackground, true);
|
||||||
setAttribute(Qt::WA_TranslucentBackground, true);
|
setAttribute(Qt::WA_TranslucentBackground, true);
|
||||||
|
|
||||||
_showTimer.setSingleShot(true);
|
_showTimer.setCallback([this] { performShow(); });
|
||||||
connect(&_showTimer, SIGNAL(timeout()), this, SLOT(onShow()));
|
_hideByLeaveTimer.setCallback([this] { Hide(); });
|
||||||
|
|
||||||
connect(App::wnd()->windowHandle(), SIGNAL(activeChanged()), this, SLOT(onWndActiveChanged()));
|
connect(App::wnd()->windowHandle(), SIGNAL(activeChanged()), this, SLOT(onWndActiveChanged()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tooltip::onShow() {
|
void Tooltip::performShow() {
|
||||||
if (_shower) {
|
if (_shower) {
|
||||||
auto text = _shower->tooltipWindowActive() ? _shower->tooltipText() : QString();
|
auto text = _shower->tooltipWindowActive() ? _shower->tooltipText() : QString();
|
||||||
if (text.isEmpty()) {
|
if (text.isEmpty()) {
|
||||||
|
@ -74,9 +75,9 @@ void Tooltip::onWndActiveChanged() {
|
||||||
|
|
||||||
bool Tooltip::eventFilter(QObject *o, QEvent *e) {
|
bool Tooltip::eventFilter(QObject *o, QEvent *e) {
|
||||||
if (e->type() == QEvent::Leave) {
|
if (e->type() == QEvent::Leave) {
|
||||||
_hideByLeaveTimer.start(10);
|
_hideByLeaveTimer.callOnce(10);
|
||||||
} else if (e->type() == QEvent::Enter) {
|
} else if (e->type() == QEvent::Enter) {
|
||||||
_hideByLeaveTimer.stop();
|
_hideByLeaveTimer.cancel();
|
||||||
} else if (e->type() == QEvent::MouseMove) {
|
} else if (e->type() == QEvent::MouseMove) {
|
||||||
if ((QCursor::pos() - _point).manhattanLength() > QApplication::startDragDistance()) {
|
if ((QCursor::pos() - _point).manhattanLength() > QApplication::startDragDistance()) {
|
||||||
Hide();
|
Hide();
|
||||||
|
@ -85,10 +86,6 @@ bool Tooltip::eventFilter(QObject *o, QEvent *e) {
|
||||||
return TWidget::eventFilter(o, e);
|
return TWidget::eventFilter(o, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tooltip::onHideByLeave() {
|
|
||||||
Hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
Tooltip::~Tooltip() {
|
Tooltip::~Tooltip() {
|
||||||
if (TooltipInstance == this) {
|
if (TooltipInstance == this) {
|
||||||
TooltipInstance = 0;
|
TooltipInstance = 0;
|
||||||
|
@ -96,10 +93,7 @@ Tooltip::~Tooltip() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tooltip::popup(const QPoint &m, const QString &text, const style::Tooltip *st) {
|
void Tooltip::popup(const QPoint &m, const QString &text, const style::Tooltip *st) {
|
||||||
if (!_hideByLeaveTimer.isSingleShot()) {
|
if (!_isEventFilter) {
|
||||||
_hideByLeaveTimer.setSingleShot(true);
|
|
||||||
connect(&_hideByLeaveTimer, SIGNAL(timeout()), this, SLOT(onHideByLeave()));
|
|
||||||
|
|
||||||
QCoreApplication::instance()->installEventFilter(this);
|
QCoreApplication::instance()->installEventFilter(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +101,7 @@ void Tooltip::popup(const QPoint &m, const QString &text, const style::Tooltip *
|
||||||
_st = st;
|
_st = st;
|
||||||
_text = Text(_st->textStyle, text, _textPlainOptions, _st->widthMax, true);
|
_text = Text(_st->textStyle, text, _textPlainOptions, _st->widthMax, true);
|
||||||
|
|
||||||
_useTransparency = Platform::TransparentWindowsSupported(_point);
|
_useTransparency = Platform::TranslucentWindowsSupported(_point);
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent, !_useTransparency);
|
setAttribute(Qt::WA_OpaquePaintEvent, !_useTransparency);
|
||||||
|
|
||||||
int32 addw = 2 * st::lineWidth + _st->textPadding.left() + _st->textPadding.right();
|
int32 addw = 2 * st::lineWidth + _st->textPadding.left() + _st->textPadding.right();
|
||||||
|
@ -150,18 +144,16 @@ void Tooltip::popup(const QPoint &m, const QString &text, const style::Tooltip *
|
||||||
|
|
||||||
setGeometry(QRect(p, s));
|
setGeometry(QRect(p, s));
|
||||||
|
|
||||||
_hideByLeaveTimer.stop();
|
_hideByLeaveTimer.cancel();
|
||||||
show();
|
show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tooltip::paintEvent(QPaintEvent *e) {
|
void Tooltip::paintEvent(QPaintEvent *e) {
|
||||||
Painter p(this);
|
Painter p(this);
|
||||||
|
|
||||||
#ifdef OS_MAC_OLD
|
if (_useTransparency) {
|
||||||
p.setCompositionMode(QPainter::CompositionMode_Source);
|
Platform::StartTranslucentPaint(p, e);
|
||||||
p.fillRect(e->rect(), Qt::transparent);
|
}
|
||||||
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
|
||||||
#endif // OS_MAC_OLD
|
|
||||||
|
|
||||||
if (_useTransparency) {
|
if (_useTransparency) {
|
||||||
p.setPen(_st->textBorder);
|
p.setPen(_st->textBorder);
|
||||||
|
@ -194,17 +186,17 @@ void Tooltip::Show(int32 delay, const AbstractTooltipShower *shower) {
|
||||||
}
|
}
|
||||||
TooltipInstance->_shower = shower;
|
TooltipInstance->_shower = shower;
|
||||||
if (delay >= 0) {
|
if (delay >= 0) {
|
||||||
TooltipInstance->_showTimer.start(delay);
|
TooltipInstance->_showTimer.callOnce(delay);
|
||||||
} else {
|
} else {
|
||||||
TooltipInstance->onShow();
|
TooltipInstance->performShow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tooltip::Hide() {
|
void Tooltip::Hide() {
|
||||||
if (auto instance = TooltipInstance) {
|
if (auto instance = TooltipInstance) {
|
||||||
TooltipInstance = nullptr;
|
TooltipInstance = nullptr;
|
||||||
instance->_showTimer.stop();
|
instance->_showTimer.cancel();
|
||||||
instance->_hideByLeaveTimer.stop();
|
instance->_hideByLeaveTimer.cancel();
|
||||||
instance->hide();
|
instance->hide();
|
||||||
instance->deleteLater();
|
instance->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "base/timer.h"
|
||||||
|
|
||||||
namespace style {
|
namespace style {
|
||||||
struct Tooltip;
|
struct Tooltip;
|
||||||
} // namespace style
|
} // namespace style
|
||||||
|
@ -41,9 +43,7 @@ public:
|
||||||
static void Hide();
|
static void Hide();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onShow();
|
|
||||||
void onWndActiveChanged();
|
void onWndActiveChanged();
|
||||||
void onHideByLeave();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent *e) override;
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
@ -52,6 +52,8 @@ protected:
|
||||||
bool eventFilter(QObject *o, QEvent *e) override;
|
bool eventFilter(QObject *o, QEvent *e) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void performShow();
|
||||||
|
|
||||||
Tooltip();
|
Tooltip();
|
||||||
~Tooltip();
|
~Tooltip();
|
||||||
|
|
||||||
|
@ -59,14 +61,15 @@ private:
|
||||||
|
|
||||||
friend class AbstractTooltipShower;
|
friend class AbstractTooltipShower;
|
||||||
const AbstractTooltipShower *_shower = nullptr;
|
const AbstractTooltipShower *_shower = nullptr;
|
||||||
QTimer _showTimer;
|
base::Timer _showTimer;
|
||||||
|
|
||||||
Text _text;
|
Text _text;
|
||||||
QPoint _point;
|
QPoint _point;
|
||||||
|
|
||||||
const style::Tooltip *_st = nullptr;
|
const style::Tooltip *_st = nullptr;
|
||||||
|
|
||||||
QTimer _hideByLeaveTimer;
|
base::Timer _hideByLeaveTimer;
|
||||||
|
bool _isEventFilter = false;
|
||||||
bool _useTransparency = true;
|
bool _useTransparency = true;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue