diff --git a/widget/gtk/mozcontainer.cpp b/widget/gtk/mozcontainer.cpp index 65fe6c5061ba..879d009d48c0 100644 --- a/widget/gtk/mozcontainer.cpp +++ b/widget/gtk/mozcontainer.cpp @@ -224,6 +224,33 @@ static gint moz_container_get_scale(MozContainer *container) { return 1; } + +void moz_container_scale_changed(MozContainer *container, + GtkAllocation *aAllocation) { + MOZ_ASSERT(!GDK_IS_X11_DISPLAY(gdk_display_get_default()), + "moz_container_scale_changed operates on Wayland display only."); + + if (!container->surface) { + return; + } + + // Set correct scaled/unscaled mozcontainer offset + // especially when wl_egl is used but we don't recreate it as Gtk+ does. + gint x, y; + gdk_window_get_position(gtk_widget_get_window(GTK_WIDGET(container)), &x, + &y); + wl_subsurface_set_position(container->subsurface, x, y); + + // Try to only resize wl_egl_window on scale factor change. + // It's a bit risky as Gtk+ recreates it at that event. + if (container->eglwindow) { + gint scale = moz_container_get_scale(container); + wl_surface_set_buffer_scale(container->surface, + moz_container_get_scale(container)); + wl_egl_window_resize(container->eglwindow, aAllocation->width * scale, + aAllocation->height * scale, 0, 0); + } +} #endif void moz_container_map(GtkWidget *widget) { @@ -511,6 +538,7 @@ struct wl_egl_window *moz_container_get_wl_egl_window(MozContainer *container) { container->eglwindow = wl_egl_window_create(surface, gdk_window_get_width(window) * scale, gdk_window_get_height(window) * scale); + wl_surface_set_buffer_scale(surface, scale); } return container->eglwindow; } diff --git a/widget/gtk/mozcontainer.h b/widget/gtk/mozcontainer.h index 450292273f41..e9c218c1bc3e 100644 --- a/widget/gtk/mozcontainer.h +++ b/widget/gtk/mozcontainer.h @@ -96,6 +96,8 @@ struct wl_egl_window *moz_container_get_wl_egl_window(MozContainer *container); gboolean moz_container_has_wl_egl_window(MozContainer *container); gboolean moz_container_surface_needs_clear(MozContainer *container); +void moz_container_scale_changed(MozContainer *container, + GtkAllocation *aAllocation); #endif #endif /* __MOZ_CONTAINER_H__ */ diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp index 9b6e5f444b58..6aaacef96b5d 100644 --- a/widget/gtk/nsWindow.cpp +++ b/widget/gtk/nsWindow.cpp @@ -3190,6 +3190,22 @@ void nsWindow::OnCompositedChanged() { } } +void nsWindow::OnScaleChanged(GtkAllocation *aAllocation) { +#ifdef MOZ_WAYLAND + if (mContainer && moz_container_has_wl_egl_window(mContainer)) { + // We need to resize wl_egl_window when scale changes. + moz_container_scale_changed(mContainer, aAllocation); + } +#endif + + // This eventually propagate new scale to the PuppetWidgets + OnDPIChanged(); + + // configure_event is already fired before scale-factor signal, + // but size-allocate isn't fired by changing scale + OnSizeAllocate(aAllocation); +} + void nsWindow::DispatchDragEvent(EventMessage aMsg, const LayoutDeviceIntPoint &aRefPoint, guint aTime) { @@ -5565,14 +5581,10 @@ static void scale_changed_cb(GtkWidget *widget, GParamSpec *aPSpec, if (!window) { return; } - // This eventually propagate new scale to the PuppetWidgets - window->OnDPIChanged(); - // configure_event is already fired before scale-factor signal, - // but size-allocate isn't fired by changing scale GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); - window->OnSizeAllocate(&allocation); + window->OnScaleChanged(&allocation); } #if GTK_CHECK_VERSION(3, 4, 0) diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h index a33f900b2984..a7d7f6804104 100644 --- a/widget/gtk/nsWindow.h +++ b/widget/gtk/nsWindow.h @@ -258,6 +258,7 @@ class nsWindow final : public nsBaseWidget { void OnDPIChanged(void); void OnCheckResize(void); void OnCompositedChanged(void); + void OnScaleChanged(GtkAllocation* aAllocation); #ifdef MOZ_X11 Window mOldFocusWindow;