From: Ken Thomases Subject: winemac: By default, make full-screen windows not float when not the active app. Message-Id: <68DB2903-1402-4D84-A8DA-51F37D4D088D@codeweavers.com> Date: Wed, 29 May 2013 09:21:25 -0500 Added a registry setting to control the behavior: WindowsFloatWhenInactive with possible values "none", "all, and "nonfullscreen" which is the default. Fixes . --- dlls/winemac.drv/cocoa_window.m | 13 +++++--- dlls/winemac.drv/macdrv_cocoa.h | 7 ++++ dlls/winemac.drv/macdrv_main.c | 66 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 5 deletions(-) diff --git a/dlls/winemac.drv/cocoa_window.m b/dlls/winemac.drv/cocoa_window.m index d2b2547..a47715a 100644 --- a/dlls/winemac.drv/cocoa_window.m +++ b/dlls/winemac.drv/cocoa_window.m @@ -577,20 +577,23 @@ - (BOOL) isOrderedIn - (NSInteger) minimumLevelForActive:(BOOL)active { + NSScreen* screen; + BOOL fullscreen; NSInteger level; - if (self.floating) + screen = screen_covered_by_rect([self frame], [NSScreen screens]); + fullscreen = (screen != nil); + + if (self.floating && (active || topmost_float_inactive == TOPMOST_FLOAT_INACTIVE_ALL || + (topmost_float_inactive == TOPMOST_FLOAT_INACTIVE_NONFULLSCREEN && !fullscreen))) level = NSFloatingWindowLevel; else level = NSNormalWindowLevel; if (active) { - BOOL fullscreen, captured; - NSScreen* screen; + BOOL captured; - screen = screen_covered_by_rect([self frame], [NSScreen screens]); - fullscreen = (screen != nil); captured = (screen || [self screen]) && [[WineApplicationController sharedController] areDisplaysCaptured]; if (captured || fullscreen) diff --git a/dlls/winemac.drv/macdrv_cocoa.h b/dlls/winemac.drv/macdrv_cocoa.h index 905738f..e7e2c4c 100644 --- a/dlls/winemac.drv/macdrv_cocoa.h +++ b/dlls/winemac.drv/macdrv_cocoa.h @@ -111,6 +111,12 @@ DRAG_OP_EVERY = UINT32_MAX }; +enum { + TOPMOST_FLOAT_INACTIVE_NONE, + TOPMOST_FLOAT_INACTIVE_NONFULLSCREEN, + TOPMOST_FLOAT_INACTIVE_ALL, +}; + typedef struct macdrv_opaque_window* macdrv_window; typedef struct macdrv_opaque_event_queue* macdrv_event_queue; @@ -129,6 +135,7 @@ /* main */ extern int macdrv_err_on; +extern int topmost_float_inactive DECLSPEC_HIDDEN; extern int macdrv_start_cocoa_app(unsigned long long tickcount) DECLSPEC_HIDDEN; extern void macdrv_window_rejected_focus(const struct macdrv_event *event) DECLSPEC_HIDDEN; diff --git a/dlls/winemac.drv/macdrv_main.c b/dlls/winemac.drv/macdrv_main.c index 501b7d5..cf036c4 100644 --- a/dlls/winemac.drv/macdrv_main.c +++ b/dlls/winemac.drv/macdrv_main.c @@ -26,6 +26,7 @@ #include "macdrv.h" #include "winuser.h" +#include "winreg.h" #include "wine/server.h" WINE_DEFAULT_DEBUG_CHANNEL(macdrv); @@ -41,6 +42,8 @@ C_ASSERT(NUM_EVENT_TYPES <= sizeof(macdrv_event_mask) * 8); DWORD thread_data_tls_index = TLS_OUT_OF_INDEXES; +int topmost_float_inactive = TOPMOST_FLOAT_INACTIVE_NONFULLSCREEN; + /************************************************************************** * debugstr_cf @@ -91,6 +94,67 @@ static void set_app_icon(void) /*********************************************************************** + * get_config_key + * + * Get a config key from either the app-specific or the default config + */ +static inline DWORD get_config_key(HKEY defkey, HKEY appkey, const char *name, + char *buffer, DWORD size) +{ + if (appkey && !RegQueryValueExA(appkey, name, 0, NULL, (LPBYTE)buffer, &size)) return 0; + if (defkey && !RegQueryValueExA(defkey, name, 0, NULL, (LPBYTE)buffer, &size)) return 0; + return ERROR_FILE_NOT_FOUND; +} + + +/*********************************************************************** + * setup_options + * + * Set up the Mac driver options. + */ +static void setup_options(void) +{ + char buffer[MAX_PATH + 16]; + HKEY hkey, appkey = 0; + DWORD len; + + /* @@ Wine registry key: HKCU\Software\Wine\Mac Driver */ + if (RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Mac Driver", &hkey)) hkey = 0; + + /* open the app-specific key */ + + len = GetModuleFileNameA(0, buffer, MAX_PATH); + if (len && len < MAX_PATH) + { + HKEY tmpkey; + char *p, *appname = buffer; + if ((p = strrchr(appname, '/'))) appname = p + 1; + if ((p = strrchr(appname, '\\'))) appname = p + 1; + strcat(appname, "\\Mac Driver"); + /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\Mac Driver */ + if (!RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\AppDefaults", &tmpkey)) + { + if (RegOpenKeyA(tmpkey, appname, &appkey)) appkey = 0; + RegCloseKey(tmpkey); + } + } + + if (!get_config_key(hkey, appkey, "WindowsFloatWhenInactive", buffer, sizeof(buffer))) + { + if (!strcmp(buffer, "none")) + topmost_float_inactive = TOPMOST_FLOAT_INACTIVE_NONE; + else if (!strcmp(buffer, "all")) + topmost_float_inactive = TOPMOST_FLOAT_INACTIVE_ALL; + else + topmost_float_inactive = TOPMOST_FLOAT_INACTIVE_NONFULLSCREEN; + } + + if (appkey) RegCloseKey(appkey); + if (hkey) RegCloseKey(hkey); +} + + +/*********************************************************************** * process_attach */ static BOOL process_attach(void) @@ -102,6 +166,8 @@ static BOOL process_attach(void) if (status != noErr || !(attributes & sessionHasGraphicAccess)) return FALSE; + setup_options(); + if ((thread_data_tls_index = TlsAlloc()) == TLS_OUT_OF_INDEXES) return FALSE; macdrv_err_on = ERR_ON(macdrv);