diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp index 9fe8d58999c5..27c0e3974593 100644 --- a/widget/gtk/nsWindow.cpp +++ b/widget/gtk/nsWindow.cpp @@ -3753,6 +3753,26 @@ void nsWindow::CreateCompositorVsyncDispatcher() { } #endif +void nsWindow::RequestRepaint(LayoutDeviceIntRegion& aRepaintRegion) { + WindowRenderer* renderer = GetWindowRenderer(); + WebRenderLayerManager* layerManager = renderer->AsWebRender(); + KnowsCompositor* knowsCompositor = renderer->AsKnowsCompositor(); + + if (knowsCompositor && layerManager && mCompositorSession) { + if (!mConfiguredClearColor && !IsPopup()) { + layerManager->WrBridge()->SendSetDefaultClearColor(LookAndFeel::Color( + LookAndFeel::ColorID::Window, PreferenceSheet::ColorSchemeForChrome(), + LookAndFeel::UseStandins::No)); + mConfiguredClearColor = true; + } + + // We need to paint to the screen even if nothing changed, since if we + // don't have a compositing window manager, our pixels could be stale. + layerManager->SetNeedsComposite(true); + layerManager->SendInvalidRegion(aRepaintRegion.ToUnknownRegion()); + } +} + gboolean nsWindow::OnExposeEvent(cairo_t* cr) { // This might destroy us. NotifyOcclusionState(OcclusionState::VISIBLE); @@ -3777,8 +3797,7 @@ gboolean nsWindow::OnExposeEvent(cairo_t* cr) { } #endif - nsIWidgetListener* listener = GetListener(); - if (!listener) { + if (!GetListener()) { return FALSE; } @@ -3795,45 +3814,30 @@ gboolean nsWindow::OnExposeEvent(cairo_t* cr) { LayoutDeviceIntRegion region = exposeRegion; region.ScaleRoundOut(scale, scale); - WindowRenderer* renderer = GetWindowRenderer(); - WebRenderLayerManager* layerManager = renderer->AsWebRender(); - KnowsCompositor* knowsCompositor = renderer->AsKnowsCompositor(); - - if (knowsCompositor && layerManager && mCompositorSession) { - if (!mConfiguredClearColor && !IsPopup()) { - layerManager->WrBridge()->SendSetDefaultClearColor(LookAndFeel::Color( - LookAndFeel::ColorID::Window, PreferenceSheet::ColorSchemeForChrome(), - LookAndFeel::UseStandins::No)); - mConfiguredClearColor = true; - } - - // We need to paint to the screen even if nothing changed, since if we - // don't have a compositing window manager, our pixels could be stale. - layerManager->SetNeedsComposite(true); - layerManager->SendInvalidRegion(region.ToUnknownRegion()); - } + RequestRepaint(region); RefPtr strongThis(this); // Dispatch WillPaintWindow notification to allow scripts etc. to run - // before we paint - { - listener->WillPaintWindow(this); + // before we paint. It also spins event loop which may show/hide the window + // so we may have new renderer etc. + GetListener()->WillPaintWindow(this); - // If the window has been destroyed during the will paint notification, - // there is nothing left to do. - if (!mGdkWindow) { - return TRUE; - } - - // Re-get the listener since the will paint notification might have - // killed it. - listener = GetListener(); - if (!listener) { - return FALSE; - } + // If the window has been destroyed during the will paint notification, + // there is nothing left to do. + if (!mGdkWindow || mIsDestroyed) { + return TRUE; } + // Re-get all rendering components since the will paint notification + // might have killed it. + nsIWidgetListener* listener = GetListener(); + if (!listener) return FALSE; + + WindowRenderer* renderer = GetWindowRenderer(); + WebRenderLayerManager* layerManager = renderer->AsWebRender(); + KnowsCompositor* knowsCompositor = renderer->AsKnowsCompositor(); + if (knowsCompositor && layerManager && layerManager->NeedsComposite()) { layerManager->ScheduleComposite(wr::RenderReasons::WIDGET); layerManager->SetNeedsComposite(false); diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h index 58af78b437d2..183b4a9e7ebf 100644 --- a/widget/gtk/nsWindow.h +++ b/widget/gtk/nsWindow.h @@ -986,6 +986,8 @@ class nsWindow final : public nsBaseWidget { void EmulateResizeDrag(GdkEventMotion* aEvent); + void RequestRepaint(LayoutDeviceIntRegion& aRepaintRegion); + #ifdef MOZ_X11 typedef enum {GTK_WIDGET_COMPOSIDED_DEFAULT = 0, GTK_WIDGET_COMPOSIDED_DISABLED = 1,