winemac: Implement support for maximizing windows.

The user is prevented from moving or resizing a maximized window.  The zoom
button is still present and enabled for a maximized window but requests that
it be restored rather than simply resizing it, which is what it does for
normal windows.

If a window is not resizable (lacks WS_THICKFRAME) but has a maximize box
(WS_MAXIMIZEBOX), then the zoom button requests that it be maximized rather
than resizing it.
This commit is contained in:
Ken Thomases 2013-12-29 21:34:48 -06:00 committed by Alexandre Julliard
parent 0137b07973
commit 66736b4ab3
6 changed files with 83 additions and 8 deletions

View File

@ -29,6 +29,8 @@ @interface WineWindow : NSPanel <NSWindowDelegate>
BOOL disabled;
BOOL noActivate;
BOOL floating;
BOOL resizable;
BOOL maximized;
BOOL fullscreen;
BOOL pendingMinimize;
WineWindow* latentParentWindow;

View File

@ -57,7 +57,7 @@ static NSUInteger style_mask_for_features(const struct macdrv_window_features* w
style_mask = NSTitledWindowMask;
if (wf->close_button) style_mask |= NSClosableWindowMask;
if (wf->minimize_button) style_mask |= NSMiniaturizableWindowMask;
if (wf->resizable) style_mask |= NSResizableWindowMask;
if (wf->resizable || wf->maximize_button) style_mask |= NSResizableWindowMask;
if (wf->utility) style_mask |= NSUtilityWindowMask;
}
else style_mask = NSBorderlessWindowMask;
@ -569,6 +569,7 @@ + (WineWindow*) createWindowWithFeatures:(const struct macdrv_window_features*)w
window.queue = queue;
window->savedContentMinSize = NSZeroSize;
window->savedContentMaxSize = NSMakeSize(FLT_MAX, FLT_MAX);
window->resizable = wf->resizable;
[window registerForDraggedTypes:[NSArray arrayWithObjects:(NSString*)kUTTypeData,
(NSString*)kUTTypeContent,
@ -615,6 +616,11 @@ - (void) dealloc
[super dealloc];
}
- (BOOL) preventResizing
{
return ([self styleMask] & NSResizableWindowMask) && (disabled || !resizable || maximized);
}
- (void) adjustFeaturesForState
{
NSUInteger style = [self styleMask];
@ -631,7 +637,7 @@ - (void) adjustFeaturesForState
[[self standardWindowButton:NSWindowFullScreenButton] setEnabled:!self.disabled];
}
if (disabled)
if ([self preventResizing])
{
NSSize size = [self contentRectForFrameRect:[self frame]].size;
[self setContentMinSize:size];
@ -644,7 +650,7 @@ - (void) adjustFeaturesForState
}
if (allow_immovable_windows)
[self setMovable:!disabled];
[self setMovable:!disabled && !maximized];
}
- (void) adjustFullScreenBehavior:(NSWindowCollectionBehavior)behavior
@ -703,6 +709,7 @@ - (void) setWindowFeatures:(const struct macdrv_window_features*)wf
[self setTitle:title];
}
resizable = wf->resizable;
[self adjustFeaturesForState];
[self setHasShadow:wf->shadow];
}
@ -846,6 +853,12 @@ - (void) setMacDrvState:(const struct macdrv_window_state*)state
forWindow:self];
}
}
if (state->maximized != maximized)
{
maximized = state->maximized;
[self adjustFeaturesForState];
}
}
- (BOOL) addChildWineWindow:(WineWindow*)child assumeVisible:(BOOL)assumeVisible
@ -1231,7 +1244,7 @@ - (void) setFrameFromWine:(NSRect)contentRect
BOOL equalSizes = NSEqualSizes(frame.size, oldFrame.size);
BOOL needEnableScreenUpdates = FALSE;
if (disabled)
if ([self preventResizing])
{
// Allow the following calls to -setFrame:display: to work even
// if they would violate the content size constraints. This
@ -1259,7 +1272,7 @@ - (void) setFrameFromWine:(NSRect)contentRect
}
[self setFrame:frame display:YES];
if (disabled)
if ([self preventResizing])
{
[self setContentMinSize:contentRect.size];
[self setContentMaxSize:contentRect.size];
@ -1414,7 +1427,7 @@ - (void) setWineMinSize:(NSSize)minSize maxSize:(NSSize)maxSize
{
savedContentMinSize = minSize;
savedContentMaxSize = maxSize;
if (!self.disabled)
if (![self preventResizing])
{
[self setContentMinSize:minSize];
[self setContentMaxSize:maxSize];
@ -1750,7 +1763,7 @@ - (void)windowDidResize:(NSNotification *)notification
if (ignore_windowResize || exitingFullScreen) return;
if (self.disabled)
if ([self preventResizing])
{
[self setContentMinSize:frame.size];
[self setContentMaxSize:frame.size];
@ -1781,6 +1794,26 @@ - (BOOL)windowShouldClose:(id)sender
return NO;
}
- (BOOL) windowShouldZoom:(NSWindow*)window toFrame:(NSRect)newFrame
{
if (maximized)
{
macdrv_event* event = macdrv_create_event(WINDOW_RESTORE_REQUESTED, self);
[queue postEvent:event];
macdrv_release_event(event);
return NO;
}
else if (!resizable)
{
macdrv_event* event = macdrv_create_event(WINDOW_MAXIMIZE_REQUESTED, self);
[queue postEvent:event];
macdrv_release_event(event);
return NO;
}
return YES;
}
- (void) windowWillClose:(NSNotification*)notification
{
WineWindow* child;

View File

@ -56,8 +56,10 @@ static const char *dbgstr_event(int type)
"WINDOW_FRAME_CHANGED",
"WINDOW_GOT_FOCUS",
"WINDOW_LOST_FOCUS",
"WINDOW_MAXIMIZE_REQUESTED",
"WINDOW_MINIMIZE_REQUESTED",
"WINDOW_RESIZE_ENDED",
"WINDOW_RESTORE_REQUESTED",
};
if (0 <= type && type < NUM_EVENT_TYPES) return event_names[type];
@ -118,8 +120,10 @@ static macdrv_event_mask get_event_mask(DWORD mask)
event_mask |= event_mask_for_type(WINDOW_CLOSE_REQUESTED);
event_mask |= event_mask_for_type(WINDOW_DRAG_BEGIN);
event_mask |= event_mask_for_type(WINDOW_DRAG_END);
event_mask |= event_mask_for_type(WINDOW_MAXIMIZE_REQUESTED);
event_mask |= event_mask_for_type(WINDOW_MINIMIZE_REQUESTED);
event_mask |= event_mask_for_type(WINDOW_RESIZE_ENDED);
event_mask |= event_mask_for_type(WINDOW_RESTORE_REQUESTED);
}
return event_mask;
@ -262,12 +266,18 @@ void macdrv_handle_event(const macdrv_event *event)
case WINDOW_LOST_FOCUS:
macdrv_window_lost_focus(hwnd, event);
break;
case WINDOW_MAXIMIZE_REQUESTED:
macdrv_window_maximize_requested(hwnd);
break;
case WINDOW_MINIMIZE_REQUESTED:
macdrv_window_minimize_requested(hwnd);
break;
case WINDOW_RESIZE_ENDED:
macdrv_window_resize_ended(hwnd);
break;
case WINDOW_RESTORE_REQUESTED:
macdrv_window_restore_requested(hwnd);
break;
default:
TRACE(" ignoring\n");
break;

View File

@ -164,10 +164,12 @@ static inline RECT rect_from_cgrect(CGRect cgrect)
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_app_quit_requested(const macdrv_event *event) DECLSPEC_HIDDEN;
extern void macdrv_window_maximize_requested(HWND hwnd) DECLSPEC_HIDDEN;
extern void macdrv_window_minimize_requested(HWND hwnd) DECLSPEC_HIDDEN;
extern void macdrv_window_did_unminimize(HWND hwnd) DECLSPEC_HIDDEN;
extern void macdrv_window_brought_forward(HWND hwnd) DECLSPEC_HIDDEN;
extern void macdrv_window_resize_ended(HWND hwnd) DECLSPEC_HIDDEN;
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_start(HWND hwnd) DECLSPEC_HIDDEN;

View File

@ -197,8 +197,10 @@ extern int macdrv_set_display_mode(const struct macdrv_display* display,
WINDOW_FRAME_CHANGED,
WINDOW_GOT_FOCUS,
WINDOW_LOST_FOCUS,
WINDOW_MAXIMIZE_REQUESTED,
WINDOW_MINIMIZE_REQUESTED,
WINDOW_RESIZE_ENDED,
WINDOW_RESTORE_REQUESTED,
NUM_EVENT_TYPES
};
@ -362,6 +364,7 @@ extern int macdrv_register_hot_key(macdrv_event_queue q, unsigned int vkey, unsi
unsigned int close_button:1;
unsigned int minimize_button:1;
unsigned int resizable:1;
unsigned int maximize_button:1;
unsigned int utility:1;
unsigned int shadow:1;
};
@ -374,6 +377,7 @@ extern int macdrv_register_hot_key(macdrv_event_queue q, unsigned int vkey, unsi
unsigned int excluded_by_cycle:1;
unsigned int minimized:1;
unsigned int minimized_valid:1;
unsigned int maximized:1;
};
extern macdrv_window macdrv_create_cocoa_window(const struct macdrv_window_features* wf,

View File

@ -68,7 +68,7 @@ static void get_cocoa_window_features(struct macdrv_win_data *data,
wf->title_bar = TRUE;
if (style & WS_SYSMENU) wf->close_button = TRUE;
if (style & WS_MINIMIZEBOX) wf->minimize_button = TRUE;
if (style & WS_MAXIMIZEBOX) wf->resizable = TRUE;
if (style & WS_MAXIMIZEBOX) wf->maximize_button = TRUE;
if (ex_style & WS_EX_TOOLWINDOW) wf->utility = TRUE;
}
}
@ -117,6 +117,7 @@ static void get_cocoa_window_state(struct macdrv_win_data *data,
state->excluded_by_expose = TRUE;
state->minimized = (style & WS_MINIMIZE) != 0;
state->minimized_valid = state->minimized != data->minimized;
state->maximized = (style & WS_MAXIMIZE) != 0;
}
@ -2054,6 +2055,17 @@ void macdrv_app_deactivated(void)
}
/***********************************************************************
* macdrv_window_maximize_requested
*
* Handler for WINDOW_MAXIMIZE_REQUESTED events.
*/
void macdrv_window_maximize_requested(HWND hwnd)
{
perform_window_command(hwnd, WS_MAXIMIZEBOX, WS_MAXIMIZE, SC_MAXIMIZE, HTMAXBUTTON);
}
/***********************************************************************
* macdrv_window_minimize_requested
*
@ -2122,6 +2134,18 @@ void macdrv_window_resize_ended(HWND hwnd)
}
/***********************************************************************
* macdrv_window_restore_requested
*
* Handler for WINDOW_RESTORE_REQUESTED events. This is specifically
* for restoring from maximized, not from minimized.
*/
void macdrv_window_restore_requested(HWND hwnd)
{
perform_window_command(hwnd, WS_MAXIMIZE, 0, SC_RESTORE, HTMAXBUTTON);
}
/***********************************************************************
* macdrv_window_drag_begin
*