mirror of
https://github.com/kotatogram/kotatogram-desktop
synced 2025-08-31 14:45:14 +00:00
Fix postponed calls from crl::on_main() on macOS.
In libdispatch crl::on_main() implementation we bypass Application::notify() frame. So we handle event loop nesting control manually by wrapping all invokations done through crl::on_main() with the same methods we do from Application::notify().
This commit is contained in:
@@ -416,12 +416,11 @@ void Application::postponeCall(FnMut<void()> &&callable) {
|
||||
});
|
||||
}
|
||||
|
||||
bool Application::notify(QObject *receiver, QEvent *e) {
|
||||
if (QThread::currentThreadId() != _mainThreadId) {
|
||||
return QApplication::notify(receiver, e);
|
||||
}
|
||||
void Application::incrementEventNestingLevel() {
|
||||
++_eventNestingLevel;
|
||||
const auto result = QApplication::notify(receiver, e);
|
||||
}
|
||||
|
||||
void Application::decrementEventNestingLevel() {
|
||||
if (_eventNestingLevel == _loopNestingLevel) {
|
||||
_loopNestingLevel = _previousLoopNestingLevels.back();
|
||||
_previousLoopNestingLevels.pop_back();
|
||||
@@ -429,7 +428,22 @@ bool Application::notify(QObject *receiver, QEvent *e) {
|
||||
const auto processTillLevel = _eventNestingLevel - 1;
|
||||
processPostponedCalls(processTillLevel);
|
||||
_eventNestingLevel = processTillLevel;
|
||||
return result;
|
||||
}
|
||||
|
||||
void Application::registerEnterFromEventLoop() {
|
||||
if (_eventNestingLevel > _loopNestingLevel) {
|
||||
_previousLoopNestingLevels.push_back(_loopNestingLevel);
|
||||
_loopNestingLevel = _eventNestingLevel;
|
||||
}
|
||||
}
|
||||
|
||||
bool Application::notify(QObject *receiver, QEvent *e) {
|
||||
if (QThread::currentThreadId() != _mainThreadId) {
|
||||
return QApplication::notify(receiver, e);
|
||||
}
|
||||
|
||||
const auto wrap = createEventNestingLevel();
|
||||
return QApplication::notify(receiver, e);
|
||||
}
|
||||
|
||||
void Application::processPostponedCalls(int level) {
|
||||
@@ -448,10 +462,7 @@ bool Application::nativeEventFilter(
|
||||
const QByteArray &eventType,
|
||||
void *message,
|
||||
long *result) {
|
||||
if (_eventNestingLevel > _loopNestingLevel) {
|
||||
_previousLoopNestingLevels.push_back(_loopNestingLevel);
|
||||
_loopNestingLevel = _eventNestingLevel;
|
||||
}
|
||||
registerEnterFromEventLoop();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@@ -28,6 +28,11 @@ public:
|
||||
|
||||
void postponeCall(FnMut<void()> &&callable);
|
||||
bool notify(QObject *receiver, QEvent *e) override;
|
||||
void registerEnterFromEventLoop();
|
||||
auto createEventNestingLevel() {
|
||||
incrementEventNestingLevel();
|
||||
return gsl::finally([=] { decrementEventNestingLevel(); });
|
||||
}
|
||||
|
||||
void activateWindowDelayed(not_null<QWidget*> widget);
|
||||
void pauseDelayedWindowActivations();
|
||||
@@ -65,6 +70,8 @@ private:
|
||||
FnMut<void()> callable;
|
||||
};
|
||||
|
||||
void incrementEventNestingLevel();
|
||||
void decrementEventNestingLevel();
|
||||
bool nativeEventFilter(
|
||||
const QByteArray &eventType,
|
||||
void *message,
|
||||
|
@@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "core/main_queue_processor.h"
|
||||
|
||||
#include "application.h"
|
||||
|
||||
namespace Core {
|
||||
namespace {
|
||||
|
||||
@@ -38,15 +40,6 @@ void ProcessorEvent::process() {
|
||||
_callable(_argument);
|
||||
}
|
||||
|
||||
void ProcessMainQueue(void (*callable)(void*), void *argument) {
|
||||
QMutexLocker lock(&ProcessorMutex);
|
||||
|
||||
if (ProcessorInstance) {
|
||||
const auto event = new ProcessorEvent(callable, argument);
|
||||
QCoreApplication::postEvent(ProcessorInstance, event);
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessObservables() {
|
||||
Global::RefHandleObservables().call();
|
||||
}
|
||||
@@ -55,7 +48,20 @@ void ProcessObservables() {
|
||||
|
||||
MainQueueProcessor::MainQueueProcessor() {
|
||||
acquire();
|
||||
crl::init_main_queue(ProcessMainQueue);
|
||||
|
||||
crl::init_main_queue([](void (*callable)(void*), void *argument) {
|
||||
QMutexLocker lock(&ProcessorMutex);
|
||||
|
||||
if (ProcessorInstance) {
|
||||
const auto event = new ProcessorEvent(callable, argument);
|
||||
QCoreApplication::postEvent(ProcessorInstance, event);
|
||||
}
|
||||
});
|
||||
crl::wrap_main_queue([](void (*callable)(void*), void *argument) {
|
||||
App().registerEnterFromEventLoop();
|
||||
const auto wrap = App().createEventNestingLevel();
|
||||
callable(argument);
|
||||
});
|
||||
|
||||
base::InitObservables(ProcessObservables);
|
||||
}
|
||||
|
2
Telegram/ThirdParty/crl
vendored
2
Telegram/ThirdParty/crl
vendored
Submodule Telegram/ThirdParty/crl updated: 4291015efa...9b7c6b5d9f
Reference in New Issue
Block a user