[FancyZones] Improve code quality (part 3: window dragging) (#23040)

This commit is contained in:
Seraphima Zykova
2023-01-26 20:02:46 +03:00
committed by GitHub
parent 923c220338
commit dbcf1fca15
8 changed files with 156 additions and 106 deletions

View File

@@ -0,0 +1,83 @@
#include "pch.h"
#include "DraggingState.h"
#include <FancyZonesLib/Settings.h>
#include <FancyZonesLib/util.h>
DraggingState::DraggingState(const std::function<void()>& 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();
}

View File

@@ -0,0 +1,30 @@
#pragma once
#include <FancyZonesLib/KeyState.h>
#include <FancyZonesLib/SecondaryMouseButtonsHook.h>
class DraggingState
{
public:
DraggingState(const std::function<void()>& keyUpdateCallback);
~DraggingState() = default;
void Enable();
void Disable();
void UpdateDraggingState() noexcept;
bool IsDragging() const noexcept;
bool IsSelectManyZonesState() const noexcept;
private:
void OnMouseDown();
std::atomic<bool> m_mouseState;
SecondaryMouseButtonsHook m_mouseHook;
KeyState<VK_LSHIFT> m_leftShiftKeyState;
KeyState<VK_RSHIFT> m_rightShiftKeyState;
KeyState<VK_LCONTROL, VK_RCONTROL> m_ctrlKeyState;
std::function<void()> m_keyUpdateCallback;
bool m_dragging{}; // True if we should be showing zone hints while dragging
};

View File

@@ -11,6 +11,7 @@
#include <common/utils/window.h>
#include <common/SettingsAPI/FileWatcher.h>
#include <FancyZonesLib/DraggingState.h>
#include <FancyZonesLib/EditorParameters.h>
#include <FancyZonesLib/FancyZonesData.h>
#include <FancyZonesLib/FancyZonesData/AppliedLayouts.h>
@@ -59,7 +60,8 @@ public:
FancyZones(HINSTANCE hinstance, std::function<void()> 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()))
{

View File

@@ -35,6 +35,7 @@
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="DraggingState.h" />
<ClInclude Include="EditorParameters.h" />
<ClInclude Include="FancyZonesData\CustomLayouts.h" />
<ClInclude Include="FancyZonesData\AppliedLayouts.h" />
@@ -82,6 +83,7 @@
</ItemGroup>
<ItemGroup>
<ClCompile Include="Colors.cpp" />
<ClCompile Include="DraggingState.cpp" />
<ClCompile Include="EditorParameters.cpp" />
<ClCompile Include="FancyZonesData\AppZoneHistory.cpp">
<PrecompiledHeaderFile>../pch.h</PrecompiledHeaderFile>

View File

@@ -159,6 +159,12 @@
<ClInclude Include="NotificationUtil.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="HighlightedZones.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="DraggingState.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp">
@@ -257,6 +263,9 @@
<ClCompile Include="HighlightedZones.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="DraggingState.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />

View File

@@ -13,17 +13,12 @@
#include <FancyZonesLib/NotificationUtil.h>
#include <FancyZonesLib/WindowUtils.h>
WindowMoveHandler::WindowMoveHandler(const std::function<void()>& 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<HMONITOR, std::shared_ptr<WorkArea>>& workAreaMap) noexcept
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))
{
@@ -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<HMONITOR, std::shared_ptr<WorkArea>>& workAreaMap) noexcept
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;
}
// 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_map<HMONIT
return;
}
bool leftShiftPressed = m_leftShiftKeyState.state();
bool rightShiftPressed = m_rightShiftKeyState.state();
m_mouseHook.disable();
m_leftShiftKeyState.disable();
m_rightShiftKeyState.disable();
m_ctrlKeyState.disable();
if (m_draggedWindowWorkArea)
{
auto workArea = std::move(m_draggedWindowWorkArea);
@@ -204,19 +175,6 @@ void WindowMoveHandler::MoveSizeEnd(HWND window, const std::unordered_map<HMONIT
}
else
{
if (FancyZonesSettings::settings().shiftDrag)
{
if (leftShiftPressed)
{
FancyZonesUtils::SwallowKey(VK_LSHIFT);
}
if (rightShiftPressed)
{
FancyZonesUtils::SwallowKey(VK_RSHIFT);
}
}
workArea->MoveSizeEnd(m_draggedWindow);
}
}
@@ -261,8 +219,6 @@ void WindowMoveHandler::MoveSizeEnd(HWND window, const std::unordered_map<HMONIT
}
m_inDragging = false;
m_dragEnabled = false;
m_mouseState = false;
m_draggedWindow = nullptr;
// Also, hide all windows (regardless of settings)
@@ -316,17 +272,6 @@ void WindowMoveHandler::AssignWindowsToZones(const std::unordered_map<HMONITOR,
}
}
void WindowMoveHandler::UpdateDragState() noexcept
{
if (FancyZonesSettings::settings().shiftDrag)
{
m_dragEnabled = ((m_leftShiftKeyState.state() || m_rightShiftKeyState.state()) ^ m_mouseState);
}
else
{
m_dragEnabled = !((m_leftShiftKeyState.state() || m_rightShiftKeyState.state()) ^ m_mouseState);
}
}
void WindowMoveHandler::SetWindowTransparency(HWND window) noexcept
{

View File

@@ -12,10 +12,10 @@ class WorkArea;
class WindowMoveHandler
{
public:
WindowMoveHandler(const std::function<void()>& keyUpdateCallback);
WindowMoveHandler();
void MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, std::shared_ptr<WorkArea>>& workAreaMap) noexcept;
void MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, std::shared_ptr<WorkArea>>& workAreaMap) noexcept;
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;
@@ -25,22 +25,6 @@ public:
void AssignWindowsToZones(const std::unordered_map<HMONITOR, std::shared_ptr<WorkArea>>& 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<WorkArea> 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<bool> m_mouseState;
SecondaryMouseButtonsHook m_mouseHook;
KeyState<VK_LSHIFT> m_leftShiftKeyState;
KeyState<VK_RSHIFT> m_rightShiftKeyState;
KeyState<VK_LCONTROL, VK_RCONTROL> m_ctrlKeyState;
std::function<void()> m_keyUpdateCallback;
};

View File

@@ -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);
}
}