mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-25 20:01:50 +00:00
Bug 1732682 [Wayland] Get screen sizes from workarea on KDE/Sway r=rmader
- Use gdk_screen_get_monitor_workarea() on KDE/Sway to get screen sizes as it's reported correctly there. - Remove unused code. Differential Revision: https://phabricator.services.mozilla.com/D127261
This commit is contained in:
parent
44f80d4fa7
commit
bf7116a05c
@ -129,30 +129,43 @@ static uint32_t GetGTKPixelDepth() {
|
||||
return gdk_visual_get_depth(visual);
|
||||
}
|
||||
|
||||
static bool IsGNOMECompositor() {
|
||||
const char* currentDesktop = getenv("XDG_CURRENT_DESKTOP");
|
||||
return currentDesktop && strstr(currentDesktop, "GNOME") != nullptr;
|
||||
}
|
||||
|
||||
static already_AddRefed<Screen> MakeScreenGtk(GdkScreen* aScreen,
|
||||
gint aMonitorNum) {
|
||||
GdkRectangle monitor;
|
||||
GdkRectangle workarea;
|
||||
gdk_screen_get_monitor_geometry(aScreen, aMonitorNum, &monitor);
|
||||
gdk_screen_get_monitor_workarea(aScreen, aMonitorNum, &workarea);
|
||||
gint gdkScaleFactor = ScreenHelperGTK::GetGTKMonitorScaleFactor(aMonitorNum);
|
||||
|
||||
// gdk_screen_get_monitor_geometry / workarea returns application pixels
|
||||
// (desktop pixels), so we need to convert it to device pixels with
|
||||
// gdkScaleFactor on X11.
|
||||
// GNOME/Wayland reports scales differently (Bug 1732682).
|
||||
gint geometryScaleFactor = 1;
|
||||
if (GdkIsX11Display()) {
|
||||
if (GdkIsX11Display() || (GdkIsWaylandDisplay() && !IsGNOMECompositor())) {
|
||||
geometryScaleFactor = gdkScaleFactor;
|
||||
}
|
||||
|
||||
LayoutDeviceIntRect rect(monitor.x * geometryScaleFactor,
|
||||
monitor.y * geometryScaleFactor,
|
||||
monitor.width * geometryScaleFactor,
|
||||
monitor.height * geometryScaleFactor);
|
||||
LayoutDeviceIntRect rect;
|
||||
|
||||
GdkRectangle workarea;
|
||||
gdk_screen_get_monitor_workarea(aScreen, aMonitorNum, &workarea);
|
||||
LayoutDeviceIntRect availRect(workarea.x * geometryScaleFactor,
|
||||
workarea.y * geometryScaleFactor,
|
||||
workarea.width * geometryScaleFactor,
|
||||
workarea.height * geometryScaleFactor);
|
||||
if (GdkIsX11Display()) {
|
||||
GdkRectangle monitor;
|
||||
gdk_screen_get_monitor_geometry(aScreen, aMonitorNum, &monitor);
|
||||
rect = LayoutDeviceIntRect(monitor.x * geometryScaleFactor,
|
||||
monitor.y * geometryScaleFactor,
|
||||
monitor.width * geometryScaleFactor,
|
||||
monitor.height * geometryScaleFactor);
|
||||
} else {
|
||||
// We use Gtk workarea on Wayland as it matches our needs (Bug 1732682).
|
||||
rect = availRect;
|
||||
}
|
||||
|
||||
uint32_t pixelDepth = GetGTKPixelDepth();
|
||||
|
||||
@ -173,11 +186,11 @@ static already_AddRefed<Screen> MakeScreenGtk(GdkScreen* aScreen,
|
||||
dpi = rect.height / (heightMM / MM_PER_INCH_FLOAT);
|
||||
}
|
||||
|
||||
MOZ_LOG(sScreenLog, LogLevel::Debug,
|
||||
("New screen [%d %d %d %d (%d %d %d %d) %d %f %f %f]", rect.x, rect.y,
|
||||
rect.width, rect.height, availRect.x, availRect.y, availRect.width,
|
||||
availRect.height, pixelDepth, contentsScale.scale,
|
||||
defaultCssScale.scale, dpi));
|
||||
LOG_SCREEN(
|
||||
("New monitor %d size [%d,%d -> %d x %d] depth %d scale %f CssScale %f "
|
||||
"DPI %f ]",
|
||||
aMonitorNum, rect.x, rect.y, rect.width, rect.height, pixelDepth,
|
||||
contentsScale.scale, defaultCssScale.scale, dpi));
|
||||
RefPtr<Screen> screen = new Screen(rect, availRect, pixelDepth, pixelDepth,
|
||||
contentsScale, defaultCssScale, dpi);
|
||||
return screen.forget();
|
||||
@ -315,57 +328,12 @@ static bool GdkMonitorGetWorkarea(GdkMonitor* monitor, GdkRectangle* workarea) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ScreenGetterWayland::MonitorUsesNonIntegerScale(int aMonitor) {
|
||||
static auto s_gdk_display_get_n_monitors =
|
||||
(int (*)(GdkDisplay*))dlsym(RTLD_DEFAULT, "gdk_display_get_n_monitors");
|
||||
static auto s_gdk_display_get_monitor = (GdkMonitor * (*)(GdkDisplay*, int))
|
||||
dlsym(RTLD_DEFAULT, "gdk_display_get_monitor");
|
||||
|
||||
if (!s_gdk_display_get_n_monitors || !s_gdk_display_get_monitor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int monitorNum = s_gdk_display_get_n_monitors(gdk_display_get_default());
|
||||
for (int m = 0; m < monitorNum; m++) {
|
||||
GdkMonitor* gdkMonitor =
|
||||
s_gdk_display_get_monitor(gdk_display_get_default(), m);
|
||||
if (!gdkMonitor) {
|
||||
return false;
|
||||
}
|
||||
GdkRectangle workArea;
|
||||
if (!GdkMonitorGetWorkarea(gdkMonitor, &workArea)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG_SCREEN(("Monitor %d Gtk workarea size %d x %d", m, workArea.width,
|
||||
workArea.height));
|
||||
LOG_SCREEN(("Monitor %d wl_output size %d x %d", aMonitor,
|
||||
mMonitors[aMonitor].width, mMonitors[aMonitor].height));
|
||||
|
||||
if (mMonitors[aMonitor].x == workArea.x &&
|
||||
mMonitors[aMonitor].y == workArea.y) {
|
||||
// When non-integer scale is used, wl_output reports framebuffer size
|
||||
// but Gtk reports downscaled logical size.
|
||||
return workArea.width < mMonitors[aMonitor].width &&
|
||||
workArea.height < mMonitors[aMonitor].height;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
already_AddRefed<Screen> ScreenGetterWayland::MakeScreenWayland(gint aMonitor) {
|
||||
MonitorConfig monitor = mMonitors[aMonitor];
|
||||
|
||||
// On GNOME/Mutter we use results from wl_output directly
|
||||
LayoutDeviceIntRect rect(monitor.x, monitor.y, monitor.width, monitor.height);
|
||||
|
||||
// Non integer scales are downscaled from upper scales so report screen sizes
|
||||
// as bigger ones.
|
||||
if (MonitorUsesNonIntegerScale(aMonitor)) {
|
||||
LOG_SCREEN(("Monitor %d uses non-integer scale", aMonitor));
|
||||
rect.width *= monitor.scale;
|
||||
rect.height *= monitor.scale;
|
||||
}
|
||||
|
||||
uint32_t pixelDepth = GetGTKPixelDepth();
|
||||
|
||||
// Use per-monitor scaling factor in gtk/wayland, or 1.0 otherwise.
|
||||
@ -438,7 +406,7 @@ int ScreenGetterWayland::GetMonitorForWindow(nsWindow* aWindow) {
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < mMonitors.Length(); i++) {
|
||||
// Although Gtk/Mutter are very creative in reporting various screens sizes
|
||||
// Although Gtk/Mutter is very creative in reporting various screens sizes
|
||||
// we can rely on Gtk work area start position to match wl_output.
|
||||
if (mMonitors[i].x == workArea.x && mMonitors[i].y == workArea.y) {
|
||||
LOG_SCREEN((" monitor %d values %d %d -> %d x %d", i, mMonitors[i].x,
|
||||
@ -461,29 +429,12 @@ RefPtr<nsIScreen> ScreenGetterWayland::GetScreenForWindow(nsWindow* aWindow) {
|
||||
}
|
||||
return mScreenList[monitor];
|
||||
}
|
||||
|
||||
void ScreenGetterWayland::GetScreenRectForWindow(nsWindow* aWindow,
|
||||
GdkRectangle* aRect) {
|
||||
int monitor = GetMonitorForWindow(aWindow);
|
||||
if (monitor < 0) {
|
||||
// fallback to first monitor
|
||||
monitor = 0;
|
||||
}
|
||||
aRect->x = aRect->y = 0;
|
||||
aRect->width = mMonitors[monitor].width;
|
||||
aRect->height = mMonitors[monitor].height;
|
||||
}
|
||||
#endif
|
||||
|
||||
RefPtr<nsIScreen> ScreenHelperGTK::GetScreenForWindow(nsWindow* aWindow) {
|
||||
return gScreenGetter->GetScreenForWindow(aWindow);
|
||||
}
|
||||
|
||||
void ScreenHelperGTK::GetScreenRectForWindow(nsWindow* aWindow,
|
||||
GdkRectangle* aRect) {
|
||||
gScreenGetter->GetScreenRectForWindow(aWindow, aRect);
|
||||
}
|
||||
|
||||
gint ScreenHelperGTK::GetGTKMonitorScaleFactor(gint aMonitorNum) {
|
||||
GdkScreen* screen = gdk_screen_get_default();
|
||||
return gdk_screen_get_monitor_scale_factor(screen, aMonitorNum);
|
||||
@ -494,9 +445,8 @@ ScreenHelperGTK::ScreenHelperGTK() {
|
||||
// Use ScreenGetterWayland on Gnome/Mutter only. It uses additional wl_output
|
||||
// to track screen size changes (which are wrongly reported by mutter)
|
||||
// and causes issues on Sway (Bug 1730476).
|
||||
const char* currentDesktop = getenv("XDG_CURRENT_DESKTOP");
|
||||
if (GdkIsWaylandDisplay() && currentDesktop &&
|
||||
strstr(currentDesktop, "GNOME")) {
|
||||
// https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/3941
|
||||
if (GdkIsWaylandDisplay() && IsGNOMECompositor()) {
|
||||
gScreenGetter = mozilla::MakeUnique<ScreenGetterWayland>();
|
||||
}
|
||||
#endif
|
||||
|
@ -31,7 +31,6 @@ class ScreenGetter {
|
||||
virtual RefPtr<nsIScreen> GetScreenForWindow(nsWindow* aWindow) {
|
||||
return nullptr;
|
||||
}
|
||||
virtual void GetScreenRectForWindow(nsWindow* aWindow, GdkRectangle* aRect){};
|
||||
};
|
||||
|
||||
class ScreenGetterGtk : public ScreenGetter {
|
||||
@ -84,7 +83,6 @@ class ScreenGetterWayland : public ScreenGetter {
|
||||
already_AddRefed<Screen> MakeScreenWayland(gint aMonitor);
|
||||
|
||||
RefPtr<nsIScreen> GetScreenForWindow(nsWindow* aWindow);
|
||||
void GetScreenRectForWindow(nsWindow* aWindow, GdkRectangle* aRect);
|
||||
|
||||
// For internal use from signal callback functions
|
||||
void RefreshScreens();
|
||||
@ -107,7 +105,6 @@ class ScreenHelperGTK final : public ScreenManager::Helper {
|
||||
|
||||
static gint GetGTKMonitorScaleFactor(gint aMonitorNum = 0);
|
||||
static RefPtr<nsIScreen> GetScreenForWindow(nsWindow* aWindow);
|
||||
static void GetScreenRectForWindow(nsWindow* aWindow, GdkRectangle* aRect);
|
||||
};
|
||||
|
||||
} // namespace widget
|
||||
|
Loading…
x
Reference in New Issue
Block a user