Added upstream Wayland patches (mozilla-1548475, mozilla-1562827,

mozilla-1567434, mozilla-1573813, mozilla-1574036,
  mozilla-1576268).
- Enable multiprocess compilation.
This commit is contained in:
Martin Stransky 2019-09-02 17:03:30 +02:00
parent 91a10435a5
commit 20c032f2ed
8 changed files with 931 additions and 4 deletions

View File

@ -21,7 +21,7 @@ ExcludeArch: s390x
%global build_with_clang 0
%global use_bundled_cbindgen 1
# FIXME disable PGO because of -j1 build would take ages
%global disable_multiprocess_compilation 1
%global disable_multiprocess_compilation 0
# Build PGO+LTO on x86_64 and aarch64 only due to build issues
# on other arches.
%ifarch x86_64 aarch64
@ -90,7 +90,7 @@ ExcludeArch: s390x
Summary: Mozilla Firefox Web browser
Name: firefox
Version: 69.0
Release: 1%{?pre_tag}%{?dist}
Release: 2%{?pre_tag}%{?dist}
URL: https://www.mozilla.org/firefox/
License: MPLv1.1 or GPLv2+ or LGPLv2+
Source0: https://archive.mozilla.org/pub/firefox/releases/%{version}%{?pre_version}/source/firefox-%{version}%{?pre_version}.source.tar.xz
@ -127,7 +127,7 @@ Patch38: build-cacheFlush-missing.patch
Patch40: build-aarch64-skia.patch
Patch41: build-disable-elfhack.patch
Patch44: build-arm-libopus.patch
Patch45: build-disable-multijobs-rust.patch
#Patch45: build-disable-multijobs-rust.patch
# Fedora specific patches
Patch215: firefox-enable-addons.patch
@ -150,6 +150,13 @@ Patch420: mozilla-1566876-webrtc-ind.patch
# Wayland specific upstream patches
Patch574: firefox-pipewire.patch
Patch575: mozilla-1548475.patch
Patch576: mozilla-1562827.patch
Patch578: mozilla-1567434-1.patch
Patch579: mozilla-1567434-2.patch
Patch580: mozilla-1573813.patch
Patch581: mozilla-1574036.patch
Patch582: mozilla-1576268.patch
# PGO/LTO patches
Patch600: pgo.patch
@ -326,7 +333,7 @@ This package contains results of tests executed during build.
%endif
%patch3 -p1 -b .arm
%patch44 -p1 -b .build-arm-libopus
%patch45 -p1 -b .build-disable-multijobs-rust
#%patch45 -p1 -b .build-disable-multijobs-rust
# Patch for big endian platforms only
%if 0%{?big_endian}
%patch26 -p1 -b .icu
@ -356,6 +363,13 @@ This package contains results of tests executed during build.
# Wayland specific upstream patches
%patch574 -p1 -b .firefox-pipewire
%patch575 -p1 -b .mozilla-1548475
%patch576 -p1 -b .mozilla-1562827
%patch578 -p1 -b .mozilla-1567434-1
%patch579 -p1 -b .mozilla-1567434-2
%patch580 -p1 -b .mozilla-1573813
%patch581 -p1 -b .mozilla-1574036
%patch582 -p1 -b .mozilla-1576268
# PGO patches
%patch600 -p1 -b .pgo
@ -932,6 +946,12 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || :
#---------------------------------------------------------------------
%changelog
* Mon Sep 2 2019 Martin Stransky <stransky@redhat.com> - 69.0-1
- Added upstream Wayland patches (mozilla-1548475, mozilla-1562827,
mozilla-1567434, mozilla-1573813, mozilla-1574036,
mozilla-1576268).
- Enable multiprocess compilation.
* Thu Aug 29 2019 Jan Horak <jhorak@redhat.com> - 69.0-1
- Update to 69.0

34
mozilla-1548475.patch Normal file
View File

@ -0,0 +1,34 @@
diff --git a/dom/plugins/base/nsPluginHost.cpp b/dom/plugins/base/nsPluginHost.cpp
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -105,6 +105,10 @@
# include "windows.h"
# include "winbase.h"
#endif
+#if (MOZ_WIDGET_GTK)
+# include <gdk/gdk.h>
+# include <gdk/gdkx.h>
+#endif
#include "npapi.h"
@@ -358,9 +362,15 @@
mOverrideInternalTypes =
Preferences::GetBool("plugin.override_internal_types", false);
- mPluginsDisabled = Preferences::GetBool("plugin.disable", false);
-
- Preferences::AddStrongObserver(this, "plugin.disable");
+ bool waylandBackend = false;
+#if MOZ_WIDGET_GTK
+ waylandBackend = !GDK_IS_X11_DISPLAY(gdk_display_get_default());
+#endif
+ mPluginsDisabled =
+ Preferences::GetBool("plugin.disable", false) || waylandBackend;
+ if (!waylandBackend) {
+ Preferences::AddStrongObserver(this, "plugin.disable");
+ }
nsCOMPtr<nsIObserverService> obsService =
mozilla::services::GetObserverService();

