2022-06-30 12:09:05 +02:00
# include "IHyprLayout.hpp"
# include "../defines.hpp"
# include "../Compositor.hpp"
void IHyprLayout : : onWindowCreated ( CWindow * pWindow ) {
if ( pWindow - > m_bIsFloating ) {
onWindowCreatedFloating ( pWindow ) ;
} else {
2022-08-05 17:52:14 +02:00
wlr_box desiredGeometry = { 0 } ;
g_pXWaylandManager - > getGeometryForWindow ( pWindow , & desiredGeometry ) ;
if ( desiredGeometry . width < = 5 | | desiredGeometry . height < = 5 ) {
const auto PMONITOR = g_pCompositor - > getMonitorFromID ( pWindow - > m_iMonitorID ) ;
pWindow - > m_vLastFloatingSize = PMONITOR - > vecSize / 2.f ;
} else {
pWindow - > m_vLastFloatingSize = Vector2D ( desiredGeometry . width , desiredGeometry . height ) ;
}
2022-06-30 12:09:05 +02:00
onWindowCreatedTiling ( pWindow ) ;
}
}
void IHyprLayout : : onWindowRemoved ( CWindow * pWindow ) {
if ( pWindow - > m_bIsFloating ) {
onWindowRemovedFloating ( pWindow ) ;
} else {
onWindowRemovedTiling ( pWindow ) ;
}
}
void IHyprLayout : : onWindowRemovedFloating ( CWindow * pWindow ) {
return ; // no-op
}
void IHyprLayout : : onWindowCreatedFloating ( CWindow * pWindow ) {
wlr_box desiredGeometry = { 0 } ;
g_pXWaylandManager - > getGeometryForWindow ( pWindow , & desiredGeometry ) ;
const auto PMONITOR = g_pCompositor - > getMonitorFromID ( pWindow - > m_iMonitorID ) ;
if ( ! PMONITOR ) {
Debug : : log ( ERR , " Window %x (%s) has an invalid monitor in onWindowCreatedFloating!!! " , pWindow , pWindow - > m_szTitle . c_str ( ) ) ;
return ;
}
2022-07-18 13:14:31 +02:00
if ( desiredGeometry . width < = 5 | | desiredGeometry . height < = 5 ) {
2022-06-30 12:09:05 +02:00
const auto PWINDOWSURFACE = g_pXWaylandManager - > getWindowSurface ( pWindow ) ;
pWindow - > m_vRealSize = Vector2D ( PWINDOWSURFACE - > current . width , PWINDOWSURFACE - > current . height ) ;
2022-07-28 15:40:06 +02:00
2022-08-03 21:03:08 +02:00
if ( ( desiredGeometry . width < = 1 | | desiredGeometry . height < = 1 ) & & pWindow - > m_bIsX11 & & pWindow - > m_iX11Type = = 2 ) { // XDG windows should be fine. TODO: check for weird atoms?
2022-10-14 21:46:32 +02:00
pWindow - > setHidden ( true ) ;
2022-07-28 15:40:06 +02:00
return ;
}
2022-09-25 20:07:48 +02:00
2022-07-18 13:14:31 +02:00
// reject any windows with size <= 5x5
if ( pWindow - > m_vRealSize . goalv ( ) . x < = 5 | | pWindow - > m_vRealSize . goalv ( ) . y < = 5 ) {
pWindow - > m_vRealSize = PMONITOR - > vecSize / 2.f ;
}
2022-06-30 12:09:05 +02:00
2022-07-18 13:14:31 +02:00
pWindow - > m_vRealPosition = Vector2D ( PMONITOR - > vecPosition . x + ( PMONITOR - > vecSize . x - pWindow - > m_vRealSize . goalv ( ) . x ) / 2.f , PMONITOR - > vecPosition . y + ( PMONITOR - > vecSize . y - pWindow - > m_vRealSize . goalv ( ) . y ) / 2.f ) ;
2022-06-30 12:09:05 +02:00
} else {
// we respect the size.
pWindow - > m_vRealSize = Vector2D ( desiredGeometry . width , desiredGeometry . height ) ;
// check if it's on the correct monitor!
Vector2D middlePoint = Vector2D ( desiredGeometry . x , desiredGeometry . y ) + Vector2D ( desiredGeometry . width , desiredGeometry . height ) / 2.f ;
2022-09-13 22:23:48 +02:00
// check if it's visible on any monitor (only for XDG)
bool visible = pWindow - > m_bIsX11 ;
2022-09-13 12:29:56 +02:00
2022-09-13 22:23:48 +02:00
if ( ! pWindow - > m_bIsX11 ) {
for ( auto & m : g_pCompositor - > m_vMonitors ) {
if ( VECINRECT ( Vector2D ( desiredGeometry . x , desiredGeometry . y ) , m - > vecPosition . x , m - > vecPosition . y , m - > vecPosition . x + m - > vecSize . x , m - > vecPosition . y + m - > vecPosition . y )
| | VECINRECT ( Vector2D ( desiredGeometry . x + desiredGeometry . width , desiredGeometry . y ) , m - > vecPosition . x , m - > vecPosition . y , m - > vecPosition . x + m - > vecSize . x , m - > vecPosition . y + m - > vecPosition . y )
| | VECINRECT ( Vector2D ( desiredGeometry . x , desiredGeometry . y + desiredGeometry . height ) , m - > vecPosition . x , m - > vecPosition . y , m - > vecPosition . x + m - > vecSize . x , m - > vecPosition . y + m - > vecPosition . y )
| | VECINRECT ( Vector2D ( desiredGeometry . x + desiredGeometry . width , desiredGeometry . y + desiredGeometry . height ) , m - > vecPosition . x , m - > vecPosition . y , m - > vecPosition . x + m - > vecSize . x , m - > vecPosition . y + m - > vecPosition . y ) ) {
visible = true ;
break ;
}
2022-09-13 12:29:56 +02:00
}
}
2022-06-30 12:09:05 +02:00
// TODO: detect a popup in a more consistent way.
2022-09-13 12:29:56 +02:00
if ( ( desiredGeometry . x = = 0 & & desiredGeometry . y = = 0 ) | | ! visible ) {
2022-06-30 12:09:05 +02:00
// if it's not, fall back to the center placement
pWindow - > m_vRealPosition = PMONITOR - > vecPosition + Vector2D ( ( PMONITOR - > vecSize . x - desiredGeometry . width ) / 2.f , ( PMONITOR - > vecSize . y - desiredGeometry . height ) / 2.f ) ;
} else {
// if it is, we respect where it wants to put itself, but apply monitor offset if outside
// most of these are popups
if ( const auto POPENMON = g_pCompositor - > getMonitorFromVector ( middlePoint ) ; POPENMON - > ID ! = PMONITOR - > ID ) {
pWindow - > m_vRealPosition = Vector2D ( desiredGeometry . x , desiredGeometry . y ) - POPENMON - > vecPosition + PMONITOR - > vecPosition ;
} else {
pWindow - > m_vRealPosition = Vector2D ( desiredGeometry . x , desiredGeometry . y ) ;
}
}
}
if ( pWindow - > m_bX11DoesntWantBorders ) {
pWindow - > m_vRealPosition . setValue ( pWindow - > m_vRealPosition . goalv ( ) ) ;
pWindow - > m_vRealSize . setValue ( pWindow - > m_vRealSize . goalv ( ) ) ;
}
2022-07-08 11:24:07 +02:00
if ( pWindow - > m_iX11Type ! = 2 ) {
g_pXWaylandManager - > setWindowSize ( pWindow , pWindow - > m_vRealSize . goalv ( ) ) ;
2022-06-30 12:09:05 +02:00
2022-07-08 11:24:07 +02:00
g_pCompositor - > moveWindowToTop ( pWindow ) ;
}
2022-06-30 12:09:05 +02:00
}
void IHyprLayout : : onBeginDragWindow ( ) {
const auto DRAGGINGWINDOW = g_pInputManager - > currentlyDraggedWindow ;
m_vBeginDragSizeXY = Vector2D ( ) ;
// Window will be floating. Let's check if it's valid. It should be, but I don't like crashing.
if ( ! g_pCompositor - > windowValidMapped ( DRAGGINGWINDOW ) ) {
Debug : : log ( ERR , " Dragging attempted on an invalid window! " ) ;
return ;
}
if ( DRAGGINGWINDOW - > m_bIsFullscreen ) {
Debug : : log ( LOG , " Rejecting drag on a fullscreen window. " ) ;
return ;
}
const auto PWORKSPACE = g_pCompositor - > getWorkspaceByID ( DRAGGINGWINDOW - > m_iWorkspaceID ) ;
if ( PWORKSPACE - > m_bHasFullscreenWindow ) {
Debug : : log ( LOG , " Rejecting drag on a fullscreen workspace. " ) ;
return ;
}
2022-07-28 13:28:43 +02:00
DRAGGINGWINDOW - > m_vRealPosition . setConfig ( g_pConfigManager - > getAnimationPropertyConfig ( " windowsMove " ) ) ;
DRAGGINGWINDOW - > m_vRealSize . setConfig ( g_pConfigManager - > getAnimationPropertyConfig ( " windowsMove " ) ) ;
2022-06-30 12:09:05 +02:00
DRAGGINGWINDOW - > m_bDraggingTiled = false ;
if ( ! DRAGGINGWINDOW - > m_bIsFloating ) {
2022-09-19 20:04:48 +02:00
if ( g_pInputManager - > dragMode = = MBIND_MOVE ) {
2022-06-30 12:09:05 +02:00
changeWindowFloatingMode ( DRAGGINGWINDOW ) ;
DRAGGINGWINDOW - > m_bIsFloating = true ;
DRAGGINGWINDOW - > m_bDraggingTiled = true ;
2022-08-05 17:52:14 +02:00
DRAGGINGWINDOW - > m_vRealPosition = g_pInputManager - > getMouseCoordsInternal ( ) - DRAGGINGWINDOW - > m_vRealSize . goalv ( ) / 2.f ;
2022-06-30 12:09:05 +02:00
}
}
m_vBeginDragXY = g_pInputManager - > getMouseCoordsInternal ( ) ;
2022-08-05 17:52:14 +02:00
m_vBeginDragPositionXY = DRAGGINGWINDOW - > m_vRealPosition . goalv ( ) ;
m_vBeginDragSizeXY = DRAGGINGWINDOW - > m_vRealSize . goalv ( ) ;
2022-06-30 12:09:05 +02:00
m_vLastDragXY = m_vBeginDragXY ;
2022-10-03 23:41:05 +02:00
// get the grab corner
if ( m_vBeginDragXY . x < m_vBeginDragPositionXY . x + m_vBeginDragSizeXY . x / 2.0 ) {
// left
if ( m_vBeginDragXY . y < m_vBeginDragPositionXY . y + m_vBeginDragSizeXY . y / 2.0 )
m_iGrabbedCorner = 0 ;
else
m_iGrabbedCorner = 4 ;
} else {
// right
if ( m_vBeginDragXY . y < m_vBeginDragPositionXY . y + m_vBeginDragSizeXY . y / 2.0 )
m_iGrabbedCorner = 1 ;
else
m_iGrabbedCorner = 3 ;
}
2022-06-30 12:09:05 +02:00
g_pHyprRenderer - > damageWindow ( DRAGGINGWINDOW ) ;
2022-07-21 19:44:34 +02:00
// shadow to ignore any bound to MAIN_MOD
g_pKeybindManager - > shadowKeybinds ( ) ;
2022-06-30 12:09:05 +02:00
}
void IHyprLayout : : onEndDragWindow ( ) {
const auto DRAGGINGWINDOW = g_pInputManager - > currentlyDraggedWindow ;
if ( ! g_pCompositor - > windowValidMapped ( DRAGGINGWINDOW ) )
return ;
if ( DRAGGINGWINDOW - > m_bDraggingTiled ) {
DRAGGINGWINDOW - > m_bIsFloating = false ;
changeWindowFloatingMode ( DRAGGINGWINDOW ) ;
}
g_pHyprRenderer - > damageWindow ( DRAGGINGWINDOW ) ;
}
void IHyprLayout : : onMouseMove ( const Vector2D & mousePos ) {
const auto DRAGGINGWINDOW = g_pInputManager - > currentlyDraggedWindow ;
// Window invalid or drag begin size 0,0 meaning we rejected it.
if ( ! g_pCompositor - > windowValidMapped ( DRAGGINGWINDOW ) | | m_vBeginDragSizeXY = = Vector2D ( ) ) {
g_pInputManager - > currentlyDraggedWindow = nullptr ;
return ;
}
const auto DELTA = Vector2D ( mousePos . x - m_vBeginDragXY . x , mousePos . y - m_vBeginDragXY . y ) ;
const auto TICKDELTA = Vector2D ( mousePos . x - m_vLastDragXY . x , mousePos . y - m_vLastDragXY . y ) ;
2022-08-16 21:56:54 +02:00
const auto PANIMATE = & g_pConfigManager - > getConfigValuePtr ( " misc:animate_manual_resizes " ) - > intValue ;
2022-06-30 12:09:05 +02:00
if ( abs ( TICKDELTA . x ) < 1.f & & abs ( TICKDELTA . y ) < 1.f )
return ;
m_vLastDragXY = mousePos ;
g_pHyprRenderer - > damageWindow ( DRAGGINGWINDOW ) ;
2022-09-19 20:04:48 +02:00
if ( g_pInputManager - > dragMode = = MBIND_MOVE ) {
2022-10-19 22:17:49 +02:00
if ( * PANIMATE ) {
DRAGGINGWINDOW - > m_vRealPosition = m_vBeginDragPositionXY + DELTA ;
} else {
DRAGGINGWINDOW - > m_vRealPosition . setValueAndWarp ( m_vBeginDragPositionXY + DELTA ) ;
}
2022-06-30 12:09:05 +02:00
g_pXWaylandManager - > setWindowSize ( DRAGGINGWINDOW , DRAGGINGWINDOW - > m_vRealSize . goalv ( ) ) ;
2022-09-19 20:04:48 +02:00
} else if ( g_pInputManager - > dragMode = = MBIND_RESIZE ) {
2022-06-30 12:09:05 +02:00
if ( DRAGGINGWINDOW - > m_bIsFloating ) {
2022-08-05 17:58:08 +02:00
2022-08-05 18:10:59 +02:00
const auto MAXSIZE = g_pXWaylandManager - > getMaxSizeForWindow ( DRAGGINGWINDOW ) ;
2022-08-05 17:58:08 +02:00
2022-10-03 23:41:05 +02:00
// calc the new size and pos
Vector2D newSize = m_vBeginDragSizeXY ;
Vector2D newPos = m_vBeginDragPositionXY ;
if ( m_iGrabbedCorner = = 3 ) {
newSize = newSize + DELTA ;
} else if ( m_iGrabbedCorner = = 0 ) {
newSize = newSize - DELTA ;
newPos = newPos + DELTA ;
} else if ( m_iGrabbedCorner = = 1 ) {
newSize = newSize + Vector2D ( DELTA . x , - DELTA . y ) ;
newPos = newPos + Vector2D ( 0 , DELTA . y ) ;
} else if ( m_iGrabbedCorner = = 4 ) {
newSize = newSize + Vector2D ( - DELTA . x , DELTA . y ) ;
newPos = newPos + Vector2D ( DELTA . x , 0 ) ;
}
newSize = newSize . clamp ( Vector2D ( 20 , 20 ) , MAXSIZE ) ;
2022-08-16 21:56:54 +02:00
if ( * PANIMATE ) {
2022-10-03 23:41:05 +02:00
DRAGGINGWINDOW - > m_vRealSize = newSize ;
DRAGGINGWINDOW - > m_vRealPosition = newPos ;
2022-08-16 21:56:54 +02:00
} else {
2022-10-03 23:41:05 +02:00
DRAGGINGWINDOW - > m_vRealSize . setValueAndWarp ( newSize ) ;
DRAGGINGWINDOW - > m_vRealPosition . setValueAndWarp ( newPos ) ;
2022-08-16 21:56:54 +02:00
}
2022-09-25 20:07:48 +02:00
2022-06-30 12:09:05 +02:00
g_pXWaylandManager - > setWindowSize ( DRAGGINGWINDOW , DRAGGINGWINDOW - > m_vRealSize . goalv ( ) ) ;
} else {
resizeActiveWindow ( TICKDELTA , DRAGGINGWINDOW ) ;
}
}
// get middle point
Vector2D middle = DRAGGINGWINDOW - > m_vRealPosition . vec ( ) + DRAGGINGWINDOW - > m_vRealSize . vec ( ) / 2.f ;
// and check its monitor
const auto PMONITOR = g_pCompositor - > getMonitorFromVector ( middle ) ;
if ( PMONITOR ) {
DRAGGINGWINDOW - > m_iMonitorID = PMONITOR - > ID ;
2022-08-21 17:01:26 +02:00
DRAGGINGWINDOW - > moveToWorkspace ( PMONITOR - > activeWorkspace ) ;
2022-09-25 20:07:48 +02:00
2022-08-06 20:57:38 +02:00
DRAGGINGWINDOW - > updateToplevel ( ) ;
2022-06-30 12:09:05 +02:00
}
2022-08-05 19:23:53 +02:00
DRAGGINGWINDOW - > updateWindowDecos ( ) ;
2022-06-30 12:09:05 +02:00
g_pHyprRenderer - > damageWindow ( DRAGGINGWINDOW ) ;
}
void IHyprLayout : : changeWindowFloatingMode ( CWindow * pWindow ) {
if ( pWindow - > m_bIsFullscreen ) {
Debug : : log ( LOG , " Rejecting a change float order because window is fullscreen. " ) ;
// restore its' floating mode
pWindow - > m_bIsFloating = ! pWindow - > m_bIsFloating ;
return ;
}
2022-09-10 13:11:02 +02:00
pWindow - > m_bPinned = false ;
2022-06-30 12:09:05 +02:00
const auto TILED = isWindowTiled ( pWindow ) ;
if ( ! TILED ) {
const auto PNEWMON = g_pCompositor - > getMonitorFromVector ( pWindow - > m_vRealPosition . vec ( ) + pWindow - > m_vRealSize . vec ( ) / 2.f ) ;
pWindow - > m_iMonitorID = PNEWMON - > ID ;
2022-08-21 17:01:26 +02:00
pWindow - > moveToWorkspace ( PNEWMON - > activeWorkspace ) ;
2022-06-30 12:09:05 +02:00
// save real pos cuz the func applies the default 5,5 mid
const auto PSAVEDPOS = pWindow - > m_vRealPosition . vec ( ) ;
const auto PSAVEDSIZE = pWindow - > m_vRealSize . vec ( ) ;
// if the window is pseudo, update its size
pWindow - > m_vPseudoSize = pWindow - > m_vRealSize . vec ( ) ;
2022-08-05 17:52:14 +02:00
pWindow - > m_vLastFloatingSize = PSAVEDSIZE ;
2022-06-30 12:09:05 +02:00
onWindowCreatedTiling ( pWindow ) ;
pWindow - > m_vRealPosition . setValue ( PSAVEDPOS ) ;
pWindow - > m_vRealSize . setValue ( PSAVEDSIZE ) ;
// fix pseudo leaving artifacts
g_pHyprRenderer - > damageMonitor ( g_pCompositor - > getMonitorFromID ( pWindow - > m_iMonitorID ) ) ;
} else {
2022-07-08 21:52:52 +02:00
pWindow - > m_vSize = pWindow - > m_vRealSize . vec ( ) ;
pWindow - > m_vPosition = pWindow - > m_vRealPosition . vec ( ) ;
2022-06-30 12:09:05 +02:00
onWindowRemovedTiling ( pWindow ) ;
g_pCompositor - > moveWindowToTop ( pWindow ) ;
2022-07-08 21:52:52 +02:00
2022-08-05 17:52:14 +02:00
pWindow - > m_vRealPosition = pWindow - > m_vRealPosition . vec ( ) + ( pWindow - > m_vRealSize . vec ( ) - pWindow - > m_vLastFloatingSize ) / 2.f ;
pWindow - > m_vRealSize = pWindow - > m_vLastFloatingSize ;
2022-07-08 21:52:52 +02:00
g_pHyprRenderer - > damageMonitor ( g_pCompositor - > getMonitorFromID ( pWindow - > m_iMonitorID ) ) ;
2022-08-05 18:08:23 +02:00
pWindow - > m_sSpecialRenderData . rounding = true ;
2022-06-30 12:09:05 +02:00
}
2022-08-06 20:57:38 +02:00
2022-08-11 19:29:39 +02:00
g_pCompositor - > updateWindowAnimatedDecorationValues ( pWindow ) ;
2022-08-06 20:57:38 +02:00
pWindow - > updateToplevel ( ) ;
2022-06-30 12:09:05 +02:00
}
void IHyprLayout : : moveActiveWindow ( const Vector2D & delta , CWindow * pWindow ) {
const auto PWINDOW = pWindow ? pWindow : g_pCompositor - > m_pLastWindow ;
if ( ! g_pCompositor - > windowValidMapped ( PWINDOW ) )
return ;
if ( ! PWINDOW - > m_bIsFloating ) {
Debug : : log ( LOG , " Dwindle cannot move a tiled window in moveActiveWindow! " ) ;
return ;
}
PWINDOW - > m_vRealPosition = PWINDOW - > m_vRealPosition . goalv ( ) + delta ;
g_pHyprRenderer - > damageWindow ( PWINDOW ) ;
2022-09-25 20:07:48 +02:00
}