mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-01-18 06:29:44 +08:00
[FancyZones] Hold Ctrl to select any number of zones (#4850)
* Started work * Did something, not yet sure that it works * Sort of works * Cleari highlighted zones when using Ctrl after leaving a monitor * Remove unnecessary line * Enhanced UX. Maybe refactor? * Changed the logic behind zone selection when dragging * Various fixups
This commit is contained in:
parent
b1d662a5b1
commit
412d80efe3
@ -18,7 +18,7 @@
|
||||
|
||||
#include <interface/win_hook_event_data.h>
|
||||
#include <lib/SecondaryMouseButtonsHook.h>
|
||||
#include <lib/ShiftKeyHook.h>
|
||||
#include <lib/GenericKeyHook.h>
|
||||
|
||||
enum class DisplayChangeType
|
||||
{
|
||||
@ -41,7 +41,8 @@ public:
|
||||
m_settings(settings),
|
||||
m_mouseHook(std::bind(&FancyZones::OnMouseDown, this)),
|
||||
m_shiftHook(std::bind(&FancyZones::OnShiftChangeState, this, std::placeholders::_1)),
|
||||
m_windowMoveHandler(settings, &m_mouseHook, &m_shiftHook)
|
||||
m_ctrlHook(std::bind(&FancyZones::OnCtrlChangeState, this, std::placeholders::_1)),
|
||||
m_windowMoveHandler(settings, &m_mouseHook, &m_shiftHook, &m_ctrlHook)
|
||||
{
|
||||
m_settings->SetCallback(this);
|
||||
}
|
||||
@ -66,6 +67,13 @@ public:
|
||||
PostMessageW(m_window, WM_PRIV_LOCATIONCHANGE, NULL, NULL);
|
||||
}
|
||||
|
||||
void OnCtrlChangeState(bool state) noexcept
|
||||
{
|
||||
m_windowMoveHandler.OnCtrlChangeState(state);
|
||||
|
||||
PostMessageW(m_window, WM_PRIV_LOCATIONCHANGE, NULL, NULL);
|
||||
}
|
||||
|
||||
void MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen) noexcept
|
||||
{
|
||||
std::unique_lock writeLock(m_lock);
|
||||
@ -244,6 +252,7 @@ private:
|
||||
MonitorWorkAreaHandler m_workAreaHandler;
|
||||
SecondaryMouseButtonsHook m_mouseHook;
|
||||
ShiftKeyHook m_shiftHook;
|
||||
CtrlKeyHook m_ctrlHook;
|
||||
|
||||
winrt::com_ptr<IFancyZonesSettings> m_settings{};
|
||||
GUID m_previousDesktopId{}; // UUID of previously active virtual desktop.
|
||||
|
@ -100,13 +100,13 @@
|
||||
<ItemGroup>
|
||||
<ClInclude Include="FancyZones.h" />
|
||||
<ClInclude Include="FancyZonesWinHookEventIDs.h" />
|
||||
<ClInclude Include="GenericKeyHook.h" />
|
||||
<ClInclude Include="JsonHelpers.h" />
|
||||
<ClInclude Include="MonitorWorkAreaHandler.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="SecondaryMouseButtonsHook.h" />
|
||||
<ClInclude Include="Settings.h" />
|
||||
<ClInclude Include="ShiftKeyHook.h" />
|
||||
<ClInclude Include="trace.h" />
|
||||
<ClInclude Include="util.h" />
|
||||
<ClInclude Include="VirtualDesktopUtils.h" />
|
||||
@ -118,6 +118,7 @@
|
||||
<ItemGroup>
|
||||
<ClCompile Include="FancyZones.cpp" />
|
||||
<ClCompile Include="FancyZonesWinHookEventIDs.cpp" />
|
||||
<ClCompile Include="GenericKeyHook.cpp" />
|
||||
<ClCompile Include="JsonHelpers.cpp" />
|
||||
<ClCompile Include="MonitorWorkAreaHandler.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
@ -125,7 +126,6 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="SecondaryMouseButtonsHook.cpp" />
|
||||
<ClCompile Include="Settings.cpp" />
|
||||
<ClCompile Include="ShiftKeyHook.cpp" />
|
||||
<ClCompile Include="trace.cpp" />
|
||||
<ClCompile Include="util.cpp" />
|
||||
<ClCompile Include="VirtualDesktopUtils.cpp" />
|
||||
|
@ -60,7 +60,7 @@
|
||||
<ClInclude Include="MonitorWorkAreaHandler.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ShiftKeyHook.h">
|
||||
<ClInclude Include="GenericKeyHook.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
@ -107,7 +107,7 @@
|
||||
<ClCompile Include="MonitorWorkAreaHandler.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ShiftKeyHook.cpp">
|
||||
<ClCompile Include="GenericKeyHook.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
|
8
src/modules/fancyzones/lib/GenericKeyHook.cpp
Normal file
8
src/modules/fancyzones/lib/GenericKeyHook.cpp
Normal file
@ -0,0 +1,8 @@
|
||||
#include "pch.h"
|
||||
#include "GenericKeyHook.h"
|
||||
|
||||
HHOOK ShiftKeyHook::hHook{};
|
||||
std::function<void(bool)> ShiftKeyHook::callback{};
|
||||
|
||||
HHOOK CtrlKeyHook::hHook{};
|
||||
std::function<void(bool)> CtrlKeyHook::callback{};
|
62
src/modules/fancyzones/lib/GenericKeyHook.h
Normal file
62
src/modules/fancyzones/lib/GenericKeyHook.h
Normal file
@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include "pch.h"
|
||||
|
||||
template<int... keys>
|
||||
class GenericKeyHook
|
||||
{
|
||||
public:
|
||||
|
||||
GenericKeyHook(std::function<void(bool)> extCallback)
|
||||
{
|
||||
callback = std::move(extCallback);
|
||||
}
|
||||
|
||||
void enable()
|
||||
{
|
||||
#if defined(DISABLE_LOWLEVEL_HOOKS_WHEN_DEBUGGED)
|
||||
if (IsDebuggerPresent())
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (!hHook)
|
||||
{
|
||||
hHook = SetWindowsHookEx(WH_KEYBOARD_LL, GenericKeyHookProc, GetModuleHandle(NULL), 0);
|
||||
}
|
||||
}
|
||||
|
||||
void disable()
|
||||
{
|
||||
if (hHook)
|
||||
{
|
||||
UnhookWindowsHookEx(hHook);
|
||||
hHook = NULL;
|
||||
callback(false);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static HHOOK hHook;
|
||||
static std::function<void(bool)> callback;
|
||||
|
||||
static LRESULT CALLBACK GenericKeyHookProc(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (nCode == HC_ACTION)
|
||||
{
|
||||
if (wParam == WM_KEYDOWN || wParam == WM_KEYUP)
|
||||
{
|
||||
PKBDLLHOOKSTRUCT kbdHookStruct = (PKBDLLHOOKSTRUCT)lParam;
|
||||
if (((kbdHookStruct->vkCode == keys) || ...))
|
||||
{
|
||||
callback(wParam == WM_KEYDOWN);
|
||||
}
|
||||
}
|
||||
}
|
||||
return CallNextHookEx(hHook, nCode, wParam, lParam);
|
||||
}
|
||||
};
|
||||
|
||||
typedef GenericKeyHook<VK_LSHIFT, VK_RSHIFT> ShiftKeyHook;
|
||||
typedef GenericKeyHook<VK_LCONTROL, VK_RCONTROL> CtrlKeyHook;
|
@ -1,68 +0,0 @@
|
||||
#include "pch.h"
|
||||
#include "ShiftKeyHook.h"
|
||||
|
||||
#include <common/debug_control.h>
|
||||
|
||||
#pragma region public
|
||||
|
||||
HHOOK ShiftKeyHook::hHook = {};
|
||||
std::function<void(bool)> ShiftKeyHook::callback = {};
|
||||
|
||||
ShiftKeyHook::ShiftKeyHook(std::function<void(bool)> extCallback)
|
||||
{
|
||||
callback = std::move(extCallback);
|
||||
}
|
||||
|
||||
void ShiftKeyHook::enable()
|
||||
{
|
||||
#if defined(DISABLE_LOWLEVEL_HOOKS_WHEN_DEBUGGED)
|
||||
if (IsDebuggerPresent())
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (!hHook)
|
||||
{
|
||||
hHook = SetWindowsHookEx(WH_KEYBOARD_LL, ShiftKeyHookProc, GetModuleHandle(NULL), 0);
|
||||
}
|
||||
}
|
||||
|
||||
void ShiftKeyHook::disable()
|
||||
{
|
||||
if (hHook)
|
||||
{
|
||||
UnhookWindowsHookEx(hHook);
|
||||
hHook = NULL;
|
||||
callback(false);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region private
|
||||
|
||||
LRESULT CALLBACK ShiftKeyHook::ShiftKeyHookProc(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (nCode == HC_ACTION)
|
||||
{
|
||||
if (wParam == WM_KEYDOWN)
|
||||
{
|
||||
PKBDLLHOOKSTRUCT kbdHookStruct = (PKBDLLHOOKSTRUCT)lParam;
|
||||
if (kbdHookStruct->vkCode == VK_LSHIFT || kbdHookStruct->vkCode == VK_RSHIFT)
|
||||
{
|
||||
callback(true);
|
||||
}
|
||||
}
|
||||
else if (wParam == WM_KEYUP)
|
||||
{
|
||||
PKBDLLHOOKSTRUCT kbdHookStruct = (PKBDLLHOOKSTRUCT)lParam;
|
||||
if (kbdHookStruct->vkCode == VK_LSHIFT || kbdHookStruct->vkCode == VK_RSHIFT)
|
||||
{
|
||||
callback(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
return CallNextHookEx(hHook, nCode, wParam, lParam);
|
||||
}
|
||||
|
||||
#pragma endregion
|
@ -1,16 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
|
||||
class ShiftKeyHook
|
||||
{
|
||||
public:
|
||||
ShiftKeyHook(std::function<void(bool)>);
|
||||
void enable();
|
||||
void disable();
|
||||
|
||||
private:
|
||||
static HHOOK hHook;
|
||||
static std::function<void(bool)> callback;
|
||||
static LRESULT CALLBACK ShiftKeyHookProc(int, WPARAM, LPARAM);
|
||||
};
|
@ -11,7 +11,7 @@
|
||||
#include "lib/util.h"
|
||||
#include "VirtualDesktopUtils.h"
|
||||
#include "lib/SecondaryMouseButtonsHook.h"
|
||||
#include <lib/ShiftKeyHook.h>
|
||||
#include "lib/GenericKeyHook.h"
|
||||
|
||||
extern "C" IMAGE_DOS_HEADER __ImageBase;
|
||||
|
||||
@ -48,10 +48,13 @@ namespace WindowMoveHandlerUtils
|
||||
class WindowMoveHandlerPrivate
|
||||
{
|
||||
public:
|
||||
WindowMoveHandlerPrivate(const winrt::com_ptr<IFancyZonesSettings>& settings, SecondaryMouseButtonsHook* mouseHook, ShiftKeyHook* shiftHook) :
|
||||
WindowMoveHandlerPrivate(const winrt::com_ptr<IFancyZonesSettings>& settings, SecondaryMouseButtonsHook* mouseHook, ShiftKeyHook* shiftHook, CtrlKeyHook* ctrlHook) :
|
||||
m_settings(settings),
|
||||
m_mouseHook(mouseHook),
|
||||
m_shiftHook(shiftHook){};
|
||||
m_shiftHook(shiftHook),
|
||||
m_ctrlHook(ctrlHook)
|
||||
{
|
||||
}
|
||||
|
||||
bool IsDragEnabled() const noexcept
|
||||
{
|
||||
@ -65,6 +68,7 @@ public:
|
||||
|
||||
void OnMouseDown() noexcept;
|
||||
void OnShiftChangeState(bool state) noexcept;
|
||||
void OnCtrlChangeState(bool state) noexcept;
|
||||
|
||||
void MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept;
|
||||
void MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept;
|
||||
@ -80,6 +84,7 @@ private:
|
||||
winrt::com_ptr<IFancyZonesSettings> m_settings{};
|
||||
SecondaryMouseButtonsHook* m_mouseHook{};
|
||||
ShiftKeyHook* m_shiftHook{};
|
||||
CtrlKeyHook* m_ctrlHook{};
|
||||
|
||||
HWND m_windowMoveSize{}; // The window that is being moved/sized
|
||||
bool m_inMoveSize{}; // Whether or not a move/size operation is currently active
|
||||
@ -87,10 +92,11 @@ private:
|
||||
bool m_dragEnabled{}; // True if we should be showing zone hints while dragging
|
||||
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_ctrlKeyState{}; // True when ctrl key was pressed after window was moved
|
||||
};
|
||||
|
||||
WindowMoveHandler::WindowMoveHandler(const winrt::com_ptr<IFancyZonesSettings>& settings, SecondaryMouseButtonsHook* mouseHook, ShiftKeyHook* shiftHook) :
|
||||
pimpl(new WindowMoveHandlerPrivate(settings, mouseHook, shiftHook)) {}
|
||||
WindowMoveHandler::WindowMoveHandler(const winrt::com_ptr<IFancyZonesSettings>& settings, SecondaryMouseButtonsHook* mouseHook, ShiftKeyHook* shiftHook, CtrlKeyHook* ctrlHook) :
|
||||
pimpl(new WindowMoveHandlerPrivate(settings, mouseHook, shiftHook, ctrlHook)) {}
|
||||
|
||||
WindowMoveHandler::~WindowMoveHandler()
|
||||
{
|
||||
@ -117,6 +123,11 @@ void WindowMoveHandler::OnShiftChangeState(bool state) noexcept
|
||||
pimpl->OnShiftChangeState(state);
|
||||
}
|
||||
|
||||
void WindowMoveHandler::OnCtrlChangeState(bool state) noexcept
|
||||
{
|
||||
pimpl->OnCtrlChangeState(state);
|
||||
}
|
||||
|
||||
void WindowMoveHandler::MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept
|
||||
{
|
||||
pimpl->MoveSizeStart(window, monitor, ptScreen, zoneWindowMap);
|
||||
@ -152,6 +163,11 @@ void WindowMoveHandlerPrivate::OnShiftChangeState(bool state) noexcept
|
||||
m_shiftKeyState = state;
|
||||
}
|
||||
|
||||
void WindowMoveHandlerPrivate::OnCtrlChangeState(bool state) noexcept
|
||||
{
|
||||
m_ctrlKeyState = state;
|
||||
}
|
||||
|
||||
void WindowMoveHandlerPrivate::MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept
|
||||
{
|
||||
if (!IsInterestingWindow(window, m_settings->GetSettings()->excludedAppsArray) || WindowMoveHandlerUtils::IsCursorTypeIndicatingSizeEvent())
|
||||
@ -175,6 +191,7 @@ void WindowMoveHandlerPrivate::MoveSizeStart(HWND window, HMONITOR monitor, POIN
|
||||
}
|
||||
|
||||
m_shiftHook->enable();
|
||||
m_ctrlHook->enable();
|
||||
|
||||
// This updates m_dragEnabled depending on if the shift key is being held down.
|
||||
UpdateDragState(window);
|
||||
@ -247,6 +264,7 @@ void WindowMoveHandlerPrivate::MoveSizeUpdate(HMONITOR monitor, POINT const& ptS
|
||||
{
|
||||
// The drag has moved to a different monitor.
|
||||
m_zoneWindowMoveSize->RestoreOriginalTransparency();
|
||||
m_zoneWindowMoveSize->ClearSelectedZones();
|
||||
|
||||
if (!m_settings->GetSettings()->showZonesOnAllMonitors)
|
||||
{
|
||||
@ -258,7 +276,7 @@ void WindowMoveHandlerPrivate::MoveSizeUpdate(HMONITOR monitor, POINT const& ptS
|
||||
|
||||
for (auto [keyMonitor, zoneWindow] : zoneWindowMap)
|
||||
{
|
||||
zoneWindow->MoveSizeUpdate(ptScreen, m_dragEnabled);
|
||||
zoneWindow->MoveSizeUpdate(ptScreen, m_dragEnabled, m_ctrlKeyState);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -281,6 +299,7 @@ void WindowMoveHandlerPrivate::MoveSizeEnd(HWND window, POINT const& ptScreen, c
|
||||
|
||||
m_mouseHook->disable();
|
||||
m_shiftHook->disable();
|
||||
m_ctrlHook->disable();
|
||||
|
||||
m_inMoveSize = false;
|
||||
m_dragEnabled = false;
|
||||
|
@ -1,14 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "SecondaryMouseButtonsHook.h"
|
||||
#include "GenericKeyHook.h"
|
||||
|
||||
interface IFancyZonesSettings;
|
||||
interface IZoneWindow;
|
||||
class SecondaryMouseButtonsHook;
|
||||
class ShiftKeyHook;
|
||||
|
||||
class WindowMoveHandler
|
||||
{
|
||||
public:
|
||||
WindowMoveHandler(const winrt::com_ptr<IFancyZonesSettings>& settings, SecondaryMouseButtonsHook* mouseHook, ShiftKeyHook* shiftHook);
|
||||
WindowMoveHandler(const winrt::com_ptr<IFancyZonesSettings>& settings, SecondaryMouseButtonsHook* mouseHook, ShiftKeyHook* shiftHook, CtrlKeyHook* ctrlHook);
|
||||
~WindowMoveHandler();
|
||||
|
||||
bool InMoveSize() const noexcept;
|
||||
@ -16,6 +17,7 @@ public:
|
||||
|
||||
void OnMouseDown() noexcept;
|
||||
void OnShiftChangeState(bool state) noexcept; //True for shift down event false for shift up
|
||||
void OnCtrlChangeState(bool state) noexcept; //True for ctrl down event false for ctrl up
|
||||
|
||||
void MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept;
|
||||
void MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept;
|
||||
|
@ -212,7 +212,7 @@ public:
|
||||
bool Init(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, const std::wstring& uniqueId, const std::wstring& parentUniqueId, bool flashZones);
|
||||
|
||||
IFACEMETHODIMP MoveSizeEnter(HWND window) noexcept;
|
||||
IFACEMETHODIMP MoveSizeUpdate(POINT const& ptScreen, bool dragEnabled) noexcept;
|
||||
IFACEMETHODIMP MoveSizeUpdate(POINT const& ptScreen, bool dragEnabled, bool selectManyZones) noexcept;
|
||||
IFACEMETHODIMP MoveSizeEnd(HWND window, POINT const& ptScreen) noexcept;
|
||||
IFACEMETHODIMP_(void)
|
||||
RestoreOriginalTransparency() noexcept;
|
||||
@ -238,6 +238,8 @@ public:
|
||||
HideZoneWindow() noexcept;
|
||||
IFACEMETHODIMP_(void)
|
||||
UpdateActiveZoneSet() noexcept;
|
||||
IFACEMETHODIMP_(void)
|
||||
ClearSelectedZones() noexcept;
|
||||
|
||||
protected:
|
||||
static LRESULT CALLBACK s_WndProc(HWND window, UINT message, WPARAM wparam, LPARAM lparam) noexcept;
|
||||
@ -263,6 +265,7 @@ private:
|
||||
bool m_flashMode{};
|
||||
winrt::com_ptr<IZoneSet> m_activeZoneSet;
|
||||
std::vector<winrt::com_ptr<IZoneSet>> m_zoneSets;
|
||||
std::vector<int> m_initialHighlightZone;
|
||||
std::vector<int> m_highlightZone;
|
||||
WPARAM m_keyLast{};
|
||||
size_t m_keyCycle{};
|
||||
@ -368,11 +371,12 @@ IFACEMETHODIMP ZoneWindow::MoveSizeEnter(HWND window) noexcept
|
||||
m_windowMoveSize = window;
|
||||
m_drawHints = true;
|
||||
m_highlightZone = {};
|
||||
m_initialHighlightZone = {};
|
||||
ShowZoneWindow();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP ZoneWindow::MoveSizeUpdate(POINT const& ptScreen, bool dragEnabled) noexcept
|
||||
IFACEMETHODIMP ZoneWindow::MoveSizeUpdate(POINT const& ptScreen, bool dragEnabled, bool selectManyZones) noexcept
|
||||
{
|
||||
bool redraw = false;
|
||||
POINT ptClient = ptScreen;
|
||||
@ -381,6 +385,61 @@ IFACEMETHODIMP ZoneWindow::MoveSizeUpdate(POINT const& ptScreen, bool dragEnable
|
||||
if (dragEnabled)
|
||||
{
|
||||
auto highlightZone = ZonesFromPoint(ptClient);
|
||||
|
||||
if (selectManyZones)
|
||||
{
|
||||
if (m_initialHighlightZone.empty())
|
||||
{
|
||||
// first time
|
||||
m_initialHighlightZone = highlightZone;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<int> newHighlightZone;
|
||||
std::set_union(begin(highlightZone), end(highlightZone), begin(m_initialHighlightZone), end(m_initialHighlightZone), std::back_inserter(newHighlightZone));
|
||||
|
||||
RECT boundingRect;
|
||||
bool boundingRectEmpty = true;
|
||||
auto zones = m_activeZoneSet->GetZones();
|
||||
|
||||
for (int zoneId : newHighlightZone)
|
||||
{
|
||||
RECT rect = zones[zoneId]->GetZoneRect();
|
||||
if (boundingRectEmpty)
|
||||
{
|
||||
boundingRect = rect;
|
||||
boundingRectEmpty = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
boundingRect.left = min(boundingRect.left, rect.left);
|
||||
boundingRect.top = min(boundingRect.top, rect.top);
|
||||
boundingRect.right = max(boundingRect.right, rect.right);
|
||||
boundingRect.bottom = max(boundingRect.bottom, rect.bottom);
|
||||
}
|
||||
}
|
||||
|
||||
highlightZone.clear();
|
||||
|
||||
if (!boundingRectEmpty)
|
||||
{
|
||||
for (size_t zoneId = 0; zoneId < zones.size(); zoneId++)
|
||||
{
|
||||
RECT rect = zones[zoneId]->GetZoneRect();
|
||||
if (boundingRect.left <= rect.left && rect.right <= boundingRect.right &&
|
||||
boundingRect.top <= rect.top && rect.bottom <= boundingRect.bottom)
|
||||
{
|
||||
highlightZone.push_back(static_cast<int>(zoneId));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_initialHighlightZone = {};
|
||||
}
|
||||
|
||||
redraw = (highlightZone != m_highlightZone);
|
||||
m_highlightZone = std::move(highlightZone);
|
||||
}
|
||||
@ -410,7 +469,7 @@ IFACEMETHODIMP ZoneWindow::MoveSizeEnd(HWND window, POINT const& ptScreen) noexc
|
||||
{
|
||||
POINT ptClient = ptScreen;
|
||||
MapWindowPoints(nullptr, m_window.get(), &ptClient, 1);
|
||||
m_activeZoneSet->MoveWindowIntoZoneByPoint(window, m_window.get(), ptClient);
|
||||
m_activeZoneSet->MoveWindowIntoZoneByIndexSet(window, m_window.get(), m_highlightZone);
|
||||
|
||||
SaveWindowProcessToZoneIndex(window);
|
||||
}
|
||||
@ -545,6 +604,16 @@ ZoneWindow::UpdateActiveZoneSet() noexcept
|
||||
CalculateZoneSet();
|
||||
}
|
||||
|
||||
IFACEMETHODIMP_(void)
|
||||
ZoneWindow::ClearSelectedZones() noexcept
|
||||
{
|
||||
if (m_highlightZone.size())
|
||||
{
|
||||
m_highlightZone.clear();
|
||||
InvalidateRect(m_window.get(), nullptr, true);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma region private
|
||||
|
||||
void ZoneWindow::InitializeZoneSets(const std::wstring& parentUniqueId) noexcept
|
||||
|
@ -29,11 +29,16 @@ interface __declspec(uuid("{7F017528-8110-4FB3-BE41-F472969C2560}")) IZoneWindow
|
||||
* A window has changed location, shape, or size. Track down window position and give zone layout
|
||||
* hints if dragging functionality is enabled.
|
||||
*
|
||||
* @param ptScreen Cursor coordinates.
|
||||
* @param dragEnabled Boolean indicating is giving hints about active zone layout enabled.
|
||||
* Hints are given while dragging window while holding SHIFT key.
|
||||
* @param ptScreen Cursor coordinates.
|
||||
* @param dragEnabled Boolean indicating is giving hints about active zone layout enabled.
|
||||
* Hints are given while dragging window while holding SHIFT key.
|
||||
* @param selectManyZones When this parameter is true, the set of highlighted zones is computed
|
||||
by finding the minimum bounding rectangle of the zone(s) from which the
|
||||
user started dragging and the zone(s) above which the user is hovering
|
||||
at the moment this function is called. Otherwise, highlight only the zone(s)
|
||||
above which the user is currently hovering.
|
||||
*/
|
||||
IFACEMETHOD(MoveSizeUpdate)(POINT const& ptScreen, bool dragEnabled) = 0;
|
||||
IFACEMETHOD(MoveSizeUpdate)(POINT const& ptScreen, bool dragEnabled, bool selectManyZones) = 0;
|
||||
/**
|
||||
* The movement or resizing of a window has finished. Assign window to the zone of it
|
||||
* is dropped within zone borders.
|
||||
@ -102,6 +107,10 @@ interface __declspec(uuid("{7F017528-8110-4FB3-BE41-F472969C2560}")) IZoneWindow
|
||||
* Update currently active zone layout for this work area.
|
||||
*/
|
||||
IFACEMETHOD_(void, UpdateActiveZoneSet)() = 0;
|
||||
/**
|
||||
* Clear the selected zones when this ZoneWindow loses focus.
|
||||
*/
|
||||
IFACEMETHOD_(void, ClearSelectedZones)() = 0;
|
||||
};
|
||||
|
||||
winrt::com_ptr<IZoneWindow> MakeZoneWindow(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor,
|
||||
|
@ -467,7 +467,7 @@ namespace FancyZonesUnitTests
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), {}, false);
|
||||
|
||||
const auto expected = S_OK;
|
||||
const auto actual = m_zoneWindow->MoveSizeUpdate(POINT{ 0, 0 }, true);
|
||||
const auto actual = m_zoneWindow->MoveSizeUpdate(POINT{ 0, 0 }, true, false);
|
||||
|
||||
Assert::AreEqual(expected, actual);
|
||||
}
|
||||
@ -477,7 +477,7 @@ namespace FancyZonesUnitTests
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), {}, false);
|
||||
|
||||
const auto expected = S_OK;
|
||||
const auto actual = m_zoneWindow->MoveSizeUpdate(POINT{ -10, -10 }, true);
|
||||
const auto actual = m_zoneWindow->MoveSizeUpdate(POINT{ -10, -10 }, true, false);
|
||||
|
||||
Assert::AreEqual(expected, actual);
|
||||
}
|
||||
@ -487,7 +487,7 @@ namespace FancyZonesUnitTests
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), {}, false);
|
||||
|
||||
const auto expected = S_OK;
|
||||
const auto actual = m_zoneWindow->MoveSizeUpdate(POINT{ m_monitorInfo.rcMonitor.right + 1, m_monitorInfo.rcMonitor.bottom + 1 }, true);
|
||||
const auto actual = m_zoneWindow->MoveSizeUpdate(POINT{ m_monitorInfo.rcMonitor.right + 1, m_monitorInfo.rcMonitor.bottom + 1 }, true, false);
|
||||
|
||||
Assert::AreEqual(expected, actual);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user