Skip to content

Commit

Permalink
Attempt to force window topmost when necessary; close #96
Browse files Browse the repository at this point in the history
  • Loading branch information
vanjac committed Jun 28, 2022
1 parent 2f45b75 commit 16adce2
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 5 deletions.
25 changes: 21 additions & 4 deletions src/ItemWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -407,10 +407,8 @@ LRESULT ItemWindow::handleMessage(UINT message, WPARAM wParam, LPARAM lParam) {
if (wParam == TIMER_MAKE_TOPMOST && !fullScreen) {
GUITHREADINFO guiThread = {sizeof(guiThread)};
// don't cover up eg. menus or drag overlays
if (!(GetGUIThreadInfo(0, &guiThread) && guiThread.hwndCapture)) {
SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0,
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
}
if (!(GetGUIThreadInfo(0, &guiThread) && guiThread.hwndCapture))
forceTopmost();
return 0;
}
break;
Expand Down Expand Up @@ -593,6 +591,25 @@ void ItemWindow::windowRectChanged() {
}
}

void ItemWindow::forceTopmost() {
RECT windowRect;
GetWindowRect(hwnd, &windowRect);
POINT testPoint {(windowRect.left + windowRect.right) / 2,
(windowRect.top + windowRect.bottom) / 2};
if (GetAncestor(WindowFromPoint(testPoint), GA_ROOT) == hwnd)
return; // already on top
SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
if (GetAncestor(WindowFromPoint(testPoint), GA_ROOT) == hwnd)
return; // success!
debugPrintf(L"Forcing topmost\n");
// ugly hack https://shlomio.wordpress.com/2012/09/04/solved-setforegroundwindow-win32-api-not-always-works/
DWORD fgThread = GetWindowThreadProcessId(GetForegroundWindow(), nullptr);
AttachThreadInput(fgThread, GetCurrentThreadId(), true);
SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
AttachThreadInput(fgThread, GetCurrentThreadId(), false);
return;
}

LRESULT ItemWindow::hitTestNCA(POINT cursor) {
// from https://docs.microsoft.com/en-us/windows/win32/dwm/customframe?redirectedfrom=MSDN#appendix-c-hittestnca-function
// the default window proc handles the left, right, and bottom edges
Expand Down
2 changes: 1 addition & 1 deletion src/ItemWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ class ItemWindow : public IUnknownImpl, public IDropSource, public IDropTarget {
HWND createChainOwner(int showCommand);

void windowRectChanged();
void bringGroupToFront();
void forceTopmost();
LRESULT hitTestNCA(POINT cursor);

void openParent();
Expand Down

0 comments on commit 16adce2

Please sign in to comment.