mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-08 12:18:50 +02:00
[FancyZones] Update windows positions after changing the layout fix (#18805)
* removed IWorkArea interface * split work area initialization * changed rect type in zoneset * tests upd work area tests removed obsolete, update others updated work area tests * get current vd windows * update windows positions * removed unused flag * moved update window positions to work area * check monitor * refactoring
This commit is contained in:
@@ -1,139 +1,111 @@
|
||||
#pragma once
|
||||
#include "FancyZones.h"
|
||||
#include "FancyZonesLib/ZoneSet.h"
|
||||
#include "FancyZonesLib/FancyZonesDataTypes.h"
|
||||
|
||||
/**
|
||||
* Class representing single work area, which is defined by monitor and virtual desktop.
|
||||
*/
|
||||
interface __declspec(uuid("{7F017528-8110-4FB3-BE41-F472969C2560}")) IWorkArea : public IUnknown
|
||||
#include <FancyZonesLib/FancyZonesDataTypes.h>
|
||||
#include <FancyZonesLib/ZoneSet.h>
|
||||
#include <FancyZonesLib/util.h>
|
||||
|
||||
class ZonesOverlay;
|
||||
|
||||
class WorkArea
|
||||
{
|
||||
/**
|
||||
* A window is being moved or resized. Track down window position and give zone layout
|
||||
* hints if dragging functionality is enabled.
|
||||
*
|
||||
* @param window Handle of window being moved or resized.
|
||||
*/
|
||||
IFACEMETHOD(MoveSizeEnter)(HWND window) = 0;
|
||||
public:
|
||||
WorkArea(HINSTANCE hinstance);
|
||||
~WorkArea();
|
||||
|
||||
/**
|
||||
* A window has changed location, shape, or size. Track down window position and give zone layout
|
||||
* hints if dragging functionality is enabled.
|
||||
*
|
||||
* @param ptScreen Cursor coordinates.
|
||||
* @param dragEnabled Boolean indicating is giving hints about active zone layout enabled.
|
||||
* Hints are given while dragging window while holding SHIFT key.
|
||||
* @param selectManyZones When this parameter is true, the set of highlighted zones is computed
|
||||
* by finding the minimum bounding rectangle of the zone(s) from which the
|
||||
* user started dragging and the zone(s) above which the user is hovering
|
||||
* at the moment this function is called. Otherwise, highlight only the zone(s)
|
||||
* above which the user is currently hovering.
|
||||
*/
|
||||
IFACEMETHOD(MoveSizeUpdate)(POINT const& ptScreen, bool dragEnabled, bool selectManyZones) = 0;
|
||||
/**
|
||||
* The movement or resizing of a window has finished. Assign window to the zone of it
|
||||
* is dropped within zone borders.
|
||||
*
|
||||
* @param window Handle of window being moved or resized.
|
||||
* @param ptScreen Cursor coordinates where window is dropped.
|
||||
*/
|
||||
IFACEMETHOD(MoveSizeEnd)(HWND window, POINT const& ptScreen) = 0;
|
||||
/**
|
||||
* Assign window to the zone based on zone index inside zone layout.
|
||||
*
|
||||
* @param window Handle of window which should be assigned to zone.
|
||||
* @param index Zone index within zone layout.
|
||||
*/
|
||||
IFACEMETHOD_(void, MoveWindowIntoZoneByIndex)(HWND window, ZoneIndex index) = 0;
|
||||
/**
|
||||
* Assign window to the zones based on the set of zone indices inside zone layout.
|
||||
*
|
||||
* @param window Handle of window which should be assigned to zone.
|
||||
* @param indexSet The set of zone indices within zone layout.
|
||||
* @param suppressMove Whether we should just update the records or move window to the zone.
|
||||
*/
|
||||
IFACEMETHOD_(void, MoveWindowIntoZoneByIndexSet)(HWND window, const ZoneIndexSet& indexSet, bool suppressMove = false) = 0;
|
||||
/**
|
||||
* Assign window to the zone based on direction (using WIN + LEFT/RIGHT arrow), based on zone index numbers,
|
||||
* not their on-screen position.
|
||||
*
|
||||
* @param window Handle of window which should be assigned to zone.
|
||||
* @param vkCode Pressed arrow key.
|
||||
* @param cycle Whether we should move window to the first zone if we reached last zone in layout.
|
||||
*
|
||||
* @returns Boolean which is always true if cycle argument is set, otherwise indicating if there is more
|
||||
* zones left in the zone layout in which window can move.
|
||||
*/
|
||||
IFACEMETHOD_(bool, MoveWindowIntoZoneByDirectionAndIndex)(HWND window, DWORD vkCode, bool cycle) = 0;
|
||||
/**
|
||||
* Assign window to the zone based on direction (using WIN + LEFT/RIGHT/UP/DOWN arrow), based on
|
||||
* their on-screen position.
|
||||
*
|
||||
* @param window Handle of window which should be assigned to zone.
|
||||
* @param vkCode Pressed arrow key.
|
||||
* @param cycle Whether we should move window to the first zone if we reached last zone in layout.
|
||||
*
|
||||
* @returns Boolean which is always true if cycle argument is set, otherwise indicating if there is more
|
||||
* zones left in the zone layout in which window can move.
|
||||
*/
|
||||
IFACEMETHOD_(bool, MoveWindowIntoZoneByDirectionAndPosition)(HWND window, DWORD vkCode, bool cycle) = 0;
|
||||
/**
|
||||
* Extend or shrink the window to an adjacent zone based on direction (using CTRL+WIN+ALT + LEFT/RIGHT/UP/DOWN arrow), based on
|
||||
* their on-screen position.
|
||||
*
|
||||
* @param window Handle of window which should be assigned to zone.
|
||||
* @param vkCode Pressed arrow key.
|
||||
*
|
||||
* @returns Boolean indicating whether the window was rezoned. False could be returned when there are no more
|
||||
* zones available in the given direction.
|
||||
*/
|
||||
IFACEMETHOD_(bool, ExtendWindowByDirectionAndPosition)(HWND window, DWORD vkCode) = 0;
|
||||
/**
|
||||
* Save information about zone in which window was assigned, when closing the window.
|
||||
* Used once we open same window again to assign it to its previous zone.
|
||||
*
|
||||
* @param window Window handle.
|
||||
*/
|
||||
IFACEMETHOD_(void, SaveWindowProcessToZoneIndex)(HWND window) = 0;
|
||||
/**
|
||||
* @returns Unique work area identifier. Format: <device-id>_<resolution>_<virtual-desktop-id>
|
||||
*/
|
||||
IFACEMETHOD_(FancyZonesDataTypes::DeviceIdData, UniqueId)() const = 0;
|
||||
/**
|
||||
* @returns Active zone layout for this work area.
|
||||
*/
|
||||
IFACEMETHOD_(IZoneSet*, ZoneSet)() const = 0;
|
||||
/*
|
||||
* @returns Zone index of the window
|
||||
*/
|
||||
IFACEMETHOD_(ZoneIndexSet, GetWindowZoneIndexes)(HWND window) const = 0;
|
||||
/**
|
||||
* Show a drawing of the zones in the work area.
|
||||
*/
|
||||
IFACEMETHOD_(void, ShowZonesOverlay)() = 0;
|
||||
/**
|
||||
* Hide the drawing of the zones in the work area.
|
||||
*/
|
||||
IFACEMETHOD_(void, HideZonesOverlay)() = 0;
|
||||
/**
|
||||
* Update currently active zone layout for this work area.
|
||||
*/
|
||||
IFACEMETHOD_(void, UpdateActiveZoneSet)() = 0;
|
||||
/**
|
||||
* Cycle through tabs in the zone that the window is in.
|
||||
*
|
||||
* @param window Handle of window which is cycled from (the current tab).
|
||||
* @param reverse Whether to cycle in reverse order (to the previous tab) or to move to the next tab.
|
||||
*/
|
||||
IFACEMETHOD_(void, CycleTabs)(HWND window, bool reverse) = 0;
|
||||
/**
|
||||
* Clear the selected zones when this WorkArea loses focus.
|
||||
*/
|
||||
IFACEMETHOD_(void, ClearSelectedZones)() = 0;
|
||||
/*
|
||||
* Display the layout on the screen and then hide it.
|
||||
*/
|
||||
IFACEMETHOD_(void, FlashZones)() = 0;
|
||||
public:
|
||||
bool Init(HINSTANCE hinstance, const FancyZonesDataTypes::DeviceIdData& uniqueId, const FancyZonesDataTypes::DeviceIdData& parentUniqueId);
|
||||
inline bool InitWorkAreaRect(HMONITOR monitor)
|
||||
{
|
||||
m_monitor = monitor;
|
||||
|
||||
#if defined(UNIT_TESTS)
|
||||
m_workAreaRect = FancyZonesUtils::Rect({ 0, 0, 1920, 1080 });
|
||||
return true;
|
||||
#endif
|
||||
|
||||
if (monitor)
|
||||
{
|
||||
MONITORINFO mi{};
|
||||
mi.cbSize = sizeof(mi);
|
||||
if (!GetMonitorInfoW(monitor, &mi))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_workAreaRect = FancyZonesUtils::Rect(mi.rcWork);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_workAreaRect = FancyZonesUtils::GetAllMonitorsCombinedRect<&MONITORINFO::rcWork>();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
FancyZonesDataTypes::DeviceIdData UniqueId() const noexcept { return { m_uniqueId }; }
|
||||
IZoneSet* ZoneSet() const noexcept { return m_zoneSet.get(); }
|
||||
|
||||
ZoneIndexSet GetWindowZoneIndexes(HWND window) const noexcept;
|
||||
|
||||
HRESULT MoveSizeEnter(HWND window) noexcept;
|
||||
HRESULT MoveSizeUpdate(POINT const& ptScreen, bool dragEnabled, bool selectManyZones) noexcept;
|
||||
HRESULT MoveSizeEnd(HWND window, POINT const& ptScreen) noexcept;
|
||||
void MoveWindowIntoZoneByIndex(HWND window, ZoneIndex index) noexcept;
|
||||
void MoveWindowIntoZoneByIndexSet(HWND window, const ZoneIndexSet& indexSet) noexcept;
|
||||
bool MoveWindowIntoZoneByDirectionAndIndex(HWND window, DWORD vkCode, bool cycle) noexcept;
|
||||
bool MoveWindowIntoZoneByDirectionAndPosition(HWND window, DWORD vkCode, bool cycle) noexcept;
|
||||
bool ExtendWindowByDirectionAndPosition(HWND window, DWORD vkCode) noexcept;
|
||||
void SaveWindowProcessToZoneIndex(HWND window) noexcept;
|
||||
|
||||
void UpdateActiveZoneSet() noexcept;
|
||||
|
||||
void ShowZonesOverlay() noexcept;
|
||||
void HideZonesOverlay() noexcept;
|
||||
void FlashZones() noexcept;
|
||||
void ClearSelectedZones() noexcept;
|
||||
|
||||
void CycleTabs(HWND window, bool reverse) noexcept;
|
||||
|
||||
void LogInitializationError();
|
||||
|
||||
protected:
|
||||
static LRESULT CALLBACK s_WndProc(HWND window, UINT message, WPARAM wparam, LPARAM lparam) noexcept;
|
||||
|
||||
private:
|
||||
void InitializeZoneSets(const FancyZonesDataTypes::DeviceIdData& parentUniqueId) noexcept;
|
||||
void CalculateZoneSet(OverlappingZonesAlgorithm overlappingAlgorithm) noexcept;
|
||||
void UpdateActiveZoneSet(_In_opt_ IZoneSet* zoneSet) noexcept;
|
||||
LRESULT WndProc(UINT message, WPARAM wparam, LPARAM lparam) noexcept;
|
||||
ZoneIndexSet ZonesFromPoint(POINT pt) noexcept;
|
||||
void SetAsTopmostWindow() noexcept;
|
||||
|
||||
HMONITOR m_monitor{};
|
||||
FancyZonesUtils::Rect m_workAreaRect{};
|
||||
|
||||
FancyZonesDataTypes::DeviceIdData m_uniqueId;
|
||||
HWND m_window{}; // Hidden tool window used to represent current monitor desktop work area.
|
||||
HWND m_windowMoveSize{};
|
||||
winrt::com_ptr<IZoneSet> m_zoneSet;
|
||||
ZoneIndexSet m_initialHighlightZone;
|
||||
ZoneIndexSet m_highlightZone;
|
||||
WPARAM m_keyLast{};
|
||||
size_t m_keyCycle{};
|
||||
std::unique_ptr<ZonesOverlay> m_zonesOverlay;
|
||||
};
|
||||
|
||||
winrt::com_ptr<IWorkArea> MakeWorkArea(HINSTANCE hinstance, HMONITOR monitor, const FancyZonesDataTypes::DeviceIdData& uniqueId, const FancyZonesDataTypes::DeviceIdData& parentUniqueId) noexcept;
|
||||
inline std::shared_ptr<WorkArea> MakeWorkArea(HINSTANCE hinstance, HMONITOR monitor, const FancyZonesDataTypes::DeviceIdData& uniqueId, const FancyZonesDataTypes::DeviceIdData& parentUniqueId) noexcept
|
||||
{
|
||||
auto self = std::make_shared<WorkArea>(hinstance);
|
||||
if (!self->InitWorkAreaRect(monitor))
|
||||
{
|
||||
self->LogInitializationError();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!self->Init(hinstance, uniqueId, parentUniqueId))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user