-
-
Notifications
You must be signed in to change notification settings - Fork 104
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feature Request] Detect the focused window to show/hide the overlay and swap settings #127
Comments
I really like this idea, however as of this writing I don't believe there's a good way to get the currently focused application from within Electron. There is only a method to detect if CrossOver is focused, not other application windows. I'll leave this open, hopefully an API will be added in the future for it. This ticket mentions using a native extension but I'm not interested in maintaining one: https://stackoverflow.com/a/39930556/939330 Thanks for bringing this up! |
Yes, there's no way (that I know) to effectively do this in pure electron. You need to interop with a C/C++ library. Basically, the C library let you attach the overlay (crossover electron window) to the target window (e.g. a game) as a child, so you can "talk" with the target window with the OS window events, such as WM_SETFOCUS to focus the target window, know if the target is focused, etc. Works on Windows and Linux. Don't think it works for macOS, cause window management is horrible on that OS unfortunately... One good thing tho, is that it handles everything, and it's simple to setup, since it uses the electron window to do it's stuff. And you can easily fork the GitHub project (like I did) and expose more Win32 API functions if you want, like find the current focused window, without firstly knowing what it is (e.g. a game, a Word document, a browser, etc.) Of course, it's possible to go custom and create a package yourself to expose Win32 API functions so you can interact with windows and the OS, but that needs to be done for each OS and might take some more work. Edit: I might take a look, just to see if it would works for CrossOver |
I haven't heard of that project, at first glance it seems like it could accomplish what you want (and potentially fix the issue of fullscreen support #62), however it will require a significant lift to even vet if it will work. Since the overlay (CrossOver) becomes a child of the game window, it may make this feature request redundant since the overlay would be hidden along with the game. I'll eventually have time to work on this, but if you want this feature badly enough to help we may be able to get it done sooner 😄 |
This may require the settings window to be rethought, since it is a child of the main CrossOver window. |
For #62 , it won't work. You can't put in any way a window on top of a true fullscreen window (at least on Windows). Users have to run the game in borderless fullscreen, but never true fullscreen. The reason why some overlays / tools works on a true fullscreen game, is because they inject themselve in the game process using DX11 (or any other renderer used by the game). The best example of that is RivaTuner that comes with MSI Afterburner for CPU/GPU monitoring. But, it is usually very simple overlays (e.g. colored characters only), so not suitable for a detailed overlay like CrossOver. Edit : and it's not just about Electron, but any framework will have the same result. It's not a bug or a problem, it's the expected behavior of the WM of the OS : One fullscreen window at any time, otherwise, it doesn't make sense. If there are many, it's simply borderless windows that are fighting each other for the "#1 AlwaysOnTop token" and those can be lowered with e.g. the Windows taskbar (The Windows key) |
Here's a demo of something simpler then electron-overlay-window that can be added without rewriting/re-thinking the app workflow. It is more suited for the problem we have (detect window and change settings, overlay depending on what is focused). And here's the code : const { U } = require('win32-api');
const user32 = U.load();
function getForegroundWindow() {
const hwnd = user32.GetForegroundWindow();
const hwndType = typeof (hwnd);
return ~['bigint', 'number'].indexOf(hwndType) ? hwnd : null;
}
function getWindowText(hwnd, maxLength = 100) {
if (!hwnd) return null;
let text = Buffer.alloc(maxLength, null, 'ucs2');
user32.GetWindowTextW(hwnd, text, maxLength);
return text.toString();
}
function runDummyWindowDetector() {
let currentForegroundWindowHwnd = null;
setInterval(() => {
const hwnd = getForegroundWindow();
if (!hwnd || hwnd === currentForegroundWindowHwnd) return;
currentForegroundWindowHwnd = hwnd;
const windowText = getWindowText(currentForegroundWindowHwnd);
if (!windowText) return;
console.log('Window changed:', windowText);
}, 500);
}
runDummyWindowDetector(); It basically just check periodically what window is on top/focused, and reads it's label. Since, we don't target specific windows, it needs to check periodically. Note that this is the code specific for Windows. It's possible to do similar things on Linux with X11. I don't know for macOS. Also note, that you'll need Windows Build Tools or an installation of Visual Studio 2015+ to be able to install the package required. |
I did some testing and here is a even simpler and better version giving more informations about the focused window (could have more, but I think that's enough) : It's not using FFI, neither win32-api, but instead uses edge-js to interop with a .NET library that then handle everything related to WinAPI and output simple data for JS. The data is {
"title": "The current focused window title", // e.g. Google Chrome - A tab name here
"processPath": "The path to the file executing that window" // e.g. C:\Games\Google\chrome.exe
} The The requirements are
Here's a fork with the basic stuff : https://github.com/nomis51/crossover/tree/feature/issue-127-detect-win Basically what's remaining is to do something with the informations coming from the
|
Basically ask the user to tell the app : Hey this program here e.g. CS GO, i want to register it and apply custom settings to it, instead of using the global / default settings of the overlay. When I say ask, I mean, the user hit a shortcut to auto create a profile, or go in the app settings to manually create a profile or something like that. A bit like the LG Hub app you can create (manually here) a mouse profile for each game/app you want (it then change automatically the profile when the targeted app is focused or you can do it manually with the dropdown) And by default it uses the global / default "Desktop" profile. So as the user, i need to tell it what app i want to have a custom profile on. |
Got it. This is kind of a heavy feature so I'll do my best to get working on it soon. |
Would be nice if the overlay could show/hide itself based on the focused window. So, when you're in the game, it shows up. And when you Alt + Tab to another window (discord, browser, etc.) it hides, instead of just staying under the mouse, and having us manually closing it and restarting it when going back to the game. Not a big deal, just a nice-to-have feature.
Also, that could be used to apply a different set of settings based on the focused window. Let's say you have CS GO and Valorant opened, when you focus CS GO, then the overlay settings of that game applies. If you then focused Valorant, the settings of that game applies, etc. (Similar to the LG Hub software that change your LG mouse settings (macros, sensitivity, colors, etc.) based on the game (or software) focused.
I suppose the easy way to implement this, is to ask the user to manually tell the overlay what game/software it needs to show up on (like those CPU/GPU monitoring OSD), so you don't have to maintain a list of games and window class names to detect them all. Also, the user could simply just allow the overlay to be always visible, if needed.
The text was updated successfully, but these errors were encountered: