Workaround Wayland popup menu bug.
When hiding a child popup first the app receives ApplicationDeactivate event and in a short time (a couple of ms) ApplicationActivate. But the first event hides all popups, so the parent popup gets closed too. Delay handling of ApplicationDeactivate event in this specific case.
This commit is contained in:
parent
d04a38e15d
commit
8db6dcf125
5 changed files with 63 additions and 1 deletions
|
|
@ -9,8 +9,9 @@
|
|||
#include "base/platform/base_platform_info.h"
|
||||
#include "base/platform/linux/base_linux_glibmm_helper.h"
|
||||
#include "base/platform/linux/base_linux_xdp_utilities.h"
|
||||
#include "ui/platform/linux/ui_linux_wayland_integration.h"
|
||||
#include "base/call_delayed.h"
|
||||
#include "base/const_string.h"
|
||||
#include "ui/platform/linux/ui_linux_wayland_integration.h"
|
||||
|
||||
#ifndef DESKTOP_APP_DISABLE_X11_INTEGRATION
|
||||
#include "base/platform/linux/base_linux_xcb_utilities.h"
|
||||
|
|
@ -26,6 +27,10 @@ namespace Platform {
|
|||
namespace {
|
||||
|
||||
constexpr auto kXCBFrameExtentsAtomName = "_GTK_FRAME_EXTENTS"_cs;
|
||||
constexpr auto kDelayDeactivateEventTimeout = crl::time(400);
|
||||
|
||||
bool PendingDeactivateEvent/* = false*/;
|
||||
int ChildPopupsHiddenOnWayland/* = 0*/;
|
||||
|
||||
#ifndef DESKTOP_APP_DISABLE_X11_INTEGRATION
|
||||
std::optional<bool> XCBWindowMapped(xcb_window_t window) {
|
||||
|
|
@ -548,6 +553,34 @@ void ShowWindowMenu(not_null<QWidget*> widget, const QPoint &point) {
|
|||
}
|
||||
}
|
||||
|
||||
void RegisterChildPopupHiding() {
|
||||
if (!::Platform::IsWayland()) {
|
||||
return;
|
||||
}
|
||||
++ChildPopupsHiddenOnWayland;
|
||||
base::call_delayed(kDelayDeactivateEventTimeout, [] {
|
||||
if (!--ChildPopupsHiddenOnWayland) {
|
||||
if (base::take(PendingDeactivateEvent)) {
|
||||
// We didn't receive ApplicationActivate event in time.
|
||||
QEvent appDeactivate(QEvent::ApplicationDeactivate);
|
||||
QCoreApplication::sendEvent(qApp, &appDeactivate);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
bool SkipApplicationDeactivateEvent() {
|
||||
if (!ChildPopupsHiddenOnWayland) {
|
||||
return false;
|
||||
}
|
||||
PendingDeactivateEvent = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void GotApplicationActivateEvent() {
|
||||
PendingDeactivateEvent = false;
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
TitleControls::Layout TitleControlsLayout() {
|
||||
|
|
|
|||
|
|
@ -147,6 +147,16 @@ std::optional<bool> IsOverlapped(
|
|||
return false;
|
||||
}
|
||||
|
||||
void RegisterChildPopupHiding() {
|
||||
}
|
||||
|
||||
bool SkipApplicationDeactivateEvent() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void GotApplicationActivateEvent() {
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
TitleControls::Layout TitleControlsLayout() {
|
||||
|
|
|
|||
|
|
@ -58,6 +58,12 @@ void ShowWindowMenu(not_null<QWidget*> widget, const QPoint &point);
|
|||
|
||||
void FixPopupMenuNativeEmojiPopup(not_null<PopupMenu*> menu);
|
||||
|
||||
// Workaround for a Qt/Wayland bug that hides the parent popup when
|
||||
// the child popup gets hidden, by sending Deactivate / Activate events.
|
||||
void RegisterChildPopupHiding();
|
||||
[[nodiscard]] bool SkipApplicationDeactivateEvent();
|
||||
void GotApplicationActivateEvent();
|
||||
|
||||
} // namespace Ui::Platform
|
||||
|
||||
// Platform dependent implementations.
|
||||
|
|
|
|||
|
|
@ -203,4 +203,14 @@ void FixPopupMenuNativeEmojiPopup(not_null<PopupMenu*> menu) {
|
|||
menu->lifetime().make_state<Filter>(menu));
|
||||
}
|
||||
|
||||
void RegisterChildPopupHiding() {
|
||||
}
|
||||
|
||||
bool SkipApplicationDeactivateEvent() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void GotApplicationActivateEvent() {
|
||||
}
|
||||
|
||||
} // namespace Ui::Platform
|
||||
|
|
|
|||
|
|
@ -673,6 +673,9 @@ bool PopupMenu::eventFilter(QObject *o, QEvent *e) {
|
|||
}
|
||||
|
||||
void PopupMenu::hideMenu(bool fast) {
|
||||
if (fast && _parent) {
|
||||
Platform::RegisterChildPopupHiding();
|
||||
}
|
||||
if (isHidden() || (_hiding && !fast)) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue