diff --git a/Telegram/SourceFiles/calls/calls_panel.cpp b/Telegram/SourceFiles/calls/calls_panel.cpp index c62fd32f65..0ae43869bd 100644 --- a/Telegram/SourceFiles/calls/calls_panel.cpp +++ b/Telegram/SourceFiles/calls/calls_panel.cpp @@ -184,7 +184,7 @@ void Panel::refreshCallbacks() { } 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_NoSystemBackground, true); setAttribute(Qt::WA_TranslucentBackground, true); @@ -267,8 +267,9 @@ bool Panel::isGoodUserPhoto(PhotoData *photo) { void Panel::initGeometry() { auto center = Messenger::Instance().getPointForCallPanelCenter(); - _useTransparency = Platform::TransparentWindowsSupported(center); - _padding = _useTransparency ? st::callShadow.extend : style::margins(); + _useTransparency = Platform::TranslucentWindowsSupported(center); + 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; auto screen = QApplication::desktop()->screenGeometry(center); auto rect = QRect(0, 0, st::callWidth, st::callHeight); @@ -359,10 +360,17 @@ void Panel::updateStatusGeometry() { void Panel::paintEvent(QPaintEvent *e) { Painter p(this); if (_useTransparency) { + Platform::StartTranslucentPaint(p, e); p.drawPixmapLeft(0, 0, width(), _cache); } else { - p.drawPixmapLeft(0, 0, width(), _userPhoto); - p.fillRect(myrtlrect(0, st::callWidth, width(), height() - st::callWidth), st::callBg); + p.drawPixmapLeft(_padding.left(), _padding.top(), width(), _userPhoto); + 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()) { @@ -381,10 +389,16 @@ void Panel::paintEvent(QPaintEvent *e) { void Panel::mousePressEvent(QMouseEvent *e) { auto dragArea = myrtlrect(_padding.left(), _padding.top(), st::callWidth, st::callWidth); - if (e->button() == Qt::LeftButton && dragArea.contains(e->pos())) { - _dragging = true; - _dragStartMousePosition = e->globalPos(); - _dragStartMyPosition = QPoint(x(), y()); + if (e->button() == Qt::LeftButton) { + if (dragArea.contains(e->pos())) { + _dragging = true; + _dragStartMousePosition = e->globalPos(); + _dragStartMyPosition = QPoint(x(), y()); + } else if (!rect().contains(e->pos())) { + if (_call && _call->state() == State::Established) { + hideDeactivated(); + } + } } } @@ -458,8 +472,15 @@ void Panel::stateChanged(State state) { if (_fingerprint.empty() && _call && _call->isKeyShaForFingerprintReady()) { fillFingerprint(); } - if (state == State::Established && !isActiveWindow()) { - hideDeactivated(); + if ((state == State::Starting) || (state == State::WaitingIncoming)) { + Platform::ReInitOnTopPanel(this); + } else { + Platform::DeInitOnTopPanel(this); + } + if (state == State::Established) { + if (!isActiveWindow()) { + hideDeactivated(); + } } } diff --git a/Telegram/SourceFiles/platform/linux/specific_linux.cpp b/Telegram/SourceFiles/platform/linux/specific_linux.cpp index 157c033834..3f2192f5c2 100644 --- a/Telegram/SourceFiles/platform/linux/specific_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/specific_linux.cpp @@ -377,10 +377,7 @@ void finish() { _psEventFilter = nullptr; } -void SetWatchingMediaKeys(bool watching) { -} - -bool TransparentWindowsSupported(QPoint globalPosition) { +bool TranslucentWindowsSupported(QPoint globalPosition) { if (auto app = static_cast(QCoreApplication::instance())) { if (auto native = app->platformNativeInterface()) { if (auto desktop = QApplication::desktop()) { @@ -405,9 +402,6 @@ bool TransparentWindowsSupported(QPoint globalPosition) { return false; } -void InitOnTopPanel(QWidget *panel) { -} - namespace ThirdParty { void start() { diff --git a/Telegram/SourceFiles/platform/linux/specific_linux.h b/Telegram/SourceFiles/platform/linux/specific_linux.h index 0117f4a07f..290aa814d5 100644 --- a/Telegram/SourceFiles/platform/linux/specific_linux.h +++ b/Telegram/SourceFiles/platform/linux/specific_linux.h @@ -20,6 +20,25 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include #include +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() { return qsl("/tmp/"); } diff --git a/Telegram/SourceFiles/platform/mac/main_window_mac.h b/Telegram/SourceFiles/platform/mac/main_window_mac.h index 770cf00568..911a19fa8f 100644 --- a/Telegram/SourceFiles/platform/mac/main_window_mac.h +++ b/Telegram/SourceFiles/platform/mac/main_window_mac.h @@ -48,9 +48,6 @@ public: return _customTitleHeight; } - // It is placed here while the window handles activeSpaceDidChange event. - void customNotificationCreated(QWidget *notification); - ~MainWindow(); class Private; @@ -104,16 +101,9 @@ private: void updateTitleCounter(); void updateIconCounters(); - class CustomNotificationHandle; - friend class CustomNotificationHandle; - void customNotificationDestroyed(CustomNotificationHandle *handle); - void activateCustomNotifications(); - friend class Private; std::unique_ptr _private; - std::set _customNotifications; - mutable bool psIdle; mutable QTimer psIdleTimer; diff --git a/Telegram/SourceFiles/platform/mac/main_window_mac.mm b/Telegram/SourceFiles/platform/mac/main_window_mac.mm index 639f8b8c70..eff6609bef 100644 --- a/Telegram/SourceFiles/platform/mac/main_window_mac.mm +++ b/Telegram/SourceFiles/platform/mac/main_window_mac.mm @@ -73,7 +73,6 @@ public: void willEnterFullScreen(); void willExitFullScreen(); - void activateCustomNotifications(); 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(parent()); - NSWindow *wnd = [reinterpret_cast(widget->winId()) window]; - [wnd orderFront:wnd]; - } - - ~CustomNotificationHandle() { - if (auto window = App::wnd()) { - window->customNotificationDestroyed(this); - } - } - -}; - } // namespace Platform @implementation MainWindowObserver { @@ -126,7 +106,6 @@ public: } - (void) activeSpaceDidChange:(NSNotification *)aNotification { - _private->activateCustomNotifications(); } - (void) darkModeChanged:(NSNotification *)aNotification { @@ -211,10 +190,6 @@ void MainWindow::Private::willExitFullScreen() { _public->setTitleVisible(true); } -void MainWindow::Private::activateCustomNotifications() { - _public->activateCustomNotifications(); -} - void MainWindow::Private::enableShadow(WId winId) { // [[(NSView*)winId window] setStyleMask:NSBorderlessWindowMask]; // [[(NSView*)winId window] setHasShadow:YES]; @@ -527,20 +502,6 @@ void MainWindow::psUpdateSysMenu(Qt::WindowState state) { void MainWindow::psUpdateMargins() { } -void MainWindow::customNotificationCreated(QWidget *notification) { - _customNotifications.insert(object_ptr(notification)); -} - -void MainWindow::customNotificationDestroyed(CustomNotificationHandle *handle) { - _customNotifications.erase(handle); -} - -void MainWindow::activateCustomNotifications() { - for (auto handle : _customNotifications) { - handle->activate(); - } -} - void MainWindow::updateGlobalMenuHook() { if (!App::wnd() || !positionInited()) return; diff --git a/Telegram/SourceFiles/platform/mac/specific_mac.cpp b/Telegram/SourceFiles/platform/mac/specific_mac.cpp index 45cd8763df..b519e29b2b 100644 --- a/Telegram/SourceFiles/platform/mac/specific_mac.cpp +++ b/Telegram/SourceFiles/platform/mac/specific_mac.cpp @@ -396,19 +396,14 @@ void finish() { objc_finish(); } -bool TransparentWindowsSupported(QPoint globalPosition) { - return true; +void StartTranslucentPaint(QPainter &p, QPaintEvent *e) { +#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 void psNewVersion() { diff --git a/Telegram/SourceFiles/platform/mac/specific_mac.h b/Telegram/SourceFiles/platform/mac/specific_mac.h index 3804c688c6..7fc27c4547 100644 --- a/Telegram/SourceFiles/platform/mac/specific_mac.h +++ b/Telegram/SourceFiles/platform/mac/specific_mac.h @@ -19,6 +19,23 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #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() { #ifndef OS_MAC_STORE return qsl("/tmp/"); diff --git a/Telegram/SourceFiles/platform/mac/specific_mac_p.mm b/Telegram/SourceFiles/platform/mac/specific_mac_p.mm index 9751a4a816..3b5e54b705 100644 --- a/Telegram/SourceFiles/platform/mac/specific_mac_p.mm +++ b/Telegram/SourceFiles/platform/mac/specific_mac_p.mm @@ -215,13 +215,27 @@ void InitOnTopPanel(QWidget *panel) { [platformPanel setFloatingPanel:YES]; [platformPanel setHidesOnDeactivate:NO]; - if (auto window = App::wnd()) { - window->customNotificationCreated(panel); - } - objc_ignoreApplicationActivationRightNow(); } +void DeInitOnTopPanel(QWidget *panel) { + auto platformWindow = [reinterpret_cast(panel->winId()) window]; + t_assert([platformWindow isKindOfClass:[NSPanel class]]); + + auto platformPanel = static_cast(platformWindow); + auto newBehavior = ([platformPanel collectionBehavior] & (~NSWindowCollectionBehaviorCanJoinAllSpaces)) | NSWindowCollectionBehaviorMoveToActiveSpace; + [platformPanel setCollectionBehavior:newBehavior]; +} + +void ReInitOnTopPanel(QWidget *panel) { + auto platformWindow = [reinterpret_cast(panel->winId()) window]; + t_assert([platformWindow isKindOfClass:[NSPanel class]]); + + auto platformPanel = static_cast(platformWindow); + auto newBehavior = ([platformPanel collectionBehavior] & (~NSWindowCollectionBehaviorMoveToActiveSpace)) | NSWindowCollectionBehaviorCanJoinAllSpaces; + [platformPanel setCollectionBehavior:newBehavior]; +} + } // namespace Platform bool objc_darkMode() { diff --git a/Telegram/SourceFiles/platform/platform_specific.h b/Telegram/SourceFiles/platform/platform_specific.h index f5cca73ce5..afdac112ff 100644 --- a/Telegram/SourceFiles/platform/platform_specific.h +++ b/Telegram/SourceFiles/platform/platform_specific.h @@ -34,9 +34,11 @@ void start(); void finish(); void SetWatchingMediaKeys(bool watching); -bool TransparentWindowsSupported(QPoint globalPosition); - +bool TranslucentWindowsSupported(QPoint globalPosition); +void StartTranslucentPaint(QPainter &p, QPaintEvent *e); void InitOnTopPanel(QWidget *panel); +void DeInitOnTopPanel(QWidget *panel); +void ReInitOnTopPanel(QWidget *panel); namespace ThirdParty { diff --git a/Telegram/SourceFiles/platform/win/specific_win.cpp b/Telegram/SourceFiles/platform/win/specific_win.cpp index f452fcd4d4..8115b3fbdb 100644 --- a/Telegram/SourceFiles/platform/win/specific_win.cpp +++ b/Telegram/SourceFiles/platform/win/specific_win.cpp @@ -527,16 +527,6 @@ void finish() { EventFilter::destroy(); } -void SetWatchingMediaKeys(bool watching) { -} - -bool TransparentWindowsSupported(QPoint globalPosition) { - return true; -} - -void InitOnTopPanel(QWidget *panel) { -} - namespace ThirdParty { void start() { diff --git a/Telegram/SourceFiles/platform/win/specific_win.h b/Telegram/SourceFiles/platform/win/specific_win.h index 2d1f0a22d0..1d98dbff91 100644 --- a/Telegram/SourceFiles/platform/win/specific_win.h +++ b/Telegram/SourceFiles/platform/win/specific_win.h @@ -22,6 +22,29 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include +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() { return qsl("Global\\"); } diff --git a/Telegram/SourceFiles/ui/widgets/popup_menu.cpp b/Telegram/SourceFiles/ui/widgets/popup_menu.cpp index 24ccce5c5f..df9c281891 100644 --- a/Telegram/SourceFiles/ui/widgets/popup_menu.cpp +++ b/Telegram/SourceFiles/ui/widgets/popup_menu.cpp @@ -107,11 +107,9 @@ PopupMenu::Actions &PopupMenu::actions() { void PopupMenu::paintEvent(QPaintEvent *e) { Painter p(this); -#ifdef OS_MAC_OLD - p.setCompositionMode(QPainter::CompositionMode_Source); - p.fillRect(e->rect(), Qt::transparent); - p.setCompositionMode(QPainter::CompositionMode_SourceOver); -#endif // OS_MAC_OLD + if (_useTransparency) { + Platform::StartTranslucentPaint(p, e); + } auto ms = getms(); 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 w = p - QPoint(0, _padding.top()); auto r = Sandbox::screenGeometry(p); - _useTransparency = Platform::TransparentWindowsSupported(p); + _useTransparency = Platform::TranslucentWindowsSupported(p); + setAttribute(Qt::WA_OpaquePaintEvent, !_useTransparency); handleCompositingUpdate(); if (rtl()) { if (w.x() - width() < r.x() - _padding.left()) { diff --git a/Telegram/SourceFiles/ui/widgets/tooltip.cpp b/Telegram/SourceFiles/ui/widgets/tooltip.cpp index 7c63fe0b8d..bd1b9bf9e4 100644 --- a/Telegram/SourceFiles/ui/widgets/tooltip.cpp +++ b/Telegram/SourceFiles/ui/widgets/tooltip.cpp @@ -19,6 +19,7 @@ #include "mainwindow.h" #include "styles/style_widgets.h" +#include "platform/platform_specific.h" namespace Ui { @@ -45,17 +46,17 @@ AbstractTooltipShower::~AbstractTooltipShower() { Tooltip::Tooltip() : TWidget(nullptr) { 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_TranslucentBackground, true); - _showTimer.setSingleShot(true); - connect(&_showTimer, SIGNAL(timeout()), this, SLOT(onShow())); + _showTimer.setCallback([this] { performShow(); }); + _hideByLeaveTimer.setCallback([this] { Hide(); }); connect(App::wnd()->windowHandle(), SIGNAL(activeChanged()), this, SLOT(onWndActiveChanged())); } -void Tooltip::onShow() { +void Tooltip::performShow() { if (_shower) { auto text = _shower->tooltipWindowActive() ? _shower->tooltipText() : QString(); if (text.isEmpty()) { @@ -74,9 +75,9 @@ void Tooltip::onWndActiveChanged() { bool Tooltip::eventFilter(QObject *o, QEvent *e) { if (e->type() == QEvent::Leave) { - _hideByLeaveTimer.start(10); + _hideByLeaveTimer.callOnce(10); } else if (e->type() == QEvent::Enter) { - _hideByLeaveTimer.stop(); + _hideByLeaveTimer.cancel(); } else if (e->type() == QEvent::MouseMove) { if ((QCursor::pos() - _point).manhattanLength() > QApplication::startDragDistance()) { Hide(); @@ -85,10 +86,6 @@ bool Tooltip::eventFilter(QObject *o, QEvent *e) { return TWidget::eventFilter(o, e); } -void Tooltip::onHideByLeave() { - Hide(); -} - Tooltip::~Tooltip() { if (TooltipInstance == this) { TooltipInstance = 0; @@ -96,10 +93,7 @@ Tooltip::~Tooltip() { } void Tooltip::popup(const QPoint &m, const QString &text, const style::Tooltip *st) { - if (!_hideByLeaveTimer.isSingleShot()) { - _hideByLeaveTimer.setSingleShot(true); - connect(&_hideByLeaveTimer, SIGNAL(timeout()), this, SLOT(onHideByLeave())); - + if (!_isEventFilter) { QCoreApplication::instance()->installEventFilter(this); } @@ -107,7 +101,7 @@ void Tooltip::popup(const QPoint &m, const QString &text, const style::Tooltip * _st = st; _text = Text(_st->textStyle, text, _textPlainOptions, _st->widthMax, true); - _useTransparency = Platform::TransparentWindowsSupported(_point); + _useTransparency = Platform::TranslucentWindowsSupported(_point); setAttribute(Qt::WA_OpaquePaintEvent, !_useTransparency); 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)); - _hideByLeaveTimer.stop(); + _hideByLeaveTimer.cancel(); show(); } void Tooltip::paintEvent(QPaintEvent *e) { Painter p(this); -#ifdef OS_MAC_OLD - p.setCompositionMode(QPainter::CompositionMode_Source); - p.fillRect(e->rect(), Qt::transparent); - p.setCompositionMode(QPainter::CompositionMode_SourceOver); -#endif // OS_MAC_OLD + if (_useTransparency) { + Platform::StartTranslucentPaint(p, e); + } if (_useTransparency) { p.setPen(_st->textBorder); @@ -194,17 +186,17 @@ void Tooltip::Show(int32 delay, const AbstractTooltipShower *shower) { } TooltipInstance->_shower = shower; if (delay >= 0) { - TooltipInstance->_showTimer.start(delay); + TooltipInstance->_showTimer.callOnce(delay); } else { - TooltipInstance->onShow(); + TooltipInstance->performShow(); } } void Tooltip::Hide() { if (auto instance = TooltipInstance) { TooltipInstance = nullptr; - instance->_showTimer.stop(); - instance->_hideByLeaveTimer.stop(); + instance->_showTimer.cancel(); + instance->_hideByLeaveTimer.cancel(); instance->hide(); instance->deleteLater(); } diff --git a/Telegram/SourceFiles/ui/widgets/tooltip.h b/Telegram/SourceFiles/ui/widgets/tooltip.h index ee530798d9..134a93b12f 100644 --- a/Telegram/SourceFiles/ui/widgets/tooltip.h +++ b/Telegram/SourceFiles/ui/widgets/tooltip.h @@ -17,6 +17,8 @@ */ #pragma once +#include "base/timer.h" + namespace style { struct Tooltip; } // namespace style @@ -41,9 +43,7 @@ public: static void Hide(); private slots: - void onShow(); void onWndActiveChanged(); - void onHideByLeave(); protected: void paintEvent(QPaintEvent *e) override; @@ -52,6 +52,8 @@ protected: bool eventFilter(QObject *o, QEvent *e) override; private: + void performShow(); + Tooltip(); ~Tooltip(); @@ -59,14 +61,15 @@ private: friend class AbstractTooltipShower; const AbstractTooltipShower *_shower = nullptr; - QTimer _showTimer; + base::Timer _showTimer; Text _text; QPoint _point; const style::Tooltip *_st = nullptr; - QTimer _hideByLeaveTimer; + base::Timer _hideByLeaveTimer; + bool _isEventFilter = false; bool _useTransparency = true; };