winemac: Implement support for minimizing windows.

This commit is contained in:
Ken Thomases 2013-02-03 17:20:07 -06:00 committed by Alexandre Julliard
parent 6efd198c52
commit 8a0c8d9264
6 changed files with 151 additions and 4 deletions

View File

@ -47,6 +47,8 @@ @interface WineWindow : NSPanel <NSWindowDelegate>
BOOL usePerPixelAlpha;
BOOL causing_becomeKeyWindow;
BOOL ignore_windowMiniaturize;
BOOL ignore_windowDeminiaturize;
}
@property (retain, readonly, nonatomic) WineEventQueue* queue;

View File

@ -287,6 +287,22 @@ - (void) setMacDrvState:(const struct macdrv_window_state*)state
[NSApp addWindowsItem:self title:[self title] filename:NO];
}
[self setCollectionBehavior:behavior];
if (state->minimized && ![self isMiniaturized])
{
ignore_windowMiniaturize = TRUE;
[self miniaturize:nil];
}
else if (!state->minimized && [self isMiniaturized])
{
ignore_windowDeminiaturize = TRUE;
[self deminiaturize:nil];
}
/* Whatever events regarding minimization might have been in the queue are now stale. */
[queue discardEventsMatchingMask:event_mask_for_type(WINDOW_DID_MINIMIZE) |
event_mask_for_type(WINDOW_DID_UNMINIMIZE)
forWindow:self];
}
/* Returns whether or not the window was ordered in, which depends on if
@ -551,6 +567,25 @@ - (void)windowDidBecomeKey:(NSNotification *)notification
[NSApp windowGotFocus:self];
}
- (void)windowDidDeminiaturize:(NSNotification *)notification
{
if (!ignore_windowDeminiaturize)
{
macdrv_event event;
/* Coalesce events by discarding any previous ones still in the queue. */
[queue discardEventsMatchingMask:event_mask_for_type(WINDOW_DID_MINIMIZE) |
event_mask_for_type(WINDOW_DID_UNMINIMIZE)
forWindow:self];
event.type = WINDOW_DID_UNMINIMIZE;
event.window = (macdrv_window)[self retain];
[queue postEvent:&event];
}
ignore_windowDeminiaturize = FALSE;
}
- (void)windowDidMove:(NSNotification *)notification
{
[self windowDidResize:notification];
@ -593,6 +628,25 @@ - (BOOL)windowShouldClose:(id)sender
return NO;
}
- (void)windowWillMiniaturize:(NSNotification *)notification
{
if (!ignore_windowMiniaturize)
{
macdrv_event event;
/* Coalesce events by discarding any previous ones still in the queue. */
[queue discardEventsMatchingMask:event_mask_for_type(WINDOW_DID_MINIMIZE) |
event_mask_for_type(WINDOW_DID_UNMINIMIZE)
forWindow:self];
event.type = WINDOW_DID_MINIMIZE;
event.window = (macdrv_window)[self retain];
[queue postEvent:&event];
}
ignore_windowMiniaturize = FALSE;
}
@end

View File

@ -35,6 +35,8 @@ static const char *dbgstr_event(int type)
"APP_DEACTIVATED",
"MOUSE_BUTTON",
"WINDOW_CLOSE_REQUESTED",
"WINDOW_DID_MINIMIZE",
"WINDOW_DID_UNMINIMIZE",
"WINDOW_FRAME_CHANGED",
"WINDOW_GOT_FOCUS",
"WINDOW_LOST_FOCUS",
@ -61,6 +63,8 @@ static macdrv_event_mask get_event_mask(DWORD mask)
{
event_mask |= event_mask_for_type(APP_DEACTIVATED);
event_mask |= event_mask_for_type(WINDOW_CLOSE_REQUESTED);
event_mask |= event_mask_for_type(WINDOW_DID_MINIMIZE);
event_mask |= event_mask_for_type(WINDOW_DID_UNMINIMIZE);
event_mask |= event_mask_for_type(WINDOW_FRAME_CHANGED);
event_mask |= event_mask_for_type(WINDOW_GOT_FOCUS);
event_mask |= event_mask_for_type(WINDOW_LOST_FOCUS);
@ -96,6 +100,12 @@ void macdrv_handle_event(macdrv_event *event)
case WINDOW_CLOSE_REQUESTED:
macdrv_window_close_requested(hwnd);
break;
case WINDOW_DID_MINIMIZE:
macdrv_window_did_minimize(hwnd);
break;
case WINDOW_DID_UNMINIMIZE:
macdrv_window_did_unminimize(hwnd);
break;
case WINDOW_FRAME_CHANGED:
macdrv_window_frame_changed(hwnd, event->window_frame_changed.frame);
break;

View File

@ -105,10 +105,11 @@ static inline RECT rect_from_cgrect(CGRect cgrect)
RECT whole_rect; /* Mac window rectangle for the whole window relative to parent */
RECT client_rect; /* client area relative to parent */
COLORREF color_key; /* color key for layered window; CLR_INVALID is not color keyed */
BOOL on_screen : 1; /* is window ordered in? */
BOOL on_screen : 1; /* is window ordered in? (minimized or not) */
BOOL shaped : 1; /* is window using a custom region shape? */
BOOL layered : 1; /* is window layered and with valid attributes? */
BOOL per_pixel_alpha : 1; /* is window using per-pixel alpha? */
BOOL minimized : 1; /* is window minimized? */
struct window_surface *surface;
};
@ -122,6 +123,8 @@ static inline RECT rect_from_cgrect(CGRect cgrect)
extern void macdrv_window_got_focus(HWND hwnd, const macdrv_event *event) DECLSPEC_HIDDEN;
extern void macdrv_window_lost_focus(HWND hwnd, const macdrv_event *event) DECLSPEC_HIDDEN;
extern void macdrv_app_deactivated(void) DECLSPEC_HIDDEN;
extern void macdrv_window_did_minimize(HWND hwnd) DECLSPEC_HIDDEN;
extern void macdrv_window_did_unminimize(HWND hwnd) DECLSPEC_HIDDEN;
extern void macdrv_mouse_button(HWND hwnd, const macdrv_event *event) DECLSPEC_HIDDEN;

