Ignore activations from ~PopupMenu in file dialog event loops.

This commit is contained in:
John Preston 2018-12-26 13:54:49 +04:00
parent cfac261516
commit 874d76b16b
5 changed files with 67 additions and 17 deletions

View file

@ -455,6 +455,30 @@ bool Application::nativeEventFilter(
return false; return false;
} }
void Application::activateWindowDelayed(not_null<QWidget*> widget) {
if (_delayedActivationsPaused) {
return;
} else if (std::exchange(_windowForDelayedActivation, widget.get())) {
return;
}
crl::on_main(this, [=] {
if (const auto widget = base::take(_windowForDelayedActivation)) {
if (!widget->isHidden()) {
widget->activateWindow();
}
}
});
}
void Application::pauseDelayedWindowActivations() {
_windowForDelayedActivation = nullptr;
_delayedActivationsPaused = true;
}
void Application::resumeDelayedWindowActivations() {
_delayedActivationsPaused = false;
}
void Application::closeApplication() { void Application::closeApplication() {
if (App::launchState() == App::QuitProcessed) return; if (App::launchState() == App::QuitProcessed) return;
App::setLaunchState(App::QuitProcessed); App::setLaunchState(App::QuitProcessed);

View file

@ -29,6 +29,10 @@ public:
void postponeCall(FnMut<void()> &&callable); void postponeCall(FnMut<void()> &&callable);
bool notify(QObject *receiver, QEvent *e) override; bool notify(QObject *receiver, QEvent *e) override;
void activateWindowDelayed(not_null<QWidget*> widget);
void pauseDelayedWindowActivations();
void resumeDelayedWindowActivations();
~Application(); ~Application();
signals: signals:
@ -73,6 +77,9 @@ private:
std::vector<int> _previousLoopNestingLevels; std::vector<int> _previousLoopNestingLevels;
std::vector<PostponedCall> _postponedCalls; std::vector<PostponedCall> _postponedCalls;
QPointer<QWidget> _windowForDelayedActivation;
bool _delayedActivationsPaused = false;
not_null<Core::Launcher*> _launcher; not_null<Core::Launcher*> _launcher;
std::unique_ptr<Messenger> _messengerInstance; std::unique_ptr<Messenger> _messengerInstance;
@ -89,6 +96,16 @@ private:
}; };
namespace Core {
inline Application &App() {
Expects(QCoreApplication::instance() != nullptr);
return *static_cast<Application*>(QCoreApplication::instance());
}
} // namespace Core
namespace Sandbox { namespace Sandbox {
QRect availableGeometry(); QRect availableGeometry();

View file

@ -7,10 +7,18 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/ */
#include "core/file_utilities.h" #include "core/file_utilities.h"
#include "mainwindow.h"
#include "storage/localstorage.h" #include "storage/localstorage.h"
#include "platform/platform_file_utilities.h" #include "platform/platform_file_utilities.h"
#include "messenger.h" #include "messenger.h"
#include "application.h"
#include "mainwindow.h"
void PreventWindowActivation() {
Core::App().pauseDelayedWindowActivations();
Core::App().postponeCall([] {
Core::App().resumeDelayedWindowActivations();
});
}
bool filedialogGetSaveFile( bool filedialogGetSaveFile(
QPointer<QWidget> parent, QPointer<QWidget> parent,
@ -20,6 +28,7 @@ bool filedialogGetSaveFile(
const QString &initialPath) { const QString &initialPath) {
QStringList files; QStringList files;
QByteArray remoteContent; QByteArray remoteContent;
PreventWindowActivation();
bool result = Platform::FileDialog::Get( bool result = Platform::FileDialog::Get(
parent, parent,
files, files,
@ -112,6 +121,7 @@ namespace File {
void OpenEmailLink(const QString &email) { void OpenEmailLink(const QString &email) {
crl::on_main([=] { crl::on_main([=] {
PreventWindowActivation();
Platform::File::UnsafeOpenEmailLink(email); Platform::File::UnsafeOpenEmailLink(email);
}); });
} }
@ -119,6 +129,7 @@ void OpenEmailLink(const QString &email) {
void OpenWith(const QString &filepath, QPoint menuPosition) { void OpenWith(const QString &filepath, QPoint menuPosition) {
InvokeQueued(QApplication::instance(), [=] { InvokeQueued(QApplication::instance(), [=] {
if (!Platform::File::UnsafeShowOpenWithDropdown(filepath, menuPosition)) { if (!Platform::File::UnsafeShowOpenWithDropdown(filepath, menuPosition)) {
PreventWindowActivation();
if (!Platform::File::UnsafeShowOpenWith(filepath)) { if (!Platform::File::UnsafeShowOpenWith(filepath)) {
Platform::File::UnsafeLaunch(filepath); Platform::File::UnsafeLaunch(filepath);
} }
@ -128,12 +139,14 @@ void OpenWith(const QString &filepath, QPoint menuPosition) {
void Launch(const QString &filepath) { void Launch(const QString &filepath) {
crl::on_main([=] { crl::on_main([=] {
PreventWindowActivation();
Platform::File::UnsafeLaunch(filepath); Platform::File::UnsafeLaunch(filepath);
}); });
} }
void ShowInFolder(const QString &filepath) { void ShowInFolder(const QString &filepath) {
crl::on_main([=] { crl::on_main([=] {
PreventWindowActivation();
Platform::File::UnsafeShowInFolder(filepath); Platform::File::UnsafeShowInFolder(filepath);
}); });
} }
@ -173,6 +186,7 @@ void GetOpenPath(
InvokeQueued(QApplication::instance(), [=] { InvokeQueued(QApplication::instance(), [=] {
auto files = QStringList(); auto files = QStringList();
auto remoteContent = QByteArray(); auto remoteContent = QByteArray();
PreventWindowActivation();
const auto success = Platform::FileDialog::Get( const auto success = Platform::FileDialog::Get(
parent, parent,
files, files,
@ -206,6 +220,7 @@ void GetOpenPaths(
InvokeQueued(QApplication::instance(), [=] { InvokeQueued(QApplication::instance(), [=] {
auto files = QStringList(); auto files = QStringList();
auto remoteContent = QByteArray(); auto remoteContent = QByteArray();
PreventWindowActivation();
const auto success = Platform::FileDialog::Get( const auto success = Platform::FileDialog::Get(
parent, parent,
files, files,
@ -254,6 +269,7 @@ void GetFolder(
InvokeQueued(QApplication::instance(), [=] { InvokeQueued(QApplication::instance(), [=] {
auto files = QStringList(); auto files = QStringList();
auto remoteContent = QByteArray(); auto remoteContent = QByteArray();
PreventWindowActivation();
const auto success = Platform::FileDialog::Get( const auto success = Platform::FileDialog::Get(
parent, parent,
files, files,

View file

@ -112,13 +112,10 @@ ApiWrap::RequestMessageDataCallback replyEditMessageDataCallback() {
}; };
} }
void ActivateWindowDelayed(not_null<Window::Controller*> controller) { void ActivateWindow(not_null<Window::Controller*> controller) {
const auto window = controller->window(); const auto window = controller->window();
const auto weak = make_weak(window.get());
window->activateWindow(); window->activateWindow();
crl::on_main(window, [=] { Core::App().activateWindowDelayed(window);
window->activateWindow();
});
} }
void InsertEmojiToField(not_null<Ui::InputField*> field, EmojiPtr emoji) { void InsertEmojiToField(not_null<Ui::InputField*> field, EmojiPtr emoji) {
@ -353,11 +350,11 @@ HistoryWidget::HistoryWidget(
_attachDragDocument->setDroppedCallback([this](const QMimeData *data) { _attachDragDocument->setDroppedCallback([this](const QMimeData *data) {
confirmSendingFiles(data, CompressConfirm::No); confirmSendingFiles(data, CompressConfirm::No);
ActivateWindowDelayed(this->controller()); ActivateWindow(this->controller());
}); });
_attachDragPhoto->setDroppedCallback([this](const QMimeData *data) { _attachDragPhoto->setDroppedCallback([this](const QMimeData *data) {
confirmSendingFiles(data, CompressConfirm::Yes); confirmSendingFiles(data, CompressConfirm::Yes);
ActivateWindowDelayed(this->controller()); ActivateWindow(this->controller());
}); });
connect(&_updateEditTimeLeftDisplay, SIGNAL(timeout()), this, SLOT(updateField())); connect(&_updateEditTimeLeftDisplay, SIGNAL(timeout()), this, SLOT(updateField()));
@ -1247,7 +1244,7 @@ void HistoryWidget::onRecordDone(
qint32 samples) { qint32 samples) {
if (!canWriteMessage() || result.isEmpty()) return; if (!canWriteMessage() || result.isEmpty()) return;
ActivateWindowDelayed(controller()); ActivateWindow(controller());
const auto duration = samples / Media::Player::kDefaultFrequency; const auto duration = samples / Media::Player::kDefaultFrequency;
auto options = ApiWrap::SendOptions(_history); auto options = ApiWrap::SendOptions(_history);
options.replyTo = replyToId(); options.replyTo = replyToId();
@ -4047,7 +4044,7 @@ bool HistoryWidget::confirmSendingFiles(
} }
})); }));
ActivateWindowDelayed(controller()); ActivateWindow(controller());
const auto shown = Ui::show(std::move(box)); const auto shown = Ui::show(std::move(box));
shown->setCloseByOutsideClick(false); shown->setCloseByOutsideClick(false);
@ -4138,7 +4135,7 @@ bool HistoryWidget::confirmSendingFiles(
void HistoryWidget::uploadFiles( void HistoryWidget::uploadFiles(
Storage::PreparedList &&list, Storage::PreparedList &&list,
SendMediaType type) { SendMediaType type) {
ActivateWindowDelayed(controller()); ActivateWindow(controller());
uploadFilesAfterConfirmation( uploadFilesAfterConfirmation(
std::move(list), std::move(list),

View file

@ -503,12 +503,8 @@ PopupMenu::~PopupMenu() {
delete submenu; delete submenu;
} }
if (const auto parent = parentWidget()) { if (const auto parent = parentWidget()) {
if (qApp->focusWidget() != nullptr) { if (Core::App().focusWidget() != nullptr) {
crl::on_main(parent, [=] { Core::App().activateWindowDelayed(parent);
if (!parent->isHidden()) {
parent->activateWindow();
}
});
} }
} }
if (_destroyedCallback) { if (_destroyedCallback) {