From: Ken Thomases Subject: winemac: Send WM_SIZING messages during resizing to let app alter the proposed size. Message-Id: <39352955-8F64-4772-8818-6BF36239196E@codeweavers.com> Date: Wed, 23 Apr 2014 20:00:29 -0500 --- dlls/winemac.drv/cocoa_window.h | 2 + dlls/winemac.drv/cocoa_window.m | 51 ++++++++++++++++++++++++++++++++++++++- dlls/winemac.drv/event.c | 4 +++ dlls/winemac.drv/macdrv.h | 1 + dlls/winemac.drv/macdrv_cocoa.h | 6 ++++ dlls/winemac.drv/window.c | 40 ++++++++++++++++++++++++++++++ 6 files changed, 103 insertions(+), 1 deletions(-) diff --git a/dlls/winemac.drv/cocoa_window.h b/dlls/winemac.drv/cocoa_window.h index a74f6da..68905a5 100644 --- a/dlls/winemac.drv/cocoa_window.h +++ b/dlls/winemac.drv/cocoa_window.h @@ -54,6 +54,8 @@ @interface WineWindow : NSPanel NSUInteger lastModifierFlags; NSTimer* liveResizeDisplayTimer; + NSRect frameAtResizeStart; + BOOL resizingFromLeft, resizingFromTop; void* imeData; BOOL commandDone; diff --git a/dlls/winemac.drv/cocoa_window.m b/dlls/winemac.drv/cocoa_window.m index 7ead126..bb173e9 100644 --- a/dlls/winemac.drv/cocoa_window.m +++ b/dlls/winemac.drv/cocoa_window.m @@ -1809,7 +1809,17 @@ - (void)windowDidResignKey:(NSNotification *)notification - (void)windowDidResize:(NSNotification *)notification { macdrv_event* event; - NSRect frame = [self contentRectForFrameRect:[self frame]]; + NSRect frame = [self frame]; + + if ([self inLiveResize]) + { + if (NSMinX(frame) != NSMinX(frameAtResizeStart)) + resizingFromLeft = TRUE; + if (NSMaxY(frame) != NSMaxY(frameAtResizeStart)) + resizingFromTop = TRUE; + } + + frame = [self contentRectForFrameRect:frame]; if (ignore_windowResize || exitingFullScreen) return; @@ -1899,6 +1909,42 @@ - (void)windowWillMiniaturize:(NSNotification *)notification [self becameIneligibleParentOrChild]; } + - (NSSize) windowWillResize:(NSWindow*)sender toSize:(NSSize)frameSize + { + if ([self inLiveResize]) + { + NSRect rect; + macdrv_query* query; + + rect = [self frame]; + if (resizingFromLeft) + rect.origin.x = NSMaxX(rect) - frameSize.width; + if (!resizingFromTop) + rect.origin.y = NSMaxY(rect) - frameSize.height; + rect.size = frameSize; + rect = [self contentRectForFrameRect:rect]; + [[WineApplicationController sharedController] flipRect:&rect]; + + query = macdrv_create_query(); + query->type = QUERY_RESIZE_SIZE; + query->window = (macdrv_window)[self retain]; + query->resize_size.rect = NSRectToCGRect(rect); + query->resize_size.from_left = resizingFromLeft; + query->resize_size.from_top = resizingFromTop; + + if ([self.queue query:query timeout:0.1]) + { + rect = NSRectFromCGRect(query->resize_size.rect); + rect = [self frameRectForContentRect:rect]; + frameSize = rect.size; + } + + macdrv_release_query(query); + } + + return frameSize; + } + - (void) windowWillStartLiveResize:(NSNotification *)notification { macdrv_query* query = macdrv_create_query(); @@ -1908,6 +1954,9 @@ - (void) windowWillStartLiveResize:(NSNotification *)notification [self.queue query:query timeout:0.3]; macdrv_release_query(query); + frameAtResizeStart = [self frame]; + resizingFromLeft = resizingFromTop = FALSE; + // There's a strange restriction in window redrawing during Cocoa- // managed window resizing. Only calls to -[NSView setNeedsDisplay...] // that happen synchronously when Cocoa tells us that our window size diff --git a/dlls/winemac.drv/event.c b/dlls/winemac.drv/event.c index 5095c99..8e03080 100644 --- a/dlls/winemac.drv/event.c +++ b/dlls/winemac.drv/event.c @@ -162,6 +162,10 @@ static void macdrv_query_event(HWND hwnd, const macdrv_event *event) TRACE("QUERY_PASTEBOARD_DATA\n"); success = query_pasteboard_data(hwnd, query->pasteboard_data.type); break; + case QUERY_RESIZE_SIZE: + TRACE("QUERY_RESIZE_SIZE\n"); + success = query_resize_size(hwnd, query); + break; case QUERY_RESIZE_START: TRACE("QUERY_RESIZE_START\n"); success = query_resize_start(hwnd); diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index 9ffeb40..56ca24f 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -173,6 +173,7 @@ static inline RECT rect_from_cgrect(CGRect cgrect) extern void macdrv_window_restore_requested(HWND hwnd) DECLSPEC_HIDDEN; extern void macdrv_window_drag_begin(HWND hwnd) DECLSPEC_HIDDEN; extern void macdrv_window_drag_end(HWND hwnd) DECLSPEC_HIDDEN; +extern BOOL query_resize_size(HWND hwnd, macdrv_query *query) DECLSPEC_HIDDEN; extern BOOL query_resize_start(HWND hwnd) DECLSPEC_HIDDEN; extern BOOL query_min_max_info(HWND hwnd) DECLSPEC_HIDDEN; diff --git a/dlls/winemac.drv/macdrv_cocoa.h b/dlls/winemac.drv/macdrv_cocoa.h index 1550280..6dbaae1 100644 --- a/dlls/winemac.drv/macdrv_cocoa.h +++ b/dlls/winemac.drv/macdrv_cocoa.h @@ -298,6 +298,7 @@ extern int macdrv_set_display_mode(const struct macdrv_display* display, QUERY_DRAG_OPERATION, QUERY_IME_CHAR_RECT, QUERY_PASTEBOARD_DATA, + QUERY_RESIZE_SIZE, QUERY_RESIZE_START, QUERY_MIN_MAX_INFO, NUM_QUERY_TYPES @@ -331,6 +332,11 @@ extern int macdrv_set_display_mode(const struct macdrv_display* display, struct { CFStringRef type; } pasteboard_data; + struct { + CGRect rect; + unsigned int from_left : 1; + unsigned int from_top : 1; + } resize_size; }; } macdrv_query; diff --git a/dlls/winemac.drv/window.c b/dlls/winemac.drv/window.c index 4678afc..6ef227c 100644 --- a/dlls/winemac.drv/window.c +++ b/dlls/winemac.drv/window.c @@ -2400,6 +2400,46 @@ fail: /*********************************************************************** + * query_resize_size + * + * Handler for QUERY_RESIZE_SIZE query. + */ +BOOL query_resize_size(HWND hwnd, macdrv_query *query) +{ + struct macdrv_win_data *data = get_win_data(hwnd); + RECT rect = rect_from_cgrect(query->resize_size.rect); + int corner; + BOOL ret = FALSE; + + if (!data) return FALSE; + + macdrv_mac_to_window_rect(data, &rect); + + if (query->resize_size.from_left) + { + if (query->resize_size.from_top) + corner = WMSZ_TOPLEFT; + else + corner = WMSZ_BOTTOMLEFT; + } + else if (query->resize_size.from_top) + corner = WMSZ_TOPRIGHT; + else + corner = WMSZ_BOTTOMRIGHT; + + if (SendMessageW(hwnd, WM_SIZING, corner, (LPARAM)&rect)) + { + macdrv_window_to_mac_rect(data, GetWindowLongW(hwnd, GWL_STYLE), &rect); + query->resize_size.rect = cgrect_from_rect(rect); + ret = TRUE; + } + + release_win_data(data); + return ret; +} + + +/*********************************************************************** * query_resize_start * * Handler for QUERY_RESIZE_START query.