mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-11 05:52:19 +02:00
[FancyZones] Dragging a window across monitors transparency fix (#5102)
This commit is contained in:
@@ -79,7 +79,11 @@ public:
|
|||||||
bool MoveWindowIntoZoneByDirection(HWND window, DWORD vkCode, bool cycle, winrt::com_ptr<IZoneWindow> zoneWindow);
|
bool MoveWindowIntoZoneByDirection(HWND window, DWORD vkCode, bool cycle, winrt::com_ptr<IZoneWindow> zoneWindow);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void UpdateDragState(HWND window) noexcept;
|
void WarnIfElevationIsRequired(HWND window) noexcept;
|
||||||
|
void UpdateDragState() noexcept;
|
||||||
|
|
||||||
|
void SetWindowTransparency(HWND window) noexcept;
|
||||||
|
void ResetWindowTransparency() noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
winrt::com_ptr<IFancyZonesSettings> m_settings{};
|
winrt::com_ptr<IFancyZonesSettings> m_settings{};
|
||||||
@@ -94,6 +98,15 @@ private:
|
|||||||
bool m_secondaryMouseButtonState{}; // True when secondary mouse button was clicked after window was moved
|
bool m_secondaryMouseButtonState{}; // True when secondary mouse button was clicked after window was moved
|
||||||
bool m_shiftKeyState{}; // True when shift key was pressed after window was moved
|
bool m_shiftKeyState{}; // True when shift key was pressed after window was moved
|
||||||
bool m_ctrlKeyState{}; // True when ctrl key was pressed after window was moved
|
bool m_ctrlKeyState{}; // True when ctrl key was pressed after window was moved
|
||||||
|
|
||||||
|
struct WindowTransparencyProperties
|
||||||
|
{
|
||||||
|
HWND draggedWindow = nullptr;
|
||||||
|
long draggedWindowExstyle = 0;
|
||||||
|
COLORREF draggedWindowCrKey = RGB(0, 0, 0);
|
||||||
|
DWORD draggedWindowDwFlags = 0;
|
||||||
|
BYTE draggedWindowInitialAlpha = 0;
|
||||||
|
} m_windowTransparencyProperties;
|
||||||
};
|
};
|
||||||
|
|
||||||
WindowMoveHandler::WindowMoveHandler(const winrt::com_ptr<IFancyZonesSettings>& settings, SecondaryMouseButtonsHook* mouseHook, ShiftKeyHook* shiftHook, CtrlKeyHook* ctrlHook) :
|
WindowMoveHandler::WindowMoveHandler(const winrt::com_ptr<IFancyZonesSettings>& settings, SecondaryMouseButtonsHook* mouseHook, ShiftKeyHook* shiftHook, CtrlKeyHook* ctrlHook) :
|
||||||
@@ -194,13 +207,17 @@ void WindowMoveHandlerPrivate::MoveSizeStart(HWND window, HMONITOR monitor, POIN
|
|||||||
m_shiftHook->enable();
|
m_shiftHook->enable();
|
||||||
m_ctrlHook->enable();
|
m_ctrlHook->enable();
|
||||||
|
|
||||||
// This updates m_dragEnabled depending on if the shift key is being held down.
|
// This updates m_dragEnabled depending on if the shift key is being held down
|
||||||
UpdateDragState(window);
|
UpdateDragState();
|
||||||
|
|
||||||
|
// Notifies user if unable to drag elevated window
|
||||||
|
WarnIfElevationIsRequired(window);
|
||||||
|
|
||||||
if (m_dragEnabled)
|
if (m_dragEnabled)
|
||||||
{
|
{
|
||||||
m_zoneWindowMoveSize = iter->second;
|
m_zoneWindowMoveSize = iter->second;
|
||||||
m_zoneWindowMoveSize->MoveSizeEnter(window);
|
SetWindowTransparency(m_windowMoveSize);
|
||||||
|
m_zoneWindowMoveSize->MoveSizeEnter(m_windowMoveSize);
|
||||||
if (m_settings->GetSettings()->showZonesOnAllMonitors)
|
if (m_settings->GetSettings()->showZonesOnAllMonitors)
|
||||||
{
|
{
|
||||||
for (auto [keyMonitor, zoneWindow] : zoneWindowMap)
|
for (auto [keyMonitor, zoneWindow] : zoneWindowMap)
|
||||||
@@ -217,7 +234,7 @@ void WindowMoveHandlerPrivate::MoveSizeStart(HWND window, HMONITOR monitor, POIN
|
|||||||
}
|
}
|
||||||
else if (m_zoneWindowMoveSize)
|
else if (m_zoneWindowMoveSize)
|
||||||
{
|
{
|
||||||
m_zoneWindowMoveSize->RestoreOriginalTransparency();
|
ResetWindowTransparency();
|
||||||
m_zoneWindowMoveSize = nullptr;
|
m_zoneWindowMoveSize = nullptr;
|
||||||
for (auto [keyMonitor, zoneWindow] : zoneWindowMap)
|
for (auto [keyMonitor, zoneWindow] : zoneWindowMap)
|
||||||
{
|
{
|
||||||
@@ -237,7 +254,7 @@ void WindowMoveHandlerPrivate::MoveSizeUpdate(HMONITOR monitor, POINT const& ptS
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This updates m_dragEnabled depending on if the shift key is being held down.
|
// This updates m_dragEnabled depending on if the shift key is being held down.
|
||||||
UpdateDragState(m_windowMoveSize);
|
UpdateDragState();
|
||||||
|
|
||||||
if (m_zoneWindowMoveSize)
|
if (m_zoneWindowMoveSize)
|
||||||
{
|
{
|
||||||
@@ -246,12 +263,12 @@ void WindowMoveHandlerPrivate::MoveSizeUpdate(HMONITOR monitor, POINT const& ptS
|
|||||||
{
|
{
|
||||||
// Drag got disabled, tell it to cancel and hide all windows
|
// Drag got disabled, tell it to cancel and hide all windows
|
||||||
m_zoneWindowMoveSize = nullptr;
|
m_zoneWindowMoveSize = nullptr;
|
||||||
|
ResetWindowTransparency();
|
||||||
|
|
||||||
for (auto [keyMonitor, zoneWindow] : zoneWindowMap)
|
for (auto [keyMonitor, zoneWindow] : zoneWindowMap)
|
||||||
{
|
{
|
||||||
if (zoneWindow)
|
if (zoneWindow)
|
||||||
{
|
{
|
||||||
zoneWindow->RestoreOriginalTransparency();
|
|
||||||
zoneWindow->HideZoneWindow();
|
zoneWindow->HideZoneWindow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -264,13 +281,12 @@ void WindowMoveHandlerPrivate::MoveSizeUpdate(HMONITOR monitor, POINT const& ptS
|
|||||||
if (iter->second != m_zoneWindowMoveSize)
|
if (iter->second != m_zoneWindowMoveSize)
|
||||||
{
|
{
|
||||||
// The drag has moved to a different monitor.
|
// The drag has moved to a different monitor.
|
||||||
m_zoneWindowMoveSize->RestoreOriginalTransparency();
|
|
||||||
m_zoneWindowMoveSize->ClearSelectedZones();
|
m_zoneWindowMoveSize->ClearSelectedZones();
|
||||||
|
|
||||||
if (!m_settings->GetSettings()->showZonesOnAllMonitors)
|
if (!m_settings->GetSettings()->showZonesOnAllMonitors)
|
||||||
{
|
{
|
||||||
m_zoneWindowMoveSize->HideZoneWindow();
|
m_zoneWindowMoveSize->HideZoneWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_zoneWindowMoveSize = iter->second;
|
m_zoneWindowMoveSize = iter->second;
|
||||||
m_zoneWindowMoveSize->MoveSizeEnter(m_windowMoveSize);
|
m_zoneWindowMoveSize->MoveSizeEnter(m_windowMoveSize);
|
||||||
}
|
}
|
||||||
@@ -302,14 +318,11 @@ void WindowMoveHandlerPrivate::MoveSizeEnd(HWND window, POINT const& ptScreen, c
|
|||||||
m_shiftHook->disable();
|
m_shiftHook->disable();
|
||||||
m_ctrlHook->disable();
|
m_ctrlHook->disable();
|
||||||
|
|
||||||
m_inMoveSize = false;
|
|
||||||
m_dragEnabled = false;
|
|
||||||
m_secondaryMouseButtonState = false;
|
|
||||||
m_windowMoveSize = nullptr;
|
|
||||||
if (m_zoneWindowMoveSize)
|
if (m_zoneWindowMoveSize)
|
||||||
{
|
{
|
||||||
auto zoneWindow = std::move(m_zoneWindowMoveSize);
|
auto zoneWindow = std::move(m_zoneWindowMoveSize);
|
||||||
zoneWindow->MoveSizeEnd(window, ptScreen);
|
ResetWindowTransparency();
|
||||||
|
zoneWindow->MoveSizeEnd(m_windowMoveSize, ptScreen);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -345,6 +358,11 @@ void WindowMoveHandlerPrivate::MoveSizeEnd(HWND window, POINT const& ptScreen, c
|
|||||||
}
|
}
|
||||||
::RemoveProp(window, MULTI_ZONE_STAMP);
|
::RemoveProp(window, MULTI_ZONE_STAMP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_inMoveSize = false;
|
||||||
|
m_dragEnabled = false;
|
||||||
|
m_secondaryMouseButtonState = false;
|
||||||
|
m_windowMoveSize = nullptr;
|
||||||
|
|
||||||
// Also, hide all windows (regardless of settings)
|
// Also, hide all windows (regardless of settings)
|
||||||
for (auto [keyMonitor, zoneWindow] : zoneWindowMap)
|
for (auto [keyMonitor, zoneWindow] : zoneWindowMap)
|
||||||
@@ -369,17 +387,8 @@ bool WindowMoveHandlerPrivate::MoveWindowIntoZoneByDirection(HWND window, DWORD
|
|||||||
return zoneWindow && zoneWindow->MoveWindowIntoZoneByDirection(window, vkCode, cycle);
|
return zoneWindow && zoneWindow->MoveWindowIntoZoneByDirection(window, vkCode, cycle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowMoveHandlerPrivate::UpdateDragState(HWND window) noexcept
|
void WindowMoveHandlerPrivate::WarnIfElevationIsRequired(HWND window) noexcept
|
||||||
{
|
{
|
||||||
if (m_settings->GetSettings()->shiftDrag)
|
|
||||||
{
|
|
||||||
m_dragEnabled = (m_shiftKeyState ^ m_secondaryMouseButtonState);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_dragEnabled = !(m_shiftKeyState ^ m_secondaryMouseButtonState);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool warning_shown = false;
|
static bool warning_shown = false;
|
||||||
if (!is_process_elevated() && IsProcessOfWindowElevated(window))
|
if (!is_process_elevated() && IsProcessOfWindowElevated(window))
|
||||||
{
|
{
|
||||||
@@ -395,3 +404,42 @@ void WindowMoveHandlerPrivate::UpdateDragState(HWND window) noexcept
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WindowMoveHandlerPrivate::UpdateDragState() noexcept
|
||||||
|
{
|
||||||
|
if (m_settings->GetSettings()->shiftDrag)
|
||||||
|
{
|
||||||
|
m_dragEnabled = (m_shiftKeyState ^ m_secondaryMouseButtonState);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_dragEnabled = !(m_shiftKeyState ^ m_secondaryMouseButtonState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowMoveHandlerPrivate::SetWindowTransparency(HWND window) noexcept
|
||||||
|
{
|
||||||
|
if (m_settings->GetSettings()->makeDraggedWindowTransparent)
|
||||||
|
{
|
||||||
|
m_windowTransparencyProperties.draggedWindowExstyle = GetWindowLong(window, GWL_EXSTYLE);
|
||||||
|
|
||||||
|
m_windowTransparencyProperties.draggedWindow = window;
|
||||||
|
SetWindowLong(window,
|
||||||
|
GWL_EXSTYLE,
|
||||||
|
m_windowTransparencyProperties.draggedWindowExstyle | WS_EX_LAYERED);
|
||||||
|
|
||||||
|
GetLayeredWindowAttributes(window, &m_windowTransparencyProperties.draggedWindowCrKey, &m_windowTransparencyProperties.draggedWindowInitialAlpha, &m_windowTransparencyProperties.draggedWindowDwFlags);
|
||||||
|
|
||||||
|
SetLayeredWindowAttributes(window, 0, (255 * 50) / 100, LWA_ALPHA);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowMoveHandlerPrivate::ResetWindowTransparency() noexcept
|
||||||
|
{
|
||||||
|
if (m_settings->GetSettings()->makeDraggedWindowTransparent && m_windowTransparencyProperties.draggedWindow != nullptr)
|
||||||
|
{
|
||||||
|
SetLayeredWindowAttributes(m_windowTransparencyProperties.draggedWindow, m_windowTransparencyProperties.draggedWindowCrKey, m_windowTransparencyProperties.draggedWindowInitialAlpha, m_windowTransparencyProperties.draggedWindowDwFlags);
|
||||||
|
SetWindowLong(m_windowTransparencyProperties.draggedWindow, GWL_EXSTYLE, m_windowTransparencyProperties.draggedWindowExstyle);
|
||||||
|
m_windowTransparencyProperties.draggedWindow = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -175,8 +175,6 @@ public:
|
|||||||
IFACEMETHODIMP MoveSizeUpdate(POINT const& ptScreen, bool dragEnabled, bool selectManyZones) noexcept;
|
IFACEMETHODIMP MoveSizeUpdate(POINT const& ptScreen, bool dragEnabled, bool selectManyZones) noexcept;
|
||||||
IFACEMETHODIMP MoveSizeEnd(HWND window, POINT const& ptScreen) noexcept;
|
IFACEMETHODIMP MoveSizeEnd(HWND window, POINT const& ptScreen) noexcept;
|
||||||
IFACEMETHODIMP_(void)
|
IFACEMETHODIMP_(void)
|
||||||
RestoreOriginalTransparency() noexcept;
|
|
||||||
IFACEMETHODIMP_(void)
|
|
||||||
MoveWindowIntoZoneByIndex(HWND window, int index) noexcept;
|
MoveWindowIntoZoneByIndex(HWND window, int index) noexcept;
|
||||||
IFACEMETHODIMP_(void)
|
IFACEMETHODIMP_(void)
|
||||||
MoveWindowIntoZoneByIndexSet(HWND window, const std::vector<int>& indexSet) noexcept;
|
MoveWindowIntoZoneByIndexSet(HWND window, const std::vector<int>& indexSet) noexcept;
|
||||||
@@ -231,13 +229,7 @@ private:
|
|||||||
size_t m_keyCycle{};
|
size_t m_keyCycle{};
|
||||||
static const UINT m_showAnimationDuration = 200; // ms
|
static const UINT m_showAnimationDuration = 200; // ms
|
||||||
static const UINT m_flashDuration = 700; // ms
|
static const UINT m_flashDuration = 700; // ms
|
||||||
|
|
||||||
HWND draggedWindow = nullptr;
|
|
||||||
long draggedWindowExstyle = 0;
|
|
||||||
COLORREF draggedWindowCrKey = RGB(0, 0, 0);
|
|
||||||
DWORD draggedWindowDwFlags = 0;
|
|
||||||
BYTE draggedWindowInitialAlpha = 0;
|
|
||||||
|
|
||||||
ULONG_PTR gdiplusToken;
|
ULONG_PTR gdiplusToken;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -309,25 +301,6 @@ bool ZoneWindow::Init(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monit
|
|||||||
|
|
||||||
IFACEMETHODIMP ZoneWindow::MoveSizeEnter(HWND window) noexcept
|
IFACEMETHODIMP ZoneWindow::MoveSizeEnter(HWND window) noexcept
|
||||||
{
|
{
|
||||||
if (m_windowMoveSize)
|
|
||||||
{
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_host->isMakeDraggedWindowTransparentActive())
|
|
||||||
{
|
|
||||||
draggedWindowExstyle = GetWindowLong(window, GWL_EXSTYLE);
|
|
||||||
|
|
||||||
draggedWindow = window;
|
|
||||||
SetWindowLong(window,
|
|
||||||
GWL_EXSTYLE,
|
|
||||||
draggedWindowExstyle | WS_EX_LAYERED);
|
|
||||||
|
|
||||||
GetLayeredWindowAttributes(window, &draggedWindowCrKey, &draggedWindowInitialAlpha, &draggedWindowDwFlags);
|
|
||||||
|
|
||||||
SetLayeredWindowAttributes(window, 0, (255 * 50) / 100, LWA_ALPHA);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_windowMoveSize = window;
|
m_windowMoveSize = window;
|
||||||
m_drawHints = true;
|
m_drawHints = true;
|
||||||
m_highlightZone = {};
|
m_highlightZone = {};
|
||||||
@@ -418,8 +391,6 @@ IFACEMETHODIMP ZoneWindow::MoveSizeUpdate(POINT const& ptScreen, bool dragEnable
|
|||||||
|
|
||||||
IFACEMETHODIMP ZoneWindow::MoveSizeEnd(HWND window, POINT const& ptScreen) noexcept
|
IFACEMETHODIMP ZoneWindow::MoveSizeEnd(HWND window, POINT const& ptScreen) noexcept
|
||||||
{
|
{
|
||||||
RestoreOriginalTransparency();
|
|
||||||
|
|
||||||
if (m_windowMoveSize != window)
|
if (m_windowMoveSize != window)
|
||||||
{
|
{
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
@@ -440,17 +411,6 @@ IFACEMETHODIMP ZoneWindow::MoveSizeEnd(HWND window, POINT const& ptScreen) noexc
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
IFACEMETHODIMP_(void)
|
|
||||||
ZoneWindow::RestoreOriginalTransparency() noexcept
|
|
||||||
{
|
|
||||||
if (m_host->isMakeDraggedWindowTransparentActive() && draggedWindow != nullptr)
|
|
||||||
{
|
|
||||||
SetLayeredWindowAttributes(draggedWindow, draggedWindowCrKey, draggedWindowInitialAlpha, draggedWindowDwFlags);
|
|
||||||
SetWindowLong(draggedWindow, GWL_EXSTYLE, draggedWindowExstyle);
|
|
||||||
draggedWindow = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IFACEMETHODIMP_(void)
|
IFACEMETHODIMP_(void)
|
||||||
ZoneWindow::MoveWindowIntoZoneByIndex(HWND window, int index) noexcept
|
ZoneWindow::MoveWindowIntoZoneByIndex(HWND window, int index) noexcept
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -17,10 +17,9 @@ interface __declspec(uuid("{7F017528-8110-4FB3-BE41-F472969C2560}")) IZoneWindow
|
|||||||
* hints if dragging functionality is enabled.
|
* hints if dragging functionality is enabled.
|
||||||
*
|
*
|
||||||
* @param window Handle of window being moved or resized.
|
* @param window Handle of window being moved or resized.
|
||||||
* @param dragEnabled Boolean indicating is giving hints about active zone layout enabled.
|
|
||||||
* Hints are given while dragging window while holding SHIFT key.
|
|
||||||
*/
|
*/
|
||||||
IFACEMETHOD(MoveSizeEnter)(HWND window) = 0;
|
IFACEMETHOD(MoveSizeEnter)(HWND window) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A window has changed location, shape, or size. Track down window position and give zone layout
|
* A window has changed location, shape, or size. Track down window position and give zone layout
|
||||||
* hints if dragging functionality is enabled.
|
* hints if dragging functionality is enabled.
|
||||||
@@ -74,10 +73,7 @@ interface __declspec(uuid("{7F017528-8110-4FB3-BE41-F472969C2560}")) IZoneWindow
|
|||||||
* @param vkCode Pressed key representing layout index.
|
* @param vkCode Pressed key representing layout index.
|
||||||
*/
|
*/
|
||||||
IFACEMETHOD_(void, CycleActiveZoneSet)(DWORD vkCode) = 0;
|
IFACEMETHOD_(void, CycleActiveZoneSet)(DWORD vkCode) = 0;
|
||||||
/**
|
|
||||||
* Restore original transaprency of dragged window.
|
|
||||||
*/
|
|
||||||
IFACEMETHOD_(void, RestoreOriginalTransparency) () = 0;
|
|
||||||
/**
|
/**
|
||||||
* Save information about zone in which window was assigned, when closing the window.
|
* Save information about zone in which window was assigned, when closing the window.
|
||||||
* Used once we open same window again to assign it to its previous zone.
|
* Used once we open same window again to assign it to its previous zone.
|
||||||
|
|||||||
@@ -457,7 +457,7 @@ namespace FancyZonesUnitTests
|
|||||||
{
|
{
|
||||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), {}, false);
|
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), {}, false);
|
||||||
|
|
||||||
const auto expected = E_INVALIDARG;
|
const auto expected = S_OK;
|
||||||
|
|
||||||
m_zoneWindow->MoveSizeEnter(Mocks::Window());
|
m_zoneWindow->MoveSizeEnter(Mocks::Window());
|
||||||
const auto actual = m_zoneWindow->MoveSizeEnter(Mocks::Window());
|
const auto actual = m_zoneWindow->MoveSizeEnter(Mocks::Window());
|
||||||
|
|||||||
Reference in New Issue
Block a user