[quartz] GdkWindow, GdkNSView frame and cairo surface same size.
The cairo surface must be padded to 4 pixels in order to transfer correctly to the GPU. The GdkWindow and GdkNSView's content frame must be the same width, otherwise there's a mismatch that causes either the GdkWindow to draw wider than the frame or the frame to be clipped narrower than the title bar. Fixes #5535.
This commit is contained in:
@@ -229,6 +229,9 @@
|
||||
GdkWindow *window = [[self contentView] gdkWindow];
|
||||
GdkEvent *event;
|
||||
gboolean maximized = gdk_window_get_state (window) & GDK_WINDOW_STATE_MAXIMIZED;
|
||||
/* Alignment to 4 pixels is on scaled pixels and these are unscaled pixels so divide by scale to compensate. */
|
||||
const gint scale = gdk_window_get_scale_factor (window);
|
||||
const guint align = GDK_WINDOW_QUARTZ_ALIGNMENT / scale;
|
||||
|
||||
/* see same in windowDidMove */
|
||||
if (maximized && !inMaximizeTransition && !NSEqualRects (lastMaximizedFrame, [self frame]))
|
||||
@@ -241,13 +244,18 @@
|
||||
window->width = content_rect.size.width;
|
||||
window->height = content_rect.size.height;
|
||||
|
||||
if(window->width % align)
|
||||
content_rect.size.width += align - window->width % align;
|
||||
|
||||
content_rect.origin.x = 0;
|
||||
content_rect.origin.y = 0;
|
||||
|
||||
[[self contentView] setFrame:content_rect];
|
||||
|
||||
/* Certain resize operations (e.g. going fullscreen), also move the
|
||||
* origin of the window.
|
||||
*/
|
||||
_gdk_quartz_window_update_position (window);
|
||||
|
||||
[[self contentView] setFrame:NSMakeRect (0, 0, window->width, window->height)];
|
||||
|
||||
_gdk_window_update_size (window);
|
||||
|
||||
/* Synthesize a configure event */
|
||||
|
||||
@@ -424,8 +424,7 @@ copy_rectangle_argb32 (cairo_surface_t *dest, cairo_surface_t *source,
|
||||
return;
|
||||
|
||||
++impl->in_paint_rect_count;
|
||||
cairo_rect_from_nsrect (&bounds_rect, &backing_bounds);
|
||||
bounds_region = cairo_region_create_rectangle (&bounds_rect);
|
||||
|
||||
if (impl->needs_display_region)
|
||||
{
|
||||
cairo_region_t *region = impl->needs_display_region;
|
||||
@@ -439,7 +438,7 @@ copy_rectangle_argb32 (cairo_surface_t *dest, cairo_surface_t *source,
|
||||
cairo_region_t *region;
|
||||
|
||||
cairo_rect_from_nsrect (&bounds, &layer_bounds);
|
||||
region = cairo_region_create_rectangle (&bounds);
|
||||
region = cairo_region_create_rectangle(&bounds);
|
||||
_gdk_window_process_updates_recurse (gdk_window, region);
|
||||
cairo_region_destroy (region);
|
||||
}
|
||||
@@ -447,8 +446,6 @@ copy_rectangle_argb32 (cairo_surface_t *dest, cairo_surface_t *source,
|
||||
if (!impl || !impl->cairo_surface)
|
||||
return;
|
||||
|
||||
impl_rect.width = cairo_image_surface_get_width (impl->cairo_surface);
|
||||
impl_rect.height = cairo_image_surface_get_height (impl->cairo_surface);
|
||||
CVPixelBufferLockBaseAddress (pixels, 0);
|
||||
cvpb_surface =
|
||||
cairo_image_surface_create_for_data (CVPixelBufferGetBaseAddress (pixels),
|
||||
@@ -458,6 +455,12 @@ copy_rectangle_argb32 (cairo_surface_t *dest, cairo_surface_t *source,
|
||||
(int)CVPixelBufferGetBytesPerRow (pixels));
|
||||
|
||||
|
||||
cairo_rect_from_nsrect (&bounds_rect, &backing_bounds);
|
||||
bounds_region = cairo_region_create_rectangle (&bounds_rect);
|
||||
|
||||
impl_rect.width = cairo_image_surface_get_width (impl->cairo_surface);
|
||||
impl_rect.height = cairo_image_surface_get_height (impl->cairo_surface);
|
||||
|
||||
cairo_region_intersect_rectangle (bounds_region, &impl_rect);
|
||||
copy_rectangle_argb32 (cvpb_surface, impl->cairo_surface, bounds_region);
|
||||
|
||||
@@ -465,7 +468,9 @@ copy_rectangle_argb32 (cairo_surface_t *dest, cairo_surface_t *source,
|
||||
cairo_region_destroy (bounds_region);
|
||||
_gdk_quartz_unref_cairo_surface (gdk_window); // reffed in gdk_window_impl_quartz_begin_paint
|
||||
CVPixelBufferUnlockBaseAddress (pixels, 0);
|
||||
|
||||
--impl->in_paint_rect_count;
|
||||
|
||||
self.layer.contents = NULL;
|
||||
self.layer.contents = (id)CVPixelBufferGetIOSurface (pixels);
|
||||
}
|
||||
|
||||
@@ -27,7 +27,8 @@
|
||||
#include "config.h"
|
||||
|
||||
#define GDK_WINDOW_IS_QUARTZ(win) (GDK_IS_WINDOW_IMPL_QUARTZ (((GdkWindow *)win)->impl))
|
||||
|
||||
/* Cairo surface widths must be 4-pixel byte aligned so that the image will transfer to the CPU. */
|
||||
#define GDK_WINDOW_QUARTZ_ALIGNMENT 16
|
||||
|
||||
/* Display */
|
||||
|
||||
|
||||
@@ -306,9 +306,10 @@ gdk_quartz_ref_cairo_surface (GdkWindow *window)
|
||||
gint height = gdk_window_get_height (impl->wrapper);
|
||||
gint scale = gdk_window_get_scale_factor (impl->wrapper);
|
||||
gint scaled_width = width * scale;
|
||||
const gint align = GDK_WINDOW_QUARTZ_ALIGNMENT;
|
||||
|
||||
if (scaled_width % 16)
|
||||
scaled_width += 16 - scaled_width % 16; // Surface widths must be 4-pixel aligned
|
||||
if (scaled_width % align)
|
||||
scaled_width += align - scaled_width % align; // Surface widths must be 4-pixel aligned
|
||||
|
||||
impl->cairo_surface = gdk_quartz_create_cairo_surface (impl,
|
||||
scaled_width,
|
||||
@@ -929,6 +930,8 @@ _gdk_quartz_display_create_window_impl (GdkDisplay *display,
|
||||
NSUInteger style_mask;
|
||||
int nx, ny;
|
||||
const char *title;
|
||||
const gint scale = gdk_window_get_scale_factor (window);
|
||||
const guint align = GDK_WINDOW_QUARTZ_ALIGNMENT / scale;
|
||||
|
||||
/* initWithContentRect will place on the mainScreen by default.
|
||||
* We want to select the screen to place on ourselves. We need
|
||||
@@ -942,6 +945,9 @@ _gdk_quartz_display_create_window_impl (GdkDisplay *display,
|
||||
nx -= screen_rect.origin.x;
|
||||
ny -= screen_rect.origin.y;
|
||||
|
||||
if (window->width % align)
|
||||
window->width += align - window->width % align;
|
||||
|
||||
content_rect = NSMakeRect (nx, ny - window->height,
|
||||
window->width,
|
||||
window->height);
|
||||
|
||||
Reference in New Issue
Block a user