winemac: Take control over when a window can become focused away from Cocoa.

This commit is contained in:
Ken Thomases 2013-01-27 16:19:41 -06:00 committed by Alexandre Julliard
parent bd269786a5
commit 6cde62ac18
5 changed files with 93 additions and 1 deletions

View File

@ -45,6 +45,8 @@ @interface WineWindow : NSPanel <NSWindowDelegate>
CGFloat colorKeyRed, colorKeyGreen, colorKeyBlue;
BOOL usePerPixelAlpha;
BOOL causing_becomeKeyWindow;
}
@end

View File

@ -440,14 +440,52 @@ - (void) postMouseButtonEvent:(NSEvent *)theEvent pressed:(int)pressed
[queue postEvent:&event];
}
- (void) makeFocused
{
NSArray* screens;
[NSApp transformProcessToForeground];
/* If a borderless window is offscreen, orderFront: won't move
it onscreen like it would for a titled window. Do that ourselves. */
screens = [NSScreen screens];
if (!([self styleMask] & NSTitledWindowMask) && ![self isVisible] &&
!frame_intersects_screens([self frame], screens))
{
NSScreen* primaryScreen = [screens objectAtIndex:0];
NSRect frame = [primaryScreen frame];
[self setFrameTopLeftPoint:NSMakePoint(NSMinX(frame), NSMaxY(frame))];
frame = [self constrainFrameRect:[self frame] toScreen:primaryScreen];
[self setFrame:frame display:YES];
}
[self orderFront:nil];
causing_becomeKeyWindow = TRUE;
[self makeKeyWindow];
causing_becomeKeyWindow = FALSE;
if (latentParentWindow)
{
[latentParentWindow addChildWindow:self ordered:NSWindowAbove];
self.latentParentWindow = nil;
}
if (![self isExcludedFromWindowsMenu])
[NSApp addWindowsItem:self title:[self title] filename:NO];
/* 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];
}
/*
* ---------- NSWindow method overrides ----------
*/
- (BOOL) canBecomeKeyWindow
{
if (causing_becomeKeyWindow) return YES;
if (self.disabled || self.noActivate) return NO;
return YES;
return [self isKeyWindow];
}
- (BOOL) canBecomeMainWindow
@ -841,3 +879,19 @@ void macdrv_window_use_per_pixel_alpha(macdrv_window w, int use_per_pixel_alpha)
[pool release];
}
/***********************************************************************
* macdrv_give_cocoa_window_focus
*
* Makes the Cocoa window "key" (gives it keyboard focus). This also
* orders it front and, if its frame was not within the desktop bounds,
* Cocoa will typically move it on-screen.
*/
void macdrv_give_cocoa_window_focus(macdrv_window w)
{
WineWindow* window = (WineWindow*)w;
OnMainThread(^{
[window makeFocused];
});
}

View File

@ -205,5 +205,6 @@ extern void macdrv_set_window_color_key(macdrv_window w, CGFloat keyRed, CGFloat
CGFloat keyBlue) DECLSPEC_HIDDEN;
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) DECLSPEC_HIDDEN;
#endif /* __WINE_MACDRV_COCOA_H */

View File

@ -43,6 +43,9 @@ static CRITICAL_SECTION win_data_section = { &critsect_debug, -1, 0, 0, 0, 0 };
static CFMutableDictionaryRef win_datas;
void CDECL macdrv_SetFocus(HWND hwnd);
/***********************************************************************
* get_cocoa_window_features
*/
@ -154,6 +157,12 @@ static void show_window(struct macdrv_win_data *data)
TRACE("win %p/%p\n", data->hwnd, data->cocoa_window);
data->on_screen = macdrv_order_cocoa_window(data->cocoa_window, NULL, NULL);
if (data->on_screen)
{
HWND hwndFocus = GetFocus();
if (hwndFocus && (data->hwnd == hwndFocus || IsChild(data->hwnd, hwndFocus)))
macdrv_SetFocus(hwndFocus);
}
}
@ -820,6 +829,31 @@ void CDECL macdrv_DestroyWindow(HWND hwnd)
}
/*****************************************************************
* SetFocus (MACDRV.@)
*
* Set the Mac focus.
*/
void CDECL macdrv_SetFocus(HWND hwnd)
{
struct macdrv_win_data *data;
TRACE("%p\n", hwnd);
if (!(hwnd = GetAncestor(hwnd, GA_ROOT))) return;
if (!(data = get_win_data(hwnd))) return;
if (data->cocoa_window)
{
/* Set Mac focus */
macdrv_give_cocoa_window_focus(data->cocoa_window);
data->on_screen = TRUE;
}
release_win_data(data);
}
/***********************************************************************
* SetLayeredWindowAttributes (MACDRV.@)
*

View File

@ -10,6 +10,7 @@
@ cdecl EnumDisplayMonitors(long ptr ptr long) macdrv_EnumDisplayMonitors
@ cdecl GetMonitorInfo(long ptr) macdrv_GetMonitorInfo
@ cdecl MsgWaitForMultipleObjectsEx(long ptr long long long) macdrv_MsgWaitForMultipleObjectsEx
@ cdecl SetFocus(long) macdrv_SetFocus
@ cdecl SetLayeredWindowAttributes(long long long long) macdrv_SetLayeredWindowAttributes
@ cdecl SetParent(long long long) macdrv_SetParent
@ cdecl SetWindowRgn(long long long) macdrv_SetWindowRgn