summaryrefslogtreecommitdiff
path: root/D49289-wayland-monitor-size.diff
diff options
context:
space:
mode:
Diffstat (limited to 'D49289-wayland-monitor-size.diff')
-rw-r--r--D49289-wayland-monitor-size.diff370
1 files changed, 0 insertions, 370 deletions
diff --git a/D49289-wayland-monitor-size.diff b/D49289-wayland-monitor-size.diff
deleted file mode 100644
index ff2ce05..0000000
--- a/D49289-wayland-monitor-size.diff
+++ /dev/null
@@ -1,370 +0,0 @@
-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:
-
bgstack15