Commit 6cde62ac authored by Ken Thomases's avatar Ken Thomases Committed by Alexandre Julliard

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

parent bd269786
...@@ -45,6 +45,8 @@ ...@@ -45,6 +45,8 @@
CGFloat colorKeyRed, colorKeyGreen, colorKeyBlue; CGFloat colorKeyRed, colorKeyGreen, colorKeyBlue;
BOOL usePerPixelAlpha; BOOL usePerPixelAlpha;
BOOL causing_becomeKeyWindow;
} }
@end @end
...@@ -440,14 +440,52 @@ static BOOL frame_intersects_screens(NSRect frame, NSArray* screens) ...@@ -440,14 +440,52 @@ static BOOL frame_intersects_screens(NSRect frame, NSArray* screens)
[queue postEvent:&event]; [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 ---------- * ---------- NSWindow method overrides ----------
*/ */
- (BOOL) canBecomeKeyWindow - (BOOL) canBecomeKeyWindow
{ {
if (causing_becomeKeyWindow) return YES;
if (self.disabled || self.noActivate) return NO; if (self.disabled || self.noActivate) return NO;
return YES; return [self isKeyWindow];
} }
- (BOOL) canBecomeMainWindow - (BOOL) canBecomeMainWindow
...@@ -841,3 +879,19 @@ void macdrv_window_use_per_pixel_alpha(macdrv_window w, int use_per_pixel_alpha) ...@@ -841,3 +879,19 @@ void macdrv_window_use_per_pixel_alpha(macdrv_window w, int use_per_pixel_alpha)
[pool release]; [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 ...@@ -205,5 +205,6 @@ extern void macdrv_set_window_color_key(macdrv_window w, CGFloat keyRed, CGFloat
CGFloat keyBlue) DECLSPEC_HIDDEN; CGFloat keyBlue) DECLSPEC_HIDDEN;
extern void macdrv_clear_window_color_key(macdrv_window w) 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_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 */ #endif /* __WINE_MACDRV_COCOA_H */
...@@ -43,6 +43,9 @@ static CRITICAL_SECTION win_data_section = { &critsect_debug, -1, 0, 0, 0, 0 }; ...@@ -43,6 +43,9 @@ static CRITICAL_SECTION win_data_section = { &critsect_debug, -1, 0, 0, 0, 0 };
static CFMutableDictionaryRef win_datas; static CFMutableDictionaryRef win_datas;
void CDECL macdrv_SetFocus(HWND hwnd);
/*********************************************************************** /***********************************************************************
* get_cocoa_window_features * get_cocoa_window_features
*/ */
...@@ -154,6 +157,12 @@ static void show_window(struct macdrv_win_data *data) ...@@ -154,6 +157,12 @@ static void show_window(struct macdrv_win_data *data)
TRACE("win %p/%p\n", data->hwnd, data->cocoa_window); TRACE("win %p/%p\n", data->hwnd, data->cocoa_window);
data->on_screen = macdrv_order_cocoa_window(data->cocoa_window, NULL, NULL); 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) ...@@ -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.@) * SetLayeredWindowAttributes (MACDRV.@)
* *
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
@ cdecl EnumDisplayMonitors(long ptr ptr long) macdrv_EnumDisplayMonitors @ cdecl EnumDisplayMonitors(long ptr ptr long) macdrv_EnumDisplayMonitors
@ cdecl GetMonitorInfo(long ptr) macdrv_GetMonitorInfo @ cdecl GetMonitorInfo(long ptr) macdrv_GetMonitorInfo
@ cdecl MsgWaitForMultipleObjectsEx(long ptr long long long) macdrv_MsgWaitForMultipleObjectsEx @ cdecl MsgWaitForMultipleObjectsEx(long ptr long long long) macdrv_MsgWaitForMultipleObjectsEx
@ cdecl SetFocus(long) macdrv_SetFocus
@ cdecl SetLayeredWindowAttributes(long long long long) macdrv_SetLayeredWindowAttributes @ cdecl SetLayeredWindowAttributes(long long long long) macdrv_SetLayeredWindowAttributes
@ cdecl SetParent(long long long) macdrv_SetParent @ cdecl SetParent(long long long) macdrv_SetParent
@ cdecl SetWindowRgn(long long long) macdrv_SetWindowRgn @ cdecl SetWindowRgn(long long long) macdrv_SetWindowRgn
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment