Merge branch 'wip/chergert/macos-fixes' into 'main'

various macOS fixes

See merge request GNOME/gtk!4424
This commit is contained in:
Matthias Clasen 2022-02-07 23:56:40 +00:00
commit 59eb9aeb73
11 changed files with 306 additions and 166 deletions

View File

@ -23,7 +23,6 @@
#include <CoreGraphics/CoreGraphics.h>
#include <cairo-quartz.h>
#import "GdkMacosCairoSubview.h"
#import "GdkMacosCairoView.h"
@ -33,7 +32,9 @@
-(void)dealloc
{
g_clear_pointer (&self->clip, cairo_region_destroy);
g_clear_pointer (&self->clip, g_array_unref);
g_clear_pointer (&self->damage, g_array_unref);
g_clear_pointer (&self->image, CGImageRelease);
[super dealloc];
}
@ -55,132 +56,67 @@
-(void)drawRect:(NSRect)rect
{
CGContextRef cgContext;
GdkSurface *gdk_surface;
cairo_surface_t *dest;
const NSRect *rects = NULL;
NSView *root_view;
NSInteger n_rects = 0;
NSRect abs_bounds;
cairo_t *cr;
CGRect image_rect;
CGRect abs_bounds;
CGSize scale;
int scale_factor;
int abs_height;
if (self->cairoSurface == NULL)
if (self->image == NULL)
return;
/* Acquire everything we need to do translations, drawing, etc */
gdk_surface = [self gdkSurface];
scale_factor = gdk_surface_get_scale_factor (gdk_surface);
root_view = [[self window] contentView];
cgContext = [[NSGraphicsContext currentContext] CGContext];
root_view = [[self window] contentView];
abs_bounds = [self convertRect:[self bounds] toView:root_view];
abs_height = CGImageGetHeight (self->image);
CGContextSaveGState (cgContext);
/* Translate scaling to remove HiDPI scaling from CGContext as
* cairo will be doing that for us already.
/* Clip while our context is still using matching coordinates
* to the self->clip region. This is usually just on the views
* for the shadow areas.
*/
CGContextAddRect (cgContext, [self bounds]);
if (self->clip != NULL)
{
for (guint i = 0; i < self->clip->len; i++)
CGContextAddRect (cgContext, g_array_index (self->clip, CGRect, i));
}
if (self->damage != NULL)
{
for (guint i = 0; i < self->damage->len; i++)
CGContextAddRect (cgContext, g_array_index (self->damage, CGRect, i));
}
CGContextClip (cgContext);
/* Scale/Translate so that the CGImageRef draws in proper format/placement */
scale = CGSizeMake (1.0, 1.0);
scale = CGContextConvertSizeToDeviceSpace (cgContext, scale);
CGContextScaleCTM (cgContext, 1.0 / scale.width, 1.0 / scale.height);
CGContextTranslateCTM (cgContext, -abs_bounds.origin.x, -abs_bounds.origin.y);
image_rect = CGRectMake (-abs_bounds.origin.x,
-abs_bounds.origin.y,
CGImageGetWidth (self->image),
CGImageGetHeight (self->image));
CGContextDrawImage (cgContext, image_rect, self->image);
/* Create the cairo surface to draw to the CGContext and translate
* coordinates so we can pretend we are in the same coordinate system
* as the GDK surface.
*/
dest = cairo_quartz_surface_create_for_cg_context (cgContext,
gdk_surface->width * scale_factor,
gdk_surface->height * scale_factor);
cairo_surface_set_device_scale (dest, scale_factor, scale_factor);
/* Create cairo context and translate things into the origin of
* the topmost contentView so that we just draw at 0,0 with a
* clip region to paint the surface.
*/
cr = cairo_create (dest);
cairo_translate (cr, -abs_bounds.origin.x, -abs_bounds.origin.y);
/* Apply the clip if provided one */
if (self->clip != NULL)
{
cairo_rectangle_int_t area;
n_rects = cairo_region_num_rectangles (self->clip);
for (guint i = 0; i < n_rects; i++)
{
cairo_region_get_rectangle (self->clip, i, &area);
cairo_rectangle (cr, area.x, area.y, area.width, area.height);
}
cairo_clip (cr);
}
/* Clip the cairo context based on the rectangles to be drawn
* within the bounding box :rect.
*/
[self getRectsBeingDrawn:&rects count:&n_rects];
for (NSInteger i = 0; i < n_rects; i++)
{
NSRect area = [self convertRect:rects[i] toView:root_view];
cairo_rectangle (cr,
area.origin.x, area.origin.y,
area.size.width, area.size.height);
}
cairo_clip (cr);
/* Now paint the surface (without blending) as we do not need
* any compositing here. The transparent regions (like shadows)
* are already on non-opaque layers.
*/
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
cairo_set_source_surface (cr, self->cairoSurface, 0, 0);
cairo_paint (cr);
/* Cleanup state, flush the surface to the backing layer, and
* restore GState for future use.
*/
cairo_destroy (cr);
cairo_surface_flush (dest);
cairo_surface_destroy (dest);
CGContextRestoreGState (cgContext);
}
-(void)setCairoSurface:(cairo_surface_t *)surface
withDamage:(cairo_region_t *)region
-(void)setImage:(CGImageRef)theImage
withDamage:(cairo_region_t *)region
{
if (surface != self->cairoSurface)
if (theImage != image)
{
g_clear_pointer (&self->cairoSurface, cairo_surface_destroy);
if (surface != NULL)
self->cairoSurface = cairo_surface_reference (surface);
g_clear_pointer (&image, CGImageRelease);
if (theImage)
image = CGImageRetain (theImage);
}
if (region != NULL)
{
NSView *root_view = [[self window] contentView];
NSRect abs_bounds = [self convertRect:[self bounds] toView:root_view];
guint n_rects = cairo_region_num_rectangles (region);
for (guint i = 0; i < n_rects; i++)
{
cairo_rectangle_int_t rect;
NSRect nsrect;
cairo_region_get_rectangle (region, i, &rect);
nsrect = NSMakeRect (rect.x, rect.y, rect.width, rect.height);
if (NSIntersectsRect (abs_bounds, nsrect))
{
nsrect.origin.x -= abs_bounds.origin.x;
nsrect.origin.y -= abs_bounds.origin.y;
[self setNeedsDisplayInRect:nsrect];
}
}
}
[self convertRegion:region toArray:&self->damage andDisplay:YES];
for (id view in [self subviews])
[(GdkMacosCairoSubview *)view setCairoSurface:surface
withDamage:region];
[(GdkMacosCairoSubview *)view setImage:theImage withDamage:region];
}
-(void)setOpaque:(BOOL)opaque
@ -188,14 +124,44 @@
self->_isOpaque = opaque;
}
-(void)setClip:(cairo_region_t*)region
-(void)convertRegion:(const cairo_region_t *)region
toArray:(GArray **)array
andDisplay:(BOOL)display
{
if (region != self->clip)
NSView *root_view;
CGRect abs_bounds;
guint n_rects;
if (*array == NULL)
*array = g_array_new (FALSE, FALSE, sizeof (CGRect));
else
g_array_set_size (*array, 0);
root_view = [[self window] contentView];
abs_bounds = [self convertRect:[self bounds] toView:root_view];
n_rects = cairo_region_num_rectangles (region);
for (guint i = 0; i < n_rects; i++)
{
g_clear_pointer (&self->clip, cairo_region_destroy);
if (region != NULL)
self->clip = cairo_region_reference (region);
cairo_rectangle_int_t rect;
CGRect nsrect;
cairo_region_get_rectangle (region, i, &rect);
nsrect = CGRectIntersection (abs_bounds, CGRectMake (rect.x, rect.y, rect.width, rect.height));
if (!CGRectIsNull (nsrect))
g_array_append_val (*array, nsrect);
if (display)
[self setNeedsDisplayInRect:CGRectMake (rect.x - abs_bounds.origin.x,
rect.y - abs_bounds.origin.y,
rect.width, rect.height)];
}
}
-(void)setClip:(cairo_region_t*)region
{
[self convertRegion:region toArray:&self->clip andDisplay:NO];
}
@end