141
mozilla-1562827.patch Normal file
View File

@ -0,0 +1,141 @@
diff -up firefox-69.0/widget/gtk/nsWindow.cpp.mozilla-1562827 firefox-69.0/widget/gtk/nsWindow.cpp
--- firefox-69.0/widget/gtk/nsWindow.cpp.mozilla-1562827 2019-09-02 15:16:15.031528276 +0200
+++ firefox-69.0/widget/gtk/nsWindow.cpp 2019-09-02 15:16:15.037528254 +0200
@@ -818,7 +818,6 @@ void nsWindow::SetParent(nsIWidget* aNew
if (mParent) {
mParent->RemoveChild(this);
}
-
mParent = aNewParent;
GtkWidget* oldContainer = GetMozContainerWidget();
@@ -830,88 +829,73 @@ void nsWindow::SetParent(nsIWidget* aNew
return;
}
+ nsWindow* newParent = static_cast<nsWindow*>(aNewParent);
+ GdkWindow* newParentWindow = nullptr;
+ GtkWidget* newContainer = nullptr;
if (aNewParent) {
aNewParent->AddChild(this);
- ReparentNativeWidget(aNewParent);
+ newParentWindow = newParent->mGdkWindow;
+ newContainer = newParent->GetMozContainerWidget();
} else {
// aNewParent is nullptr, but reparent to a hidden window to avoid
// destroying the GdkWindow and its descendants.
// An invisible container widget is needed to hold descendant
// GtkWidgets.
- GtkWidget* newContainer = EnsureInvisibleContainer();
- GdkWindow* newParentWindow = gtk_widget_get_window(newContainer);
- ReparentNativeWidgetInternal(aNewParent, newContainer, newParentWindow,
- oldContainer);
- }
-}
-
-bool nsWindow::WidgetTypeSupportsAcceleration() { return !IsSmallPopup(); }
-
-void nsWindow::ReparentNativeWidget(nsIWidget* aNewParent) {
- MOZ_ASSERT(aNewParent, "null widget");
- NS_ASSERTION(!mIsDestroyed, "");
- NS_ASSERTION(!static_cast<nsWindow*>(aNewParent)->mIsDestroyed, "");
-
- GtkWidget* oldContainer = GetMozContainerWidget();
- if (!oldContainer) {
- // The GdkWindows have been destroyed so there is nothing else to
- // reparent.
- MOZ_ASSERT(gdk_window_is_destroyed(mGdkWindow),
- "live GdkWindow with no widget");
- return;
+ newContainer = EnsureInvisibleContainer();
+ newParentWindow = gtk_widget_get_window(newContainer);
}
- MOZ_ASSERT(!gdk_window_is_destroyed(mGdkWindow),
- "destroyed GdkWindow with widget");
- auto* newParent = static_cast<nsWindow*>(aNewParent);
- GdkWindow* newParentWindow = newParent->mGdkWindow;
- GtkWidget* newContainer = newParent->GetMozContainerWidget();
- GtkWindow* shell = GTK_WINDOW(mShell);
-
- if (shell && gtk_window_get_transient_for(shell)) {
- GtkWindow* topLevelParent =
- GTK_WINDOW(gtk_widget_get_toplevel(newContainer));
- gtk_window_set_transient_for(shell, topLevelParent);
- }
-
- ReparentNativeWidgetInternal(aNewParent, newContainer, newParentWindow,
- oldContainer);
-}
-
-void nsWindow::ReparentNativeWidgetInternal(nsIWidget* aNewParent,
- GtkWidget* aNewContainer,
- GdkWindow* aNewParentWindow,
- GtkWidget* aOldContainer) {
- if (!aNewContainer) {
+ if (!newContainer) {
// The new parent GdkWindow has been destroyed.
- MOZ_ASSERT(!aNewParentWindow || gdk_window_is_destroyed(aNewParentWindow),
+ MOZ_ASSERT(!newParentWindow || gdk_window_is_destroyed(newParentWindow),
"live GdkWindow with no widget");
Destroy();
} else {
- if (aNewContainer != aOldContainer) {
- MOZ_ASSERT(!gdk_window_is_destroyed(aNewParentWindow),
+ if (newContainer != oldContainer) {
+ MOZ_ASSERT(!gdk_window_is_destroyed(newParentWindow),
"destroyed GdkWindow with widget");
- SetWidgetForHierarchy(mGdkWindow, aOldContainer, aNewContainer);
+ SetWidgetForHierarchy(mGdkWindow, oldContainer, newContainer);
- if (aOldContainer == gInvisibleContainer) {
+ if (oldContainer == gInvisibleContainer) {
CheckDestroyInvisibleContainer();
}
}
- if (!mIsTopLevel) {
- gdk_window_reparent(mGdkWindow, aNewParentWindow,
- DevicePixelsToGdkCoordRoundDown(mBounds.x),
- DevicePixelsToGdkCoordRoundDown(mBounds.y));
- }
+ gdk_window_reparent(mGdkWindow, newParentWindow,
+ DevicePixelsToGdkCoordRoundDown(mBounds.x),
+ DevicePixelsToGdkCoordRoundDown(mBounds.y));
+ mToplevelParentWindow = GTK_WINDOW(gtk_widget_get_toplevel(newContainer));
}
- auto* newParent = static_cast<nsWindow*>(aNewParent);
bool parentHasMappedToplevel = newParent && newParent->mHasMappedToplevel;
if (mHasMappedToplevel != parentHasMappedToplevel) {
SetHasMappedToplevel(parentHasMappedToplevel);
}
}
+bool nsWindow::WidgetTypeSupportsAcceleration() { return !IsSmallPopup(); }
+
+void nsWindow::ReparentNativeWidget(nsIWidget* aNewParent) {
+ MOZ_ASSERT(aNewParent, "null widget");
+ MOZ_ASSERT(!mIsDestroyed, "");
+ MOZ_ASSERT(!static_cast<nsWindow*>(aNewParent)->mIsDestroyed, "");
+ MOZ_ASSERT(!gdk_window_is_destroyed(mGdkWindow),
+ "destroyed GdkWindow with widget");
+
+ MOZ_ASSERT(
+ !mParent,
+ "nsWindow::ReparentNativeWidget() works on toplevel windows only.");
+
+ auto* newParent = static_cast<nsWindow*>(aNewParent);
+ GtkWindow* newParentWidget = GTK_WINDOW(newParent->GetGtkWidget());
+ GtkWindow* shell = GTK_WINDOW(mShell);
+
+ if (shell && gtk_window_get_transient_for(shell)) {
+ gtk_window_set_transient_for(shell, newParentWidget);
+ mToplevelParentWindow = newParentWidget;
+ }
+}
+
void nsWindow::SetModal(bool aModal) {
LOG(("nsWindow::SetModal [%p] %d\n", (void*)this, aModal));
if (mIsDestroyed) return;
diff -up firefox-69.0/widget/gtk/nsWindow.h.mozilla-1562827 firefox-69.0/widget/gtk/nsWindow.h

226
mozilla-1567434-1.patch Normal file
View File

@ -0,0 +1,226 @@
diff --git a/widget/gtk/WindowSurfaceWayland.cpp b/widget/gtk/WindowSurfaceWayland.cpp
--- a/widget/gtk/WindowSurfaceWayland.cpp
+++ b/widget/gtk/WindowSurfaceWayland.cpp
@@ -616,8 +616,6 @@
}
if (!aFullScreenUpdate) {
- NS_WARNING(
- "We can't create a new Wayland buffer for non-fullscreen updates!");
return nullptr;
}
@@ -674,8 +672,6 @@
(void*)buffer));
if (!buffer) {
- NS_WARNING(
- "WindowSurfaceWayland::LockWaylandBuffer(): No buffer available");
return nullptr;
}
diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h
--- a/widget/gtk/nsWindow.h
+++ b/widget/gtk/nsWindow.h
@@ -487,6 +487,7 @@
GtkWidget* mShell;
MozContainer* mContainer;
GdkWindow* mGdkWindow;
+ GtkWindow* mToplevelParentWindow;
bool mWindowShouldStartDragging = false;
PlatformCompositorWidgetDelegate* mCompositorWidgetDelegate;
diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -401,6 +401,7 @@
mContainer = nullptr;
mGdkWindow = nullptr;
mShell = nullptr;
+ mToplevelParentWindow = nullptr;
mCompositorWidgetDelegate = nullptr;
mHasMappedToplevel = false;
mIsFullyObscured = false;
@@ -1144,6 +1145,8 @@
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 @@
// 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 @@
// 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 @@
// 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 @@
}
}
+ 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 @@
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 @@
// 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 @@
// - 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 @@
}
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 @@
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 @@
// 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 @@
// 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 @@
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 @@
}
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 @@
#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));

