[Fancy Zones] Middle click to toggle spanning multiple zones (#26079)

* Attempt to use middle click to toggle zone spanning

* Merge Middle and Secondary Button hooks

* Make mouse state variables more identifiable.
This commit is contained in:
Basit Ali
2023-06-13 14:31:22 +05:00
committed by GitHub
parent 06e4518742
commit c69c74a8ad
8 changed files with 108 additions and 86 deletions

View File

@@ -5,8 +5,9 @@
#include <FancyZonesLib/util.h>
DraggingState::DraggingState(const std::function<void()>& keyUpdateCallback) :
m_mouseState(false),
m_mouseHook(std::bind(&DraggingState::OnMouseDown, this)),
m_secondaryMouseState(false),
m_middleMouseState(false),
m_mouseHook(std::bind(&DraggingState::OnSecondaryMouseDown, this), std::bind(&DraggingState::OnMiddleMouseDown, this)),
m_leftShiftKeyState(keyUpdateCallback),
m_rightShiftKeyState(keyUpdateCallback),
m_ctrlKeyState(keyUpdateCallback),
@@ -45,7 +46,8 @@ void DraggingState::Disable()
}
m_dragging = false;
m_mouseState = false;
m_secondaryMouseState = false;
m_middleMouseState = false;
m_mouseHook.disable();
m_leftShiftKeyState.disable();
@@ -58,17 +60,28 @@ 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);
m_dragging = ((m_leftShiftKeyState.state() || m_rightShiftKeyState.state()) ^ m_secondaryMouseState);
}
else
{
m_dragging = !((m_leftShiftKeyState.state() || m_rightShiftKeyState.state()) ^ m_mouseState);
m_dragging = !((m_leftShiftKeyState.state() || m_rightShiftKeyState.state()) ^ m_secondaryMouseState);
}
}
void DraggingState::OnMouseDown()
void DraggingState::OnSecondaryMouseDown()
{
m_mouseState = !m_mouseState;
m_secondaryMouseState = !m_secondaryMouseState;
m_keyUpdateCallback();
}
void DraggingState::OnMiddleMouseDown()
{
if (!this->IsDragging())
{
return;
}
m_middleMouseState = !m_middleMouseState;
m_keyUpdateCallback();
}
@@ -79,5 +92,5 @@ bool DraggingState::IsDragging() const noexcept
bool DraggingState::IsSelectManyZonesState() const noexcept
{
return m_ctrlKeyState.state();
return m_ctrlKeyState.state() || m_middleMouseState;
}

View File

