2020-04-30 18:16:08 +08:00
|
|
|
#include "pch.h"
|
|
|
|
#include "WindowMoveHandler.h"
|
|
|
|
|
|
|
|
#include <common/notifications.h>
|
|
|
|
#include <common/notifications/fancyzones_notifications.h>
|
|
|
|
#include <common/window_helpers.h>
|
2020-07-01 21:36:05 +08:00
|
|
|
#include <common/dpi_aware.h>
|
2020-04-30 18:16:08 +08:00
|
|
|
|
|
|
|
#include "lib/Settings.h"
|
|
|
|
#include "lib/ZoneWindow.h"
|
|
|
|
#include "lib/util.h"
|
2020-05-06 23:16:16 +08:00
|
|
|
#include "VirtualDesktopUtils.h"
|
2020-06-05 22:53:08 +08:00
|
|
|
#include "lib/SecondaryMouseButtonsHook.h"
|
2020-07-10 17:06:01 +08:00
|
|
|
#include "lib/GenericKeyHook.h"
|
2020-07-22 16:39:13 +08:00
|
|
|
#include "lib/FancyZonesData.h"
|
2020-08-24 15:19:39 +08:00
|
|
|
#include "lib/KeyState.h"
|
2020-04-30 18:16:08 +08:00
|
|
|
|
|
|
|
extern "C" IMAGE_DOS_HEADER __ImageBase;
|
|
|
|
|
2020-08-11 19:51:06 +08:00
|
|
|
// Non-Localizable strings
|
|
|
|
namespace NonLocalizable
|
2020-07-28 00:53:29 +08:00
|
|
|
{
|
2020-08-11 19:51:06 +08:00
|
|
|
const wchar_t FancyZonesRunAsAdminInfoPage[] = L"https://aka.ms/powertoysDetectedElevatedHelp";
|
|
|
|
const wchar_t ToastNotificationButtonUrl[] = L"powertoys://cant_drag_elevated_disable/";
|
2020-07-28 00:53:29 +08:00
|
|
|
}
|
|
|
|
|
2020-04-30 18:16:08 +08:00
|
|
|
namespace WindowMoveHandlerUtils
|
|
|
|
{
|
|
|
|
bool IsCursorTypeIndicatingSizeEvent()
|
|
|
|
{
|
|
|
|
CURSORINFO cursorInfo = { 0 };
|
|
|
|
cursorInfo.cbSize = sizeof(cursorInfo);
|
|
|
|
|
|
|
|
if (::GetCursorInfo(&cursorInfo))
|
|
|
|
{
|
|
|
|
if (::LoadCursor(NULL, IDC_SIZENS) == cursorInfo.hCursor)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (::LoadCursor(NULL, IDC_SIZEWE) == cursorInfo.hCursor)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (::LoadCursor(NULL, IDC_SIZENESW) == cursorInfo.hCursor)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (::LoadCursor(NULL, IDC_SIZENWSE) == cursorInfo.hCursor)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class WindowMoveHandlerPrivate
|
|
|
|
{
|
|
|
|
public:
|
2020-08-24 15:19:39 +08:00
|
|
|
WindowMoveHandlerPrivate(const winrt::com_ptr<IFancyZonesSettings>& settings, const std::function<void()>& keyUpdateCallback) :
|
2020-06-05 22:53:08 +08:00
|
|
|
m_settings(settings),
|
2020-08-24 15:19:39 +08:00
|
|
|
m_mouseState(false),
|
|
|
|
m_mouseHook(std::bind(&WindowMoveHandlerPrivate::OnMouseDown, this)),
|
|
|
|
m_shiftKeyState(keyUpdateCallback),
|
|
|
|
m_ctrlKeyState(keyUpdateCallback),
|
|
|
|
m_keyUpdateCallback(keyUpdateCallback)
|
2020-07-10 17:06:01 +08:00
|
|
|
{
|
|
|
|
}
|
2020-04-30 18:16:08 +08:00
|
|
|
|
|
|
|
bool IsDragEnabled() const noexcept
|
|
|
|
{
|
|
|
|
return m_dragEnabled;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool InMoveSize() const noexcept
|
|
|
|
{
|
|
|
|
return m_inMoveSize;
|
|
|
|
}
|
|
|
|
|
2020-06-05 22:53:08 +08:00
|
|
|
void MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept;
|
2020-05-31 18:36:45 +08:00
|
|
|
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;
|
2020-04-30 18:16:08 +08:00
|
|
|
|
2020-08-24 20:39:34 +08:00
|
|
|
void MoveWindowIntoZoneByIndexSet(HWND window, const std::vector<size_t>& indexSet, winrt::com_ptr<IZoneWindow> zoneWindow) noexcept;
|
2020-08-21 18:53:03 +08:00
|
|
|
bool MoveWindowIntoZoneByDirectionAndIndex(HWND window, DWORD vkCode, bool cycle, winrt::com_ptr<IZoneWindow> zoneWindow);
|
|
|
|
bool MoveWindowIntoZoneByDirectionAndPosition(HWND window, DWORD vkCode, bool cycle, winrt::com_ptr<IZoneWindow> zoneWindow);
|
2020-04-30 18:16:08 +08:00
|
|
|
|
|
|
|
private:
|
2020-07-23 00:00:03 +08:00
|
|
|
void WarnIfElevationIsRequired(HWND window) noexcept;
|
|
|
|
void UpdateDragState() noexcept;
|
|
|
|
|
|
|
|
void SetWindowTransparency(HWND window) noexcept;
|
|
|
|
void ResetWindowTransparency() noexcept;
|
2020-04-30 18:16:08 +08:00
|
|
|
|
2020-08-24 15:19:39 +08:00
|
|
|
inline void OnMouseDown() noexcept
|
|
|
|
{
|
|
|
|
m_mouseState = !m_mouseState;
|
|
|
|
m_keyUpdateCallback();
|
|
|
|
}
|
|
|
|
|
2020-04-30 18:16:08 +08:00
|
|
|
private:
|
|
|
|
winrt::com_ptr<IFancyZonesSettings> m_settings{};
|
|
|
|
|
|
|
|
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
|
2020-08-24 15:19:39 +08:00
|
|
|
|
|
|
|
std::atomic<bool> m_mouseState;
|
|
|
|
SecondaryMouseButtonsHook m_mouseHook;
|
|
|
|
KeyState<VK_LSHIFT, VK_RSHIFT> m_shiftKeyState;
|
|
|
|
KeyState<VK_LCONTROL, VK_RCONTROL> m_ctrlKeyState;
|
|
|
|
std::function<void()> m_keyUpdateCallback;
|
2020-07-23 00:00:03 +08:00
|
|
|
|
|
|
|
struct WindowTransparencyProperties
|
|
|
|
{
|
|
|
|
HWND draggedWindow = nullptr;
|
|
|
|
long draggedWindowExstyle = 0;
|
|
|
|
COLORREF draggedWindowCrKey = RGB(0, 0, 0);
|
|
|
|
DWORD draggedWindowDwFlags = 0;
|
|
|
|
BYTE draggedWindowInitialAlpha = 0;
|
|
|
|
} m_windowTransparencyProperties;
|
2020-04-30 18:16:08 +08:00
|
|
|
};
|
|
|
|
|
2020-08-24 15:19:39 +08:00
|
|
|
WindowMoveHandler::WindowMoveHandler(const winrt::com_ptr<IFancyZonesSettings>& settings, const std::function<void()>& keyUpdateCallback) :
|
|
|
|
pimpl(new WindowMoveHandlerPrivate(settings, keyUpdateCallback)) {}
|
2020-04-30 18:16:08 +08:00
|
|
|
|
|
|
|
WindowMoveHandler::~WindowMoveHandler()
|
|
|
|
{
|
|
|
|
delete pimpl;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool WindowMoveHandler::InMoveSize() const noexcept
|
|
|
|
{
|
|
|
|
return pimpl->InMoveSize();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool WindowMoveHandler::IsDragEnabled() const noexcept
|
|
|
|
{
|
|
|
|
return pimpl->IsDragEnabled();
|
|
|
|
}
|
|
|
|
|
2020-05-31 18:36:45 +08:00
|
|
|
void WindowMoveHandler::MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept
|
2020-04-30 18:16:08 +08:00
|
|
|
{
|
|
|
|
pimpl->MoveSizeStart(window, monitor, ptScreen, zoneWindowMap);
|
|
|
|
}
|
|
|
|
|
2020-05-31 18:36:45 +08:00
|
|
|
void WindowMoveHandler::MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept
|
2020-04-30 18:16:08 +08:00
|
|
|
{
|
|
|
|
pimpl->MoveSizeUpdate(monitor, ptScreen, zoneWindowMap);
|
|
|
|
}
|
|
|
|
|
2020-05-31 18:36:45 +08:00
|
|
|
void WindowMoveHandler::MoveSizeEnd(HWND window, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept
|
2020-04-30 18:16:08 +08:00
|
|
|
{
|
|
|
|
pimpl->MoveSizeEnd(window, ptScreen, zoneWindowMap);
|
|
|
|
}
|
|
|
|
|
2020-08-24 20:39:34 +08:00
|
|
|
void WindowMoveHandler::MoveWindowIntoZoneByIndexSet(HWND window, const std::vector<size_t>& indexSet, winrt::com_ptr<IZoneWindow> zoneWindow) noexcept
|
2020-04-30 18:16:08 +08:00
|
|
|
{
|
2020-05-31 18:36:45 +08:00
|
|
|
pimpl->MoveWindowIntoZoneByIndexSet(window, indexSet, zoneWindow);
|
2020-04-30 18:16:08 +08:00
|
|
|
}
|
|
|
|
|
2020-08-21 18:53:03 +08:00
|
|
|
bool WindowMoveHandler::MoveWindowIntoZoneByDirectionAndIndex(HWND window, DWORD vkCode, bool cycle, winrt::com_ptr<IZoneWindow> zoneWindow)
|
2020-04-30 18:16:08 +08:00
|
|
|
{
|
2020-08-21 18:53:03 +08:00
|
|
|
return pimpl->MoveWindowIntoZoneByDirectionAndIndex(window, vkCode, cycle, zoneWindow);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool WindowMoveHandler::MoveWindowIntoZoneByDirectionAndPosition(HWND window, DWORD vkCode, bool cycle, winrt::com_ptr<IZoneWindow> zoneWindow)
|
|
|
|
{
|
|
|
|
return pimpl->MoveWindowIntoZoneByDirectionAndPosition(window, vkCode, cycle, zoneWindow);
|
2020-04-30 18:16:08 +08:00
|
|
|
}
|
|
|
|
|
2020-05-31 18:36:45 +08:00
|
|
|
void WindowMoveHandlerPrivate::MoveSizeStart(HWND window, HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept
|
2020-04-30 18:16:08 +08:00
|
|
|
{
|
|
|
|
if (!IsInterestingWindow(window, m_settings->GetSettings()->excludedAppsArray) || WindowMoveHandlerUtils::IsCursorTypeIndicatingSizeEvent())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_inMoveSize = true;
|
|
|
|
|
|
|
|
auto iter = zoneWindowMap.find(monitor);
|
|
|
|
if (iter == end(zoneWindowMap))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_windowMoveSize = window;
|
|
|
|
|
2020-06-05 22:53:08 +08:00
|
|
|
if (m_settings->GetSettings()->mouseSwitch)
|
|
|
|
{
|
2020-08-24 15:19:39 +08:00
|
|
|
m_mouseHook.enable();
|
2020-06-05 22:53:08 +08:00
|
|
|
}
|
|
|
|
|
2020-08-24 15:19:39 +08:00
|
|
|
m_shiftKeyState.enable();
|
|
|
|
m_ctrlKeyState.enable();
|
2020-06-17 21:06:16 +08:00
|
|
|
|
2020-07-23 00:00:03 +08:00
|
|
|
// This updates m_dragEnabled depending on if the shift key is being held down
|
|
|
|
UpdateDragState();
|
|
|
|
|
|
|
|
// Notifies user if unable to drag elevated window
|
|
|
|
WarnIfElevationIsRequired(window);
|
2020-04-30 18:16:08 +08:00
|
|
|
|
|
|
|
if (m_dragEnabled)
|
|
|
|
{
|
|
|
|
m_zoneWindowMoveSize = iter->second;
|
2020-07-23 00:00:03 +08:00
|
|
|
SetWindowTransparency(m_windowMoveSize);
|
|
|
|
m_zoneWindowMoveSize->MoveSizeEnter(m_windowMoveSize);
|
2020-04-30 18:16:08 +08:00
|
|
|
if (m_settings->GetSettings()->showZonesOnAllMonitors)
|
|
|
|
{
|
|
|
|
for (auto [keyMonitor, zoneWindow] : zoneWindowMap)
|
|
|
|
{
|
|
|
|
// Skip calling ShowZoneWindow for iter->second (m_zoneWindowMoveSize) since it
|
|
|
|
// was already called in MoveSizeEnter
|
|
|
|
const bool moveSizeEnterCalled = zoneWindow == m_zoneWindowMoveSize;
|
|
|
|
if (zoneWindow && !moveSizeEnterCalled)
|
|
|
|
{
|
|
|
|
zoneWindow->ShowZoneWindow();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (m_zoneWindowMoveSize)
|
|
|
|
{
|
2020-07-23 00:00:03 +08:00
|
|
|
ResetWindowTransparency();
|
2020-04-30 18:16:08 +08:00
|
|
|
m_zoneWindowMoveSize = nullptr;
|
|
|
|
for (auto [keyMonitor, zoneWindow] : zoneWindowMap)
|
|
|
|
{
|
|
|
|
if (zoneWindow)
|
|
|
|
{
|
|
|
|
zoneWindow->HideZoneWindow();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-31 18:36:45 +08:00
|
|
|
void WindowMoveHandlerPrivate::MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept
|
2020-04-30 18:16:08 +08:00
|
|
|
{
|
|
|
|
if (!m_inMoveSize)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// This updates m_dragEnabled depending on if the shift key is being held down.
|
2020-07-23 00:00:03 +08:00
|
|
|
UpdateDragState();
|
2020-04-30 18:16:08 +08:00
|
|
|
|
|
|
|
if (m_zoneWindowMoveSize)
|
|
|
|
{
|
|
|
|
// Update the ZoneWindow already handling move/size
|
|
|
|
if (!m_dragEnabled)
|
|
|
|
{
|
|
|
|
// Drag got disabled, tell it to cancel and hide all windows
|
|
|
|
m_zoneWindowMoveSize = nullptr;
|
2020-07-23 00:00:03 +08:00
|
|
|
ResetWindowTransparency();
|
2020-04-30 18:16:08 +08:00
|
|
|
|
|
|
|
for (auto [keyMonitor, zoneWindow] : zoneWindowMap)
|
|
|
|
{
|
|
|
|
if (zoneWindow)
|
|
|
|
{
|
|
|
|
zoneWindow->HideZoneWindow();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
auto iter = zoneWindowMap.find(monitor);
|
|
|
|
if (iter != zoneWindowMap.end())
|
|
|
|
{
|
|
|
|
if (iter->second != m_zoneWindowMoveSize)
|
|
|
|
{
|
|
|
|
// The drag has moved to a different monitor.
|
2020-07-10 17:06:01 +08:00
|
|
|
m_zoneWindowMoveSize->ClearSelectedZones();
|
2020-04-30 18:16:08 +08:00
|
|
|
if (!m_settings->GetSettings()->showZonesOnAllMonitors)
|
|
|
|
{
|
|
|
|
m_zoneWindowMoveSize->HideZoneWindow();
|
|
|
|
}
|
2020-07-23 00:00:03 +08:00
|
|
|
|
2020-04-30 18:16:08 +08:00
|
|
|
m_zoneWindowMoveSize = iter->second;
|
2020-06-05 22:53:08 +08:00
|
|
|
m_zoneWindowMoveSize->MoveSizeEnter(m_windowMoveSize);
|
2020-04-30 18:16:08 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
for (auto [keyMonitor, zoneWindow] : zoneWindowMap)
|
|
|
|
{
|
2020-08-24 15:19:39 +08:00
|
|
|
zoneWindow->MoveSizeUpdate(ptScreen, m_dragEnabled, m_ctrlKeyState.state());
|
2020-04-30 18:16:08 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (m_dragEnabled)
|
|
|
|
{
|
|
|
|
// We'll get here if the user presses/releases shift while dragging.
|
|
|
|
// Restart the drag on the ZoneWindow that m_windowMoveSize is on
|
|
|
|
MoveSizeStart(m_windowMoveSize, monitor, ptScreen, zoneWindowMap);
|
|
|
|
MoveSizeUpdate(monitor, ptScreen, zoneWindowMap);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-31 18:36:45 +08:00
|
|
|
void WindowMoveHandlerPrivate::MoveSizeEnd(HWND window, POINT const& ptScreen, const std::unordered_map<HMONITOR, winrt::com_ptr<IZoneWindow>>& zoneWindowMap) noexcept
|
2020-04-30 18:16:08 +08:00
|
|
|
{
|
|
|
|
if (window != m_windowMoveSize && !IsInterestingWindow(window, m_settings->GetSettings()->excludedAppsArray))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-08-24 15:19:39 +08:00
|
|
|
m_mouseHook.disable();
|
|
|
|
m_shiftKeyState.disable();
|
|
|
|
m_ctrlKeyState.disable();
|
2020-06-05 22:53:08 +08:00
|
|
|
|
2020-04-30 18:16:08 +08:00
|
|
|
if (m_zoneWindowMoveSize)
|
|
|
|
{
|
|
|
|
auto zoneWindow = std::move(m_zoneWindowMoveSize);
|
2020-07-23 00:00:03 +08:00
|
|
|
ResetWindowTransparency();
|
|
|
|
zoneWindow->MoveSizeEnd(m_windowMoveSize, ptScreen);
|
2020-04-30 18:16:08 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-07-01 21:36:05 +08:00
|
|
|
if (m_settings->GetSettings()->restoreSize)
|
|
|
|
{
|
|
|
|
if (WindowMoveHandlerUtils::IsCursorTypeIndicatingSizeEvent())
|
|
|
|
{
|
2020-08-11 19:51:06 +08:00
|
|
|
::RemoveProp(window, ZonedWindowProperties::PropertyRestoreSizeID);
|
2020-07-01 21:36:05 +08:00
|
|
|
}
|
2020-08-06 21:12:49 +08:00
|
|
|
else if (!IsWindowMaximized(window))
|
2020-07-01 21:36:05 +08:00
|
|
|
{
|
|
|
|
RestoreWindowSize(window);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-30 18:16:08 +08:00
|
|
|
auto monitor = MonitorFromWindow(window, MONITOR_DEFAULTTONULL);
|
|
|
|
if (monitor)
|
|
|
|
{
|
|
|
|
auto zoneWindow = zoneWindowMap.find(monitor);
|
|
|
|
if (zoneWindow != zoneWindowMap.end())
|
|
|
|
{
|
|
|
|
const auto zoneWindowPtr = zoneWindow->second;
|
|
|
|
const auto activeZoneSet = zoneWindowPtr->ActiveZoneSet();
|
|
|
|
if (activeZoneSet)
|
|
|
|
{
|
|
|
|
wil::unique_cotaskmem_string guidString;
|
|
|
|
if (SUCCEEDED_LOG(StringFromCLSID(activeZoneSet->Id(), &guidString)))
|
|
|
|
{
|
2020-07-22 16:39:13 +08:00
|
|
|
FancyZonesDataInstance().RemoveAppLastZone(window, zoneWindowPtr->UniqueId(), guidString.get());
|
2020-04-30 18:16:08 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-08-11 19:51:06 +08:00
|
|
|
::RemoveProp(window, ZonedWindowProperties::PropertyMultipleZoneID);
|
2020-04-30 18:16:08 +08:00
|
|
|
}
|
2020-07-23 00:00:03 +08:00
|
|
|
|
|
|
|
m_inMoveSize = false;
|
|
|
|
m_dragEnabled = false;
|
2020-08-24 15:19:39 +08:00
|
|
|
m_mouseState = false;
|
2020-07-23 00:00:03 +08:00
|
|
|
m_windowMoveSize = nullptr;
|
2020-04-30 18:16:08 +08:00
|
|
|
|
|
|
|
// Also, hide all windows (regardless of settings)
|
|
|
|
for (auto [keyMonitor, zoneWindow] : zoneWindowMap)
|
|
|
|
{
|
|
|
|
if (zoneWindow)
|
|
|
|
{
|
|
|
|
zoneWindow->HideZoneWindow();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-24 20:39:34 +08:00
|
|
|
void WindowMoveHandlerPrivate::MoveWindowIntoZoneByIndexSet(HWND window, const std::vector<size_t>& indexSet, winrt::com_ptr<IZoneWindow> zoneWindow) noexcept
|
2020-04-30 18:16:08 +08:00
|
|
|
{
|
|
|
|
if (window != m_windowMoveSize)
|
|
|
|
{
|
2020-05-31 18:36:45 +08:00
|
|
|
zoneWindow->MoveWindowIntoZoneByIndexSet(window, indexSet);
|
2020-04-30 18:16:08 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-21 18:53:03 +08:00
|
|
|
bool WindowMoveHandlerPrivate::MoveWindowIntoZoneByDirectionAndIndex(HWND window, DWORD vkCode, bool cycle, winrt::com_ptr<IZoneWindow> zoneWindow)
|
|
|
|
{
|
|
|
|
return zoneWindow && zoneWindow->MoveWindowIntoZoneByDirectionAndIndex(window, vkCode, cycle);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool WindowMoveHandlerPrivate::MoveWindowIntoZoneByDirectionAndPosition(HWND window, DWORD vkCode, bool cycle, winrt::com_ptr<IZoneWindow> zoneWindow)
|
2020-04-30 18:16:08 +08:00
|
|
|
{
|
2020-08-21 18:53:03 +08:00
|
|
|
return zoneWindow && zoneWindow->MoveWindowIntoZoneByDirectionAndPosition(window, vkCode, cycle);
|
2020-04-30 18:16:08 +08:00
|
|
|
}
|
|
|
|
|
2020-07-23 00:00:03 +08:00
|
|
|
void WindowMoveHandlerPrivate::WarnIfElevationIsRequired(HWND window) noexcept
|
2020-04-30 18:16:08 +08:00
|
|
|
{
|
|
|
|
static bool warning_shown = false;
|
|
|
|
if (!is_process_elevated() && IsProcessOfWindowElevated(window))
|
|
|
|
{
|
|
|
|
m_dragEnabled = false;
|
|
|
|
if (!warning_shown && !is_cant_drag_elevated_warning_disabled())
|
|
|
|
{
|
|
|
|
std::vector<notifications::action_t> actions = {
|
2020-08-11 19:51:06 +08:00
|
|
|
notifications::link_button{ GET_RESOURCE_STRING(IDS_CANT_DRAG_ELEVATED_LEARN_MORE), NonLocalizable::FancyZonesRunAsAdminInfoPage },
|
|
|
|
notifications::link_button{ GET_RESOURCE_STRING(IDS_CANT_DRAG_ELEVATED_DIALOG_DONT_SHOW_AGAIN), NonLocalizable::ToastNotificationButtonUrl }
|
2020-04-30 18:16:08 +08:00
|
|
|
};
|
2020-07-28 00:53:29 +08:00
|
|
|
notifications::show_toast_with_activations(GET_RESOURCE_STRING(IDS_CANT_DRAG_ELEVATED),
|
2020-08-11 19:51:06 +08:00
|
|
|
GET_RESOURCE_STRING(IDS_FANCYZONES),
|
2020-07-28 00:53:29 +08:00
|
|
|
{},
|
|
|
|
std::move(actions));
|
2020-04-30 18:16:08 +08:00
|
|
|
warning_shown = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-07-23 00:00:03 +08:00
|
|
|
|
|
|
|
void WindowMoveHandlerPrivate::UpdateDragState() noexcept
|
|
|
|
{
|
|
|
|
if (m_settings->GetSettings()->shiftDrag)
|
|
|
|
{
|
2020-08-24 15:19:39 +08:00
|
|
|
m_dragEnabled = (m_shiftKeyState.state() ^ m_mouseState);
|
2020-07-23 00:00:03 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-08-24 15:19:39 +08:00
|
|
|
m_dragEnabled = !(m_shiftKeyState.state() ^ m_mouseState);
|
2020-07-23 00:00:03 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void WindowMoveHandlerPrivate::SetWindowTransparency(HWND window) noexcept
|
|
|
|
{
|
|
|
|
if (m_settings->GetSettings()->makeDraggedWindowTransparent)
|
|
|
|
{
|
|
|
|
m_windowTransparencyProperties.draggedWindowExstyle = GetWindowLong(window, GWL_EXSTYLE);
|
|
|
|
|
|
|
|
m_windowTransparencyProperties.draggedWindow = window;
|
|
|
|
SetWindowLong(window,
|
|
|
|
GWL_EXSTYLE,
|
|
|
|
m_windowTransparencyProperties.draggedWindowExstyle | WS_EX_LAYERED);
|
|
|
|
|
|
|
|
GetLayeredWindowAttributes(window, &m_windowTransparencyProperties.draggedWindowCrKey, &m_windowTransparencyProperties.draggedWindowInitialAlpha, &m_windowTransparencyProperties.draggedWindowDwFlags);
|
|
|
|
|
|
|
|
SetLayeredWindowAttributes(window, 0, (255 * 50) / 100, LWA_ALPHA);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void WindowMoveHandlerPrivate::ResetWindowTransparency() noexcept
|
|
|
|
{
|
|
|
|
if (m_settings->GetSettings()->makeDraggedWindowTransparent && m_windowTransparencyProperties.draggedWindow != nullptr)
|
|
|
|
{
|
|
|
|
SetLayeredWindowAttributes(m_windowTransparencyProperties.draggedWindow, m_windowTransparencyProperties.draggedWindowCrKey, m_windowTransparencyProperties.draggedWindowInitialAlpha, m_windowTransparencyProperties.draggedWindowDwFlags);
|
|
|
|
SetWindowLong(m_windowTransparencyProperties.draggedWindow, GWL_EXSTYLE, m_windowTransparencyProperties.draggedWindowExstyle);
|
|
|
|
m_windowTransparencyProperties.draggedWindow = nullptr;
|
|
|
|
}
|
|
|
|
}
|