winemac: Take control over when a window can become focused away from Cocoa.
This commit is contained in:
parent
bd269786a5
commit
6cde62ac18
|
@ -45,6 +45,8 @@ @interface WineWindow : NSPanel <NSWindowDelegate>
|
|||
CGFloat colorKeyRed, colorKeyGreen, colorKeyBlue;
|
||||
|
||||
BOOL usePerPixelAlpha;
|
||||
|
||||
BOOL causing_becomeKeyWindow;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -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];
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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.@)
|
||||
*
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue