mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-08 20:27:36 +02:00
[AlwaysOnTop] Release/recreate borders instead of hiding/showing (#15733)
This commit is contained in:
2
.github/actions/spell-check/expect.txt
vendored
2
.github/actions/spell-check/expect.txt
vendored
@@ -1220,6 +1220,8 @@ mindaro
|
|||||||
Minimatch
|
Minimatch
|
||||||
Minimizeallwindows
|
Minimizeallwindows
|
||||||
MINIMIZEBOX
|
MINIMIZEBOX
|
||||||
|
MINIMIZEEND
|
||||||
|
MINIMIZESTART
|
||||||
miniz
|
miniz
|
||||||
minlevel
|
minlevel
|
||||||
Miracast
|
Miracast
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ void AlwaysOnTop::SettingsUpdate(SettingId id)
|
|||||||
{
|
{
|
||||||
if (!iter.second)
|
if (!iter.second)
|
||||||
{
|
{
|
||||||
AssignBorderTracker(iter.first);
|
AssignBorder(iter.first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -119,7 +119,7 @@ void AlwaysOnTop::SettingsUpdate(SettingId id)
|
|||||||
case SettingId::ExcludeApps:
|
case SettingId::ExcludeApps:
|
||||||
{
|
{
|
||||||
std::vector<HWND> toErase{};
|
std::vector<HWND> toErase{};
|
||||||
for (const auto& [window, tracker] : m_topmostWindows)
|
for (const auto& [window, border] : m_topmostWindows)
|
||||||
{
|
{
|
||||||
if (isExcluded(window))
|
if (isExcluded(window))
|
||||||
{
|
{
|
||||||
@@ -187,14 +187,7 @@ void AlwaysOnTop::ProcessCommand(HWND window)
|
|||||||
if (PinTopmostWindow(window))
|
if (PinTopmostWindow(window))
|
||||||
{
|
{
|
||||||
soundType = Sound::Type::On;
|
soundType = Sound::Type::On;
|
||||||
if (AlwaysOnTopSettings::settings().enableFrame)
|
AssignBorder(window);
|
||||||
{
|
|
||||||
AssignBorderTracker(window);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_topmostWindows[window] = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,34 +229,26 @@ void AlwaysOnTop::StartTrackingTopmostWindows()
|
|||||||
{
|
{
|
||||||
if (IsTopmost(window))
|
if (IsTopmost(window))
|
||||||
{
|
{
|
||||||
if (AlwaysOnTopSettings::settings().enableFrame)
|
AssignBorder(window);
|
||||||
{
|
|
||||||
AssignBorderTracker(window);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_topmostWindows[window] = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AlwaysOnTop::AssignBorderTracker(HWND window)
|
bool AlwaysOnTop::AssignBorder(HWND window)
|
||||||
{
|
{
|
||||||
auto tracker = std::make_unique<WindowBorder>(window);
|
if (m_virtualDesktopUtils.IsWindowOnCurrentDesktop(window) && AlwaysOnTopSettings::settings().enableFrame)
|
||||||
if (!tracker->Init(m_hinstance))
|
|
||||||
{
|
{
|
||||||
// Failed to init tracker, reset topmost
|
auto border = WindowBorder::Create(window, m_hinstance);
|
||||||
UnpinTopmostWindow(window);
|
if (border)
|
||||||
return false;
|
{
|
||||||
|
m_topmostWindows[window] = std::move(border);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (m_virtualDesktopUtils.IsWindowOnCurrentDesktop(window))
|
|
||||||
{
|
{
|
||||||
tracker->Show();
|
m_topmostWindows[window] = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_topmostWindows[window] = std::move(tracker);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,10 +261,11 @@ void AlwaysOnTop::RegisterHotkey() const
|
|||||||
void AlwaysOnTop::SubscribeToEvents()
|
void AlwaysOnTop::SubscribeToEvents()
|
||||||
{
|
{
|
||||||
// subscribe to windows events
|
// subscribe to windows events
|
||||||
std::array<DWORD, 5> events_to_subscribe = {
|
std::array<DWORD, 6> events_to_subscribe = {
|
||||||
EVENT_OBJECT_LOCATIONCHANGE,
|
EVENT_OBJECT_LOCATIONCHANGE,
|
||||||
|
EVENT_SYSTEM_MINIMIZESTART,
|
||||||
|
EVENT_SYSTEM_MINIMIZEEND,
|
||||||
EVENT_SYSTEM_MOVESIZEEND,
|
EVENT_SYSTEM_MOVESIZEEND,
|
||||||
EVENT_SYSTEM_SWITCHEND,
|
|
||||||
EVENT_OBJECT_DESTROY,
|
EVENT_OBJECT_DESTROY,
|
||||||
EVENT_OBJECT_NAMECHANGE
|
EVENT_OBJECT_NAMECHANGE
|
||||||
};
|
};
|
||||||
@@ -300,7 +286,7 @@ void AlwaysOnTop::SubscribeToEvents()
|
|||||||
|
|
||||||
void AlwaysOnTop::UnpinAll()
|
void AlwaysOnTop::UnpinAll()
|
||||||
{
|
{
|
||||||
for (const auto& [topWindow, tracker] : m_topmostWindows)
|
for (const auto& [topWindow, border] : m_topmostWindows)
|
||||||
{
|
{
|
||||||
if (!UnpinTopmostWindow(topWindow))
|
if (!UnpinTopmostWindow(topWindow))
|
||||||
{
|
{
|
||||||
@@ -355,13 +341,46 @@ void AlwaysOnTop::HandleWinHookEvent(WinHookEvent* data) noexcept
|
|||||||
switch (data->event)
|
switch (data->event)
|
||||||
{
|
{
|
||||||
case EVENT_OBJECT_LOCATIONCHANGE:
|
case EVENT_OBJECT_LOCATIONCHANGE:
|
||||||
|
{
|
||||||
|
auto iter = m_topmostWindows.find(data->hwnd);
|
||||||
|
if (iter != m_topmostWindows.end())
|
||||||
|
{
|
||||||
|
const auto& border = iter->second;
|
||||||
|
if (border)
|
||||||
|
{
|
||||||
|
border->UpdateBorderPosition();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EVENT_SYSTEM_MINIMIZESTART:
|
||||||
|
{
|
||||||
|
auto iter = m_topmostWindows.find(data->hwnd);
|
||||||
|
if (iter != m_topmostWindows.end())
|
||||||
|
{
|
||||||
|
m_topmostWindows[data->hwnd] = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EVENT_SYSTEM_MINIMIZEEND:
|
||||||
|
{
|
||||||
|
auto iter = m_topmostWindows.find(data->hwnd);
|
||||||
|
if (iter != m_topmostWindows.end())
|
||||||
|
{
|
||||||
|
AssignBorder(data->hwnd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case EVENT_SYSTEM_MOVESIZEEND:
|
case EVENT_SYSTEM_MOVESIZEEND:
|
||||||
{
|
{
|
||||||
auto iter = m_topmostWindows.find(data->hwnd);
|
auto iter = m_topmostWindows.find(data->hwnd);
|
||||||
if (iter != m_topmostWindows.end())
|
if (iter != m_topmostWindows.end())
|
||||||
{
|
{
|
||||||
const auto& tracker = iter->second;
|
const auto& border = iter->second;
|
||||||
tracker->UpdateBorderPosition();
|
if (border)
|
||||||
|
{
|
||||||
|
border->UpdateBorderPosition();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -374,16 +393,6 @@ void AlwaysOnTop::HandleWinHookEvent(WinHookEvent* data) noexcept
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EVENT_SYSTEM_SWITCHEND:
|
|
||||||
{
|
|
||||||
auto iter = m_topmostWindows.find(data->hwnd);
|
|
||||||
if (iter != m_topmostWindows.end())
|
|
||||||
{
|
|
||||||
const auto& tracker = iter->second;
|
|
||||||
tracker->Hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EVENT_OBJECT_NAMECHANGE:
|
case EVENT_OBJECT_NAMECHANGE:
|
||||||
{
|
{
|
||||||
// The accessibility name of the desktop window changes whenever the user
|
// The accessibility name of the desktop window changes whenever the user
|
||||||
@@ -401,15 +410,15 @@ void AlwaysOnTop::HandleWinHookEvent(WinHookEvent* data) noexcept
|
|||||||
|
|
||||||
void AlwaysOnTop::VirtualDesktopSwitchedHandle()
|
void AlwaysOnTop::VirtualDesktopSwitchedHandle()
|
||||||
{
|
{
|
||||||
for (const auto& [window, tracker] : m_topmostWindows)
|
for (const auto& [window, border] : m_topmostWindows)
|
||||||
{
|
{
|
||||||
if (m_virtualDesktopUtils.IsWindowOnCurrentDesktop(window))
|
if (m_virtualDesktopUtils.IsWindowOnCurrentDesktop(window))
|
||||||
{
|
{
|
||||||
tracker->Show();
|
AssignBorder(window);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tracker->Hide();
|
m_topmostWindows[window] = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,7 +67,7 @@ private:
|
|||||||
|
|
||||||
bool PinTopmostWindow(HWND window) const noexcept;
|
bool PinTopmostWindow(HWND window) const noexcept;
|
||||||
bool UnpinTopmostWindow(HWND window) const noexcept;
|
bool UnpinTopmostWindow(HWND window) const noexcept;
|
||||||
bool AssignBorderTracker(HWND window);
|
bool AssignBorder(HWND window);
|
||||||
|
|
||||||
virtual void SettingsUpdate(SettingId type) override;
|
virtual void SettingsUpdate(SettingId type) override;
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,17 @@ WindowBorder::~WindowBorder()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<WindowBorder> WindowBorder::Create(HWND window, HINSTANCE hinstance)
|
||||||
|
{
|
||||||
|
auto self = std::unique_ptr<WindowBorder>(new WindowBorder(window));
|
||||||
|
if (self->Init(hinstance))
|
||||||
|
{
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
bool WindowBorder::Init(HINSTANCE hinstance)
|
bool WindowBorder::Init(HINSTANCE hinstance)
|
||||||
{
|
{
|
||||||
if (!m_trackingWindow)
|
if (!m_trackingWindow)
|
||||||
@@ -118,7 +129,14 @@ bool WindowBorder::Init(HINSTANCE hinstance)
|
|||||||
, SWP_NOMOVE | SWP_NOSIZE);
|
, SWP_NOMOVE | SWP_NOSIZE);
|
||||||
|
|
||||||
m_frameDrawer = FrameDrawer::Create(m_window);
|
m_frameDrawer = FrameDrawer::Create(m_window);
|
||||||
return m_frameDrawer != nullptr;
|
if (!m_frameDrawer)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateBorderProperties();
|
||||||
|
m_frameDrawer->Show();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowBorder::UpdateBorderPosition() const
|
void WindowBorder::UpdateBorderPosition() const
|
||||||
@@ -131,6 +149,7 @@ void WindowBorder::UpdateBorderPosition() const
|
|||||||
auto rectOpt = GetFrameRect(m_trackingWindow);
|
auto rectOpt = GetFrameRect(m_trackingWindow);
|
||||||
if (!rectOpt.has_value())
|
if (!rectOpt.has_value())
|
||||||
{
|
{
|
||||||
|
m_frameDrawer->Hide();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,17 +188,6 @@ void WindowBorder::UpdateBorderProperties() const
|
|||||||
m_frameDrawer->SetBorderRect(frameRect, color, AlwaysOnTopSettings::settings().frameThickness);
|
m_frameDrawer->SetBorderRect(frameRect, color, AlwaysOnTopSettings::settings().frameThickness);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowBorder::Show() const
|
|
||||||
{
|
|
||||||
UpdateBorderProperties();
|
|
||||||
m_frameDrawer->Show();
|
|
||||||
}
|
|
||||||
|
|
||||||
void WindowBorder::Hide() const
|
|
||||||
{
|
|
||||||
m_frameDrawer->Hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
LRESULT WindowBorder::WndProc(UINT message, WPARAM wparam, LPARAM lparam) noexcept
|
LRESULT WindowBorder::WndProc(UINT message, WPARAM wparam, LPARAM lparam) noexcept
|
||||||
{
|
{
|
||||||
switch (message)
|
switch (message)
|
||||||
|
|||||||
@@ -6,16 +6,13 @@ class FrameDrawer;
|
|||||||
|
|
||||||
class WindowBorder : public SettingsObserver
|
class WindowBorder : public SettingsObserver
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
WindowBorder(HWND window);
|
WindowBorder(HWND window);
|
||||||
WindowBorder(WindowBorder&& other);
|
WindowBorder(WindowBorder&& other);
|
||||||
|
|
||||||
|
public:
|
||||||
|
static std::unique_ptr<WindowBorder> Create(HWND window, HINSTANCE hinstance);
|
||||||
~WindowBorder();
|
~WindowBorder();
|
||||||
|
|
||||||
bool Init(HINSTANCE hinstance);
|
|
||||||
|
|
||||||
void Show() const;
|
|
||||||
void Hide() const;
|
|
||||||
|
|
||||||
void UpdateBorderPosition() const;
|
void UpdateBorderPosition() const;
|
||||||
void UpdateBorderProperties() const;
|
void UpdateBorderProperties() const;
|
||||||
|
|
||||||
@@ -41,5 +38,6 @@ private:
|
|||||||
|
|
||||||
LRESULT WndProc(UINT message, WPARAM wparam, LPARAM lparam) noexcept;
|
LRESULT WndProc(UINT message, WPARAM wparam, LPARAM lparam) noexcept;
|
||||||
|
|
||||||
|
bool Init(HINSTANCE hinstance);
|
||||||
virtual void SettingsUpdate(SettingId id) override;
|
virtual void SettingsUpdate(SettingId id) override;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user