@@ -1,7 +1,7 @@
#pragma once
#include <FancyZonesLib/KeyState.h>
#include <FancyZonesLib/SecondaryMouseButtonsHook.h>
#include <FancyZonesLib/MouseButtonsHook.h>
class DraggingState
{
@@ -17,10 +17,12 @@ public:
bool IsSelectManyZonesState() const noexcept;
private:
void OnMouseDown();
void OnSecondaryMouseDown();
void OnMiddleMouseDown();
std::atomic<bool> m_mouseState;
SecondaryMouseButtonsHook m_mouseHook;
std::atomic<bool> m_secondaryMouseState;
std::atomic<bool> m_middleMouseState;
MouseButtonsHook m_mouseHook;
KeyState<VK_LSHIFT> m_leftShiftKeyState;
KeyState<VK_RSHIFT> m_rightShiftKeyState;
KeyState<VK_LCONTROL, VK_RCONTROL> m_ctrlKeyState;

View File

@@ -64,7 +64,7 @@
<ClInclude Include="pch.h" />
<ClInclude Include="Generated Files/resource.h" />
<None Include="resource.base.h" />
<ClInclude Include="SecondaryMouseButtonsHook.h" />
<ClInclude Include="MouseButtonsHook.h" />
<ClInclude Include="Settings.h" />
<ClInclude Include="SettingsConstants.h" />
<ClInclude Include="SettingsObserver.h" />
@@ -118,7 +118,7 @@
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(CIBuild)'!='true'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="SecondaryMouseButtonsHook.cpp" />
<ClCompile Include="MouseButtonsHook.cpp" />
<ClCompile Include="Settings.cpp" />
<ClCompile Include="trace.cpp" />
<ClCompile Include="util.cpp" />

View File

@@ -51,7 +51,7 @@
<ClInclude Include="FancyZonesWinHookEventIDs.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SecondaryMouseButtonsHook.h">
<ClInclude Include="MouseButtonsHook.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="MonitorWorkAreaMap.h">
@@ -194,7 +194,7 @@
<ClCompile Include="FancyZonesWinHookEventIDs.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SecondaryMouseButtonsHook.cpp">
<ClCompile Include="MouseButtonsHook.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="MonitorWorkAreaMap.cpp">

View File

@@ -0,0 +1,60 @@
#include "pch.h"
#include "MouseButtonsHook.h"
#include <common/debug_control.h>
#pragma region public
HHOOK MouseButtonsHook::hHook = {};
std::function<void()> MouseButtonsHook::secondaryClickCallback = {};
std::function<void()> MouseButtonsHook::middleClickCallback = {};
MouseButtonsHook::MouseButtonsHook(std::function<void()> extRightClickCallback, std::function<void()> extMiddleClickCallback)
{
secondaryClickCallback = std::move(extRightClickCallback);
middleClickCallback = std::move(extMiddleClickCallback);
}
void MouseButtonsHook::enable()
{
#if defined(DISABLE_LOWLEVEL_HOOKS_WHEN_DEBUGGED)
if (IsDebuggerPresent())
{
return;
}
#endif
if (!hHook)
{
hHook = SetWindowsHookEx(WH_MOUSE_LL, MouseButtonsProc, GetModuleHandle(NULL), 0);
}
}
void MouseButtonsHook::disable()
{
if (hHook)
{
UnhookWindowsHookEx(hHook);
hHook = NULL;
}
}
#pragma endregion
#pragma region private
LRESULT CALLBACK MouseButtonsHook::MouseButtonsProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HC_ACTION)
{
if (wParam == WM_RBUTTONDOWN || wParam == WM_XBUTTONDOWN)
{
secondaryClickCallback();
}
else if (wParam == WM_MBUTTONDOWN)
{
middleClickCallback();
}
}
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
#pragma endregion

View File

@@ -0,0 +1,17 @@
#pragma once
#include <functional>
class MouseButtonsHook
{
public:
MouseButtonsHook(std::function<void()>, std::function<void()>);
void enable();
void disable();
private:
static HHOOK hHook;
static std::function<void()> middleClickCallback;
static std::function<void()> secondaryClickCallback;
static LRESULT CALLBACK MouseButtonsProc(int, WPARAM, LPARAM);
};

View File

@@ -1,54 +0,0 @@
#include "pch.h"
#include "SecondaryMouseButtonsHook.h"
#include <common/debug_control.h>
#pragma region public
HHOOK SecondaryMouseButtonsHook::hHook = {};
std::function<void()> SecondaryMouseButtonsHook::callback = {};
SecondaryMouseButtonsHook::SecondaryMouseButtonsHook(std::function<void()> extCallback)
{
callback = std::move(extCallback);
}
void SecondaryMouseButtonsHook::enable()
{
#if defined(DISABLE_LOWLEVEL_HOOKS_WHEN_DEBUGGED)
if (IsDebuggerPresent())
{
return;
}
#endif
if (!hHook)
{
hHook = SetWindowsHookEx(WH_MOUSE_LL, SecondaryMouseButtonsProc, GetModuleHandle(NULL), 0);
}
}
void SecondaryMouseButtonsHook::disable()
{
if (hHook)
{
UnhookWindowsHookEx(hHook);
hHook = NULL;
}
}
#pragma endregion
#pragma region private
LRESULT CALLBACK SecondaryMouseButtonsHook::SecondaryMouseButtonsProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HC_ACTION)
{
if (wParam == WM_RBUTTONDOWN || wParam == WM_MBUTTONDOWN || wParam == WM_XBUTTONDOWN)
{
callback();
}
}
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
#pragma endregion

View File

@@ -1,16 +0,0 @@
#pragma once
#include <functional>
class SecondaryMouseButtonsHook
{
public:
SecondaryMouseButtonsHook(std::function<void()>);
void enable();
void disable();
private:
static HHOOK hHook;
static std::function<void()> callback;
static LRESULT CALLBACK SecondaryMouseButtonsProc(int, WPARAM, LPARAM);
};