Bug 1580174 - Don't use toplevel window as parent for the menus in popupnotification; r=stransky

Under Wayland where there's a strict popup window hierarchy, using toplevel window
for the submenus in popupnotification cause the popupnotification to hide
when opening them and this breaks user to Allow/Don't allow the action.

We have to use last opened popup window as a parent for these submenus.

Differential Revision: https://phabricator.services.mozilla.com/D45343

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jan Horak 2019-09-12 09:38:05 +00:00
parent 96689a4a96
commit ab88be917c

View File

@ -1155,6 +1155,28 @@ void nsWindow::HideWaylandPopupAndAllChildren() {
}
}
bool IsPopupWithoutToplevelParent(nsMenuPopupFrame* aMenuPopupFrame) {
// Check if the popup is autocomplete (like tags autocomplete
// in the bookmark edit popup).
nsAtom* popupId = aMenuPopupFrame->GetContent()->GetID();
if (popupId && popupId->Equals(NS_LITERAL_STRING("PopupAutoComplete"))) {
return true;
}
// Check if the popup is in popupnotificationcontent (like choosing capture
// device when starting webrtc session).
nsIFrame* parentFrame = aMenuPopupFrame->GetParent();
if (!parentFrame) {
return false;
}
parentFrame = parentFrame->GetParent();
if (parentFrame && parentFrame->GetContent()->NodeName().EqualsLiteral(
"popupnotificationcontent")) {
return true;
}
return false;
}
// Wayland keeps strong popup window hierarchy. We need to track active
// (visible) popup windows and make sure we hide popup on the same level
// before we open another one on that level. It means that every open
@ -1211,10 +1233,14 @@ GtkWidget* nsWindow::ConfigureWaylandPopupWindows() {
LOG(("...[%p] GetParentMenuWidget() = %p\n", (void*)this, parentWindow));
// If the popup is a regular menu but GetParentMenuWidget() returns
// nullptr which means it's connected non-menu parent
// (bookmark toolbar for instance).
// nullptr which means is not a submenu of any other menu.
// In this case use a parent given at nsWindow::Create().
if (!parentWindow && !menuPopupFrame->IsContextMenu()) {
// But we have to avoid using mToplevelParentWindow in case the popup
// is in 'popupnotificationcontent' element or autocomplete popup,
// otherwise the popupnotification would disappear when for
// example opening a popup with microphone selection.
if (!parentWindow && !menuPopupFrame->IsContextMenu() &&
!IsPopupWithoutToplevelParent(menuPopupFrame)) {
parentWindow =
get_window_for_gtk_widget(GTK_WIDGET(mToplevelParentWindow));
}