decorations: Decoration Positioner (#3800)
This commit is contained in:
parent
7345b1a1ea
commit
9be6fbf5ea
27 changed files with 610 additions and 266 deletions
96
src/render/decorations/DecorationPositioner.hpp
Normal file
96
src/render/decorations/DecorationPositioner.hpp
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include "../../helpers/Box.hpp"
|
||||
|
||||
class CWindow;
|
||||
class IHyprWindowDecoration;
|
||||
|
||||
enum eDecorationPositioningPolicy
|
||||
{
|
||||
DECORATION_POSITION_ABSOLUTE = 0, /* Decoration does not interfere with anything else */
|
||||
DECORATION_POSITION_STICKY, /* Decoration is stuck to some edge of a window */
|
||||
};
|
||||
|
||||
enum eDecorationEdges
|
||||
{
|
||||
DECORATION_EDGE_TOP = 1 << 0,
|
||||
DECORATION_EDGE_BOTTOM = 1 << 1,
|
||||
DECORATION_EDGE_LEFT = 1 << 2,
|
||||
DECORATION_EDGE_RIGHT = 1 << 3
|
||||
};
|
||||
|
||||
/*
|
||||
Request the positioner to position a decoration
|
||||
|
||||
DECORATION_POSITION_ABSOLUTE:
|
||||
- desiredExtents may contain the extents to be used when reserved is set. Edges has to have the edges used.
|
||||
DECORATION_POSITION_STICKY:
|
||||
- one edge allowed
|
||||
- priority allowed
|
||||
- desiredExtents contains the desired extents. Any other edge than the one selected is ignored.
|
||||
- reserved is allowed
|
||||
*/
|
||||
struct SDecorationPositioningInfo {
|
||||
eDecorationPositioningPolicy policy = DECORATION_POSITION_ABSOLUTE;
|
||||
uint32_t edges = 0; // enum eDecorationEdges
|
||||
uint32_t priority = 10; // priority, decos will be evaluated high -> low
|
||||
SWindowDecorationExtents desiredExtents;
|
||||
bool reserved = false; // if true, geometry will use reserved area
|
||||
};
|
||||
|
||||
/*
|
||||
A reply from the positioner. This may be sent multiple times, if anything changes.
|
||||
|
||||
DECORATION_POSITION_ABSOLUTE:
|
||||
- assignedGeometry is empty
|
||||
DECORATION_POSITION_STICKY:
|
||||
- assignedGeometry is relative to the edge's center point
|
||||
- ephemeral is sent
|
||||
*/
|
||||
struct SDecorationPositioningReply {
|
||||
CBox assignedGeometry;
|
||||
bool ephemeral = false; // if true, means it's a result of an animation and will change soon.
|
||||
};
|
||||
|
||||
class CDecorationPositioner {
|
||||
public:
|
||||
CDecorationPositioner();
|
||||
|
||||
Vector2D getEdgeDefinedPoint(uint32_t edges, CWindow* pWindow);
|
||||
|
||||
// called on resize, or insert/removal of a new deco
|
||||
void onWindowUpdate(CWindow* pWindow);
|
||||
void uncacheDecoration(IHyprWindowDecoration* deco);
|
||||
SWindowDecorationExtents getWindowDecorationReserved(CWindow* pWindow);
|
||||
SWindowDecorationExtents getWindowDecorationExtents(CWindow* pWindow, bool inputOnly = false);
|
||||
CBox getBoxWithIncludedDecos(CWindow* pWindow);
|
||||
void repositionDeco(IHyprWindowDecoration* deco);
|
||||
CBox getWindowDecorationBox(IHyprWindowDecoration* deco);
|
||||
|
||||
private:
|
||||
struct SWindowPositioningData {
|
||||
CWindow* pWindow = nullptr;
|
||||
IHyprWindowDecoration* pDecoration = nullptr;
|
||||
SDecorationPositioningInfo positioningInfo;
|
||||
SDecorationPositioningReply lastReply;
|
||||
bool needsReposition = true;
|
||||
};
|
||||
|
||||
struct SWindowData {
|
||||
Vector2D lastWindowSize = {};
|
||||
SWindowDecorationExtents reserved = {};
|
||||
SWindowDecorationExtents extents = {};
|
||||
};
|
||||
|
||||
std::unordered_map<CWindow*, SWindowData> m_mWindowDatas;
|
||||
std::vector<std::unique_ptr<SWindowPositioningData>> m_vWindowPositioningDatas;
|
||||
|
||||
SWindowPositioningData* getDataFor(IHyprWindowDecoration* pDecoration, CWindow* pWindow);
|
||||
void onWindowUnmap(CWindow* pWindow);
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CDecorationPositioner> g_pDecorationPositioner;
|
||||
Loading…
Add table
Add a link
Reference in a new issue