Skip to content

Commit

Permalink
[WPE] Consider actual available size instead of whole screen size for…
Browse files Browse the repository at this point in the history
… screen.availHeight and screen.availWidth

https://bugs.webkit.org/show_bug.cgi?id=278511

Reviewed by NOBODY (OOPS!).

Add new wpe_monitor_get_available_width/height API to report the
available screen size. This is used to feed JS's
screen.availWidth/availHeight[1]. If not possible to detect the available
dimensions, fallback to the previous behavior of using the whole screen
size, as it's also one of the accepted values in the spec:

> The Web-exposed available screen area is one of the following:
> The available area of the rendering surface of the output device, in CSS pixels.
> The area of the output device, in CSS pixels.

https://drafts.csswg.org/cssom-view/#dom-screen-availw

In Wayland, use the `xdg_toplevel::configure_bounds` event to get the
information from the compositor. Given Wayland design decisions, we
can't get the actual screen position of the client, so we default to
(0,0).

This is not a problem regarding the `availWidth/availHeight`,
which is the information settled currently in the CSS spec. For the
record, this position limitation might become an issue when Window
Management's `availLeft/availTop`[2] eventually become an accepted
standard. This limitation is described in the Window Management github,
in [3].

[1] https://developer.mozilla.org/en-US/docs/Web/API/Screen/availHeight
[2] https://w3c.github.io/window-management/#ref-for-dom-screendetailed-availleft
[3] w3c/window-management#68

* Source/WebKit/UIProcess/wpe/ScreenManagerWPE.cpp:
(WebKit::ScreenManager::collectScreenProperties const):
* Source/WebKit/WPEPlatform/wpe/WPEMonitor.cpp:
(wpeMonitorGetProperty):
(wpe_monitor_class_init):
(wpe_monitor_get_available_width):
(wpe_monitor_get_available_height):
(wpe_monitor_set_available_size):
* Source/WebKit/WPEPlatform/wpe/WPEMonitor.h:
* Source/WebKit/WPEPlatform/wpe/wayland/WPEDisplayWayland.cpp:
* Source/WebKit/WPEPlatform/wpe/wayland/WPEToplevelWayland.cpp:
(wpeToplevelWaylandConstructed):
  • Loading branch information
lauromoura committed Aug 22, 2024
1 parent 77eec0a commit eeb1b75
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 5 deletions.
4 changes: 3 additions & 1 deletion Source/WebKit/UIProcess/wpe/ScreenManagerWPE.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ ScreenProperties ScreenManager::collectScreenProperties() const

