winemac: At the start of a resize operation, get window min/max size info and pass it to Cocoa.
This commit is contained in:
parent
040e47fece
commit
a3197b8ad0
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue