Skip to content

Commit

Permalink
[FancyZones] Secondary mouse buttons click to toggle zones activation (
Browse files Browse the repository at this point in the history
…#3989)

* Changed option name in settings, changed behaviour of zones activation by mouse to switch
* Removed IsDragEnabled from ZoneWindow
  • Loading branch information
yevhenii44-zz committed Jun 5, 2020
1 parent e6408a0 commit 8410d7b
Show file tree
Hide file tree
Showing 12 changed files with 134 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@
<value>Make dragged window transparent</value>
</data>
<data name="FancyZones_MouseDragCheckBoxControl_Header.Content" xml:space="preserve">
<value>Hold a non-primary mouse button to activate zones while dragging</value>
<value>Use a non-primary mouse button to toggle zone activation</value>
</data>
<data name="FancyZones_MoveWindowsAcrossAllMonitorsCheckBoxControl.Content" xml:space="preserve">
<value>Move windows between zones across all monitors when snapping with (Win + Arrow)</value>
Expand Down
14 changes: 13 additions & 1 deletion src/modules/fancyzones/lib/FancyZones.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "MonitorWorkAreaHandler.h"

#include <interface/win_hook_event_data.h>
#include <lib/SecondaryMouseButtonsHook.h>

enum class DisplayChangeType
{
Expand All @@ -32,7 +33,8 @@ struct FancyZones : public winrt::implements<FancyZones, IFancyZones, IFancyZone
FancyZones(HINSTANCE hinstance, const winrt::com_ptr<IFancyZonesSettings>& settings) noexcept :
m_hinstance(hinstance),
m_settings(settings),
m_windowMoveHandler(settings)
m_mouseHook(std::bind(&FancyZones::OnMouseDown, this)),
m_windowMoveHandler(settings, &m_mouseHook)
{
m_settings->SetCallback(this);
}
Expand All @@ -43,6 +45,14 @@ struct FancyZones : public winrt::implements<FancyZones, IFancyZones, IFancyZone
IFACEMETHODIMP_(void)
Destroy() noexcept;

void OnMouseDown() noexcept
{
std::unique_lock writeLock(m_lock);
m_windowMoveHandler.OnMouseDown();

PostMessageW(m_window, WM_PRIV_LOCATIONCHANGE, NULL, NULL);
}

void MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen) noexcept
{
std::unique_lock writeLock(m_lock);
Expand All @@ -60,6 +70,7 @@ struct FancyZones : public winrt::implements<FancyZones, IFancyZones, IFancyZone
std::unique_lock writeLock(m_lock);
m_windowMoveHandler.MoveSizeEnd(window, ptScreen, m_workAreaHandler.GetWorkAreasByDesktopId(m_currentDesktopId));
}

IFACEMETHODIMP_(void)
HandleWinHookEvent(const WinHookEvent* data) noexcept
{
Expand Down Expand Up @@ -213,6 +224,7 @@ struct FancyZones : public winrt::implements<FancyZones, IFancyZones, IFancyZone
HWND m_window{};
WindowMoveHandler m_windowMoveHandler;
MonitorWorkAreaHandler m_workAreaHandler;
SecondaryMouseButtonsHook m_mouseHook;

winrt::com_ptr<IFancyZonesSettings> m_settings{};
GUID m_previousDesktopId{}; // UUID of previously active virtual desktop.
Expand Down
2 changes: 2 additions & 0 deletions src/modules/fancyzones/lib/FancyZonesLib.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@
<ClInclude Include="MonitorWorkAreaHandler.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="SecondaryMouseButtonsHook.h" />
<ClInclude Include="Settings.h" />
<ClInclude Include="trace.h" />
<ClInclude Include="util.h" />
Expand All @@ -121,6 +122,7 @@
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(CIBuild)'!='true'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="SecondaryMouseButtonsHook.cpp" />
<ClCompile Include="Settings.cpp" />
<ClCompile Include="trace.cpp" />
<ClCompile Include="util.cpp" />
Expand Down
6 changes: 6 additions & 0 deletions src/modules/fancyzones/lib/FancyZonesLib.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@
<ClInclude Include="FancyZonesWinHookEventIDs.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SecondaryMouseButtonsHook.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="MonitorWorkAreaHandler.h">
<Filter>Header Files</Filter>
</ClInclude>
Expand Down Expand Up @@ -95,6 +98,9 @@
<ClCompile Include="FancyZonesWinHookEventIDs.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SecondaryMouseButtonsHook.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="MonitorWorkAreaHandler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
Expand Down
48 changes: 48 additions & 0 deletions src/modules/fancyzones/lib/SecondaryMouseButtonsHook.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#include "pch.h"
#include "SecondaryMouseButtonsHook.h"

#pragma region public

HHOOK SecondaryMouseButtonsHook::hHook = {};
std::function<void()> SecondaryMouseButtonsHook::callback = {};

SecondaryMouseButtonsHook::SecondaryMouseButtonsHook(std::function<void()> extCallback)
{
callback = std::move(extCallback);
hHook = SetWindowsHookEx(WH_MOUSE_LL, SecondaryMouseButtonsProc, GetModuleHandle(NULL), 0);
}

void SecondaryMouseButtonsHook::enable()
{
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 == (GetSystemMetrics(SM_SWAPBUTTON) ? WM_LBUTTONDOWN : WM_RBUTTONDOWN) || wParam == WM_MBUTTONDOWN || wParam == WM_XBUTTONDOWN)
{
callback();
}
}
return CallNextHookEx(hHook, nCode, wParam, lParam);
}

