mirror of
https://github.com/microsoft/PowerToys
synced 2025-08-30 05:57:42 +00:00
[MouseHighlighter]Bringing to front to be on top of other topmost windows (#27062)
* [MouseHighlighter] modifying window to be 'topmost' to be visible when clicking on 'pinned to top' windows. * Fixing window hidden when clicking on a pinned to top window. * Moving the code which starts the bring-to-front-timer to the mouse click events. Also adding modifications to await 5 times 10 ms after the event to have surely the desired effect as in some cases the window repositioning takes longer than 10 ms. * Minor changes * Add safety code to ensure timer is never started paralely. Also minor format changes. * Add comments * spell checker corrections
This commit is contained in:
parent
c95508c8a5
commit
6948ffca53
@ -45,6 +45,7 @@ private:
|
||||
void StartDrawingPointFading(MouseButton button);
|
||||
void ClearDrawingPoint(MouseButton button);
|
||||
void ClearDrawing();
|
||||
void BringToFront();
|
||||
HHOOK m_mouseHook = NULL;
|
||||
static LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam) noexcept;
|
||||
|
||||
@ -72,6 +73,7 @@ private:
|
||||
|
||||
bool m_leftButtonPressed = false;
|
||||
bool m_rightButtonPressed = false;
|
||||
UINT_PTR m_timer_id = 0;
|
||||
|
||||
bool m_visible = false;
|
||||
|
||||
@ -85,7 +87,7 @@ private:
|
||||
winrt::Windows::UI::Color m_rightClickColor = MOUSE_HIGHLIGHTER_DEFAULT_RIGHT_BUTTON_COLOR;
|
||||
winrt::Windows::UI::Color m_alwaysColor = MOUSE_HIGHLIGHTER_DEFAULT_ALWAYS_COLOR;
|
||||
};
|
||||
|
||||
static const uint32_t BRING_TO_FRONT_TIMER_ID = 123;
|
||||
Highlighter* Highlighter::instance = nullptr;
|
||||
|
||||
bool Highlighter::CreateHighlighter()
|
||||
@ -126,11 +128,10 @@ bool Highlighter::CreateHighlighter()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Highlighter::AddDrawingPoint(MouseButton button)
|
||||
{
|
||||
POINT pt;
|
||||
|
||||
|
||||
// Applies DPIs.
|
||||
GetCursorPos(&pt);
|
||||
|
||||
@ -257,6 +258,13 @@ LRESULT CALLBACK Highlighter::MouseHookProc(int nCode, WPARAM wParam, LPARAM lPa
|
||||
}
|
||||
instance->AddDrawingPoint(MouseButton::Left);
|
||||
instance->m_leftButtonPressed = true;
|
||||
// start a timer for the scenario, when the user clicks a pinned window which has no focus.
|
||||
// after we drow the highlighting circle the pinned window will jump in front of us,
|
||||
// we have to bring our window back to topmost position
|
||||
if (instance->m_timer_id == 0)
|
||||
{
|
||||
instance->m_timer_id = SetTimer(instance->m_hwnd, BRING_TO_FRONT_TIMER_ID, 10, nullptr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WM_RBUTTONDOWN:
|
||||
@ -269,6 +277,11 @@ LRESULT CALLBACK Highlighter::MouseHookProc(int nCode, WPARAM wParam, LPARAM lPa
|
||||
}
|
||||
instance->AddDrawingPoint(MouseButton::Right);
|
||||
instance->m_rightButtonPressed = true;
|
||||
// same as for the left button, start a timer for reposition ourselves to topmost position
|
||||
if (instance->m_timer_id == 0)
|
||||
{
|
||||
instance->m_timer_id = SetTimer(instance->m_hwnd, BRING_TO_FRONT_TIMER_ID, 10, nullptr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WM_MOUSEMOVE:
|
||||
@ -316,7 +329,6 @@ LRESULT CALLBACK Highlighter::MouseHookProc(int nCode, WPARAM wParam, LPARAM lPa
|
||||
return CallNextHookEx(0, nCode, wParam, lParam);
|
||||
}
|
||||
|
||||
|
||||
void Highlighter::StartDrawing()
|
||||
{
|
||||
Logger::info("Starting draw mode.");
|
||||
@ -363,6 +375,11 @@ void Highlighter::ApplySettings(MouseHighlighterSettings settings) {
|
||||
m_alwaysPointerEnabled = settings.alwaysColor.A != 0;
|
||||
}
|
||||
|
||||
void Highlighter::BringToFront() {
|
||||
// HACK: Draw with 1 pixel off. Otherwise Windows glitches the task bar transparency when a transparent window fill the whole screen.
|
||||
SetWindowPos(m_hwnd, HWND_TOPMOST, GetSystemMetrics(SM_XVIRTUALSCREEN) + 1, GetSystemMetrics(SM_YVIRTUALSCREEN) + 1, GetSystemMetrics(SM_CXVIRTUALSCREEN) - 2, GetSystemMetrics(SM_CYVIRTUALSCREEN) - 2, 0);
|
||||
}
|
||||
|
||||
void Highlighter::DestroyHighlighter()
|
||||
{
|
||||
StopDrawing();
|
||||
@ -393,6 +410,28 @@ LRESULT CALLBACK Highlighter::WndProc(HWND hWnd, UINT message, WPARAM wParam, LP
|
||||
case WM_DESTROY:
|
||||
instance->DestroyHighlighter();
|
||||
break;
|
||||
case WM_TIMER:
|
||||
{
|
||||
switch (wParam)
|
||||
{
|
||||
// when the bring-to-front-timer expires (every 10 ms), we are repositioning our window to topmost Z order position
|
||||
// As we experience that it takes 0-30 ms that the pinned window hides our window,
|
||||
// we await 5 timer ticks (50 ms together) and then we stop the timer.
|
||||
// If we would use a timer with a 50 ms period, there would be a flickering on the UI, as in most of the cases
|
||||
// the pinned window hides our window in a few milliseconds.
|
||||
case BRING_TO_FRONT_TIMER_ID:
|
||||
static int fireCount = 0;
|
||||
if (fireCount++ >= 4)
|
||||
{
|
||||
KillTimer(instance->m_hwnd, instance->m_timer_id);
|
||||
instance->m_timer_id = 0;
|
||||
fireCount = 0;
|
||||
}
|
||||
instance->BringToFront();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user