View File

@ -127,6 +127,8 @@
APP_DEACTIVATED,
MOUSE_BUTTON,
WINDOW_CLOSE_REQUESTED,
WINDOW_DID_MINIMIZE,
WINDOW_DID_UNMINIMIZE,
WINDOW_FRAME_CHANGED,
WINDOW_GOT_FOCUS,
WINDOW_LOST_FOCUS,
@ -186,6 +188,7 @@ extern int macdrv_get_event_from_queue(macdrv_event_queue queue,
unsigned int floating:1;
unsigned int excluded_by_expose:1;
unsigned int excluded_by_cycle:1;
unsigned int minimized:1;
};
extern macdrv_window macdrv_create_cocoa_window(const struct macdrv_window_features* wf,

View File

@ -113,6 +113,7 @@ static void get_cocoa_window_state(struct macdrv_win_data *data,
state->excluded_by_expose = state->excluded_by_cycle =
!(ex_style & WS_EX_APPWINDOW) &&
(GetWindow(data->hwnd, GW_OWNER) || (ex_style & (WS_EX_TOOLWINDOW | WS_EX_NOACTIVATE)));
state->minimized = (style & WS_MINIMIZE) != 0;
}
@ -337,6 +338,7 @@ static void set_cocoa_window_properties(struct macdrv_win_data *data)
get_cocoa_window_state(data, style, ex_style, &state);
macdrv_set_cocoa_window_state(data->cocoa_window, &state);
data->minimized = state.minimized;
}
@ -674,7 +676,11 @@ RGNDATA *get_region_data(HRGN hrgn, HDC hdc_lptodp)
*/
static void sync_window_position(struct macdrv_win_data *data, UINT swp_flags)
{
CGRect frame = cgrect_from_rect(data->whole_rect);
CGRect frame;
if (data->minimized) return;
frame = cgrect_from_rect(data->whole_rect);
constrain_window_frame(&frame);
data->on_screen = macdrv_set_cocoa_window_frame(data->cocoa_window, &frame);
@ -1010,7 +1016,9 @@ UINT CDECL macdrv_ShowWindow(HWND hwnd, INT cmd, RECT *rect, UINT swp)
if (!thread_data->current_event || thread_data->current_event->window != data->cocoa_window)
goto done;
if (thread_data->current_event->type != WINDOW_FRAME_CHANGED)
if (thread_data->current_event->type != WINDOW_FRAME_CHANGED &&
thread_data->current_event->type != WINDOW_DID_MINIMIZE &&
thread_data->current_event->type != WINDOW_DID_UNMINIMIZE)
goto done;
TRACE("win %p/%p cmd %d at %s flags %08x\n",
@ -1309,7 +1317,9 @@ void CDECL macdrv_WindowPosChanged(HWND hwnd, HWND insert_after, UINT swp_flags,
/* 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)
(thread_data->current_event->type != WINDOW_FRAME_CHANGED &&
thread_data->current_event->type != WINDOW_DID_MINIMIZE &&
thread_data->current_event->type != WINDOW_DID_UNMINIMIZE))
{
sync_window_position(data, swp_flags);
set_cocoa_window_properties(data);
@ -1484,3 +1494,68 @@ void macdrv_app_deactivated(void)
SetForegroundWindow(GetDesktopWindow());
}
}
/***********************************************************************
* macdrv_window_did_minimize
*
* Handler for WINDOW_DID_MINIMIZE events.
*/
void macdrv_window_did_minimize(HWND hwnd)
{
struct macdrv_win_data *data;
DWORD style;
TRACE("win %p\n", hwnd);
if (!(data = get_win_data(hwnd))) return;
if (data->minimized) goto done;
style = GetWindowLongW(hwnd, GWL_STYLE);
data->minimized = TRUE;
if ((style & WS_MINIMIZEBOX) && !(style & WS_DISABLED))
{
TRACE("minimizing win %p/%p\n", hwnd, data->cocoa_window);
release_win_data(data);
SendMessageW(hwnd, WM_SYSCOMMAND, SC_MINIMIZE, 0);
return;
}
TRACE("not minimizing win %p/%p style %08x\n", hwnd, data->cocoa_window, style);
done:
release_win_data(data);
}
/***********************************************************************
* macdrv_window_did_unminimize
*
* Handler for WINDOW_DID_UNMINIMIZE events.
*/
void macdrv_window_did_unminimize(HWND hwnd)
{
struct macdrv_win_data *data;
DWORD style;
TRACE("win %p\n", hwnd);
if (!(data = get_win_data(hwnd))) return;
if (!data->minimized) goto done;
style = GetWindowLongW(hwnd, GWL_STYLE);
data->minimized = FALSE;
if (style & (WS_MINIMIZE | WS_MAXIMIZE))
{
TRACE("restoring win %p/%p\n", hwnd, data->cocoa_window);
release_win_data(data);
SendMessageW(hwnd, WM_SYSCOMMAND, SC_RESTORE, 0);
return;
}
TRACE("not restoring win %p/%p style %08x\n", hwnd, data->cocoa_window, style);
done:
release_win_data(data);
}