#pragma endregion
16 changes: 16 additions & 0 deletions src/modules/fancyzones/lib/SecondaryMouseButtonsHook.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#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);
};
67 changes: 33 additions & 34 deletions src/modules/fancyzones/lib/WindowMoveHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "lib/ZoneWindow.h"
#include "lib/util.h"
#include "VirtualDesktopUtils.h"
#include "lib/SecondaryMouseButtonsHook.h"

extern "C" IMAGE_DOS_HEADER __ImageBase;

Expand Down Expand Up @@ -42,13 +43,12 @@ namespace WindowMoveHandlerUtils
}
}


class WindowMoveHandlerPrivate
{
public:
WindowMoveHandlerPrivate(const winrt::com_ptr<IFancyZonesSettings>& settings) :
m_settings(settings)
{};
WindowMoveHandlerPrivate(const winrt::com_ptr<IFancyZonesSettings>& settings, SecondaryMouseButtonsHook* mouseHook) :
m_settings(settings),
m_mouseHook(mouseHook){};

bool IsDragEnabled() const noexcept
{
Expand All @@ -60,7 +60,9 @@ class WindowMoveHandlerPrivate
return m_inMoveSize;
}

void MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR,winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept;
void OnMouseDown() 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 MoveSizeEnd(HWND window, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept;

Expand All @@ -72,19 +74,17 @@ class WindowMoveHandlerPrivate

private:
winrt::com_ptr<IFancyZonesSettings> m_settings{};
SecondaryMouseButtonsHook* m_mouseHook{};

HWND m_windowMoveSize{}; // The window that is being moved/sized
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.
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;
};


WindowMoveHandler::WindowMoveHandler(const winrt::com_ptr<IFancyZonesSettings>& settings) :
pimpl(new WindowMoveHandlerPrivate(settings))
{

}
WindowMoveHandler::WindowMoveHandler(const winrt::com_ptr<IFancyZonesSettings>& settings, SecondaryMouseButtonsHook* mouseHook) :
pimpl(new WindowMoveHandlerPrivate(settings, mouseHook)) {}

WindowMoveHandler::~WindowMoveHandler()
{
Expand All @@ -101,6 +101,11 @@ bool WindowMoveHandler::IsDragEnabled() const noexcept
return pimpl->IsDragEnabled();
}

void WindowMoveHandler::OnMouseDown() noexcept
{
pimpl->OnMouseDown();
}

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);
Expand All @@ -126,6 +131,11 @@ bool WindowMoveHandler::MoveWindowIntoZoneByDirection(HWND window, DWORD vkCode,
return pimpl->MoveWindowIntoZoneByDirection(window, vkCode, cycle, zoneWindow);
}

