2022-07-27 12:32:00 +02:00
# include "Monitor.hpp"
# include "../Compositor.hpp"
2023-03-24 20:23:16 +01:00
int ratHandler ( void * data ) {
g_pHyprRenderer - > renderMonitor ( ( CMonitor * ) data ) ;
return 1 ;
}
2023-04-07 13:18:40 +02:00
CMonitor : : CMonitor ( ) {
wlr_damage_ring_init ( & damage ) ;
}
CMonitor : : ~ CMonitor ( ) {
wlr_damage_ring_finish ( & damage ) ;
}
2022-07-27 12:32:00 +02:00
void CMonitor : : onConnect ( bool noRule ) {
2022-11-19 14:14:55 +01:00
hyprListener_monitorDestroy . removeCallback ( ) ;
hyprListener_monitorFrame . removeCallback ( ) ;
2022-11-19 17:28:04 +01:00
hyprListener_monitorStateRequest . removeCallback ( ) ;
2023-04-07 17:31:51 +02:00
hyprListener_monitorDamage . removeCallback ( ) ;
2023-04-07 18:25:56 +02:00
hyprListener_monitorNeedsFrame . removeCallback ( ) ;
2023-04-12 22:40:51 +02:00
hyprListener_monitorCommit . removeCallback ( ) ;
2022-11-19 14:14:55 +01:00
hyprListener_monitorFrame . initCallback ( & output - > events . frame , & Events : : listener_monitorFrame , this ) ;
hyprListener_monitorDestroy . initCallback ( & output - > events . destroy , & Events : : listener_monitorDestroy , this ) ;
2022-11-19 17:28:04 +01:00
hyprListener_monitorStateRequest . initCallback ( & output - > events . request_state , & Events : : listener_monitorStateRequest , this ) ;
2023-04-07 17:31:51 +02:00
hyprListener_monitorDamage . initCallback ( & output - > events . damage , & Events : : listener_monitorDamage , this ) ;
2023-04-07 18:25:56 +02:00
hyprListener_monitorNeedsFrame . initCallback ( & output - > events . needs_frame , & Events : : listener_monitorNeedsFrame , this ) ;
2023-04-12 22:40:51 +02:00
hyprListener_monitorCommit . initCallback ( & output - > events . commit , & Events : : listener_monitorCommit , this ) ;
2022-11-19 14:14:55 +01:00
if ( m_bEnabled ) {
wlr_output_enable ( output , 1 ) ;
wlr_output_commit ( output ) ;
2022-08-03 16:05:25 +02:00
return ;
2022-11-19 14:14:55 +01:00
}
2022-08-03 16:05:25 +02:00
2022-08-10 13:44:04 +02:00
szName = output - > name ;
2022-11-05 19:04:44 +01:00
if ( ! wlr_backend_is_drm ( output - > backend ) )
createdByUser = true ; // should be true. WL, X11 and Headless backends should be addable / removable
2022-07-27 12:32:00 +02:00
// get monitor rule that matches
2022-10-05 11:22:33 +02:00
SMonitorRule monitorRule = g_pConfigManager - > getMonitorRuleFor ( output - > name , output - > description ? output - > description : " " ) ;
2022-07-27 12:32:00 +02:00
// if it's disabled, disable and ignore
if ( monitorRule . disabled ) {
2022-08-10 13:31:58 +02:00
wlr_output_set_scale ( output , 1 ) ;
wlr_output_set_transform ( output , WL_OUTPUT_TRANSFORM_NORMAL ) ;
auto PREFSTATE = wlr_output_preferred_mode ( output ) ;
if ( ! PREFSTATE ) {
wlr_output_mode * mode ;
wl_list_for_each ( mode , & output - > modes , link ) {
wlr_output_set_mode ( output , PREFSTATE ) ;
if ( ! wlr_output_test ( output ) )
continue ;
2022-09-25 20:07:48 +02:00
2022-08-10 13:31:58 +02:00
PREFSTATE = mode ;
break ;
}
}
if ( PREFSTATE )
wlr_output_set_mode ( output , PREFSTATE ) ;
2022-08-10 13:44:04 +02:00
else
2022-08-10 13:45:20 +02:00
Debug : : log ( WARN , " No mode found for disabled output %s " , output - > name ) ;
2022-08-10 13:31:58 +02:00
2022-07-27 12:32:00 +02:00
wlr_output_enable ( output , 0 ) ;
2022-09-25 20:07:48 +02:00
2022-08-10 13:44:04 +02:00
if ( ! wlr_output_commit ( output ) ) {
Debug : : log ( ERR , " Couldn't commit disabled state on output %s " , output - > name ) ;
}
Events : : listener_change ( nullptr , nullptr ) ;
2022-07-27 12:32:00 +02:00
2022-08-10 13:31:58 +02:00
m_bEnabled = false ;
2022-07-27 12:32:00 +02:00
hyprListener_monitorFrame . removeCallback ( ) ;
return ;
}
2022-08-27 23:10:13 +02:00
if ( output - > non_desktop ) {
Debug : : log ( LOG , " Not configuring non-desktop output " ) ;
2022-12-16 18:17:31 +01:00
if ( g_pCompositor - > m_sWRLDRMLeaseMgr ) {
wlr_drm_lease_v1_manager_offer_output ( g_pCompositor - > m_sWRLDRMLeaseMgr , output ) ;
}
return ;
}
2022-08-27 23:10:13 +02:00
2022-08-10 13:44:04 +02:00
if ( ! m_bRenderingInitPassed ) {
2022-09-19 21:45:00 +02:00
output - > allocator = nullptr ;
2022-12-16 18:17:31 +01:00
output - > renderer = nullptr ;
2022-08-10 13:44:04 +02:00
wlr_output_init_render ( output , g_pCompositor - > m_sWLRAllocator , g_pCompositor - > m_sWLRRenderer ) ;
m_bRenderingInitPassed = true ;
}
2022-08-03 17:42:19 +02:00
if ( ! m_pThisWrap ) {
// find the wrap
for ( auto & m : g_pCompositor - > m_vRealMonitors ) {
if ( m - > ID = = ID ) {
m_pThisWrap = & m ;
break ;
}
}
}
2022-12-16 18:17:31 +01:00
if ( std : : find_if ( g_pCompositor - > m_vMonitors . begin ( ) , g_pCompositor - > m_vMonitors . end ( ) , [ & ] ( auto & other ) { return other . get ( ) = = this ; } ) = = g_pCompositor - > m_vMonitors . end ( ) ) {
2022-07-27 12:32:00 +02:00
g_pCompositor - > m_vMonitors . push_back ( * m_pThisWrap ) ;
}
2022-09-25 20:07:48 +02:00
2022-07-27 12:32:00 +02:00
m_bEnabled = true ;
// create it in the arr
vecPosition = monitorRule . offset ;
2022-12-16 18:17:31 +01:00
vecSize = monitorRule . resolution ;
2022-07-27 12:32:00 +02:00
refreshRate = monitorRule . refreshRate ;
wlr_output_enable ( output , 1 ) ;
// set mode, also applies
if ( ! noRule )
g_pHyprRenderer - > applyMonitorRule ( this , & monitorRule , true ) ;
2023-04-07 13:18:40 +02:00
wlr_damage_ring_set_bounds ( & damage , vecTransformedSize . x , vecTransformedSize . y ) ;
2022-12-15 18:17:15 +01:00
wlr_xcursor_manager_load ( g_pCompositor - > m_sWLRXCursorMgr , scale ) ;
2023-04-17 18:35:28 +02:00
Debug : : log ( LOG , " Added new monitor with name %s at %i,%i with size %ix%i, pointer %lx " , output - > name , ( int ) vecPosition . x , ( int ) vecPosition . y , ( int ) vecPixelSize . x ,
2022-12-16 18:17:31 +01:00
( int ) vecPixelSize . y , output ) ;
2022-07-27 12:32:00 +02:00
// add a WLR workspace group
if ( ! pWLRWorkspaceGroupHandle ) {
pWLRWorkspaceGroupHandle = wlr_ext_workspace_group_handle_v1_create ( g_pCompositor - > m_sWLREXTWorkspaceMgr ) ;
}
2022-09-25 20:07:48 +02:00
2022-07-27 12:32:00 +02:00
wlr_ext_workspace_group_handle_v1_output_enter ( pWLRWorkspaceGroupHandle , output ) ;
2022-09-25 20:07:48 +02:00
2022-09-13 15:25:42 +02:00
setupDefaultWS ( monitorRule ) ;
2022-07-27 12:32:00 +02:00
scale = monitorRule . scale ;
2023-04-04 23:54:35 +02:00
if ( scale < 0.1 )
scale = getDefaultScale ( ) ;
2022-07-27 12:32:00 +02:00
2022-08-03 17:42:19 +02:00
m_pThisWrap = nullptr ;
2022-12-16 18:17:31 +01:00
forceFullFrames = 3 ; // force 3 full frames to make sure there is no blinking due to double-buffering.
2022-07-27 12:32:00 +02:00
//
2022-11-19 17:41:36 +01:00
g_pEventManager - > postEvent ( SHyprIPCEvent { " monitoradded " , szName } ) ;
2023-02-19 21:54:53 +01:00
EMIT_HOOK_EVENT ( " monitorAdded " , this ) ;
2022-11-19 17:41:36 +01:00
2022-12-16 18:17:31 +01:00
if ( ! g_pCompositor - > m_pLastMonitor ) // set the last monitor if it isnt set yet
2022-11-19 17:41:36 +01:00
g_pCompositor - > setActiveMonitor ( this ) ;
2022-07-27 12:32:00 +02:00
2022-08-10 21:22:11 +02:00
wlr_xcursor_manager_load ( g_pCompositor - > m_sWLRXCursorMgr , scale ) ;
2022-08-10 21:54:09 +02:00
g_pHyprRenderer - > arrangeLayersForMonitor ( ID ) ;
g_pLayoutManager - > getCurrentLayout ( ) - > recalculateMonitor ( ID ) ;
2022-10-22 22:45:17 +02:00
// ensure VRR (will enable if necessary)
2022-10-29 00:48:48 +02:00
g_pConfigManager - > ensureVRR ( this ) ;
2022-12-12 21:51:20 +01:00
// verify last mon valid
bool found = false ;
for ( auto & m : g_pCompositor - > m_vMonitors ) {
if ( m . get ( ) = = g_pCompositor - > m_pLastMonitor ) {
found = true ;
break ;
}
}
if ( ! found )
g_pCompositor - > setActiveMonitor ( this ) ;
2023-03-24 20:23:16 +01:00
renderTimer = wl_event_loop_add_timer ( g_pCompositor - > m_sWLEventLoop , ratHandler , this ) ;
2022-07-27 12:32:00 +02:00
}
void CMonitor : : onDisconnect ( ) {
2022-08-03 16:05:25 +02:00
2023-03-24 20:23:16 +01:00
if ( renderTimer ) {
wl_event_source_remove ( renderTimer ) ;
renderTimer = nullptr ;
}
2022-10-06 19:43:50 +02:00
if ( ! m_bEnabled | | g_pCompositor - > m_bIsShuttingDown )
2022-08-03 16:05:25 +02:00
return ;
2022-11-19 14:01:32 +01:00
Debug : : log ( LOG , " onDisconnect called for %s " , output - > name ) ;
2022-07-27 12:32:00 +02:00
// Cleanup everything. Move windows back, snap cursor, shit.
CMonitor * BACKUPMON = nullptr ;
for ( auto & m : g_pCompositor - > m_vMonitors ) {
if ( m . get ( ) ! = this ) {
BACKUPMON = m . get ( ) ;
break ;
}
}
2022-09-13 15:25:42 +02:00
// remove mirror
if ( pMirrorOf ) {
pMirrorOf - > mirrors . erase ( std : : find_if ( pMirrorOf - > mirrors . begin ( ) , pMirrorOf - > mirrors . end ( ) , [ & ] ( const auto & other ) { return other = = this ; } ) ) ;
pMirrorOf = nullptr ;
}
if ( ! mirrors . empty ( ) ) {
for ( auto & m : mirrors ) {
m - > setMirror ( " " ) ;
}
g_pConfigManager - > m_bWantsMonitorReload = true ;
}
2022-12-16 18:17:31 +01:00
m_bEnabled = false ;
2022-08-10 23:19:15 +02:00
m_bRenderingInitPassed = false ;
2022-07-27 12:32:00 +02:00
hyprListener_monitorFrame . removeCallback ( ) ;
2023-04-07 17:31:51 +02:00
hyprListener_monitorDamage . removeCallback ( ) ;
2023-04-07 18:25:56 +02:00
hyprListener_monitorNeedsFrame . removeCallback ( ) ;
2023-04-12 22:40:51 +02:00
hyprListener_monitorCommit . removeCallback ( ) ;
2022-07-27 12:32:00 +02:00
2023-01-02 16:16:28 +01:00
for ( size_t i = 0 ; i < 4 ; + + i ) {
2023-01-22 17:03:25 +01:00
for ( auto & ls : m_aLayerSurfaceLayers [ i ] ) {
2023-01-23 19:23:44 +01:00
if ( ls - > layerSurface & & ! ls - > fadingOut )
wlr_layer_surface_v1_destroy ( ls - > layerSurface ) ;
2023-01-02 16:16:28 +01:00
}
2023-01-22 17:03:25 +01:00
m_aLayerSurfaceLayers [ i ] . clear ( ) ;
2023-01-02 16:16:28 +01:00
}
2023-01-19 16:27:04 +01:00
Debug : : log ( LOG , " Removed monitor %s! " , szName . c_str ( ) ) ;
g_pEventManager - > postEvent ( SHyprIPCEvent { " monitorremoved " , szName } ) ;
2023-02-19 21:54:53 +01:00
EMIT_HOOK_EVENT ( " monitorRemoved " , this ) ;
2023-01-19 16:27:04 +01:00
2022-08-10 21:54:09 +02:00
if ( ! BACKUPMON ) {
Debug : : log ( WARN , " Unplugged last monitor, entering an unsafe state. Good luck my friend. " ) ;
2022-11-19 17:28:04 +01:00
hyprListener_monitorStateRequest . removeCallback ( ) ;
2022-08-10 21:54:09 +02:00
hyprListener_monitorDestroy . removeCallback ( ) ;
g_pCompositor - > m_bUnsafeState = true ;
2023-03-16 17:33:27 +01:00
std : : erase_if ( g_pCompositor - > m_vMonitors , [ & ] ( std : : shared_ptr < CMonitor > & el ) { return el . get ( ) = = this ; } ) ;
2022-08-10 21:54:09 +02:00
return ;
}
2022-07-27 12:32:00 +02:00
// snap cursor
2022-12-16 18:17:31 +01:00
wlr_cursor_warp ( g_pCompositor - > m_sWLRCursor , nullptr , BACKUPMON - > vecPosition . x + BACKUPMON - > vecTransformedSize . x / 2.f ,
BACKUPMON - > vecPosition . y + BACKUPMON - > vecTransformedSize . y / 2.f ) ;
2022-07-27 12:32:00 +02:00
// move workspaces
std : : deque < CWorkspace * > wspToMove ;
for ( auto & w : g_pCompositor - > m_vWorkspaces ) {
if ( w - > m_iMonitorID = = ID ) {
wspToMove . push_back ( w . get ( ) ) ;
}
}
for ( auto & w : wspToMove ) {
g_pCompositor - > moveWorkspaceToMonitor ( w , BACKUPMON ) ;
w - > startAnim ( true , true , true ) ;
}
activeWorkspace = - 1 ;
wlr_output_layout_remove ( g_pCompositor - > m_sWLROutputLayout , output ) ;
wlr_output_enable ( output , false ) ;
wlr_output_commit ( output ) ;
2022-11-17 22:52:45 +01:00
std : : erase_if ( g_pCompositor - > m_vWorkspaces , [ & ] ( std : : unique_ptr < CWorkspace > & el ) { return el - > m_iMonitorID = = ID ; } ) ;
2022-07-27 12:32:00 +02:00
2022-12-21 16:17:24 +01:00
if ( g_pCompositor - > m_pLastMonitor = = this )
g_pCompositor - > setActiveMonitor ( BACKUPMON ) ;
2022-12-22 13:15:00 +01:00
if ( g_pHyprRenderer - > m_pMostHzMonitor = = this ) {
int mostHz = 0 ;
CMonitor * pMonitorMostHz = nullptr ;
for ( auto & m : g_pCompositor - > m_vMonitors ) {
if ( m - > refreshRate > mostHz & & m . get ( ) ! = this ) {
pMonitorMostHz = m . get ( ) ;
mostHz = m - > refreshRate ;
}
}
g_pHyprRenderer - > m_pMostHzMonitor = pMonitorMostHz ;
}
2022-11-17 22:52:45 +01:00
std : : erase_if ( g_pCompositor - > m_vMonitors , [ & ] ( std : : shared_ptr < CMonitor > & el ) { return el . get ( ) = = this ; } ) ;
2022-07-27 12:32:00 +02:00
}
2022-08-23 16:07:47 +02:00
2023-04-07 17:31:51 +02:00
void CMonitor : : addDamage ( const pixman_region32_t * rg ) {
2023-04-16 15:48:38 +02:00
static auto * const PZOOMFACTOR = & g_pConfigManager - > getConfigValuePtr ( " misc:cursor_zoom_factor " ) - > floatValue ;
if ( * PZOOMFACTOR ! = 1.f & & g_pCompositor - > getMonitorFromCursor ( ) = = this ) {
wlr_damage_ring_add_whole ( & damage ) ;
g_pCompositor - > scheduleFrameForMonitor ( this ) ;
}
2023-04-07 18:25:56 +02:00
if ( wlr_damage_ring_add ( & damage , rg ) )
g_pCompositor - > scheduleFrameForMonitor ( this ) ;
2022-08-23 16:07:47 +02:00
}
2023-04-07 17:31:51 +02:00
void CMonitor : : addDamage ( const wlr_box * box ) {
2023-04-16 15:48:38 +02:00
static auto * const PZOOMFACTOR = & g_pConfigManager - > getConfigValuePtr ( " misc:cursor_zoom_factor " ) - > floatValue ;
if ( * PZOOMFACTOR ! = 1.f & & g_pCompositor - > getMonitorFromCursor ( ) = = this ) {
wlr_damage_ring_add_whole ( & damage ) ;
g_pCompositor - > scheduleFrameForMonitor ( this ) ;
}
2023-04-07 18:25:56 +02:00
if ( wlr_damage_ring_add_box ( & damage , box ) )
g_pCompositor - > scheduleFrameForMonitor ( this ) ;
2022-08-23 16:07:47 +02:00
}
2022-09-13 15:25:42 +02:00
bool CMonitor : : isMirror ( ) {
return pMirrorOf ! = nullptr ;
}
2022-12-09 18:17:02 +01:00
int CMonitor : : findAvailableDefaultWS ( ) {
for ( size_t i = 1 ; i < INT32_MAX ; + + i ) {
if ( g_pCompositor - > getWorkspaceByID ( i ) )
continue ;
if ( const auto BOUND = g_pConfigManager - > getBoundMonitorStringForWS ( std : : to_string ( i ) ) ; ! BOUND . empty ( ) & & BOUND ! = szName )
continue ;
2022-12-16 18:17:31 +01:00
2022-12-09 18:17:02 +01:00
return i ;
}
return INT32_MAX ; // shouldn't be reachable
}
2022-09-13 15:25:42 +02:00
void CMonitor : : setupDefaultWS ( const SMonitorRule & monitorRule ) {
// Workspace
std : : string newDefaultWorkspaceName = " " ;
2023-03-18 17:12:43 +01:00
int64_t WORKSPACEID = g_pConfigManager - > getDefaultWorkspaceFor ( szName ) . empty ( ) ?
findAvailableDefaultWS ( ) :
getWorkspaceIDFromString ( g_pConfigManager - > getDefaultWorkspaceFor ( szName ) , newDefaultWorkspaceName ) ;
2022-09-13 15:25:42 +02:00
2022-11-27 23:42:22 +01:00
if ( WORKSPACEID = = INT_MAX | | ( WORKSPACEID > = SPECIAL_WORKSPACE_START & & WORKSPACEID < = - 2 ) ) {
2022-12-16 18:17:31 +01:00
WORKSPACEID = g_pCompositor - > m_vWorkspaces . size ( ) + 1 ;
2022-09-13 15:25:42 +02:00
newDefaultWorkspaceName = std : : to_string ( WORKSPACEID ) ;
2023-03-18 17:12:43 +01:00
Debug : : log ( LOG , " Invalid workspace= directive name in monitor parsing, workspace name \" %s \" is invalid. " , g_pConfigManager - > getDefaultWorkspaceFor ( szName ) . c_str ( ) ) ;
2022-09-13 15:25:42 +02:00
}
auto PNEWWORKSPACE = g_pCompositor - > getWorkspaceByID ( WORKSPACEID ) ;
Debug : : log ( LOG , " New monitor: WORKSPACEID %d, exists: %d " , WORKSPACEID , ( int ) ( PNEWWORKSPACE ! = nullptr ) ) ;
if ( PNEWWORKSPACE ) {
// workspace exists, move it to the newly connected monitor
g_pCompositor - > moveWorkspaceToMonitor ( PNEWWORKSPACE , this ) ;
activeWorkspace = PNEWWORKSPACE - > m_iID ;
g_pLayoutManager - > getCurrentLayout ( ) - > recalculateMonitor ( ID ) ;
PNEWWORKSPACE - > startAnim ( true , true , true ) ;
} else {
if ( newDefaultWorkspaceName = = " " )
newDefaultWorkspaceName = std : : to_string ( WORKSPACEID ) ;
PNEWWORKSPACE = g_pCompositor - > m_vWorkspaces . emplace_back ( std : : make_unique < CWorkspace > ( ID , newDefaultWorkspaceName ) ) . get ( ) ;
// We are required to set the name here immediately
wlr_ext_workspace_handle_v1_set_name ( PNEWWORKSPACE - > m_pWlrHandle , newDefaultWorkspaceName . c_str ( ) ) ;
PNEWWORKSPACE - > m_iID = WORKSPACEID ;
}
activeWorkspace = PNEWWORKSPACE - > m_iID ;
g_pCompositor - > deactivateAllWLRWorkspaces ( PNEWWORKSPACE - > m_pWlrHandle ) ;
PNEWWORKSPACE - > setActive ( true ) ;
}
void CMonitor : : setMirror ( const std : : string & mirrorOf ) {
const auto PMIRRORMON = g_pCompositor - > getMonitorFromString ( mirrorOf ) ;
if ( PMIRRORMON = = pMirrorOf )
return ;
if ( PMIRRORMON & & PMIRRORMON - > isMirror ( ) ) {
Debug : : log ( ERR , " Cannot mirror a mirror! " ) ;
return ;
}
if ( PMIRRORMON = = this ) {
Debug : : log ( ERR , " Cannot mirror self! " ) ;
return ;
}
if ( ! PMIRRORMON ) {
// disable mirroring
if ( pMirrorOf ) {
pMirrorOf - > mirrors . erase ( std : : find_if ( pMirrorOf - > mirrors . begin ( ) , pMirrorOf - > mirrors . end ( ) , [ & ] ( const auto & other ) { return other = = this ; } ) ) ;
}
pMirrorOf = nullptr ;
// set rule
2022-10-05 11:22:33 +02:00
const auto RULE = g_pConfigManager - > getMonitorRuleFor ( this - > szName , this - > output - > description ? this - > output - > description : " " ) ;
2022-09-13 15:25:42 +02:00
vecPosition = RULE . offset ;
// push to mvmonitors
if ( ! m_pThisWrap ) {
// find the wrap
for ( auto & m : g_pCompositor - > m_vRealMonitors ) {
if ( m - > ID = = ID ) {
m_pThisWrap = & m ;
break ;
}
}
}
2022-12-16 18:17:31 +01:00
if ( std : : find_if ( g_pCompositor - > m_vMonitors . begin ( ) , g_pCompositor - > m_vMonitors . end ( ) , [ & ] ( auto & other ) { return other . get ( ) = = this ; } ) = =
g_pCompositor - > m_vMonitors . end ( ) ) {
2022-09-13 15:25:42 +02:00
g_pCompositor - > m_vMonitors . push_back ( * m_pThisWrap ) ;
}
setupDefaultWS ( RULE ) ;
2022-11-19 17:58:14 +01:00
g_pHyprRenderer - > applyMonitorRule ( this , ( SMonitorRule * ) & RULE , true ) ; // will apply the offset and stuff
2022-09-13 15:25:42 +02:00
} else {
CMonitor * BACKUPMON = nullptr ;
for ( auto & m : g_pCompositor - > m_vMonitors ) {
if ( m . get ( ) ! = this ) {
BACKUPMON = m . get ( ) ;
break ;
}
}
// move all the WS
std : : deque < CWorkspace * > wspToMove ;
for ( auto & w : g_pCompositor - > m_vWorkspaces ) {
if ( w - > m_iMonitorID = = ID ) {
wspToMove . push_back ( w . get ( ) ) ;
}
}
for ( auto & w : wspToMove ) {
g_pCompositor - > moveWorkspaceToMonitor ( w , BACKUPMON ) ;
w - > startAnim ( true , true , true ) ;
}
activeWorkspace = - 1 ;
wlr_output_layout_remove ( g_pCompositor - > m_sWLROutputLayout , output ) ;
2023-03-04 01:48:02 +01:00
vecPosition = PMIRRORMON - > vecPosition ;
2022-09-13 15:25:42 +02:00
pMirrorOf = PMIRRORMON ;
pMirrorOf - > mirrors . push_back ( this ) ;
// remove from mvmonitors
2022-12-16 18:17:31 +01:00
std : : erase_if ( g_pCompositor - > m_vMonitors , [ & ] ( const auto & other ) { return other . get ( ) = = this ; } ) ;
2022-09-13 15:25:42 +02:00
2022-11-19 17:41:36 +01:00
g_pCompositor - > setActiveMonitor ( g_pCompositor - > m_vMonitors . front ( ) . get ( ) ) ;
2022-12-26 13:26:53 +01:00
g_pCompositor - > sanityCheckWorkspaces ( ) ;
2022-09-13 15:25:42 +02:00
}
2022-09-19 20:44:33 +02:00
}
2022-12-14 18:57:18 +01:00
float CMonitor : : getDefaultScale ( ) {
if ( ! m_bEnabled )
return 1 ;
static constexpr double MMPERINCH = 25.4 ;
2022-12-16 18:17:31 +01:00
const auto DIAGONALPX = sqrt ( pow ( vecPixelSize . x , 2 ) + pow ( vecPixelSize . y , 2 ) ) ;
const auto DIAGONALIN = sqrt ( pow ( output - > phys_width / MMPERINCH , 2 ) + pow ( output - > phys_height / MMPERINCH , 2 ) ) ;
2022-12-14 18:57:18 +01:00
2022-12-16 18:17:31 +01:00
const auto PPI = DIAGONALPX / DIAGONALIN ;
2022-12-14 18:57:18 +01:00
if ( PPI > 200 /* High PPI, 2x*/ )
return 2 ;
2022-12-20 14:33:29 +01:00
else if ( PPI > 140 /* Medium PPI, 1.5x*/ )
2022-12-14 18:57:18 +01:00
return 1.5 ;
return 1 ;
}
2023-04-14 16:03:53 +02:00
void CMonitor : : changeWorkspace ( CWorkspace * const pWorkspace , bool internal ) {
2023-04-14 16:28:22 +02:00
if ( ! pWorkspace )
2023-04-14 16:03:53 +02:00
return ;
2023-04-17 14:32:35 +02:00
if ( pWorkspace - > m_bIsSpecialWorkspace ) {
Debug : : log ( ERR , " BUG THIS: Attempted to changeWorkspace to special! " ) ;
return ;
}
2023-04-14 16:28:22 +02:00
if ( pWorkspace - > m_iID = = activeWorkspace ) {
// in some cases (e.g. workspace from one monitor to another)
// we need to send this
g_pCompositor - > deactivateAllWLRWorkspaces ( pWorkspace - > m_pWlrHandle ) ;
pWorkspace - > setActive ( true ) ;
return ;
}
2023-04-14 16:03:53 +02:00
const auto POLDWORKSPACE = g_pCompositor - > getWorkspaceByID ( activeWorkspace ) ;
activeWorkspace = pWorkspace - > m_iID ;
if ( ! internal ) {
const auto ANIMTOLEFT = pWorkspace - > m_iID > POLDWORKSPACE - > m_iID ;
POLDWORKSPACE - > startAnim ( false , ANIMTOLEFT ) ;
pWorkspace - > startAnim ( true , ANIMTOLEFT ) ;
// move pinned windows
for ( auto & w : g_pCompositor - > m_vWindows ) {
if ( w - > m_iWorkspaceID = = POLDWORKSPACE - > m_iID & & w - > m_bPinned ) {
w - > m_iWorkspaceID = pWorkspace - > m_iID ;
}
}
if ( const auto PLASTWINDOW = pWorkspace - > getLastFocusedWindow ( ) ; PLASTWINDOW )
g_pCompositor - > focusWindow ( PLASTWINDOW ) ;
else {
g_pCompositor - > focusWindow ( nullptr ) ;
g_pInputManager - > refocus ( ) ;
}
2023-04-16 02:11:57 +02:00
g_pLayoutManager - > getCurrentLayout ( ) - > recalculateMonitor ( ID ) ;
2023-04-14 16:03:53 +02:00
// set some flags and fire event
2023-04-14 16:28:22 +02:00
g_pCompositor - > deactivateAllWLRWorkspaces ( pWorkspace - > m_pWlrHandle ) ;
2023-04-14 16:03:53 +02:00
pWorkspace - > setActive ( true ) ;
g_pEventManager - > postEvent ( SHyprIPCEvent { " workspace " , pWorkspace - > m_szName } ) ;
EMIT_HOOK_EVENT ( " workspace " , pWorkspace ) ;
}
2023-04-15 17:16:33 +02:00
g_pHyprRenderer - > damageMonitor ( this ) ;
2023-04-30 02:12:20 +02:00
g_pCompositor - > updateFullscreenFadeOnWorkspace ( pWorkspace ) ;
2023-04-14 16:03:53 +02:00
}
void CMonitor : : changeWorkspace ( const int & id , bool internal ) {
changeWorkspace ( g_pCompositor - > getWorkspaceByID ( id ) , internal ) ;
}
void CMonitor : : setSpecialWorkspace ( CWorkspace * const pWorkspace ) {
2023-04-15 17:16:33 +02:00
g_pHyprRenderer - > damageMonitor ( this ) ;
2023-04-14 16:03:53 +02:00
if ( ! pWorkspace ) {
// remove special if exists
if ( const auto EXISTINGSPECIAL = g_pCompositor - > getWorkspaceByID ( specialWorkspaceID ) ; EXISTINGSPECIAL )
EXISTINGSPECIAL - > startAnim ( false , false ) ;
specialWorkspaceID = 0 ;
g_pLayoutManager - > getCurrentLayout ( ) - > recalculateMonitor ( ID ) ;
const auto PWORKSPACE = g_pCompositor - > getWorkspaceByID ( activeWorkspace ) ;
if ( const auto PLAST = PWORKSPACE - > getLastFocusedWindow ( ) ; PLAST )
g_pCompositor - > focusWindow ( PLAST ) ;
else
g_pInputManager - > refocus ( ) ;
return ;
}
// open special
2023-04-17 23:58:59 +02:00
pWorkspace - > m_iMonitorID = ID ;
specialWorkspaceID = pWorkspace - > m_iID ;
2023-04-14 16:03:53 +02:00
pWorkspace - > startAnim ( true , true ) ;
g_pLayoutManager - > getCurrentLayout ( ) - > recalculateMonitor ( ID ) ;
if ( const auto PLAST = pWorkspace - > getLastFocusedWindow ( ) ; PLAST )
g_pCompositor - > focusWindow ( PLAST ) ;
else
g_pInputManager - > refocus ( ) ;
}
void CMonitor : : setSpecialWorkspace ( const int & id ) {
setSpecialWorkspace ( g_pCompositor - > getWorkspaceByID ( id ) ) ;
}