35
mozilla-1567434-2.patch Normal file
View File

@ -0,0 +1,35 @@
diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -1208,6 +1208,7 @@
if (frame) {
menuPopupFrame = do_QueryFrame(frame);
}
+
// The popup is not fully created yet (we're called from
// nsWindow::Create()) or we're toplevel popup without parent.
// In both cases just use parent which was passed to nsWindow::Create().
@@ -1217,10 +1218,22 @@
return GTK_WIDGET(parentWidget);
}
+ LOG(("...[%p] is %s\n", (void*)this,
+ menuPopupFrame->IsContextMenu() ? "context menu" : "popup"));
+
nsWindow* parentWindow =
static_cast<nsWindow*>(menuPopupFrame->GetParentMenuWidget());
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).
+ // In this case use a parent given at nsWindow::Create().
+ if (!parentWindow && !menuPopupFrame->IsContextMenu()) {
+ parentWindow =
+ get_window_for_gtk_widget(GTK_WIDGET(mToplevelParentWindow));
+ }
+
if (!parentWindow) {
LOG(("...[%p] using active/visible popups as a parent [%p]\n",
(void*)this, gVisibleWaylandPopupWindows->data));

29
mozilla-1573813.patch Normal file
View File

@ -0,0 +1,29 @@
diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -6577,11 +6577,22 @@
}
gint nsWindow::GdkScaleFactor() {
+ // For popup windows with parent window we need to get scale factor of the
+ // parent window. Otherwise the scale factor of the popup is not updated
+ // during it's hidden.
+ GdkWindow* scaledGdkWindow = mGdkWindow;
+ if (mToplevelParentWindow) {
+ scaledGdkWindow = gtk_widget_get_window(GTK_WIDGET(mToplevelParentWindow));
+ // Fallback for windows which parent has been unrealized.
+ if (!scaledGdkWindow) {
+ scaledGdkWindow = mGdkWindow;
+ }
+ }
// Available as of GTK 3.10+
static auto sGdkWindowGetScaleFactorPtr =
(gint(*)(GdkWindow*))dlsym(RTLD_DEFAULT, "gdk_window_get_scale_factor");
- if (sGdkWindowGetScaleFactorPtr && mGdkWindow)
- return (*sGdkWindowGetScaleFactorPtr)(mGdkWindow);
+ if (sGdkWindowGetScaleFactorPtr && scaledGdkWindow)
+ return (*sGdkWindowGetScaleFactorPtr)(scaledGdkWindow);
return ScreenHelperGTK::GetGTKMonitorScaleFactor();
}