View File

@ -19,19 +19,21 @@
*/
#include <AppKit/AppKit.h>
#include <cairo.h>
#include <glib.h>
#define GDK_IS_MACOS_CAIRO_SUBVIEW(obj) ((obj) && [obj isKindOfClass:[GdkMacosCairoSubview class]])
@interface GdkMacosCairoSubview : NSView
{
BOOL _isOpaque;
cairo_surface_t *cairoSurface;
cairo_region_t *clip;
BOOL _isOpaque;
GArray *clip;
GArray *damage;
CGImageRef image;
}
-(void)setOpaque:(BOOL)opaque;
-(void)setCairoSurface:(cairo_surface_t *)cairoSurface
withDamage:(cairo_region_t *)region;
-(void)setImage:(CGImageRef)theImage withDamage:(cairo_region_t *)region;
-(void)setClip:(cairo_region_t*)region;
@end

View File

@ -28,6 +28,7 @@
#import "GdkMacosCairoView.h"
#import "GdkMacosCairoSubview.h"
#include "gdkmacosmonitor-private.h"
#include "gdkmacossurface-private.h"
@implementation GdkMacosCairoView
@ -58,12 +59,92 @@
[child setNeedsDisplay:needsDisplay];
}
static void
release_surface_provider (void *info,
const void *data,
size_t size)
{
cairo_surface_destroy (info);
}
-(void)setCairoSurface:(cairo_surface_t *)cairoSurface
withDamage:(cairo_region_t *)cairoRegion
{
CGImageRef image = NULL;
if (cairoSurface != NULL)
{
const CGColorRenderingIntent intent = kCGRenderingIntentDefault;
CGDataProviderRef provider;
CGColorSpaceRef rgb;
cairo_format_t format;
CGBitmapInfo bitmap = kCGBitmapByteOrder32Host;
GdkMonitor *monitor;
guint8 *framebuffer;
size_t width;
size_t height;
int rowstride;
int bpp;
int bpc;
cairo_surface_flush (cairoSurface);
format = cairo_image_surface_get_format (cairoSurface);
framebuffer = cairo_image_surface_get_data (cairoSurface);
rowstride = cairo_image_surface_get_stride (cairoSurface);
width = cairo_image_surface_get_width (cairoSurface);
height = cairo_image_surface_get_height (cairoSurface);
monitor = _gdk_macos_surface_get_best_monitor ([self gdkSurface]);
rgb = _gdk_macos_monitor_copy_colorspace (GDK_MACOS_MONITOR (monitor));
/* If we have an WCG colorspace, just take the slow path or we risk
* really screwing things up.
*/
if (CGColorSpaceIsWideGamutRGB (rgb))
{
CGColorSpaceRelease (rgb);
rgb = CGColorSpaceCreateDeviceRGB ();
}
/* Assert that our image surface was created correctly with
* 16-byte aligned pointers and strides. This is needed to
* ensure that we're working with fast paths in CoreGraphics.
*/
g_assert (format == CAIRO_FORMAT_ARGB32 || format == CAIRO_FORMAT_RGB24);
g_assert (framebuffer != NULL);
g_assert (((intptr_t)framebuffer & (intptr_t)~0xF) == (intptr_t)framebuffer);
g_assert ((rowstride & ~0xF) == rowstride);
if (format == CAIRO_FORMAT_ARGB32)
{
bitmap |= kCGImageAlphaPremultipliedFirst;
bpp = 32;
bpc = 8;
}
else
{
bitmap |= kCGImageAlphaNoneSkipFirst;
bpp = 32;
bpc = 8;
}
provider = CGDataProviderCreateWithData (cairo_surface_reference (cairoSurface),
framebuffer,
rowstride * height,
release_surface_provider);
image = CGImageCreate (width, height, bpc, bpp, rowstride, rgb, bitmap, provider, NULL, FALSE, intent);
CGDataProviderRelease (provider);
CGColorSpaceRelease (rgb);
}
for (id view in [self subviews])
[(GdkMacosCairoSubview *)view setCairoSurface:cairoSurface
withDamage:cairoRegion];
[(GdkMacosCairoSubview *)view setImage:image
withDamage:cairoRegion];
if (image != NULL)
CGImageRelease (image);
}
-(void)removeOpaqueChildren
@ -162,7 +243,6 @@
*/
self->transparent = [[GdkMacosCairoSubview alloc] initWithFrame:frame];
[self addSubview:self->transparent];
}
return self;

