Merge branch 'master' into f31
This commit is contained in:
commit
749fe62a4f
370
D49289-wayland-monitor-size.diff
Normal file
370
D49289-wayland-monitor-size.diff
Normal file
@ -0,0 +1,370 @@
|
||||
diff --git a/layout/xul/nsMenuPopupFrame.cpp b/layout/xul/nsMenuPopupFrame.cpp
|
||||
--- a/layout/xul/nsMenuPopupFrame.cpp
|
||||
+++ b/layout/xul/nsMenuPopupFrame.cpp
|
||||
@@ -1502,7 +1502,7 @@
|
||||
|
||||
nscoord oldAlignmentOffset = mAlignmentOffset;
|
||||
|
||||
- bool inWayland = false;
|
||||
+ static bool inWayland = false;
|
||||
#ifdef MOZ_WAYLAND
|
||||
inWayland = !GDK_IS_X11_DISPLAY(gdk_display_get_default());
|
||||
#endif
|
||||
@@ -1512,9 +1512,9 @@
|
||||
// However, if a panel is already constrained or flipped (mIsOffset), then we
|
||||
// want to continue to calculate this. Also, always do this for content
|
||||
// shells, so that the popup doesn't extend outside the containing frame.
|
||||
- if (!inWayland && (mInContentShell || (mFlip != FlipType_None &&
|
||||
- (!aIsMove || mIsOffset ||
|
||||
- mPopupType != ePopupTypePanel)))) {
|
||||
+ if (mInContentShell ||
|
||||
+ (mFlip != FlipType_None &&
|
||||
+ (!aIsMove || mIsOffset || mPopupType != ePopupTypePanel))) {
|
||||
int32_t appPerDev = presContext->AppUnitsPerDevPixel();
|
||||
LayoutDeviceIntRect anchorRectDevPix =
|
||||
LayoutDeviceIntRect::FromAppUnitsToNearest(anchorRect, appPerDev);
|
||||
@@ -1532,60 +1532,66 @@
|
||||
if (mRect.width > screenRect.width) mRect.width = screenRect.width;
|
||||
if (mRect.height > screenRect.height) mRect.height = screenRect.height;
|
||||
|
||||
- // at this point the anchor (anchorRect) is within the available screen
|
||||
- // area (screenRect) and the popup is known to be no larger than the screen.
|
||||
+ // We can't get the subsequent change of the popup position under
|
||||
+ // waylande where gdk_window_move_to_rect is used to place them
|
||||
+ // because we don't know the absolute position of the window on the screen.
|
||||
+ if (!inWayland) {
|
||||
+ // at this point the anchor (anchorRect) is within the available screen
|
||||
+ // area (screenRect) and the popup is known to be no larger than the
|
||||
+ // screen.
|
||||
|
||||
- // We might want to "slide" an arrow if the panel is of the correct type -
|
||||
- // but we can only slide on one axis - the other axis must be "flipped or
|
||||
- // resized" as normal.
|
||||
- bool slideHorizontal = false, slideVertical = false;
|
||||
- if (mFlip == FlipType_Slide) {
|
||||
- int8_t position = GetAlignmentPosition();
|
||||
- slideHorizontal = position >= POPUPPOSITION_BEFORESTART &&
|
||||
- position <= POPUPPOSITION_AFTEREND;
|
||||
- slideVertical = position >= POPUPPOSITION_STARTBEFORE &&
|
||||
- position <= POPUPPOSITION_ENDAFTER;
|
||||
- }
|
||||
+ // We might want to "slide" an arrow if the panel is of the correct type -
|
||||
+ // but we can only slide on one axis - the other axis must be "flipped or
|
||||
+ // resized" as normal.
|
||||
+ bool slideHorizontal = false, slideVertical = false;
|
||||
+ if (mFlip == FlipType_Slide) {
|
||||
+ int8_t position = GetAlignmentPosition();
|
||||
+ slideHorizontal = position >= POPUPPOSITION_BEFORESTART &&
|
||||
+ position <= POPUPPOSITION_AFTEREND;
|
||||
+ slideVertical = position >= POPUPPOSITION_STARTBEFORE &&
|
||||
+ position <= POPUPPOSITION_ENDAFTER;
|
||||
+ }
|
||||
|
||||
- // Next, check if there is enough space to show the popup at full size when
|
||||
- // positioned at screenPoint. If not, flip the popups to the opposite side
|
||||
- // of their anchor point, or resize them as necessary.
|
||||
- bool endAligned = IsDirectionRTL()
|
||||
- ? mPopupAlignment == POPUPALIGNMENT_TOPLEFT ||
|
||||
- mPopupAlignment == POPUPALIGNMENT_BOTTOMLEFT
|
||||
- : mPopupAlignment == POPUPALIGNMENT_TOPRIGHT ||
|
||||
- mPopupAlignment == POPUPALIGNMENT_BOTTOMRIGHT;
|
||||
- nscoord preOffsetScreenPoint = screenPoint.x;
|
||||
- if (slideHorizontal) {
|
||||
- mRect.width = SlideOrResize(screenPoint.x, mRect.width, screenRect.x,
|
||||
- screenRect.XMost(), &mAlignmentOffset);
|
||||
- } else {
|
||||
- mRect.width = FlipOrResize(
|
||||
- screenPoint.x, mRect.width, screenRect.x, screenRect.XMost(),
|
||||
- anchorRect.x, anchorRect.XMost(), margin.left, margin.right,
|
||||
- offsetForContextMenu.x, hFlip, endAligned, &mHFlip);
|
||||
- }
|
||||
- mIsOffset = preOffsetScreenPoint != screenPoint.x;
|
||||
+ // Next, check if there is enough space to show the popup at full size
|
||||
+ // when positioned at screenPoint. If not, flip the popups to the opposite
|
||||
+ // side of their anchor point, or resize them as necessary.
|
||||
+ bool endAligned = IsDirectionRTL()
|
||||
+ ? mPopupAlignment == POPUPALIGNMENT_TOPLEFT ||
|
||||
+ mPopupAlignment == POPUPALIGNMENT_BOTTOMLEFT
|
||||
+ : mPopupAlignment == POPUPALIGNMENT_TOPRIGHT ||
|
||||
+ mPopupAlignment == POPUPALIGNMENT_BOTTOMRIGHT;
|
||||
+ nscoord preOffsetScreenPoint = screenPoint.x;
|
||||
+ if (slideHorizontal) {
|
||||
+ mRect.width = SlideOrResize(screenPoint.x, mRect.width, screenRect.x,
|
||||
+ screenRect.XMost(), &mAlignmentOffset);
|
||||
+ } else {
|
||||
+ mRect.width = FlipOrResize(
|
||||
+ screenPoint.x, mRect.width, screenRect.x, screenRect.XMost(),
|
||||
+ anchorRect.x, anchorRect.XMost(), margin.left, margin.right,
|
||||
+ offsetForContextMenu.x, hFlip, endAligned, &mHFlip);
|
||||
+ }
|
||||
+ mIsOffset = preOffsetScreenPoint != screenPoint.x;
|
||||
|
||||
- endAligned = mPopupAlignment == POPUPALIGNMENT_BOTTOMLEFT ||
|
||||
- mPopupAlignment == POPUPALIGNMENT_BOTTOMRIGHT;
|
||||
- preOffsetScreenPoint = screenPoint.y;
|
||||
- if (slideVertical) {
|
||||
- mRect.height = SlideOrResize(screenPoint.y, mRect.height, screenRect.y,
|
||||
- screenRect.YMost(), &mAlignmentOffset);
|
||||
- } else {
|
||||
- mRect.height = FlipOrResize(
|
||||
- screenPoint.y, mRect.height, screenRect.y, screenRect.YMost(),
|
||||
- anchorRect.y, anchorRect.YMost(), margin.top, margin.bottom,
|
||||
- offsetForContextMenu.y, vFlip, endAligned, &mVFlip);
|
||||
+ endAligned = mPopupAlignment == POPUPALIGNMENT_BOTTOMLEFT ||
|
||||
+ mPopupAlignment == POPUPALIGNMENT_BOTTOMRIGHT;
|
||||
+ preOffsetScreenPoint = screenPoint.y;
|
||||
+ if (slideVertical) {
|
||||
+ mRect.height = SlideOrResize(screenPoint.y, mRect.height, screenRect.y,
|
||||
+ screenRect.YMost(), &mAlignmentOffset);
|
||||
+ } else {
|
||||
+ mRect.height = FlipOrResize(
|
||||
+ screenPoint.y, mRect.height, screenRect.y, screenRect.YMost(),
|
||||
+ anchorRect.y, anchorRect.YMost(), margin.top, margin.bottom,
|
||||
+ offsetForContextMenu.y, vFlip, endAligned, &mVFlip);
|
||||
+ }
|
||||
+ mIsOffset = mIsOffset || (preOffsetScreenPoint != screenPoint.y);
|
||||
+
|
||||
+ NS_ASSERTION(screenPoint.x >= screenRect.x &&
|
||||
+ screenPoint.y >= screenRect.y &&
|
||||
+ screenPoint.x + mRect.width <= screenRect.XMost() &&
|
||||
+ screenPoint.y + mRect.height <= screenRect.YMost(),
|
||||
+ "Popup is offscreen");
|
||||
}
|
||||
- mIsOffset = mIsOffset || (preOffsetScreenPoint != screenPoint.y);
|
||||
-
|
||||
- NS_ASSERTION(screenPoint.x >= screenRect.x &&
|
||||
- screenPoint.y >= screenRect.y &&
|
||||
- screenPoint.x + mRect.width <= screenRect.XMost() &&
|
||||
- screenPoint.y + mRect.height <= screenRect.YMost(),
|
||||
- "Popup is offscreen");
|
||||
}
|
||||
|
||||
// snap the popup's position in screen coordinates to device pixels,
|
||||
@@ -1687,6 +1693,14 @@
|
||||
screen->GetAvailRect(&screenRectPixels.x, &screenRectPixels.y,
|
||||
&screenRectPixels.width, &screenRectPixels.height);
|
||||
}
|
||||
+#ifdef MOZ_WAYLAND
|
||||
+ else {
|
||||
+ if (GetWidget() &&
|
||||
+ GetWidget()->GetScreenRect(&screenRectPixels) != NS_OK) {
|
||||
+ NS_WARNING("Cannot get screen rect from widget!");
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
}
|
||||
|
||||
if (mInContentShell) {
|
||||
diff --git a/widget/ScreenManager.cpp b/widget/ScreenManager.cpp
|
||||
--- a/widget/ScreenManager.cpp
|
||||
+++ b/widget/ScreenManager.cpp
|
||||
@@ -11,6 +11,11 @@
|
||||
#include "mozilla/dom/DOMTypes.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
+#ifdef MOZ_WAYLAND
|
||||
+# include <gdk/gdk.h>
|
||||
+# include <gdk/gdkx.h>
|
||||
+# include <gdk/gdkwayland.h>
|
||||
+#endif /* MOZ_WAYLAND */
|
||||
|
||||
static mozilla::LazyLogModule sScreenLog("WidgetScreen");
|
||||
|
||||
@@ -104,6 +109,15 @@
|
||||
NS_IMETHODIMP
|
||||
ScreenManager::ScreenForRect(int32_t aX, int32_t aY, int32_t aWidth,
|
||||
int32_t aHeight, nsIScreen** aOutScreen) {
|
||||
+#ifdef MOZ_WAYLAND
|
||||
+ static bool inWayland = !GDK_IS_X11_DISPLAY(gdk_display_get_default());
|
||||
+
|
||||
+ if (inWayland) {
|
||||
+ *aOutScreen = nullptr;
|
||||
+ return NS_OK;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
if (mScreenList.IsEmpty()) {
|
||||
MOZ_LOG(sScreenLog, LogLevel::Warning,
|
||||
("No screen available. This can happen in xpcshell."));
|
||||
diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h
|
||||
--- a/widget/gtk/nsWindow.h
|
||||
+++ b/widget/gtk/nsWindow.h
|
||||
@@ -398,6 +398,9 @@
|
||||
static bool HideTitlebarByDefault();
|
||||
static bool GetTopLevelWindowActiveState(nsIFrame* aFrame);
|
||||
static bool TitlebarCanUseShapeMask();
|
||||
+#ifdef MOZ_WAYLAND
|
||||
+ virtual nsresult GetScreenRect(LayoutDeviceIntRect* aRect) override;
|
||||
+#endif
|
||||
|
||||
protected:
|
||||
virtual ~nsWindow();
|
||||
@@ -630,6 +633,7 @@
|
||||
void HideWaylandTooltips();
|
||||
void HideWaylandPopupAndAllChildren();
|
||||
void CleanupWaylandPopups();
|
||||
+ GtkWindow* GetCurrentTopmostWindow();
|
||||
|
||||
/**
|
||||
* |mIMContext| takes all IME related stuff.
|
||||
diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp
|
||||
--- a/widget/gtk/nsWindow.cpp
|
||||
+++ b/widget/gtk/nsWindow.cpp
|
||||
@@ -1294,10 +1294,14 @@
|
||||
GdkWindow* window, const GdkRectangle* flipped_rect,
|
||||
const GdkRectangle* final_rect, gboolean flipped_x, gboolean flipped_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));
|
||||
+ LOG(("%s [%p] flipped_x %d flipped_y %d\n", __FUNCTION__, aWindow, flipped_x,
|
||||
+ flipped_y));
|
||||
+
|
||||
+ LOG(("%s [%p] flipped %d %d w:%d h:%d\n", __FUNCTION__, aWindow,
|
||||
+ flipped_rect->x, flipped_rect->y, flipped_rect->width,
|
||||
+ flipped_rect->height));
|
||||
+ LOG(("%s [%p] final %d %d w:%d h:%d\n", __FUNCTION__, aWindow, final_rect->x,
|
||||
+ final_rect->y, final_rect->width, final_rect->height));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1384,6 +1388,16 @@
|
||||
HideWaylandWindow();
|
||||
}
|
||||
|
||||
+ LOG(
|
||||
+ ("nsWindow::NativeMoveResizeWaylandPopup [%p]: requested rect: x%d y%d "
|
||||
+ "w%d h%d\n",
|
||||
+ this, rect.x, rect.y, rect.width, rect.height));
|
||||
+ if (aSize) {
|
||||
+ LOG((" aSize: x%d y%d w%d h%d\n", aSize->x, aSize->y, aSize->width,
|
||||
+ aSize->height));
|
||||
+ } else {
|
||||
+ LOG((" No aSize given"));
|
||||
+ }
|
||||
sGdkWindowMoveToRect(gdkWindow, &rect, rectAnchor, menuAnchor, hints, 0, 0);
|
||||
|
||||
if (isWidgetVisible) {
|
||||
@@ -1399,7 +1413,8 @@
|
||||
LOG(("nsWindow::NativeMove [%p] %d %d\n", (void*)this, point.x, point.y));
|
||||
|
||||
if (IsWaylandPopup()) {
|
||||
- NativeMoveResizeWaylandPopup(&point, nullptr);
|
||||
+ GdkRectangle size = DevicePixelsToGdkSizeRoundUp(mBounds.Size());
|
||||
+ NativeMoveResizeWaylandPopup(&point, &size);
|
||||
} else if (mIsTopLevel) {
|
||||
gtk_window_move(GTK_WINDOW(mShell), point.x, point.y);
|
||||
} else if (mGdkWindow) {
|
||||
@@ -6724,6 +6739,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
+GtkWindow* nsWindow::GetCurrentTopmostWindow() {
|
||||
+ GtkWindow* parentWindow = GTK_WINDOW(GetGtkWidget());
|
||||
+ GtkWindow* topmostParentWindow;
|
||||
+ while (parentWindow) {
|
||||
+ topmostParentWindow = parentWindow;
|
||||
+ parentWindow = gtk_window_get_transient_for(parentWindow);
|
||||
+ }
|
||||
+ return topmostParentWindow;
|
||||
+}
|
||||
+
|
||||
gint nsWindow::GdkScaleFactor() {
|
||||
GdkWindow* scaledGdkWindow = mGdkWindow;
|
||||
if (!mIsX11Display) {
|
||||
@@ -6732,12 +6757,7 @@
|
||||
// not updated during it's hidden.
|
||||
if (mWindowType == eWindowType_popup || mWindowType == eWindowType_dialog) {
|
||||
// Get toplevel window for scale factor:
|
||||
- GtkWindow* parentWindow = GTK_WINDOW(GetGtkWidget());
|
||||
- GtkWindow* topmostParentWindow;
|
||||
- while (parentWindow) {
|
||||
- topmostParentWindow = parentWindow;
|
||||
- parentWindow = gtk_window_get_transient_for(parentWindow);
|
||||
- }
|
||||
+ GtkWindow* topmostParentWindow = GetCurrentTopmostWindow();
|
||||
if (topmostParentWindow) {
|
||||
scaledGdkWindow =
|
||||
gtk_widget_get_window(GTK_WIDGET(topmostParentWindow));
|
||||
@@ -7268,6 +7288,41 @@
|
||||
return window.forget();
|
||||
}
|
||||
|
||||
+#ifdef MOZ_WAYLAND
|
||||
+nsresult nsWindow::GetScreenRect(LayoutDeviceIntRect* aRect) {
|
||||
+ typedef struct _GdkMonitor GdkMonitor;
|
||||
+ static auto s_gdk_display_get_monitor_at_window =
|
||||
+ (GdkMonitor * (*)(GdkDisplay*, GdkWindow*))
|
||||
+ dlsym(RTLD_DEFAULT, "gdk_display_get_monitor_at_window");
|
||||
+
|
||||
+ static auto s_gdk_monitor_get_workarea =
|
||||
+ (void (*)(GdkMonitor*, GdkRectangle*))dlsym(RTLD_DEFAULT,
|
||||
+ "gdk_monitor_get_workarea");
|
||||
+
|
||||
+ if (!s_gdk_display_get_monitor_at_window || !s_gdk_monitor_get_workarea) {
|
||||
+ return NS_ERROR_NOT_IMPLEMENTED;
|
||||
+ }
|
||||
+
|
||||
+ GtkWindow* topmostParentWindow = GetCurrentTopmostWindow();
|
||||
+ GdkWindow* gdkWindow = gtk_widget_get_window(GTK_WIDGET(topmostParentWindow));
|
||||
+
|
||||
+ GdkMonitor* monitor =
|
||||
+ s_gdk_display_get_monitor_at_window(gdk_display_get_default(), gdkWindow);
|
||||
+ if (monitor) {
|
||||
+ GdkRectangle workArea;
|
||||
+ s_gdk_monitor_get_workarea(monitor, &workArea);
|
||||
+ aRect->x = workArea.x;
|
||||
+ aRect->y = workArea.y;
|
||||
+ aRect->width = workArea.width;
|
||||
+ aRect->height = workArea.height;
|
||||
+ LOG((" workarea for [%p], monitor %p: x%d y%d w%d h%d\n", this, monitor,
|
||||
+ workArea.x, workArea.y, workArea.width, workArea.height));
|
||||
+ return NS_OK;
|
||||
+ }
|
||||
+ return NS_ERROR_NOT_IMPLEMENTED;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
bool nsWindow::GetTopLevelWindowActiveState(nsIFrame* aFrame) {
|
||||
// Used by window frame and button box rendering. We can end up in here in
|
||||
// the content process when rendering one of these moz styles freely in a
|
||||
diff --git a/widget/moz.build b/widget/moz.build
|
||||
--- a/widget/moz.build
|
||||
+++ b/widget/moz.build
|
||||
@@ -210,7 +210,6 @@
|
||||
'PuppetBidiKeyboard.cpp',
|
||||
'PuppetWidget.cpp',
|
||||
'Screen.cpp',
|
||||
- 'ScreenManager.cpp',
|
||||
'SharedWidgetUtils.cpp',
|
||||
'TextEventDispatcher.cpp',
|
||||
'VsyncDispatcher.cpp',
|
||||
@@ -242,6 +241,7 @@
|
||||
SOURCES += [
|
||||
'nsBaseDragService.cpp',
|
||||
'nsBaseWidget.cpp',
|
||||
+ 'ScreenManager.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_INSTRUMENT_EVENT_LOOP']:
|
||||
diff --git a/widget/nsIWidget.h b/widget/nsIWidget.h
|
||||
--- a/widget/nsIWidget.h
|
||||
+++ b/widget/nsIWidget.h
|
||||
@@ -1713,6 +1713,15 @@
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
+ // Get rectangle of the screen where the window is placed.
|
||||
+ // It's used to detect popup overflow under Wayland because
|
||||
+ // Screenmanager does not work under it.
|
||||
+#ifdef MOZ_WAYLAND
|
||||
+ virtual nsresult GetScreenRect(LayoutDeviceIntRect* aRect) {
|
||||
+ return NS_ERROR_NOT_IMPLEMENTED;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
private:
|
||||
class LongTapInfo {
|
||||
public:
|
||||
|
@ -94,7 +94,7 @@ ExcludeArch: ppc64le
|
||||
Summary: Mozilla Firefox Web browser
|
||||
Name: firefox
|
||||
Version: 70.0.1
|
||||
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
|
||||
@ -152,6 +152,7 @@ Patch417: bug1375074-save-restore-x28.patch
|
||||
Patch419: mozilla-1568569.patch
|
||||
Patch421: mozilla-1579023.patch
|
||||
Patch422: mozilla-1580174-webrtc-popup.patch
|
||||
Patch423: D49289-wayland-monitor-size.diff
|
||||
|
||||
# Wayland specific upstream patches
|
||||
Patch574: firefox-pipewire.patch
|
||||
@ -361,6 +362,7 @@ This package contains results of tests executed during build.
|
||||
%endif
|
||||
%patch419 -p1 -b .1568569
|
||||
%patch421 -p1 -b .1579023
|
||||
%patch423 -p1 -b .D49289
|
||||
|
||||
# Wayland specific upstream patches
|
||||
%patch574 -p1 -b .firefox-pipewire
|
||||
@ -949,6 +951,9 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || :
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
%changelog
|
||||
* Mon Nov 04 2019 Jan Horak <jhorak@redhat.com> - 70.0.1-2
|
||||
- Added fix for non-scrollable popups
|
||||
|
||||
* Fri Nov 1 2019 Martin Stransky <stransky@redhat.com> - 70.0.1-1
|
||||
- Updated to 70.0.1
|
||||
- Built with system-nss (reverted 70.0-2 change).
|
||||
|
Loading…
Reference in New Issue
Block a user