G_DEFINE_TYPE (GdkWaylandSurface, gdk_wayland_surface, GDK_TYPE_SURFACE)
-static void gdk_wayland_surface_maybe_resize (GdkSurface *surface,
- int width,
- int height,
- int scale);
-
static void gdk_wayland_surface_configure (GdkSurface *surface);
static void gdk_wayland_surface_sync_shadow (GdkSurface *surface);
static void
gdk_wayland_surface_init (GdkWaylandSurface *impl)
{
- impl->scale = 1;
+ impl->scale = GDK_FRACTIONAL_SCALE_INIT_INT (1);
}
void
gdk_wayland_surface_configure (surface);
}
+static void
+gdk_wayland_surface_maybe_resize (GdkSurface *surface,
+ int width,
+ int height,
+ const GdkFractionalScale *scale)
+{
+ GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
+ gboolean hide_temporarily;
+
+ if (surface->width == width &&
+ surface->height == height &&
+ gdk_fractional_scale_equal (&impl->scale, scale))
+ return;
+
+ /* For xdg_popup using an xdg_positioner, there is a race condition if
+ * the application tries to change the size after it's mapped, but before
+ * the initial configure is received, so hide and show the surface again
+ * force the new size onto the compositor. See bug #772505.
+ */
+ hide_temporarily = GDK_IS_WAYLAND_POPUP (surface) &&
+ gdk_surface_get_mapped (surface) &&
+ !impl->initial_configure_received;
+
+ if (hide_temporarily)
+ gdk_surface_hide (surface);
+
+ gdk_wayland_surface_update_size (surface, width, height, scale);
+
+ if (hide_temporarily)
+ gdk_wayland_surface_create_wl_surface (surface);
+}
+
void
-gdk_wayland_surface_update_size (GdkSurface *surface,
- int32_t width,
- int32_t height,
- int scale)
+gdk_wayland_surface_update_size (GdkSurface *surface,
+ int32_t width,
+ int32_t height,
+ const GdkFractionalScale *scale)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
gboolean width_changed, height_changed, scale_changed;
width_changed = surface->width != width;
height_changed = surface->height != height;
- scale_changed = impl->scale != scale;
+ scale_changed = !gdk_fractional_scale_equal (&impl->scale, scale);
if (!width_changed && !height_changed && !scale_changed)
return;
surface->width = width;
surface->height = height;
- impl->scale = scale;
+ if (scale_changed)
+ {
+ impl->scale = *scale;
+ impl->buffer_scale_dirty = TRUE;
+ }
if (impl->display_server.egl_window)
- wl_egl_window_resize (impl->display_server.egl_window, width * scale, height * scale, 0, 0);
- if (scale_changed)
- impl->buffer_scale_dirty = TRUE;
+ wl_egl_window_resize (impl->display_server.egl_window,
+ width * gdk_fractional_scale_to_int (scale),
+ height * gdk_fractional_scale_to_int (scale), 0, 0);
gdk_surface_invalidate_rect (surface, NULL);
return;
if (!impl->display_server.outputs)
+ return;
+
+ scale = 1;
+ for (l = impl->display_server.outputs; l != NULL; l = l->next)
{
- scale = impl->scale;
- }
- else
- {
- scale = 1;
- for (l = impl->display_server.outputs; l != NULL; l = l->next)
- {
- struct wl_output *output = l->data;
- uint32_t output_scale;
+ struct wl_output *output = l->data;
+ uint32_t output_scale;
- output_scale = gdk_wayland_display_get_output_scale (display_wayland,
- output);
- scale = MAX (scale, output_scale);
- }
+ output_scale = gdk_wayland_display_get_output_scale (display_wayland,
+ output);
+ scale = MAX (scale, output_scale);
}
/* Notify app that scale changed */
gdk_wayland_surface_maybe_resize (surface,
surface->width, surface->height,
- scale);
+ &GDK_FRACTIONAL_SCALE_INIT_INT (scale));
}
GdkSurface *
if (monitor)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
+ guint32 monitor_scale = gdk_monitor_get_scale_factor (monitor);
- impl->scale = gdk_monitor_get_scale_factor (monitor);
- if (impl->scale != 1)
- impl->buffer_scale_dirty = TRUE;
+ if (monitor_scale != 1)
+ {
+ impl->scale = GDK_FRACTIONAL_SCALE_INIT_INT (monitor_scale);
+ impl->buffer_scale_dirty = TRUE;
+ }
g_object_unref (monitor);
}
G_OBJECT_CLASS (gdk_wayland_surface_parent_class)->finalize (object);
}
-static void
-gdk_wayland_surface_maybe_resize (GdkSurface *surface,
- int width,
- int height,
- int scale)
-{
- GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
- gboolean hide_temporarily;
-
- if (surface->width == width &&
- surface->height == height &&
- impl->scale == scale)
- return;
-
- /* For xdg_popup using an xdg_positioner, there is a race condition if
- * the application tries to change the size after it's mapped, but before
- * the initial configure is received, so hide and show the surface again
- * force the new size onto the compositor. See bug #772505.
- */
- hide_temporarily = GDK_IS_WAYLAND_POPUP (surface) &&
- gdk_surface_get_mapped (surface) &&
- !impl->initial_configure_received;
-
- if (hide_temporarily)
- gdk_surface_hide (surface);
-
- gdk_wayland_surface_update_size (surface, width, height, scale);
-
- if (hide_temporarily)
- gdk_wayland_surface_create_wl_surface (surface);
-}
-
static void
gdk_wayland_surface_sync_shadow (GdkSurface *surface)
{
/* Only set the buffer scale if supported by the compositor */
if (wl_surface_get_version (impl->display_server.wl_surface) >= WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION)
- wl_surface_set_buffer_scale (impl->display_server.wl_surface, impl->scale);
+ wl_surface_set_buffer_scale (impl->display_server.wl_surface,
+ gdk_fractional_scale_to_int (&impl->scale));
impl->buffer_scale_dirty = FALSE;
}
/* Notify app that scale changed */
gdk_wayland_surface_maybe_resize (surface,
surface->width, surface->height,
- ceil (scale / 120.0));
+ &GDK_FRACTIONAL_SCALE_INIT (scale));
}
static const struct wp_fractional_scale_v1_listener fractional_scale_listener = {
impl->has_uncommitted_ack_configure = FALSE;
impl->input_region_dirty = TRUE;
impl->opaque_region_dirty = TRUE;
- if (impl->scale != 1)
+ if (!gdk_fractional_scale_equal (&impl->scale, &GDK_FRACTIONAL_SCALE_INIT_INT (1)))
impl->buffer_scale_dirty = TRUE;
impl->last_sent_window_geometry = (GdkRectangle) { 0 };
surface->x = x;
surface->y = y;
- gdk_wayland_surface_maybe_resize (surface, width, height, impl->scale);
+ gdk_wayland_surface_maybe_resize (surface, width, height, &impl->scale);
}
static void
if (GDK_SURFACE_DESTROYED (surface))
return 1;
- return impl->scale;
+ return gdk_fractional_scale_to_int (&impl->scale);
}
static void
{
impl->display_server.egl_window =
wl_egl_window_create (impl->display_server.wl_surface,
- surface->width * impl->scale,
- surface->height * impl->scale);
+ surface->width * gdk_fractional_scale_to_int (&impl->scale),
+ surface->height * gdk_fractional_scale_to_int (&impl->scale));
gdk_surface_set_egl_native_window (surface, impl->display_server.egl_window);
}
}