425
mozilla-1574036.patch Normal file
View File

@ -0,0 +1,425 @@
diff --git a/widget/gtk/WindowSurfaceWayland.h b/widget/gtk/WindowSurfaceWayland.h
--- a/widget/gtk/WindowSurfaceWayland.h
+++ b/widget/gtk/WindowSurfaceWayland.h
@@ -177,12 +177,9 @@
private:
WindowBackBuffer* CreateWaylandBuffer(int aWidth, int aHeight);
- WindowBackBuffer* GetWaylandBufferToDraw(int aWidth, int aHeight,
- bool aFullScreenUpdate);
+ WindowBackBuffer* GetWaylandBufferToDraw(bool aCanSwitchBuffer);
- already_AddRefed<gfx::DrawTarget> LockWaylandBuffer(int aWidth, int aHeight,
- bool aClearBuffer,
- bool aFullScreenUpdate);
+ already_AddRefed<gfx::DrawTarget> LockWaylandBuffer(bool aCanSwitchBuffer);
void UnlockWaylandBuffer();
already_AddRefed<gfx::DrawTarget> LockImageSurface(
@@ -198,7 +195,10 @@
// TODO: Do we need to hold a reference to nsWindow object?
nsWindow* mWindow;
- LayoutDeviceIntRect mLastScreenRect;
+ // Buffer screen rects helps us understand if we operate on
+ // the same window size as we're called on WindowSurfaceWayland::Lock().
+ // mBufferScreenRect is window size when our wayland buffer was allocated.
+ LayoutDeviceIntRect mBufferScreenRect;
nsWaylandDisplay* mWaylandDisplay;
WindowBackBuffer* mWaylandBuffer;
LayoutDeviceIntRegion mWaylandBufferDamage;
@@ -211,7 +211,8 @@
AutoTArray<WindowImageSurface, 30> mDelayedImageCommits;
bool mDrawToWaylandBufferDirectly;
bool mPendingCommit;
- bool mWaylandBufferFullScreenDamage;
+ bool mWholeWindowBufferDamage;
+ bool mBufferNeedsClear;
bool mIsMainThread;
bool mNeedScaleFactorUpdate;
diff --git a/widget/gtk/WindowSurfaceWayland.cpp b/widget/gtk/WindowSurfaceWayland.cpp
--- a/widget/gtk/WindowSurfaceWayland.cpp
+++ b/widget/gtk/WindowSurfaceWayland.cpp
@@ -499,7 +499,8 @@
mDelayedCommitHandle(nullptr),
mDrawToWaylandBufferDirectly(true),
mPendingCommit(false),
- mWaylandBufferFullScreenDamage(false),
+ mWholeWindowBufferDamage(false),
+ mBufferNeedsClear(false),
mIsMainThread(NS_IsMainThread()),
mNeedScaleFactorUpdate(true) {
for (int i = 0; i < BACK_BUFFER_NUM; i++) mBackupBuffer[i] = nullptr;
@@ -565,18 +566,20 @@
}
WindowBackBuffer* WindowSurfaceWayland::GetWaylandBufferToDraw(
- int aWidth, int aHeight, bool aFullScreenUpdate) {
+ bool aCanSwitchBuffer) {
LOGWAYLAND(("%s [%p] Requested buffer [%d x %d]\n", __PRETTY_FUNCTION__,
- (void*)this, aWidth, aHeight));
+ (void*)this, mBufferScreenRect.width, mBufferScreenRect.height));
// There's no buffer created yet, create a new one.
if (!mWaylandBuffer) {
- MOZ_ASSERT(aFullScreenUpdate, "Created new buffer for partial drawing!");
+ MOZ_ASSERT(aCanSwitchBuffer && mWholeWindowBufferDamage,
+ "Created new buffer for partial drawing!");
LOGWAYLAND(("%s [%p] Created new buffer [%d x %d]\n", __PRETTY_FUNCTION__,
- (void*)this, aWidth, aHeight));
+ (void*)this, mBufferScreenRect.width,
+ mBufferScreenRect.height));
- mWaylandBuffer = CreateWaylandBuffer(aWidth, aHeight);
- mWaylandBufferFullScreenDamage = true;
+ mWaylandBuffer =
+ CreateWaylandBuffer(mBufferScreenRect.width, mBufferScreenRect.height);
mNeedScaleFactorUpdate = true;
return mWaylandBuffer;
}
@@ -593,29 +596,31 @@
LOGWAYLAND(
("%s [%p] Use recent buffer.\n", __PRETTY_FUNCTION__, (void*)this));
- if (mWaylandBuffer->IsMatchingSize(aWidth, aHeight)) {
+ if (mWaylandBuffer->IsMatchingSize(mBufferScreenRect.width,
+ mBufferScreenRect.height)) {
LOGWAYLAND(("%s [%p] Size is ok, use the buffer [%d x %d]\n",
- __PRETTY_FUNCTION__, (void*)this, aWidth, aHeight));
+ __PRETTY_FUNCTION__, (void*)this, mBufferScreenRect.width,
+ mBufferScreenRect.height));
return mWaylandBuffer;
}
- if (!aFullScreenUpdate) {
+ if (!aCanSwitchBuffer) {
NS_WARNING("We can't resize Wayland buffer for non-fullscreen updates!");
return nullptr;
}
LOGWAYLAND(("%s [%p] Reuse buffer with resize [%d x %d]\n",
- __PRETTY_FUNCTION__, (void*)this, aWidth, aHeight));
+ __PRETTY_FUNCTION__, (void*)this, mBufferScreenRect.width,
+ mBufferScreenRect.height));
- mWaylandBuffer->Resize(aWidth, aHeight);
+ mWaylandBuffer->Resize(mBufferScreenRect.width, mBufferScreenRect.height);
// There's a chance that scale factor has been changed
// when buffer size changed
- mWaylandBufferFullScreenDamage = true;
mNeedScaleFactorUpdate = true;
return mWaylandBuffer;
}
- if (!aFullScreenUpdate) {
+ if (!aCanSwitchBuffer) {
return nullptr;
}
@@ -625,8 +630,10 @@
availableBuffer++) {
if (!mBackupBuffer[availableBuffer]) {
LOGWAYLAND(("%s [%p] Created new buffer [%d x %d]\n", __PRETTY_FUNCTION__,
- (void*)this, aWidth, aHeight));
- mBackupBuffer[availableBuffer] = CreateWaylandBuffer(aWidth, aHeight);
+ (void*)this, mBufferScreenRect.width,
+ mBufferScreenRect.height));
+ mBackupBuffer[availableBuffer] = CreateWaylandBuffer(
+ mBufferScreenRect.width, mBufferScreenRect.height);
break;
}
@@ -650,23 +657,23 @@
__PRETTY_FUNCTION__, (void*)this, (void*)lastWaylandBuffer,
(void*)mWaylandBuffer));
- mWaylandBufferFullScreenDamage = true;
mNeedScaleFactorUpdate = true;
- bool bufferNeedsResize = !mWaylandBuffer->IsMatchingSize(aWidth, aHeight);
+ bool bufferNeedsResize = !mWaylandBuffer->IsMatchingSize(
+ mBufferScreenRect.width, mBufferScreenRect.height);
if (bufferNeedsResize) {
LOGWAYLAND(("%s [%p] Resize buffer to [%d x %d]\n", __PRETTY_FUNCTION__,
- (void*)this, aWidth, aHeight));
- mWaylandBuffer->Resize(aWidth, aHeight);
+ (void*)this, mBufferScreenRect.width,
+ mBufferScreenRect.height));
+ mWaylandBuffer->Resize(mBufferScreenRect.width, mBufferScreenRect.height);
}
return mWaylandBuffer;
}
already_AddRefed<gfx::DrawTarget> WindowSurfaceWayland::LockWaylandBuffer(
- int aWidth, int aHeight, bool aClearBuffer, bool aFullScreenUpdate) {
- WindowBackBuffer* buffer =
- GetWaylandBufferToDraw(aWidth, aHeight, aFullScreenUpdate);
+ bool aCanSwitchBuffer) {
+ WindowBackBuffer* buffer = GetWaylandBufferToDraw(aCanSwitchBuffer);
LOGWAYLAND(("%s [%p] Got buffer %p\n", __PRETTY_FUNCTION__, (void*)this,
(void*)buffer));
@@ -675,8 +682,9 @@
return nullptr;
}
- if (aClearBuffer) {
+ if (mBufferNeedsClear && mWholeWindowBufferDamage) {
buffer->Clear();
+ mBufferNeedsClear = false;
}
return buffer->Lock();
@@ -744,7 +752,7 @@
const LayoutDeviceIntRegion& aRegion) {
MOZ_ASSERT(mIsMainThread == NS_IsMainThread());
- LayoutDeviceIntRect screenRect = mWindow->GetBounds();
+ LayoutDeviceIntRect lockedScreenRect = mWindow->GetBounds();
gfx::IntRect bounds = aRegion.GetBounds().ToUnknownRect();
gfx::IntSize lockSize(bounds.XMost(), bounds.YMost());
@@ -753,54 +761,77 @@
mWindow->IsWaylandPopup() &&
(eTransparencyTransparent == mWindow->GetTransparencyMode());
- mDrawToWaylandBufferDirectly =
- isTransparentPopup ? IsPopupFullScreenUpdate(screenRect, aRegion)
- : IsWindowFullScreenUpdate(screenRect, aRegion);
+ // We have request to lock whole buffer/window.
+ mWholeWindowBufferDamage =
+ isTransparentPopup ? IsPopupFullScreenUpdate(lockedScreenRect, aRegion)
+ : IsWindowFullScreenUpdate(lockedScreenRect, aRegion);
- bool needsClear = mWindow->WaylandSurfaceNeedsClear() ||
- (isTransparentPopup && mDrawToWaylandBufferDirectly);
+ // Clear buffer when we (re)draw new transparent popup window,
+ // otherwise leave it as-is, mBufferNeedsClear can be set from previous
+ // (already pending) commits which are cached now.
+ if (mWholeWindowBufferDamage) {
+ mBufferNeedsClear =
+ mWindow->WaylandSurfaceNeedsClear() || isTransparentPopup;
+ }
LOGWAYLAND(("%s [%p] lockSize [%d x %d] windowSize [%d x %d]\n",
__PRETTY_FUNCTION__, (void*)this, lockSize.width, lockSize.height,
- screenRect.width, screenRect.height));
+ lockedScreenRect.width, lockedScreenRect.height));
LOGWAYLAND((" nsWindow = %p\n", mWindow));
LOGWAYLAND((" isPopup = %d\n", mWindow->IsWaylandPopup()));
LOGWAYLAND((" isTransparentPopup = %d\n", isTransparentPopup));
LOGWAYLAND((" IsPopupFullScreenUpdate = %d\n",
- IsPopupFullScreenUpdate(screenRect, aRegion)));
+ IsPopupFullScreenUpdate(lockedScreenRect, aRegion)));
LOGWAYLAND((" IsWindowFullScreenUpdate = %d\n",
- IsWindowFullScreenUpdate(screenRect, aRegion)));
- LOGWAYLAND((" needsClear = %d\n", needsClear));
- LOGWAYLAND(
- (" mDrawToWaylandBufferDirectly = %d\n", mDrawToWaylandBufferDirectly));
+ IsWindowFullScreenUpdate(lockedScreenRect, aRegion)));
+ LOGWAYLAND((" mBufferNeedsClear = %d\n", mBufferNeedsClear));
+ LOGWAYLAND((" mWholeWindowBufferDamage = %d\n", mWholeWindowBufferDamage));
+
+#if DEBUG
+ if (!(mBufferScreenRect == lockedScreenRect)) {
+ LOGWAYLAND((" screen size changed\n"));
+ }
+#endif
- // Allow full screen allocation and clear
- // when window size changed.
- bool bufferRedraw = !(screenRect == mLastScreenRect);
- if (bufferRedraw) {
- mDrawToWaylandBufferDirectly = true;
- needsClear = true;
+ if (!(mBufferScreenRect == lockedScreenRect)) {
+ // Screen (window) size changed and we still have some painting pending
+ // for the last window size. That can happen when window is resized.
+ // We can't commit them any more as they're for former window size, so
+ // scratch them.
+ mDelayedImageCommits.Clear();
+
+ if (!mWholeWindowBufferDamage) {
+ NS_WARNING("Partial screen update when window is resized!");
+ // This should not happen. Screen size changed but we got only
+ // partal screen update instead of whole screen. Discard this painting
+ // as it produces artifacts.
+ return nullptr;
+ }
+ mBufferScreenRect = lockedScreenRect;
}
- if (mDrawToWaylandBufferDirectly) {
+ if (mWholeWindowBufferDamage) {
+ // We can lock/commit entire buffer direcly.
+ mDrawToWaylandBufferDirectly = true;
+
// If there's any pending image commit scratch them as we're going
// to redraw the whole sceen anyway.
mDelayedImageCommits.Clear();
- RefPtr<gfx::DrawTarget> dt =
- LockWaylandBuffer(screenRect.width, screenRect.height, needsClear,
- /* aFullScreenUpdate */ true);
+ RefPtr<gfx::DrawTarget> dt = LockWaylandBuffer(
+ /* aCanSwitchBuffer */ mWholeWindowBufferDamage);
if (dt) {
- if (bufferRedraw) {
- mLastScreenRect = screenRect;
- }
return dt.forget();
}
+ }
- // We don't have any front buffer available. Try indirect drawing
- // to mImageSurface which is mirrored to front buffer at commit.
- mDrawToWaylandBufferDirectly = false;
- }
+ // We do indirect drawing due to:
+ //
+ // 1) We don't have any front buffer available. Try indirect drawing
+ // to mImageSurface which is mirrored to front buffer at commit.
+ // 2) Only part of the screen is locked. We can't lock entire screen for
+ // such drawing as it produces visible artifacts.
+ mDrawToWaylandBufferDirectly = false;
LOGWAYLAND((" Indirect drawing.\n"));
return LockImageSurface(lockSize);
@@ -851,16 +882,14 @@
LayoutDeviceIntRegion& aWaylandBufferDamage) {
MOZ_ASSERT(!mDrawToWaylandBufferDirectly);
- LayoutDeviceIntRect screenRect = mWindow->GetBounds();
+#ifdef DEBUG
gfx::IntRect bounds = aRegion.GetBounds().ToUnknownRect();
-
gfx::Rect rect(bounds);
- if (rect.IsEmpty()) {
- return false;
- }
+ MOZ_ASSERT(!rect.IsEmpty(), "Empty drawing?");
+#endif
LOGWAYLAND(("%s [%p] screenSize [%d x %d]\n", __PRETTY_FUNCTION__,
- (void*)this, screenRect.width, screenRect.height));
+ (void*)this, mBufferScreenRect.width, mBufferScreenRect.height));
RefPtr<gfx::SourceSurface> surf =
gfx::Factory::CreateSourceSurfaceForCairoSurface(
@@ -871,13 +900,8 @@
return false;
}
- // Allow full screen allocation and clear
- // when window size changed.
- bool bufferRedraw = !(screenRect == mLastScreenRect);
- RefPtr<gfx::DrawTarget> dt =
- LockWaylandBuffer(screenRect.width, screenRect.height,
- /* needs clear*/ bufferRedraw,
- /* aFullScreenUpdate */ bufferRedraw);
+ RefPtr<gfx::DrawTarget> dt = LockWaylandBuffer(
+ /* aCanSwitchBuffer */ mWholeWindowBufferDamage);
if (dt) {
LOGWAYLAND(
(" Flushing %ld cached WindowImageSurfaces to Wayland buffer\n",
@@ -885,14 +909,11 @@
// Draw any delayed image commits first
DrawDelayedImageCommits(dt, aWaylandBufferDamage);
+ // Draw image from recent WindowSurfaceWayland::Lock().
WindowImageSurface::Draw(surf, dt, aRegion);
// Submit all drawing to final Wayland buffer upload
aWaylandBufferDamage.OrWith(aRegion);
UnlockWaylandBuffer();
-
- if (bufferRedraw) {
- mLastScreenRect = screenRect;
- }
} else {
mDelayedImageCommits.AppendElement(WindowImageSurface(surf, aRegion));
LOGWAYLAND((" Added WindowImageSurfaces, cached surfaces %ld\n",
@@ -930,29 +951,25 @@
LOGWAYLAND(("%s [%p]\n", __PRETTY_FUNCTION__, (void*)this));
LOGWAYLAND(
(" mDrawToWaylandBufferDirectly = %d\n", mDrawToWaylandBufferDirectly));
- LOGWAYLAND((" mWaylandBufferFullScreenDamage = %d\n",
- mWaylandBufferFullScreenDamage));
+ LOGWAYLAND((" mWholeWindowBufferDamage = %d\n", mWholeWindowBufferDamage));
LOGWAYLAND((" mDelayedCommitHandle = %p\n", mDelayedCommitHandle));
LOGWAYLAND((" mFrameCallback = %p\n", mFrameCallback));
LOGWAYLAND((" mLastCommittedSurface = %p\n", mLastCommittedSurface));
if (!mDrawToWaylandBufferDirectly) {
+ MOZ_ASSERT(mDelayedImageCommits.Length(),
+ "Indirect drawing without any image?");
+
// There's some cached drawings - try to flush them now.
- LayoutDeviceIntRect screenRect = mWindow->GetBounds();
- bool bufferRedraw = !(screenRect == mLastScreenRect);
- RefPtr<gfx::DrawTarget> dt =
- LockWaylandBuffer(screenRect.width, screenRect.height,
- /* needsClear */ bufferRedraw,
- /* full screen update */ bufferRedraw);
+ RefPtr<gfx::DrawTarget> dt = LockWaylandBuffer(
+ /* aCanSwitchBuffer */ mWholeWindowBufferDamage);
+
if (dt) {
LOGWAYLAND(("%s [%p] flushed indirect drawing\n", __PRETTY_FUNCTION__,
(void*)this));
DrawDelayedImageCommits(dt, mWaylandBufferDamage);
UnlockWaylandBuffer();
mDrawToWaylandBufferDirectly = true;
- if (bufferRedraw) {
- mLastScreenRect = screenRect;
- }
}
}
@@ -1000,10 +1017,10 @@
mLastCommittedSurface = nullptr;
}
- if (mWaylandBufferFullScreenDamage) {
- LayoutDeviceIntRect rect = mWindow->GetBounds();
- wl_surface_damage(waylandSurface, 0, 0, rect.width, rect.height);
- mWaylandBufferFullScreenDamage = false;
+ if (mWholeWindowBufferDamage) {
+ wl_surface_damage(waylandSurface, 0, 0, mBufferScreenRect.width,
+ mBufferScreenRect.height);
+ mWholeWindowBufferDamage = false;
mNeedScaleFactorUpdate = true;
} else {
gint scaleFactor = mWindow->GdkScaleFactor();
@@ -1043,24 +1060,24 @@
#ifdef DEBUG
{
- LayoutDeviceIntRect screenRect = mWindow->GetBounds();
gfx::IntRect bounds = aInvalidRegion.GetBounds().ToUnknownRect();
gfx::IntSize lockSize(bounds.XMost(), bounds.YMost());
LOGWAYLAND(("%s [%p] lockSize [%d x %d] screenSize [%d x %d]\n",
__PRETTY_FUNCTION__, (void*)this, lockSize.width,
- lockSize.height, screenRect.width, screenRect.height));
+ lockSize.height, mBufferScreenRect.width,
+ mBufferScreenRect.height));
LOGWAYLAND((" mDrawToWaylandBufferDirectly = %d\n",
mDrawToWaylandBufferDirectly));
- LOGWAYLAND((" mWaylandBufferFullScreenDamage = %d\n",
- mWaylandBufferFullScreenDamage));
+ LOGWAYLAND(
+ (" mWholeWindowBufferDamage = %d\n", mWholeWindowBufferDamage));
}
#endif
if (mDrawToWaylandBufferDirectly) {
MOZ_ASSERT(mWaylandBuffer->IsLocked());
// If we're not at fullscreen damage add drawing area from aInvalidRegion
- if (!mWaylandBufferFullScreenDamage) {
+ if (!mWholeWindowBufferDamage) {
mWaylandBufferDamage.OrWith(aInvalidRegion);
}
UnlockWaylandBuffer();

17
mozilla-1576268.patch Normal file
View File

@ -0,0 +1,17 @@
diff --git a/widget/gtk/nsClipboardWayland.cpp b/widget/gtk/nsClipboardWayland.cpp
--- a/widget/gtk/nsClipboardWayland.cpp
+++ b/widget/gtk/nsClipboardWayland.cpp
@@ -195,6 +195,12 @@
uint32_t all_actions = WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY |
WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE;
+ /* Default to move D&D action (Bug 1576268).
+ */
+ if (dnd_actions == 0) {
+ all_actions = WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE;
+ }
+
wl_data_offer_set_actions(mWaylandDataOffer, all_actions, dnd_actions);
/* Workaround Wayland D&D architecture here. To get the data_device_drop()