desktop: cleanup, unify desktop elements as views (#12563)
This commit is contained in:
parent
834f019bab
commit
920353370b
105 changed files with 2636 additions and 2337 deletions
|
|
@ -1,26 +1,30 @@
|
|||
#pragma once
|
||||
#include "../helpers/memory/Memory.hpp"
|
||||
|
||||
class CWorkspace;
|
||||
class CWindow;
|
||||
class CLayerSurface;
|
||||
class CMonitor;
|
||||
|
||||
namespace Desktop::View {
|
||||
class CWindow;
|
||||
class CLayerSurface;
|
||||
}
|
||||
|
||||
/* Shared pointer to a workspace */
|
||||
using PHLWORKSPACE = SP<CWorkspace>;
|
||||
/* Weak pointer to a workspace */
|
||||
using PHLWORKSPACEREF = WP<CWorkspace>;
|
||||
|
||||
/* Shared pointer to a window */
|
||||
using PHLWINDOW = SP<CWindow>;
|
||||
using PHLWINDOW = SP<Desktop::View::CWindow>;
|
||||
/* Weak pointer to a window */
|
||||
using PHLWINDOWREF = WP<CWindow>;
|
||||
using PHLWINDOWREF = WP<Desktop::View::CWindow>;
|
||||
|
||||
/* Shared pointer to a layer surface */
|
||||
using PHLLS = SP<CLayerSurface>;
|
||||
using PHLLS = SP<Desktop::View::CLayerSurface>;
|
||||
/* Weak pointer to a layer surface */
|
||||
using PHLLSREF = WP<CLayerSurface>;
|
||||
using PHLLSREF = WP<Desktop::View::CLayerSurface>;
|
||||
|
||||
/* Shared pointer to a monitor */
|
||||
using PHLMONITOR = SP<CMonitor>;
|
||||
/* Weak pointer to a monitor */
|
||||
using PHLMONITORREF = WP<CMonitor>;
|
||||
using PHLMONITORREF = WP<CMonitor>;
|
||||
|
|
@ -1,95 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "../defines.hpp"
|
||||
#include "WLSurface.hpp"
|
||||
#include "rule/layerRule/LayerRuleApplicator.hpp"
|
||||
#include "../helpers/AnimatedVariable.hpp"
|
||||
|
||||
class CLayerShellResource;
|
||||
|
||||
class CLayerSurface {
|
||||
public:
|
||||
static PHLLS create(SP<CLayerShellResource>);
|
||||
|
||||
private:
|
||||
CLayerSurface(SP<CLayerShellResource>);
|
||||
|
||||
public:
|
||||
~CLayerSurface();
|
||||
|
||||
bool isFadedOut();
|
||||
int popupsCount();
|
||||
|
||||
PHLANIMVAR<Vector2D> m_realPosition;
|
||||
PHLANIMVAR<Vector2D> m_realSize;
|
||||
PHLANIMVAR<float> m_alpha;
|
||||
|
||||
WP<CLayerShellResource> m_layerSurface;
|
||||
|
||||
// the header providing the enum type cannot be imported here
|
||||
int m_interactivity = 0;
|
||||
|
||||
SP<CWLSurface> m_surface;
|
||||
|
||||
bool m_mapped = false;
|
||||
uint32_t m_layer = 0;
|
||||
|
||||
PHLMONITORREF m_monitor;
|
||||
|
||||
bool m_fadingOut = false;
|
||||
bool m_readyToDelete = false;
|
||||
bool m_noProcess = false;
|
||||
|
||||
UP<Desktop::Rule::CLayerRuleApplicator> m_ruleApplicator;
|
||||
|
||||
PHLLSREF m_self;
|
||||
|
||||
CBox m_geometry = {0, 0, 0, 0};
|
||||
Vector2D m_position;
|
||||
std::string m_namespace = "";
|
||||
UP<CPopup> m_popupHead;
|
||||
|
||||
pid_t getPID();
|
||||
|
||||
void onDestroy();
|
||||
void onMap();
|
||||
void onUnmap();
|
||||
void onCommit();
|
||||
MONITORID monitorID();
|
||||
|
||||
private:
|
||||
struct {
|
||||
CHyprSignalListener destroy;
|
||||
CHyprSignalListener map;
|
||||
CHyprSignalListener unmap;
|
||||
CHyprSignalListener commit;
|
||||
} m_listeners;
|
||||
|
||||
void registerCallbacks();
|
||||
|
||||
// For the list lookup
|
||||
bool operator==(const CLayerSurface& rhs) const {
|
||||
return m_layerSurface == rhs.m_layerSurface && m_monitor == rhs.m_monitor;
|
||||
}
|
||||
};
|
||||
|
||||
inline bool valid(PHLLS l) {
|
||||
return l;
|
||||
}
|
||||
|
||||
inline bool valid(PHLLSREF l) {
|
||||
return l;
|
||||
}
|
||||
|
||||
inline bool validMapped(PHLLS l) {
|
||||
if (!valid(l))
|
||||
return false;
|
||||
return l->m_mapped;
|
||||
}
|
||||
|
||||
inline bool validMapped(PHLLSREF l) {
|
||||
if (!valid(l))
|
||||
return false;
|
||||
return l->m_mapped;
|
||||
}
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "Subsurface.hpp"
|
||||
#include "../helpers/signal/Signal.hpp"
|
||||
#include "../helpers/memory/Memory.hpp"
|
||||
#include "../helpers/AnimatedVariable.hpp"
|
||||
|
||||
class CXDGPopupResource;
|
||||
|
||||
class CPopup {
|
||||
public:
|
||||
// dummy head nodes
|
||||
static UP<CPopup> create(PHLWINDOW pOwner);
|
||||
static UP<CPopup> create(PHLLS pOwner);
|
||||
|
||||
// real nodes
|
||||
static UP<CPopup> create(SP<CXDGPopupResource> popup, WP<CPopup> pOwner);
|
||||
|
||||
~CPopup();
|
||||
|
||||
SP<CWLSurface> getT1Owner();
|
||||
Vector2D coordsRelativeToParent();
|
||||
Vector2D coordsGlobal();
|
||||
PHLMONITOR getMonitor();
|
||||
|
||||
Vector2D size();
|
||||
|
||||
void onNewPopup(SP<CXDGPopupResource> popup);
|
||||
void onDestroy();
|
||||
void onMap();
|
||||
void onUnmap();
|
||||
void onCommit(bool ignoreSiblings = false);
|
||||
void onReposition();
|
||||
|
||||
void recheckTree();
|
||||
|
||||
bool visible();
|
||||
bool inert() const;
|
||||
|
||||
// will also loop over this node
|
||||
void breadthfirst(std::function<void(WP<CPopup>, void*)> fn, void* data);
|
||||
WP<CPopup> at(const Vector2D& globalCoords, bool allowsInput = false);
|
||||
|
||||
//
|
||||
SP<CWLSurface> m_wlSurface;
|
||||
WP<CPopup> m_self;
|
||||
bool m_mapped = false;
|
||||
|
||||
// fade in-out
|
||||
PHLANIMVAR<float> m_alpha;
|
||||
bool m_fadingOut = false;
|
||||
|
||||
private:
|
||||
CPopup() = default;
|
||||
|
||||
// T1 owners, each popup has to have one of these
|
||||
PHLWINDOWREF m_windowOwner;
|
||||
PHLLSREF m_layerOwner;
|
||||
|
||||
// T2 owners
|
||||
WP<CPopup> m_parent;
|
||||
|
||||
WP<CXDGPopupResource> m_resource;
|
||||
|
||||
Vector2D m_lastSize = {};
|
||||
Vector2D m_lastPos = {};
|
||||
|
||||
bool m_requestedReposition = false;
|
||||
|
||||
bool m_inert = false;
|
||||
|
||||
//
|
||||
std::vector<UP<CPopup>> m_children;
|
||||
UP<CSubsurface> m_subsurfaceHead;
|
||||
|
||||
struct {
|
||||
CHyprSignalListener newPopup;
|
||||
CHyprSignalListener destroy;
|
||||
CHyprSignalListener map;
|
||||
CHyprSignalListener unmap;
|
||||
CHyprSignalListener commit;
|
||||
CHyprSignalListener dismissed;
|
||||
CHyprSignalListener reposition;
|
||||
} m_listeners;
|
||||
|
||||
void initAllSignals();
|
||||
void reposition();
|
||||
void recheckChildrenRecursive();
|
||||
void sendScale();
|
||||
void fullyDestroy();
|
||||
|
||||
Vector2D localToGlobal(const Vector2D& rel);
|
||||
Vector2D t1ParentCoords();
|
||||
static void bfHelper(std::vector<WP<CPopup>> const& nodes, std::function<void(WP<CPopup>, void*)> fn, void* data);
|
||||
};
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "../defines.hpp"
|
||||
#include <vector>
|
||||
#include "WLSurface.hpp"
|
||||
|
||||
class CPopup;
|
||||
class CWLSubsurfaceResource;
|
||||
|
||||
class CSubsurface {
|
||||
public:
|
||||
// root dummy nodes
|
||||
static UP<CSubsurface> create(PHLWINDOW pOwner);
|
||||
static UP<CSubsurface> create(WP<CPopup> pOwner);
|
||||
|
||||
// real nodes
|
||||
static UP<CSubsurface> create(SP<CWLSubsurfaceResource> pSubsurface, PHLWINDOW pOwner);
|
||||
static UP<CSubsurface> create(SP<CWLSubsurfaceResource> pSubsurface, WP<CPopup> pOwner);
|
||||
|
||||
~CSubsurface() = default;
|
||||
|
||||
Vector2D coordsRelativeToParent();
|
||||
Vector2D coordsGlobal();
|
||||
|
||||
Vector2D size();
|
||||
|
||||
void onCommit();
|
||||
void onDestroy();
|
||||
void onNewSubsurface(SP<CWLSubsurfaceResource> pSubsurface);
|
||||
void onMap();
|
||||
void onUnmap();
|
||||
|
||||
bool visible();
|
||||
|
||||
void recheckDamageForSubsurfaces();
|
||||
|
||||
WP<CSubsurface> m_self;
|
||||
|
||||
private:
|
||||
CSubsurface() = default;
|
||||
|
||||
struct {
|
||||
CHyprSignalListener destroySubsurface;
|
||||
CHyprSignalListener commitSubsurface;
|
||||
CHyprSignalListener mapSubsurface;
|
||||
CHyprSignalListener unmapSubsurface;
|
||||
CHyprSignalListener newSubsurface;
|
||||
} m_listeners;
|
||||
|
||||
WP<CWLSubsurfaceResource> m_subsurface;
|
||||
SP<CWLSurface> m_wlSurface;
|
||||
Vector2D m_lastSize = {};
|
||||
Vector2D m_lastPosition = {};
|
||||
|
||||
// if nullptr, means it's a dummy node
|
||||
WP<CSubsurface> m_parent;
|
||||
|
||||
PHLWINDOWREF m_windowParent;
|
||||
WP<CPopup> m_popupParent;
|
||||
|
||||
std::vector<UP<CSubsurface>> m_children;
|
||||
|
||||
bool m_inert = false;
|
||||
|
||||
void initSignals();
|
||||
void initExistingSubsurfaces(SP<CWLSurfaceResource> pSurface);
|
||||
void checkSiblingDamage();
|
||||
void damageLastArea();
|
||||
};
|
||||
|
|
@ -1,124 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "../defines.hpp"
|
||||
#include "../helpers/math/Math.hpp"
|
||||
#include "../helpers/signal/Signal.hpp"
|
||||
|
||||
class CSubsurface;
|
||||
class CPopup;
|
||||
class CPointerConstraint;
|
||||
class CWLSurfaceResource;
|
||||
|
||||
class CWLSurface {
|
||||
public:
|
||||
static SP<CWLSurface> create() {
|
||||
auto p = SP<CWLSurface>(new CWLSurface);
|
||||
p->m_self = p;
|
||||
return p;
|
||||
}
|
||||
~CWLSurface();
|
||||
|
||||
// anonymous surfaces are non-desktop components, e.g. a cursor surface or a DnD
|
||||
void assign(SP<CWLSurfaceResource> pSurface);
|
||||
void assign(SP<CWLSurfaceResource> pSurface, PHLWINDOW pOwner);
|
||||
void assign(SP<CWLSurfaceResource> pSurface, PHLLS pOwner);
|
||||
void assign(SP<CWLSurfaceResource> pSurface, CSubsurface* pOwner);
|
||||
void assign(SP<CWLSurfaceResource> pSurface, CPopup* pOwner);
|
||||
void unassign();
|
||||
|
||||
CWLSurface(const CWLSurface&) = delete;
|
||||
CWLSurface(CWLSurface&&) = delete;
|
||||
CWLSurface& operator=(const CWLSurface&) = delete;
|
||||
CWLSurface& operator=(CWLSurface&&) = delete;
|
||||
|
||||
SP<CWLSurfaceResource> resource() const;
|
||||
bool exists() const;
|
||||
bool small() const; // means surface is smaller than the requested size
|
||||
Vector2D correctSmallVec() const; // returns a corrective vector for small() surfaces
|
||||
Vector2D correctSmallVecBuf() const; // returns a corrective vector for small() surfaces, in BL coords
|
||||
Vector2D getViewporterCorrectedSize() const;
|
||||
CRegion computeDamage() const; // logical coordinates. May be wrong if the surface is unassigned
|
||||
bool visible();
|
||||
bool keyboardFocusable() const;
|
||||
|
||||
// getters for owners.
|
||||
PHLWINDOW getWindow() const;
|
||||
PHLLS getLayer() const;
|
||||
CPopup* getPopup() const;
|
||||
CSubsurface* getSubsurface() const;
|
||||
|
||||
// desktop components misc utils
|
||||
std::optional<CBox> getSurfaceBoxGlobal() const;
|
||||
void appendConstraint(WP<CPointerConstraint> constraint);
|
||||
SP<CPointerConstraint> constraint() const;
|
||||
|
||||
// allow stretching. Useful for plugins.
|
||||
bool m_fillIgnoreSmall = false;
|
||||
|
||||
// track surface data and avoid dupes
|
||||
float m_lastScaleFloat = 0;
|
||||
int m_lastScaleInt = 0;
|
||||
wl_output_transform m_lastTransform = sc<wl_output_transform>(-1);
|
||||
|
||||
//
|
||||
CWLSurface& operator=(SP<CWLSurfaceResource> pSurface) {
|
||||
destroy();
|
||||
m_resource = pSurface;
|
||||
init();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const CWLSurface& other) const {
|
||||
return other.resource() == resource();
|
||||
}
|
||||
|
||||
bool operator==(const SP<CWLSurfaceResource> other) const {
|
||||
return other == resource();
|
||||
}
|
||||
|
||||
explicit operator bool() const {
|
||||
return exists();
|
||||
}
|
||||
|
||||
static SP<CWLSurface> fromResource(SP<CWLSurfaceResource> pSurface);
|
||||
|
||||
// used by the alpha-modifier protocol
|
||||
float m_alphaModifier = 1.F;
|
||||
|
||||
// used by the hyprland-surface protocol
|
||||
float m_overallOpacity = 1.F;
|
||||
CRegion m_visibleRegion;
|
||||
|
||||
struct {
|
||||
CSignalT<> destroy;
|
||||
} m_events;
|
||||
|
||||
WP<CWLSurface> m_self;
|
||||
|
||||
private:
|
||||
CWLSurface() = default;
|
||||
|
||||
bool m_inert = true;
|
||||
|
||||
WP<CWLSurfaceResource> m_resource;
|
||||
|
||||
PHLWINDOWREF m_windowOwner;
|
||||
PHLLSREF m_layerOwner;
|
||||
CPopup* m_popupOwner = nullptr;
|
||||
CSubsurface* m_subsurfaceOwner = nullptr;
|
||||
|
||||
//
|
||||
WP<CPointerConstraint> m_constraint;
|
||||
|
||||
void destroy();
|
||||
void init();
|
||||
bool desktopComponent() const;
|
||||
|
||||
struct {
|
||||
CHyprSignalListener destroy;
|
||||
} m_listeners;
|
||||
|
||||
friend class CPointerConstraint;
|
||||
friend class CXxColorManagerV4;
|
||||
};
|
||||
|
|
@ -1,438 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <optional>
|
||||
|
||||
#include "../config/ConfigDataValues.hpp"
|
||||
#include "../helpers/AnimatedVariable.hpp"
|
||||
#include "../helpers/TagKeeper.hpp"
|
||||
#include "../macros.hpp"
|
||||
#include "../managers/XWaylandManager.hpp"
|
||||
#include "../render/decorations/IHyprWindowDecoration.hpp"
|
||||
#include "../render/Transformer.hpp"
|
||||
#include "DesktopTypes.hpp"
|
||||
#include "Popup.hpp"
|
||||
#include "Subsurface.hpp"
|
||||
#include "WLSurface.hpp"
|
||||
#include "Workspace.hpp"
|
||||
#include "rule/windowRule/WindowRuleApplicator.hpp"
|
||||
#include "../protocols/types/ContentType.hpp"
|
||||
|
||||
class CXDGSurfaceResource;
|
||||
class CXWaylandSurface;
|
||||
|
||||
enum eGroupRules : uint8_t {
|
||||
// effective only during first map, except for _ALWAYS variant
|
||||
GROUP_NONE = 0,
|
||||
GROUP_SET = 1 << 0, // Open as new group or add to focused group
|
||||
GROUP_SET_ALWAYS = 1 << 1,
|
||||
GROUP_BARRED = 1 << 2, // Don't insert to focused group.
|
||||
GROUP_LOCK = 1 << 3, // Lock m_sGroupData.lock
|
||||
GROUP_LOCK_ALWAYS = 1 << 4,
|
||||
GROUP_INVADE = 1 << 5, // Force enter a group, event if lock is engaged
|
||||
GROUP_OVERRIDE = 1 << 6, // Override other rules
|
||||
};
|
||||
|
||||
enum eGetWindowProperties : uint8_t {
|
||||
WINDOW_ONLY = 0,
|
||||
RESERVED_EXTENTS = 1 << 0,
|
||||
INPUT_EXTENTS = 1 << 1,
|
||||
FULL_EXTENTS = 1 << 2,
|
||||
FLOATING_ONLY = 1 << 3,
|
||||
ALLOW_FLOATING = 1 << 4,
|
||||
USE_PROP_TILED = 1 << 5,
|
||||
SKIP_FULLSCREEN_PRIORITY = 1 << 6,
|
||||
FOCUS_PRIORITY = 1 << 7,
|
||||
};
|
||||
|
||||
enum eSuppressEvents : uint8_t {
|
||||
SUPPRESS_NONE = 0,
|
||||
SUPPRESS_FULLSCREEN = 1 << 0,
|
||||
SUPPRESS_MAXIMIZE = 1 << 1,
|
||||
SUPPRESS_ACTIVATE = 1 << 2,
|
||||
SUPPRESS_ACTIVATE_FOCUSONLY = 1 << 3,
|
||||
SUPPRESS_FULLSCREEN_OUTPUT = 1 << 4,
|
||||
};
|
||||
|
||||
class IWindowTransformer;
|
||||
|
||||
struct SInitialWorkspaceToken {
|
||||
PHLWINDOWREF primaryOwner;
|
||||
std::string workspace;
|
||||
};
|
||||
|
||||
struct SFullscreenState {
|
||||
eFullscreenMode internal = FSMODE_NONE;
|
||||
eFullscreenMode client = FSMODE_NONE;
|
||||
};
|
||||
|
||||
class CWindow {
|
||||
public:
|
||||
static PHLWINDOW create(SP<CXDGSurfaceResource>);
|
||||
static PHLWINDOW create(SP<CXWaylandSurface>);
|
||||
|
||||
private:
|
||||
CWindow(SP<CXDGSurfaceResource> resource);
|
||||
CWindow(SP<CXWaylandSurface> surface);
|
||||
|
||||
public:
|
||||
~CWindow();
|
||||
|
||||
SP<CWLSurface> m_wlSurface;
|
||||
|
||||
struct {
|
||||
CSignalT<> destroy;
|
||||
} m_events;
|
||||
|
||||
WP<CXDGSurfaceResource> m_xdgSurface;
|
||||
WP<CXWaylandSurface> m_xwaylandSurface;
|
||||
|
||||
// this is the position and size of the "bounding box"
|
||||
Vector2D m_position = Vector2D(0, 0);
|
||||
Vector2D m_size = Vector2D(0, 0);
|
||||
|
||||
// this is the real position and size used to draw the thing
|
||||
PHLANIMVAR<Vector2D> m_realPosition;
|
||||
PHLANIMVAR<Vector2D> m_realSize;
|
||||
|
||||
// for not spamming the protocols
|
||||
Vector2D m_reportedPosition;
|
||||
Vector2D m_reportedSize;
|
||||
Vector2D m_pendingReportedSize;
|
||||
std::optional<std::pair<uint32_t, Vector2D>> m_pendingSizeAck;
|
||||
std::vector<std::pair<uint32_t, Vector2D>> m_pendingSizeAcks;
|
||||
|
||||
// for restoring floating statuses
|
||||
Vector2D m_lastFloatingSize;
|
||||
Vector2D m_lastFloatingPosition;
|
||||
|
||||
// for floating window offset in workspace animations
|
||||
Vector2D m_floatingOffset = Vector2D(0, 0);
|
||||
|
||||
// this is used for pseudotiling
|
||||
bool m_isPseudotiled = false;
|
||||
Vector2D m_pseudoSize = Vector2D(1280, 720);
|
||||
|
||||
// for recovering relative cursor position
|
||||
Vector2D m_relativeCursorCoordsOnLastWarp = Vector2D(-1, -1);
|
||||
|
||||
bool m_firstMap = false; // for layouts
|
||||
bool m_isFloating = false;
|
||||
bool m_draggingTiled = false; // for dragging around tiled windows
|
||||
SFullscreenState m_fullscreenState = {.internal = FSMODE_NONE, .client = FSMODE_NONE};
|
||||
std::string m_title = "";
|
||||
std::string m_class = "";
|
||||
std::string m_initialTitle = "";
|
||||
std::string m_initialClass = "";
|
||||
PHLWORKSPACE m_workspace;
|
||||
PHLMONITORREF m_monitor;
|
||||
|
||||
bool m_isMapped = false;
|
||||
|
||||
bool m_requestsFloat = false;
|
||||
|
||||
// This is for fullscreen apps
|
||||
bool m_createdOverFullscreen = false;
|
||||
|
||||
// XWayland stuff
|
||||
bool m_isX11 = false;
|
||||
bool m_X11DoesntWantBorders = false;
|
||||
bool m_X11ShouldntFocus = false;
|
||||
float m_X11SurfaceScaledBy = 1.f;
|
||||
//
|
||||
|
||||
// For nofocus
|
||||
bool m_noInitialFocus = false;
|
||||
|
||||
// Fullscreen and Maximize
|
||||
bool m_wantsInitialFullscreen = false;
|
||||
MONITORID m_wantsInitialFullscreenMonitor = MONITOR_INVALID;
|
||||
|
||||
// bitfield suppressEvents
|
||||
uint64_t m_suppressedEvents = SUPPRESS_NONE;
|
||||
|
||||
// desktop components
|
||||
UP<CSubsurface> m_subsurfaceHead;
|
||||
UP<CPopup> m_popupHead;
|
||||
|
||||
// Animated border
|
||||
CGradientValueData m_realBorderColor = {0};
|
||||
CGradientValueData m_realBorderColorPrevious = {0};
|
||||
PHLANIMVAR<float> m_borderFadeAnimationProgress;
|
||||
PHLANIMVAR<float> m_borderAngleAnimationProgress;
|
||||
|
||||
// Fade in-out
|
||||
PHLANIMVAR<float> m_alpha;
|
||||
bool m_fadingOut = false;
|
||||
bool m_readyToDelete = false;
|
||||
Vector2D m_originalClosedPos; // these will be used for calculations later on in
|
||||
Vector2D m_originalClosedSize; // drawing the closing animations
|
||||
SBoxExtents m_originalClosedExtents;
|
||||
bool m_animatingIn = false;
|
||||
|
||||
// For pinned (sticky) windows
|
||||
bool m_pinned = false;
|
||||
|
||||
// For preserving pinned state when fullscreening a pinned window
|
||||
bool m_pinFullscreened = false;
|
||||
|
||||
// urgency hint
|
||||
bool m_isUrgent = false;
|
||||
|
||||
// for proper cycling. While cycling we can't just move the pointers, so we need to keep track of the last cycled window.
|
||||
PHLWINDOWREF m_lastCycledWindow;
|
||||
|
||||
// Window decorations
|
||||
// TODO: make this a SP.
|
||||
std::vector<UP<IHyprWindowDecoration>> m_windowDecorations;
|
||||
std::vector<IHyprWindowDecoration*> m_decosToRemove;
|
||||
|
||||
// Special render data, rules, etc
|
||||
UP<Desktop::Rule::CWindowRuleApplicator> m_ruleApplicator;
|
||||
|
||||
// Transformers
|
||||
std::vector<UP<IWindowTransformer>> m_transformers;
|
||||
|
||||
// for alpha
|
||||
PHLANIMVAR<float> m_activeInactiveAlpha;
|
||||
PHLANIMVAR<float> m_movingFromWorkspaceAlpha;
|
||||
|
||||
// animated shadow color
|
||||
PHLANIMVAR<CHyprColor> m_realShadowColor;
|
||||
|
||||
// animated tint
|
||||
PHLANIMVAR<float> m_dimPercent;
|
||||
|
||||
// animate moving to an invisible workspace
|
||||
int m_monitorMovedFrom = -1; // -1 means not moving
|
||||
PHLANIMVAR<float> m_movingToWorkspaceAlpha;
|
||||
|
||||
// swallowing
|
||||
PHLWINDOWREF m_swallowed;
|
||||
bool m_currentlySwallowed = false;
|
||||
bool m_groupSwallowed = false;
|
||||
|
||||
// for toplevel monitor events
|
||||
MONITORID m_lastSurfaceMonitorID = -1;
|
||||
|
||||
// initial token. Will be unregistered on workspace change or timeout of 2 minutes
|
||||
std::string m_initialWorkspaceToken = "";
|
||||
|
||||
// for groups
|
||||
struct SGroupData {
|
||||
PHLWINDOWREF pNextWindow; // nullptr means no grouping. Self means single group.
|
||||
bool head = false;
|
||||
bool locked = false; // per group lock
|
||||
bool deny = false; // deny window from enter a group or made a group
|
||||
} m_groupData;
|
||||
uint16_t m_groupRules = GROUP_NONE;
|
||||
|
||||
bool m_tearingHint = false;
|
||||
|
||||
// ANR
|
||||
PHLANIMVAR<float> m_notRespondingTint;
|
||||
|
||||
// For the noclosefor windowrule
|
||||
Time::steady_tp m_closeableSince = Time::steadyNow();
|
||||
|
||||
// For the list lookup
|
||||
bool operator==(const CWindow& rhs) const {
|
||||
return m_xdgSurface == rhs.m_xdgSurface && m_xwaylandSurface == rhs.m_xwaylandSurface && m_position == rhs.m_position && m_size == rhs.m_size &&
|
||||
m_fadingOut == rhs.m_fadingOut;
|
||||
}
|
||||
|
||||
// methods
|
||||
CBox getFullWindowBoundingBox();
|
||||
SBoxExtents getFullWindowExtents();
|
||||
CBox getWindowBoxUnified(uint64_t props);
|
||||
SBoxExtents getWindowExtentsUnified(uint64_t props);
|
||||
CBox getWindowIdealBoundingBoxIgnoreReserved();
|
||||
void addWindowDeco(UP<IHyprWindowDecoration> deco);
|
||||
void updateWindowDecos();
|
||||
void removeWindowDeco(IHyprWindowDecoration* deco);
|
||||
void uncacheWindowDecos();
|
||||
bool checkInputOnDecos(const eInputType, const Vector2D&, std::any = {});
|
||||
pid_t getPID();
|
||||
IHyprWindowDecoration* getDecorationByType(eDecorationType);
|
||||
void updateToplevel();
|
||||
void updateSurfaceScaleTransformDetails(bool force = false);
|
||||
void moveToWorkspace(PHLWORKSPACE);
|
||||
PHLWINDOW x11TransientFor();
|
||||
void onUnmap();
|
||||
void onMap();
|
||||
void setHidden(bool hidden);
|
||||
bool isHidden();
|
||||
void updateDecorationValues();
|
||||
SBoxExtents getFullWindowReservedArea();
|
||||
Vector2D middle();
|
||||
bool opaque();
|
||||
float rounding();
|
||||
float roundingPower();
|
||||
bool canBeTorn();
|
||||
void setSuspended(bool suspend);
|
||||
bool visibleOnMonitor(PHLMONITOR pMonitor);
|
||||
WORKSPACEID workspaceID();
|
||||
MONITORID monitorID();
|
||||
bool onSpecialWorkspace();
|
||||
void activate(bool force = false);
|
||||
int surfacesCount();
|
||||
void clampWindowSize(const std::optional<Vector2D> minSize, const std::optional<Vector2D> maxSize);
|
||||
bool isFullscreen();
|
||||
bool isEffectiveInternalFSMode(const eFullscreenMode);
|
||||
int getRealBorderSize();
|
||||
float getScrollMouse();
|
||||
float getScrollTouchpad();
|
||||
bool isScrollMouseOverridden();
|
||||
bool isScrollTouchpadOverridden();
|
||||
void updateWindowData();
|
||||
void updateWindowData(const struct SWorkspaceRule&);
|
||||
void onBorderAngleAnimEnd(WP<Hyprutils::Animation::CBaseAnimatedVariable> pav);
|
||||
bool isInCurvedCorner(double x, double y);
|
||||
bool hasPopupAt(const Vector2D& pos);
|
||||
int popupsCount();
|
||||
void applyGroupRules();
|
||||
void createGroup();
|
||||
void destroyGroup();
|
||||
PHLWINDOW getGroupHead();
|
||||
PHLWINDOW getGroupTail();
|
||||
PHLWINDOW getGroupCurrent();
|
||||
PHLWINDOW getGroupPrevious();
|
||||
PHLWINDOW getGroupWindowByIndex(int);
|
||||
bool hasInGroup(PHLWINDOW);
|
||||
int getGroupSize();
|
||||
bool canBeGroupedInto(PHLWINDOW pWindow);
|
||||
void setGroupCurrent(PHLWINDOW pWindow);
|
||||
void insertWindowToGroup(PHLWINDOW pWindow);
|
||||
void updateGroupOutputs();
|
||||
void switchWithWindowInGroup(PHLWINDOW pWindow);
|
||||
void setAnimationsToMove();
|
||||
void onWorkspaceAnimUpdate();
|
||||
void onFocusAnimUpdate();
|
||||
void onUpdateState();
|
||||
void onUpdateMeta();
|
||||
void onX11ConfigureRequest(CBox box);
|
||||
void onResourceChangeX11();
|
||||
std::string fetchTitle();
|
||||
std::string fetchClass();
|
||||
void warpCursor(bool force = false);
|
||||
PHLWINDOW getSwallower();
|
||||
bool isX11OverrideRedirect();
|
||||
bool isModal();
|
||||
Vector2D requestedMinSize();
|
||||
Vector2D requestedMaxSize();
|
||||
Vector2D realToReportSize();
|
||||
Vector2D realToReportPosition();
|
||||
Vector2D xwaylandSizeToReal(Vector2D size);
|
||||
Vector2D xwaylandPositionToReal(Vector2D size);
|
||||
void updateX11SurfaceScale();
|
||||
void sendWindowSize(bool force = false);
|
||||
NContentType::eContentType getContentType();
|
||||
void setContentType(NContentType::eContentType contentType);
|
||||
void deactivateGroupMembers();
|
||||
bool isNotResponding();
|
||||
std::optional<std::string> xdgTag();
|
||||
std::optional<std::string> xdgDescription();
|
||||
PHLWINDOW parent();
|
||||
bool priorityFocus();
|
||||
SP<CWLSurfaceResource> getSolitaryResource();
|
||||
Vector2D getReportedSize();
|
||||
std::optional<Vector2D> calculateExpression(const std::string& s);
|
||||
|
||||
CBox getWindowMainSurfaceBox() const {
|
||||
return {m_realPosition->value().x, m_realPosition->value().y, m_realSize->value().x, m_realSize->value().y};
|
||||
}
|
||||
|
||||
// listeners
|
||||
void onAck(uint32_t serial);
|
||||
|
||||
//
|
||||
std::unordered_map<std::string, std::string> getEnv();
|
||||
|
||||
//
|
||||
PHLWINDOWREF m_self;
|
||||
|
||||
// make private once we move listeners to inside CWindow
|
||||
struct {
|
||||
CHyprSignalListener map;
|
||||
CHyprSignalListener ack;
|
||||
CHyprSignalListener unmap;
|
||||
CHyprSignalListener commit;
|
||||
CHyprSignalListener destroy;
|
||||
CHyprSignalListener activate;
|
||||
CHyprSignalListener configureRequest;
|
||||
CHyprSignalListener setGeometry;
|
||||
CHyprSignalListener updateState;
|
||||
CHyprSignalListener updateMetadata;
|
||||
CHyprSignalListener resourceChange;
|
||||
} m_listeners;
|
||||
|
||||
private:
|
||||
std::optional<double> calculateSingleExpr(const std::string& s);
|
||||
|
||||
// For hidden windows and stuff
|
||||
bool m_hidden = false;
|
||||
bool m_suspended = false;
|
||||
WORKSPACEID m_lastWorkspace = WORKSPACE_INVALID;
|
||||
};
|
||||
|
||||
inline bool valid(PHLWINDOW w) {
|
||||
return w.get();
|
||||
}
|
||||
|
||||
inline bool valid(PHLWINDOWREF w) {
|
||||
return !w.expired();
|
||||
}
|
||||
|
||||
inline bool validMapped(PHLWINDOW w) {
|
||||
if (!valid(w))
|
||||
return false;
|
||||
return w->m_isMapped;
|
||||
}
|
||||
|
||||
inline bool validMapped(PHLWINDOWREF w) {
|
||||
if (!valid(w))
|
||||
return false;
|
||||
return w->m_isMapped;
|
||||
}
|
||||
|
||||
/**
|
||||
format specification
|
||||
- 'x', only address, equivalent of (uintpr_t)CWindow*
|
||||
- 'm', with monitor id
|
||||
- 'w', with workspace id
|
||||
- 'c', with application class
|
||||
*/
|
||||
|
||||
template <typename CharT>
|
||||
struct std::formatter<PHLWINDOW, CharT> : std::formatter<CharT> {
|
||||
bool formatAddressOnly = false;
|
||||
bool formatWorkspace = false;
|
||||
bool formatMonitor = false;
|
||||
bool formatClass = false;
|
||||
FORMAT_PARSE( //
|
||||
FORMAT_FLAG('x', formatAddressOnly) //
|
||||
FORMAT_FLAG('m', formatMonitor) //
|
||||
FORMAT_FLAG('w', formatWorkspace) //
|
||||
FORMAT_FLAG('c', formatClass),
|
||||
PHLWINDOW)
|
||||
|
||||
template <typename FormatContext>
|
||||
auto format(PHLWINDOW const& w, FormatContext& ctx) const {
|
||||
auto&& out = ctx.out();
|
||||
if (formatAddressOnly)
|
||||
return std::format_to(out, "{:x}", rc<uintptr_t>(w.get()));
|
||||
if (!w)
|
||||
return std::format_to(out, "[Window nullptr]");
|
||||
|
||||
std::format_to(out, "[");
|
||||
std::format_to(out, "Window {:x}: title: \"{}\"", rc<uintptr_t>(w.get()), w->m_title);
|
||||
if (formatWorkspace)
|
||||
std::format_to(out, ", workspace: {}", w->m_workspace ? w->workspaceID() : WORKSPACE_INVALID);
|
||||
if (formatMonitor)
|
||||
std::format_to(out, ", monitor: {}", w->monitorID());
|
||||
if (formatClass)
|
||||
std::format_to(out, ", class: {}", w->m_class);
|
||||
return std::format_to(out, "]");
|
||||
}
|
||||
};
|
||||
|
|
@ -13,8 +13,6 @@ enum eFullscreenMode : int8_t {
|
|||
FSMODE_MAX = (1 << 2) - 1
|
||||
};
|
||||
|
||||
class CWindow;
|
||||
|
||||
class CWorkspace {
|
||||
public:
|
||||
static PHLWORKSPACE create(WORKSPACEID id, PHLMONITOR monitor, std::string name, bool special = false, bool isEmpty = true);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#include "Engine.hpp"
|
||||
#include "Rule.hpp"
|
||||
#include "../LayerSurface.hpp"
|
||||
#include "../view/LayerSurface.hpp"
|
||||
#include "../../Compositor.hpp"
|
||||
|
||||
using namespace Desktop;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#include "LayerRule.hpp"
|
||||
#include "../../../debug/Log.hpp"
|
||||
#include "../../LayerSurface.hpp"
|
||||
#include "../../view/LayerSurface.hpp"
|
||||
|
||||
using namespace Desktop;
|
||||
using namespace Desktop::Rule;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#include "LayerRuleApplicator.hpp"
|
||||
#include "LayerRule.hpp"
|
||||
#include "../Engine.hpp"
|
||||
#include "../../LayerSurface.hpp"
|
||||
#include "../../view/LayerSurface.hpp"
|
||||
#include "../../types/OverridableVar.hpp"
|
||||
#include "../../../helpers/MiscFunctions.hpp"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#include "WindowRule.hpp"
|
||||
#include "../../Window.hpp"
|
||||
#include "../../view/Window.hpp"
|
||||
#include "../../../helpers/Monitor.hpp"
|
||||
#include "../../../Compositor.hpp"
|
||||
#include "../../../managers/TokenManager.hpp"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
#include "WindowRule.hpp"
|
||||
#include "../Engine.hpp"
|
||||
#include "../utils/SetUtils.hpp"
|
||||
#include "../../Window.hpp"
|
||||
#include "../../view/Window.hpp"
|
||||
#include "../../types/OverridableVar.hpp"
|
||||
#include "../../../managers/LayoutManager.hpp"
|
||||
#include "../../../managers/HookSystemManager.hpp"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#include "FocusState.hpp"
|
||||
#include "../Window.hpp"
|
||||
#include "../view/Window.hpp"
|
||||
#include "../../Compositor.hpp"
|
||||
#include "../../protocols/XDGShell.hpp"
|
||||
#include "../../render/Renderer.hpp"
|
||||
|
|
@ -191,7 +191,7 @@ void CFocusState::rawWindowFocus(PHLWINDOW pWindow, SP<CWLSurfaceResource> surfa
|
|||
g_pXWaylandManager->activateWindow(PLASTWINDOW, false);
|
||||
}
|
||||
|
||||
const auto PWINDOWSURFACE = surface ? surface : pWindow->m_wlSurface->resource();
|
||||
const auto PWINDOWSURFACE = surface ? surface : pWindow->wlSurface()->resource();
|
||||
|
||||
rawSurfaceFocus(PWINDOWSURFACE, pWindow);
|
||||
|
||||
|
|
@ -227,7 +227,7 @@ void CFocusState::rawWindowFocus(PHLWINDOW pWindow, SP<CWLSurfaceResource> surfa
|
|||
}
|
||||
|
||||
void CFocusState::rawSurfaceFocus(SP<CWLSurfaceResource> pSurface, PHLWINDOW pWindowOwner) {
|
||||
if (g_pSeatManager->m_state.keyboardFocus == pSurface || (pWindowOwner && g_pSeatManager->m_state.keyboardFocus == pWindowOwner->m_wlSurface->resource()))
|
||||
if (g_pSeatManager->m_state.keyboardFocus == pSurface || (pWindowOwner && g_pSeatManager->m_state.keyboardFocus == pWindowOwner->wlSurface()->resource()))
|
||||
return; // Don't focus when already focused on this.
|
||||
|
||||
if (g_pSessionLockManager->isSessionLocked() && pSurface && !g_pSessionLockManager->isSurfaceSessionLock(pSurface))
|
||||
|
|
@ -266,8 +266,8 @@ void CFocusState::rawSurfaceFocus(SP<CWLSurfaceResource> pSurface, PHLWINDOW pWi
|
|||
|
||||
EMIT_HOOK_EVENT("keyboardFocus", pSurface);
|
||||
|
||||
const auto SURF = CWLSurface::fromResource(pSurface);
|
||||
const auto OLDSURF = CWLSurface::fromResource(PLASTSURF);
|
||||
const auto SURF = Desktop::View::CWLSurface::fromResource(pSurface);
|
||||
const auto OLDSURF = Desktop::View::CWLSurface::fromResource(PLASTSURF);
|
||||
|
||||
if (OLDSURF && OLDSURF->constraint())
|
||||
OLDSURF->constraint()->deactivate();
|
||||
|
|
|
|||
82
src/desktop/view/GlobalViewMethods.cpp
Normal file
82
src/desktop/view/GlobalViewMethods.cpp
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
#include "GlobalViewMethods.hpp"
|
||||
#include "../../Compositor.hpp"
|
||||
|
||||
#include "LayerSurface.hpp"
|
||||
#include "Window.hpp"
|
||||
#include "Popup.hpp"
|
||||
#include "Subsurface.hpp"
|
||||
#include "SessionLock.hpp"
|
||||
|
||||
#include "../../protocols/core/Compositor.hpp"
|
||||
#include "../../protocols/core/Subcompositor.hpp"
|
||||
#include "../../protocols/SessionLock.hpp"
|
||||
|
||||
using namespace Desktop;
|
||||
using namespace Desktop::View;
|
||||
|
||||
std::vector<SP<IView>> View::getViewsForWorkspace(PHLWORKSPACE ws) {
|
||||
std::vector<SP<IView>> views;
|
||||
|
||||
for (const auto& w : g_pCompositor->m_windows) {
|
||||
if (!w->visible() || w->m_workspace != ws)
|
||||
continue;
|
||||
|
||||
views.emplace_back(w);
|
||||
|
||||
w->wlSurface()->resource()->breadthfirst(
|
||||
[&views](SP<CWLSurfaceResource> s, const Vector2D& pos, void* data) {
|
||||
auto surf = CWLSurface::fromResource(s);
|
||||
if (!surf || !s->m_mapped)
|
||||
return;
|
||||
|
||||
views.emplace_back(surf->view());
|
||||
},
|
||||
nullptr);
|
||||
|
||||
// xwl windows dont have this
|
||||
if (w->m_popupHead) {
|
||||
w->m_popupHead->breadthfirst(
|
||||
[&views](SP<CPopup> s, void* data) {
|
||||
auto surf = s->wlSurface();
|
||||
if (!surf || !s->visible())
|
||||
return;
|
||||
|
||||
views.emplace_back(surf->view());
|
||||
},
|
||||
nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& l : g_pCompositor->m_layers) {
|
||||
if (!l->visible() || l->m_monitor != ws->m_monitor)
|
||||
continue;
|
||||
|
||||
views.emplace_back(l);
|
||||
|
||||
l->m_popupHead->breadthfirst(
|
||||
[&views](SP<CPopup> p, void* data) {
|
||||
auto surf = p->wlSurface();
|
||||
if (!surf || !p->visible())
|
||||
return;
|
||||
|
||||
views.emplace_back(surf->view());
|
||||
},
|
||||
nullptr);
|
||||
}
|
||||
|
||||
for (const auto& v : g_pCompositor->m_otherViews) {
|
||||
if (!v->visible() || !v->desktopComponent())
|
||||
continue;
|
||||
|
||||
if (v->type() == VIEW_TYPE_LOCK_SCREEN) {
|
||||
const auto LOCK = Desktop::View::CSessionLock::fromView(v);
|
||||
if (LOCK->monitor() != ws->m_monitor)
|
||||
continue;
|
||||
|
||||
views.emplace_back(LOCK);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return views;
|
||||
}
|
||||
11
src/desktop/view/GlobalViewMethods.hpp
Normal file
11
src/desktop/view/GlobalViewMethods.hpp
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include "View.hpp"
|
||||
|
||||
#include "../Workspace.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Desktop::View {
|
||||
std::vector<SP<IView>> getViewsForWorkspace(PHLWORKSPACE ws);
|
||||
};
|
||||
|
|
@ -1,25 +1,27 @@
|
|||
#include "LayerSurface.hpp"
|
||||
#include "state/FocusState.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
#include "../events/Events.hpp"
|
||||
#include "../protocols/LayerShell.hpp"
|
||||
#include "../protocols/core/Compositor.hpp"
|
||||
#include "../managers/SeatManager.hpp"
|
||||
#include "../managers/animation/AnimationManager.hpp"
|
||||
#include "../managers/animation/DesktopAnimationManager.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
#include "../config/ConfigManager.hpp"
|
||||
#include "../helpers/Monitor.hpp"
|
||||
#include "../managers/input/InputManager.hpp"
|
||||
#include "../managers/HookSystemManager.hpp"
|
||||
#include "../managers/EventManager.hpp"
|
||||
#include "../state/FocusState.hpp"
|
||||
#include "../../Compositor.hpp"
|
||||
#include "../../protocols/LayerShell.hpp"
|
||||
#include "../../protocols/core/Compositor.hpp"
|
||||
#include "../../managers/SeatManager.hpp"
|
||||
#include "../../managers/animation/AnimationManager.hpp"
|
||||
#include "../../managers/animation/DesktopAnimationManager.hpp"
|
||||
#include "../../render/Renderer.hpp"
|
||||
#include "../../config/ConfigManager.hpp"
|
||||
#include "../../helpers/Monitor.hpp"
|
||||
#include "../../managers/input/InputManager.hpp"
|
||||
#include "../../managers/HookSystemManager.hpp"
|
||||
#include "../../managers/EventManager.hpp"
|
||||
|
||||
using namespace Desktop;
|
||||
using namespace Desktop::View;
|
||||
|
||||
PHLLS CLayerSurface::create(SP<CLayerShellResource> resource) {
|
||||
PHLLS pLS = SP<CLayerSurface>(new CLayerSurface(resource));
|
||||
|
||||
auto pMonitor = resource->m_monitor.empty() ? Desktop::focusState()->monitor() : g_pCompositor->getMonitorFromName(resource->m_monitor);
|
||||
|
||||
pLS->m_surface->assign(resource->m_surface.lock(), pLS);
|
||||
pLS->m_wlSurface->assign(resource->m_surface.lock(), pLS);
|
||||
|
||||
if (!pMonitor) {
|
||||
Debug::log(ERR, "New LS has no monitor??");
|
||||
|
|
@ -54,6 +56,12 @@ PHLLS CLayerSurface::create(SP<CLayerShellResource> resource) {
|
|||
return pLS;
|
||||
}
|
||||
|
||||
PHLLS CLayerSurface::fromView(SP<IView> v) {
|
||||
if (!v || v->type() != VIEW_TYPE_LAYER_SURFACE)
|
||||
return nullptr;
|
||||
return dynamicPointerCast<CLayerSurface>(v);
|
||||
}
|
||||
|
||||
void CLayerSurface::registerCallbacks() {
|
||||
m_alpha->setUpdateCallback([this](auto) {
|
||||
if (m_ruleApplicator->dimAround().valueOrDefault() && m_monitor)
|
||||
|
|
@ -61,21 +69,19 @@ void CLayerSurface::registerCallbacks() {
|
|||
});
|
||||
}
|
||||
|
||||
CLayerSurface::CLayerSurface(SP<CLayerShellResource> resource_) : m_layerSurface(resource_) {
|
||||
CLayerSurface::CLayerSurface(SP<CLayerShellResource> resource_) : IView(CWLSurface::create()), m_layerSurface(resource_) {
|
||||
m_listeners.commit = m_layerSurface->m_events.commit.listen([this] { onCommit(); });
|
||||
m_listeners.map = m_layerSurface->m_events.map.listen([this] { onMap(); });
|
||||
m_listeners.unmap = m_layerSurface->m_events.unmap.listen([this] { onUnmap(); });
|
||||
m_listeners.destroy = m_layerSurface->m_events.destroy.listen([this] { onDestroy(); });
|
||||
|
||||
m_surface = CWLSurface::create();
|
||||
}
|
||||
|
||||
CLayerSurface::~CLayerSurface() {
|
||||
if (!g_pHyprOpenGL)
|
||||
return;
|
||||
|
||||
if (m_surface)
|
||||
m_surface->unassign();
|
||||
if (m_wlSurface)
|
||||
m_wlSurface->unassign();
|
||||
g_pHyprRenderer->makeEGLCurrent();
|
||||
std::erase_if(g_pHyprOpenGL->m_layerFramebuffers, [&](const auto& other) { return other.first.expired() || other.first.lock() == m_self.lock(); });
|
||||
|
||||
|
|
@ -86,6 +92,29 @@ CLayerSurface::~CLayerSurface() {
|
|||
}
|
||||
}
|
||||
|
||||
eViewType CLayerSurface::type() const {
|
||||
return VIEW_TYPE_LAYER_SURFACE;
|
||||
}
|
||||
|
||||
bool CLayerSurface::visible() const {
|
||||
return (m_mapped && m_layerSurface && m_layerSurface->m_mapped && m_wlSurface && m_wlSurface->resource()) || (m_fadingOut && m_alpha->value() > 0.F);
|
||||
}
|
||||
|
||||
std::optional<CBox> CLayerSurface::logicalBox() const {
|
||||
return surfaceLogicalBox();
|
||||
}
|
||||
|
||||
std::optional<CBox> CLayerSurface::surfaceLogicalBox() const {
|
||||
if (!visible())
|
||||
return std::nullopt;
|
||||
|
||||
return CBox{m_realPosition->value(), m_realSize->value()};
|
||||
}
|
||||
|
||||
bool CLayerSurface::desktopComponent() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void CLayerSurface::onDestroy() {
|
||||
Debug::log(LOG, "LayerSurface {:x} destroyed", rc<uintptr_t>(m_layerSurface.get()));
|
||||
|
||||
|
|
@ -123,8 +152,8 @@ void CLayerSurface::onDestroy() {
|
|||
|
||||
m_readyToDelete = true;
|
||||
m_layerSurface.reset();
|
||||
if (m_surface)
|
||||
m_surface->unassign();
|
||||
if (m_wlSurface)
|
||||
m_wlSurface->unassign();
|
||||
|
||||
m_listeners.unmap.reset();
|
||||
m_listeners.destroy.reset();
|
||||
|
|
@ -156,7 +185,7 @@ void CLayerSurface::onMap() {
|
|||
|
||||
g_pHyprRenderer->arrangeLayersForMonitor(PMONITOR->m_id);
|
||||
|
||||
m_surface->resource()->enter(PMONITOR->m_self.lock());
|
||||
m_wlSurface->resource()->enter(PMONITOR->m_self.lock());
|
||||
|
||||
const bool ISEXCLUSIVE = m_layerSurface->m_current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE;
|
||||
|
||||
|
|
@ -170,14 +199,14 @@ void CLayerSurface::onMap() {
|
|||
|
||||
if (GRABSFOCUS) {
|
||||
// TODO: use the new superb really very cool grab
|
||||
if (g_pSeatManager->m_seatGrab && !g_pSeatManager->m_seatGrab->accepts(m_surface->resource()))
|
||||
if (g_pSeatManager->m_seatGrab && !g_pSeatManager->m_seatGrab->accepts(m_wlSurface->resource()))
|
||||
g_pSeatManager->setGrab(nullptr);
|
||||
|
||||
g_pInputManager->releaseAllMouseButtons();
|
||||
Desktop::focusState()->rawSurfaceFocus(m_surface->resource());
|
||||
Desktop::focusState()->rawSurfaceFocus(m_wlSurface->resource());
|
||||
|
||||
const auto LOCAL = g_pInputManager->getMouseCoordsInternal() - Vector2D(m_geometry.x + PMONITOR->m_position.x, m_geometry.y + PMONITOR->m_position.y);
|
||||
g_pSeatManager->setPointerFocus(m_surface->resource(), LOCAL);
|
||||
g_pSeatManager->setPointerFocus(m_wlSurface->resource(), LOCAL);
|
||||
g_pInputManager->m_emptyFocusCursorSet = false;
|
||||
}
|
||||
|
||||
|
|
@ -194,8 +223,8 @@ void CLayerSurface::onMap() {
|
|||
g_pEventManager->postEvent(SHyprIPCEvent{.event = "openlayer", .data = m_namespace});
|
||||
EMIT_HOOK_EVENT("openLayer", m_self.lock());
|
||||
|
||||
g_pCompositor->setPreferredScaleForSurface(m_surface->resource(), PMONITOR->m_scale);
|
||||
g_pCompositor->setPreferredTransformForSurface(m_surface->resource(), PMONITOR->m_transform);
|
||||
g_pCompositor->setPreferredScaleForSurface(m_wlSurface->resource(), PMONITOR->m_scale);
|
||||
g_pCompositor->setPreferredTransformForSurface(m_wlSurface->resource(), PMONITOR->m_transform);
|
||||
}
|
||||
|
||||
void CLayerSurface::onUnmap() {
|
||||
|
|
@ -238,7 +267,7 @@ void CLayerSurface::onUnmap() {
|
|||
|
||||
const auto PMONITOR = m_monitor.lock();
|
||||
|
||||
const bool WASLASTFOCUS = g_pSeatManager->m_state.keyboardFocus == m_surface->resource() || g_pSeatManager->m_state.pointerFocus == m_surface->resource();
|
||||
const bool WASLASTFOCUS = g_pSeatManager->m_state.keyboardFocus == m_wlSurface->resource() || g_pSeatManager->m_state.pointerFocus == m_wlSurface->resource();
|
||||
|
||||
if (!PMONITOR)
|
||||
return;
|
||||
|
|
@ -249,7 +278,7 @@ void CLayerSurface::onUnmap() {
|
|||
(Desktop::focusState()->surface() && Desktop::focusState()->surface()->m_hlSurface && !Desktop::focusState()->surface()->m_hlSurface->keyboardFocusable())) {
|
||||
if (!g_pInputManager->refocusLastWindow(PMONITOR))
|
||||
g_pInputManager->refocus();
|
||||
} else if (Desktop::focusState()->surface() && Desktop::focusState()->surface() != m_surface->resource())
|
||||
} else if (Desktop::focusState()->surface() && Desktop::focusState()->surface() != m_wlSurface->resource())
|
||||
g_pSeatManager->setKeyboardFocus(Desktop::focusState()->surface());
|
||||
|
||||
CBox geomFixed = {m_geometry.x + PMONITOR->m_position.x, m_geometry.y + PMONITOR->m_position.y, m_geometry.width, m_geometry.height};
|
||||
|
|
@ -359,8 +388,8 @@ void CLayerSurface::onCommit() {
|
|||
nullptr);
|
||||
if (!WASLASTFOCUS && m_popupHead) {
|
||||
m_popupHead->breadthfirst(
|
||||
[&WASLASTFOCUS](WP<CPopup> popup, void* data) {
|
||||
WASLASTFOCUS = WASLASTFOCUS || (popup->m_wlSurface && g_pSeatManager->m_state.keyboardFocus == popup->m_wlSurface->resource());
|
||||
[&WASLASTFOCUS](WP<Desktop::View::CPopup> popup, void* data) {
|
||||
WASLASTFOCUS = WASLASTFOCUS || (popup->wlSurface() && g_pSeatManager->m_state.keyboardFocus == popup->wlSurface()->resource());
|
||||
},
|
||||
nullptr);
|
||||
}
|
||||
|
|
@ -384,20 +413,20 @@ void CLayerSurface::onCommit() {
|
|||
// if now exclusive and not previously
|
||||
g_pSeatManager->setGrab(nullptr);
|
||||
g_pInputManager->releaseAllMouseButtons();
|
||||
Desktop::focusState()->rawSurfaceFocus(m_surface->resource());
|
||||
Desktop::focusState()->rawSurfaceFocus(m_wlSurface->resource());
|
||||
|
||||
const auto LOCAL = g_pInputManager->getMouseCoordsInternal() - Vector2D(m_geometry.x + PMONITOR->m_position.x, m_geometry.y + PMONITOR->m_position.y);
|
||||
g_pSeatManager->setPointerFocus(m_surface->resource(), LOCAL);
|
||||
g_pSeatManager->setPointerFocus(m_wlSurface->resource(), LOCAL);
|
||||
g_pInputManager->m_emptyFocusCursorSet = false;
|
||||
}
|
||||
}
|
||||
|
||||
m_interactivity = m_layerSurface->m_current.interactivity;
|
||||
|
||||
g_pHyprRenderer->damageSurface(m_surface->resource(), m_position.x, m_position.y);
|
||||
g_pHyprRenderer->damageSurface(m_wlSurface->resource(), m_position.x, m_position.y);
|
||||
|
||||
g_pCompositor->setPreferredScaleForSurface(m_surface->resource(), PMONITOR->m_scale);
|
||||
g_pCompositor->setPreferredTransformForSurface(m_surface->resource(), PMONITOR->m_transform);
|
||||
g_pCompositor->setPreferredScaleForSurface(m_wlSurface->resource(), PMONITOR->m_scale);
|
||||
g_pCompositor->setPreferredTransformForSurface(m_wlSurface->resource(), PMONITOR->m_transform);
|
||||
}
|
||||
|
||||
bool CLayerSurface::isFadedOut() {
|
||||
|
|
@ -412,7 +441,7 @@ int CLayerSurface::popupsCount() {
|
|||
return 0;
|
||||
|
||||
int no = -1; // we have one dummy
|
||||
m_popupHead->breadthfirst([](WP<CPopup> p, void* data) { *sc<int*>(data) += 1; }, &no);
|
||||
m_popupHead->breadthfirst([](WP<Desktop::View::CPopup> p, void* data) { *sc<int*>(data) += 1; }, &no);
|
||||
return no;
|
||||
}
|
||||
|
||||
|
|
@ -424,10 +453,10 @@ pid_t CLayerSurface::getPID() {
|
|||
pid_t PID = -1;
|
||||
|
||||
if (!m_layerSurface || !m_layerSurface->m_surface || !m_layerSurface->m_surface->getResource() || !m_layerSurface->m_surface->getResource()->resource() ||
|
||||
!m_layerSurface->m_surface->getResource()->resource()->client)
|
||||
!m_layerSurface->m_surface->getResource()->client())
|
||||
return -1;
|
||||
|
||||
wl_client_get_credentials(m_layerSurface->m_surface->getResource()->resource()->client, &PID, nullptr, nullptr);
|
||||
wl_client_get_credentials(m_layerSurface->m_surface->getResource()->client(), &PID, nullptr, nullptr);
|
||||
|
||||
return PID;
|
||||
}
|
||||
105
src/desktop/view/LayerSurface.hpp
Normal file
105
src/desktop/view/LayerSurface.hpp
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "../../defines.hpp"
|
||||
#include "WLSurface.hpp"
|
||||
#include "View.hpp"
|
||||
#include "../rule/layerRule/LayerRuleApplicator.hpp"
|
||||
#include "../../helpers/AnimatedVariable.hpp"
|
||||
|
||||
class CLayerShellResource;
|
||||
|
||||
namespace Desktop::View {
|
||||
|
||||
class CLayerSurface : public IView {
|
||||
public:
|
||||
static PHLLS create(SP<CLayerShellResource>);
|
||||
static PHLLS fromView(SP<IView>);
|
||||
|
||||
private:
|
||||
CLayerSurface(SP<CLayerShellResource>);
|
||||
|
||||
public:
|
||||
virtual ~CLayerSurface();
|
||||
|
||||
virtual eViewType type() const;
|
||||
virtual bool visible() const;
|
||||
virtual std::optional<CBox> logicalBox() const;
|
||||
virtual bool desktopComponent() const;
|
||||
virtual std::optional<CBox> surfaceLogicalBox() const;
|
||||
|
||||
bool isFadedOut();
|
||||
int popupsCount();
|
||||
|
||||
PHLANIMVAR<Vector2D> m_realPosition;
|
||||
PHLANIMVAR<Vector2D> m_realSize;
|
||||
PHLANIMVAR<float> m_alpha;
|
||||
|
||||
WP<CLayerShellResource> m_layerSurface;
|
||||
|
||||
// the header providing the enum type cannot be imported here
|
||||
int m_interactivity = 0;
|
||||
|
||||
bool m_mapped = false;
|
||||
uint32_t m_layer = 0;
|
||||
|
||||
PHLMONITORREF m_monitor;
|
||||
|
||||
bool m_fadingOut = false;
|
||||
bool m_readyToDelete = false;
|
||||
bool m_noProcess = false;
|
||||
|
||||
UP<Desktop::Rule::CLayerRuleApplicator> m_ruleApplicator;
|
||||
|
||||
PHLLSREF m_self;
|
||||
|
||||
CBox m_geometry = {0, 0, 0, 0};
|
||||
Vector2D m_position;
|
||||
std::string m_namespace = "";
|
||||
SP<Desktop::View::CPopup> m_popupHead;
|
||||
|
||||
pid_t getPID();
|
||||
|
||||
void onDestroy();
|
||||
void onMap();
|
||||
void onUnmap();
|
||||
void onCommit();
|
||||
MONITORID monitorID();
|
||||
|
||||
private:
|
||||
struct {
|
||||
CHyprSignalListener destroy;
|
||||
CHyprSignalListener map;
|
||||
CHyprSignalListener unmap;
|
||||
CHyprSignalListener commit;
|
||||
} m_listeners;
|
||||
|
||||
void registerCallbacks();
|
||||
|
||||
// For the list lookup
|
||||
bool operator==(const CLayerSurface& rhs) const {
|
||||
return m_layerSurface == rhs.m_layerSurface && m_monitor == rhs.m_monitor;
|
||||
}
|
||||
};
|
||||
|
||||
inline bool valid(PHLLS l) {
|
||||
return l;
|
||||
}
|
||||
|
||||
inline bool valid(PHLLSREF l) {
|
||||
return l;
|
||||
}
|
||||
|
||||
inline bool validMapped(PHLLS l) {
|
||||
if (!valid(l))
|
||||
return false;
|
||||
return l->visible();
|
||||
}
|
||||
|
||||
inline bool validMapped(PHLLSREF l) {
|
||||
if (!valid(l))
|
||||
return false;
|
||||
return l->visible();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,43 +1,45 @@
|
|||
#include "Popup.hpp"
|
||||
#include "../config/ConfigValue.hpp"
|
||||
#include "../config/ConfigManager.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
#include "../protocols/LayerShell.hpp"
|
||||
#include "../protocols/XDGShell.hpp"
|
||||
#include "../protocols/core/Compositor.hpp"
|
||||
#include "../managers/SeatManager.hpp"
|
||||
#include "../managers/animation/AnimationManager.hpp"
|
||||
#include "../desktop/LayerSurface.hpp"
|
||||
#include "../managers/input/InputManager.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
#include "../render/OpenGL.hpp"
|
||||
#include "../../config/ConfigValue.hpp"
|
||||
#include "../../config/ConfigManager.hpp"
|
||||
#include "../../Compositor.hpp"
|
||||
#include "../../protocols/LayerShell.hpp"
|
||||
#include "../../protocols/XDGShell.hpp"
|
||||
#include "../../protocols/core/Compositor.hpp"
|
||||
#include "../../managers/SeatManager.hpp"
|
||||
#include "../../managers/animation/AnimationManager.hpp"
|
||||
#include "LayerSurface.hpp"
|
||||
#include "../../managers/input/InputManager.hpp"
|
||||
#include "../../render/Renderer.hpp"
|
||||
#include "../../render/OpenGL.hpp"
|
||||
#include <ranges>
|
||||
|
||||
UP<CPopup> CPopup::create(PHLWINDOW pOwner) {
|
||||
auto popup = UP<CPopup>(new CPopup());
|
||||
using namespace Desktop;
|
||||
using namespace Desktop::View;
|
||||
|
||||
SP<CPopup> CPopup::create(PHLWINDOW pOwner) {
|
||||
auto popup = SP<CPopup>(new CPopup());
|
||||
popup->m_windowOwner = pOwner;
|
||||
popup->m_self = popup;
|
||||
popup->initAllSignals();
|
||||
return popup;
|
||||
}
|
||||
|
||||
UP<CPopup> CPopup::create(PHLLS pOwner) {
|
||||
auto popup = UP<CPopup>(new CPopup());
|
||||
SP<CPopup> CPopup::create(PHLLS pOwner) {
|
||||
auto popup = SP<CPopup>(new CPopup());
|
||||
popup->m_layerOwner = pOwner;
|
||||
popup->m_self = popup;
|
||||
popup->initAllSignals();
|
||||
return popup;
|
||||
}
|
||||
|
||||
UP<CPopup> CPopup::create(SP<CXDGPopupResource> resource, WP<CPopup> pOwner) {
|
||||
auto popup = UP<CPopup>(new CPopup());
|
||||
SP<CPopup> CPopup::create(SP<CXDGPopupResource> resource, WP<CPopup> pOwner) {
|
||||
auto popup = SP<CPopup>(new CPopup());
|
||||
popup->m_resource = resource;
|
||||
popup->m_windowOwner = pOwner->m_windowOwner;
|
||||
popup->m_layerOwner = pOwner->m_layerOwner;
|
||||
popup->m_parent = pOwner;
|
||||
popup->m_self = popup;
|
||||
popup->m_wlSurface = CWLSurface::create();
|
||||
popup->m_wlSurface->assign(resource->m_surface->m_surface.lock(), popup.get());
|
||||
popup->wlSurface()->assign(resource->m_surface->m_surface.lock(), popup);
|
||||
|
||||
popup->m_lastSize = resource->m_surface->m_current.geometry.size();
|
||||
popup->reposition();
|
||||
|
|
@ -46,11 +48,56 @@ UP<CPopup> CPopup::create(SP<CXDGPopupResource> resource, WP<CPopup> pOwner) {
|
|||
return popup;
|
||||
}
|
||||
|
||||
SP<CPopup> CPopup::fromView(SP<IView> v) {
|
||||
if (!v || v->type() != VIEW_TYPE_POPUP)
|
||||
return nullptr;
|
||||
return dynamicPointerCast<CPopup>(v);
|
||||
}
|
||||
|
||||
CPopup::CPopup() : IView(CWLSurface::create()) {
|
||||
;
|
||||
}
|
||||
|
||||
CPopup::~CPopup() {
|
||||
if (m_wlSurface)
|
||||
m_wlSurface->unassign();
|
||||
}
|
||||
|
||||
eViewType CPopup::type() const {
|
||||
return VIEW_TYPE_POPUP;
|
||||
}
|
||||
|
||||
bool CPopup::visible() const {
|
||||
if (!m_mapped || !m_wlSurface->resource())
|
||||
return false;
|
||||
|
||||
if (!m_windowOwner.expired())
|
||||
return g_pHyprRenderer->shouldRenderWindow(m_windowOwner.lock());
|
||||
|
||||
if (!m_layerOwner.expired())
|
||||
return true;
|
||||
|
||||
if (m_parent)
|
||||
return m_parent->visible();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::optional<CBox> CPopup::logicalBox() const {
|
||||
return surfaceLogicalBox();
|
||||
}
|
||||
|
||||
std::optional<CBox> CPopup::surfaceLogicalBox() const {
|
||||
if (!visible())
|
||||
return std::nullopt;
|
||||
|
||||
return CBox{t1ParentCoords(), size()};
|
||||
}
|
||||
|
||||
bool CPopup::desktopComponent() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void CPopup::initAllSignals() {
|
||||
|
||||
g_pAnimationManager->createAnimation(0.f, m_alpha, g_pConfigManager->getAnimationPropertyConfig("fadePopupsIn"), AVARDAMAGE_NONE);
|
||||
|
|
@ -286,11 +333,11 @@ void CPopup::reposition() {
|
|||
m_resource->applyPositioning(box, COORDS);
|
||||
}
|
||||
|
||||
SP<CWLSurface> CPopup::getT1Owner() {
|
||||
SP<Desktop::View::CWLSurface> CPopup::getT1Owner() {
|
||||
if (m_windowOwner)
|
||||
return m_windowOwner->m_wlSurface;
|
||||
return m_windowOwner->wlSurface();
|
||||
else
|
||||
return m_layerOwner->m_surface;
|
||||
return m_layerOwner->wlSurface();
|
||||
}
|
||||
|
||||
Vector2D CPopup::coordsRelativeToParent() {
|
||||
|
|
@ -304,7 +351,7 @@ Vector2D CPopup::coordsRelativeToParent() {
|
|||
|
||||
while (current->m_parent && current->m_resource) {
|
||||
|
||||
offset += current->m_wlSurface->resource()->m_current.offset;
|
||||
offset += current->wlSurface()->resource()->m_current.offset;
|
||||
offset += current->m_resource->m_geometry.pos();
|
||||
|
||||
current = current->m_parent;
|
||||
|
|
@ -321,7 +368,7 @@ Vector2D CPopup::localToGlobal(const Vector2D& rel) {
|
|||
return t1ParentCoords() + rel;
|
||||
}
|
||||
|
||||
Vector2D CPopup::t1ParentCoords() {
|
||||
Vector2D CPopup::t1ParentCoords() const {
|
||||
if (!m_windowOwner.expired())
|
||||
return m_windowOwner->m_realPosition->value();
|
||||
if (!m_layerOwner.expired())
|
||||
|
|
@ -352,36 +399,25 @@ void CPopup::recheckChildrenRecursive() {
|
|||
}
|
||||
}
|
||||
|
||||
Vector2D CPopup::size() {
|
||||
Vector2D CPopup::size() const {
|
||||
return m_lastSize;
|
||||
}
|
||||
|
||||
void CPopup::sendScale() {
|
||||
if (!m_windowOwner.expired())
|
||||
g_pCompositor->setPreferredScaleForSurface(m_wlSurface->resource(), m_windowOwner->m_wlSurface->m_lastScaleFloat);
|
||||
g_pCompositor->setPreferredScaleForSurface(m_wlSurface->resource(), m_windowOwner->wlSurface()->m_lastScaleFloat);
|
||||
else if (!m_layerOwner.expired())
|
||||
g_pCompositor->setPreferredScaleForSurface(m_wlSurface->resource(), m_layerOwner->m_surface->m_lastScaleFloat);
|
||||
g_pCompositor->setPreferredScaleForSurface(m_wlSurface->resource(), m_layerOwner->wlSurface()->m_lastScaleFloat);
|
||||
else
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
bool CPopup::visible() {
|
||||
if (!m_windowOwner.expired())
|
||||
return g_pHyprRenderer->shouldRenderWindow(m_windowOwner.lock());
|
||||
if (!m_layerOwner.expired())
|
||||
return true;
|
||||
if (m_parent)
|
||||
return m_parent->visible();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CPopup::bfHelper(std::vector<WP<CPopup>> const& nodes, std::function<void(WP<CPopup>, void*)> fn, void* data) {
|
||||
void CPopup::bfHelper(std::vector<SP<CPopup>> const& nodes, std::function<void(SP<CPopup>, void*)> fn, void* data) {
|
||||
for (auto const& n : nodes) {
|
||||
fn(n, data);
|
||||
}
|
||||
|
||||
std::vector<WP<CPopup>> nodes2;
|
||||
std::vector<SP<CPopup>> nodes2;
|
||||
nodes2.reserve(nodes.size() * 2);
|
||||
|
||||
for (auto const& n : nodes) {
|
||||
|
|
@ -389,7 +425,7 @@ void CPopup::bfHelper(std::vector<WP<CPopup>> const& nodes, std::function<void(W
|
|||
continue;
|
||||
|
||||
for (auto const& c : n->m_children) {
|
||||
nodes2.push_back(c->m_self);
|
||||
nodes2.emplace_back(c->m_self.lock());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -397,18 +433,18 @@ void CPopup::bfHelper(std::vector<WP<CPopup>> const& nodes, std::function<void(W
|
|||
bfHelper(nodes2, fn, data);
|
||||
}
|
||||
|
||||
void CPopup::breadthfirst(std::function<void(WP<CPopup>, void*)> fn, void* data) {
|
||||
void CPopup::breadthfirst(std::function<void(SP<CPopup>, void*)> fn, void* data) {
|
||||
if (!m_self)
|
||||
return;
|
||||
|
||||
std::vector<WP<CPopup>> popups;
|
||||
popups.push_back(m_self);
|
||||
std::vector<SP<CPopup>> popups;
|
||||
popups.emplace_back(m_self.lock());
|
||||
bfHelper(popups, fn, data);
|
||||
}
|
||||
|
||||
WP<CPopup> CPopup::at(const Vector2D& globalCoords, bool allowsInput) {
|
||||
std::vector<WP<CPopup>> popups;
|
||||
breadthfirst([&popups](WP<CPopup> popup, void* data) { popups.push_back(popup); }, &popups);
|
||||
SP<CPopup> CPopup::at(const Vector2D& globalCoords, bool allowsInput) {
|
||||
std::vector<SP<CPopup>> popups;
|
||||
breadthfirst([&popups](SP<CPopup> popup, void* data) { popups.push_back(popup); }, &popups);
|
||||
|
||||
for (auto const& p : popups | std::views::reverse) {
|
||||
if (!p->m_resource || !p->m_mapped)
|
||||
|
|
@ -427,7 +463,7 @@ WP<CPopup> CPopup::at(const Vector2D& globalCoords, bool allowsInput) {
|
|||
if (BOX.containsPoint(globalCoords))
|
||||
return p;
|
||||
} else {
|
||||
const auto REGION = CRegion{p->m_wlSurface->resource()->m_current.input}.intersect(CBox{{}, p->m_wlSurface->resource()->m_current.size}).translate(p->coordsGlobal());
|
||||
const auto REGION = CRegion{p->wlSurface()->resource()->m_current.input}.intersect(CBox{{}, p->wlSurface()->resource()->m_current.size}).translate(p->coordsGlobal());
|
||||
if (REGION.containsPoint(globalCoords))
|
||||
return p;
|
||||
}
|
||||
106
src/desktop/view/Popup.hpp
Normal file
106
src/desktop/view/Popup.hpp
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "Subsurface.hpp"
|
||||
#include "View.hpp"
|
||||
#include "../../helpers/signal/Signal.hpp"
|
||||
#include "../../helpers/memory/Memory.hpp"
|
||||
#include "../../helpers/AnimatedVariable.hpp"
|
||||
|
||||
class CXDGPopupResource;
|
||||
|
||||
namespace Desktop::View {
|
||||
|
||||
class CPopup : public IView {
|
||||
public:
|
||||
// dummy head nodes
|
||||
static SP<CPopup> create(PHLWINDOW pOwner);
|
||||
static SP<CPopup> create(PHLLS pOwner);
|
||||
|
||||
// real nodes
|
||||
static SP<CPopup> create(SP<CXDGPopupResource> popup, WP<CPopup> pOwner);
|
||||
|
||||
static SP<CPopup> fromView(SP<IView>);
|
||||
|
||||
virtual ~CPopup();
|
||||
|
||||
virtual eViewType type() const;
|
||||
virtual bool visible() const;
|
||||
virtual std::optional<CBox> logicalBox() const;
|
||||
virtual bool desktopComponent() const;
|
||||
virtual std::optional<CBox> surfaceLogicalBox() const;
|
||||
|
||||
SP<Desktop::View::CWLSurface> getT1Owner();
|
||||
Vector2D coordsRelativeToParent();
|
||||
Vector2D coordsGlobal();
|
||||
PHLMONITOR getMonitor();
|
||||
|
||||
Vector2D size() const;
|
||||
|
||||
void onNewPopup(SP<CXDGPopupResource> popup);
|
||||
void onDestroy();
|
||||
void onMap();
|
||||
void onUnmap();
|
||||
void onCommit(bool ignoreSiblings = false);
|
||||
void onReposition();
|
||||
|
||||
void recheckTree();
|
||||
|
||||
bool inert() const;
|
||||
|
||||
// will also loop over this node
|
||||
void breadthfirst(std::function<void(SP<Desktop::View::CPopup>, void*)> fn, void* data);
|
||||
SP<Desktop::View::CPopup> at(const Vector2D& globalCoords, bool allowsInput = false);
|
||||
|
||||
//
|
||||
WP<Desktop::View::CPopup> m_self;
|
||||
bool m_mapped = false;
|
||||
|
||||
// fade in-out
|
||||
PHLANIMVAR<float> m_alpha;
|
||||
bool m_fadingOut = false;
|
||||
|
||||
private:
|
||||
CPopup();
|
||||
|
||||
// T1 owners, each popup has to have one of these
|
||||
PHLWINDOWREF m_windowOwner;
|
||||
PHLLSREF m_layerOwner;
|
||||
|
||||
// T2 owners
|
||||
WP<Desktop::View::CPopup> m_parent;
|
||||
|
||||
WP<CXDGPopupResource> m_resource;
|
||||
|
||||
Vector2D m_lastSize = {};
|
||||
Vector2D m_lastPos = {};
|
||||
|
||||
bool m_requestedReposition = false;
|
||||
|
||||
bool m_inert = false;
|
||||
|
||||
//
|
||||
std::vector<SP<Desktop::View::CPopup>> m_children;
|
||||
SP<Desktop::View::CSubsurface> m_subsurfaceHead;
|
||||
|
||||
struct {
|
||||
CHyprSignalListener newPopup;
|
||||
CHyprSignalListener destroy;
|
||||
CHyprSignalListener map;
|
||||
CHyprSignalListener unmap;
|
||||
CHyprSignalListener commit;
|
||||
CHyprSignalListener dismissed;
|
||||
CHyprSignalListener reposition;
|
||||
} m_listeners;
|
||||
|
||||
void initAllSignals();
|
||||
void reposition();
|
||||
void recheckChildrenRecursive();
|
||||
void sendScale();
|
||||
void fullyDestroy();
|
||||
|
||||
Vector2D localToGlobal(const Vector2D& rel);
|
||||
Vector2D t1ParentCoords() const;
|
||||
static void bfHelper(std::vector<SP<CPopup>> const& nodes, std::function<void(SP<CPopup>, void*)> fn, void* data);
|
||||
};
|
||||
}
|
||||
74
src/desktop/view/SessionLock.cpp
Normal file
74
src/desktop/view/SessionLock.cpp
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
#include "SessionLock.hpp"
|
||||
|
||||
#include "../../protocols/SessionLock.hpp"
|
||||
#include "../../protocols/core/Compositor.hpp"
|
||||
#include "../../helpers/Monitor.hpp"
|
||||
|
||||
#include "../../Compositor.hpp"
|
||||
|
||||
using namespace Desktop;
|
||||
using namespace Desktop::View;
|
||||
|
||||
SP<View::CSessionLock> View::CSessionLock::create(SP<CSessionLockSurface> resource) {
|
||||
auto lock = SP<CSessionLock>(new CSessionLock());
|
||||
lock->m_surface = resource;
|
||||
lock->m_self = lock;
|
||||
|
||||
lock->init();
|
||||
|
||||
return lock;
|
||||
}
|
||||
|
||||
View::CSessionLock::CSessionLock() : IView(CWLSurface::create()) {
|
||||
;
|
||||
}
|
||||
|
||||
View::CSessionLock::~CSessionLock() {
|
||||
m_wlSurface->unassign();
|
||||
}
|
||||
|
||||
void View::CSessionLock::init() {
|
||||
m_listeners.destroy = m_surface->m_events.destroy.listen([this] { std::erase_if(g_pCompositor->m_otherViews, [this](const auto& e) { return e == m_self; }); });
|
||||
|
||||
m_wlSurface->assign(m_surface->surface(), m_self.lock());
|
||||
}
|
||||
|
||||
SP<View::CSessionLock> View::CSessionLock::fromView(SP<IView> v) {
|
||||
if (!v || v->type() != VIEW_TYPE_LOCK_SCREEN)
|
||||
return nullptr;
|
||||
return dynamicPointerCast<View::CSessionLock>(v);
|
||||
}
|
||||
|
||||
eViewType View::CSessionLock::type() const {
|
||||
return VIEW_TYPE_LOCK_SCREEN;
|
||||
}
|
||||
|
||||
bool View::CSessionLock::visible() const {
|
||||
return m_wlSurface && m_wlSurface->resource() && m_wlSurface->resource()->m_mapped;
|
||||
}
|
||||
|
||||
std::optional<CBox> View::CSessionLock::logicalBox() const {
|
||||
return surfaceLogicalBox();
|
||||
}
|
||||
|
||||
std::optional<CBox> View::CSessionLock::surfaceLogicalBox() const {
|
||||
if (!visible())
|
||||
return std::nullopt;
|
||||
|
||||
const auto MON = m_surface->monitor();
|
||||
|
||||
if (!MON)
|
||||
return std::nullopt;
|
||||
|
||||
return MON->logicalBox();
|
||||
}
|
||||
|
||||
bool View::CSessionLock::desktopComponent() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
PHLMONITOR View::CSessionLock::monitor() const {
|
||||
if (m_surface)
|
||||
return m_surface->monitor();
|
||||
return nullptr;
|
||||
}
|
||||
40
src/desktop/view/SessionLock.hpp
Normal file
40
src/desktop/view/SessionLock.hpp
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../defines.hpp"
|
||||
#include <vector>
|
||||
#include "WLSurface.hpp"
|
||||
#include "View.hpp"
|
||||
|
||||
class CSessionLockSurface;
|
||||
|
||||
namespace Desktop::View {
|
||||
class CSessionLock : public IView {
|
||||
public:
|
||||
static SP<CSessionLock> create(SP<CSessionLockSurface> resource);
|
||||
|
||||
static SP<CSessionLock> fromView(SP<IView>);
|
||||
|
||||
virtual ~CSessionLock();
|
||||
|
||||
virtual eViewType type() const;
|
||||
virtual bool visible() const;
|
||||
virtual std::optional<CBox> logicalBox() const;
|
||||
virtual bool desktopComponent() const;
|
||||
virtual std::optional<CBox> surfaceLogicalBox() const;
|
||||
|
||||
PHLMONITOR monitor() const;
|
||||
|
||||
WP<CSessionLock> m_self;
|
||||
|
||||
private:
|
||||
CSessionLock();
|
||||
|
||||
void init();
|
||||
|
||||
struct {
|
||||
CHyprSignalListener destroy;
|
||||
} m_listeners;
|
||||
|
||||
WP<CSessionLockSurface> m_surface;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,56 +1,101 @@
|
|||
#include "Subsurface.hpp"
|
||||
#include "../events/Events.hpp"
|
||||
#include "../desktop/state/FocusState.hpp"
|
||||
#include "../desktop/Window.hpp"
|
||||
#include "../config/ConfigValue.hpp"
|
||||
#include "../protocols/core/Compositor.hpp"
|
||||
#include "../protocols/core/Subcompositor.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
#include "../managers/input/InputManager.hpp"
|
||||
#include "../state/FocusState.hpp"
|
||||
#include "Window.hpp"
|
||||
#include "../../config/ConfigValue.hpp"
|
||||
#include "../../protocols/core/Compositor.hpp"
|
||||
#include "../../protocols/core/Subcompositor.hpp"
|
||||
#include "../../render/Renderer.hpp"
|
||||
#include "../../managers/input/InputManager.hpp"
|
||||
|
||||
UP<CSubsurface> CSubsurface::create(PHLWINDOW pOwner) {
|
||||
auto subsurface = UP<CSubsurface>(new CSubsurface());
|
||||
using namespace Desktop;
|
||||
using namespace Desktop::View;
|
||||
|
||||
SP<CSubsurface> CSubsurface::create(PHLWINDOW pOwner) {
|
||||
auto subsurface = SP<CSubsurface>(new CSubsurface());
|
||||
subsurface->m_windowParent = pOwner;
|
||||
subsurface->m_self = subsurface;
|
||||
|
||||
subsurface->initSignals();
|
||||
subsurface->initExistingSubsurfaces(pOwner->m_wlSurface->resource());
|
||||
subsurface->initExistingSubsurfaces(pOwner->wlSurface()->resource());
|
||||
return subsurface;
|
||||
}
|
||||
|
||||
UP<CSubsurface> CSubsurface::create(WP<CPopup> pOwner) {
|
||||
auto subsurface = UP<CSubsurface>(new CSubsurface());
|
||||
SP<CSubsurface> CSubsurface::create(WP<Desktop::View::CPopup> pOwner) {
|
||||
auto subsurface = SP<CSubsurface>(new CSubsurface());
|
||||
subsurface->m_popupParent = pOwner;
|
||||
subsurface->m_self = subsurface;
|
||||
subsurface->initSignals();
|
||||
subsurface->initExistingSubsurfaces(pOwner->m_wlSurface->resource());
|
||||
subsurface->initExistingSubsurfaces(pOwner->wlSurface()->resource());
|
||||
return subsurface;
|
||||
}
|
||||
|
||||
UP<CSubsurface> CSubsurface::create(SP<CWLSubsurfaceResource> pSubsurface, PHLWINDOW pOwner) {
|
||||
auto subsurface = UP<CSubsurface>(new CSubsurface());
|
||||
SP<CSubsurface> CSubsurface::create(SP<CWLSubsurfaceResource> pSubsurface, PHLWINDOW pOwner) {
|
||||
auto subsurface = SP<CSubsurface>(new CSubsurface());
|
||||
subsurface->m_windowParent = pOwner;
|
||||
subsurface->m_subsurface = pSubsurface;
|
||||
subsurface->m_self = subsurface;
|
||||
subsurface->m_wlSurface = CWLSurface::create();
|
||||
subsurface->m_wlSurface->assign(pSubsurface->m_surface.lock(), subsurface.get());
|
||||
subsurface->wlSurface() = CWLSurface::create();
|
||||
subsurface->wlSurface()->assign(pSubsurface->m_surface.lock(), subsurface);
|
||||
subsurface->initSignals();
|
||||
subsurface->initExistingSubsurfaces(pSubsurface->m_surface.lock());
|
||||
return subsurface;
|
||||
}
|
||||
|
||||
UP<CSubsurface> CSubsurface::create(SP<CWLSubsurfaceResource> pSubsurface, WP<CPopup> pOwner) {
|
||||
auto subsurface = UP<CSubsurface>(new CSubsurface());
|
||||
SP<CSubsurface> CSubsurface::create(SP<CWLSubsurfaceResource> pSubsurface, WP<Desktop::View::CPopup> pOwner) {
|
||||
auto subsurface = SP<CSubsurface>(new CSubsurface());
|
||||
subsurface->m_popupParent = pOwner;
|
||||
subsurface->m_subsurface = pSubsurface;
|
||||
subsurface->m_self = subsurface;
|
||||
subsurface->m_wlSurface = CWLSurface::create();
|
||||
subsurface->m_wlSurface->assign(pSubsurface->m_surface.lock(), subsurface.get());
|
||||
subsurface->wlSurface() = CWLSurface::create();
|
||||
subsurface->wlSurface()->assign(pSubsurface->m_surface.lock(), subsurface);
|
||||
subsurface->initSignals();
|
||||
subsurface->initExistingSubsurfaces(pSubsurface->m_surface.lock());
|
||||
return subsurface;
|
||||
}
|
||||
|
||||
SP<CSubsurface> CSubsurface::fromView(SP<IView> v) {
|
||||
if (!v || v->type() != VIEW_TYPE_SUBSURFACE)
|
||||
return nullptr;
|
||||
return dynamicPointerCast<CSubsurface>(v);
|
||||
}
|
||||
|
||||
CSubsurface::CSubsurface() : IView(CWLSurface::create()) {
|
||||
;
|
||||
}
|
||||
|
||||
eViewType CSubsurface::type() const {
|
||||
return VIEW_TYPE_SUBSURFACE;
|
||||
}
|
||||
|
||||
bool CSubsurface::visible() const {
|
||||
if (!m_wlSurface || !m_wlSurface->resource() || !m_wlSurface->resource()->m_mapped)
|
||||
return false;
|
||||
|
||||
if (!m_windowParent.expired())
|
||||
return g_pHyprRenderer->shouldRenderWindow(m_windowParent.lock());
|
||||
if (m_popupParent)
|
||||
return m_popupParent->visible();
|
||||
if (m_parent)
|
||||
return m_parent->visible();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CSubsurface::desktopComponent() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<CBox> CSubsurface::logicalBox() const {
|
||||
return surfaceLogicalBox();
|
||||
}
|
||||
|
||||
std::optional<CBox> CSubsurface::surfaceLogicalBox() const {
|
||||
if (!visible())
|
||||
return std::nullopt;
|
||||
|
||||
return CBox{coordsGlobal(), m_lastSize};
|
||||
}
|
||||
|
||||
void CSubsurface::initSignals() {
|
||||
if (m_subsurface) {
|
||||
m_listeners.commitSubsurface = m_subsurface->m_surface->m_events.commit.listen([this] { onCommit(); });
|
||||
|
|
@ -60,9 +105,9 @@ void CSubsurface::initSignals() {
|
|||
m_listeners.newSubsurface = m_subsurface->m_surface->m_events.newSubsurface.listen([this](const auto& resource) { onNewSubsurface(resource); });
|
||||
} else {
|
||||
if (m_windowParent)
|
||||
m_listeners.newSubsurface = m_windowParent->m_wlSurface->resource()->m_events.newSubsurface.listen([this](const auto& resource) { onNewSubsurface(resource); });
|
||||
m_listeners.newSubsurface = m_windowParent->wlSurface()->resource()->m_events.newSubsurface.listen([this](const auto& resource) { onNewSubsurface(resource); });
|
||||
else if (m_popupParent)
|
||||
m_listeners.newSubsurface = m_popupParent->m_wlSurface->resource()->m_events.newSubsurface.listen([this](const auto& resource) { onNewSubsurface(resource); });
|
||||
m_listeners.newSubsurface = m_popupParent->wlSurface()->resource()->m_events.newSubsurface.listen([this](const auto& resource) { onNewSubsurface(resource); });
|
||||
else
|
||||
ASSERT(false);
|
||||
}
|
||||
|
|
@ -79,14 +124,14 @@ void CSubsurface::checkSiblingDamage() {
|
|||
continue;
|
||||
|
||||
const auto COORDS = n->coordsGlobal();
|
||||
g_pHyprRenderer->damageSurface(n->m_wlSurface->resource(), COORDS.x, COORDS.y, SCALE);
|
||||
g_pHyprRenderer->damageSurface(n->wlSurface()->resource(), COORDS.x, COORDS.y, SCALE);
|
||||
}
|
||||
}
|
||||
|
||||
void CSubsurface::recheckDamageForSubsurfaces() {
|
||||
for (auto const& n : m_children) {
|
||||
const auto COORDS = n->coordsGlobal();
|
||||
g_pHyprRenderer->damageSurface(n->m_wlSurface->resource(), COORDS.x, COORDS.y);
|
||||
g_pHyprRenderer->damageSurface(n->wlSurface()->resource(), COORDS.x, COORDS.y);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -105,7 +150,7 @@ void CSubsurface::onCommit() {
|
|||
|
||||
g_pHyprRenderer->damageSurface(m_wlSurface->resource(), COORDS.x, COORDS.y);
|
||||
|
||||
if (m_popupParent && !m_popupParent->inert() && m_popupParent->m_wlSurface)
|
||||
if (m_popupParent && !m_popupParent->inert() && m_popupParent->wlSurface())
|
||||
m_popupParent->recheckTree();
|
||||
if (!m_windowParent.expired()) // I hate you firefox why are you doing this
|
||||
m_windowParent->m_popupHead->recheckTree();
|
||||
|
|
@ -187,13 +232,13 @@ void CSubsurface::damageLastArea() {
|
|||
g_pHyprRenderer->damageBox(box);
|
||||
}
|
||||
|
||||
Vector2D CSubsurface::coordsRelativeToParent() {
|
||||
Vector2D CSubsurface::coordsRelativeToParent() const {
|
||||
if (!m_subsurface)
|
||||
return {};
|
||||
return m_subsurface->posRelativeToParent();
|
||||
}
|
||||
|
||||
Vector2D CSubsurface::coordsGlobal() {
|
||||
Vector2D CSubsurface::coordsGlobal() const {
|
||||
Vector2D coords = coordsRelativeToParent();
|
||||
|
||||
if (!m_windowParent.expired())
|
||||
|
|
@ -215,14 +260,3 @@ void CSubsurface::initExistingSubsurfaces(SP<CWLSurfaceResource> pSurface) {
|
|||
Vector2D CSubsurface::size() {
|
||||
return m_wlSurface->resource()->m_current.size;
|
||||
}
|
||||
|
||||
bool CSubsurface::visible() {
|
||||
if (!m_windowParent.expired())
|
||||
return g_pHyprRenderer->shouldRenderWindow(m_windowParent.lock());
|
||||
if (m_popupParent)
|
||||
return m_popupParent->visible();
|
||||
if (m_parent)
|
||||
return m_parent->visible();
|
||||
|
||||
return false;
|
||||
}
|
||||
77
src/desktop/view/Subsurface.hpp
Normal file
77
src/desktop/view/Subsurface.hpp
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../defines.hpp"
|
||||
#include <vector>
|
||||
#include "WLSurface.hpp"
|
||||
#include "View.hpp"
|
||||
|
||||
class CWLSubsurfaceResource;
|
||||
|
||||
namespace Desktop::View {
|
||||
class CPopup;
|
||||
class CSubsurface : public IView {
|
||||
public:
|
||||
// root dummy nodes
|
||||
static SP<CSubsurface> create(PHLWINDOW pOwner);
|
||||
static SP<CSubsurface> create(WP<Desktop::View::CPopup> pOwner);
|
||||
|
||||
// real nodes
|
||||
static SP<CSubsurface> create(SP<CWLSubsurfaceResource> pSubsurface, PHLWINDOW pOwner);
|
||||
static SP<CSubsurface> create(SP<CWLSubsurfaceResource> pSubsurface, WP<Desktop::View::CPopup> pOwner);
|
||||
|
||||
static SP<CSubsurface> fromView(SP<IView>);
|
||||
|
||||
virtual ~CSubsurface() = default;
|
||||
|
||||
virtual eViewType type() const;
|
||||
virtual bool visible() const;
|
||||
virtual std::optional<CBox> logicalBox() const;
|
||||
virtual bool desktopComponent() const;
|
||||
virtual std::optional<CBox> surfaceLogicalBox() const;
|
||||
|
||||
Vector2D coordsRelativeToParent() const;
|
||||
Vector2D coordsGlobal() const;
|
||||
|
||||
Vector2D size();
|
||||
|
||||
void onCommit();
|
||||
void onDestroy();
|
||||
void onNewSubsurface(SP<CWLSubsurfaceResource> pSubsurface);
|
||||
void onMap();
|
||||
void onUnmap();
|
||||
|
||||
void recheckDamageForSubsurfaces();
|
||||
|
||||
WP<Desktop::View::CSubsurface> m_self;
|
||||
|
||||
private:
|
||||
CSubsurface();
|
||||
|
||||
struct {
|
||||
CHyprSignalListener destroySubsurface;
|
||||
CHyprSignalListener commitSubsurface;
|
||||
CHyprSignalListener mapSubsurface;
|
||||
CHyprSignalListener unmapSubsurface;
|
||||
CHyprSignalListener newSubsurface;
|
||||
} m_listeners;
|
||||
|
||||
WP<CWLSubsurfaceResource> m_subsurface;
|
||||
Vector2D m_lastSize = {};
|
||||
Vector2D m_lastPosition = {};
|
||||
|
||||
// if nullptr, means it's a dummy node
|
||||
WP<Desktop::View::CSubsurface> m_parent;
|
||||
|
||||
PHLWINDOWREF m_windowParent;
|
||||
WP<Desktop::View::CPopup> m_popupParent;
|
||||
|
||||
std::vector<SP<Desktop::View::CSubsurface>> m_children;
|
||||
|
||||
bool m_inert = false;
|
||||
|
||||
void initSignals();
|
||||
void initExistingSubsurfaces(SP<CWLSurfaceResource> pSurface);
|
||||
void checkSiblingDamage();
|
||||
void damageLastArea();
|
||||
};
|
||||
}
|
||||
16
src/desktop/view/View.cpp
Normal file
16
src/desktop/view/View.cpp
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#include "View.hpp"
|
||||
|
||||
using namespace Desktop;
|
||||
using namespace Desktop::View;
|
||||
|
||||
SP<Desktop::View::CWLSurface> IView::wlSurface() const {
|
||||
return m_wlSurface;
|
||||
}
|
||||
|
||||
IView::IView(SP<Desktop::View::CWLSurface> pWlSurface) : m_wlSurface(pWlSurface) {
|
||||
;
|
||||
}
|
||||
|
||||
SP<CWLSurfaceResource> IView::resource() const {
|
||||
return m_wlSurface ? m_wlSurface->resource() : nullptr;
|
||||
}
|
||||
32
src/desktop/view/View.hpp
Normal file
32
src/desktop/view/View.hpp
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#pragma once
|
||||
|
||||
#include "WLSurface.hpp"
|
||||
#include "../../helpers/math/Math.hpp"
|
||||
|
||||
namespace Desktop::View {
|
||||
enum eViewType : uint8_t {
|
||||
VIEW_TYPE_WINDOW = 0,
|
||||
VIEW_TYPE_SUBSURFACE,
|
||||
VIEW_TYPE_POPUP,
|
||||
VIEW_TYPE_LAYER_SURFACE,
|
||||
VIEW_TYPE_LOCK_SCREEN,
|
||||
};
|
||||
|
||||
class IView {
|
||||
public:
|
||||
virtual ~IView() = default;
|
||||
|
||||
virtual SP<Desktop::View::CWLSurface> wlSurface() const;
|
||||
virtual SP<CWLSurfaceResource> resource() const;
|
||||
virtual eViewType type() const = 0;
|
||||
virtual bool visible() const = 0;
|
||||
virtual bool desktopComponent() const = 0;
|
||||
virtual std::optional<CBox> logicalBox() const = 0;
|
||||
virtual std::optional<CBox> surfaceLogicalBox() const = 0;
|
||||
|
||||
protected:
|
||||
IView(SP<Desktop::View::CWLSurface> pWlSurface);
|
||||
|
||||
SP<Desktop::View::CWLSurface> m_wlSurface;
|
||||
};
|
||||
};
|
||||
|
|
@ -1,9 +1,12 @@
|
|||
#include "WLSurface.hpp"
|
||||
#include "LayerSurface.hpp"
|
||||
#include "../desktop/Window.hpp"
|
||||
#include "../protocols/core/Compositor.hpp"
|
||||
#include "../protocols/LayerShell.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
#include "Window.hpp"
|
||||
#include "../../protocols/core/Compositor.hpp"
|
||||
#include "../../protocols/LayerShell.hpp"
|
||||
#include "../../render/Renderer.hpp"
|
||||
|
||||
using namespace Desktop;
|
||||
using namespace Desktop::View;
|
||||
|
||||
void CWLSurface::assign(SP<CWLSurfaceResource> pSurface) {
|
||||
m_resource = pSurface;
|
||||
|
|
@ -11,30 +14,9 @@ void CWLSurface::assign(SP<CWLSurfaceResource> pSurface) {
|
|||
m_inert = false;
|
||||
}
|
||||
|
||||
void CWLSurface::assign(SP<CWLSurfaceResource> pSurface, PHLWINDOW pOwner) {
|
||||
m_windowOwner = pOwner;
|
||||
m_resource = pSurface;
|
||||
init();
|
||||
m_inert = false;
|
||||
}
|
||||
|
||||
void CWLSurface::assign(SP<CWLSurfaceResource> pSurface, PHLLS pOwner) {
|
||||
m_layerOwner = pOwner;
|
||||
m_resource = pSurface;
|
||||
init();
|
||||
m_inert = false;
|
||||
}
|
||||
|
||||
void CWLSurface::assign(SP<CWLSurfaceResource> pSurface, CSubsurface* pOwner) {
|
||||
m_subsurfaceOwner = pOwner;
|
||||
m_resource = pSurface;
|
||||
init();
|
||||
m_inert = false;
|
||||
}
|
||||
|
||||
void CWLSurface::assign(SP<CWLSurfaceResource> pSurface, CPopup* pOwner) {
|
||||
m_popupOwner = pOwner;
|
||||
m_resource = pSurface;
|
||||
void CWLSurface::assign(SP<CWLSurfaceResource> pSurface, SP<IView> pOwner) {
|
||||
m_view = pOwner;
|
||||
m_resource = pSurface;
|
||||
init();
|
||||
m_inert = false;
|
||||
}
|
||||
|
|
@ -56,24 +38,24 @@ SP<CWLSurfaceResource> CWLSurface::resource() const {
|
|||
}
|
||||
|
||||
bool CWLSurface::small() const {
|
||||
if (!validMapped(m_windowOwner) || !exists())
|
||||
if (!m_view || !m_view->visible() || m_view->type() != VIEW_TYPE_WINDOW || !exists())
|
||||
return false;
|
||||
|
||||
if (!m_resource->m_current.texture)
|
||||
return false;
|
||||
|
||||
const auto O = m_windowOwner.lock();
|
||||
const auto O = dynamicPointerCast<CWindow>(m_view.lock());
|
||||
const auto REPORTED_SIZE = O->getReportedSize();
|
||||
|
||||
return REPORTED_SIZE.x > m_resource->m_current.size.x + 1 || REPORTED_SIZE.y > m_resource->m_current.size.y + 1;
|
||||
}
|
||||
|
||||
Vector2D CWLSurface::correctSmallVec() const {
|
||||
if (!validMapped(m_windowOwner) || !exists() || !small() || m_fillIgnoreSmall)
|
||||
if (!m_view || !m_view->visible() || m_view->type() != VIEW_TYPE_WINDOW || !exists() || !small() || !m_fillIgnoreSmall)
|
||||
return {};
|
||||
|
||||
const auto SIZE = getViewporterCorrectedSize();
|
||||
const auto O = m_windowOwner.lock();
|
||||
const auto O = dynamicPointerCast<CWindow>(m_view.lock());
|
||||
const auto REP = O->getReportedSize();
|
||||
|
||||
return Vector2D{(REP.x - SIZE.x) / 2, (REP.y - SIZE.y) / 2}.clamp({}, {INFINITY, INFINITY}) * (O->m_realSize->value() / REP);
|
||||
|
|
@ -123,8 +105,8 @@ CRegion CWLSurface::computeDamage() const {
|
|||
|
||||
damage.scale(SCALE);
|
||||
if (BOX.has_value()) {
|
||||
if (m_windowOwner)
|
||||
damage.intersect(CBox{{}, BOX->size() * m_windowOwner->m_X11SurfaceScaledBy});
|
||||
if (m_view->type() == VIEW_TYPE_WINDOW)
|
||||
damage.intersect(CBox{{}, BOX->size() * dynamicPointerCast<CWindow>(m_view.lock())->m_X11SurfaceScaledBy});
|
||||
else
|
||||
damage.intersect(CBox{{}, BOX->size()});
|
||||
}
|
||||
|
|
@ -142,11 +124,8 @@ void CWLSurface::destroy() {
|
|||
|
||||
m_listeners.destroy.reset();
|
||||
m_resource->m_hlSurface.reset();
|
||||
m_windowOwner.reset();
|
||||
m_layerOwner.reset();
|
||||
m_popupOwner = nullptr;
|
||||
m_subsurfaceOwner = nullptr;
|
||||
m_inert = true;
|
||||
m_view.reset();
|
||||
m_inert = true;
|
||||
|
||||
if (g_pHyprRenderer && g_pHyprRenderer->m_lastCursorData.surf && g_pHyprRenderer->m_lastCursorData.surf->get() == this)
|
||||
g_pHyprRenderer->m_lastCursorData.surf.reset();
|
||||
|
|
@ -169,40 +148,19 @@ void CWLSurface::init() {
|
|||
Debug::log(LOG, "CWLSurface {:x} called init()", rc<uintptr_t>(this));
|
||||
}
|
||||
|
||||
PHLWINDOW CWLSurface::getWindow() const {
|
||||
return m_windowOwner.lock();
|
||||
}
|
||||
|
||||
PHLLS CWLSurface::getLayer() const {
|
||||
return m_layerOwner.lock();
|
||||
}
|
||||
|
||||
CPopup* CWLSurface::getPopup() const {
|
||||
return m_popupOwner;
|
||||
}
|
||||
|
||||
CSubsurface* CWLSurface::getSubsurface() const {
|
||||
return m_subsurfaceOwner;
|
||||
SP<IView> CWLSurface::view() const {
|
||||
return m_view.lock();
|
||||
}
|
||||
|
||||
bool CWLSurface::desktopComponent() const {
|
||||
return !m_layerOwner.expired() || !m_windowOwner.expired() || m_subsurfaceOwner || m_popupOwner;
|
||||
return m_view && m_view->visible();
|
||||
}
|
||||
|
||||
std::optional<CBox> CWLSurface::getSurfaceBoxGlobal() const {
|
||||
if (!desktopComponent())
|
||||
return {};
|
||||
|
||||
if (!m_windowOwner.expired())
|
||||
return m_windowOwner->getWindowMainSurfaceBox();
|
||||
if (!m_layerOwner.expired())
|
||||
return m_layerOwner->m_geometry;
|
||||
if (m_popupOwner)
|
||||
return CBox{m_popupOwner->coordsGlobal(), m_popupOwner->size()};
|
||||
if (m_subsurfaceOwner)
|
||||
return CBox{m_subsurfaceOwner->coordsGlobal(), m_subsurfaceOwner->size()};
|
||||
|
||||
return {};
|
||||
return m_view->surfaceLogicalBox();
|
||||
}
|
||||
|
||||
void CWLSurface::appendConstraint(WP<CPointerConstraint> constraint) {
|
||||
|
|
@ -214,27 +172,23 @@ SP<CPointerConstraint> CWLSurface::constraint() const {
|
|||
}
|
||||
|
||||
bool CWLSurface::visible() {
|
||||
if (!m_windowOwner.expired())
|
||||
return g_pHyprRenderer->shouldRenderWindow(m_windowOwner.lock());
|
||||
if (!m_layerOwner.expired())
|
||||
return true;
|
||||
if (m_popupOwner)
|
||||
return m_popupOwner->visible();
|
||||
if (m_subsurfaceOwner)
|
||||
return m_subsurfaceOwner->visible();
|
||||
if (m_view)
|
||||
return m_view->visible();
|
||||
return true; // non-desktop, we don't know much.
|
||||
}
|
||||
|
||||
SP<CWLSurface> CWLSurface::fromResource(SP<CWLSurfaceResource> pSurface) {
|
||||
SP<Desktop::View::CWLSurface> CWLSurface::fromResource(SP<CWLSurfaceResource> pSurface) {
|
||||
if (!pSurface)
|
||||
return nullptr;
|
||||
return pSurface->m_hlSurface.lock();
|
||||
}
|
||||
|
||||
bool CWLSurface::keyboardFocusable() const {
|
||||
if (m_windowOwner || m_popupOwner || m_subsurfaceOwner)
|
||||
if (!m_view)
|
||||
return false;
|
||||
if (m_view->type() == VIEW_TYPE_WINDOW || m_view->type() == VIEW_TYPE_SUBSURFACE || m_view->type() == VIEW_TYPE_POPUP)
|
||||
return true;
|
||||
if (m_layerOwner && m_layerOwner->m_layerSurface)
|
||||
return m_layerOwner->m_layerSurface->m_current.interactivity != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE;
|
||||
if (const auto LS = CLayerSurface::fromView(m_view.lock()); LS && LS->m_layerSurface)
|
||||
return LS->m_layerSurface->m_current.interactivity != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE;
|
||||
return false;
|
||||
}
|
||||
118
src/desktop/view/WLSurface.hpp
Normal file
118
src/desktop/view/WLSurface.hpp
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../defines.hpp"
|
||||
#include "../../helpers/math/Math.hpp"
|
||||
#include "../../helpers/signal/Signal.hpp"
|
||||
|
||||
class CPointerConstraint;
|
||||
class CWLSurfaceResource;
|
||||
|
||||
namespace Desktop::View {
|
||||
class CSubsurface;
|
||||
class CPopup;
|
||||
class IView;
|
||||
|
||||
class CWLSurface {
|
||||
public:
|
||||
static SP<Desktop::View::CWLSurface> create() {
|
||||
auto p = SP<Desktop::View::CWLSurface>(new CWLSurface);
|
||||
p->m_self = p;
|
||||
return p;
|
||||
}
|
||||
~CWLSurface();
|
||||
|
||||
// anonymous surfaces are non-desktop components, e.g. a cursor surface or a DnD
|
||||
void assign(SP<CWLSurfaceResource> pSurface);
|
||||
void assign(SP<CWLSurfaceResource> pSurface, SP<IView> pOwner);
|
||||
void unassign();
|
||||
|
||||
CWLSurface(const CWLSurface&) = delete;
|
||||
CWLSurface(CWLSurface&&) = delete;
|
||||
CWLSurface& operator=(const CWLSurface&) = delete;
|
||||
CWLSurface& operator=(CWLSurface&&) = delete;
|
||||
|
||||
SP<CWLSurfaceResource> resource() const;
|
||||
bool exists() const;
|
||||
bool small() const; // means surface is smaller than the requested size
|
||||
Vector2D correctSmallVec() const; // returns a corrective vector for small() surfaces
|
||||
Vector2D correctSmallVecBuf() const; // returns a corrective vector for small() surfaces, in BL coords
|
||||
Vector2D getViewporterCorrectedSize() const;
|
||||
CRegion computeDamage() const; // logical coordinates. May be wrong if the surface is unassigned
|
||||
bool visible();
|
||||
bool keyboardFocusable() const;
|
||||
|
||||
SP<IView> view() const;
|
||||
|
||||
// desktop components misc utils
|
||||
std::optional<CBox> getSurfaceBoxGlobal() const;
|
||||
void appendConstraint(WP<CPointerConstraint> constraint);
|
||||
SP<CPointerConstraint> constraint() const;
|
||||
|
||||
// allow stretching. Useful for plugins.
|
||||
bool m_fillIgnoreSmall = false;
|
||||
|
||||
// track surface data and avoid dupes
|
||||
float m_lastScaleFloat = 0;
|
||||
int m_lastScaleInt = 0;
|
||||
wl_output_transform m_lastTransform = sc<wl_output_transform>(-1);
|
||||
|
||||
//
|
||||
CWLSurface& operator=(SP<CWLSurfaceResource> pSurface) {
|
||||
destroy();
|
||||
m_resource = pSurface;
|
||||
init();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const CWLSurface& other) const {
|
||||
return other.resource() == resource();
|
||||
}
|
||||
|
||||
bool operator==(const SP<CWLSurfaceResource> other) const {
|
||||
return other == resource();
|
||||
}
|
||||
|
||||
explicit operator bool() const {
|
||||
return exists();
|
||||
}
|
||||
|
||||
static SP<Desktop::View::CWLSurface> fromResource(SP<CWLSurfaceResource> pSurface);
|
||||
|
||||
// used by the alpha-modifier protocol
|
||||
float m_alphaModifier = 1.F;
|
||||
|
||||
// used by the hyprland-surface protocol
|
||||
float m_overallOpacity = 1.F;
|
||||
CRegion m_visibleRegion;
|
||||
|
||||
struct {
|
||||
CSignalT<> destroy;
|
||||
} m_events;
|
||||
|
||||
WP<Desktop::View::CWLSurface> m_self;
|
||||
|
||||
private:
|
||||
CWLSurface() = default;
|
||||
|
||||
bool m_inert = true;
|
||||
|
||||
WP<CWLSurfaceResource> m_resource;
|
||||
|
||||
WP<IView> m_view;
|
||||
|
||||
//
|
||||
WP<CPointerConstraint> m_constraint;
|
||||
|
||||
void destroy();
|
||||
void init();
|
||||
bool desktopComponent() const;
|
||||
|
||||
struct {
|
||||
CHyprSignalListener destroy;
|
||||
} m_listeners;
|
||||
|
||||
friend class ::CPointerConstraint;
|
||||
friend class CXxColorManagerV4;
|
||||
};
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
454
src/desktop/view/Window.hpp
Normal file
454
src/desktop/view/Window.hpp
Normal file
|
|
@ -0,0 +1,454 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <optional>
|
||||
|
||||
#include "View.hpp"
|
||||
#include "../../config/ConfigDataValues.hpp"
|
||||
#include "../../helpers/AnimatedVariable.hpp"
|
||||
#include "../../helpers/TagKeeper.hpp"
|
||||
#include "../../macros.hpp"
|
||||
#include "../../managers/XWaylandManager.hpp"
|
||||
#include "../../render/decorations/IHyprWindowDecoration.hpp"
|
||||
#include "../../render/Transformer.hpp"
|
||||
#include "../DesktopTypes.hpp"
|
||||
#include "Popup.hpp"
|
||||
#include "Subsurface.hpp"
|
||||
#include "WLSurface.hpp"
|
||||
#include "../Workspace.hpp"
|
||||
#include "../rule/windowRule/WindowRuleApplicator.hpp"
|
||||
#include "../../protocols/types/ContentType.hpp"
|
||||
|
||||
class CXDGSurfaceResource;
|
||||
class CXWaylandSurface;
|
||||
struct SWorkspaceRule;
|
||||
|
||||
class IWindowTransformer;
|
||||
|
||||
namespace Desktop::View {
|
||||
|
||||
enum eGroupRules : uint8_t {
|
||||
// effective only during first map, except for _ALWAYS variant
|
||||
GROUP_NONE = 0,
|
||||
GROUP_SET = 1 << 0, // Open as new group or add to focused group
|
||||
GROUP_SET_ALWAYS = 1 << 1,
|
||||
GROUP_BARRED = 1 << 2, // Don't insert to focused group.
|
||||
GROUP_LOCK = 1 << 3, // Lock m_sGroupData.lock
|
||||
GROUP_LOCK_ALWAYS = 1 << 4,
|
||||
GROUP_INVADE = 1 << 5, // Force enter a group, event if lock is engaged
|
||||
GROUP_OVERRIDE = 1 << 6, // Override other rules
|
||||
};
|
||||
|
||||
enum eGetWindowProperties : uint8_t {
|
||||
WINDOW_ONLY = 0,
|
||||
RESERVED_EXTENTS = 1 << 0,
|
||||
INPUT_EXTENTS = 1 << 1,
|
||||
FULL_EXTENTS = 1 << 2,
|
||||
FLOATING_ONLY = 1 << 3,
|
||||
ALLOW_FLOATING = 1 << 4,
|
||||
USE_PROP_TILED = 1 << 5,
|
||||
SKIP_FULLSCREEN_PRIORITY = 1 << 6,
|
||||
FOCUS_PRIORITY = 1 << 7,
|
||||
};
|
||||
|
||||
enum eSuppressEvents : uint8_t {
|
||||
SUPPRESS_NONE = 0,
|
||||
SUPPRESS_FULLSCREEN = 1 << 0,
|
||||
SUPPRESS_MAXIMIZE = 1 << 1,
|
||||
SUPPRESS_ACTIVATE = 1 << 2,
|
||||
SUPPRESS_ACTIVATE_FOCUSONLY = 1 << 3,
|
||||
SUPPRESS_FULLSCREEN_OUTPUT = 1 << 4,
|
||||
};
|
||||
|
||||
struct SInitialWorkspaceToken {
|
||||
PHLWINDOWREF primaryOwner;
|
||||
std::string workspace;
|
||||
};
|
||||
|
||||
struct SFullscreenState {
|
||||
eFullscreenMode internal = FSMODE_NONE;
|
||||
eFullscreenMode client = FSMODE_NONE;
|
||||
};
|
||||
|
||||
class CWindow : public IView {
|
||||
public:
|
||||
static PHLWINDOW create(SP<CXDGSurfaceResource>);
|
||||
static PHLWINDOW create(SP<CXWaylandSurface>);
|
||||
static PHLWINDOW fromView(SP<IView>);
|
||||
|
||||
private:
|
||||
CWindow(SP<CXDGSurfaceResource> resource);
|
||||
CWindow(SP<CXWaylandSurface> surface);
|
||||
|
||||
public:
|
||||
virtual ~CWindow();
|
||||
|
||||
virtual eViewType type() const;
|
||||
virtual bool visible() const;
|
||||
virtual std::optional<CBox> logicalBox() const;
|
||||
virtual bool desktopComponent() const;
|
||||
virtual std::optional<CBox> surfaceLogicalBox() const;
|
||||
|
||||
struct {
|
||||
CSignalT<> destroy;
|
||||
} m_events;
|
||||
|
||||
WP<CXDGSurfaceResource> m_xdgSurface;
|
||||
WP<CXWaylandSurface> m_xwaylandSurface;
|
||||
|
||||
// this is the position and size of the "bounding box"
|
||||
Vector2D m_position = Vector2D(0, 0);
|
||||
Vector2D m_size = Vector2D(0, 0);
|
||||
|
||||
// this is the real position and size used to draw the thing
|
||||
PHLANIMVAR<Vector2D> m_realPosition;
|
||||
PHLANIMVAR<Vector2D> m_realSize;
|
||||
|
||||
// for not spamming the protocols
|
||||
Vector2D m_reportedPosition;
|
||||
Vector2D m_reportedSize;
|
||||
Vector2D m_pendingReportedSize;
|
||||
std::optional<std::pair<uint32_t, Vector2D>> m_pendingSizeAck;
|
||||
std::vector<std::pair<uint32_t, Vector2D>> m_pendingSizeAcks;
|
||||
|
||||
// for restoring floating statuses
|
||||
Vector2D m_lastFloatingSize;
|
||||
Vector2D m_lastFloatingPosition;
|
||||
|
||||
// for floating window offset in workspace animations
|
||||
Vector2D m_floatingOffset = Vector2D(0, 0);
|
||||
|
||||
// this is used for pseudotiling
|
||||
bool m_isPseudotiled = false;
|
||||
Vector2D m_pseudoSize = Vector2D(1280, 720);
|
||||
|
||||
// for recovering relative cursor position
|
||||
Vector2D m_relativeCursorCoordsOnLastWarp = Vector2D(-1, -1);
|
||||
|
||||
bool m_firstMap = false; // for layouts
|
||||
bool m_isFloating = false;
|
||||
bool m_draggingTiled = false; // for dragging around tiled windows
|
||||
SFullscreenState m_fullscreenState = {.internal = FSMODE_NONE, .client = FSMODE_NONE};
|
||||
std::string m_title = "";
|
||||
std::string m_class = "";
|
||||
std::string m_initialTitle = "";
|
||||
std::string m_initialClass = "";
|
||||
PHLWORKSPACE m_workspace;
|
||||
PHLMONITORREF m_monitor;
|
||||
|
||||
bool m_isMapped = false;
|
||||
|
||||
bool m_requestsFloat = false;
|
||||
|
||||
// This is for fullscreen apps
|
||||
bool m_createdOverFullscreen = false;
|
||||
|
||||
// XWayland stuff
|
||||
bool m_isX11 = false;
|
||||
bool m_X11DoesntWantBorders = false;
|
||||
bool m_X11ShouldntFocus = false;
|
||||
float m_X11SurfaceScaledBy = 1.f;
|
||||
//
|
||||
|
||||
// For nofocus
|
||||
bool m_noInitialFocus = false;
|
||||
|
||||
// Fullscreen and Maximize
|
||||
bool m_wantsInitialFullscreen = false;
|
||||
MONITORID m_wantsInitialFullscreenMonitor = MONITOR_INVALID;
|
||||
|
||||
// bitfield suppressEvents
|
||||
uint64_t m_suppressedEvents = SUPPRESS_NONE;
|
||||
|
||||
// desktop components
|
||||
SP<Desktop::View::CSubsurface> m_subsurfaceHead;
|
||||
SP<Desktop::View::CPopup> m_popupHead;
|
||||
|
||||
// Animated border
|
||||
CGradientValueData m_realBorderColor = {0};
|
||||
CGradientValueData m_realBorderColorPrevious = {0};
|
||||
PHLANIMVAR<float> m_borderFadeAnimationProgress;
|
||||
PHLANIMVAR<float> m_borderAngleAnimationProgress;
|
||||
|
||||
// Fade in-out
|
||||
PHLANIMVAR<float> m_alpha;
|
||||
bool m_fadingOut = false;
|
||||
bool m_readyToDelete = false;
|
||||
Vector2D m_originalClosedPos; // these will be used for calculations later on in
|
||||
Vector2D m_originalClosedSize; // drawing the closing animations
|
||||
SBoxExtents m_originalClosedExtents;
|
||||
bool m_animatingIn = false;
|
||||
|
||||
// For pinned (sticky) windows
|
||||
bool m_pinned = false;
|
||||
|
||||
// For preserving pinned state when fullscreening a pinned window
|
||||
bool m_pinFullscreened = false;
|
||||
|
||||
// urgency hint
|
||||
bool m_isUrgent = false;
|
||||
|
||||
// for proper cycling. While cycling we can't just move the pointers, so we need to keep track of the last cycled window.
|
||||
PHLWINDOWREF m_lastCycledWindow;
|
||||
|
||||
// Window decorations
|
||||
// TODO: make this a SP.
|
||||
std::vector<UP<IHyprWindowDecoration>> m_windowDecorations;
|
||||
std::vector<IHyprWindowDecoration*> m_decosToRemove;
|
||||
|
||||
// Special render data, rules, etc
|
||||
UP<Desktop::Rule::CWindowRuleApplicator> m_ruleApplicator;
|
||||
|
||||
// Transformers
|
||||
std::vector<UP<IWindowTransformer>> m_transformers;
|
||||
|
||||
// for alpha
|
||||
PHLANIMVAR<float> m_activeInactiveAlpha;
|
||||
PHLANIMVAR<float> m_movingFromWorkspaceAlpha;
|
||||
|
||||
// animated shadow color
|
||||
PHLANIMVAR<CHyprColor> m_realShadowColor;
|
||||
|
||||
// animated tint
|
||||
PHLANIMVAR<float> m_dimPercent;
|
||||
|
||||
// animate moving to an invisible workspace
|
||||
int m_monitorMovedFrom = -1; // -1 means not moving
|
||||
PHLANIMVAR<float> m_movingToWorkspaceAlpha;
|
||||
|
||||
// swallowing
|
||||
PHLWINDOWREF m_swallowed;
|
||||
bool m_currentlySwallowed = false;
|
||||
bool m_groupSwallowed = false;
|
||||
|
||||
// for toplevel monitor events
|
||||
MONITORID m_lastSurfaceMonitorID = -1;
|
||||
|
||||
// initial token. Will be unregistered on workspace change or timeout of 2 minutes
|
||||
std::string m_initialWorkspaceToken = "";
|
||||
|
||||
// for groups
|
||||
struct SGroupData {
|
||||
PHLWINDOWREF pNextWindow; // nullptr means no grouping. Self means single group.
|
||||
bool head = false;
|
||||
bool locked = false; // per group lock
|
||||
bool deny = false; // deny window from enter a group or made a group
|
||||
} m_groupData;
|
||||
uint16_t m_groupRules = Desktop::View::GROUP_NONE;
|
||||
|
||||
bool m_tearingHint = false;
|
||||
|
||||
// ANR
|
||||
PHLANIMVAR<float> m_notRespondingTint;
|
||||
|
||||
// For the noclosefor windowrule
|
||||
Time::steady_tp m_closeableSince = Time::steadyNow();
|
||||
|
||||
// For the list lookup
|
||||
bool operator==(const CWindow& rhs) const {
|
||||
return m_xdgSurface == rhs.m_xdgSurface && m_xwaylandSurface == rhs.m_xwaylandSurface && m_position == rhs.m_position && m_size == rhs.m_size &&
|
||||
m_fadingOut == rhs.m_fadingOut;
|
||||
}
|
||||
|
||||
// methods
|
||||
CBox getFullWindowBoundingBox() const;
|
||||
SBoxExtents getFullWindowExtents() const;
|
||||
CBox getWindowBoxUnified(uint64_t props);
|
||||
SBoxExtents getWindowExtentsUnified(uint64_t props);
|
||||
CBox getWindowIdealBoundingBoxIgnoreReserved();
|
||||
void addWindowDeco(UP<IHyprWindowDecoration> deco);
|
||||
void updateWindowDecos();
|
||||
void removeWindowDeco(IHyprWindowDecoration* deco);
|
||||
void uncacheWindowDecos();
|
||||
bool checkInputOnDecos(const eInputType, const Vector2D&, std::any = {});
|
||||
pid_t getPID();
|
||||
IHyprWindowDecoration* getDecorationByType(eDecorationType);
|
||||
void updateToplevel();
|
||||
void updateSurfaceScaleTransformDetails(bool force = false);
|
||||
void moveToWorkspace(PHLWORKSPACE);
|
||||
PHLWINDOW x11TransientFor();
|
||||
void onUnmap();
|
||||
void onMap();
|
||||
void setHidden(bool hidden);
|
||||
bool isHidden();
|
||||
void updateDecorationValues();
|
||||
SBoxExtents getFullWindowReservedArea();
|
||||
Vector2D middle();
|
||||
bool opaque();
|
||||
float rounding();
|
||||
float roundingPower();
|
||||
bool canBeTorn();
|
||||
void setSuspended(bool suspend);
|
||||
bool visibleOnMonitor(PHLMONITOR pMonitor);
|
||||
WORKSPACEID workspaceID();
|
||||
MONITORID monitorID();
|
||||
bool onSpecialWorkspace();
|
||||
void activate(bool force = false);
|
||||
int surfacesCount();
|
||||
void clampWindowSize(const std::optional<Vector2D> minSize, const std::optional<Vector2D> maxSize);
|
||||
bool isFullscreen();
|
||||
bool isEffectiveInternalFSMode(const eFullscreenMode) const;
|
||||
int getRealBorderSize() const;
|
||||
float getScrollMouse();
|
||||
float getScrollTouchpad();
|
||||
bool isScrollMouseOverridden();
|
||||
bool isScrollTouchpadOverridden();
|
||||
void updateWindowData();
|
||||
void updateWindowData(const SWorkspaceRule&);
|
||||
void onBorderAngleAnimEnd(WP<Hyprutils::Animation::CBaseAnimatedVariable> pav);
|
||||
bool isInCurvedCorner(double x, double y);
|
||||
bool hasPopupAt(const Vector2D& pos);
|
||||
int popupsCount();
|
||||
void applyGroupRules();
|
||||
void createGroup();
|
||||
void destroyGroup();
|
||||
PHLWINDOW getGroupHead();
|
||||
PHLWINDOW getGroupTail();
|
||||
PHLWINDOW getGroupCurrent();
|
||||
PHLWINDOW getGroupPrevious();
|
||||
PHLWINDOW getGroupWindowByIndex(int);
|
||||
bool hasInGroup(PHLWINDOW);
|
||||
int getGroupSize();
|
||||
bool canBeGroupedInto(PHLWINDOW pWindow);
|
||||
void setGroupCurrent(PHLWINDOW pWindow);
|
||||
void insertWindowToGroup(PHLWINDOW pWindow);
|
||||
void updateGroupOutputs();
|
||||
void switchWithWindowInGroup(PHLWINDOW pWindow);
|
||||
void setAnimationsToMove();
|
||||
void onWorkspaceAnimUpdate();
|
||||
void onFocusAnimUpdate();
|
||||
void onUpdateState();
|
||||
void onUpdateMeta();
|
||||
void onX11ConfigureRequest(CBox box);
|
||||
void onResourceChangeX11();
|
||||
std::string fetchTitle();
|
||||
std::string fetchClass();
|
||||
void warpCursor(bool force = false);
|
||||
PHLWINDOW getSwallower();
|
||||
bool isX11OverrideRedirect();
|
||||
bool isModal();
|
||||
Vector2D requestedMinSize();
|
||||
Vector2D requestedMaxSize();
|
||||
Vector2D realToReportSize();
|
||||
Vector2D realToReportPosition();
|
||||
Vector2D xwaylandSizeToReal(Vector2D size);
|
||||
Vector2D xwaylandPositionToReal(Vector2D size);
|
||||
void updateX11SurfaceScale();
|
||||
void sendWindowSize(bool force = false);
|
||||
NContentType::eContentType getContentType();
|
||||
void setContentType(NContentType::eContentType contentType);
|
||||
void deactivateGroupMembers();
|
||||
bool isNotResponding();
|
||||
std::optional<std::string> xdgTag();
|
||||
std::optional<std::string> xdgDescription();
|
||||
PHLWINDOW parent();
|
||||
bool priorityFocus();
|
||||
SP<CWLSurfaceResource> getSolitaryResource();
|
||||
Vector2D getReportedSize();
|
||||
std::optional<Vector2D> calculateExpression(const std::string& s);
|
||||
|
||||
CBox getWindowMainSurfaceBox() const {
|
||||
return {m_realPosition->value().x, m_realPosition->value().y, m_realSize->value().x, m_realSize->value().y};
|
||||
}
|
||||
|
||||
// listeners
|
||||
void onAck(uint32_t serial);
|
||||
|
||||
//
|
||||
std::unordered_map<std::string, std::string> getEnv();
|
||||
|
||||
//
|
||||
PHLWINDOWREF m_self;
|
||||
|
||||
// make private once we move listeners to inside CWindow
|
||||
struct {
|
||||
CHyprSignalListener map;
|
||||
CHyprSignalListener ack;
|
||||
CHyprSignalListener unmap;
|
||||
CHyprSignalListener commit;
|
||||
CHyprSignalListener destroy;
|
||||
CHyprSignalListener activate;
|
||||
CHyprSignalListener configureRequest;
|
||||
CHyprSignalListener setGeometry;
|
||||
CHyprSignalListener updateState;
|
||||
CHyprSignalListener updateMetadata;
|
||||
CHyprSignalListener resourceChange;
|
||||
} m_listeners;
|
||||
|
||||
private:
|
||||
std::optional<double> calculateSingleExpr(const std::string& s);
|
||||
void mapWindow();
|
||||
void unmapWindow();
|
||||
void commitWindow();
|
||||
void destroyWindow();
|
||||
void activateX11();
|
||||
void unmanagedSetGeometry();
|
||||
|
||||
// For hidden windows and stuff
|
||||
bool m_hidden = false;
|
||||
bool m_suspended = false;
|
||||
WORKSPACEID m_lastWorkspace = WORKSPACE_INVALID;
|
||||
};
|
||||
|
||||
inline bool valid(PHLWINDOW w) {
|
||||
return w.get();
|
||||
}
|
||||
|
||||
inline bool valid(PHLWINDOWREF w) {
|
||||
return !w.expired();
|
||||
}
|
||||
|
||||
inline bool validMapped(PHLWINDOW w) {
|
||||
if (!valid(w))
|
||||
return false;
|
||||
return w->m_isMapped;
|
||||
}
|
||||
|
||||
inline bool validMapped(PHLWINDOWREF w) {
|
||||
if (!valid(w))
|
||||
return false;
|
||||
return w->m_isMapped;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
format specification
|
||||
- 'x', only address, equivalent of (uintpr_t)CWindow*
|
||||
- 'm', with monitor id
|
||||
- 'w', with workspace id
|
||||
- 'c', with application class
|
||||
*/
|
||||
|
||||
template <typename CharT>
|
||||
struct std::formatter<PHLWINDOW, CharT> : std::formatter<CharT> {
|
||||
bool formatAddressOnly = false;
|
||||
bool formatWorkspace = false;
|
||||
bool formatMonitor = false;
|
||||
bool formatClass = false;
|
||||
FORMAT_PARSE( //
|
||||
FORMAT_FLAG('x', formatAddressOnly) //
|
||||
FORMAT_FLAG('m', formatMonitor) //
|
||||
FORMAT_FLAG('w', formatWorkspace) //
|
||||
FORMAT_FLAG('c', formatClass),
|
||||
PHLWINDOW)
|
||||
|
||||
template <typename FormatContext>
|
||||
auto format(PHLWINDOW const& w, FormatContext& ctx) const {
|
||||
auto&& out = ctx.out();
|
||||
if (formatAddressOnly)
|
||||
return std::format_to(out, "{:x}", rc<uintptr_t>(w.get()));
|
||||
if (!w)
|
||||
return std::format_to(out, "[Window nullptr]");
|
||||
|
||||
std::format_to(out, "[");
|
||||
std::format_to(out, "Window {:x}: title: \"{}\"", rc<uintptr_t>(w.get()), w->m_title);
|
||||
if (formatWorkspace)
|
||||
std::format_to(out, ", workspace: {}", w->m_workspace ? w->workspaceID() : WORKSPACE_INVALID);
|
||||
if (formatMonitor)
|
||||
std::format_to(out, ", monitor: {}", w->monitorID());
|
||||
if (formatClass)
|
||||
std::format_to(out, ", class: {}", w->m_class);
|
||||
return std::format_to(out, "]");
|
||||
}
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue