2022-03-17 20:22:29 +01:00
# pragma once
# include "defines.hpp"
2022-03-27 21:46:27 +02:00
# include "helpers/SubsurfaceTree.hpp"
2022-04-23 14:16:02 +02:00
# include "helpers/AnimatedVariable.hpp"
2022-05-28 20:46:20 +02:00
# include "render/decorations/IHyprWindowDecoration.hpp"
# include <deque>
2022-11-26 18:56:43 +01:00
# include "config/ConfigDataValues.hpp"
2023-02-18 23:35:31 +01:00
# include "helpers/Vector2D.hpp"
2023-03-20 16:00:58 +01:00
# include "helpers/WLSurface.hpp"
2023-09-20 17:25:03 +02:00
# include "macros.hpp"
# include "managers/XWaylandManager.hpp"
2022-03-17 20:22:29 +01:00
2023-12-06 23:54:56 +01:00
enum eIdleInhibitMode {
2022-10-31 13:26:07 +01:00
IDLEINHIBIT_NONE = 0 ,
IDLEINHIBIT_ALWAYS ,
IDLEINHIBIT_FULLSCREEN ,
IDLEINHIBIT_FOCUS
} ;
2023-12-06 23:54:56 +01:00
enum eGroupRules {
2023-09-22 01:42:00 +02:00
// 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
} ;
2023-10-21 15:15:48 +02:00
class IWindowTransformer ;
2023-01-24 20:05:34 +01:00
template < typename T >
class CWindowOverridableVar {
public :
CWindowOverridableVar ( T val ) {
value = val ;
}
2023-01-24 23:46:16 +01:00
~ CWindowOverridableVar ( ) = default ;
CWindowOverridableVar < T > & operator = ( CWindowOverridableVar < T > other ) {
2023-01-24 20:05:34 +01:00
if ( locked )
return * this ;
locked = other . locked ;
value = other . value ;
return * this ;
}
T operator = ( T & other ) {
if ( locked )
return value ;
value = other ;
return other ;
}
void forceSetIgnoreLocked ( T val , bool lock = false ) {
value = val ;
locked = lock ;
}
T operator * ( T & other ) {
return value * other ;
}
T operator + ( T & other ) {
return value + other ;
}
bool operator = = ( T & other ) {
return other = = value ;
}
bool operator > = ( T & other ) {
return value > = other ;
}
bool operator < = ( T & other ) {
return value < = other ;
}
bool operator > ( T & other ) {
return value > other ;
}
bool operator < ( T & other ) {
return value < other ;
}
explicit operator bool ( ) {
return static_cast < bool > ( value ) ;
}
T toUnderlying ( ) {
return value ;
}
bool locked = false ;
private :
T value ;
} ;
2022-04-22 14:37:38 +02:00
struct SWindowSpecialRenderData {
2023-01-24 20:05:34 +01:00
CWindowOverridableVar < bool > alphaOverride = false ;
CWindowOverridableVar < float > alpha = 1.f ;
CWindowOverridableVar < bool > alphaInactiveOverride = false ;
CWindowOverridableVar < float > alphaInactive = - 1.f ; // -1 means unset
2022-08-01 12:51:52 +02:00
2023-01-24 20:05:34 +01:00
CWindowOverridableVar < int64_t > activeBorderColor = - 1 ; // -1 means unset
CWindowOverridableVar < int64_t > inactiveBorderColor = - 1 ; // -1 means unset
2022-11-13 20:33:13 +01:00
2022-08-01 12:51:52 +02:00
// set by the layout
2023-06-04 21:29:38 +02:00
CWindowOverridableVar < int > borderSize = - 1 ; // -1 means unset
bool rounding = true ;
bool border = true ;
bool decorate = true ;
2023-08-12 23:37:55 +02:00
bool shadow = true ;
2022-09-25 20:07:48 +02:00
} ;
2022-03-17 20:22:29 +01:00
2022-05-15 14:18:31 +02:00
struct SWindowAdditionalConfigData {
2023-04-03 20:16:51 +02:00
std : : string animationStyle = std : : string ( " " ) ;
CWindowOverridableVar < int > rounding = - 1 ; // -1 means no
CWindowOverridableVar < bool > forceNoBlur = false ;
CWindowOverridableVar < bool > forceOpaque = false ;
2023-03-30 00:44:25 +02:00
CWindowOverridableVar < bool > forceOpaqueOverridden = false ; // if true, a rule will not change the forceOpaque state. This is for the force opaque dispatcher.
2023-04-03 20:16:51 +02:00
CWindowOverridableVar < bool > forceAllowsInput = false ;
CWindowOverridableVar < bool > forceNoAnims = false ;
CWindowOverridableVar < bool > forceNoBorder = false ;
CWindowOverridableVar < bool > forceNoShadow = false ;
2023-05-31 21:11:20 +02:00
CWindowOverridableVar < bool > forceNoDim = false ;
2023-04-03 20:16:51 +02:00
CWindowOverridableVar < bool > windowDanceCompat = false ;
CWindowOverridableVar < bool > noMaxSize = false ;
CWindowOverridableVar < bool > dimAround = false ;
CWindowOverridableVar < bool > forceRGBX = false ;
2023-08-08 18:52:20 +02:00
CWindowOverridableVar < bool > keepAspectRatio = false ;
2023-08-09 22:03:24 +02:00
CWindowOverridableVar < int > xray = - 1 ; // -1 means unset, takes precedence over the renderdata one
2023-07-18 00:11:29 +02:00
CWindowOverridableVar < int > borderSize = - 1 ; // -1 means unset, takes precedence over the renderdata one
2023-09-28 22:48:33 +02:00
CWindowOverridableVar < bool > forceTearing = false ;
2023-10-24 22:28:55 +02:00
CWindowOverridableVar < bool > nearestNeighbor = false ;
2022-05-15 14:18:31 +02:00
} ;
2022-11-15 11:21:26 +01:00
struct SWindowRule {
std : : string szRule ;
std : : string szValue ;
2022-12-16 18:17:31 +01:00
bool v2 = false ;
2022-11-15 11:21:26 +01:00
std : : string szTitle ;
std : : string szClass ;
2022-12-16 18:17:31 +01:00
int bX11 = - 1 ; // -1 means "ANY"
int bFloating = - 1 ;
int bFullscreen = - 1 ;
int bPinned = - 1 ;
2023-12-08 17:02:16 +01:00
int bFocus = - 1 ;
2023-08-02 13:21:38 +02:00
std : : string szWorkspace = " " ; // empty means any
2022-11-15 11:21:26 +01:00
} ;
2022-03-17 20:22:29 +01:00
class CWindow {
2022-12-16 18:17:31 +01:00
public :
2022-04-23 14:16:02 +02:00
CWindow ( ) ;
2022-03-30 21:18:42 +02:00
~ CWindow ( ) ;
2022-03-17 20:22:29 +01:00
DYNLISTENER ( commitWindow ) ;
DYNLISTENER ( mapWindow ) ;
DYNLISTENER ( unmapWindow ) ;
DYNLISTENER ( destroyWindow ) ;
DYNLISTENER ( setTitleWindow ) ;
2022-07-08 11:24:07 +02:00
DYNLISTENER ( setGeometryX11U ) ;
2022-03-17 20:22:29 +01:00
DYNLISTENER ( fullscreenWindow ) ;
2022-03-20 14:00:46 +01:00
DYNLISTENER ( newPopupXDG ) ;
2022-07-16 00:11:21 +02:00
DYNLISTENER ( requestMove ) ;
DYNLISTENER ( requestMinimize ) ;
DYNLISTENER ( requestMaximize ) ;
DYNLISTENER ( requestResize ) ;
2022-08-06 20:57:38 +02:00
DYNLISTENER ( activateX11 ) ;
DYNLISTENER ( configureX11 ) ;
DYNLISTENER ( toplevelClose ) ;
DYNLISTENER ( toplevelActivate ) ;
DYNLISTENER ( toplevelFullscreen ) ;
2023-02-28 19:50:47 +01:00
DYNLISTENER ( setOverrideRedirect ) ;
2023-06-03 12:20:23 +02:00
DYNLISTENER ( associateX11 ) ;
DYNLISTENER ( dissociateX11 ) ;
2023-11-09 23:43:52 +01:00
DYNLISTENER ( ackConfigure ) ;
2022-12-16 18:17:31 +01:00
// DYNLISTENER(newSubsurfaceWindow);
2022-03-17 20:22:29 +01:00
2023-03-20 16:00:58 +01:00
CWLSurface m_pWLSurface ;
std : : list < CWLSurface > m_lPopupSurfaces ;
2022-03-17 20:22:29 +01:00
union {
2022-12-16 18:17:31 +01:00
wlr_xdg_surface * xdg ;
2022-03-17 20:22:29 +01:00
wlr_xwayland_surface * xwayland ;
} m_uSurface ;
// this is the position and size of the "bounding box"
2022-12-20 03:18:47 +01:00
Vector2D m_vPosition = Vector2D ( 0 , 0 ) ;
Vector2D m_vSize = Vector2D ( 0 , 0 ) ;
2022-03-17 20:22:29 +01:00
// this is the real position and size used to draw the thing
2022-12-20 03:18:47 +01:00
CAnimatedVariable m_vRealPosition ;
CAnimatedVariable m_vRealSize ;
2022-03-17 20:22:29 +01:00
2022-07-28 23:55:00 +02:00
// for not spamming the protocols
2023-11-10 01:13:22 +01:00
Vector2D m_vReportedPosition ;
Vector2D m_vReportedSize ;
Vector2D m_vPendingReportedSize ;
std : : optional < std : : pair < uint32_t , Vector2D > > m_pPendingSizeAck ;
std : : vector < std : : pair < uint32_t , Vector2D > > m_vPendingSizeAcks ;
2022-07-28 23:55:00 +02:00
2022-08-05 17:52:14 +02:00
// for restoring floating statuses
2022-12-20 03:18:47 +01:00
Vector2D m_vLastFloatingSize ;
Vector2D m_vLastFloatingPosition ;
2022-08-05 17:52:14 +02:00
2022-04-02 20:04:32 +02:00
// this is used for pseudotiling
2022-12-20 03:18:47 +01:00
bool m_bIsPseudotiled = false ;
Vector2D m_vPseudoSize = Vector2D ( 0 , 0 ) ;
2022-04-02 20:04:32 +02:00
2023-05-24 19:23:07 +02:00
bool m_bFirstMap = false ; // for layouts
2022-12-20 03:18:47 +01:00
bool m_bIsFloating = false ;
bool m_bDraggingTiled = false ; // for dragging around tiled windows
bool m_bIsFullscreen = false ;
2023-01-17 13:20:10 +01:00
bool m_bWasMaximized = false ;
2022-12-20 03:18:47 +01:00
uint64_t m_iMonitorID = - 1 ;
std : : string m_szTitle = " " ;
2023-04-03 20:16:51 +02:00
std : : string m_szInitialTitle = " " ;
std : : string m_szInitialClass = " " ;
2022-12-20 03:18:47 +01:00
int m_iWorkspaceID = - 1 ;
2022-03-18 20:03:39 +01:00
2022-12-20 03:18:47 +01:00
bool m_bIsMapped = false ;
2022-03-22 20:53:11 +01:00
2022-12-20 03:18:47 +01:00
bool m_bRequestsFloat = false ;
2022-05-26 19:05:32 +02:00
2022-03-30 20:16:23 +02:00
// This is for fullscreen apps
2022-12-20 03:18:47 +01:00
bool m_bCreatedOverFullscreen = false ;
2022-03-30 20:16:23 +02:00
2022-03-18 20:03:39 +01:00
// XWayland stuff
2022-12-20 03:18:47 +01:00
bool m_bIsX11 = false ;
bool m_bMappedX11 = false ;
CWindow * m_pX11Parent = nullptr ;
uint64_t m_iX11Type = 0 ;
bool m_bIsModal = false ;
bool m_bX11DoesntWantBorders = false ;
bool m_bX11ShouldntFocus = false ;
2023-06-11 21:52:13 +02:00
float m_fX11SurfaceScaledBy = 1.f ;
2022-03-18 20:03:39 +01:00
//
2022-03-18 22:35:51 +01:00
2022-05-14 14:37:57 +02:00
// For nofocus
2022-12-20 03:18:47 +01:00
bool m_bNoFocus = false ;
bool m_bNoInitialFocus = false ;
2022-05-14 14:37:57 +02:00
2023-07-23 19:47:41 +02:00
// Fullscreen and Maximize
2022-12-20 03:18:47 +01:00
bool m_bWantsInitialFullscreen = false ;
bool m_bNoFullscreenRequest = false ;
2023-07-23 19:47:41 +02:00
bool m_bNoMaximizeRequest = false ;
2022-08-21 22:30:48 +02:00
2022-12-20 03:18:47 +01:00
SSurfaceTreeNode * m_pSurfaceTree = nullptr ;
2022-03-27 21:46:27 +02:00
2022-03-31 17:50:00 +02:00
// Animated border
2022-12-20 03:18:47 +01:00
CGradientValueData m_cRealBorderColor = { 0 } ;
CGradientValueData m_cRealBorderColorPrevious = { 0 } ;
2023-02-01 22:06:01 +01:00
CAnimatedVariable m_fBorderFadeAnimationProgress ;
CAnimatedVariable m_fBorderAngleAnimationProgress ;
2022-03-31 17:50:00 +02:00
2022-04-05 19:28:10 +02:00
// Fade in-out
2023-08-09 14:28:04 +02:00
CAnimatedVariable m_fAlpha ;
bool m_bFadingOut = false ;
bool m_bReadyToDelete = false ;
Vector2D m_vOriginalClosedPos ; // these will be used for calculations later on in
Vector2D m_vOriginalClosedSize ; // drawing the closing animations
SWindowDecorationExtents m_eOriginalClosedExtents ;
2022-04-05 19:28:10 +02:00
2022-09-10 13:11:02 +02:00
// For pinned (sticky) windows
2022-12-20 03:18:47 +01:00
bool m_bPinned = false ;
2022-09-10 13:11:02 +02:00
2023-01-14 20:31:11 +01:00
// urgency hint
bool m_bIsUrgent = false ;
2023-01-01 16:54:13 +01:00
// fakefullscreen
2023-01-06 13:29:43 +01:00
bool m_bFakeFullscreenState = false ;
2023-01-01 16:54:13 +01:00
2022-08-24 22:01:25 +02:00
// for proper cycling. While cycling we can't just move the pointers, so we need to keep track of the last cycled window.
2022-12-20 03:18:47 +01:00
CWindow * m_pLastCycledWindow = nullptr ;
2022-08-24 22:01:25 +02:00
2022-05-29 11:24:42 +02:00
// Foreign Toplevel proto
2022-12-20 03:18:47 +01:00
wlr_foreign_toplevel_handle_v1 * m_phForeignToplevel = nullptr ;
2022-05-29 11:24:42 +02:00
2022-05-28 20:46:20 +02:00
// Window decorations
2022-05-28 23:43:11 +02:00
std : : deque < std : : unique_ptr < IHyprWindowDecoration > > m_dWindowDecorations ;
2022-12-16 18:17:31 +01:00
std : : vector < IHyprWindowDecoration * > m_vDecosToRemove ;
2022-05-28 20:46:20 +02:00
2022-04-22 14:37:38 +02:00
// Special render data, rules, etc
2022-12-20 03:18:47 +01:00
SWindowSpecialRenderData m_sSpecialRenderData ;
SWindowAdditionalConfigData m_sAdditionalConfigData ;
2022-03-18 22:35:51 +01:00
2023-10-21 15:15:48 +02:00
// Transformers
std : : vector < std : : unique_ptr < IWindowTransformer > > m_vTransformers ;
2022-07-12 13:40:55 +02:00
// for alpha
2022-12-20 03:18:47 +01:00
CAnimatedVariable m_fActiveInactiveAlpha ;
2022-07-12 13:40:55 +02:00
2022-07-16 12:44:45 +02:00
// animated shadow color
2022-12-20 03:18:47 +01:00
CAnimatedVariable m_cRealShadowColor ;
2022-07-16 12:44:45 +02:00
2022-08-30 12:46:17 +02:00
// animated tint
2022-12-20 03:18:47 +01:00
CAnimatedVariable m_fDimPercent ;
2022-08-30 12:46:17 +02:00
2022-10-01 20:19:15 +02:00
// swallowing
2022-12-20 03:18:47 +01:00
CWindow * m_pSwallowed = nullptr ;
2022-10-01 20:19:15 +02:00
2023-07-04 12:05:25 +02:00
// focus stuff
bool m_bStayFocused = false ;
2022-08-06 20:57:38 +02:00
// for toplevel monitor events
2022-12-20 03:18:47 +01:00
uint64_t m_iLastToplevelMonitorID = - 1 ;
uint64_t m_iLastSurfaceMonitorID = - 1 ;
2022-08-06 20:57:38 +02:00
2022-10-31 13:26:07 +01:00
// for idle inhibiting windows
2022-12-20 03:18:47 +01:00
eIdleInhibitMode m_eIdleInhibitMode = IDLEINHIBIT_NONE ;
2022-10-31 13:26:07 +01:00
2023-02-19 22:07:32 +01:00
// for groups
struct SGroupData {
CWindow * pNextWindow = nullptr ; // nullptr means no grouping. Self means single group.
bool head = false ;
2023-09-22 01:42:00 +02:00
bool locked = false ; // per group lock
bool deny = false ; // deny window from enter a group or made a group
2023-02-19 22:07:32 +01:00
} m_sGroupData ;
2023-09-22 01:42:00 +02:00
uint16_t m_eGroupRules = GROUP_NONE ;
2023-02-19 22:07:32 +01:00
2023-09-28 22:48:33 +02:00
bool m_bTearingHint = false ;
2022-03-18 22:35:51 +01:00
// For the list lookup
2022-12-20 03:18:47 +01:00
bool operator = = ( const CWindow & rhs ) {
2022-12-16 18:17:31 +01:00
return m_uSurface . xdg = = rhs . m_uSurface . xdg & & m_uSurface . xwayland = = rhs . m_uSurface . xwayland & & m_vPosition = = rhs . m_vPosition & & m_vSize = = rhs . m_vSize & &
m_bFadingOut = = rhs . m_bFadingOut ;
2022-03-18 22:35:51 +01:00
}
2022-05-30 14:55:42 +02:00
// methods
2023-11-04 18:03:05 +01:00
CBox getFullWindowBoundingBox ( ) ;
2023-08-09 14:28:04 +02:00
SWindowDecorationExtents getFullWindowExtents ( ) ;
2023-11-04 18:03:05 +01:00
CBox getWindowInputBox ( ) ;
CBox getWindowMainSurfaceBox ( ) ;
CBox getWindowIdealBoundingBoxIgnoreReserved ( ) ;
2023-11-11 15:37:17 +01:00
void addWindowDeco ( std : : unique_ptr < IHyprWindowDecoration > deco ) ;
2023-02-28 20:36:36 +01:00
void updateWindowDecos ( ) ;
2023-11-11 15:37:17 +01:00
void removeWindowDeco ( IHyprWindowDecoration * deco ) ;
2023-02-28 20:36:36 +01:00
pid_t getPID ( ) ;
IHyprWindowDecoration * getDecorationByType ( eDecorationType ) ;
void removeDecorationByType ( eDecorationType ) ;
void createToplevelHandle ( ) ;
void destroyToplevelHandle ( ) ;
void updateToplevel ( ) ;
void updateSurfaceOutputs ( ) ;
void moveToWorkspace ( int ) ;
CWindow * X11TransientFor ( ) ;
void onUnmap ( ) ;
void onMap ( ) ;
void setHidden ( bool hidden ) ;
bool isHidden ( ) ;
void applyDynamicRule ( const SWindowRule & r ) ;
void updateDynamicRules ( ) ;
SWindowDecorationExtents getFullWindowReservedArea ( ) ;
2023-04-14 16:03:53 +02:00
Vector2D middle ( ) ;
2023-04-22 13:36:50 +02:00
bool opaque ( ) ;
2023-07-19 16:13:55 +02:00
float rounding ( ) ;
2023-09-28 22:48:33 +02:00
bool canBeTorn ( ) ;
2023-02-28 20:36:36 +01:00
2023-08-17 10:13:19 +02:00
int getRealBorderSize ( ) ;
void updateSpecialRenderData ( ) ;
2023-02-28 20:36:36 +01:00
void onBorderAngleAnimEnd ( void * ptr ) ;
bool isInCurvedCorner ( double x , double y ) ;
bool hasPopupAt ( const Vector2D & pos ) ;
2023-09-22 01:42:00 +02:00
void applyGroupRules ( ) ;
void createGroup ( ) ;
void destroyGroup ( ) ;
2023-02-28 20:36:36 +01:00
CWindow * getGroupHead ( ) ;
CWindow * getGroupTail ( ) ;
CWindow * getGroupCurrent ( ) ;
2023-07-13 17:55:20 +02:00
CWindow * getGroupPrevious ( ) ;
2023-08-30 17:39:22 +02:00
CWindow * getGroupWindowByIndex ( int ) ;
int getGroupSize ( ) ;
2023-10-30 15:54:12 +01:00
bool canBeGroupedInto ( CWindow * pWindow ) ;
2023-02-28 20:36:36 +01:00
void setGroupCurrent ( CWindow * pWindow ) ;
void insertWindowToGroup ( CWindow * pWindow ) ;
2023-03-18 17:30:29 +01:00
void updateGroupOutputs ( ) ;
2023-07-13 17:55:20 +02:00
void switchWithWindowInGroup ( CWindow * pWindow ) ;
2023-02-19 22:07:32 +01:00
2022-12-16 18:17:31 +01:00
private :
2022-10-14 21:46:32 +02:00
// For hidden windows and stuff
2022-12-16 18:17:31 +01:00
bool m_bHidden = false ;
2022-06-24 22:28:54 +02:00
} ;
2023-09-20 17:25:03 +02:00
/**
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 < CWindow * , 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 ) ,
CWindow * )
template < typename FormatContext >
auto format ( CWindow * const & w , FormatContext & ctx ) const {
auto & & out = ctx . out ( ) ;
if ( formatAddressOnly )
return std : : format_to ( out , " {:x} " , ( uintptr_t ) w ) ;
if ( ! w )
return std : : format_to ( out , " [Window nullptr] " ) ;
std : : format_to ( out , " [ " ) ;
std : : format_to ( out , " Window {:x}: title: \" {} \" " , ( uintptr_t ) w , w - > m_szTitle ) ;
if ( formatWorkspace )
std : : format_to ( out , " , workspace: {} " , w - > m_iWorkspaceID ) ;
if ( formatMonitor )
std : : format_to ( out , " , monitor: {} " , w - > m_iMonitorID ) ;
if ( formatClass )
std : : format_to ( out , " , class: {} " , g_pXWaylandManager - > getAppIDClass ( w ) ) ;
return std : : format_to ( out , " ] " ) ;
}
2023-10-30 15:54:12 +01:00
} ;