From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winemac.drv/cocoa_window.m | 9 +++++++++ dlls/winemac.drv/macdrv.h | 1 + dlls/winemac.drv/surface.c | 29 +++++++++++++++++++---------- dlls/winemac.drv/window.c | 2 ++ 4 files changed, 31 insertions(+), 10 deletions(-)
diff --git a/dlls/winemac.drv/cocoa_window.m b/dlls/winemac.drv/cocoa_window.m index caf06ff338f..a56dbbc4614 100644 --- a/dlls/winemac.drv/cocoa_window.m +++ b/dlls/winemac.drv/cocoa_window.m @@ -365,6 +365,7 @@ - (id) initWithFrame:(NSRect)frame device:(id<MTLDevice>)device;
@interface WineContentView : WineBaseView <NSTextInputClient, NSViewLayerContentScaleDelegate> { + CGRect surfaceRect; CGImageRef colorImage;
NSMutableArray* glContexts; @@ -489,6 +490,7 @@ - (instancetype) initWithFrame:(NSRect)frame self = [super initWithFrame:frame]; if (self) { + [self setLayerContentsPlacement:NSViewLayerContentsPlacementTopLeft]; [self setWantsLayer:YES]; [self setLayerRetinaProperties:retina_on]; [self setAutoresizesSubviews:NO]; @@ -552,6 +554,7 @@ - (void) updateLayer
if (image) { + layer.position = surfaceRect.origin; layer.contents = (id)image; CFRelease(image); [window windowDidDrawContent]; @@ -567,6 +570,11 @@ - (void) updateLayer } }
+ - (void) setSurfaceRect:(CGRect)rect + { + surfaceRect = rect; + } + - (void) setColorImage:(CGImageRef)image { CGImageRelease(colorImage); @@ -3516,6 +3524,7 @@ void macdrv_window_set_color_image(macdrv_window w, CGImageRef image, CGRect rec WineContentView *view = [window contentView];
[view setColorImage:image]; + [view setSurfaceRect:cgrect_mac_from_win(rect)]; [view setNeedsDisplayInRect:NSRectFromCGRect(cgrect_mac_from_win(dirty))];
CGImageRelease(image); diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index 811947f723c..6863232b65a 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -208,6 +208,7 @@ extern BOOL macdrv_SystemParametersInfo(UINT action, UINT int_param, void *ptr_p extern RGNDATA *get_region_data(HRGN hrgn, HDC hdc_lptodp); extern void activate_on_following_focus(void); extern void set_surface_use_alpha(struct window_surface *window_surface, BOOL use_alpha); +extern BOOL get_surface_rect(const RECT *visible_rect, RECT *surface_rect);
extern void macdrv_handle_event(const macdrv_event *event);
diff --git a/dlls/winemac.drv/surface.c b/dlls/winemac.drv/surface.c index 8b68d5d0ab5..7b4f744edba 100644 --- a/dlls/winemac.drv/surface.c +++ b/dlls/winemac.drv/surface.c @@ -225,16 +225,25 @@ void set_surface_use_alpha(struct window_surface *window_surface, BOOL use_alpha }
-static inline RECT get_surface_rect(const RECT *visible_rect) +BOOL get_surface_rect(const RECT *visible_rect, RECT *surface_rect) { - RECT rect = *visible_rect; - - OffsetRect(&rect, -visible_rect->left, -visible_rect->top); - rect.left &= ~127; - rect.top &= ~127; - rect.right = max(rect.left + 128, (rect.right + 127) & ~127); - rect.bottom = max(rect.top + 128, (rect.bottom + 127) & ~127); - return rect; + RECT virtual_rect = NtUserGetVirtualScreenRect(); + + *surface_rect = *visible_rect; + + /* crop surfaces which are larger than the virtual screen rect, some applications create huge windows */ + if ((surface_rect->right - surface_rect->left > virtual_rect.right - virtual_rect.left || + surface_rect->bottom - surface_rect->top > virtual_rect.bottom - virtual_rect.top) && + !intersect_rect( surface_rect, surface_rect, &virtual_rect )) + return FALSE; + OffsetRect(surface_rect, -visible_rect->left, -visible_rect->top); + + /* round the surface coordinates to avoid re-creating them too often on resize */ + surface_rect->left &= ~127; + surface_rect->top &= ~127; + surface_rect->right = max(surface_rect->left + 128, (surface_rect->right + 127) & ~127); + surface_rect->bottom = max(surface_rect->top + 128, (surface_rect->bottom + 127) & ~127); + return TRUE; }
@@ -250,11 +259,11 @@ BOOL macdrv_CreateWindowSurface(HWND hwnd, UINT swp_flags, const RECT *visible_r TRACE("hwnd %p, swp_flags %08x, visible %s, surface %p\n", hwnd, swp_flags, wine_dbgstr_rect(visible_rect), surface);
if (!(data = get_win_data(hwnd))) return TRUE; /* use default surface */ + if (!get_surface_rect( visible_rect, &surface_rect )) goto done; /* use default surface */
if (*surface) window_surface_release(*surface); *surface = NULL;
- surface_rect = get_surface_rect(visible_rect); if (data->surface) { if (EqualRect(&data->surface->rect, &surface_rect)) diff --git a/dlls/winemac.drv/window.c b/dlls/winemac.drv/window.c index 36f3e3053d6..0f38d96523e 100644 --- a/dlls/winemac.drv/window.c +++ b/dlls/winemac.drv/window.c @@ -1951,6 +1951,7 @@ BOOL macdrv_WindowPosChanging(HWND hwnd, UINT swp_flags, const RECT *window_rect { struct macdrv_win_data *data = get_win_data(hwnd); DWORD style = NtUserGetWindowLongW(hwnd, GWL_STYLE); + RECT surface_rect; BOOL ret = FALSE;
TRACE("%p swp %04x window %s client %s visible %s\n", hwnd, @@ -1966,6 +1967,7 @@ BOOL macdrv_WindowPosChanging(HWND hwnd, UINT swp_flags, const RECT *window_rect if (!data->cocoa_window) goto done; /* use default surface */ if (swp_flags & SWP_HIDEWINDOW) goto done; /* use default surface */ if (data->ulw_layered) goto done; /* use default surface */ + if (!get_surface_rect( visible_rect, &surface_rect )) goto done; /* use default surface */
ret = TRUE;