void WindowMoveHandlerPrivate::OnMouseDown() noexcept
{
m_secondaryMouseButtonState = !m_secondaryMouseButtonState;
}

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())
Expand All @@ -143,13 +153,18 @@ void WindowMoveHandlerPrivate::MoveSizeStart(HWND window, HMONITOR monitor, POIN

m_windowMoveSize = window;

if (m_settings->GetSettings()->mouseSwitch)
{
m_mouseHook->enable();
}

// This updates m_dragEnabled depending on if the shift key is being held down.
UpdateDragState(window);

if (m_dragEnabled)
{
m_zoneWindowMoveSize = iter->second;
m_zoneWindowMoveSize->MoveSizeEnter(window, m_dragEnabled);
m_zoneWindowMoveSize->MoveSizeEnter(window);
if (m_settings->GetSettings()->showZonesOnAllMonitors)
{
for (auto [keyMonitor, zoneWindow] : zoneWindowMap)
Expand Down Expand Up @@ -220,7 +235,7 @@ void WindowMoveHandlerPrivate::MoveSizeUpdate(HMONITOR monitor, POINT const& ptS
m_zoneWindowMoveSize->HideZoneWindow();
}
m_zoneWindowMoveSize = iter->second;
m_zoneWindowMoveSize->MoveSizeEnter(m_windowMoveSize, m_zoneWindowMoveSize->IsDragEnabled());
m_zoneWindowMoveSize->MoveSizeEnter(m_windowMoveSize);
}

for (auto [keyMonitor, zoneWindow] : zoneWindowMap)
Expand All @@ -246,8 +261,11 @@ void WindowMoveHandlerPrivate::MoveSizeEnd(HWND window, POINT const& ptScreen, c
return;
}

m_mouseHook->disable();

m_inMoveSize = false;
m_dragEnabled = false;
m_secondaryMouseButtonState = false;
m_windowMoveSize = nullptr;
if (m_zoneWindowMoveSize)
{
Expand Down Expand Up @@ -304,33 +322,14 @@ bool WindowMoveHandlerPrivate::MoveWindowIntoZoneByDirection(HWND window, DWORD
void WindowMoveHandlerPrivate::UpdateDragState(HWND window) noexcept
{
const bool shift = GetAsyncKeyState(VK_SHIFT) & 0x8000;
const bool mouseL = GetAsyncKeyState(VK_LBUTTON) & 0x8000;
const bool mouseR = GetAsyncKeyState(VK_RBUTTON) & 0x8000;
const bool mouseM = GetAsyncKeyState(VK_MBUTTON) & 0x8000;
const bool mouseX1 = GetAsyncKeyState(VK_XBUTTON1) & 0x8000;
const bool mouseX2 = GetAsyncKeyState(VK_XBUTTON2) & 0x8000;

// Note, Middle, X1 and X2 can also be used in addition to R/L
bool mouse = mouseM | mouseX1 | mouseX2;
// If the user has swapped their Right and Left Buttons, use the "Right" equivalent
if (GetSystemMetrics(SM_SWAPBUTTON))
{
mouse |= mouseL;
}
else
{
mouse |= mouseR;
}

mouse &= m_settings->GetSettings()->mouseSwitch;

if (m_settings->GetSettings()->shiftDrag)
{
m_dragEnabled = (shift | mouse);
m_dragEnabled = (shift ^ m_secondaryMouseButtonState);
}
else
{
m_dragEnabled = !(shift | mouse);
m_dragEnabled = !(shift ^ m_secondaryMouseButtonState);
}

static bool warning_shown = false;
Expand Down
5 changes: 4 additions & 1 deletion src/modules/fancyzones/lib/WindowMoveHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,19 @@

interface IFancyZonesSettings;
interface IZoneWindow;
interface SecondaryMouseButtonsHook;

class WindowMoveHandler
{
public:
WindowMoveHandler(const winrt::com_ptr<IFancyZonesSettings>& settings);
WindowMoveHandler(const winrt::com_ptr<IFancyZonesSettings>& settings, SecondaryMouseButtonsHook* mouseHook);
~WindowMoveHandler();

bool InMoveSize() const noexcept;
bool IsDragEnabled() const noexcept;

void OnMouseDown() 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 MoveSizeEnd(HWND window, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept;
Expand Down
10 changes: 2 additions & 8 deletions src/modules/fancyzones/lib/ZoneWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,13 +206,11 @@ struct ZoneWindow : public winrt::implements<ZoneWindow, IZoneWindow>

bool Init(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, const std::wstring& uniqueId, const std::wstring& parentUniqueId, bool flashZones);

IFACEMETHODIMP MoveSizeEnter(HWND window, bool dragEnabled) noexcept;
IFACEMETHODIMP MoveSizeEnter(HWND window) noexcept;
IFACEMETHODIMP MoveSizeUpdate(POINT const& ptScreen, bool dragEnabled) noexcept;
IFACEMETHODIMP MoveSizeEnd(HWND window, POINT const& ptScreen) noexcept;
IFACEMETHODIMP_(void)
RestoreOriginalTransparency() noexcept;
IFACEMETHODIMP_(bool)
IsDragEnabled() noexcept { return m_dragEnabled; }
IFACEMETHODIMP_(void)
MoveWindowIntoZoneByIndex(HWND window, int index) noexcept;
IFACEMETHODIMP_(void)
Expand Down Expand Up @@ -258,7 +256,6 @@ struct ZoneWindow : public winrt::implements<ZoneWindow, IZoneWindow>
HWND m_windowMoveSize{};
bool m_drawHints{};
bool m_flashMode{};
bool m_dragEnabled{};
winrt::com_ptr<IZoneSet> m_activeZoneSet;
std::vector<winrt::com_ptr<IZoneSet>> m_zoneSets;
std::vector<int> m_highlightZone;
Expand Down Expand Up @@ -342,7 +339,7 @@ bool ZoneWindow::Init(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monit
return true;
}

IFACEMETHODIMP ZoneWindow::MoveSizeEnter(HWND window, bool dragEnabled) noexcept
IFACEMETHODIMP ZoneWindow::MoveSizeEnter(HWND window) noexcept
{
if (m_windowMoveSize)
{
Expand All @@ -363,7 +360,6 @@ IFACEMETHODIMP ZoneWindow::MoveSizeEnter(HWND window, bool dragEnabled) noexcept
SetLayeredWindowAttributes(window, 0, (255 * 50) / 100, LWA_ALPHA);
}

m_dragEnabled = dragEnabled;
m_windowMoveSize = window;
m_drawHints = true;
m_highlightZone = {};
Expand All @@ -377,8 +373,6 @@ IFACEMETHODIMP ZoneWindow::MoveSizeUpdate(POINT const& ptScreen, bool dragEnable
POINT ptClient = ptScreen;
MapWindowPoints(nullptr, m_window.get(), &ptClient, 1);

m_dragEnabled = dragEnabled;

if (dragEnabled)
{
auto highlightZone = ZonesFromPoint(ptClient);
Expand Down

0 comments on commit 8410d7b

Please sign in to comment.