diff --git a/src/modules/fancyzones/FancyZonesLib/DraggingState.cpp b/src/modules/fancyzones/FancyZonesLib/DraggingState.cpp index 50aeb3f6fe..bc08d5be0a 100644 --- a/src/modules/fancyzones/FancyZonesLib/DraggingState.cpp +++ b/src/modules/fancyzones/FancyZonesLib/DraggingState.cpp @@ -8,8 +8,6 @@ DraggingState::DraggingState(const std::function& keyUpdateCallback) : 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), m_keyUpdateCallback(keyUpdateCallback) { @@ -22,49 +20,30 @@ void DraggingState::Enable() m_mouseHook.enable(); } - m_leftShiftKeyState.enable(); - m_rightShiftKeyState.enable(); m_ctrlKeyState.enable(); } void DraggingState::Disable() { - const bool leftShiftPressed = m_leftShiftKeyState.state(); - const 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_secondaryMouseState = false; m_middleMouseState = false; + m_shift = 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 + // This updates m_dragging depending on if the shift key is being held down if (FancyZonesSettings::settings().shiftDrag) { - m_dragging = ((m_leftShiftKeyState.state() || m_rightShiftKeyState.state()) ^ m_secondaryMouseState); + m_dragging = (m_shift ^ m_secondaryMouseState); } else { - m_dragging = !((m_leftShiftKeyState.state() || m_rightShiftKeyState.state()) ^ m_secondaryMouseState); + m_dragging = !(m_shift ^ m_secondaryMouseState); } } @@ -96,4 +75,10 @@ bool DraggingState::IsDragging() const noexcept bool DraggingState::IsSelectManyZonesState() const noexcept { return m_ctrlKeyState.state() || m_middleMouseState; -} \ No newline at end of file +} + +void DraggingState::SetShiftState(bool value) noexcept +{ + m_shift = value; + m_keyUpdateCallback(); +} diff --git a/src/modules/fancyzones/FancyZonesLib/DraggingState.h b/src/modules/fancyzones/FancyZonesLib/DraggingState.h index f11db5fe33..d3b2e663a3 100644 --- a/src/modules/fancyzones/FancyZonesLib/DraggingState.h +++ b/src/modules/fancyzones/FancyZonesLib/DraggingState.h @@ -16,6 +16,8 @@ public: bool IsDragging() const noexcept; bool IsSelectManyZonesState() const noexcept; + void SetShiftState(bool value) noexcept; + private: void OnSecondaryMouseDown(); void OnMiddleMouseDown(); @@ -23,9 +25,10 @@ private: std::atomic m_secondaryMouseState; std::atomic m_middleMouseState; MouseButtonsHook m_mouseHook; - KeyState m_leftShiftKeyState; - KeyState m_rightShiftKeyState; KeyState m_ctrlKeyState; + + bool m_shift{}; + 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 d5b35de3cf..b1505c2699 100644 --- a/src/modules/fancyzones/FancyZonesLib/FancyZones.cpp +++ b/src/modules/fancyzones/FancyZonesLib/FancyZones.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -143,6 +144,7 @@ public: void ToggleEditor() noexcept; LRESULT WndProc(HWND, UINT, WPARAM, LPARAM) noexcept; + void OnKeyboardInput(WPARAM flags, HRAWINPUT hInput) noexcept; void OnDisplayChange(DisplayChangeType changeType) noexcept; bool AddWorkArea(HMONITOR monitor, const FancyZonesDataTypes::WorkAreaId& id, const FancyZonesUtils::Rect& rect) noexcept; @@ -220,7 +222,13 @@ FancyZones::Run() noexcept m_window = CreateWindowExW(WS_EX_TOOLWINDOW, NonLocalizable::ToolWindowClassName, L"", WS_POPUP, 0, 0, 0, 0, nullptr, nullptr, m_hinstance, this); if (!m_window) { - Logger::error(L"Failed to create FancyZones window"); + Logger::critical(L"Failed to create FancyZones window"); + return; + } + + if (!KeyboardInput::Initialize(m_window)) + { + Logger::critical(L"Failed to register raw input device"); return; } @@ -580,6 +588,12 @@ LRESULT FancyZones::WndProc(HWND window, UINT message, WPARAM wparam, LPARAM lpa } break; + case WM_INPUT: + { + OnKeyboardInput(wparam, reinterpret_cast(lparam)); + } + break; + case WM_SETTINGCHANGE: { if (wparam == SPI_SETWORKAREA) @@ -717,6 +731,26 @@ LRESULT FancyZones::WndProc(HWND window, UINT message, WPARAM wparam, LPARAM lpa return 0; } +void FancyZones::OnKeyboardInput(WPARAM /*flags*/, HRAWINPUT hInput) noexcept +{ + auto input = KeyboardInput::OnKeyboardInput(hInput); + if (!input.has_value()) + { + return; + } + + switch (input.value().vkKey) + { + case VK_SHIFT: + { + m_draggingState.SetShiftState(input.value().pressed); + } + break; + default: + break; + } +} + void FancyZones::OnDisplayChange(DisplayChangeType changeType) noexcept { Logger::info(L"Display changed, type: {}", DisplayChangeTypeName(changeType)); diff --git a/src/modules/fancyzones/FancyZonesLib/FancyZonesLib.vcxproj b/src/modules/fancyzones/FancyZonesLib/FancyZonesLib.vcxproj index 8b8315edb6..bff83a8d09 100644 --- a/src/modules/fancyzones/FancyZonesLib/FancyZonesLib.vcxproj +++ b/src/modules/fancyzones/FancyZonesLib/FancyZonesLib.vcxproj @@ -53,6 +53,7 @@ + @@ -114,6 +115,7 @@ ../pch.h + diff --git a/src/modules/fancyzones/FancyZonesLib/FancyZonesLib.vcxproj.filters b/src/modules/fancyzones/FancyZonesLib/FancyZonesLib.vcxproj.filters index c72ebd2892..d2a909f577 100644 --- a/src/modules/fancyzones/FancyZonesLib/FancyZonesLib.vcxproj.filters +++ b/src/modules/fancyzones/FancyZonesLib/FancyZonesLib.vcxproj.filters @@ -168,6 +168,9 @@ Header Files\FancyZonesData + + Header Files + @@ -278,6 +281,9 @@ Source Files + + Source Files + diff --git a/src/modules/fancyzones/FancyZonesLib/KeyboardInput.cpp b/src/modules/fancyzones/FancyZonesLib/KeyboardInput.cpp new file mode 100644 index 0000000000..fd0227c5d2 --- /dev/null +++ b/src/modules/fancyzones/FancyZonesLib/KeyboardInput.cpp @@ -0,0 +1,43 @@ +#include "pch.h" +#include "KeyboardInput.h" + +#include + +#include +#include + +bool KeyboardInput::Initialize(HWND window) +{ + RAWINPUTDEVICE inputDevice{}; + inputDevice.usUsagePage = HID_USAGE_PAGE_GENERIC; + inputDevice.usUsage = HID_USAGE_GENERIC_KEYBOARD; + inputDevice.dwFlags = RIDEV_INPUTSINK; + inputDevice.hwndTarget = window; + + bool res = RegisterRawInputDevices(&inputDevice, 1, sizeof(inputDevice)); + if (!res) + { + Logger::error(L"RegisterRawInputDevices error: {}", get_last_error_or_default(GetLastError())); + } + + return res; +} + +std::optional KeyboardInput::OnKeyboardInput(HRAWINPUT hInput) +{ + RAWINPUT input; + UINT size = sizeof(input); + auto result = GetRawInputData(hInput, RID_INPUT, &input, &size, sizeof(RAWINPUTHEADER)); + if (result < sizeof(RAWINPUTHEADER)) + { + return std::nullopt; + } + + if (input.header.dwType == RIM_TYPEKEYBOARD) + { + bool pressed = (input.data.keyboard.Flags & RI_KEY_BREAK) == 0; + return KeyboardInput::Key{ input.data.keyboard.VKey, pressed }; + } + + return std::nullopt; +} \ No newline at end of file diff --git a/src/modules/fancyzones/FancyZonesLib/KeyboardInput.h b/src/modules/fancyzones/FancyZonesLib/KeyboardInput.h new file mode 100644 index 0000000000..3ffbaf1207 --- /dev/null +++ b/src/modules/fancyzones/FancyZonesLib/KeyboardInput.h @@ -0,0 +1,17 @@ +#pragma once + +class KeyboardInput +{ +public: + struct Key + { + USHORT vkKey{}; + bool pressed{}; + }; + + KeyboardInput() = default; + ~KeyboardInput() = default; + + static bool Initialize(HWND window); + static std::optional OnKeyboardInput(HRAWINPUT hInput); +};