winemac: Implement WINDOW_FRAME_CHANGED event to tell Wine when window is moved or resized.
This commit is contained in:
parent
b28aff0dd7
commit
6e59740e18
|
@ -207,6 +207,10 @@ + (WineWindow*) createWindowWithFeatures:(const struct macdrv_window_features*)w
|
||||||
|
|
||||||
[window setContentView:contentView];
|
[window setContentView:contentView];
|
||||||
|
|
||||||
|
/* In case Cocoa adjusted the frame we tried to set, generate a frame-changed
|
||||||
|
event. The back end will ignore it if nothing actually changed. */
|
||||||
|
[window windowDidResize:nil];
|
||||||
|
|
||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,6 +301,11 @@ - (BOOL) orderBelow:(WineWindow*)prev orAbove:(WineWindow*)next
|
||||||
self.latentParentWindow = nil;
|
self.latentParentWindow = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Cocoa may adjust the frame when the window is ordered onto the screen.
|
||||||
|
Generate a frame-changed event just in case. The back end will ignore
|
||||||
|
it if nothing actually changed. */
|
||||||
|
[self windowDidResize:nil];
|
||||||
|
|
||||||
if (![self isExcludedFromWindowsMenu])
|
if (![self isExcludedFromWindowsMenu])
|
||||||
[NSApp addWindowsItem:self title:[self title] filename:NO];
|
[NSApp addWindowsItem:self title:[self title] filename:NO];
|
||||||
}
|
}
|
||||||
|
@ -341,6 +350,10 @@ - (BOOL) setFrameIfOnScreen:(NSRect)contentRect
|
||||||
[self setFrame:frame display:YES];
|
[self setFrame:frame display:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* In case Cocoa adjusted the frame we tried to set, generate a frame-changed
|
||||||
|
event. The back end will ignore it if nothing actually changed. */
|
||||||
|
[self windowDidResize:nil];
|
||||||
|
|
||||||
return on_screen;
|
return on_screen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,6 +448,28 @@ - (BOOL) validateMenuItem:(NSMenuItem *)menuItem
|
||||||
/*
|
/*
|
||||||
* ---------- NSWindowDelegate methods ----------
|
* ---------- NSWindowDelegate methods ----------
|
||||||
*/
|
*/
|
||||||
|
- (void)windowDidMove:(NSNotification *)notification
|
||||||
|
{
|
||||||
|
[self windowDidResize:notification];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)windowDidResize:(NSNotification *)notification
|
||||||
|
{
|
||||||
|
macdrv_event event;
|
||||||
|
NSRect frame = [self contentRectForFrameRect:[self frame]];
|
||||||
|
|
||||||
|
[[self class] flipRect:&frame];
|
||||||
|
|
||||||
|
/* Coalesce events by discarding any previous ones still in the queue. */
|
||||||
|
[queue discardEventsMatchingMask:event_mask_for_type(WINDOW_FRAME_CHANGED)
|
||||||
|
forWindow:self];
|
||||||
|
|
||||||
|
event.type = WINDOW_FRAME_CHANGED;
|
||||||
|
event.window = (macdrv_window)[self retain];
|
||||||
|
event.window_frame_changed.frame = NSRectToCGRect(frame);
|
||||||
|
[queue postEvent:&event];
|
||||||
|
}
|
||||||
|
|
||||||
- (BOOL)windowShouldClose:(id)sender
|
- (BOOL)windowShouldClose:(id)sender
|
||||||
{
|
{
|
||||||
macdrv_event event;
|
macdrv_event event;
|
||||||
|
@ -611,6 +646,24 @@ int macdrv_set_cocoa_window_frame(macdrv_window w, const CGRect* new_frame)
|
||||||
return on_screen;
|
return on_screen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* macdrv_get_cocoa_window_frame
|
||||||
|
*
|
||||||
|
* Gets the frame of a Cocoa window.
|
||||||
|
*/
|
||||||
|
void macdrv_get_cocoa_window_frame(macdrv_window w, CGRect* out_frame)
|
||||||
|
{
|
||||||
|
WineWindow* window = (WineWindow*)w;
|
||||||
|
|
||||||
|
OnMainThread(^{
|
||||||
|
NSRect frame;
|
||||||
|
|
||||||
|
frame = [window contentRectForFrameRect:[window frame]];
|
||||||
|
[[window class] flipRect:&frame];
|
||||||
|
*out_frame = NSRectToCGRect(frame);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* macdrv_set_cocoa_parent_window
|
* macdrv_set_cocoa_parent_window
|
||||||
*
|
*
|
||||||
|
|
|
@ -33,6 +33,7 @@ static const char *dbgstr_event(int type)
|
||||||
{
|
{
|
||||||
static const char * const event_names[] = {
|
static const char * const event_names[] = {
|
||||||
"WINDOW_CLOSE_REQUESTED",
|
"WINDOW_CLOSE_REQUESTED",
|
||||||
|
"WINDOW_FRAME_CHANGED",
|
||||||
};
|
};
|
||||||
|
|
||||||
if (0 <= type && type < NUM_EVENT_TYPES) return event_names[type];
|
if (0 <= type && type < NUM_EVENT_TYPES) return event_names[type];
|
||||||
|
@ -50,7 +51,10 @@ static macdrv_event_mask get_event_mask(DWORD mask)
|
||||||
if ((mask & QS_ALLINPUT) == QS_ALLINPUT) return -1;
|
if ((mask & QS_ALLINPUT) == QS_ALLINPUT) return -1;
|
||||||
|
|
||||||
if (mask & QS_POSTMESSAGE)
|
if (mask & QS_POSTMESSAGE)
|
||||||
|
{
|
||||||
event_mask |= event_mask_for_type(WINDOW_CLOSE_REQUESTED);
|
event_mask |= event_mask_for_type(WINDOW_CLOSE_REQUESTED);
|
||||||
|
event_mask |= event_mask_for_type(WINDOW_FRAME_CHANGED);
|
||||||
|
}
|
||||||
|
|
||||||
return event_mask;
|
return event_mask;
|
||||||
}
|
}
|
||||||
|
@ -76,6 +80,9 @@ void macdrv_handle_event(macdrv_event *event)
|
||||||
case WINDOW_CLOSE_REQUESTED:
|
case WINDOW_CLOSE_REQUESTED:
|
||||||
macdrv_window_close_requested(hwnd);
|
macdrv_window_close_requested(hwnd);
|
||||||
break;
|
break;
|
||||||
|
case WINDOW_FRAME_CHANGED:
|
||||||
|
macdrv_window_frame_changed(hwnd, event->window_frame_changed.frame);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
TRACE(" ignoring\n");
|
TRACE(" ignoring\n");
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -118,5 +118,6 @@ static inline RECT rect_from_cgrect(CGRect cgrect)
|
||||||
extern void set_surface_use_alpha(struct window_surface *window_surface, BOOL use_alpha) DECLSPEC_HIDDEN;
|
extern void set_surface_use_alpha(struct window_surface *window_surface, BOOL use_alpha) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
extern void macdrv_window_close_requested(HWND hwnd) DECLSPEC_HIDDEN;
|
extern void macdrv_window_close_requested(HWND hwnd) DECLSPEC_HIDDEN;
|
||||||
|
extern void macdrv_window_frame_changed(HWND hwnd, CGRect frame) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
#endif /* __WINE_MACDRV_H */
|
#endif /* __WINE_MACDRV_H */
|
||||||
|
|
|
@ -123,6 +123,7 @@
|
||||||
/* event */
|
/* event */
|
||||||
enum {
|
enum {
|
||||||
WINDOW_CLOSE_REQUESTED,
|
WINDOW_CLOSE_REQUESTED,
|
||||||
|
WINDOW_FRAME_CHANGED,
|
||||||
NUM_EVENT_TYPES
|
NUM_EVENT_TYPES
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -131,6 +132,11 @@
|
||||||
typedef struct macdrv_event {
|
typedef struct macdrv_event {
|
||||||
int type;
|
int type;
|
||||||
macdrv_window window;
|
macdrv_window window;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
CGRect frame;
|
||||||
|
} window_frame_changed;
|
||||||
|
};
|
||||||
} macdrv_event;
|
} macdrv_event;
|
||||||
|
|
||||||
static inline macdrv_event_mask event_mask_for_type(int type)
|
static inline macdrv_event_mask event_mask_for_type(int type)
|
||||||
|
@ -179,6 +185,7 @@ extern int macdrv_order_cocoa_window(macdrv_window w, macdrv_window prev,
|
||||||
macdrv_window next) DECLSPEC_HIDDEN;
|
macdrv_window next) DECLSPEC_HIDDEN;
|
||||||
extern void macdrv_hide_cocoa_window(macdrv_window w) DECLSPEC_HIDDEN;
|
extern void macdrv_hide_cocoa_window(macdrv_window w) DECLSPEC_HIDDEN;
|
||||||
extern int macdrv_set_cocoa_window_frame(macdrv_window w, const CGRect* new_frame) DECLSPEC_HIDDEN;
|
extern int macdrv_set_cocoa_window_frame(macdrv_window w, const CGRect* new_frame) DECLSPEC_HIDDEN;
|
||||||
|
extern void macdrv_get_cocoa_window_frame(macdrv_window w, CGRect* out_frame) DECLSPEC_HIDDEN;
|
||||||
extern void macdrv_set_cocoa_parent_window(macdrv_window w, macdrv_window parent) DECLSPEC_HIDDEN;
|
extern void macdrv_set_cocoa_parent_window(macdrv_window w, macdrv_window parent) DECLSPEC_HIDDEN;
|
||||||
extern void macdrv_set_window_surface(macdrv_window w, void *surface, pthread_mutex_t *mutex) DECLSPEC_HIDDEN;
|
extern void macdrv_set_window_surface(macdrv_window w, void *surface, pthread_mutex_t *mutex) DECLSPEC_HIDDEN;
|
||||||
extern CGImageRef create_surface_image(void *window_surface, CGRect *rect, int copy_data) DECLSPEC_HIDDEN;
|
extern CGImageRef create_surface_image(void *window_surface, CGRect *rect, int copy_data) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -949,6 +949,51 @@ void CDECL macdrv_SetWindowText(HWND hwnd, LPCWSTR text)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* ShowWindow (MACDRV.@)
|
||||||
|
*/
|
||||||
|
UINT CDECL macdrv_ShowWindow(HWND hwnd, INT cmd, RECT *rect, UINT swp)
|
||||||
|
{
|
||||||
|
struct macdrv_thread_data *thread_data = macdrv_thread_data();
|
||||||
|
struct macdrv_win_data *data = get_win_data(hwnd);
|
||||||
|
CGRect frame;
|
||||||
|
|
||||||
|
if (!data || !data->cocoa_window) goto done;
|
||||||
|
if (IsRectEmpty(rect)) goto done;
|
||||||
|
if (GetWindowLongW(hwnd, GWL_STYLE) & WS_MINIMIZE)
|
||||||
|
{
|
||||||
|
if (rect->left != -32000 || rect->top != -32000)
|
||||||
|
{
|
||||||
|
OffsetRect(rect, -32000 - rect->left, -32000 - rect->top);
|
||||||
|
swp &= ~(SWP_NOMOVE | SWP_NOCLIENTMOVE);
|
||||||
|
}
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (!data->on_screen) goto done;
|
||||||
|
|
||||||
|
/* only fetch the new rectangle if the ShowWindow was a result of an external event */
|
||||||
|
|
||||||
|
if (!thread_data->current_event || thread_data->current_event->window != data->cocoa_window)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
if (thread_data->current_event->type != WINDOW_FRAME_CHANGED)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
TRACE("win %p/%p cmd %d at %s flags %08x\n",
|
||||||
|
hwnd, data->cocoa_window, cmd, wine_dbgstr_rect(rect), swp);
|
||||||
|
|
||||||
|
macdrv_get_cocoa_window_frame(data->cocoa_window, &frame);
|
||||||
|
*rect = rect_from_cgrect(frame);
|
||||||
|
macdrv_mac_to_window_rect(data, rect);
|
||||||
|
TRACE("rect %s -> %s\n", wine_dbgstr_cgrect(frame), wine_dbgstr_rect(rect));
|
||||||
|
swp &= ~(SWP_NOMOVE | SWP_NOCLIENTMOVE | SWP_NOSIZE | SWP_NOCLIENTSIZE);
|
||||||
|
|
||||||
|
done:
|
||||||
|
release_win_data(data);
|
||||||
|
return swp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* UpdateLayeredWindow (MACDRV.@)
|
* UpdateLayeredWindow (MACDRV.@)
|
||||||
*/
|
*/
|
||||||
|
@ -1148,12 +1193,15 @@ void CDECL macdrv_WindowPosChanged(HWND hwnd, HWND insert_after, UINT swp_flags,
|
||||||
const RECT *visible_rect, const RECT *valid_rects,
|
const RECT *visible_rect, const RECT *valid_rects,
|
||||||
struct window_surface *surface)
|
struct window_surface *surface)
|
||||||
{
|
{
|
||||||
|
struct macdrv_thread_data *thread_data;
|
||||||
struct macdrv_win_data *data;
|
struct macdrv_win_data *data;
|
||||||
DWORD new_style = GetWindowLongW(hwnd, GWL_STYLE);
|
DWORD new_style = GetWindowLongW(hwnd, GWL_STYLE);
|
||||||
RECT old_window_rect, old_whole_rect, old_client_rect;
|
RECT old_window_rect, old_whole_rect, old_client_rect;
|
||||||
|
|
||||||
if (!(data = get_win_data(hwnd))) return;
|
if (!(data = get_win_data(hwnd))) return;
|
||||||
|
|
||||||
|
thread_data = macdrv_thread_data();
|
||||||
|
|
||||||
old_window_rect = data->window_rect;
|
old_window_rect = data->window_rect;
|
||||||
old_whole_rect = data->whole_rect;
|
old_whole_rect = data->whole_rect;
|
||||||
old_client_rect = data->client_rect;
|
old_client_rect = data->client_rect;
|
||||||
|
@ -1224,8 +1272,14 @@ void CDECL macdrv_WindowPosChanged(HWND hwnd, HWND insert_after, UINT swp_flags,
|
||||||
show_window(data);
|
show_window(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check if we are currently processing an event relevant to this window */
|
||||||
|
if (!thread_data || !thread_data->current_event ||
|
||||||
|
thread_data->current_event->window != data->cocoa_window ||
|
||||||
|
thread_data->current_event->type != WINDOW_FRAME_CHANGED)
|
||||||
|
{
|
||||||
sync_window_position(data, swp_flags);
|
sync_window_position(data, swp_flags);
|
||||||
set_cocoa_window_properties(data);
|
set_cocoa_window_properties(data);
|
||||||
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
release_win_data(data);
|
release_win_data(data);
|
||||||
|
@ -1279,3 +1333,55 @@ void macdrv_window_close_requested(HWND hwnd)
|
||||||
PostMessageW(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0);
|
PostMessageW(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* macdrv_window_frame_changed
|
||||||
|
*
|
||||||
|
* Handler for WINDOW_FRAME_CHANGED events.
|
||||||
|
*/
|
||||||
|
void macdrv_window_frame_changed(HWND hwnd, CGRect frame)
|
||||||
|
{
|
||||||
|
struct macdrv_win_data *data;
|
||||||
|
RECT rect;
|
||||||
|
HWND parent;
|
||||||
|
UINT flags = SWP_NOACTIVATE | SWP_NOZORDER;
|
||||||
|
int width, height;
|
||||||
|
|
||||||
|
if (!hwnd) return;
|
||||||
|
if (!(data = get_win_data(hwnd))) return;
|
||||||
|
if (!data->on_screen) goto done;
|
||||||
|
|
||||||
|
/* Get geometry */
|
||||||
|
|
||||||
|
parent = GetAncestor(hwnd, GA_PARENT);
|
||||||
|
|
||||||
|
TRACE("win %p/%p new Cocoa frame %s\n", hwnd, data->cocoa_window, wine_dbgstr_cgrect(frame));
|
||||||
|
|
||||||
|
rect = rect_from_cgrect(frame);
|
||||||
|
macdrv_mac_to_window_rect(data, &rect);
|
||||||
|
MapWindowPoints(0, parent, (POINT *)&rect, 2);
|
||||||
|
|
||||||
|
width = rect.right - rect.left;
|
||||||
|
height = rect.bottom - rect.top;
|
||||||
|
|
||||||
|
if (data->window_rect.left == rect.left && data->window_rect.top == rect.top)
|
||||||
|
flags |= SWP_NOMOVE;
|
||||||
|
else
|
||||||
|
TRACE("%p moving from (%d,%d) to (%d,%d)\n", hwnd, data->window_rect.left,
|
||||||
|
data->window_rect.top, rect.left, rect.top);
|
||||||
|
|
||||||
|
if ((data->window_rect.right - data->window_rect.left == width &&
|
||||||
|
data->window_rect.bottom - data->window_rect.top == height) ||
|
||||||
|
(IsRectEmpty(&data->window_rect) && width <= 0 && height <= 0))
|
||||||
|
flags |= SWP_NOSIZE;
|
||||||
|
else
|
||||||
|
TRACE("%p resizing from (%dx%d) to (%dx%d)\n", hwnd, data->window_rect.right - data->window_rect.left,
|
||||||
|
data->window_rect.bottom - data->window_rect.top, width, height);
|
||||||
|
|
||||||
|
done:
|
||||||
|
release_win_data(data);
|
||||||
|
|
||||||
|
if (!(flags & SWP_NOSIZE) || !(flags & SWP_NOMOVE))
|
||||||
|
SetWindowPos(hwnd, 0, rect.left, rect.top, width, height, flags);
|
||||||
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
@ cdecl SetWindowRgn(long long long) macdrv_SetWindowRgn
|
@ cdecl SetWindowRgn(long long long) macdrv_SetWindowRgn
|
||||||
@ cdecl SetWindowStyle(ptr long ptr) macdrv_SetWindowStyle
|
@ cdecl SetWindowStyle(ptr long ptr) macdrv_SetWindowStyle
|
||||||
@ cdecl SetWindowText(long wstr) macdrv_SetWindowText
|
@ cdecl SetWindowText(long wstr) macdrv_SetWindowText
|
||||||
|
@ cdecl ShowWindow(long long ptr long) macdrv_ShowWindow
|
||||||
@ cdecl UpdateLayeredWindow(long ptr ptr) macdrv_UpdateLayeredWindow
|
@ cdecl UpdateLayeredWindow(long ptr ptr) macdrv_UpdateLayeredWindow
|
||||||
@ cdecl WindowMessage(long long long long) macdrv_WindowMessage
|
@ cdecl WindowMessage(long long long long) macdrv_WindowMessage
|
||||||
@ cdecl WindowPosChanged(long long long ptr ptr ptr ptr ptr) macdrv_WindowPosChanged
|
@ cdecl WindowPosChanged(long long long ptr ptr ptr ptr ptr) macdrv_WindowPosChanged
|
||||||
|
|
Loading…
Reference in New Issue