mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-19 08:15:31 +00:00
Bug 1567434 - [Wayland] Don't use gtk_window_get_transient_for() to get parent toplevel window, r=jhorak
- gtk_window_get_transient_for() fails to return correct toplevel window as the toplevel window changes when popup is moved in popup hierarchy. So store the toplevel given at nsWindow::Create() and use it instead. - Remove some redundat NS_WARNING() from wayland code - Attach "moved-to-rect" signal handler to GdkWindow only once a update NativeMoveResizeWaylandPopupCallback() loging. - Add more logging to Wayland popup related code. Differential Revision: https://phabricator.services.mozilla.com/D39347 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
5b6538716e
commit
6354d2287a
@ -616,8 +616,6 @@ WindowBackBuffer* WindowSurfaceWayland::GetWaylandBufferToDraw(
|
||||
}
|
||||
|
||||
if (!aFullScreenUpdate) {
|
||||
NS_WARNING(
|
||||
"We can't create a new Wayland buffer for non-fullscreen updates!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -674,8 +672,6 @@ already_AddRefed<gfx::DrawTarget> WindowSurfaceWayland::LockWaylandBuffer(
|
||||
(void*)buffer));
|
||||
|
||||
if (!buffer) {
|
||||
NS_WARNING(
|
||||
"WindowSurfaceWayland::LockWaylandBuffer(): No buffer available");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -401,6 +401,7 @@ nsWindow::nsWindow() {
|
||||
mContainer = nullptr;
|
||||
mGdkWindow = nullptr;
|
||||
mShell = nullptr;
|
||||
mToplevelParentWindow = nullptr;
|
||||
mCompositorWidgetDelegate = nullptr;
|
||||
mHasMappedToplevel = false;
|
||||
mIsFullyObscured = false;
|
||||
@ -1144,6 +1145,8 @@ void nsWindow::HideWaylandTooltips() {
|
||||
nsWindow* window =
|
||||
static_cast<nsWindow*>(gVisibleWaylandPopupWindows->data);
|
||||
if (window->mPopupType != ePopupTypeTooltip) break;
|
||||
LOG(("nsWindow::HideWaylandTooltips [%p] hidding tooltip [%p].\n",
|
||||
(void*)this, window));
|
||||
window->HideWaylandWindow();
|
||||
gVisibleWaylandPopupWindows = g_list_delete_link(
|
||||
gVisibleWaylandPopupWindows, gVisibleWaylandPopupWindows);
|
||||
@ -1172,9 +1175,12 @@ void nsWindow::HideWaylandPopupAndAllChildren() {
|
||||
// before we open another one on that level. It means that every open
|
||||
// popup needs to have an unique parent.
|
||||
GtkWidget* nsWindow::ConfigureWaylandPopupWindows() {
|
||||
LOG(("nsWindow::ConfigureWaylandPopupWindows [%p]\n", (void*)this));
|
||||
|
||||
// Check if we're already configured.
|
||||
if (gVisibleWaylandPopupWindows &&
|
||||
g_list_find(gVisibleWaylandPopupWindows, this)) {
|
||||
LOG(("...[%p] is already configured.\n", (void*)this));
|
||||
return GTK_WIDGET(gtk_window_get_transient_for(GTK_WINDOW(mShell)));
|
||||
}
|
||||
|
||||
@ -1182,9 +1188,15 @@ GtkWidget* nsWindow::ConfigureWaylandPopupWindows() {
|
||||
// as it's short lived temporary window.
|
||||
HideWaylandTooltips();
|
||||
|
||||
GtkWindow* parentWidget = nullptr;
|
||||
GtkWindow* parentWidget = mToplevelParentWindow;
|
||||
if (gVisibleWaylandPopupWindows) {
|
||||
LOG(("... there's visible active popup [%p]\n",
|
||||
gVisibleWaylandPopupWindows->data));
|
||||
|
||||
if (mPopupType == ePopupTypeTooltip) {
|
||||
LOG(("...[%p] is tooltip, parent [%p]\n", (void*)this,
|
||||
gVisibleWaylandPopupWindows->data));
|
||||
|
||||
// Attach tooltip window to the latest popup window
|
||||
// to have both visible.
|
||||
nsWindow* window =
|
||||
@ -1200,12 +1212,19 @@ GtkWidget* nsWindow::ConfigureWaylandPopupWindows() {
|
||||
// nsWindow::Create()) or we're toplevel popup without parent.
|
||||
// In both cases just use parent which was passed to nsWindow::Create().
|
||||
if (!menuPopupFrame) {
|
||||
return GTK_WIDGET(gtk_window_get_transient_for(GTK_WINDOW(mShell)));
|
||||
LOG(("...[%p] menuPopupFrame = null, using given parent widget [%p]\n",
|
||||
(void*)this, parentWidget));
|
||||
return GTK_WIDGET(parentWidget);
|
||||
}
|
||||
|
||||
nsWindow* parentWindow =
|
||||
static_cast<nsWindow*>(menuPopupFrame->GetParentMenuWidget());
|
||||
LOG(("...[%p] GetParentMenuWidget() = %p\n", (void*)this, parentWindow));
|
||||
|
||||
if (!parentWindow) {
|
||||
LOG(("...[%p] using active/visible popups as a parent [%p]\n",
|
||||
(void*)this, gVisibleWaylandPopupWindows->data));
|
||||
|
||||
// We're toplevel popup menu attached to another menu. Just use our
|
||||
// latest popup as a parent.
|
||||
parentWindow =
|
||||
@ -1234,10 +1253,10 @@ GtkWidget* nsWindow::ConfigureWaylandPopupWindows() {
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT(parentWidget, "Missing parent widget for wayland popup!");
|
||||
if (parentWidget) {
|
||||
LOG(("...[%p] set parent widget [%p]\n", (void*)this, parentWidget));
|
||||
gtk_window_set_transient_for(GTK_WINDOW(mShell), parentWidget);
|
||||
} else {
|
||||
parentWidget = gtk_window_get_transient_for(GTK_WINDOW(mShell));
|
||||
}
|
||||
gVisibleWaylandPopupWindows =
|
||||
g_list_prepend(gVisibleWaylandPopupWindows, this);
|
||||
@ -1248,9 +1267,11 @@ GtkWidget* nsWindow::ConfigureWaylandPopupWindows() {
|
||||
static void NativeMoveResizeWaylandPopupCallback(
|
||||
GdkWindow* window, const GdkRectangle* flipped_rect,
|
||||
const GdkRectangle* final_rect, gboolean flipped_x, gboolean flipped_y,
|
||||
void* unused) {
|
||||
LOG(("%s flipped %d %d\n", __FUNCTION__, flipped_rect->x, flipped_rect->y));
|
||||
LOG(("%s final %d %d\n", __FUNCTION__, final_rect->x, final_rect->y));
|
||||
void* aWindow) {
|
||||
LOG(("%s [%p] flipped %d %d\n", __FUNCTION__, aWindow, flipped_rect->x,
|
||||
flipped_rect->y));
|
||||
LOG(("%s [%p] final %d %d\n", __FUNCTION__, aWindow, final_rect->x,
|
||||
final_rect->y));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1264,6 +1285,8 @@ void nsWindow::NativeMoveResizeWaylandPopup(GdkPoint* aPosition,
|
||||
// Compositor may be confused by windows with width/height = 0
|
||||
// and positioning such windows leads to Bug 1555866.
|
||||
if (!AreBoundsSane()) {
|
||||
LOG(("nsWindow::NativeMoveResizeWaylandPopup [%p] Bounds are not sane\n",
|
||||
(void*)this));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1277,6 +1300,8 @@ void nsWindow::NativeMoveResizeWaylandPopup(GdkPoint* aPosition,
|
||||
// - gdk_window_move_to_rect() is not available
|
||||
// - the widget doesn't have a valid GdkWindow
|
||||
if (!sGdkWindowMoveToRect || !gdkWindow) {
|
||||
LOG(("nsWindow::NativeMoveResizeWaylandPopup [%p] use gtk_window_move()\n",
|
||||
(void*)this));
|
||||
gtk_window_move(GTK_WINDOW(mShell), aPosition->x, aPosition->y);
|
||||
return;
|
||||
}
|
||||
@ -1302,8 +1327,12 @@ void nsWindow::NativeMoveResizeWaylandPopup(GdkPoint* aPosition,
|
||||
}
|
||||
LOG((" request result %d %d\n", rect.x, rect.y));
|
||||
#ifdef DEBUG
|
||||
g_signal_connect(gdkWindow, "moved-to-rect",
|
||||
G_CALLBACK(NativeMoveResizeWaylandPopupCallback), this);
|
||||
if (!g_signal_handler_find(
|
||||
gdkWindow, G_SIGNAL_MATCH_FUNC, 0, 0, nullptr,
|
||||
FuncToGpointer(NativeMoveResizeWaylandPopupCallback), this)) {
|
||||
g_signal_connect(gdkWindow, "moved-to-rect",
|
||||
G_CALLBACK(NativeMoveResizeWaylandPopupCallback), this);
|
||||
}
|
||||
#endif
|
||||
|
||||
GdkGravity rectAnchor = GDK_GRAVITY_NORTH_WEST;
|
||||
@ -3508,7 +3537,6 @@ nsresult nsWindow::Create(nsIWidget* aParent, nsNativeWidget aNativeParent,
|
||||
GtkWidget* parentMozContainer = nullptr;
|
||||
GtkContainer* parentGtkContainer = nullptr;
|
||||
GdkWindow* parentGdkWindow = nullptr;
|
||||
GtkWindow* topLevelParent = nullptr;
|
||||
nsWindow* parentnsWindow = nullptr;
|
||||
GtkWidget* eventWidget = nullptr;
|
||||
bool drawToContainer = false;
|
||||
@ -3534,7 +3562,8 @@ nsresult nsWindow::Create(nsIWidget* aParent, nsNativeWidget aNativeParent,
|
||||
|
||||
// get the toplevel window just in case someone needs to use it
|
||||
// for setting transients or whatever.
|
||||
topLevelParent = GTK_WINDOW(gtk_widget_get_toplevel(parentMozContainer));
|
||||
mToplevelParentWindow =
|
||||
GTK_WINDOW(gtk_widget_get_toplevel(parentMozContainer));
|
||||
}
|
||||
|
||||
if (!mIsX11Display) {
|
||||
@ -3542,7 +3571,7 @@ nsresult nsWindow::Create(nsIWidget* aParent, nsNativeWidget aNativeParent,
|
||||
// eWindowType_child is not supported on Wayland. Just switch to toplevel
|
||||
// as a workaround.
|
||||
mWindowType = eWindowType_toplevel;
|
||||
} else if (mWindowType == eWindowType_popup && !topLevelParent) {
|
||||
} else if (mWindowType == eWindowType_popup && !mToplevelParentWindow) {
|
||||
// Workaround for Wayland where the popup windows always need to have
|
||||
// parent window. For example webrtc ui is a popup window without parent.
|
||||
mWindowType = eWindowType_toplevel;
|
||||
@ -3677,7 +3706,7 @@ nsresult nsWindow::Create(nsIWidget* aParent, nsNativeWidget aNativeParent,
|
||||
gdk_get_program_class());
|
||||
gtk_window_set_type_hint(GTK_WINDOW(mShell),
|
||||
GDK_WINDOW_TYPE_HINT_DIALOG);
|
||||
gtk_window_set_transient_for(GTK_WINDOW(mShell), topLevelParent);
|
||||
gtk_window_set_transient_for(GTK_WINDOW(mShell), mToplevelParentWindow);
|
||||
} else if (mWindowType == eWindowType_popup) {
|
||||
gtk_window_set_wmclass(GTK_WINDOW(mShell), "Popup",
|
||||
gdk_get_program_class());
|
||||
@ -3730,10 +3759,11 @@ nsresult nsWindow::Create(nsIWidget* aParent, nsNativeWidget aNativeParent,
|
||||
}
|
||||
gtk_window_set_type_hint(GTK_WINDOW(mShell), gtkTypeHint);
|
||||
|
||||
if (topLevelParent) {
|
||||
if (mToplevelParentWindow) {
|
||||
LOG(("nsWindow::Create [%p] Set popup parent %p\n", (void*)this,
|
||||
topLevelParent));
|
||||
gtk_window_set_transient_for(GTK_WINDOW(mShell), topLevelParent);
|
||||
mToplevelParentWindow));
|
||||
gtk_window_set_transient_for(GTK_WINDOW(mShell),
|
||||
mToplevelParentWindow);
|
||||
}
|
||||
|
||||
// We need realized mShell at NativeMove().
|
||||
@ -4011,7 +4041,8 @@ nsresult nsWindow::Create(nsIWidget* aParent, nsNativeWidget aNativeParent,
|
||||
#endif
|
||||
}
|
||||
|
||||
LOG(("nsWindow [%p]\n", (void*)this));
|
||||
LOG(("nsWindow [%p] %s\n", (void*)this,
|
||||
mWindowType == eWindowType_toplevel ? "Toplevel" : "Popup"));
|
||||
if (mShell) {
|
||||
LOG(("\tmShell %p mContainer %p mGdkWindow %p 0x%lx\n", mShell, mContainer,
|
||||
mGdkWindow, mIsX11Display ? gdk_x11_window_get_xid(mGdkWindow) : 0));
|
||||
|
@ -487,6 +487,7 @@ class nsWindow final : public nsBaseWidget {
|
||||
GtkWidget* mShell;
|
||||
MozContainer* mContainer;
|
||||
GdkWindow* mGdkWindow;
|
||||
GtkWindow* mToplevelParentWindow;
|
||||
bool mWindowShouldStartDragging = false;
|
||||
PlatformCompositorWidgetDelegate* mCompositorWidgetDelegate;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user