ScreenData data;
data.screenRect = FloatRect(wpe_monitor_get_x(monitor), wpe_monitor_get_y(monitor), width, height);
data.screenAvailableRect = data.screenRect;
// TODO: add some API to get the available position to support screen.availTop/Left if it become a standard in the future
// For now we're settling to 0,0 as Wayland doesn't provide this information to clients
data.screenAvailableRect = FloatRect(0, 0, wpe_monitor_get_available_width(monitor), wpe_monitor_get_available_height(monitor));
data.screenDepth = 24;
data.screenDepthPerComponent = 8;
data.screenSize = { wpe_monitor_get_physical_width(monitor), wpe_monitor_get_physical_height(monitor) };
Expand Down
100 changes: 100 additions & 0 deletions Source/WebKit/WPEPlatform/wpe/WPEMonitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ struct _WPEMonitorPrivate {
int y { -1 };
int width { -1 };
int height { -1 };
int availableWidth { -1 };
int availableHeight { -1 };
int physicalWidth { -1 };
int physicalHeight { -1 };
gdouble scale { 1 };
Expand All @@ -54,6 +56,8 @@ enum {
PROP_Y,
PROP_WIDTH,
PROP_HEIGHT,
PROP_AVAILABLE_WIDTH,
PROP_AVAILABLE_HEIGHT,
PROP_PHYSICAL_WIDTH,
PROP_PHYSICAL_HEIGHT,
PROP_SCALE,
Expand Down Expand Up @@ -84,6 +88,12 @@ static void wpeMonitorSetProperty(GObject* object, guint propId, const GValue* v
case PROP_HEIGHT:
wpe_monitor_set_size(monitor, -1, g_value_get_int(value));
break;
case PROP_AVAILABLE_WIDTH:
wpe_monitor_set_available_size(monitor, g_value_get_int(value), -1);
break;
case PROP_AVAILABLE_HEIGHT:
wpe_monitor_set_available_size(monitor, -1, g_value_get_int(value));
break;
case PROP_PHYSICAL_WIDTH:
wpe_monitor_set_physical_size(monitor, g_value_get_int(value), -1);
break;
Expand Down Expand Up @@ -121,6 +131,12 @@ static void wpeMonitorGetProperty(GObject* object, guint propId, GValue* value,
case PROP_HEIGHT:
g_value_set_int(value, wpe_monitor_get_height(monitor));
break;
case PROP_AVAILABLE_WIDTH:
g_value_set_int(value, wpe_monitor_get_available_width(monitor));
break;
case PROP_AVAILABLE_HEIGHT:
g_value_set_int(value, wpe_monitor_get_available_height(monitor));
break;
case PROP_PHYSICAL_WIDTH:
g_value_set_int(value, wpe_monitor_get_physical_width(monitor));
break;
Expand Down Expand Up @@ -204,6 +220,32 @@ static void wpe_monitor_class_init(WPEMonitorClass* monitorClass)
-1, G_MAXINT, -1,
WEBKIT_PARAM_READWRITE);

/**
* WPEMonitor:available-width:
*
* The available width of the monitor in logical coordinates. This is the
* width of the monitor excluding any reserved areas like docks or panels.
*/
sObjProperties[PROP_AVAILABLE_WIDTH] =
g_param_spec_int(
"available-width",
nullptr, nullptr,
-1, G_MAXINT, -1,
WEBKIT_PARAM_READWRITE);

/**
* WPEMonitor:available-height:
*
* The available height of the monitor in logical coordinates. This is the
* height of the monitor excluding any reserved areas like docks or panels.
*/
sObjProperties[PROP_AVAILABLE_HEIGHT] =
g_param_spec_int(
"available-height",
nullptr, nullptr,
-1, G_MAXINT, -1,
WEBKIT_PARAM_READWRITE);

/**
* WPEMonitor:physical-width:
*
Expand Down Expand Up @@ -398,6 +440,64 @@ void wpe_monitor_set_size(WPEMonitor* monitor, int width, int height)
}
}

/**
* wpe_monitor_get_available_width:
* @monitor: a #WPEMonitor
*
* Get the available width of @monitor in logical coordinates. This is the
* width of the monitor excluding any reserved areas like docks or panels.
*
* Returns: the available width of @monitor, or the full monitor width if available width could not be determined.
*/
int wpe_monitor_get_available_width(WPEMonitor* monitor)
{
g_return_val_if_fail(WPE_IS_MONITOR(monitor), -1);

return monitor->priv->availableWidth != -1 ? monitor->priv->availableWidth : monitor->priv->width;
}

/**
* wpe_monitor_get_available_height:
* @monitor: a #WPEMonitor
*
* Get the available height of @monitor in logical coordinates. This is the
* height of the monitor excluding any reserved areas like docks or panels.
*
* Returns: the available height of @monitor, or the full monitor height if available height could not be determined.
*/
int wpe_monitor_get_available_height(WPEMonitor* monitor)
{
g_return_val_if_fail(WPE_IS_MONITOR(monitor), -1);

return monitor->priv->availableHeight != -1 ? monitor->priv->availableHeight : monitor->priv->height;
}

/**
* wpe_monitor_set_available_size:
* @monitor: a #WPEMonitor
* @width: the available width, or -1
* @height: the available height, o -1
*
* Set the available size of @monitor in logical coordinates. This is the
* size of the monitor excluding any reserved areas like docks or panels.
*/
void wpe_monitor_set_available_size(WPEMonitor* monitor, int width, int height)
{
g_return_if_fail(WPE_IS_MONITOR(monitor));
g_return_if_fail(width == -1 || width >= 0);
g_return_if_fail(height == -1 || height >= 0);

if (width != -1 && width != monitor->priv->availableWidth) {
monitor->priv->availableWidth = width;
g_object_notify_by_pspec(G_OBJECT(monitor), sObjProperties[PROP_AVAILABLE_WIDTH]);
}

if (height != -1 && height != monitor->priv->availableHeight) {
monitor->priv->availableHeight = height;
g_object_notify_by_pspec(G_OBJECT(monitor), sObjProperties[PROP_AVAILABLE_HEIGHT]);
}
}

/**
* wpe_monitor_get_physical_width:
* @monitor: a #WPEMonitor
Expand Down
5 changes: 5 additions & 0 deletions Source/WebKit/WPEPlatform/wpe/WPEMonitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ WPE_API int wpe_monitor_get_height (WPEMonitor *monitor);
WPE_API void wpe_monitor_set_size (WPEMonitor *monitor,
int width,
int height);
WPE_API int wpe_monitor_get_available_width (WPEMonitor *monitor);
WPE_API int wpe_monitor_get_available_height(WPEMonitor *monitor);
WPE_API void wpe_monitor_set_available_size (WPEMonitor *monitor,
int width,
int height);
WPE_API int wpe_monitor_get_physical_width (WPEMonitor *monitor);
WPE_API int wpe_monitor_get_physical_height (WPEMonitor *monitor);
WPE_API void wpe_monitor_set_physical_size (WPEMonitor *monitor,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ const struct wl_registry_listener registryListener = {
if (!std::strcmp(interface, "wl_compositor"))
priv->wlCompositor = static_cast<struct wl_compositor*>(wl_registry_bind(registry, name, &wl_compositor_interface, std::min<uint32_t>(version, 5)));
else if (!std::strcmp(interface, "xdg_wm_base"))
priv->xdgWMBase = static_cast<struct xdg_wm_base*>(wl_registry_bind(registry, name, &xdg_wm_base_interface, 1));
priv->xdgWMBase = static_cast<struct xdg_wm_base*>(wl_registry_bind(registry, name, &xdg_wm_base_interface, std::min<uint32_t>(version, 4)));
// FIXME: support zxdg_shell_v6?
else if (!std::strcmp(interface, "wl_seat"))
priv->wlSeat = makeUnique<WPE::WaylandSeat>(static_cast<struct wl_seat*>(wl_registry_bind(registry, name, &wl_seat_interface, std::min<uint32_t>(version, 8))));
Expand Down
9 changes: 6 additions & 3 deletions Source/WebKit/WPEPlatform/wpe/wayland/WPEToplevelWayland.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -349,8 +349,11 @@ const struct xdg_toplevel_listener xdgToplevelListener = {
},
#ifdef XDG_TOPLEVEL_CONFIGURE_BOUNDS_SINCE_VERSION
// configure_bounds
[](void*, struct xdg_toplevel*, int32_t, int32_t)
[](void* data, struct xdg_toplevel*, int32_t width, int32_t height)
{
auto* priv = WPE_TOPLEVEL_WAYLAND(data)->priv;
if (priv->currentMonitor)
wpe_monitor_set_available_size(priv->currentMonitor.get(), width, height);
},
#endif
#ifdef XDG_TOPLEVEL_WM_CAPABILITIES_SINCE_VERSION
Expand Down Expand Up @@ -567,8 +570,6 @@ static void wpeToplevelWaylandConstructed(GObject *object)
zwp_linux_dmabuf_feedback_v1_add_listener(priv->dmabufFeedback, &linuxDMABufFeedbackListener, object);
}

wl_display_roundtrip(wpe_display_wayland_get_wl_display(display));

// Set the first monitor as the default one until enter monitor is emitted.
if (wpe_display_get_n_monitors(WPE_DISPLAY(display))) {
priv->currentMonitor = wpe_display_get_monitor(WPE_DISPLAY(display), 0);
Expand All @@ -578,6 +579,8 @@ static void wpeToplevelWaylandConstructed(GObject *object)
wpe_toplevel_scale_changed(toplevel, scale);
}

wl_display_roundtrip(wpe_display_wayland_get_wl_display(display));

if (auto* explicitSync = wpeDisplayWaylandGetLinuxExplicitSync(display))
priv->surfaceSync = zwp_linux_explicit_synchronization_v1_get_synchronization(explicitSync, priv->wlSurface);
}
Expand Down

0 comments on commit eeb1b75

Please sign in to comment.