winemac: At the start of a resize operation, get window min/max size info and pass it to Cocoa.

This commit is contained in:
Ken Thomases 2013-09-18 13:00:37 -05:00 committed by Alexandre Julliard
parent 040e47fece
commit a3197b8ad0
6 changed files with 188 additions and 10 deletions

View File

@ -55,6 +55,9 @@ @interface WineWindow : NSPanel <NSWindowDelegate>
void* imeData;
BOOL commandDone;
NSSize savedContentMinSize;
NSSize savedContentMaxSize;
BOOL causing_becomeKeyWindow;
BOOL ignore_windowMiniaturize;
BOOL ignore_windowDeminiaturize;

View File

@ -500,6 +500,8 @@ + (WineWindow*) createWindowWithFeatures:(const struct macdrv_window_features*)w
[window setDelegate:window];
window.hwnd = hwnd;
window.queue = queue;
window->savedContentMinSize = NSZeroSize;
window->savedContentMaxSize = NSMakeSize(FLT_MAX, FLT_MAX);
[window registerForDraggedTypes:[NSArray arrayWithObjects:(NSString*)kUTTypeData,
(NSString*)kUTTypeContent,
@ -1131,14 +1133,14 @@ - (void) setDisabled:(BOOL)newValue
if (disabled)
{
NSSize size = [self frame].size;
[self setMinSize:size];
[self setMaxSize:size];
NSSize size = [self contentRectForFrameRect:[self frame]].size;
[self setContentMinSize:size];
[self setContentMaxSize:size];
}
else
{
[self setMaxSize:NSMakeSize(FLT_MAX, FLT_MAX)];
[self setMinSize:NSZeroSize];
[self setContentMaxSize:savedContentMaxSize];
[self setContentMinSize:savedContentMinSize];
}
}
}
@ -1231,6 +1233,17 @@ - (void) postKeyEvent:(NSEvent *)theEvent
event:theEvent];
}
- (void) setWineMinSize:(NSSize)minSize maxSize:(NSSize)maxSize
{
savedContentMinSize = minSize;
savedContentMaxSize = maxSize;
if (!self.disabled)
{
[self setContentMinSize:minSize];
[self setContentMaxSize:maxSize];
}
}
/*
* ---------- NSWindow method overrides ----------
@ -1480,16 +1493,14 @@ - (void)windowDidResignKey:(NSNotification *)notification
- (void)windowDidResize:(NSNotification *)notification
{
macdrv_event* event;
NSRect frame = [self frame];
NSRect frame = [self contentRectForFrameRect:[self frame]];
if (self.disabled)
{
NSSize size = frame.size;
[self setMinSize:size];
[self setMaxSize:size];
[self setContentMinSize:frame.size];
[self setContentMaxSize:frame.size];
}
frame = [self contentRectForFrameRect:frame];
[[WineApplicationController sharedController] flipRect:&frame];
/* Coalesce events by discarding any previous ones still in the queue. */
@ -1554,6 +1565,13 @@ - (void)windowWillMiniaturize:(NSNotification *)notification
- (void) windowWillStartLiveResize:(NSNotification *)notification
{
macdrv_query* query = macdrv_create_query();
query->type = QUERY_RESIZE_START;
query->window = (macdrv_window)[self retain];
[self.queue query:query timeout:0.3];
macdrv_release_query(query);
// 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
@ -2010,6 +2028,20 @@ void macdrv_give_cocoa_window_focus(macdrv_window w, int activate)
});
}
/***********************************************************************
* macdrv_set_window_min_max_sizes
*
* Sets the window's minimum and maximum content sizes.
*/
void macdrv_set_window_min_max_sizes(macdrv_window w, CGSize min_size, CGSize max_size)
{
WineWindow* window = (WineWindow*)w;
OnMainThread(^{
[window setWineMinSize:NSSizeFromCGSize(min_size) maxSize:NSSizeFromCGSize(max_size)];
});
}
/***********************************************************************
* macdrv_create_view
*

View File

@ -146,6 +146,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_START:
TRACE("QUERY_RESIZE_START\n");
success = query_resize_start(hwnd);
break;
default:
FIXME("unrecognized query type %d\n", query->type);
break;

View File

@ -161,6 +161,7 @@ static inline RECT rect_from_cgrect(CGRect cgrect)
extern void macdrv_app_quit_requested(const macdrv_event *event) DECLSPEC_HIDDEN;
extern void macdrv_window_did_minimize(HWND hwnd) DECLSPEC_HIDDEN;
extern void macdrv_window_did_unminimize(HWND hwnd) DECLSPEC_HIDDEN;
extern BOOL query_resize_start(HWND hwnd) DECLSPEC_HIDDEN;
extern void macdrv_mouse_button(HWND hwnd, const macdrv_event *event) DECLSPEC_HIDDEN;
extern void macdrv_mouse_moved(HWND hwnd, const macdrv_event *event) DECLSPEC_HIDDEN;

View File

@ -272,6 +272,7 @@ extern int macdrv_set_display_mode(const struct macdrv_display* display,
QUERY_DRAG_OPERATION,
QUERY_IME_CHAR_RECT,
QUERY_PASTEBOARD_DATA,
QUERY_RESIZE_START,
NUM_QUERY_TYPES
};
@ -373,6 +374,7 @@ extern void macdrv_set_window_color_key(macdrv_window w, CGFloat keyRed, CGFloat
extern void macdrv_clear_window_color_key(macdrv_window w) DECLSPEC_HIDDEN;
extern void macdrv_window_use_per_pixel_alpha(macdrv_window w, int use_per_pixel_alpha) DECLSPEC_HIDDEN;
extern void macdrv_give_cocoa_window_focus(macdrv_window w, int activate) DECLSPEC_HIDDEN;
extern void macdrv_set_window_min_max_sizes(macdrv_window w, CGSize min_size, CGSize max_size) DECLSPEC_HIDDEN;
extern macdrv_view macdrv_create_view(macdrv_window w, CGRect rect) DECLSPEC_HIDDEN;
extern void macdrv_dispose_view(macdrv_view v) DECLSPEC_HIDDEN;
extern void macdrv_set_view_window_and_frame(macdrv_view v, macdrv_window w, CGRect rect) DECLSPEC_HIDDEN;

View File

@ -464,6 +464,129 @@ static void sync_window_opacity(struct macdrv_win_data *data, COLORREF key, BYTE
}
/***********************************************************************
* sync_window_min_max_info
*/
static void sync_window_min_max_info(HWND hwnd)
{
LONG style = GetWindowLongW(hwnd, GWL_STYLE);
LONG exstyle = GetWindowLongW(hwnd, GWL_EXSTYLE);
RECT win_rect, primary_monitor_rect;
MINMAXINFO minmax;
LONG adjustedStyle;
INT xinc, yinc;
WINDOWPLACEMENT wpl;
HMONITOR monitor;
struct macdrv_win_data *data;
RECT min_rect, max_rect;
CGSize min_size, max_size;
TRACE("win %p\n", hwnd);
if (!macdrv_get_cocoa_window(hwnd, FALSE)) return;
GetWindowRect(hwnd, &win_rect);
minmax.ptReserved.x = win_rect.left;
minmax.ptReserved.y = win_rect.top;
if ((style & WS_CAPTION) == WS_CAPTION)
adjustedStyle = style & ~WS_BORDER; /* WS_CAPTION = WS_DLGFRAME | WS_BORDER */
else
adjustedStyle = style;
primary_monitor_rect.left = primary_monitor_rect.top = 0;
primary_monitor_rect.right = GetSystemMetrics(SM_CXSCREEN);
primary_monitor_rect.bottom = GetSystemMetrics(SM_CYSCREEN);
AdjustWindowRectEx(&primary_monitor_rect, adjustedStyle, ((style & WS_POPUP) && GetMenu(hwnd)), exstyle);
xinc = -primary_monitor_rect.left;
yinc = -primary_monitor_rect.top;
minmax.ptMaxSize.x = primary_monitor_rect.right - primary_monitor_rect.left;
minmax.ptMaxSize.y = primary_monitor_rect.bottom - primary_monitor_rect.top;
minmax.ptMaxPosition.x = -xinc;
minmax.ptMaxPosition.y = -yinc;
if (style & (WS_DLGFRAME | WS_BORDER))
{
minmax.ptMinTrackSize.x = GetSystemMetrics(SM_CXMINTRACK);
minmax.ptMinTrackSize.y = GetSystemMetrics(SM_CYMINTRACK);
}
else
{
minmax.ptMinTrackSize.x = 2 * xinc;
minmax.ptMinTrackSize.y = 2 * yinc;
}
minmax.ptMaxTrackSize.x = GetSystemMetrics(SM_CXMAXTRACK);
minmax.ptMaxTrackSize.y = GetSystemMetrics(SM_CYMAXTRACK);
wpl.length = sizeof(wpl);
if (GetWindowPlacement(hwnd, &wpl) && (wpl.ptMaxPosition.x != -1 || wpl.ptMaxPosition.y != -1))
{
minmax.ptMaxPosition = wpl.ptMaxPosition;
/* Convert from GetWindowPlacement's workspace coordinates to screen coordinates. */
minmax.ptMaxPosition.x -= wpl.rcNormalPosition.left - win_rect.left;
minmax.ptMaxPosition.y -= wpl.rcNormalPosition.top - win_rect.top;
}
TRACE("initial ptMaxSize %s ptMaxPosition %s ptMinTrackSize %s ptMaxTrackSize %s\n", wine_dbgstr_point(&minmax.ptMaxSize),
wine_dbgstr_point(&minmax.ptMaxPosition), wine_dbgstr_point(&minmax.ptMinTrackSize), wine_dbgstr_point(&minmax.ptMaxTrackSize));
SendMessageW(hwnd, WM_GETMINMAXINFO, 0, (LPARAM)&minmax);
TRACE("app's ptMaxSize %s ptMaxPosition %s ptMinTrackSize %s ptMaxTrackSize %s\n", wine_dbgstr_point(&minmax.ptMaxSize),
wine_dbgstr_point(&minmax.ptMaxPosition), wine_dbgstr_point(&minmax.ptMinTrackSize), wine_dbgstr_point(&minmax.ptMaxTrackSize));
/* if the app didn't change the values, adapt them for the window's monitor */
if ((monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTOPRIMARY)))
{
MONITORINFO mon_info;
RECT monitor_rect;
mon_info.cbSize = sizeof(mon_info);
GetMonitorInfoW(monitor, &mon_info);
if ((style & WS_MAXIMIZEBOX) && ((style & WS_CAPTION) == WS_CAPTION || !(style & WS_POPUP)))
monitor_rect = mon_info.rcWork;
else
monitor_rect = mon_info.rcMonitor;
if (minmax.ptMaxSize.x == primary_monitor_rect.right - primary_monitor_rect.left &&
minmax.ptMaxSize.y == primary_monitor_rect.bottom - primary_monitor_rect.top)
{
minmax.ptMaxSize.x = (monitor_rect.right - monitor_rect.left) + 2 * xinc;
minmax.ptMaxSize.y = (monitor_rect.bottom - monitor_rect.top) + 2 * yinc;
}
if (minmax.ptMaxPosition.x == -xinc && minmax.ptMaxPosition.y == -yinc)
{
minmax.ptMaxPosition.x = monitor_rect.left - xinc;
minmax.ptMaxPosition.y = monitor_rect.top - yinc;
}
}
minmax.ptMaxTrackSize.x = max(minmax.ptMaxTrackSize.x, minmax.ptMinTrackSize.x);
minmax.ptMaxTrackSize.y = max(minmax.ptMaxTrackSize.y, minmax.ptMinTrackSize.y);
TRACE("adjusted ptMaxSize %s ptMaxPosition %s ptMinTrackSize %s ptMaxTrackSize %s\n", wine_dbgstr_point(&minmax.ptMaxSize),
wine_dbgstr_point(&minmax.ptMaxPosition), wine_dbgstr_point(&minmax.ptMinTrackSize), wine_dbgstr_point(&minmax.ptMaxTrackSize));
if ((data = get_win_data(hwnd)) && data->cocoa_window)
{
SetRect(&min_rect, 0, 0, minmax.ptMinTrackSize.x, minmax.ptMinTrackSize.y);
SetRect(&max_rect, 0, 0, minmax.ptMaxTrackSize.x, minmax.ptMaxTrackSize.y);
macdrv_window_to_mac_rect(data, style, &min_rect);
macdrv_window_to_mac_rect(data, style, &max_rect);
min_size = CGSizeMake(min_rect.right - min_rect.left, min_rect.bottom - min_rect.top);
max_size = CGSizeMake(max_rect.right - max_rect.left, max_rect.bottom - max_rect.top);
TRACE("min_size (%g,%g) max_size (%g,%g)\n", min_size.width, min_size.height, max_size.width, max_size.height);
macdrv_set_window_min_max_sizes(data->cocoa_window, min_size, max_size);
}
release_win_data(data);
}
/**********************************************************************
* create_cocoa_window
*
@ -1858,3 +1981,16 @@ fail:
}
macdrv_quit_reply(FALSE);
}
/***********************************************************************
* query_resize_start
*
* Handler for QUERY_RESIZE_START query.
*/
BOOL query_resize_start(HWND hwnd)
{
TRACE("hwnd %p\n", hwnd);
sync_window_min_max_info(hwnd);
return TRUE;
}