mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-06-11 12:14:53 +08:00
[FancyZones] Improve code quality (part 4) (#23638)
This commit is contained in:
parent
c94c79a057
commit
92f61d6ef5
@ -28,8 +28,8 @@ void DraggingState::Enable()
|
|||||||
|
|
||||||
void DraggingState::Disable()
|
void DraggingState::Disable()
|
||||||
{
|
{
|
||||||
bool leftShiftPressed = m_leftShiftKeyState.state();
|
const bool leftShiftPressed = m_leftShiftKeyState.state();
|
||||||
bool rightShiftPressed = m_rightShiftKeyState.state();
|
const bool rightShiftPressed = m_rightShiftKeyState.state();
|
||||||
|
|
||||||
if (FancyZonesSettings::settings().shiftDrag)
|
if (FancyZonesSettings::settings().shiftDrag)
|
||||||
{
|
{
|
||||||
@ -80,4 +80,4 @@ bool DraggingState::IsDragging() const noexcept
|
|||||||
bool DraggingState::IsSelectManyZonesState() const noexcept
|
bool DraggingState::IsSelectManyZonesState() const noexcept
|
||||||
{
|
{
|
||||||
return m_ctrlKeyState.state();
|
return m_ctrlKeyState.state();
|
||||||
}
|
}
|
@ -1,14 +1,11 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "FancyZones.h"
|
#include "FancyZones.h"
|
||||||
|
|
||||||
#include <common/display/dpi_aware.h>
|
|
||||||
#include <common/interop/shared_constants.h>
|
#include <common/interop/shared_constants.h>
|
||||||
#include <common/logger/logger.h>
|
#include <common/logger/logger.h>
|
||||||
#include <common/logger/call_tracer.h>
|
#include <common/logger/call_tracer.h>
|
||||||
#include <common/utils/EventWaiter.h>
|
#include <common/utils/EventWaiter.h>
|
||||||
#include <common/utils/resources.h>
|
|
||||||
#include <common/utils/winapi_error.h>
|
#include <common/utils/winapi_error.h>
|
||||||
#include <common/utils/window.h>
|
|
||||||
#include <common/SettingsAPI/FileWatcher.h>
|
#include <common/SettingsAPI/FileWatcher.h>
|
||||||
|
|
||||||
#include <FancyZonesLib/DraggingState.h>
|
#include <FancyZonesLib/DraggingState.h>
|
||||||
@ -24,20 +21,13 @@
|
|||||||
#include <FancyZonesLib/FancyZonesWindowProperties.h>
|
#include <FancyZonesLib/FancyZonesWindowProperties.h>
|
||||||
#include <FancyZonesLib/FancyZonesWinHookEventIDs.h>
|
#include <FancyZonesLib/FancyZonesWinHookEventIDs.h>
|
||||||
#include <FancyZonesLib/MonitorUtils.h>
|
#include <FancyZonesLib/MonitorUtils.h>
|
||||||
|
#include <FancyZonesLib/MonitorWorkAreaHandler.h>
|
||||||
|
#include <FancyZonesLib/on_thread_executor.h>
|
||||||
#include <FancyZonesLib/Settings.h>
|
#include <FancyZonesLib/Settings.h>
|
||||||
#include <FancyZonesLib/SettingsObserver.h>
|
#include <FancyZonesLib/SettingsObserver.h>
|
||||||
|
#include <FancyZonesLib/trace.h>
|
||||||
|
#include <FancyZonesLib/WindowDrag.h>
|
||||||
#include <FancyZonesLib/WorkArea.h>
|
#include <FancyZonesLib/WorkArea.h>
|
||||||
#include <FancyZonesLib/WindowMoveHandler.h>
|
|
||||||
#include <FancyZonesLib/WindowUtils.h>
|
|
||||||
#include <FancyZonesLib/util.h>
|
|
||||||
|
|
||||||
#include "on_thread_executor.h"
|
|
||||||
#include "trace.h"
|
|
||||||
#include "VirtualDesktop.h"
|
|
||||||
#include "MonitorWorkAreaHandler.h"
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
#include <FancyZonesLib/SecondaryMouseButtonsHook.h>
|
|
||||||
|
|
||||||
enum class DisplayChangeType
|
enum class DisplayChangeType
|
||||||
{
|
{
|
||||||
@ -60,7 +50,6 @@ public:
|
|||||||
FancyZones(HINSTANCE hinstance, std::function<void()> disableModuleCallbackFunction) noexcept :
|
FancyZones(HINSTANCE hinstance, std::function<void()> disableModuleCallbackFunction) noexcept :
|
||||||
SettingsObserver({ SettingId::EditorHotkey, SettingId::PrevTabHotkey, SettingId::NextTabHotkey, SettingId::SpanZonesAcrossMonitors }),
|
SettingsObserver({ SettingId::EditorHotkey, SettingId::PrevTabHotkey, SettingId::NextTabHotkey, SettingId::SpanZonesAcrossMonitors }),
|
||||||
m_hinstance(hinstance),
|
m_hinstance(hinstance),
|
||||||
m_windowMoveHandler(),
|
|
||||||
m_draggingState([this]() {
|
m_draggingState([this]() {
|
||||||
PostMessageW(m_window, WM_PRIV_LOCATIONCHANGE, NULL, NULL);
|
PostMessageW(m_window, WM_PRIV_LOCATIONCHANGE, NULL, NULL);
|
||||||
})
|
})
|
||||||
@ -84,36 +73,6 @@ public:
|
|||||||
IFACEMETHODIMP_(void)
|
IFACEMETHODIMP_(void)
|
||||||
Destroy() noexcept;
|
Destroy() noexcept;
|
||||||
|
|
||||||
void MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen) noexcept
|
|
||||||
{
|
|
||||||
if (FancyZonesSettings::settings().spanZonesAcrossMonitors)
|
|
||||||
{
|
|
||||||
monitor = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_draggingState.Enable();
|
|
||||||
m_draggingState.UpdateDraggingState();
|
|
||||||
m_windowMoveHandler.MoveSizeStart(window, monitor, ptScreen, m_workAreaHandler.GetWorkAreasByDesktopId(VirtualDesktop::instance().GetCurrentVirtualDesktopId()), m_draggingState.IsDragging());
|
|
||||||
}
|
|
||||||
|
|
||||||
void MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen) noexcept
|
|
||||||
{
|
|
||||||
if (FancyZonesSettings::settings().spanZonesAcrossMonitors)
|
|
||||||
{
|
|
||||||
monitor = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_draggingState.UpdateDraggingState();
|
|
||||||
m_windowMoveHandler.MoveSizeUpdate(monitor, ptScreen, m_workAreaHandler.GetWorkAreasByDesktopId(VirtualDesktop::instance().GetCurrentVirtualDesktopId()), m_draggingState.IsDragging(), m_draggingState.IsSelectManyZonesState());
|
|
||||||
}
|
|
||||||
|
|
||||||
void MoveSizeEnd(HWND window) noexcept
|
|
||||||
{
|
|
||||||
m_draggingState.UpdateDraggingState();
|
|
||||||
m_windowMoveHandler.MoveSizeEnd(window, m_workAreaHandler.GetWorkAreasByDesktopId(VirtualDesktop::instance().GetCurrentVirtualDesktopId()));
|
|
||||||
m_draggingState.Disable();
|
|
||||||
}
|
|
||||||
|
|
||||||
IFACEMETHODIMP_(void)
|
IFACEMETHODIMP_(void)
|
||||||
HandleWinHookEvent(const WinHookEvent* data) noexcept
|
HandleWinHookEvent(const WinHookEvent* data) noexcept
|
||||||
{
|
{
|
||||||
@ -150,6 +109,10 @@ public:
|
|||||||
IFACEMETHODIMP_(bool)
|
IFACEMETHODIMP_(bool)
|
||||||
OnKeyDown(PKBDLLHOOKSTRUCT info) noexcept;
|
OnKeyDown(PKBDLLHOOKSTRUCT info) noexcept;
|
||||||
|
|
||||||
|
void MoveSizeStart(HWND window, HMONITOR monitor);
|
||||||
|
void MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen);
|
||||||
|
void MoveSizeEnd();
|
||||||
|
|
||||||
void WindowCreated(HWND window) noexcept;
|
void WindowCreated(HWND window) noexcept;
|
||||||
void ToggleEditor() noexcept;
|
void ToggleEditor() noexcept;
|
||||||
|
|
||||||
@ -175,6 +138,7 @@ private:
|
|||||||
std::pair<std::shared_ptr<WorkArea>, ZoneIndexSet> GetAppZoneHistoryInfo(HWND window, HMONITOR monitor, const std::unordered_map<HMONITOR, std::shared_ptr<WorkArea>>& workAreaMap) noexcept;
|
std::pair<std::shared_ptr<WorkArea>, ZoneIndexSet> GetAppZoneHistoryInfo(HWND window, HMONITOR monitor, const std::unordered_map<HMONITOR, std::shared_ptr<WorkArea>>& workAreaMap) noexcept;
|
||||||
void MoveWindowIntoZone(HWND window, std::shared_ptr<WorkArea> workArea, const ZoneIndexSet& zoneIndexSet) noexcept;
|
void MoveWindowIntoZone(HWND window, std::shared_ptr<WorkArea> workArea, const ZoneIndexSet& zoneIndexSet) noexcept;
|
||||||
bool MoveToAppLastZone(HWND window, HMONITOR active, HMONITOR primary) noexcept;
|
bool MoveToAppLastZone(HWND window, HMONITOR active, HMONITOR primary) noexcept;
|
||||||
|
void RefreshWorkAreaWindows(bool updatePositions);
|
||||||
|
|
||||||
void OnEditorExitEvent() noexcept;
|
void OnEditorExitEvent() noexcept;
|
||||||
void UpdateZoneSets() noexcept;
|
void UpdateZoneSets() noexcept;
|
||||||
@ -191,7 +155,7 @@ private:
|
|||||||
const HINSTANCE m_hinstance{};
|
const HINSTANCE m_hinstance{};
|
||||||
|
|
||||||
HWND m_window{};
|
HWND m_window{};
|
||||||
WindowMoveHandler m_windowMoveHandler;
|
std::unique_ptr<WindowDrag> m_windowDrag{};
|
||||||
MonitorWorkAreaHandler m_workAreaHandler;
|
MonitorWorkAreaHandler m_workAreaHandler;
|
||||||
DraggingState m_draggingState;
|
DraggingState m_draggingState;
|
||||||
|
|
||||||
@ -317,6 +281,46 @@ FancyZones::VirtualDesktopChanged() noexcept
|
|||||||
PostMessage(m_window, WM_PRIV_VD_SWITCH, 0, 0);
|
PostMessage(m_window, WM_PRIV_VD_SWITCH, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FancyZones::MoveSizeStart(HWND window, HMONITOR monitor)
|
||||||
|
{
|
||||||
|
m_windowDrag = WindowDrag::Create(window, m_workAreaHandler.GetWorkAreasByDesktopId(VirtualDesktop::instance().GetCurrentVirtualDesktopId()));
|
||||||
|
if (m_windowDrag)
|
||||||
|
{
|
||||||
|
if (FancyZonesSettings::settings().spanZonesAcrossMonitors)
|
||||||
|
{
|
||||||
|
monitor = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_draggingState.Enable();
|
||||||
|
m_draggingState.UpdateDraggingState();
|
||||||
|
m_windowDrag->MoveSizeStart(monitor, m_draggingState.IsDragging());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FancyZones::MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen)
|
||||||
|
{
|
||||||
|
if (m_windowDrag)
|
||||||
|
{
|
||||||
|
if (FancyZonesSettings::settings().spanZonesAcrossMonitors)
|
||||||
|
{
|
||||||
|
monitor = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_draggingState.UpdateDraggingState();
|
||||||
|
m_windowDrag->MoveSizeUpdate(monitor, ptScreen, m_draggingState.IsDragging(), m_draggingState.IsSelectManyZonesState());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FancyZones::MoveSizeEnd()
|
||||||
|
{
|
||||||
|
if (m_windowDrag)
|
||||||
|
{
|
||||||
|
m_windowDrag->MoveSizeEnd();
|
||||||
|
m_draggingState.Disable();
|
||||||
|
m_windowDrag = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::pair<std::shared_ptr<WorkArea>, ZoneIndexSet> FancyZones::GetAppZoneHistoryInfo(HWND window, HMONITOR monitor, const std::unordered_map<HMONITOR, std::shared_ptr<WorkArea>>& workAreaMap) noexcept
|
std::pair<std::shared_ptr<WorkArea>, ZoneIndexSet> FancyZones::GetAppZoneHistoryInfo(HWND window, HMONITOR monitor, const std::unordered_map<HMONITOR, std::shared_ptr<WorkArea>>& workAreaMap) noexcept
|
||||||
{
|
{
|
||||||
if (monitor)
|
if (monitor)
|
||||||
@ -351,8 +355,9 @@ void FancyZones::MoveWindowIntoZone(HWND window, std::shared_ptr<WorkArea> workA
|
|||||||
if (workArea)
|
if (workArea)
|
||||||
{
|
{
|
||||||
Trace::FancyZones::SnapNewWindowIntoZone(workArea->GetLayout().get(), workArea->GetLayoutWindows().get());
|
Trace::FancyZones::SnapNewWindowIntoZone(workArea->GetLayout().get(), workArea->GetLayoutWindows().get());
|
||||||
|
workArea->MoveWindowIntoZoneByIndexSet(window, zoneIndexSet);
|
||||||
}
|
}
|
||||||
m_windowMoveHandler.MoveWindowIntoZoneByIndexSet(window, zoneIndexSet, workArea);
|
|
||||||
AppZoneHistory::instance().UpdateProcessIdToHandleMap(window, workArea->UniqueId());
|
AppZoneHistory::instance().UpdateProcessIdToHandleMap(window, workArea->UniqueId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -395,6 +400,25 @@ bool FancyZones::MoveToAppLastZone(HWND window, HMONITOR active, HMONITOR primar
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FancyZones::RefreshWorkAreaWindows(bool updatePositions)
|
||||||
|
{
|
||||||
|
auto activeWorkAreas = m_workAreaHandler.GetWorkAreasByDesktopId(VirtualDesktop::instance().GetCurrentVirtualDesktopId());
|
||||||
|
for (const auto& window : VirtualDesktop::instance().GetWindowsFromCurrentDesktop())
|
||||||
|
{
|
||||||
|
auto zoneIndexSet = FancyZonesWindowProperties::RetrieveZoneIndexProperty(window);
|
||||||
|
if (zoneIndexSet.size() == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto monitor = MonitorFromWindow(window, MONITOR_DEFAULTTONULL);
|
||||||
|
if (monitor && activeWorkAreas.contains(monitor))
|
||||||
|
{
|
||||||
|
activeWorkAreas.at(monitor)->MoveWindowIntoZoneByIndexSet(window, zoneIndexSet, updatePositions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void FancyZones::WindowCreated(HWND window) noexcept
|
void FancyZones::WindowCreated(HWND window) noexcept
|
||||||
{
|
{
|
||||||
const bool moveToAppLastZone = FancyZonesSettings::settings().appLastZone_moveWindows;
|
const bool moveToAppLastZone = FancyZonesSettings::settings().appLastZone_moveWindows;
|
||||||
@ -637,13 +661,12 @@ LRESULT FancyZones::WndProc(HWND window, UINT message, WPARAM wparam, LPARAM lpa
|
|||||||
auto hwnd = reinterpret_cast<HWND>(wparam);
|
auto hwnd = reinterpret_cast<HWND>(wparam);
|
||||||
if (auto monitor = MonitorFromPoint(ptScreen, MONITOR_DEFAULTTONULL))
|
if (auto monitor = MonitorFromPoint(ptScreen, MONITOR_DEFAULTTONULL))
|
||||||
{
|
{
|
||||||
MoveSizeStart(hwnd, monitor, ptScreen);
|
MoveSizeStart(hwnd, monitor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (message == WM_PRIV_MOVESIZEEND)
|
else if (message == WM_PRIV_MOVESIZEEND)
|
||||||
{
|
{
|
||||||
auto hwnd = reinterpret_cast<HWND>(wparam);
|
MoveSizeEnd();
|
||||||
MoveSizeEnd(hwnd);
|
|
||||||
}
|
}
|
||||||
else if (message == WM_PRIV_LOCATIONCHANGE)
|
else if (message == WM_PRIV_LOCATIONCHANGE)
|
||||||
{
|
{
|
||||||
@ -717,9 +740,7 @@ void FancyZones::OnDisplayChange(DisplayChangeType changeType) noexcept
|
|||||||
}
|
}
|
||||||
|
|
||||||
UpdateWorkAreas();
|
UpdateWorkAreas();
|
||||||
|
RefreshWorkAreaWindows(FancyZonesSettings::settings().displayChange_moveWindows && changeType != DisplayChangeType::VirtualDesktop);
|
||||||
auto activeWorkAreas = m_workAreaHandler.GetWorkAreasByDesktopId(VirtualDesktop::instance().GetCurrentVirtualDesktopId());
|
|
||||||
m_windowMoveHandler.AssignWindowsToZones(activeWorkAreas, FancyZonesSettings::settings().displayChange_moveWindows && changeType != DisplayChangeType::VirtualDesktop);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FancyZones::AddWorkArea(HMONITOR monitor, const FancyZonesDataTypes::WorkAreaId& id) noexcept
|
void FancyZones::AddWorkArea(HMONITOR monitor, const FancyZonesDataTypes::WorkAreaId& id) noexcept
|
||||||
@ -820,7 +841,7 @@ bool FancyZones::OnSnapHotkeyBasedOnZoneNumber(HWND window, DWORD vkCode) noexce
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
auto workArea = m_workAreaHandler.GetWorkArea(VirtualDesktop::instance().GetCurrentVirtualDesktopId(), *currMonitorInfo);
|
auto workArea = m_workAreaHandler.GetWorkArea(VirtualDesktop::instance().GetCurrentVirtualDesktopId(), *currMonitorInfo);
|
||||||
if (m_windowMoveHandler.MoveWindowIntoZoneByDirectionAndIndex(window, vkCode, false /* cycle through zones */, workArea))
|
if (workArea && workArea->MoveWindowIntoZoneByDirectionAndIndex(window, vkCode, false /* cycle through zones */))
|
||||||
{
|
{
|
||||||
// unassign from previous work area
|
// unassign from previous work area
|
||||||
for (auto& prevWorkArea : m_workAreaHandler.GetAllWorkAreas())
|
for (auto& prevWorkArea : m_workAreaHandler.GetAllWorkAreas())
|
||||||
@ -859,13 +880,13 @@ bool FancyZones::OnSnapHotkeyBasedOnZoneNumber(HWND window, DWORD vkCode) noexce
|
|||||||
// Single monitor environment, or combined multi-monitor environment.
|
// Single monitor environment, or combined multi-monitor environment.
|
||||||
if (FancyZonesSettings::settings().restoreSize)
|
if (FancyZonesSettings::settings().restoreSize)
|
||||||
{
|
{
|
||||||
bool moved = m_windowMoveHandler.MoveWindowIntoZoneByDirectionAndIndex(window, vkCode, false /* cycle through zones */, workArea);
|
bool moved = workArea && workArea->MoveWindowIntoZoneByDirectionAndIndex(window, vkCode, false /* cycle through zones */);
|
||||||
if (!moved)
|
if (!moved)
|
||||||
{
|
{
|
||||||
FancyZonesWindowUtils::RestoreWindowOrigin(window);
|
FancyZonesWindowUtils::RestoreWindowOrigin(window);
|
||||||
FancyZonesWindowUtils::RestoreWindowSize(window);
|
FancyZonesWindowUtils::RestoreWindowSize(window);
|
||||||
}
|
}
|
||||||
else
|
else if (workArea)
|
||||||
{
|
{
|
||||||
Trace::FancyZones::KeyboardSnapWindowToZone(workArea->GetLayout().get(), workArea->GetLayoutWindows().get());
|
Trace::FancyZones::KeyboardSnapWindowToZone(workArea->GetLayout().get(), workArea->GetLayoutWindows().get());
|
||||||
}
|
}
|
||||||
@ -873,11 +894,13 @@ bool FancyZones::OnSnapHotkeyBasedOnZoneNumber(HWND window, DWORD vkCode) noexce
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool moved = m_windowMoveHandler.MoveWindowIntoZoneByDirectionAndIndex(window, vkCode, true /* cycle through zones */, workArea);
|
bool moved = workArea && workArea->MoveWindowIntoZoneByDirectionAndIndex(window, vkCode, true /* cycle through zones */);
|
||||||
|
|
||||||
if (moved)
|
if (moved)
|
||||||
{
|
{
|
||||||
Trace::FancyZones::KeyboardSnapWindowToZone(workArea->GetLayout().get(), workArea->GetLayoutWindows().get());
|
Trace::FancyZones::KeyboardSnapWindowToZone(workArea->GetLayout().get(), workArea->GetLayoutWindows().get());
|
||||||
}
|
}
|
||||||
|
|
||||||
return moved;
|
return moved;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -951,7 +974,11 @@ bool FancyZones::OnSnapHotkeyBasedOnPosition(HWND window, DWORD vkCode) noexcept
|
|||||||
{
|
{
|
||||||
// Moving to another monitor succeeded
|
// Moving to another monitor succeeded
|
||||||
const auto& [trueZoneIdx, workArea] = zoneRectsInfo[chosenIdx];
|
const auto& [trueZoneIdx, workArea] = zoneRectsInfo[chosenIdx];
|
||||||
m_windowMoveHandler.MoveWindowIntoZoneByIndexSet(window, { trueZoneIdx }, workArea);
|
if (workArea)
|
||||||
|
{
|
||||||
|
workArea->MoveWindowIntoZoneByIndexSet(window, { trueZoneIdx });
|
||||||
|
}
|
||||||
|
|
||||||
Trace::FancyZones::KeyboardSnapWindowToZone(workArea->GetLayout().get(), workArea->GetLayoutWindows().get());
|
Trace::FancyZones::KeyboardSnapWindowToZone(workArea->GetLayout().get(), workArea->GetLayoutWindows().get());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -996,7 +1023,12 @@ bool FancyZones::OnSnapHotkeyBasedOnPosition(HWND window, DWORD vkCode) noexcept
|
|||||||
{
|
{
|
||||||
// Moving to another monitor succeeded
|
// Moving to another monitor succeeded
|
||||||
const auto& [trueZoneIdx, workArea] = zoneRectsInfo[chosenIdx];
|
const auto& [trueZoneIdx, workArea] = zoneRectsInfo[chosenIdx];
|
||||||
m_windowMoveHandler.MoveWindowIntoZoneByIndexSet(window, { trueZoneIdx }, workArea);
|
|
||||||
|
if (workArea)
|
||||||
|
{
|
||||||
|
workArea->MoveWindowIntoZoneByIndexSet(window, { trueZoneIdx });
|
||||||
|
}
|
||||||
|
|
||||||
Trace::FancyZones::KeyboardSnapWindowToZone(workArea->GetLayout().get(), workArea->GetLayoutWindows().get());
|
Trace::FancyZones::KeyboardSnapWindowToZone(workArea->GetLayout().get(), workArea->GetLayoutWindows().get());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1030,7 +1062,7 @@ bool FancyZones::ProcessDirectedSnapHotkey(HWND window, DWORD vkCode, bool cycle
|
|||||||
// Check whether Alt is used in the shortcut key combination
|
// Check whether Alt is used in the shortcut key combination
|
||||||
if (GetAsyncKeyState(VK_MENU) & 0x8000)
|
if (GetAsyncKeyState(VK_MENU) & 0x8000)
|
||||||
{
|
{
|
||||||
bool result = m_windowMoveHandler.ExtendWindowByDirectionAndPosition(window, vkCode, workArea);
|
bool result = workArea && workArea->ExtendWindowByDirectionAndPosition(window, vkCode);
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
Trace::FancyZones::KeyboardSnapWindowToZone(workArea->GetLayout().get(), workArea->GetLayoutWindows().get());
|
Trace::FancyZones::KeyboardSnapWindowToZone(workArea->GetLayout().get(), workArea->GetLayoutWindows().get());
|
||||||
@ -1039,7 +1071,7 @@ bool FancyZones::ProcessDirectedSnapHotkey(HWND window, DWORD vkCode, bool cycle
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool result = m_windowMoveHandler.MoveWindowIntoZoneByDirectionAndPosition(window, vkCode, cycle, workArea);
|
bool result = workArea && workArea->MoveWindowIntoZoneByDirectionAndPosition(window, vkCode, cycle);
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
Trace::FancyZones::KeyboardSnapWindowToZone(workArea->GetLayout().get(), workArea->GetLayoutWindows().get());
|
Trace::FancyZones::KeyboardSnapWindowToZone(workArea->GetLayout().get(), workArea->GetLayoutWindows().get());
|
||||||
@ -1129,11 +1161,7 @@ void FancyZones::UpdateZoneSets() noexcept
|
|||||||
workArea->UpdateActiveZoneSet();
|
workArea->UpdateActiveZoneSet();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FancyZonesSettings::settings().zoneSetChange_moveWindows)
|
RefreshWorkAreaWindows(FancyZonesSettings::settings().zoneSetChange_moveWindows);
|
||||||
{
|
|
||||||
auto activeWorkAreas = m_workAreaHandler.GetWorkAreasByDesktopId(VirtualDesktop::instance().GetCurrentVirtualDesktopId());
|
|
||||||
m_windowMoveHandler.AssignWindowsToZones(activeWorkAreas, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FancyZones::ShouldProcessSnapHotkey(DWORD vkCode) noexcept
|
bool FancyZones::ShouldProcessSnapHotkey(DWORD vkCode) noexcept
|
||||||
|
@ -71,7 +71,7 @@
|
|||||||
<ClInclude Include="trace.h" />
|
<ClInclude Include="trace.h" />
|
||||||
<ClInclude Include="util.h" />
|
<ClInclude Include="util.h" />
|
||||||
<ClInclude Include="VirtualDesktop.h" />
|
<ClInclude Include="VirtualDesktop.h" />
|
||||||
<ClInclude Include="WindowMoveHandler.h" />
|
<ClInclude Include="WindowDrag.h" />
|
||||||
<ClInclude Include="FancyZonesWindowProperties.h" />
|
<ClInclude Include="FancyZonesWindowProperties.h" />
|
||||||
<ClInclude Include="WindowUtils.h" />
|
<ClInclude Include="WindowUtils.h" />
|
||||||
<ClInclude Include="Zone.h" />
|
<ClInclude Include="Zone.h" />
|
||||||
@ -123,7 +123,7 @@
|
|||||||
<ClCompile Include="trace.cpp" />
|
<ClCompile Include="trace.cpp" />
|
||||||
<ClCompile Include="util.cpp" />
|
<ClCompile Include="util.cpp" />
|
||||||
<ClCompile Include="VirtualDesktop.cpp" />
|
<ClCompile Include="VirtualDesktop.cpp" />
|
||||||
<ClCompile Include="WindowMoveHandler.cpp" />
|
<ClCompile Include="WindowDrag.cpp" />
|
||||||
<ClCompile Include="WindowUtils.cpp" />
|
<ClCompile Include="WindowUtils.cpp" />
|
||||||
<ClCompile Include="Zone.cpp" />
|
<ClCompile Include="Zone.cpp" />
|
||||||
<ClCompile Include="WorkArea.cpp" />
|
<ClCompile Include="WorkArea.cpp" />
|
||||||
|
@ -48,9 +48,6 @@
|
|||||||
<ClInclude Include="VirtualDesktop.h">
|
<ClInclude Include="VirtualDesktop.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="WindowMoveHandler.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="FancyZonesWinHookEventIDs.h">
|
<ClInclude Include="FancyZonesWinHookEventIDs.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@ -165,6 +162,9 @@
|
|||||||
<ClInclude Include="DraggingState.h">
|
<ClInclude Include="DraggingState.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="WindowDrag.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="pch.cpp">
|
<ClCompile Include="pch.cpp">
|
||||||
@ -191,9 +191,6 @@
|
|||||||
<ClCompile Include="VirtualDesktop.cpp">
|
<ClCompile Include="VirtualDesktop.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="WindowMoveHandler.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="FancyZonesWinHookEventIDs.cpp">
|
<ClCompile Include="FancyZonesWinHookEventIDs.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -266,6 +263,9 @@
|
|||||||
<ClCompile Include="DraggingState.cpp">
|
<ClCompile Include="DraggingState.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="WindowDrag.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include <FancyZonesLib/Layout.h>
|
#include <FancyZonesLib/Layout.h>
|
||||||
|
|
||||||
HighlightedZones::HighlightedZones()
|
HighlightedZones::HighlightedZones() noexcept
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ class Layout;
|
|||||||
class HighlightedZones
|
class HighlightedZones
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HighlightedZones();
|
HighlightedZones() noexcept;
|
||||||
~HighlightedZones() = default;
|
~HighlightedZones() = default;
|
||||||
|
|
||||||
const ZoneIndexSet& Zones() const noexcept;
|
const ZoneIndexSet& Zones() const noexcept;
|
||||||
|
245
src/modules/fancyzones/FancyZonesLib/WindowDrag.cpp
Normal file
245
src/modules/fancyzones/FancyZonesLib/WindowDrag.cpp
Normal file
@ -0,0 +1,245 @@
|
|||||||
|
#include "pch.h"
|
||||||
|
#include "WindowDrag.h"
|
||||||
|
|
||||||
|
#include <FancyZonesLib/FancyZonesData/AppZoneHistory.h>
|
||||||
|
#include <FancyZonesLib/FancyZonesWindowProcessing.h>
|
||||||
|
#include <FancyZonesLib/FancyZonesWindowProperties.h>
|
||||||
|
#include <FancyZonesLib/NotificationUtil.h>
|
||||||
|
#include <FancyZonesLib/Settings.h>
|
||||||
|
#include <FancyZonesLib/WindowUtils.h>
|
||||||
|
#include <FancyZonesLib/WorkArea.h>
|
||||||
|
|
||||||
|
#include <FancyZonesLib/trace.h>
|
||||||
|
|
||||||
|
#include <common/utils/elevation.h>
|
||||||
|
|
||||||
|
WindowDrag::WindowDrag(HWND window, const std::unordered_map<HMONITOR, std::shared_ptr<WorkArea>>& activeWorkAreas) :
|
||||||
|
m_window(window),
|
||||||
|
m_activeWorkAreas(activeWorkAreas),
|
||||||
|
m_snappingMode(false)
|
||||||
|
{
|
||||||
|
m_windowProperties.hasNoVisibleOwner = !FancyZonesWindowUtils::HasVisibleOwner(m_window);
|
||||||
|
m_windowProperties.isStandardWindow = FancyZonesWindowUtils::IsStandardWindow(m_window) &&
|
||||||
|
(!FancyZonesWindowUtils::IsPopupWindow(m_window) || FancyZonesSettings::settings().allowSnapPopupWindows);
|
||||||
|
}
|
||||||
|
|
||||||
|
WindowDrag::~WindowDrag()
|
||||||
|
{
|
||||||
|
ResetWindowTransparency();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<WindowDrag> WindowDrag::Create(HWND window, const std::unordered_map<HMONITOR, std::shared_ptr<WorkArea>>& activeWorkAreas)
|
||||||
|
{
|
||||||
|
if (!FancyZonesWindowProcessing::IsProcessable(window) ||
|
||||||
|
!FancyZonesWindowUtils::IsCandidateForZoning(window) ||
|
||||||
|
FancyZonesWindowUtils::IsCursorTypeIndicatingSizeEvent())
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_process_elevated() && FancyZonesWindowUtils::IsProcessOfWindowElevated(window))
|
||||||
|
{
|
||||||
|
// Notifies user if unable to drag elevated window
|
||||||
|
FancyZonesNotifications::WarnIfElevationIsRequired();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::unique_ptr<WindowDrag>(new WindowDrag(window, activeWorkAreas));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WindowDrag::MoveSizeStart(HMONITOR monitor, bool isSnapping)
|
||||||
|
{
|
||||||
|
auto iter = m_activeWorkAreas.find(monitor);
|
||||||
|
if (iter == end(m_activeWorkAreas))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isSnapping)
|
||||||
|
{
|
||||||
|
m_currentWorkArea = iter->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
SwitchSnappingMode(isSnapping);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowDrag::MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, bool isSnapping, bool isSelectManyZonesState)
|
||||||
|
{
|
||||||
|
auto iter = m_activeWorkAreas.find(monitor);
|
||||||
|
if (isSnapping && iter != m_activeWorkAreas.end())
|
||||||
|
{
|
||||||
|
// The drag has moved to a different monitor.
|
||||||
|
// Change work area
|
||||||
|
if (iter->second != m_currentWorkArea)
|
||||||
|
{
|
||||||
|
m_highlightedZones.Reset();
|
||||||
|
|
||||||
|
if (m_currentWorkArea)
|
||||||
|
{
|
||||||
|
if (!FancyZonesSettings::settings().showZonesOnAllMonitors)
|
||||||
|
{
|
||||||
|
m_currentWorkArea->HideZonesOverlay();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_currentWorkArea->ShowZonesOverlay({}, m_window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_currentWorkArea = iter->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_currentWorkArea)
|
||||||
|
{
|
||||||
|
POINT ptClient = ptScreen;
|
||||||
|
MapWindowPoints(nullptr, m_currentWorkArea->GetWorkAreaWindow(), &ptClient, 1);
|
||||||
|
const bool redraw = m_highlightedZones.Update(m_currentWorkArea->GetLayout().get(), ptClient, isSelectManyZonesState);
|
||||||
|
if (redraw)
|
||||||
|
{
|
||||||
|
m_currentWorkArea->ShowZonesOverlay(m_highlightedZones.Zones(), m_window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SwitchSnappingMode(isSnapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowDrag::MoveSizeEnd()
|
||||||
|
{
|
||||||
|
if (m_snappingMode)
|
||||||
|
{
|
||||||
|
const bool hasNoVisibleOwner = !FancyZonesWindowUtils::HasVisibleOwner(m_window);
|
||||||
|
const bool isStandardWindow = FancyZonesWindowUtils::IsStandardWindow(m_window);
|
||||||
|
|
||||||
|
if ((isStandardWindow == false && hasNoVisibleOwner == true &&
|
||||||
|
m_windowProperties.isStandardWindow == true && m_windowProperties.hasNoVisibleOwner == true) ||
|
||||||
|
FancyZonesWindowUtils::IsWindowMaximized(m_window))
|
||||||
|
{
|
||||||
|
// Abort the zoning, this is a Chromium based tab that is merged back with an existing window
|
||||||
|
// or if the window is maximized by Windows when the cursor hits the screen top border
|
||||||
|
}
|
||||||
|
else if (m_currentWorkArea)
|
||||||
|
{
|
||||||
|
m_currentWorkArea->MoveWindowIntoZoneByIndexSet(m_window, m_highlightedZones.Zones());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FancyZonesWindowUtils::ResetRoundCornersPreference(m_window);
|
||||||
|
if (FancyZonesSettings::settings().restoreSize)
|
||||||
|
{
|
||||||
|
if (FancyZonesWindowUtils::IsCursorTypeIndicatingSizeEvent())
|
||||||
|
{
|
||||||
|
::RemoveProp(m_window, ZonedWindowProperties::PropertyRestoreSizeID);
|
||||||
|
}
|
||||||
|
else if (!FancyZonesWindowUtils::IsWindowMaximized(m_window))
|
||||||
|
{
|
||||||
|
FancyZonesWindowUtils::RestoreWindowSize(m_window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SwitchSnappingMode(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowDrag::SwitchSnappingMode(bool isSnapping)
|
||||||
|
{
|
||||||
|
if (!m_snappingMode && isSnapping) // turn on
|
||||||
|
{
|
||||||
|
m_highlightedZones.Reset();
|
||||||
|
SetWindowTransparency();
|
||||||
|
|
||||||
|
if (FancyZonesSettings::settings().showZonesOnAllMonitors)
|
||||||
|
{
|
||||||
|
for (const auto& [_, workArea] : m_activeWorkAreas)
|
||||||
|
{
|
||||||
|
if (workArea)
|
||||||
|
{
|
||||||
|
workArea->ShowZonesOverlay({}, m_window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_currentWorkArea)
|
||||||
|
{
|
||||||
|
m_currentWorkArea->ShowZonesOverlay({}, m_window);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_currentWorkArea)
|
||||||
|
{
|
||||||
|
m_currentWorkArea->UnsnapWindow(m_window);
|
||||||
|
FancyZonesWindowProperties::RemoveZoneIndexProperty(m_window);
|
||||||
|
|
||||||
|
const auto& layout = m_currentWorkArea->GetLayout();
|
||||||
|
if (layout)
|
||||||
|
{
|
||||||
|
auto guidStr = FancyZonesUtils::GuidToString(layout->Id());
|
||||||
|
if (guidStr.has_value())
|
||||||
|
{
|
||||||
|
AppZoneHistory::instance().RemoveAppLastZone(m_window, m_currentWorkArea->UniqueId(), guidStr.value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Trace::WorkArea::MoveOrResizeStarted(m_currentWorkArea->GetLayout().get(), m_currentWorkArea->GetLayoutWindows().get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_snappingMode && !isSnapping) // turn off
|
||||||
|
{
|
||||||
|
ResetWindowTransparency();
|
||||||
|
m_highlightedZones.Reset();
|
||||||
|
|
||||||
|
// Hide all layouts (regardless of settings)
|
||||||
|
for (auto& [_, workArea] : m_activeWorkAreas)
|
||||||
|
{
|
||||||
|
if (workArea)
|
||||||
|
{
|
||||||
|
workArea->HideZonesOverlay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_currentWorkArea)
|
||||||
|
{
|
||||||
|
Trace::WorkArea::MoveOrResizeEnd(m_currentWorkArea->GetLayout().get(), m_currentWorkArea->GetLayoutWindows().get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_snappingMode = isSnapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowDrag::SetWindowTransparency()
|
||||||
|
{
|
||||||
|
if (FancyZonesSettings::settings().makeDraggedWindowTransparent)
|
||||||
|
{
|
||||||
|
m_windowProperties.exstyle = GetWindowLong(m_window, GWL_EXSTYLE);
|
||||||
|
|
||||||
|
SetWindowLong(m_window, GWL_EXSTYLE, m_windowProperties.exstyle | WS_EX_LAYERED);
|
||||||
|
|
||||||
|
if (!GetLayeredWindowAttributes(m_window, &m_windowProperties.crKey, &m_windowProperties.alpha, &m_windowProperties.dwFlags))
|
||||||
|
{
|
||||||
|
Logger::error(L"Window transparency: GetLayeredWindowAttributes failed, {}", get_last_error_or_default(GetLastError()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SetLayeredWindowAttributes(m_window, 0, (255 * 50) / 100, LWA_ALPHA))
|
||||||
|
{
|
||||||
|
Logger::error(L"Window transparency: SetLayeredWindowAttributes failed, {}", get_last_error_or_default(GetLastError()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowDrag::ResetWindowTransparency()
|
||||||
|
{
|
||||||
|
if (FancyZonesSettings::settings().makeDraggedWindowTransparent)
|
||||||
|
{
|
||||||
|
if (!SetLayeredWindowAttributes(m_window, m_windowProperties.crKey, m_windowProperties.alpha, m_windowProperties.dwFlags))
|
||||||
|
{
|
||||||
|
Logger::error(L"Window transparency: SetLayeredWindowAttributes failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SetWindowLong(m_window, GWL_EXSTYLE, m_windowProperties.exstyle) == 0)
|
||||||
|
{
|
||||||
|
Logger::error(L"Window transparency: SetWindowLong failed, {}", get_last_error_or_default(GetLastError()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
47
src/modules/fancyzones/FancyZonesLib/WindowDrag.h
Normal file
47
src/modules/fancyzones/FancyZonesLib/WindowDrag.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <FancyZonesLib/HighlightedZones.h>
|
||||||
|
|
||||||
|
class WorkArea;
|
||||||
|
|
||||||
|
class WindowDrag
|
||||||
|
{
|
||||||
|
WindowDrag(HWND window, const std::unordered_map<HMONITOR, std::shared_ptr<WorkArea>>& activeWorkAreas);
|
||||||
|
|
||||||
|
public:
|
||||||
|
static std::unique_ptr<WindowDrag> Create(HWND window, const std::unordered_map<HMONITOR, std::shared_ptr<WorkArea>>& activeWorkAreas);
|
||||||
|
~WindowDrag();
|
||||||
|
|
||||||
|
bool MoveSizeStart(HMONITOR monitor, bool isSnapping);
|
||||||
|
void MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, bool isSnapping, bool isSelectManyZonesState);
|
||||||
|
void MoveSizeEnd();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void SwitchSnappingMode(bool isSnapping);
|
||||||
|
|
||||||
|
void SetWindowTransparency();
|
||||||
|
void ResetWindowTransparency();
|
||||||
|
|
||||||
|
struct WindowProperties
|
||||||
|
{
|
||||||
|
// True if from the styles the window looks like a standard window
|
||||||
|
bool isStandardWindow = false;
|
||||||
|
// True if the window is a top-level window that does not have a visible owner
|
||||||
|
bool hasNoVisibleOwner = false;
|
||||||
|
// Properties to restore after dragging
|
||||||
|
long exstyle = 0;
|
||||||
|
COLORREF crKey = RGB(0, 0, 0);
|
||||||
|
DWORD dwFlags = 0;
|
||||||
|
BYTE alpha = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
const HWND m_window;
|
||||||
|
WindowProperties m_windowProperties; // MoveSizeWindowInfo of the window at the moment when dragging started
|
||||||
|
|
||||||
|
const std::unordered_map<HMONITOR, std::shared_ptr<WorkArea>>& m_activeWorkAreas; // all WorkAreas on current virtual desktop, mapped with monitors
|
||||||
|
std::shared_ptr<WorkArea> m_currentWorkArea; // "Active" WorkArea, where the move/size is happening. Will update as drag moves between monitors.
|
||||||
|
|
||||||
|
bool m_snappingMode{ false };
|
||||||
|
|
||||||
|
HighlightedZones m_highlightedZones;
|
||||||
|
};
|
@ -1,317 +0,0 @@
|
|||||||
#include "pch.h"
|
|
||||||
#include "WindowMoveHandler.h"
|
|
||||||
|
|
||||||
#include <common/display/dpi_aware.h>
|
|
||||||
#include <common/logger/logger.h>
|
|
||||||
#include <common/utils/elevation.h>
|
|
||||||
#include <common/utils/winapi_error.h>
|
|
||||||
|
|
||||||
#include "FancyZonesData/AppZoneHistory.h"
|
|
||||||
#include "Settings.h"
|
|
||||||
#include "WorkArea.h"
|
|
||||||
#include <FancyZonesLib/FancyZonesWindowProcessing.h>
|
|
||||||
#include <FancyZonesLib/NotificationUtil.h>
|
|
||||||
#include <FancyZonesLib/WindowUtils.h>
|
|
||||||
|
|
||||||
|
|
||||||
WindowMoveHandler::WindowMoveHandler()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void WindowMoveHandler::MoveSizeStart(HWND window, HMONITOR monitor, POINT const& /*ptScreen*/, const std::unordered_map<HMONITOR, std::shared_ptr<WorkArea>>& workAreaMap, bool dragEnabled) noexcept
|
|
||||||
{
|
|
||||||
if (!FancyZonesWindowProcessing::IsProcessable(window))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!FancyZonesWindowUtils::IsCandidateForZoning(window) || FancyZonesWindowUtils::IsCursorTypeIndicatingSizeEvent())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_draggedWindowInfo.hasNoVisibleOwner = !FancyZonesWindowUtils::HasVisibleOwner(window);
|
|
||||||
m_draggedWindowInfo.isStandardWindow = FancyZonesWindowUtils::IsStandardWindow(window) && (!FancyZonesWindowUtils::IsPopupWindow(window) || FancyZonesSettings::settings().allowSnapPopupWindows);
|
|
||||||
m_inDragging = true;
|
|
||||||
|
|
||||||
auto iter = workAreaMap.find(monitor);
|
|
||||||
if (iter == end(workAreaMap))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_draggedWindow = window;
|
|
||||||
|
|
||||||
if (!is_process_elevated() && FancyZonesWindowUtils::IsProcessOfWindowElevated(window))
|
|
||||||
{
|
|
||||||
// Notifies user if unable to drag elevated window
|
|
||||||
FancyZonesNotifications::WarnIfElevationIsRequired();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dragEnabled)
|
|
||||||
{
|
|
||||||
m_draggedWindowWorkArea = iter->second;
|
|
||||||
SetWindowTransparency(m_draggedWindow);
|
|
||||||
m_draggedWindowWorkArea->MoveSizeEnter(m_draggedWindow);
|
|
||||||
if (FancyZonesSettings::settings().showZonesOnAllMonitors)
|
|
||||||
{
|
|
||||||
for (const auto& [keyMonitor, workArea] : workAreaMap)
|
|
||||||
{
|
|
||||||
// Skip calling ShowZonesOverlay for iter->second (m_draggedWindowWorkArea) since it
|
|
||||||
// was already called in MoveSizeEnter
|
|
||||||
const bool moveSizeEnterCalled = workArea == m_draggedWindowWorkArea;
|
|
||||||
if (workArea && !moveSizeEnterCalled)
|
|
||||||
{
|
|
||||||
workArea->ShowZonesOverlay();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (m_draggedWindowWorkArea)
|
|
||||||
{
|
|
||||||
ResetWindowTransparency();
|
|
||||||
m_draggedWindowWorkArea = nullptr;
|
|
||||||
for (const auto& [keyMonitor, workArea] : workAreaMap)
|
|
||||||
{
|
|
||||||
if (workArea)
|
|
||||||
{
|
|
||||||
workArea->HideZonesOverlay();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto workArea = workAreaMap.find(monitor);
|
|
||||||
if (workArea != workAreaMap.end())
|
|
||||||
{
|
|
||||||
workArea->second->UnsnapWindow(window);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WindowMoveHandler::MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, std::shared_ptr<WorkArea>>& workAreaMap, bool dragEnabled, bool multipleZones) noexcept
|
|
||||||
{
|
|
||||||
if (!m_inDragging)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_draggedWindowWorkArea)
|
|
||||||
{
|
|
||||||
// Update the WorkArea already handling move/size
|
|
||||||
if (!dragEnabled)
|
|
||||||
{
|
|
||||||
// Drag got disabled, tell it to cancel and hide all windows
|
|
||||||
m_draggedWindowWorkArea = nullptr;
|
|
||||||
ResetWindowTransparency();
|
|
||||||
|
|
||||||
for (auto [keyMonitor, workArea] : workAreaMap)
|
|
||||||
{
|
|
||||||
if (workArea)
|
|
||||||
{
|
|
||||||
workArea->HideZonesOverlay();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto iter = workAreaMap.find(monitor);
|
|
||||||
if (iter != workAreaMap.end())
|
|
||||||
{
|
|
||||||
if (iter->second != m_draggedWindowWorkArea)
|
|
||||||
{
|
|
||||||
// The drag has moved to a different monitor.
|
|
||||||
m_draggedWindowWorkArea->ClearSelectedZones();
|
|
||||||
if (!FancyZonesSettings::settings().showZonesOnAllMonitors)
|
|
||||||
{
|
|
||||||
m_draggedWindowWorkArea->HideZonesOverlay();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_draggedWindowWorkArea = iter->second;
|
|
||||||
m_draggedWindowWorkArea->MoveSizeEnter(m_draggedWindow);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto [keyMonitor, workArea] : workAreaMap)
|
|
||||||
{
|
|
||||||
workArea->MoveSizeUpdate(ptScreen, dragEnabled, multipleZones);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (dragEnabled)
|
|
||||||
{
|
|
||||||
// We'll get here if the user presses/releases shift while dragging.
|
|
||||||
// Restart the drag on the WorkArea that m_draggedWindow is on
|
|
||||||
MoveSizeStart(m_draggedWindow, monitor, ptScreen, workAreaMap, dragEnabled);
|
|
||||||
|
|
||||||
// m_dragEnabled could get set to false if we're moving an elevated window.
|
|
||||||
// In that case do not proceed.
|
|
||||||
if (dragEnabled)
|
|
||||||
{
|
|
||||||
MoveSizeUpdate(monitor, ptScreen, workAreaMap, dragEnabled, multipleZones);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WindowMoveHandler::MoveSizeEnd(HWND window, const std::unordered_map<HMONITOR, std::shared_ptr<WorkArea>>& workAreaMap) noexcept
|
|
||||||
{
|
|
||||||
if (window != m_draggedWindow)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_draggedWindowWorkArea)
|
|
||||||
{
|
|
||||||
auto workArea = std::move(m_draggedWindowWorkArea);
|
|
||||||
ResetWindowTransparency();
|
|
||||||
|
|
||||||
bool hasNoVisibleOwner = !FancyZonesWindowUtils::HasVisibleOwner(window);
|
|
||||||
bool isStandardWindow = FancyZonesWindowUtils::IsStandardWindow(window);
|
|
||||||
|
|
||||||
if ((isStandardWindow == false && hasNoVisibleOwner == true &&
|
|
||||||
m_draggedWindowInfo.isStandardWindow == true && m_draggedWindowInfo.hasNoVisibleOwner == true) ||
|
|
||||||
FancyZonesWindowUtils::IsWindowMaximized(window))
|
|
||||||
{
|
|
||||||
// Abort the zoning, this is a Chromium based tab that is merged back with an existing window
|
|
||||||
// or if the window is maximized by Windows when the cursor hits the screen top border
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
workArea->MoveSizeEnd(m_draggedWindow);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (FancyZonesSettings::settings().restoreSize)
|
|
||||||
{
|
|
||||||
if (FancyZonesWindowUtils::IsCursorTypeIndicatingSizeEvent())
|
|
||||||
{
|
|
||||||
::RemoveProp(window, ZonedWindowProperties::PropertyRestoreSizeID);
|
|
||||||
}
|
|
||||||
else if (!FancyZonesWindowUtils::IsWindowMaximized(window))
|
|
||||||
{
|
|
||||||
FancyZonesWindowUtils::RestoreWindowSize(window);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FancyZonesWindowUtils::ResetRoundCornersPreference(window);
|
|
||||||
|
|
||||||
auto monitor = MonitorFromWindow(window, MONITOR_DEFAULTTONULL);
|
|
||||||
if (monitor)
|
|
||||||
{
|
|
||||||
auto workArea = workAreaMap.find(monitor);
|
|
||||||
if (workArea != workAreaMap.end())
|
|
||||||
{
|
|
||||||
const auto workAreaPtr = workArea->second;
|
|
||||||
const auto& layout = workAreaPtr->GetLayout();
|
|
||||||
if (layout)
|
|
||||||
{
|
|
||||||
auto guidStr = FancyZonesUtils::GuidToString(layout->Id());
|
|
||||||
if (guidStr.has_value())
|
|
||||||
{
|
|
||||||
AppZoneHistory::instance().RemoveAppLastZone(window, workAreaPtr->UniqueId(), guidStr.value());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
workAreaPtr->UnsnapWindow(window);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FancyZonesWindowProperties::RemoveZoneIndexProperty(window);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_inDragging = false;
|
|
||||||
m_draggedWindow = nullptr;
|
|
||||||
|
|
||||||
// Also, hide all windows (regardless of settings)
|
|
||||||
for (auto [keyMonitor, workArea] : workAreaMap)
|
|
||||||
{
|
|
||||||
if (workArea)
|
|
||||||
{
|
|
||||||
workArea->HideZonesOverlay();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WindowMoveHandler::MoveWindowIntoZoneByIndexSet(HWND window, const ZoneIndexSet& indexSet, std::shared_ptr<WorkArea> workArea) noexcept
|
|
||||||
{
|
|
||||||
if (window != m_draggedWindow)
|
|
||||||
{
|
|
||||||
workArea->MoveWindowIntoZoneByIndexSet(window, indexSet);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WindowMoveHandler::MoveWindowIntoZoneByDirectionAndIndex(HWND window, DWORD vkCode, bool cycle, std::shared_ptr<WorkArea> workArea) noexcept
|
|
||||||
{
|
|
||||||
return workArea && workArea->MoveWindowIntoZoneByDirectionAndIndex(window, vkCode, cycle);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WindowMoveHandler::MoveWindowIntoZoneByDirectionAndPosition(HWND window, DWORD vkCode, bool cycle, std::shared_ptr<WorkArea> workArea) noexcept
|
|
||||||
{
|
|
||||||
return workArea && workArea->MoveWindowIntoZoneByDirectionAndPosition(window, vkCode, cycle);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WindowMoveHandler::ExtendWindowByDirectionAndPosition(HWND window, DWORD vkCode, std::shared_ptr<WorkArea> workArea) noexcept
|
|
||||||
{
|
|
||||||
return workArea && workArea->ExtendWindowByDirectionAndPosition(window, vkCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WindowMoveHandler::AssignWindowsToZones(const std::unordered_map<HMONITOR, std::shared_ptr<WorkArea>>& activeWorkAreas, bool updatePositions) noexcept
|
|
||||||
{
|
|
||||||
for (const auto& window : VirtualDesktop::instance().GetWindowsFromCurrentDesktop())
|
|
||||||
{
|
|
||||||
auto zoneIndexSet = FancyZonesWindowProperties::RetrieveZoneIndexProperty(window);
|
|
||||||
if (zoneIndexSet.size() == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto monitor = MonitorFromWindow(window, MONITOR_DEFAULTTONULL);
|
|
||||||
if (monitor && activeWorkAreas.contains(monitor))
|
|
||||||
{
|
|
||||||
activeWorkAreas.at(monitor)->MoveWindowIntoZoneByIndexSet(window, zoneIndexSet, updatePositions);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void WindowMoveHandler::SetWindowTransparency(HWND window) noexcept
|
|
||||||
{
|
|
||||||
if (FancyZonesSettings::settings().makeDraggedWindowTransparent)
|
|
||||||
{
|
|
||||||
m_windowTransparencyProperties.draggedWindowExstyle = GetWindowLong(window, GWL_EXSTYLE);
|
|
||||||
|
|
||||||
SetWindowLong(window,
|
|
||||||
GWL_EXSTYLE,
|
|
||||||
m_windowTransparencyProperties.draggedWindowExstyle | WS_EX_LAYERED);
|
|
||||||
|
|
||||||
if (!GetLayeredWindowAttributes(window, &m_windowTransparencyProperties.draggedWindowCrKey, &m_windowTransparencyProperties.draggedWindowInitialAlpha, &m_windowTransparencyProperties.draggedWindowDwFlags))
|
|
||||||
{
|
|
||||||
Logger::error(L"Window transparency: GetLayeredWindowAttributes failed, {}", get_last_error_or_default(GetLastError()));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_windowTransparencyProperties.draggedWindow = window;
|
|
||||||
|
|
||||||
if (!SetLayeredWindowAttributes(window, 0, (255 * 50) / 100, LWA_ALPHA))
|
|
||||||
{
|
|
||||||
Logger::error(L"Window transparency: SetLayeredWindowAttributes failed, {}", get_last_error_or_default(GetLastError()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WindowMoveHandler::ResetWindowTransparency() noexcept
|
|
||||||
{
|
|
||||||
if (FancyZonesSettings::settings().makeDraggedWindowTransparent && m_windowTransparencyProperties.draggedWindow != nullptr)
|
|
||||||
{
|
|
||||||
if (!SetLayeredWindowAttributes(m_windowTransparencyProperties.draggedWindow, m_windowTransparencyProperties.draggedWindowCrKey, m_windowTransparencyProperties.draggedWindowInitialAlpha, m_windowTransparencyProperties.draggedWindowDwFlags))
|
|
||||||
{
|
|
||||||
Logger::error(L"Window transparency: SetLayeredWindowAttributes failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SetWindowLong(m_windowTransparencyProperties.draggedWindow, GWL_EXSTYLE, m_windowTransparencyProperties.draggedWindowExstyle) == 0)
|
|
||||||
{
|
|
||||||
Logger::error(L"Window transparency: SetWindowLong failed, {}", get_last_error_or_default(GetLastError()));
|
|
||||||
}
|
|
||||||
|
|
||||||
m_windowTransparencyProperties.draggedWindow = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,57 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "FancyZonesWindowProperties.h"
|
|
||||||
#include "KeyState.h"
|
|
||||||
#include "SecondaryMouseButtonsHook.h"
|
|
||||||
|
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
interface IFancyZonesSettings;
|
|
||||||
class WorkArea;
|
|
||||||
|
|
||||||
class WindowMoveHandler
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
WindowMoveHandler();
|
|
||||||
|
|
||||||
void MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, std::shared_ptr<WorkArea>>& workAreaMap, bool dragEnabled) noexcept;
|
|
||||||
void MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, std::shared_ptr<WorkArea>>& workAreaMap, bool dragEnabled, bool multipleZones) noexcept;
|
|
||||||
void MoveSizeEnd(HWND window, const std::unordered_map<HMONITOR, std::shared_ptr<WorkArea>>& workAreaMap) noexcept;
|
|
||||||
|
|
||||||
void MoveWindowIntoZoneByIndexSet(HWND window, const ZoneIndexSet& indexSet, std::shared_ptr<WorkArea> workArea) noexcept;
|
|
||||||
bool MoveWindowIntoZoneByDirectionAndIndex(HWND window, DWORD vkCode, bool cycle, std::shared_ptr<WorkArea> workArea) noexcept;
|
|
||||||
bool MoveWindowIntoZoneByDirectionAndPosition(HWND window, DWORD vkCode, bool cycle, std::shared_ptr<WorkArea> workArea) noexcept;
|
|
||||||
bool ExtendWindowByDirectionAndPosition(HWND window, DWORD vkCode, std::shared_ptr<WorkArea> workArea) noexcept;
|
|
||||||
|
|
||||||
void AssignWindowsToZones(const std::unordered_map<HMONITOR, std::shared_ptr<WorkArea>>& activeWorkAreas, bool updatePositions) noexcept;
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct WindowTransparencyProperties
|
|
||||||
{
|
|
||||||
HWND draggedWindow = nullptr;
|
|
||||||
long draggedWindowExstyle = 0;
|
|
||||||
COLORREF draggedWindowCrKey = RGB(0, 0, 0);
|
|
||||||
DWORD draggedWindowDwFlags = 0;
|
|
||||||
BYTE draggedWindowInitialAlpha = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
// MoveSize related window properties
|
|
||||||
struct MoveSizeWindowInfo
|
|
||||||
{
|
|
||||||
// True if from the styles the window looks like a standard window
|
|
||||||
bool isStandardWindow = false;
|
|
||||||
// True if the window is a top-level window that does not have a visible owner
|
|
||||||
bool hasNoVisibleOwner = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
void SetWindowTransparency(HWND window) noexcept;
|
|
||||||
void ResetWindowTransparency() noexcept;
|
|
||||||
|
|
||||||
bool m_inDragging{}; // Whether or not a move/size operation is currently active
|
|
||||||
HWND m_draggedWindow{}; // The window that is being moved/sized
|
|
||||||
MoveSizeWindowInfo m_draggedWindowInfo; // MoveSizeWindowInfo of the window at the moment when dragging started
|
|
||||||
std::shared_ptr<WorkArea> m_draggedWindowWorkArea; // "Active" WorkArea, where the move/size is happening. Will update as drag moves between monitors.
|
|
||||||
|
|
||||||
WindowTransparencyProperties m_windowTransparencyProperties;
|
|
||||||
|
|
||||||
};
|
|
@ -127,62 +127,6 @@ WorkArea::~WorkArea()
|
|||||||
windowPool.FreeZonesOverlayWindow(m_window);
|
windowPool.FreeZonesOverlayWindow(m_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT WorkArea::MoveSizeEnter(HWND window) noexcept
|
|
||||||
{
|
|
||||||
m_windowMoveSize = window;
|
|
||||||
m_highlightedZones.Reset();
|
|
||||||
ShowZonesOverlay();
|
|
||||||
Trace::WorkArea::MoveOrResizeStarted(m_layout.get(), m_layoutWindows.get());
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT WorkArea::MoveSizeUpdate(POINT const& ptScreen, bool dragEnabled, bool selectManyZones) noexcept
|
|
||||||
{
|
|
||||||
if (!m_layout)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool redraw = false;
|
|
||||||
|
|
||||||
if (dragEnabled)
|
|
||||||
{
|
|
||||||
POINT ptClient = ptScreen;
|
|
||||||
MapWindowPoints(nullptr, m_window, &ptClient, 1);
|
|
||||||
|
|
||||||
redraw = m_highlightedZones.Update(m_layout.get(), ptClient, selectManyZones);
|
|
||||||
}
|
|
||||||
else if (!m_highlightedZones.Empty())
|
|
||||||
{
|
|
||||||
m_highlightedZones.Reset();
|
|
||||||
redraw = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (redraw && m_zonesOverlay)
|
|
||||||
{
|
|
||||||
m_zonesOverlay->DrawActiveZoneSet(m_layout->Zones(), m_highlightedZones.Zones(), Colors::GetZoneColors(), FancyZonesSettings::settings().showZoneNumber);
|
|
||||||
}
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT WorkArea::MoveSizeEnd(HWND window) noexcept
|
|
||||||
{
|
|
||||||
if (m_windowMoveSize != window)
|
|
||||||
{
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
MoveWindowIntoZoneByIndexSet(window, m_highlightedZones.Zones());
|
|
||||||
m_highlightedZones.Reset();
|
|
||||||
|
|
||||||
Trace::WorkArea::MoveOrResizeEnd(m_layout.get(), m_layoutWindows.get());
|
|
||||||
|
|
||||||
HideZonesOverlay();
|
|
||||||
m_windowMoveSize = nullptr;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WorkArea::MoveWindowIntoZoneByIndex(HWND window, ZoneIndex index) noexcept
|
void WorkArea::MoveWindowIntoZoneByIndex(HWND window, ZoneIndex index) noexcept
|
||||||
{
|
{
|
||||||
MoveWindowIntoZoneByIndexSet(window, { index });
|
MoveWindowIntoZoneByIndexSet(window, { index });
|
||||||
@ -482,22 +426,31 @@ ZoneIndexSet WorkArea::GetWindowZoneIndexes(HWND window) const noexcept
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorkArea::ShowZonesOverlay() noexcept
|
void WorkArea::ShowZonesOverlay(const ZoneIndexSet& highlight, HWND draggedWindow/* = nullptr*/)
|
||||||
{
|
{
|
||||||
if (m_window && m_layout)
|
if (m_layout && m_zonesOverlay)
|
||||||
{
|
{
|
||||||
SetAsTopmostWindow();
|
SetWorkAreaWindowAsTopmost(draggedWindow);
|
||||||
m_zonesOverlay->DrawActiveZoneSet(m_layout->Zones(), m_highlightedZones.Zones(), Colors::GetZoneColors(), FancyZonesSettings::settings().showZoneNumber);
|
m_zonesOverlay->DrawActiveZoneSet(m_layout->Zones(), highlight, Colors::GetZoneColors(), FancyZonesSettings::settings().showZoneNumber);
|
||||||
m_zonesOverlay->Show();
|
m_zonesOverlay->Show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorkArea::HideZonesOverlay() noexcept
|
void WorkArea::HideZonesOverlay()
|
||||||
{
|
{
|
||||||
if (m_window)
|
if (m_zonesOverlay)
|
||||||
{
|
{
|
||||||
m_zonesOverlay->Hide();
|
m_zonesOverlay->Hide();
|
||||||
m_windowMoveSize = nullptr;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorkArea::FlashZones()
|
||||||
|
{
|
||||||
|
if (m_layout && m_zonesOverlay)
|
||||||
|
{
|
||||||
|
SetWorkAreaWindowAsTopmost(nullptr);
|
||||||
|
m_zonesOverlay->DrawActiveZoneSet(m_layout->Zones(), {}, Colors::GetZoneColors(), FancyZonesSettings::settings().showZoneNumber);
|
||||||
|
m_zonesOverlay->Flash();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -524,25 +477,6 @@ void WorkArea::CycleWindows(HWND window, bool reverse) noexcept
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorkArea::ClearSelectedZones() noexcept
|
|
||||||
{
|
|
||||||
if (!m_highlightedZones.Empty() && m_layout)
|
|
||||||
{
|
|
||||||
m_highlightedZones.Reset();
|
|
||||||
m_zonesOverlay->DrawActiveZoneSet(m_layout->Zones(), {}, Colors::GetZoneColors(), FancyZonesSettings::settings().showZoneNumber);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WorkArea::FlashZones() noexcept
|
|
||||||
{
|
|
||||||
if (m_window && m_layout)
|
|
||||||
{
|
|
||||||
SetAsTopmostWindow();
|
|
||||||
m_zonesOverlay->DrawActiveZoneSet(m_layout->Zones(), {}, Colors::GetZoneColors(), FancyZonesSettings::settings().showZoneNumber);
|
|
||||||
m_zonesOverlay->Flash();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma region private
|
#pragma region private
|
||||||
|
|
||||||
bool WorkArea::InitWindow(HINSTANCE hinstance) noexcept
|
bool WorkArea::InitWindow(HINSTANCE hinstance) noexcept
|
||||||
@ -618,21 +552,16 @@ LRESULT WorkArea::WndProc(UINT message, WPARAM wparam, LPARAM lparam) noexcept
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorkArea::SetAsTopmostWindow() noexcept
|
void WorkArea::SetWorkAreaWindowAsTopmost(HWND draggedWindow) noexcept
|
||||||
{
|
{
|
||||||
if (!m_window)
|
if (!m_window)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT flags = SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE;
|
HWND windowInsertAfter = draggedWindow ? draggedWindow : HWND_TOPMOST;
|
||||||
|
|
||||||
HWND windowInsertAfter = m_windowMoveSize;
|
|
||||||
if (windowInsertAfter == nullptr)
|
|
||||||
{
|
|
||||||
windowInsertAfter = HWND_TOPMOST;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
const UINT flags = SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE;
|
||||||
SetWindowPos(m_window, windowInsertAfter, 0, 0, 0, 0, flags);
|
SetWindowPos(m_window, windowInsertAfter, 0, 0, 0, 0, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <FancyZonesLib/FancyZonesDataTypes.h>
|
#include <FancyZonesLib/FancyZonesDataTypes.h>
|
||||||
#include <FancyZonesLib/HighlightedZones.h>
|
|
||||||
#include <FancyZonesLib/Layout.h>
|
#include <FancyZonesLib/Layout.h>
|
||||||
#include <FancyZonesLib/LayoutAssignedWindows.h>
|
#include <FancyZonesLib/LayoutAssignedWindows.h>
|
||||||
#include <FancyZonesLib/util.h>
|
#include <FancyZonesLib/util.h>
|
||||||
@ -30,12 +29,10 @@ public:
|
|||||||
FancyZonesDataTypes::WorkAreaId UniqueId() const noexcept { return { m_uniqueId }; }
|
FancyZonesDataTypes::WorkAreaId UniqueId() const noexcept { return { m_uniqueId }; }
|
||||||
const std::unique_ptr<Layout>& GetLayout() const noexcept { return m_layout; }
|
const std::unique_ptr<Layout>& GetLayout() const noexcept { return m_layout; }
|
||||||
const std::unique_ptr<LayoutAssignedWindows>& GetLayoutWindows() const noexcept { return m_layoutWindows; }
|
const std::unique_ptr<LayoutAssignedWindows>& GetLayoutWindows() const noexcept { return m_layoutWindows; }
|
||||||
|
const HWND GetWorkAreaWindow() const noexcept { return m_window; }
|
||||||
|
|
||||||
ZoneIndexSet GetWindowZoneIndexes(HWND window) const noexcept;
|
ZoneIndexSet GetWindowZoneIndexes(HWND window) const noexcept;
|
||||||
|
|
||||||
HRESULT MoveSizeEnter(HWND window) noexcept;
|
|
||||||
HRESULT MoveSizeUpdate(POINT const& ptScreen, bool dragEnabled, bool selectManyZones) noexcept;
|
|
||||||
HRESULT MoveSizeEnd(HWND window) noexcept;
|
|
||||||
void MoveWindowIntoZoneByIndex(HWND window, ZoneIndex index) noexcept;
|
void MoveWindowIntoZoneByIndex(HWND window, ZoneIndex index) noexcept;
|
||||||
void MoveWindowIntoZoneByIndexSet(HWND window, const ZoneIndexSet& indexSet, bool updatePosition = true) noexcept;
|
void MoveWindowIntoZoneByIndexSet(HWND window, const ZoneIndexSet& indexSet, bool updatePosition = true) noexcept;
|
||||||
bool MoveWindowIntoZoneByDirectionAndIndex(HWND window, DWORD vkCode, bool cycle) noexcept;
|
bool MoveWindowIntoZoneByDirectionAndIndex(HWND window, DWORD vkCode, bool cycle) noexcept;
|
||||||
@ -46,10 +43,9 @@ public:
|
|||||||
|
|
||||||
void UpdateActiveZoneSet() noexcept;
|
void UpdateActiveZoneSet() noexcept;
|
||||||
|
|
||||||
void ShowZonesOverlay() noexcept;
|
void ShowZonesOverlay(const ZoneIndexSet& highlight, HWND draggedWindow = nullptr);
|
||||||
void HideZonesOverlay() noexcept;
|
void HideZonesOverlay();
|
||||||
void FlashZones() noexcept;
|
void FlashZones();
|
||||||
void ClearSelectedZones() noexcept;
|
|
||||||
|
|
||||||
void CycleWindows(HWND window, bool reverse) noexcept;
|
void CycleWindows(HWND window, bool reverse) noexcept;
|
||||||
|
|
||||||
@ -61,7 +57,7 @@ private:
|
|||||||
void InitLayout(const FancyZonesDataTypes::WorkAreaId& parentUniqueId) noexcept;
|
void InitLayout(const FancyZonesDataTypes::WorkAreaId& parentUniqueId) noexcept;
|
||||||
void CalculateZoneSet() noexcept;
|
void CalculateZoneSet() noexcept;
|
||||||
LRESULT WndProc(UINT message, WPARAM wparam, LPARAM lparam) noexcept;
|
LRESULT WndProc(UINT message, WPARAM wparam, LPARAM lparam) noexcept;
|
||||||
void SetAsTopmostWindow() noexcept;
|
void SetWorkAreaWindowAsTopmost(HWND draggedWindow) noexcept;
|
||||||
|
|
||||||
const FancyZonesUtils::Rect m_workAreaRect{};
|
const FancyZonesUtils::Rect m_workAreaRect{};
|
||||||
const FancyZonesDataTypes::WorkAreaId m_uniqueId;
|
const FancyZonesDataTypes::WorkAreaId m_uniqueId;
|
||||||
@ -69,9 +65,6 @@ private:
|
|||||||
std::unique_ptr<Layout> m_layout;
|
std::unique_ptr<Layout> m_layout;
|
||||||
std::unique_ptr<LayoutAssignedWindows> m_layoutWindows;
|
std::unique_ptr<LayoutAssignedWindows> m_layoutWindows;
|
||||||
std::unique_ptr<ZonesOverlay> m_zonesOverlay;
|
std::unique_ptr<ZonesOverlay> m_zonesOverlay;
|
||||||
HighlightedZones m_highlightedZones;
|
|
||||||
|
|
||||||
HWND m_windowMoveSize{};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::shared_ptr<WorkArea> MakeWorkArea(HINSTANCE hinstance, const FancyZonesDataTypes::WorkAreaId& uniqueId, const FancyZonesDataTypes::WorkAreaId& parentUniqueId, const FancyZonesUtils::Rect& workAreaRect)
|
inline std::shared_ptr<WorkArea> MakeWorkArea(HINSTANCE hinstance, const FancyZonesDataTypes::WorkAreaId& uniqueId, const FancyZonesDataTypes::WorkAreaId& parentUniqueId, const FancyZonesUtils::Rect& workAreaRect)
|
||||||
|
@ -204,98 +204,6 @@ namespace FancyZonesUnitTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TEST_METHOD (MoveSizeEnter)
|
|
||||||
{
|
|
||||||
auto workArea = MakeWorkArea(m_hInst, m_uniqueId, m_parentUniqueId, m_workAreaRect);
|
|
||||||
|
|
||||||
constexpr auto expected = S_OK;
|
|
||||||
const auto actual = workArea->MoveSizeEnter(Mocks::Window());
|
|
||||||
|
|
||||||
Assert::AreEqual(expected, actual);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD (MoveSizeEnterTwice)
|
|
||||||
{
|
|
||||||
auto workArea = MakeWorkArea(m_hInst, m_uniqueId, m_parentUniqueId, m_workAreaRect);
|
|
||||||
|
|
||||||
constexpr auto expected = S_OK;
|
|
||||||
|
|
||||||
workArea->MoveSizeEnter(Mocks::Window());
|
|
||||||
const auto actual = workArea->MoveSizeEnter(Mocks::Window());
|
|
||||||
|
|
||||||
Assert::AreEqual(expected, actual);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD (MoveSizeUpdate)
|
|
||||||
{
|
|
||||||
auto workArea = MakeWorkArea(m_hInst, m_uniqueId, m_parentUniqueId, m_workAreaRect);
|
|
||||||
|
|
||||||
constexpr auto expected = S_OK;
|
|
||||||
const auto actual = workArea->MoveSizeUpdate(POINT{ 0, 0 }, true, false);
|
|
||||||
|
|
||||||
Assert::AreEqual(expected, actual);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD (MoveSizeUpdatePointNegativeCoordinates)
|
|
||||||
{
|
|
||||||
auto workArea = MakeWorkArea(m_hInst, m_uniqueId, m_parentUniqueId, m_workAreaRect);
|
|
||||||
|
|
||||||
constexpr auto expected = S_OK;
|
|
||||||
const auto actual = workArea->MoveSizeUpdate(POINT{ -10, -10 }, true, false);
|
|
||||||
|
|
||||||
Assert::AreEqual(expected, actual);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD (MoveSizeUpdatePointBigCoordinates)
|
|
||||||
{
|
|
||||||
auto workArea = MakeWorkArea(m_hInst, m_uniqueId, m_parentUniqueId, m_workAreaRect);
|
|
||||||
|
|
||||||
constexpr auto expected = S_OK;
|
|
||||||
const auto actual = workArea->MoveSizeUpdate(POINT{ LONG_MAX, LONG_MAX }, true, false);
|
|
||||||
|
|
||||||
Assert::AreEqual(expected, actual);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD (MoveSizeEnd)
|
|
||||||
{
|
|
||||||
auto workArea = MakeWorkArea(m_hInst, m_uniqueId, m_parentUniqueId, m_workAreaRect);
|
|
||||||
|
|
||||||
const auto window = Mocks::Window();
|
|
||||||
workArea->MoveSizeEnter(window);
|
|
||||||
workArea->MoveSizeUpdate({ 20, 20 }, true, true);
|
|
||||||
|
|
||||||
constexpr auto expected = S_OK;
|
|
||||||
const auto actual = workArea->MoveSizeEnd(window);
|
|
||||||
Assert::AreEqual(expected, actual);
|
|
||||||
|
|
||||||
const auto& layoutWindows = workArea->GetLayoutWindows();
|
|
||||||
const auto actualZoneIndexSet = layoutWindows->GetZoneIndexSetFromWindow(window);
|
|
||||||
Assert::IsFalse(std::vector<ZoneIndex>{} == actualZoneIndexSet);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD (MoveSizeEndDifferentWindows)
|
|
||||||
{
|
|
||||||
auto workArea = MakeWorkArea(m_hInst, m_uniqueId, m_parentUniqueId, m_workAreaRect);
|
|
||||||
|
|
||||||
const auto window = Mocks::Window();
|
|
||||||
workArea->MoveSizeEnter(window);
|
|
||||||
|
|
||||||
constexpr auto expected = E_INVALIDARG;
|
|
||||||
const auto actual = workArea->MoveSizeEnd(Mocks::Window());
|
|
||||||
|
|
||||||
Assert::AreEqual(expected, actual);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD (MoveSizeEndWindowNotSet)
|
|
||||||
{
|
|
||||||
auto workArea = MakeWorkArea(m_hInst, m_uniqueId, m_parentUniqueId, m_workAreaRect);
|
|
||||||
|
|
||||||
constexpr auto expected = E_INVALIDARG;
|
|
||||||
const auto actual = workArea->MoveSizeEnd(Mocks::Window());
|
|
||||||
|
|
||||||
Assert::AreEqual(expected, actual);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD (SaveWindowProcessToZoneIndexNullptrWindow)
|
TEST_METHOD (SaveWindowProcessToZoneIndexNullptrWindow)
|
||||||
{
|
{
|
||||||
auto workArea = MakeWorkArea(m_hInst, m_uniqueId, m_parentUniqueId, m_workAreaRect);
|
auto workArea = MakeWorkArea(m_hInst, m_uniqueId, m_parentUniqueId, m_workAreaRect);
|
||||||
|
Loading…
Reference in New Issue
Block a user