Skip to content

Commit 19b4665

Browse files
authored
(NT-77) Improve focus window implementation on Windows to deal with f… (#178)
* (NT-77) Improve focus window implementation on Windows to deal with focus stealing countermeasures on Windows * (NT-77) Adjust focus test
1 parent d376d4f commit 19b4665

File tree

2 files changed

+32
-18
lines changed

2 files changed

+32
-18
lines changed

src/win32/window_manager.cc

+24-18
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,15 @@ std::vector<WindowHandle> getWindows() {
2222
}
2323

2424
WindowHandle getActiveWindow() {
25-
HWND foregroundWindow = GetForegroundWindow();
25+
auto foregroundWindow = GetForegroundWindow();
2626
if (IsWindow(foregroundWindow)) {
2727
return reinterpret_cast<WindowHandle>(foregroundWindow);
2828
}
2929
return -1;
3030
}
3131

3232
MMRect getWindowRect(const WindowHandle windowHandle) {
33-
HWND hWnd = reinterpret_cast<HWND>(windowHandle);
33+
auto hWnd = reinterpret_cast<HWND>(windowHandle);
3434
RECT windowRect;
3535
if (IsWindow(hWnd) && GetWindowRect(hWnd, &windowRect)) {
3636
return MMRectMake(windowRect.left, windowRect.top, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top);
@@ -39,65 +39,71 @@ MMRect getWindowRect(const WindowHandle windowHandle) {
3939
}
4040

4141
std::string getWindowTitle(const WindowHandle windowHandle) {
42-
HWND hWnd = reinterpret_cast<HWND>(windowHandle);
42+
auto hWnd = reinterpret_cast<HWND>(windowHandle);
4343
if (IsWindow(hWnd)) {
4444
auto BUFFER_SIZE = GetWindowTextLength(hWnd) + 1;
4545
if (BUFFER_SIZE) {
46-
LPSTR windowTitle = new CHAR[BUFFER_SIZE];
46+
auto windowTitle = new CHAR[BUFFER_SIZE];
4747
if (GetWindowText(hWnd, windowTitle, BUFFER_SIZE)) {
48-
return std::string(windowTitle);
48+
return {windowTitle};
4949
}
5050
}
5151
}
5252
return "";
5353
}
5454

5555
bool focusWindow(const WindowHandle windowHandle) {
56-
HWND hWnd = reinterpret_cast<HWND>(windowHandle);
56+
auto hWnd = reinterpret_cast<HWND>(windowHandle);
5757
if (IsWindow(hWnd)) {
5858
// Restore the window if it's minimized
5959
if (IsIconic(hWnd)) {
6060
ShowWindow(hWnd, SW_RESTORE);
6161
}
62-
62+
63+
auto processId = GetCurrentProcessId();
64+
// const auto allowSetForeground = AllowSetForegroundWindow(ASFW_ANY);
65+
const auto allowSetForeground = AllowSetForegroundWindow(processId);
66+
const auto setTopLevel = BringWindowToTop(hWnd);
67+
const auto setForeground = SetForegroundWindow(hWnd);
68+
6369
// Try to set the window to the foreground
64-
return SetForegroundWindow(hWnd);
70+
return allowSetForeground && setTopLevel && setForeground;
6571
}
6672
return false;
6773
}
6874

6975
bool resizeWindow(const WindowHandle windowHandle, const MMSize newSize) {
70-
HWND hWnd = reinterpret_cast<HWND>(windowHandle);
76+
auto hWnd = reinterpret_cast<HWND>(windowHandle);
7177
if (IsWindow(hWnd)) {
7278
//size
73-
auto width = newSize.width;
74-
auto height = newSize.height;
79+
const auto width = newSize.width;
80+
const auto height = newSize.height;
7581

7682
RECT currentPosition;
7783
GetWindowRect(reinterpret_cast<HWND>(windowHandle), &currentPosition);
7884

7985
//origin
80-
auto x = currentPosition.left;
81-
auto y = currentPosition.top;
86+
const auto x = currentPosition.left;
87+
const auto y = currentPosition.top;
8288

8389
return MoveWindow(hWnd, x, y, width, height, TRUE);
8490
}
8591
return false;
8692
}
8793

8894
bool moveWindow(const WindowHandle windowHandle, const MMPoint newOrigin) {
89-
HWND hWnd = reinterpret_cast<HWND>(windowHandle);
95+
auto hWnd = reinterpret_cast<HWND>(windowHandle);
9096
if (IsWindow(hWnd)) {
9197
// origin
92-
auto x = newOrigin.x;
93-
auto y = newOrigin.y;
98+
const auto x = newOrigin.x;
99+
const auto y = newOrigin.y;
94100

95101
RECT currentPosition;
96102
GetWindowRect(reinterpret_cast<HWND>(windowHandle), &currentPosition);
97103

98104
// size
99-
auto width = currentPosition.right - currentPosition.left;
100-
auto height = currentPosition.bottom - currentPosition.top;
105+
const auto width = currentPosition.right - currentPosition.left;
106+
const auto height = currentPosition.bottom - currentPosition.top;
101107

102108
return MoveWindow(hWnd, x, y, width, height, TRUE);
103109
}

test/window-integration-tests/test.js

+8
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,18 @@ describe("focusWindow", () => {
103103
// WHEN
104104
const secondApp = await electron.launch({args: ['second.js']});
105105
const secondPage = await secondApp.firstWindow({timeout: APP_TIMEOUT});
106+
const handle = await secondApp.browserWindow(secondPage);
107+
await secondPage.waitForLoadState("domcontentloaded");
108+
await handle.evaluate((win) => {
109+
win.minimize();
110+
win.restore();
111+
win.focus();
112+
});
106113

107114
const result = libnut.focusWindow(openWindowHandle);
108115

109116
// THEN
117+
await sleep(1500);
110118
const activeWindowHandle = libnut.getActiveWindow();
111119
const activeWindowName = libnut.getWindowTitle(activeWindowHandle);
112120
expect(activeWindowName).toBe(TITLE);

0 commit comments

Comments
 (0)