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;
}
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() {
if (App::launchState() == App::QuitProcessed) return;
App::setLaunchState(App::QuitProcessed);

View file

@ -29,6 +29,10 @@ public:
void postponeCall(FnMut<void()> &&callable);
bool notify(QObject *receiver, QEvent *e) override;
void activateWindowDelayed(not_null<QWidget*> widget);
void pauseDelayedWindowActivations();
void resumeDelayedWindowActivations();
~Application();
signals:
@ -73,6 +77,9 @@ private:
std::vector<int> _previousLoopNestingLevels;
std::vector<PostponedCall> _postponedCalls;
QPointer<QWidget> _windowForDelayedActivation;
bool _delayedActivationsPaused = false;
not_null<Core::Launcher*> _launcher;
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 {
QRect availableGeometry();

View file

@ -7,10 +7,18 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "core/file_utilities.h"
#include "mainwindow.h"
#include "storage/localstorage.h"
#include "platform/platform_file_utilities.h"
#include "messenger.h"
#include "application.h"
#include "mainwindow.h"
void PreventWindowActivation() {
Core::App().pauseDelayedWindowActivations();
Core::App().postponeCall([] {
Core::App().resumeDelayedWindowActivations();
});
}
bool filedialogGetSaveFile(
QPointer<QWidget> parent,
@ -20,6 +28,7 @@ bool filedialogGetSaveFile(
const QString &initialPath) {
QStringList files;
QByteArray remoteContent;
PreventWindowActivation();
bool result = Platform::FileDialog::Get(
parent,
files,
@ -112,6 +121,7 @@ namespace File {
void OpenEmailLink(const QString &email) {
crl::on_main([=] {
PreventWindowActivation();
Platform::File::UnsafeOpenEmailLink(email);
});
}
@ -119,6 +129,7 @@ void OpenEmailLink(const QString &email) {
void OpenWith(const QString &filepath, QPoint menuPosition) {
InvokeQueued(QApplication::instance(), [=] {
if (!Platform::File::UnsafeShowOpenWithDropdown(filepath, menuPosition)) {
PreventWindowActivation();
if (!Platform::File::UnsafeShowOpenWith(filepath)) {
Platform::File::UnsafeLaunch(filepath);
}
@ -128,12 +139,14 @@ void OpenWith(const QString &filepath, QPoint menuPosition) {
void Launch(const QString &filepath) {
crl::on_main([=] {
PreventWindowActivation();
Platform::File::UnsafeLaunch(filepath);
});
}
void ShowInFolder(const QString &filepath) {
crl::on_main([=] {
PreventWindowActivation();
Platform::File::UnsafeShowInFolder(filepath);
});
}
@ -173,6 +186,7 @@ void GetOpenPath(
InvokeQueued(QApplication::instance(), [=] {
auto files = QStringList();
auto remoteContent = QByteArray();
PreventWindowActivation();
const auto success = Platform::FileDialog::Get(
parent,
files,
@ -206,6 +220,7 @@ void GetOpenPaths(
InvokeQueued(QApplication::instance(), [=] {
auto files = QStringList();
auto remoteContent = QByteArray();
PreventWindowActivation();
const auto success = Platform::FileDialog::Get(
parent,
files,
@ -254,6 +269,7 @@ void GetFolder(
InvokeQueued(QApplication::instance(), [=] {
auto files = QStringList();
auto remoteContent = QByteArray();
PreventWindowActivation();
const auto success = Platform::FileDialog::Get(
parent,
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 weak = make_weak(window.get());
window->activateWindow();
crl::on_main(window, [=] {
window->activateWindow();
});
Core::App().activateWindowDelayed(window);
}
void InsertEmojiToField(not_null<Ui::InputField*> field, EmojiPtr emoji) {
@ -353,11 +350,11 @@ HistoryWidget::HistoryWidget(
_attachDragDocument->setDroppedCallback([this](const QMimeData *data) {
confirmSendingFiles(data, CompressConfirm::No);
ActivateWindowDelayed(this->controller());
ActivateWindow(this->controller());
});
_attachDragPhoto->setDroppedCallback([this](const QMimeData *data) {
confirmSendingFiles(data, CompressConfirm::Yes);
ActivateWindowDelayed(this->controller());
ActivateWindow(this->controller());
});
connect(&_updateEditTimeLeftDisplay, SIGNAL(timeout()), this, SLOT(updateField()));
@ -1247,7 +1244,7 @@ void HistoryWidget::onRecordDone(
qint32 samples) {
if (!canWriteMessage() || result.isEmpty()) return;
ActivateWindowDelayed(controller());
ActivateWindow(controller());
const auto duration = samples / Media::Player::kDefaultFrequency;
auto options = ApiWrap::SendOptions(_history);
options.replyTo = replyToId();
@ -4047,7 +4044,7 @@ bool HistoryWidget::confirmSendingFiles(
}
}));
ActivateWindowDelayed(controller());
ActivateWindow(controller());
const auto shown = Ui::show(std::move(box));
shown->setCloseByOutsideClick(false);
@ -4138,7 +4135,7 @@ bool HistoryWidget::confirmSendingFiles(
void HistoryWidget::uploadFiles(
Storage::PreparedList &&list,
SendMediaType type) {
ActivateWindowDelayed(controller());
ActivateWindow(controller());
uploadFilesAfterConfirmation(
std::move(list),

View file

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