mirror of
https://github.com/vale981/tdesktop
synced 2025-03-06 02:01:40 -05:00
Add workaround for macOS leaveEvent() bugs.
On macOS sometimes when mouse leaves the window we don't receive leaveEvent() calls in the nested widgets, like buttons, only for the window itself.
This commit is contained in:
parent
d93c1ccbaa
commit
44e94bfbf5
9 changed files with 66 additions and 4 deletions
|
@ -272,7 +272,6 @@ public:
|
|||
using reference = pair_type&;
|
||||
using const_reference = const pair_type&;
|
||||
|
||||
class const_iterator;
|
||||
class iterator : public iterator_base {
|
||||
public:
|
||||
using iterator_base::iterator_base;
|
||||
|
@ -292,7 +291,6 @@ public:
|
|||
}
|
||||
|
||||
};
|
||||
class const_reverse_iterator;
|
||||
class reverse_iterator : public reverse_iterator_base {
|
||||
public:
|
||||
using reverse_iterator_base::reverse_iterator_base;
|
||||
|
|
|
@ -25,6 +25,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
#include "chat_helpers/tabbed_selector.h"
|
||||
#include "window/window_controller.h"
|
||||
#include "mainwindow.h"
|
||||
#include "messenger.h"
|
||||
|
||||
namespace ChatHelpers {
|
||||
namespace {
|
||||
|
@ -178,6 +179,7 @@ void TabbedPanel::moveByBottom() {
|
|||
}
|
||||
|
||||
void TabbedPanel::enterEventHook(QEvent *e) {
|
||||
Messenger::Instance().registerLeaveSubscription(this);
|
||||
showAnimated();
|
||||
}
|
||||
|
||||
|
@ -189,6 +191,7 @@ bool TabbedPanel::preventAutoHide() const {
|
|||
}
|
||||
|
||||
void TabbedPanel::leaveEventHook(QEvent *e) {
|
||||
Messenger::Instance().unregisterLeaveSubscription(this);
|
||||
if (preventAutoHide()) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
*/
|
||||
#include "messenger.h"
|
||||
|
||||
#include <rpl/complete.h>
|
||||
#include "data/data_photo.h"
|
||||
#include "data/data_document.h"
|
||||
#include "base/timer.h"
|
||||
|
@ -995,6 +996,36 @@ QPoint Messenger::getPointForCallPanelCenter() const {
|
|||
return QApplication::desktop()->screenGeometry().center();
|
||||
}
|
||||
|
||||
// macOS Qt bug workaround, sometimes no leaveEvent() gets to the nested widgets.
|
||||
void Messenger::registerLeaveSubscription(QWidget *widget) {
|
||||
#ifdef Q_OS_MAC
|
||||
if (auto topLevel = widget->window()) {
|
||||
if (topLevel == _window.get()) {
|
||||
auto guarded = weak(widget);
|
||||
auto subscription = _window->leaveEvents()
|
||||
| rpl::start_with_next([guarded] {
|
||||
if (auto w = guarded.data()) {
|
||||
QEvent ev(QEvent::Leave);
|
||||
QGuiApplication::sendEvent(w, &ev);
|
||||
}
|
||||
});
|
||||
_leaveSubscriptions.emplace_back(guarded, std::move(subscription));
|
||||
}
|
||||
}
|
||||
#endif // Q_OS_MAC
|
||||
}
|
||||
|
||||
void Messenger::unregisterLeaveSubscription(QWidget *widget) {
|
||||
#ifdef Q_OS_MAC
|
||||
_leaveSubscriptions = std::move(
|
||||
_leaveSubscriptions
|
||||
) | ranges::action::remove_if([&](const LeaveSubscription &subscription) {
|
||||
auto pointer = subscription.pointer.data();
|
||||
return !pointer || (pointer == widget);
|
||||
});
|
||||
#endif // Q_OS_MAC
|
||||
}
|
||||
|
||||
void Messenger::QuitAttempt() {
|
||||
auto prevents = false;
|
||||
if (!Sandbox::isSavingSession() && AuthSession::Exists()) {
|
||||
|
|
|
@ -174,6 +174,9 @@ public:
|
|||
return _passcodedChanged;
|
||||
}
|
||||
|
||||
void registerLeaveSubscription(QWidget *widget);
|
||||
void unregisterLeaveSubscription(QWidget *widget);
|
||||
|
||||
void quitPreventFinished();
|
||||
|
||||
void handleAppActivated();
|
||||
|
@ -246,4 +249,14 @@ private:
|
|||
|
||||
base::DelayedCallTimer _callDelayedTimer;
|
||||
|
||||
struct LeaveSubscription {
|
||||
LeaveSubscription(QPointer<QWidget> pointer, rpl::lifetime &&subscription)
|
||||
: pointer(pointer), subscription(std::move(subscription)) {
|
||||
}
|
||||
|
||||
QPointer<QWidget> pointer;
|
||||
rpl::lifetime subscription;
|
||||
};
|
||||
std::vector<LeaveSubscription> _leaveSubscriptions;
|
||||
|
||||
};
|
||||
|
|
|
@ -135,7 +135,7 @@ template <typename Value, typename Error>
|
|||
inline void type_erased_handlers<Value, Error>::terminate() {
|
||||
if (!_terminated) {
|
||||
_terminated = true;
|
||||
details::take(_lifetime).destroy();
|
||||
_lifetime.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
|
||||
#include <rpl/filter.h>
|
||||
#include <rpl/mappers.h>
|
||||
#include "messenger.h"
|
||||
|
||||
namespace Ui {
|
||||
|
||||
|
@ -109,10 +110,12 @@ void AbstractButton::setOver(bool over, StateChangeSource source) {
|
|||
if (over && !(_state & StateFlag::Over)) {
|
||||
auto was = _state;
|
||||
_state |= StateFlag::Over;
|
||||
Messenger::Instance().registerLeaveSubscription(this);
|
||||
onStateChanged(was, source);
|
||||
} else if (!over && (_state & StateFlag::Over)) {
|
||||
auto was = _state;
|
||||
_state &= ~State(StateFlag::Over);
|
||||
Messenger::Instance().unregisterLeaveSubscription(this);
|
||||
onStateChanged(was, source);
|
||||
}
|
||||
updateCursor();
|
||||
|
|
|
@ -169,7 +169,8 @@ void HistoryDownButton::setUnreadCount(int unreadCount) {
|
|||
}
|
||||
}
|
||||
|
||||
EmojiButton::EmojiButton(QWidget *parent, const style::IconButton &st) : RippleButton(parent, st.ripple)
|
||||
EmojiButton::EmojiButton(QWidget *parent, const style::IconButton &st)
|
||||
: RippleButton(parent, st.ripple)
|
||||
, _st(st)
|
||||
, _a_loading(animation(this, &EmojiButton::step_loading)) {
|
||||
resize(_st.width, _st.height);
|
||||
|
|
|
@ -261,6 +261,14 @@ void MainWindow::resizeEvent(QResizeEvent *e) {
|
|||
updateControlsGeometry();
|
||||
}
|
||||
|
||||
rpl::producer<> MainWindow::leaveEvents() const {
|
||||
return _leaveEvents.events();
|
||||
}
|
||||
|
||||
void MainWindow::leaveEvent(QEvent *e) {
|
||||
_leaveEvents.fire({});
|
||||
}
|
||||
|
||||
void MainWindow::updateControlsGeometry() {
|
||||
auto bodyTop = 0;
|
||||
auto bodyWidth = width();
|
||||
|
|
|
@ -20,6 +20,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include <rpl/event_stream.h>
|
||||
#include "window/window_title.h"
|
||||
#include "base/timer.h"
|
||||
|
||||
|
@ -96,6 +97,8 @@ public:
|
|||
return _dragFinished;
|
||||
}
|
||||
|
||||
rpl::producer<> leaveEvents() const;
|
||||
|
||||
public slots:
|
||||
bool minimizeToTray();
|
||||
void updateGlobalMenu() {
|
||||
|
@ -104,6 +107,7 @@ public slots:
|
|||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *e) override;
|
||||
void leaveEvent(QEvent *e) override;
|
||||
|
||||
void savePosition(Qt::WindowState state = Qt::WindowActive);
|
||||
void handleStateChanged(Qt::WindowState state);
|
||||
|
@ -187,6 +191,7 @@ private:
|
|||
base::Timer _inactivePressTimer;
|
||||
|
||||
base::Observable<void> _dragFinished;
|
||||
rpl::event_stream<> _leaveEvents;
|
||||
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue