mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-06-07 17:42:45 +08:00
[FancyZones] Changed Shift key capture method (#4274)
* Used windows hook to capture shift key instead of getting state of key on window move
This commit is contained in:
parent
698e5ec6ea
commit
da38e6a23d
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include <interface/win_hook_event_data.h>
|
#include <interface/win_hook_event_data.h>
|
||||||
#include <lib/SecondaryMouseButtonsHook.h>
|
#include <lib/SecondaryMouseButtonsHook.h>
|
||||||
|
#include <lib/ShiftKeyHook.h>
|
||||||
|
|
||||||
enum class DisplayChangeType
|
enum class DisplayChangeType
|
||||||
{
|
{
|
||||||
@ -34,7 +35,8 @@ public:
|
|||||||
m_hinstance(hinstance),
|
m_hinstance(hinstance),
|
||||||
m_settings(settings),
|
m_settings(settings),
|
||||||
m_mouseHook(std::bind(&FancyZones::OnMouseDown, this)),
|
m_mouseHook(std::bind(&FancyZones::OnMouseDown, this)),
|
||||||
m_windowMoveHandler(settings, &m_mouseHook)
|
m_shiftHook(std::bind(&FancyZones::OnShiftChangeState, this, std::placeholders::_1)),
|
||||||
|
m_windowMoveHandler(settings, &m_mouseHook, &m_shiftHook)
|
||||||
{
|
{
|
||||||
m_settings->SetCallback(this);
|
m_settings->SetCallback(this);
|
||||||
}
|
}
|
||||||
@ -47,12 +49,18 @@ public:
|
|||||||
|
|
||||||
void OnMouseDown() noexcept
|
void OnMouseDown() noexcept
|
||||||
{
|
{
|
||||||
std::unique_lock writeLock(m_lock);
|
|
||||||
m_windowMoveHandler.OnMouseDown();
|
m_windowMoveHandler.OnMouseDown();
|
||||||
|
|
||||||
PostMessageW(m_window, WM_PRIV_LOCATIONCHANGE, NULL, NULL);
|
PostMessageW(m_window, WM_PRIV_LOCATIONCHANGE, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OnShiftChangeState(bool state) noexcept
|
||||||
|
{
|
||||||
|
m_windowMoveHandler.OnShiftChangeState(state);
|
||||||
|
|
||||||
|
PostMessageW(m_window, WM_PRIV_LOCATIONCHANGE, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
void MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen) noexcept
|
void MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen) noexcept
|
||||||
{
|
{
|
||||||
std::unique_lock writeLock(m_lock);
|
std::unique_lock writeLock(m_lock);
|
||||||
@ -230,6 +238,7 @@ private:
|
|||||||
WindowMoveHandler m_windowMoveHandler;
|
WindowMoveHandler m_windowMoveHandler;
|
||||||
MonitorWorkAreaHandler m_workAreaHandler;
|
MonitorWorkAreaHandler m_workAreaHandler;
|
||||||
SecondaryMouseButtonsHook m_mouseHook;
|
SecondaryMouseButtonsHook m_mouseHook;
|
||||||
|
ShiftKeyHook m_shiftHook;
|
||||||
|
|
||||||
winrt::com_ptr<IFancyZonesSettings> m_settings{};
|
winrt::com_ptr<IFancyZonesSettings> m_settings{};
|
||||||
GUID m_previousDesktopId{}; // UUID of previously active virtual desktop.
|
GUID m_previousDesktopId{}; // UUID of previously active virtual desktop.
|
||||||
|
@ -106,6 +106,7 @@
|
|||||||
<ClInclude Include="resource.h" />
|
<ClInclude Include="resource.h" />
|
||||||
<ClInclude Include="SecondaryMouseButtonsHook.h" />
|
<ClInclude Include="SecondaryMouseButtonsHook.h" />
|
||||||
<ClInclude Include="Settings.h" />
|
<ClInclude Include="Settings.h" />
|
||||||
|
<ClInclude Include="ShiftKeyHook.h" />
|
||||||
<ClInclude Include="trace.h" />
|
<ClInclude Include="trace.h" />
|
||||||
<ClInclude Include="util.h" />
|
<ClInclude Include="util.h" />
|
||||||
<ClInclude Include="VirtualDesktopUtils.h" />
|
<ClInclude Include="VirtualDesktopUtils.h" />
|
||||||
@ -124,6 +125,7 @@
|
|||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="SecondaryMouseButtonsHook.cpp" />
|
<ClCompile Include="SecondaryMouseButtonsHook.cpp" />
|
||||||
<ClCompile Include="Settings.cpp" />
|
<ClCompile Include="Settings.cpp" />
|
||||||
|
<ClCompile Include="ShiftKeyHook.cpp" />
|
||||||
<ClCompile Include="trace.cpp" />
|
<ClCompile Include="trace.cpp" />
|
||||||
<ClCompile Include="util.cpp" />
|
<ClCompile Include="util.cpp" />
|
||||||
<ClCompile Include="VirtualDesktopUtils.cpp" />
|
<ClCompile Include="VirtualDesktopUtils.cpp" />
|
||||||
|
@ -60,6 +60,9 @@
|
|||||||
<ClInclude Include="MonitorWorkAreaHandler.h">
|
<ClInclude Include="MonitorWorkAreaHandler.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="ShiftKeyHook.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="pch.cpp">
|
<ClCompile Include="pch.cpp">
|
||||||
@ -104,6 +107,9 @@
|
|||||||
<ClCompile Include="MonitorWorkAreaHandler.cpp">
|
<ClCompile Include="MonitorWorkAreaHandler.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="ShiftKeyHook.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="fancyzones.rc">
|
<ResourceCompile Include="fancyzones.rc">
|
||||||
|
60
src/modules/fancyzones/lib/ShiftKeyHook.cpp
Normal file
60
src/modules/fancyzones/lib/ShiftKeyHook.cpp
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#include "pch.h"
|
||||||
|
#include "ShiftKeyHook.h"
|
||||||
|
|
||||||
|
#pragma region public
|
||||||
|
|
||||||
|
HHOOK ShiftKeyHook::hHook = {};
|
||||||
|
std::function<void(bool)> ShiftKeyHook::callback = {};
|
||||||
|
|
||||||
|
ShiftKeyHook::ShiftKeyHook(std::function<void(bool)> extCallback)
|
||||||
|
{
|
||||||
|
callback = std::move(extCallback);
|
||||||
|
hHook = SetWindowsHookEx(WH_KEYBOARD_LL, ShiftKeyHookProc, GetModuleHandle(NULL), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShiftKeyHook::enable()
|
||||||
|
{
|
||||||
|
if (!hHook)
|
||||||
|
{
|
||||||
|
hHook = SetWindowsHookEx(WH_KEYBOARD_LL, ShiftKeyHookProc, GetModuleHandle(NULL), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShiftKeyHook::disable()
|
||||||
|
{
|
||||||
|
if (hHook)
|
||||||
|
{
|
||||||
|
UnhookWindowsHookEx(hHook);
|
||||||
|
hHook = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region private
|
||||||
|
|
||||||
|
LRESULT CALLBACK ShiftKeyHook::ShiftKeyHookProc(int nCode, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
if (nCode == HC_ACTION)
|
||||||
|
{
|
||||||
|
if (wParam == WM_KEYDOWN)
|
||||||
|
{
|
||||||
|
PKBDLLHOOKSTRUCT kbdHookStruct = (PKBDLLHOOKSTRUCT)lParam;
|
||||||
|
if (kbdHookStruct->vkCode == VK_LSHIFT || kbdHookStruct->vkCode == VK_RSHIFT)
|
||||||
|
{
|
||||||
|
callback(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (wParam == WM_KEYUP)
|
||||||
|
{
|
||||||
|
PKBDLLHOOKSTRUCT kbdHookStruct = (PKBDLLHOOKSTRUCT)lParam;
|
||||||
|
if (kbdHookStruct->vkCode == VK_LSHIFT || kbdHookStruct->vkCode == VK_RSHIFT)
|
||||||
|
{
|
||||||
|
callback(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CallNextHookEx(hHook, nCode, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma endregion
|
16
src/modules/fancyzones/lib/ShiftKeyHook.h
Normal file
16
src/modules/fancyzones/lib/ShiftKeyHook.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
class ShiftKeyHook
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ShiftKeyHook(std::function<void(bool)>);
|
||||||
|
void enable();
|
||||||
|
void disable();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static HHOOK hHook;
|
||||||
|
static std::function<void(bool)> callback;
|
||||||
|
static LRESULT CALLBACK ShiftKeyHookProc(int, WPARAM, LPARAM);
|
||||||
|
};
|
@ -10,6 +10,7 @@
|
|||||||
#include "lib/util.h"
|
#include "lib/util.h"
|
||||||
#include "VirtualDesktopUtils.h"
|
#include "VirtualDesktopUtils.h"
|
||||||
#include "lib/SecondaryMouseButtonsHook.h"
|
#include "lib/SecondaryMouseButtonsHook.h"
|
||||||
|
#include <lib/ShiftKeyHook.h>
|
||||||
|
|
||||||
extern "C" IMAGE_DOS_HEADER __ImageBase;
|
extern "C" IMAGE_DOS_HEADER __ImageBase;
|
||||||
|
|
||||||
@ -46,9 +47,10 @@ namespace WindowMoveHandlerUtils
|
|||||||
class WindowMoveHandlerPrivate
|
class WindowMoveHandlerPrivate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WindowMoveHandlerPrivate(const winrt::com_ptr<IFancyZonesSettings>& settings, SecondaryMouseButtonsHook* mouseHook) :
|
WindowMoveHandlerPrivate(const winrt::com_ptr<IFancyZonesSettings>& settings, SecondaryMouseButtonsHook* mouseHook, ShiftKeyHook* shiftHook) :
|
||||||
m_settings(settings),
|
m_settings(settings),
|
||||||
m_mouseHook(mouseHook){};
|
m_mouseHook(mouseHook),
|
||||||
|
m_shiftHook(shiftHook){};
|
||||||
|
|
||||||
bool IsDragEnabled() const noexcept
|
bool IsDragEnabled() const noexcept
|
||||||
{
|
{
|
||||||
@ -61,6 +63,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OnMouseDown() noexcept;
|
void OnMouseDown() noexcept;
|
||||||
|
void OnShiftChangeState(bool state) noexcept;
|
||||||
|
|
||||||
void MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept;
|
void MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept;
|
||||||
void MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept;
|
void MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept;
|
||||||
@ -75,16 +78,18 @@ private:
|
|||||||
private:
|
private:
|
||||||
winrt::com_ptr<IFancyZonesSettings> m_settings{};
|
winrt::com_ptr<IFancyZonesSettings> m_settings{};
|
||||||
SecondaryMouseButtonsHook* m_mouseHook{};
|
SecondaryMouseButtonsHook* m_mouseHook{};
|
||||||
|
ShiftKeyHook* m_shiftHook{};
|
||||||
|
|
||||||
HWND m_windowMoveSize{}; // The window that is being moved/sized
|
HWND m_windowMoveSize{}; // The window that is being moved/sized
|
||||||
bool m_inMoveSize{}; // Whether or not a move/size operation is currently active
|
bool m_inMoveSize{}; // Whether or not a move/size operation is currently active
|
||||||
winrt::com_ptr<IZoneWindow> m_zoneWindowMoveSize; // "Active" ZoneWindow, where the move/size is happening. Will update as drag moves between monitors.
|
winrt::com_ptr<IZoneWindow> m_zoneWindowMoveSize; // "Active" ZoneWindow, 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
|
bool m_dragEnabled{}; // True if we should be showing zone hints while dragging
|
||||||
bool m_secondaryMouseButtonState{}; // True when secondary mouse button was clicked after windows was moved;
|
bool m_secondaryMouseButtonState{}; // True when secondary mouse button was clicked after window was moved
|
||||||
|
bool m_shiftKeyState{}; // True when shift key was pressed after window was moved
|
||||||
};
|
};
|
||||||
|
|
||||||
WindowMoveHandler::WindowMoveHandler(const winrt::com_ptr<IFancyZonesSettings>& settings, SecondaryMouseButtonsHook* mouseHook) :
|
WindowMoveHandler::WindowMoveHandler(const winrt::com_ptr<IFancyZonesSettings>& settings, SecondaryMouseButtonsHook* mouseHook, ShiftKeyHook* shiftHook) :
|
||||||
pimpl(new WindowMoveHandlerPrivate(settings, mouseHook)) {}
|
pimpl(new WindowMoveHandlerPrivate(settings, mouseHook, shiftHook)) {}
|
||||||
|
|
||||||
WindowMoveHandler::~WindowMoveHandler()
|
WindowMoveHandler::~WindowMoveHandler()
|
||||||
{
|
{
|
||||||
@ -106,6 +111,11 @@ void WindowMoveHandler::OnMouseDown() noexcept
|
|||||||
pimpl->OnMouseDown();
|
pimpl->OnMouseDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WindowMoveHandler::OnShiftChangeState(bool state) noexcept
|
||||||
|
{
|
||||||
|
pimpl->OnShiftChangeState(state);
|
||||||
|
}
|
||||||
|
|
||||||
void WindowMoveHandler::MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept
|
void WindowMoveHandler::MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept
|
||||||
{
|
{
|
||||||
pimpl->MoveSizeStart(window, monitor, ptScreen, zoneWindowMap);
|
pimpl->MoveSizeStart(window, monitor, ptScreen, zoneWindowMap);
|
||||||
@ -136,6 +146,11 @@ void WindowMoveHandlerPrivate::OnMouseDown() noexcept
|
|||||||
m_secondaryMouseButtonState = !m_secondaryMouseButtonState;
|
m_secondaryMouseButtonState = !m_secondaryMouseButtonState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WindowMoveHandlerPrivate::OnShiftChangeState(bool state) noexcept
|
||||||
|
{
|
||||||
|
m_shiftKeyState = state;
|
||||||
|
}
|
||||||
|
|
||||||
void WindowMoveHandlerPrivate::MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept
|
void WindowMoveHandlerPrivate::MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept
|
||||||
{
|
{
|
||||||
if (!IsInterestingWindow(window, m_settings->GetSettings()->excludedAppsArray) || WindowMoveHandlerUtils::IsCursorTypeIndicatingSizeEvent())
|
if (!IsInterestingWindow(window, m_settings->GetSettings()->excludedAppsArray) || WindowMoveHandlerUtils::IsCursorTypeIndicatingSizeEvent())
|
||||||
@ -158,6 +173,11 @@ void WindowMoveHandlerPrivate::MoveSizeStart(HWND window, HMONITOR monitor, POIN
|
|||||||
m_mouseHook->enable();
|
m_mouseHook->enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_settings->GetSettings()->shiftDrag)
|
||||||
|
{
|
||||||
|
m_shiftHook->enable();
|
||||||
|
}
|
||||||
|
|
||||||
// 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.
|
||||||
UpdateDragState(window);
|
UpdateDragState(window);
|
||||||
|
|
||||||
@ -262,6 +282,7 @@ void WindowMoveHandlerPrivate::MoveSizeEnd(HWND window, POINT const& ptScreen, c
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_mouseHook->disable();
|
m_mouseHook->disable();
|
||||||
|
m_shiftHook->disable();
|
||||||
|
|
||||||
m_inMoveSize = false;
|
m_inMoveSize = false;
|
||||||
m_dragEnabled = false;
|
m_dragEnabled = false;
|
||||||
@ -321,15 +342,13 @@ bool WindowMoveHandlerPrivate::MoveWindowIntoZoneByDirection(HWND window, DWORD
|
|||||||
|
|
||||||
void WindowMoveHandlerPrivate::UpdateDragState(HWND window) noexcept
|
void WindowMoveHandlerPrivate::UpdateDragState(HWND window) noexcept
|
||||||
{
|
{
|
||||||
const bool shift = GetAsyncKeyState(VK_SHIFT) & 0x8000;
|
|
||||||
|
|
||||||
if (m_settings->GetSettings()->shiftDrag)
|
if (m_settings->GetSettings()->shiftDrag)
|
||||||
{
|
{
|
||||||
m_dragEnabled = (shift ^ m_secondaryMouseButtonState);
|
m_dragEnabled = (m_shiftKeyState ^ m_secondaryMouseButtonState);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_dragEnabled = !(shift ^ m_secondaryMouseButtonState);
|
m_dragEnabled = !(m_shiftKeyState ^ m_secondaryMouseButtonState);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool warning_shown = false;
|
static bool warning_shown = false;
|
||||||
|
@ -2,18 +2,20 @@
|
|||||||
|
|
||||||
interface IFancyZonesSettings;
|
interface IFancyZonesSettings;
|
||||||
interface IZoneWindow;
|
interface IZoneWindow;
|
||||||
interface SecondaryMouseButtonsHook;
|
class SecondaryMouseButtonsHook;
|
||||||
|
class ShiftKeyHook;
|
||||||
|
|
||||||
class WindowMoveHandler
|
class WindowMoveHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WindowMoveHandler(const winrt::com_ptr<IFancyZonesSettings>& settings, SecondaryMouseButtonsHook* mouseHook);
|
WindowMoveHandler(const winrt::com_ptr<IFancyZonesSettings>& settings, SecondaryMouseButtonsHook* mouseHook, ShiftKeyHook* shiftHook);
|
||||||
~WindowMoveHandler();
|
~WindowMoveHandler();
|
||||||
|
|
||||||
bool InMoveSize() const noexcept;
|
bool InMoveSize() const noexcept;
|
||||||
bool IsDragEnabled() const noexcept;
|
bool IsDragEnabled() const noexcept;
|
||||||
|
|
||||||
void OnMouseDown() noexcept;
|
void OnMouseDown() noexcept;
|
||||||
|
void OnShiftChangeState(bool state) noexcept; //True for shift down event false for shift up
|
||||||
|
|
||||||
void MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept;
|
void MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept;
|
||||||
void MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept;
|
void MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept;
|
||||||
|
Loading…
Reference in New Issue
Block a user