mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-08 04:07:40 +02:00
[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:
@@ -5,8 +5,9 @@
|
|||||||
#include <FancyZonesLib/util.h>
|
#include <FancyZonesLib/util.h>
|
||||||
|
|
||||||
DraggingState::DraggingState(const std::function<void()>& keyUpdateCallback) :
|
DraggingState::DraggingState(const std::function<void()>& keyUpdateCallback) :
|
||||||
m_mouseState(false),
|
m_secondaryMouseState(false),
|
||||||
m_mouseHook(std::bind(&DraggingState::OnMouseDown, this)),
|
m_middleMouseState(false),
|
||||||
|
m_mouseHook(std::bind(&DraggingState::OnSecondaryMouseDown, this), std::bind(&DraggingState::OnMiddleMouseDown, this)),
|
||||||
m_leftShiftKeyState(keyUpdateCallback),
|
m_leftShiftKeyState(keyUpdateCallback),
|
||||||
m_rightShiftKeyState(keyUpdateCallback),
|
m_rightShiftKeyState(keyUpdateCallback),
|
||||||
m_ctrlKeyState(keyUpdateCallback),
|
m_ctrlKeyState(keyUpdateCallback),
|
||||||
@@ -45,7 +46,8 @@ void DraggingState::Disable()
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_dragging = false;
|
m_dragging = false;
|
||||||
m_mouseState = false;
|
m_secondaryMouseState = false;
|
||||||
|
m_middleMouseState = false;
|
||||||
|
|
||||||
m_mouseHook.disable();
|
m_mouseHook.disable();
|
||||||
m_leftShiftKeyState.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
|
// This updates m_dragEnabled depending on if the shift key is being held down
|
||||||
if (FancyZonesSettings::settings().shiftDrag)
|
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
|
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();
|
m_keyUpdateCallback();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,5 +92,5 @@ bool DraggingState::IsDragging() const noexcept
|
|||||||
|
|
||||||
bool DraggingState::IsSelectManyZonesState() const noexcept
|
bool DraggingState::IsSelectManyZonesState() const noexcept
|
||||||
{
|
{
|
||||||
return m_ctrlKeyState.state();
|
return m_ctrlKeyState.state() || m_middleMouseState;
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <FancyZonesLib/KeyState.h>
|
#include <FancyZonesLib/KeyState.h>
|
||||||
#include <FancyZonesLib/SecondaryMouseButtonsHook.h>
|
#include <FancyZonesLib/MouseButtonsHook.h>
|
||||||
|
|
||||||
class DraggingState
|
class DraggingState
|
||||||
{
|
{
|
||||||
@@ -17,10 +17,12 @@ public:
|
|||||||
bool IsSelectManyZonesState() const noexcept;
|
bool IsSelectManyZonesState() const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void OnMouseDown();
|
void OnSecondaryMouseDown();
|
||||||
|
void OnMiddleMouseDown();
|
||||||
|
|
||||||
std::atomic<bool> m_mouseState;
|
std::atomic<bool> m_secondaryMouseState;
|
||||||
SecondaryMouseButtonsHook m_mouseHook;
|
std::atomic<bool> m_middleMouseState;
|
||||||
|
MouseButtonsHook m_mouseHook;
|
||||||
KeyState<VK_LSHIFT> m_leftShiftKeyState;
|
KeyState<VK_LSHIFT> m_leftShiftKeyState;
|
||||||
KeyState<VK_RSHIFT> m_rightShiftKeyState;
|
KeyState<VK_RSHIFT> m_rightShiftKeyState;
|
||||||
KeyState<VK_LCONTROL, VK_RCONTROL> m_ctrlKeyState;
|
KeyState<VK_LCONTROL, VK_RCONTROL> m_ctrlKeyState;
|
||||||
|
|||||||
@@ -64,7 +64,7 @@
|
|||||||
<ClInclude Include="pch.h" />
|
<ClInclude Include="pch.h" />
|
||||||
<ClInclude Include="Generated Files/resource.h" />
|
<ClInclude Include="Generated Files/resource.h" />
|
||||||
<None Include="resource.base.h" />
|
<None Include="resource.base.h" />
|
||||||
<ClInclude Include="SecondaryMouseButtonsHook.h" />
|
<ClInclude Include="MouseButtonsHook.h" />
|
||||||
<ClInclude Include="Settings.h" />
|
<ClInclude Include="Settings.h" />
|
||||||
<ClInclude Include="SettingsConstants.h" />
|
<ClInclude Include="SettingsConstants.h" />
|
||||||
<ClInclude Include="SettingsObserver.h" />
|
<ClInclude Include="SettingsObserver.h" />
|
||||||
@@ -118,7 +118,7 @@
|
|||||||
<ClCompile Include="pch.cpp">
|
<ClCompile Include="pch.cpp">
|
||||||
<PrecompiledHeader Condition="'$(CIBuild)'!='true'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(CIBuild)'!='true'">Create</PrecompiledHeader>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="SecondaryMouseButtonsHook.cpp" />
|
<ClCompile Include="MouseButtonsHook.cpp" />
|
||||||
<ClCompile Include="Settings.cpp" />
|
<ClCompile Include="Settings.cpp" />
|
||||||
<ClCompile Include="trace.cpp" />
|
<ClCompile Include="trace.cpp" />
|
||||||
<ClCompile Include="util.cpp" />
|
<ClCompile Include="util.cpp" />
|
||||||
|
|||||||
@@ -51,7 +51,7 @@
|
|||||||
<ClInclude Include="FancyZonesWinHookEventIDs.h">
|
<ClInclude Include="FancyZonesWinHookEventIDs.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="SecondaryMouseButtonsHook.h">
|
<ClInclude Include="MouseButtonsHook.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="MonitorWorkAreaMap.h">
|
<ClInclude Include="MonitorWorkAreaMap.h">
|
||||||
@@ -194,7 +194,7 @@
|
|||||||
<ClCompile Include="FancyZonesWinHookEventIDs.cpp">
|
<ClCompile Include="FancyZonesWinHookEventIDs.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="SecondaryMouseButtonsHook.cpp">
|
<ClCompile Include="MouseButtonsHook.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="MonitorWorkAreaMap.cpp">
|
<ClCompile Include="MonitorWorkAreaMap.cpp">
|
||||||
|
|||||||
60
src/modules/fancyzones/FancyZonesLib/MouseButtonsHook.cpp
Normal file
60
src/modules/fancyzones/FancyZonesLib/MouseButtonsHook.cpp
Normal 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
|
||||||
17
src/modules/fancyzones/FancyZonesLib/MouseButtonsHook.h
Normal file
17
src/modules/fancyzones/FancyZonesLib/MouseButtonsHook.h
Normal 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);
|
||||||
|
};
|
||||||
@@ -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
|
|
||||||
@@ -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);
|
|
||||||
};
|
|
||||||
Reference in New Issue
Block a user