View File

@ -214,7 +214,14 @@ typedef NSString *CALayerContentsGravity;
* as we are leaving maximized state.
*/
if ((style_mask & NSWindowStyleMaskTitled) == 0 && [self isOpaque])
[self setOpaque:NO];
{
GdkSurface *surface = GDK_SURFACE ([self gdkSurface]);
[self setOpaque:NO];
/* Force updating of various styling, regions, etc */
_gdk_surface_update_size (surface);
}
}
-(void)windowDidMove:(NSNotification *)aNotification

View File

@ -34,6 +34,7 @@ struct _GdkMacosCairoContext
GdkCairoContext parent_instance;
cairo_surface_t *window_surface;
cairo_t *cr;
};
struct _GdkMacosCairoContextClass
@ -46,30 +47,66 @@ G_DEFINE_TYPE (GdkMacosCairoContext, _gdk_macos_cairo_context, GDK_TYPE_CAIRO_CO
static cairo_surface_t *
create_cairo_surface_for_surface (GdkSurface *surface)
{
static const cairo_user_data_key_t buffer_key;
cairo_surface_t *cairo_surface;
guint8 *data;
cairo_format_t format;
size_t size;
size_t rowstride;
size_t width;
size_t height;
int scale;
int width;
int height;
g_assert (GDK_IS_MACOS_SURFACE (surface));
/* We use a cairo image surface here instead of a quartz surface because
* we get strange artifacts with the quartz surface such as empty
* cross-fades when hovering buttons. For performance, we want to be using
* GL rendering so there isn't much point here as correctness is better.
*
* Additionally, so we can take avantage of faster paths in Core
* Graphics, we want our data pointer to be 16-byte aligned and our rows
* to be 16-byte aligned or we risk errors below us. Normally, cairo
* image surface does not guarantee the later, which means we could end
* up doing some costly copies along the way to compositing.
*/
if ([GDK_MACOS_SURFACE (surface)->window isOpaque])
format = CAIRO_FORMAT_RGB24;
else
format = CAIRO_FORMAT_ARGB32;
scale = gdk_surface_get_scale_factor (surface);
width = scale * gdk_surface_get_width (surface);
height = scale * gdk_surface_get_height (surface);
/* We use a cairo image surface here instead of a quartz surface because we
* get strange artifacts with the quartz surface such as empty cross-fades
* when hovering buttons. For performance, we want to be using GL rendering
* so there isn't much point here as correctness is better.
*/
cairo_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
if (cairo_surface != NULL)
cairo_surface_set_device_scale (cairo_surface, scale, scale);
rowstride = (cairo_format_stride_for_width (format, width) + 0xF) & ~0xF;
size = rowstride * height;
data = g_malloc0 (size);
cairo_surface = cairo_image_surface_create_for_data (data, format, width, height, rowstride);
cairo_surface_set_user_data (cairo_surface, &buffer_key, data, g_free);
cairo_surface_set_device_scale (cairo_surface, scale, scale);
return cairo_surface;
}
static cairo_t *
do_cairo_create (GdkMacosCairoContext *self)
{
GdkSurface *surface;
cairo_t *cr;
g_assert (GDK_IS_MACOS_CAIRO_CONTEXT (self));
surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (self));
cr = cairo_create (self->window_surface);
/* Draw upside down as quartz prefers */
cairo_translate (cr, 0, surface->height);
cairo_scale (cr, 1.0, -1.0);
return cr;
}
static cairo_t *
_gdk_macos_cairo_context_cairo_create (GdkCairoContext *cairo_context)
{
@ -77,7 +114,10 @@ _gdk_macos_cairo_context_cairo_create (GdkCairoContext *cairo_context)
g_assert (GDK_IS_MACOS_CAIRO_CONTEXT (self));
return cairo_create (self->window_surface);
if (self->cr != NULL)
return cairo_reference (self->cr);
return do_cairo_create (self);
}
static void
@ -95,20 +135,18 @@ _gdk_macos_cairo_context_begin_frame (GdkDrawContext *draw_context,
nswindow = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (surface));
if (self->window_surface == NULL)
self->window_surface = create_cairo_surface_for_surface (surface);
self->cr = do_cairo_create (self);
if (![nswindow isOpaque])
{
self->window_surface = create_cairo_surface_for_surface (surface);
}
else
{
if (![nswindow isOpaque])
{
cairo_t *cr = cairo_create (self->window_surface);
gdk_cairo_region (cr, region);
cairo_set_source_rgba (cr, 0, 0, 0, 0);
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
cairo_fill (cr);
cairo_destroy (cr);
}
cairo_save (self->cr);
gdk_cairo_region (self->cr, region);
cairo_set_source_rgba (self->cr, 0, 0, 0, 0);
cairo_set_operator (self->cr, CAIRO_OPERATOR_SOURCE);
cairo_fill (self->cr);
cairo_restore (self->cr);
}
}
@ -126,6 +164,8 @@ _gdk_macos_cairo_context_end_frame (GdkDrawContext *draw_context,
surface = gdk_draw_context_get_surface (draw_context);
nsview = _gdk_macos_surface_get_view (GDK_MACOS_SURFACE (surface));
g_clear_pointer (&self->cr, cairo_destroy);
if (GDK_IS_MACOS_CAIRO_VIEW (nsview))
[(GdkMacosCairoView *)nsview setCairoSurface:self->window_surface
withDamage:painted];
@ -141,12 +181,25 @@ _gdk_macos_cairo_context_surface_resized (GdkDrawContext *draw_context)
g_clear_pointer (&self->window_surface, cairo_surface_destroy);
}
static void
_gdk_macos_cairo_context_dispose (GObject *object)
{
GdkMacosCairoContext *self = (GdkMacosCairoContext *)object;
g_clear_pointer (&self->window_surface, cairo_surface_destroy);
G_OBJECT_CLASS (_gdk_macos_cairo_context_parent_class)->dispose (object);
}
static void
_gdk_macos_cairo_context_class_init (GdkMacosCairoContextClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GdkCairoContextClass *cairo_context_class = GDK_CAIRO_CONTEXT_CLASS (klass);
GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS (klass);
object_class->dispose = _gdk_macos_cairo_context_dispose;
draw_context_class->begin_frame = _gdk_macos_cairo_context_begin_frame;
draw_context_class->end_frame = _gdk_macos_cairo_context_end_frame;
draw_context_class->surface_resized = _gdk_macos_cairo_context_surface_resized;

View File

@ -301,10 +301,14 @@ gdk_macos_display_frame_cb (gpointer data)
iter = iter->next;
_gdk_macos_surface_publish_timings (surface,
source->presentation_time,
source->refresh_interval);
_gdk_macos_display_remove_frame_callback (self, surface);
_gdk_macos_surface_thaw (surface,
source->presentation_time,
source->refresh_interval);
if (GDK_SURFACE_IS_MAPPED (GDK_SURFACE (surface)))
gdk_surface_thaw_updates (GDK_SURFACE (surface));
}
return G_SOURCE_CONTINUE;
@ -987,7 +991,11 @@ _gdk_macos_display_add_frame_callback (GdkMacosDisplay *self,
if (!queue_contains (&self->awaiting_frames, &surface->frame))
{
g_queue_push_tail_link (&self->awaiting_frames, &surface->frame);
/* Processing frames is always head to tail, so push to the
* head so that we don't possibly re-enter this right after
* adding to the queue.
*/
g_queue_push_head_link (&self->awaiting_frames, &surface->frame);
if (self->awaiting_frames.length == 1)
gdk_display_link_source_unpause ((GdkDisplayLinkSource *)self->frame_source);

View File

@ -29,10 +29,11 @@
G_BEGIN_DECLS
GdkMacosMonitor *_gdk_macos_monitor_new (GdkMacosDisplay *display,
CGDirectDisplayID screen_id);
CGDirectDisplayID _gdk_macos_monitor_get_screen_id (GdkMacosMonitor *self);
gboolean _gdk_macos_monitor_reconfigure (GdkMacosMonitor *self);
GdkMacosMonitor *_gdk_macos_monitor_new (GdkMacosDisplay *display,
CGDirectDisplayID screen_id);
CGDirectDisplayID _gdk_macos_monitor_get_screen_id (GdkMacosMonitor *self);
gboolean _gdk_macos_monitor_reconfigure (GdkMacosMonitor *self);
CGColorSpaceRef _gdk_macos_monitor_copy_colorspace (GdkMacosMonitor *self);
G_END_DECLS

View File

@ -298,3 +298,11 @@ _gdk_macos_monitor_get_screen_id (GdkMacosMonitor *self)
return self->screen_id;
}
CGColorSpaceRef
_gdk_macos_monitor_copy_colorspace (GdkMacosMonitor *self)
{
g_return_val_if_fail (GDK_IS_MACOS_MONITOR (self), NULL);
return CGDisplayCopyColorSpace (self->screen_id);
}

View File

@ -204,6 +204,10 @@ static void
_gdk_macos_popup_surface_finalize (GObject *object)
{
GdkMacosPopupSurface *self = (GdkMacosPopupSurface *)object;
GdkSurface *parent = GDK_SURFACE (self)->parent;
if (parent != NULL)
parent->children = g_list_remove (parent->children, self);
g_clear_object (&GDK_SURFACE (self)->parent);
g_clear_pointer (&self->layout, gdk_popup_layout_unref);

View File

@ -104,7 +104,7 @@ void _gdk_macos_surface_resize (GdkMacosSurface
void _gdk_macos_surface_update_fullscreen_state (GdkMacosSurface *self);
void _gdk_macos_surface_update_position (GdkMacosSurface *self);
void _gdk_macos_surface_show (GdkMacosSurface *self);
void _gdk_macos_surface_thaw (GdkMacosSurface *self,
void _gdk_macos_surface_publish_timings (GdkMacosSurface *self,
gint64 predicted_presentation_time,
gint64 refresh_interval);
CGContextRef _gdk_macos_surface_acquire_context (GdkMacosSurface *self,

View File

@ -125,6 +125,8 @@ gdk_macos_surface_hide (GdkSurface *surface)
g_assert (GDK_IS_MACOS_SURFACE (self));
_gdk_macos_display_remove_frame_callback (GDK_MACOS_DISPLAY (surface->display), self);
was_mapped = GDK_SURFACE_IS_MAPPED (GDK_SURFACE (self));
seat = gdk_display_get_default_seat (surface->display);
@ -190,15 +192,20 @@ gdk_macos_surface_end_frame (GdkMacosSurface *self)
g_assert (GDK_IS_MACOS_SURFACE (self));
if (GDK_SURFACE_DESTROYED (self))
return;
display = gdk_surface_get_display (GDK_SURFACE (self));
frame_clock = gdk_surface_get_frame_clock (GDK_SURFACE (self));
if ((timings = gdk_frame_clock_get_current_timings (frame_clock)))
self->pending_frame_counter = timings->frame_counter;
_gdk_macos_display_add_frame_callback (GDK_MACOS_DISPLAY (display), self);
gdk_surface_freeze_updates (GDK_SURFACE (self));
if (GDK_SURFACE_IS_MAPPED (GDK_SURFACE (self)))
{
_gdk_macos_display_add_frame_callback (GDK_MACOS_DISPLAY (display), self);
gdk_surface_freeze_updates (GDK_SURFACE (self));
}
}
static void
@ -210,10 +217,11 @@ gdk_macos_surface_before_paint (GdkMacosSurface *self,
g_assert (GDK_IS_MACOS_SURFACE (self));
g_assert (GDK_IS_FRAME_CLOCK (frame_clock));
if (surface->update_freeze_count > 0)
if (GDK_SURFACE_DESTROYED (self))
return;
gdk_macos_surface_begin_frame (self);
if (surface->update_freeze_count == 0)
gdk_macos_surface_begin_frame (self);
}
static void
@ -225,10 +233,11 @@ gdk_macos_surface_after_paint (GdkMacosSurface *self,
g_assert (GDK_IS_MACOS_SURFACE (self));
g_assert (GDK_IS_FRAME_CLOCK (frame_clock));
if (surface->update_freeze_count > 0)
if (GDK_SURFACE_DESTROYED (self))
return;
gdk_macos_surface_end_frame (self);
if (surface->update_freeze_count == 0)
gdk_macos_surface_end_frame (self);
}
static void
@ -715,18 +724,17 @@ _gdk_macos_surface_update_position (GdkMacosSurface *self)
}
void
_gdk_macos_surface_thaw (GdkMacosSurface *self,
gint64 presentation_time,
gint64 refresh_interval)
_gdk_macos_surface_publish_timings (GdkMacosSurface *self,
gint64 presentation_time,
gint64 refresh_interval)
{
GdkFrameTimings *timings;
GdkFrameClock *frame_clock;
g_return_if_fail (GDK_IS_MACOS_SURFACE (self));
gdk_surface_thaw_updates (GDK_SURFACE (self));
frame_clock = gdk_surface_get_frame_clock (GDK_SURFACE (self));
if (!(frame_clock = gdk_surface_get_frame_clock (GDK_SURFACE (self))))
return;
if (self->pending_frame_counter)
{
@ -986,6 +994,9 @@ _gdk_macos_surface_monitor_changed (GdkMacosSurface *self)
g_object_unref (monitor);
}
_gdk_surface_update_size (GDK_SURFACE (self));
gdk_surface_invalidate_rect (GDK_SURFACE (self), NULL);
}
GdkMonitor *