diff --git a/src/modules/fancyzones/FancyZonesLib/DraggingState.cpp b/src/modules/fancyzones/FancyZonesLib/DraggingState.cpp new file mode 100644 index 0000000000..03cc789e1e --- /dev/null +++ b/src/modules/fancyzones/FancyZonesLib/DraggingState.cpp @@ -0,0 +1,83 @@ +#include "pch.h" +#include "DraggingState.h" + +#include +#include + +DraggingState::DraggingState(const std::function& keyUpdateCallback) : + m_mouseState(false), + m_mouseHook(std::bind(&DraggingState::OnMouseDown, this)), + m_leftShiftKeyState(keyUpdateCallback), + m_rightShiftKeyState(keyUpdateCallback), + m_ctrlKeyState(keyUpdateCallback), + m_keyUpdateCallback(keyUpdateCallback) +{ +} + +void DraggingState::Enable() +{ + if (FancyZonesSettings::settings().mouseSwitch) + { + m_mouseHook.enable(); + } + + m_leftShiftKeyState.enable(); + m_rightShiftKeyState.enable(); + m_ctrlKeyState.enable(); +} + +void DraggingState::Disable() +{ + bool leftShiftPressed = m_leftShiftKeyState.state(); + bool rightShiftPressed = m_rightShiftKeyState.state(); + + if (FancyZonesSettings::settings().shiftDrag) + { + if (leftShiftPressed) + { + FancyZonesUtils::SwallowKey(VK_LSHIFT); + } + + if (rightShiftPressed) + { + FancyZonesUtils::SwallowKey(VK_RSHIFT); + } + } + + m_dragging = false; + m_mouseState = false; + + m_mouseHook.disable(); + m_leftShiftKeyState.disable(); + m_rightShiftKeyState.disable(); + m_ctrlKeyState.disable(); +} + +void DraggingState::UpdateDraggingState() noexcept +{ + // This updates m_dragEnabled depending on if the shift key is being held down + if (FancyZonesSettings::settings().shiftDrag) + { + m_dragging = ((m_leftShiftKeyState.state() || m_rightShiftKeyState.state()) ^ m_mouseState); + } + else + { + m_dragging = !((m_leftShiftKeyState.state() || m_rightShiftKeyState.state()) ^ m_mouseState); + } +} + +void DraggingState::OnMouseDown() +{ + m_mouseState = !m_mouseState; + m_keyUpdateCallback(); +} + +bool DraggingState::IsDragging() const noexcept +{ + return m_dragging; +} + +bool DraggingState::IsSelectManyZonesState() const noexcept +{ + return m_ctrlKeyState.state(); +} diff --git a/src/modules/fancyzones/FancyZonesLib/DraggingState.h b/src/modules/fancyzones/FancyZonesLib/DraggingState.h new file mode 100644 index 0000000000..cb6873a1be --- /dev/null +++ b/src/modules/fancyzones/FancyZonesLib/DraggingState.h @@ -0,0 +1,30 @@ +#pragma once + +#include +#include + +class DraggingState +{ +public: + DraggingState(const std::function& keyUpdateCallback); + ~DraggingState() = default; + + void Enable(); + void Disable(); + void UpdateDraggingState() noexcept; + + bool IsDragging() const noexcept; + bool IsSelectManyZonesState() const noexcept; + +private: + void OnMouseDown(); + + std::atomic m_mouseState; + SecondaryMouseButtonsHook m_mouseHook; + KeyState m_leftShiftKeyState; + KeyState m_rightShiftKeyState; + KeyState m_ctrlKeyState; + std::function m_keyUpdateCallback; + + bool m_dragging{}; // True if we should be showing zone hints while dragging +}; diff --git a/src/modules/fancyzones/FancyZonesLib/FancyZones.cpp b/src/modules/fancyzones/FancyZonesLib/FancyZones.cpp index cf2c569a8f..940232b38e 100644 --- a/src/modules/fancyzones/FancyZonesLib/FancyZones.cpp +++ b/src/modules/fancyzones/FancyZonesLib/FancyZones.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -59,7 +60,8 @@ public: FancyZones(HINSTANCE hinstance, std::function disableModuleCallbackFunction) noexcept : SettingsObserver({ SettingId::EditorHotkey, SettingId::PrevTabHotkey, SettingId::NextTabHotkey, SettingId::SpanZonesAcrossMonitors }), m_hinstance(hinstance), - m_windowMoveHandler([this]() { + m_windowMoveHandler(), + m_draggingState([this]() { PostMessageW(m_window, WM_PRIV_LOCATIONCHANGE, NULL, NULL); }) { @@ -89,7 +91,9 @@ public: monitor = NULL; } - m_windowMoveHandler.MoveSizeStart(window, monitor, ptScreen, m_workAreaHandler.GetWorkAreasByDesktopId(VirtualDesktop::instance().GetCurrentVirtualDesktopId())); + 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 @@ -98,12 +102,16 @@ public: { monitor = NULL; } - m_windowMoveHandler.MoveSizeUpdate(monitor, ptScreen, m_workAreaHandler.GetWorkAreasByDesktopId(VirtualDesktop::instance().GetCurrentVirtualDesktopId())); + + 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) @@ -185,6 +193,7 @@ private: HWND m_window{}; WindowMoveHandler m_windowMoveHandler; MonitorWorkAreaHandler m_workAreaHandler; + DraggingState m_draggingState; wil::unique_handle m_terminateEditorEvent; // Handle of FancyZonesEditor.exe we launch and wait on @@ -478,7 +487,7 @@ FancyZones::OnKeyDown(PKBDLLHOOKSTRUCT info) noexcept digitPressed = info->vkCode - VK_NUMPAD0; } - bool dragging = m_windowMoveHandler.InDragging(); + bool dragging = m_draggingState.IsDragging(); bool changeLayoutWhileNotDragging = !dragging && !shift && win && ctrl && alt && digitPressed != -1; bool changeLayoutWhileDragging = dragging && digitPressed != -1; @@ -494,7 +503,7 @@ FancyZones::OnKeyDown(PKBDLLHOOKSTRUCT info) noexcept } } - if (m_windowMoveHandler.IsDragEnabled() && shift) + if (m_draggingState.IsDragging() && shift) { return true; } @@ -638,12 +647,9 @@ LRESULT FancyZones::WndProc(HWND window, UINT message, WPARAM wparam, LPARAM lpa } else if (message == WM_PRIV_LOCATIONCHANGE) { - if (m_windowMoveHandler.InDragging()) + if (auto monitor = MonitorFromPoint(ptScreen, MONITOR_DEFAULTTONULL)) { - if (auto monitor = MonitorFromPoint(ptScreen, MONITOR_DEFAULTTONULL)) - { - MoveSizeUpdate(monitor, ptScreen); - } + MoveSizeUpdate(monitor, ptScreen); } } else if (message == WM_PRIV_WINDOWCREATED) @@ -1197,7 +1203,7 @@ void FancyZones::ApplyQuickLayout(int key) noexcept void FancyZones::FlashZones() noexcept { - if (FancyZonesSettings::settings().flashZonesOnQuickSwitch && !m_windowMoveHandler.IsDragEnabled()) + if (FancyZonesSettings::settings().flashZonesOnQuickSwitch && !m_draggingState.IsDragging()) { for (auto [monitor, workArea] : m_workAreaHandler.GetWorkAreasByDesktopId(VirtualDesktop::instance().GetCurrentVirtualDesktopId())) { diff --git a/src/modules/fancyzones/FancyZonesLib/FancyZonesLib.vcxproj b/src/modules/fancyzones/FancyZonesLib/FancyZonesLib.vcxproj index 224779b0fa..a9969328c6 100644 --- a/src/modules/fancyzones/FancyZonesLib/FancyZonesLib.vcxproj +++ b/src/modules/fancyzones/FancyZonesLib/FancyZonesLib.vcxproj @@ -35,6 +35,7 @@ + @@ -82,6 +83,7 @@ + ../pch.h diff --git a/src/modules/fancyzones/FancyZonesLib/FancyZonesLib.vcxproj.filters b/src/modules/fancyzones/FancyZonesLib/FancyZonesLib.vcxproj.filters index d14e7a6a4a..50f82600b4 100644 --- a/src/modules/fancyzones/FancyZonesLib/FancyZonesLib.vcxproj.filters +++ b/src/modules/fancyzones/FancyZonesLib/FancyZonesLib.vcxproj.filters @@ -159,6 +159,12 @@ Header Files + + Header Files + + + Header Files + @@ -257,6 +263,9 @@ Source Files + + Source Files + diff --git a/src/modules/fancyzones/FancyZonesLib/WindowMoveHandler.cpp b/src/modules/fancyzones/FancyZonesLib/WindowMoveHandler.cpp index 1e2867513e..7f314f2d6a 100644 --- a/src/modules/fancyzones/FancyZonesLib/WindowMoveHandler.cpp +++ b/src/modules/fancyzones/FancyZonesLib/WindowMoveHandler.cpp @@ -13,17 +13,12 @@ #include #include -WindowMoveHandler::WindowMoveHandler(const std::function& keyUpdateCallback) : - m_mouseState(false), - m_mouseHook(std::bind(&WindowMoveHandler::OnMouseDown, this)), - m_leftShiftKeyState(keyUpdateCallback), - m_rightShiftKeyState(keyUpdateCallback), - m_ctrlKeyState(keyUpdateCallback), - m_keyUpdateCallback(keyUpdateCallback) + +WindowMoveHandler::WindowMoveHandler() { } -void WindowMoveHandler::MoveSizeStart(HWND window, HMONITOR monitor, POINT const& /*ptScreen*/, const std::unordered_map>& workAreaMap) noexcept +void WindowMoveHandler::MoveSizeStart(HWND window, HMONITOR monitor, POINT const& /*ptScreen*/, const std::unordered_map>& workAreaMap, bool dragEnabled) noexcept { if (!FancyZonesWindowProcessing::IsProcessable(window)) { @@ -47,26 +42,13 @@ void WindowMoveHandler::MoveSizeStart(HWND window, HMONITOR monitor, POINT const m_draggedWindow = window; - if (FancyZonesSettings::settings().mouseSwitch) - { - m_mouseHook.enable(); - } - - m_leftShiftKeyState.enable(); - m_rightShiftKeyState.enable(); - m_ctrlKeyState.enable(); - - // This updates m_dragEnabled depending on if the shift key is being held down - UpdateDragState(); - if (!is_process_elevated() && FancyZonesWindowUtils::IsProcessOfWindowElevated(window)) { // Notifies user if unable to drag elevated window FancyZonesNotifications::WarnIfElevationIsRequired(); - m_dragEnabled = false; } - if (m_dragEnabled) + if (dragEnabled) { m_draggedWindowWorkArea = iter->second; SetWindowTransparency(m_draggedWindow); @@ -105,20 +87,17 @@ void WindowMoveHandler::MoveSizeStart(HWND window, HMONITOR monitor, POINT const } } -void WindowMoveHandler::MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, const std::unordered_map>& workAreaMap) noexcept +void WindowMoveHandler::MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, const std::unordered_map>& workAreaMap, bool dragEnabled, bool multipleZones) noexcept { if (!m_inDragging) { return; } - // This updates m_dragEnabled depending on if the shift key is being held down. - UpdateDragState(); - if (m_draggedWindowWorkArea) { // Update the WorkArea already handling move/size - if (!m_dragEnabled) + if (!dragEnabled) { // Drag got disabled, tell it to cancel and hide all windows m_draggedWindowWorkArea = nullptr; @@ -152,22 +131,22 @@ void WindowMoveHandler::MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, for (auto [keyMonitor, workArea] : workAreaMap) { - workArea->MoveSizeUpdate(ptScreen, m_dragEnabled, m_ctrlKeyState.state()); + workArea->MoveSizeUpdate(ptScreen, dragEnabled, multipleZones); } } } } - else if (m_dragEnabled) + 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); + 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 (m_dragEnabled) + if (dragEnabled) { - MoveSizeUpdate(monitor, ptScreen, workAreaMap); + MoveSizeUpdate(monitor, ptScreen, workAreaMap, dragEnabled, multipleZones); } } } @@ -179,14 +158,6 @@ void WindowMoveHandler::MoveSizeEnd(HWND window, const std::unordered_mapMoveSizeEnd(m_draggedWindow); } } @@ -261,8 +219,6 @@ void WindowMoveHandler::MoveSizeEnd(HWND window, const std::unordered_map& keyUpdateCallback); + WindowMoveHandler(); - void MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::unordered_map>& workAreaMap) noexcept; - void MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, const std::unordered_map>& workAreaMap) noexcept; + void MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::unordered_map>& workAreaMap, bool dragEnabled) noexcept; + void MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, const std::unordered_map>& workAreaMap, bool dragEnabled, bool multipleZones) noexcept; void MoveSizeEnd(HWND window, const std::unordered_map>& workAreaMap) noexcept; void MoveWindowIntoZoneByIndexSet(HWND window, const ZoneIndexSet& indexSet, std::shared_ptr workArea) noexcept; @@ -25,22 +25,6 @@ public: void AssignWindowsToZones(const std::unordered_map>& activeWorkAreas, bool updatePositions) noexcept; - inline void OnMouseDown() noexcept - { - m_mouseState = !m_mouseState; - m_keyUpdateCallback(); - } - - inline bool IsDragEnabled() const noexcept - { - return m_dragEnabled; - } - - inline bool InDragging() const noexcept - { - return m_inDragging; - } - private: struct WindowTransparencyProperties { @@ -60,8 +44,6 @@ private: bool hasNoVisibleOwner = false; }; - void UpdateDragState() noexcept; - void SetWindowTransparency(HWND window) noexcept; void ResetWindowTransparency() noexcept; @@ -69,14 +51,7 @@ private: 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 m_draggedWindowWorkArea; // "Active" WorkArea, where the move/size is happening. Will update as drag moves between monitors. - bool m_dragEnabled{}; // True if we should be showing zone hints while dragging WindowTransparencyProperties m_windowTransparencyProperties; - std::atomic m_mouseState; - SecondaryMouseButtonsHook m_mouseHook; - KeyState m_leftShiftKeyState; - KeyState m_rightShiftKeyState; - KeyState m_ctrlKeyState; - std::function m_keyUpdateCallback; }; diff --git a/src/modules/fancyzones/FancyZonesLib/WorkArea.cpp b/src/modules/fancyzones/FancyZonesLib/WorkArea.cpp index 69e19cc5f9..bf9c2252ce 100644 --- a/src/modules/fancyzones/FancyZonesLib/WorkArea.cpp +++ b/src/modules/fancyzones/FancyZonesLib/WorkArea.cpp @@ -650,4 +650,4 @@ LRESULT CALLBACK WorkArea::s_WndProc(HWND window, UINT message, WPARAM wparam, L return (thisRef != nullptr) ? thisRef->WndProc(message, wparam, lparam) : DefWindowProc(window, message, wparam, lparam); -} +} \ No newline at end of file