2022-03-20 16:51:14 +01:00
# include "HyprCtl.hpp"
2022-03-21 18:29:41 +01:00
# include <netinet/in.h>
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <sys/socket.h>
2022-03-20 16:51:14 +01:00
# include <sys/stat.h>
2022-03-21 18:29:41 +01:00
# include <sys/types.h>
2022-05-24 19:42:43 +02:00
# include <sys/un.h>
2022-03-20 16:51:14 +01:00
# include <unistd.h>
2022-03-30 16:24:42 +02:00
# include <errno.h>
2022-03-20 16:51:14 +01:00
2023-01-31 01:03:23 +01:00
# include <sstream>
2022-03-20 16:51:14 +01:00
# include <string>
2023-05-24 17:46:56 +02:00
static void trimTrailingComma ( std : : string & str ) {
if ( ! str . empty ( ) & & str . back ( ) = = ' , ' )
str . pop_back ( ) ;
}
2023-06-02 13:25:33 +02:00
static std : : string getWorkspaceNameFromSpecialID ( const int workspaceID ) {
if ( workspaceID = = 0 )
return " " ;
const auto * workspace = g_pCompositor - > getWorkspaceByID ( workspaceID ) ;
if ( ! workspace )
return " " ;
return workspace - > m_szName ;
}
2022-07-12 22:59:36 +02:00
std : : string monitorsRequest ( HyprCtl : : eHyprCtlOutputFormat format ) {
2022-03-20 16:51:14 +01:00
std : : string result = " " ;
2022-07-12 22:59:36 +02:00
if ( format = = HyprCtl : : FORMAT_JSON ) {
2022-07-12 19:57:33 +02:00
result + = " [ " ;
2022-09-25 20:07:48 +02:00
2022-07-12 19:57:33 +02:00
for ( auto & m : g_pCompositor - > m_vMonitors ) {
2023-03-16 01:18:39 +01:00
if ( ! m - > output )
continue ;
2022-07-12 19:57:33 +02:00
result + = getFormat (
2023-09-06 12:51:36 +02:00
R " #({{
" id " : { } ,
" name " : " {} " ,
" description " : " {} " ,
" make " : " {} " ,
" model " : " {} " ,
" serial " : " {} " ,
" width " : { } ,
" height " : { } ,
" refreshRate " : { : .5f } ,
" x " : { } ,
" y " : { } ,
" activeWorkspace " : { {
" id " : { } ,
" name " : " {} "
} } ,
" specialWorkspace " : { {
" id " : { } ,
" name " : " {} "
} } ,
" reserved " : [ { } , { } , { } , { } ] ,
" scale " : { : .2f } ,
" transform " : { } ,
" focused " : { } ,
" dpmsStatus " : { } ,
" vrr " : { }
} } , ) # " ,
2023-09-06 21:45:37 +02:00
m - > ID , escapeJSONStrings ( m - > szName ) , escapeJSONStrings ( m - > output - > description ? m - > output - > description : " " ) , ( m - > output - > make ? m - > output - > make : " " ) ,
( m - > output - > model ? m - > output - > model : " " ) , ( m - > output - > serial ? m - > output - > serial : " " ) , ( int ) m - > vecPixelSize . x , ( int ) m - > vecPixelSize . y , m - > refreshRate ,
( int ) m - > vecPosition . x , ( int ) m - > vecPosition . y , m - > activeWorkspace , escapeJSONStrings ( g_pCompositor - > getWorkspaceByID ( m - > activeWorkspace ) - > m_szName ) ,
m - > specialWorkspaceID , escapeJSONStrings ( getWorkspaceNameFromSpecialID ( m - > specialWorkspaceID ) ) , ( int ) m - > vecReservedTopLeft . x , ( int ) m - > vecReservedTopLeft . y ,
2022-12-16 18:17:31 +01:00
( int ) m - > vecReservedBottomRight . x , ( int ) m - > vecReservedBottomRight . y , m - > scale , ( int ) m - > transform , ( m . get ( ) = = g_pCompositor - > m_pLastMonitor ? " true " : " false " ) ,
2023-02-16 23:20:10 +01:00
( m - > dpmsStatus ? " true " : " false " ) , ( m - > output - > adaptive_sync_status = = WLR_OUTPUT_ADAPTIVE_SYNC_ENABLED ? " true " : " false " ) ) ;
2022-07-12 19:57:33 +02:00
}
2023-05-24 17:46:56 +02:00
trimTrailingComma ( result ) ;
2022-07-12 19:57:33 +02:00
result + = " ] " ;
} else {
for ( auto & m : g_pCompositor - > m_vMonitors ) {
2023-03-16 01:18:39 +01:00
if ( ! m - > output )
continue ;
2023-09-06 21:45:37 +02:00
result + =
getFormat ( " Monitor {} (ID {}): \n \t {}x{}@{:.5f} at {}x{} \n \t description: {} \n \t make: {} \n \t model: {} \n \t serial: {} \n \t active workspace: {} ({}) \n \t special "
" workspace: {} ({}) \n \t reserved: {} "
" {} {} {} \n \t scale: {:.2f} \n \t transform: "
" {} \n \t focused: {} \n \t dpmsStatus: {} \n \t vrr: {} \n \n " ,
m - > szName , m - > ID , ( int ) m - > vecPixelSize . x , ( int ) m - > vecPixelSize . y , m - > refreshRate , ( int ) m - > vecPosition . x , ( int ) m - > vecPosition . y ,
( m - > output - > description ? m - > output - > description : " " ) , ( m - > output - > make ? m - > output - > make : " " ) , ( m - > output - > model ? m - > output - > model : " " ) ,
( m - > output - > serial ? m - > output - > serial : " " ) , m - > activeWorkspace , g_pCompositor - > getWorkspaceByID ( m - > activeWorkspace ) - > m_szName , m - > specialWorkspaceID ,
getWorkspaceNameFromSpecialID ( m - > specialWorkspaceID ) , ( int ) m - > vecReservedTopLeft . x , ( int ) m - > vecReservedTopLeft . y , ( int ) m - > vecReservedBottomRight . x ,
( int ) m - > vecReservedBottomRight . y , m - > scale , ( int ) m - > transform , ( m . get ( ) = = g_pCompositor - > m_pLastMonitor ? " yes " : " no " ) , ( int ) m - > dpmsStatus ,
( int ) ( m - > output - > adaptive_sync_status = = WLR_OUTPUT_ADAPTIVE_SYNC_ENABLED ) ) ;
2022-07-12 19:57:33 +02:00
}
2022-03-20 16:51:14 +01:00
}
return result ;
}
2022-12-04 22:03:29 +01:00
static std : : string getGroupedData ( CWindow * w , HyprCtl : : eHyprCtlOutputFormat format ) {
const bool isJson = format = = HyprCtl : : FORMAT_JSON ;
2023-02-20 10:28:42 +01:00
if ( ! w - > m_sGroupData . pNextWindow )
2022-12-04 22:03:29 +01:00
return isJson ? " " : " 0 " ;
2023-02-20 10:28:42 +01:00
std : : vector < CWindow * > groupMembers ;
CWindow * curr = w ;
do {
groupMembers . push_back ( curr ) ;
curr = curr - > m_sGroupData . pNextWindow ;
} while ( curr ! = w ) ;
2022-12-04 22:03:29 +01:00
2022-12-16 18:17:31 +01:00
const auto comma = isJson ? " , " : " , " ;
2023-09-06 12:51:36 +02:00
const auto fmt = isJson ? " \" 0x{:x} \" " : " {:x} " ;
2022-12-04 22:03:29 +01:00
std : : ostringstream result ;
2022-12-16 18:17:31 +01:00
bool first = true ;
2022-12-04 22:03:29 +01:00
for ( auto & gw : groupMembers ) {
if ( first )
first = false ;
else
result < < comma ;
2023-09-06 12:51:36 +02:00
result < < getFormat ( fmt , ( uintptr_t ) gw ) ;
2022-12-04 22:03:29 +01:00
}
return result . str ( ) ;
}
2022-11-13 01:39:21 +01:00
static std : : string getWindowData ( CWindow * w , HyprCtl : : eHyprCtlOutputFormat format ) {
2022-07-12 22:59:36 +02:00
if ( format = = HyprCtl : : FORMAT_JSON ) {
2022-11-13 01:39:21 +01:00
return getFormat (
2023-09-06 12:51:36 +02:00
R " #({{
" address " : " 0x{:x} " ,
" mapped " : { } ,
" hidden " : { } ,
" at " : [ { } , { } ] ,
" size " : [ { } , { } ] ,
" workspace " : { {
" id " : { } ,
" name " : " {} "
} } ,
" floating " : { } ,
" monitor " : { } ,
" class " : " {} " ,
" title " : " {} " ,
" initialClass " : " {} " ,
" initialTitle " : " {} " ,
" pid " : { } ,
" xwayland " : { } ,
" pinned " : { } ,
" fullscreen " : { } ,
" fullscreenMode " : { } ,
" fakeFullscreen " : { } ,
" grouped " : [ { } ] ,
" swallowing " : " 0x{:x} "
} } , ) # " ,
( uintptr_t ) w , ( w - > m_bIsMapped ? " true " : " false " ) , ( w - > isHidden ( ) ? " true " : " false " ) , ( int ) w - > m_vRealPosition . goalv ( ) . x , ( int ) w - > m_vRealPosition . goalv ( ) . y ,
2023-02-28 13:41:46 +01:00
( int ) w - > m_vRealSize . goalv ( ) . x , ( int ) w - > m_vRealSize . goalv ( ) . y , w - > m_iWorkspaceID ,
2022-12-16 18:17:31 +01:00
escapeJSONStrings ( w - > m_iWorkspaceID = = - 1 ? " " :
g_pCompositor - > getWorkspaceByID ( w - > m_iWorkspaceID ) ? g_pCompositor - > getWorkspaceByID ( w - > m_iWorkspaceID ) - > m_szName :
2023-09-06 12:51:36 +02:00
std : : string ( " Invalid workspace " + std : : to_string ( w - > m_iWorkspaceID ) ) ) ,
( ( int ) w - > m_bIsFloating = = 1 ? " true " : " false " ) , w - > m_iMonitorID , escapeJSONStrings ( g_pXWaylandManager - > getAppIDClass ( w ) ) ,
escapeJSONStrings ( g_pXWaylandManager - > getTitle ( w ) ) , escapeJSONStrings ( w - > m_szInitialClass ) , escapeJSONStrings ( w - > m_szInitialTitle ) , w - > getPID ( ) ,
2023-04-03 20:16:51 +02:00
( ( int ) w - > m_bIsX11 = = 1 ? " true " : " false " ) , ( w - > m_bPinned ? " true " : " false " ) , ( w - > m_bIsFullscreen ? " true " : " false " ) ,
2023-09-06 12:51:36 +02:00
( w - > m_bIsFullscreen ? ( g_pCompositor - > getWorkspaceByID ( w - > m_iWorkspaceID ) ? ( int ) g_pCompositor - > getWorkspaceByID ( w - > m_iWorkspaceID ) - > m_efFullscreenMode : 0 ) : 0 ) ,
w - > m_bFakeFullscreenState ? " true " : " false " , getGroupedData ( w , format ) , ( uintptr_t ) w - > m_pSwallowed ) ;
2022-11-13 01:39:21 +01:00
} else {
2022-12-16 18:17:31 +01:00
return getFormat (
2023-09-06 12:51:36 +02:00
" Window {:x} -> {}: \n \t mapped: {} \n \t hidden: {} \n \t at: {},{} \n \t size: {},{} \n \t workspace: {} ({}) \n \t floating: {} \n \t monitor: {} \n \t class: {} \n \t title: "
" {} \n \t initialClass: {} \n \t initialTitle: {} \n \t pid: "
" {} \n \t xwayland: {} \n \t pinned: "
" {} \n \t fullscreen: {} \n \t fullscreenmode: {} \n \t fakefullscreen: {} \n \t grouped: {} \n \t swallowing: {:x} \n \n " ,
2023-09-06 21:45:37 +02:00
( uintptr_t ) w , w - > m_szTitle , ( int ) w - > m_bIsMapped , ( int ) w - > isHidden ( ) , ( int ) w - > m_vRealPosition . goalv ( ) . x , ( int ) w - > m_vRealPosition . goalv ( ) . y ,
2023-09-06 12:51:36 +02:00
( int ) w - > m_vRealSize . goalv ( ) . x , ( int ) w - > m_vRealSize . goalv ( ) . y , w - > m_iWorkspaceID ,
2022-12-16 18:17:31 +01:00
( w - > m_iWorkspaceID = = - 1 ? " " :
2023-09-06 21:45:37 +02:00
g_pCompositor - > getWorkspaceByID ( w - > m_iWorkspaceID ) ? g_pCompositor - > getWorkspaceByID ( w - > m_iWorkspaceID ) - > m_szName :
std : : string ( " Invalid workspace " + std : : to_string ( w - > m_iWorkspaceID ) ) ) ,
( int ) w - > m_bIsFloating , w - > m_iMonitorID , g_pXWaylandManager - > getAppIDClass ( w ) , g_pXWaylandManager - > getTitle ( w ) , w - > m_szInitialClass , w - > m_szInitialTitle , w - > getPID ( ) ,
( int ) w - > m_bIsX11 , ( int ) w - > m_bPinned , ( int ) w - > m_bIsFullscreen ,
2022-12-16 18:17:31 +01:00
( w - > m_bIsFullscreen ? ( g_pCompositor - > getWorkspaceByID ( w - > m_iWorkspaceID ) ? g_pCompositor - > getWorkspaceByID ( w - > m_iWorkspaceID ) - > m_efFullscreenMode : 0 ) : 0 ) ,
2023-09-06 21:45:37 +02:00
( int ) w - > m_bFakeFullscreenState , getGroupedData ( w , format ) , ( uintptr_t ) w - > m_pSwallowed ) ;
2022-11-13 01:39:21 +01:00
}
}
std : : string clientsRequest ( HyprCtl : : eHyprCtlOutputFormat format ) {
std : : string result = " " ;
if ( format = = HyprCtl : : FORMAT_JSON ) {
result + = " [ " ;
for ( auto & w : g_pCompositor - > m_vWindows ) {
2023-02-28 13:41:46 +01:00
result + = getWindowData ( w . get ( ) , format ) ;
2022-07-12 19:57:33 +02:00
}
2023-05-24 17:46:56 +02:00
trimTrailingComma ( result ) ;
2022-07-12 19:57:33 +02:00
result + = " ] " ;
} else {
for ( auto & w : g_pCompositor - > m_vWindows ) {
2023-02-28 13:41:46 +01:00
result + = getWindowData ( w . get ( ) , format ) ;
2022-06-27 13:17:11 +02:00
}
2022-03-20 16:51:14 +01:00
}
return result ;
}
2023-05-02 15:51:52 +02:00
static std : : string getWorkspaceData ( CWorkspace * w , HyprCtl : : eHyprCtlOutputFormat format ) {
const auto PLASTW = w - > getLastFocusedWindow ( ) ;
const auto PMONITOR = g_pCompositor - > getMonitorFromID ( w - > m_iMonitorID ) ;
2022-07-12 22:59:36 +02:00
if ( format = = HyprCtl : : FORMAT_JSON ) {
2023-09-06 12:51:36 +02:00
return getFormat ( R " #({{
" id " : { } ,
" name " : " {} " ,
" monitor " : " {} " ,
" windows " : { } ,
" hasfullscreen " : { } ,
" lastwindow " : " 0x{:x} " ,
" lastwindowtitle " : " {} "
} } ) # " ,
2023-09-06 21:45:37 +02:00
w - > m_iID , escapeJSONStrings ( w - > m_szName ) , escapeJSONStrings ( PMONITOR ? PMONITOR - > szName : " ? " ) , g_pCompositor - > getWindowsOnWorkspace ( w - > m_iID ) ,
( ( int ) w - > m_bHasFullscreenWindow = = 1 ? " true " : " false " ) , ( uintptr_t ) PLASTW , PLASTW ? escapeJSONStrings ( PLASTW - > m_szTitle ) : " " ) ;
2023-05-02 15:51:52 +02:00
} else {
2023-09-06 21:45:37 +02:00
return getFormat ( " workspace ID {} ({}) on monitor { } : \ n \ twindows : { } \ n \ thasfullscreen : { } \ n \ tlastwindow : 0 x { : x } \ n \ tlastwindowtitle : { } \ n \ n " , w->m_iID, w->m_szName,
PMONITOR ? PMONITOR - > szName : " ? " , g_pCompositor - > getWindowsOnWorkspace ( w - > m_iID ) , ( int ) w - > m_bHasFullscreenWindow , ( uintptr_t ) PLASTW ,
PLASTW ? PLASTW - > m_szTitle : " " ) ;
2023-05-02 15:51:52 +02:00
}
}
std : : string activeWorkspaceRequest ( HyprCtl : : eHyprCtlOutputFormat format ) {
std : : string result = " " ;
auto w = g_pCompositor - > getWorkspaceByID ( g_pCompositor - > m_pLastMonitor - > activeWorkspace ) ;
return getWorkspaceData ( w , format ) ;
}
std : : string workspacesRequest ( HyprCtl : : eHyprCtlOutputFormat format ) {
std : : string result = " " ;
if ( format = = HyprCtl : : FORMAT_JSON ) {
result + = " [ " ;
for ( auto & w : g_pCompositor - > m_vWorkspaces ) {
result + = getWorkspaceData ( w . get ( ) , format ) ;
result + = " , " ;
2022-07-12 19:57:33 +02:00
}
2023-05-24 17:46:56 +02:00
trimTrailingComma ( result ) ;
2022-07-12 19:57:33 +02:00
result + = " ] " ;
} else {
for ( auto & w : g_pCompositor - > m_vWorkspaces ) {
2023-05-02 15:51:52 +02:00
result + = getWorkspaceData ( w . get ( ) , format ) ;
2022-07-12 19:57:33 +02:00
}
2022-03-20 16:51:14 +01:00
}
2023-05-02 15:51:52 +02:00
2022-03-20 16:51:14 +01:00
return result ;
}
2022-07-12 22:59:36 +02:00
std : : string activeWindowRequest ( HyprCtl : : eHyprCtlOutputFormat format ) {
2022-04-02 18:57:09 +02:00
const auto PWINDOW = g_pCompositor - > m_pLastWindow ;
2022-03-22 16:54:45 +01:00
if ( ! g_pCompositor - > windowValidMapped ( PWINDOW ) )
2022-08-06 21:36:28 +02:00
return format = = HyprCtl : : FORMAT_JSON ? " {} " : " Invalid " ;
2022-11-13 12:12:04 +01:00
auto result = getWindowData ( PWINDOW , format ) ;
2022-12-16 18:17:31 +01:00
2022-11-13 12:12:04 +01:00
if ( format = = HyprCtl : : FORMAT_JSON )
result . pop_back ( ) ;
return result ;
2022-03-22 16:54:45 +01:00
}
2022-07-12 22:59:36 +02:00
std : : string layersRequest ( HyprCtl : : eHyprCtlOutputFormat format ) {
2022-03-22 16:54:45 +01:00
std : : string result = " " ;
2022-07-12 22:59:36 +02:00
if ( format = = HyprCtl : : FORMAT_JSON ) {
2022-07-12 19:57:33 +02:00
result + = " { \n " ;
for ( auto & mon : g_pCompositor - > m_vMonitors ) {
result + = getFormat (
2023-09-06 12:51:36 +02:00
R " #( " { } " : {{
" levels " : { {
2022-07-12 19:57:33 +02:00
) # " ,
2023-09-06 21:45:37 +02:00
escapeJSONStrings ( mon - > szName ) ) ;
2022-07-12 19:57:33 +02:00
int layerLevel = 0 ;
2023-01-22 17:03:25 +01:00
for ( auto & level : mon - > m_aLayerSurfaceLayers ) {
2022-07-12 19:57:33 +02:00
result + = getFormat (
2022-12-16 18:17:31 +01:00
R " #(
2023-09-06 12:51:36 +02:00
" {} " : [
2022-07-12 19:57:33 +02:00
) # " ,
2022-12-16 18:17:31 +01:00
layerLevel ) ;
2022-07-12 19:57:33 +02:00
for ( auto & layer : level ) {
result + = getFormat (
2023-09-06 12:51:36 +02:00
R " #( {{
" address " : " 0x{:x} " ,
" x " : { } ,
" y " : { } ,
" w " : { } ,
" h " : { } ,
" namespace " : " {} "
} } , ) # " ,
2023-09-06 21:45:37 +02:00
( uintptr_t ) layer . get ( ) , layer - > geometry . x , layer - > geometry . y , layer - > geometry . width , layer - > geometry . height , escapeJSONStrings ( layer - > szNamespace ) ) ;
2022-07-12 19:57:33 +02:00
}
2023-05-24 17:46:56 +02:00
trimTrailingComma ( result ) ;
2022-07-12 19:57:33 +02:00
if ( level . size ( ) > 0 )
result + = " \n " ;
result + = " ], " ;
layerLevel + + ;
2022-03-22 16:54:45 +01:00
}
2023-05-24 17:46:56 +02:00
trimTrailingComma ( result ) ;
2022-07-12 19:57:33 +02:00
result + = " \n } \n }, " ;
}
2023-05-24 17:46:56 +02:00
trimTrailingComma ( result ) ;
2022-07-12 19:57:33 +02:00
result + = " \n } \n " ;
2022-09-25 20:07:48 +02:00
2022-07-12 19:57:33 +02:00
} else {
for ( auto & mon : g_pCompositor - > m_vMonitors ) {
2023-09-06 21:45:37 +02:00
result + = getFormat ( " Monitor {}: \n " , mon - > szName ) ;
2023-01-09 21:26:07 +01:00
int layerLevel = 0 ;
static const std : : array < std : : string , 4 > levelNames = { " background " , " bottom " , " top " , " overlay " } ;
2023-01-22 17:03:25 +01:00
for ( auto & level : mon - > m_aLayerSurfaceLayers ) {
2023-09-06 21:45:37 +02:00
result + = getFormat ( " \t Layer level {} ({}): \n " , layerLevel , levelNames [ layerLevel ] ) ;
2022-07-12 19:57:33 +02:00
for ( auto & layer : level ) {
2023-09-06 12:51:36 +02:00
result + = getFormat ( " \t \t Layer {:x}: xywh: {} {} {} {}, namespace: {} \n " , ( uintptr_t ) layer . get ( ) , layer - > geometry . x , layer - > geometry . y , layer - > geometry . width ,
2023-09-06 21:45:37 +02:00
layer - > geometry . height , layer - > szNamespace ) ;
2022-07-12 19:57:33 +02:00
}
layerLevel + + ;
}
result + = " \n \n " ;
2022-03-22 16:54:45 +01:00
}
}
return result ;
}
2022-07-12 22:59:36 +02:00
std : : string devicesRequest ( HyprCtl : : eHyprCtlOutputFormat format ) {
2022-06-02 13:59:33 +02:00
std : : string result = " " ;
2022-07-12 22:59:36 +02:00
if ( format = = HyprCtl : : FORMAT_JSON ) {
2022-07-12 19:57:33 +02:00
result + = " { \n " ;
result + = " \" mice \" : [ \n " ;
for ( auto & m : g_pInputManager - > m_lMice ) {
result + = getFormat (
2023-09-06 12:51:36 +02:00
R " #( {{
" address " : " 0x{:x} " ,
" name " : " {} " ,
" defaultSpeed " : { : .5f }
} } , ) # " ,
2023-09-06 21:45:37 +02:00
( uintptr_t ) & m , escapeJSONStrings ( m . name ) ,
2022-12-16 18:17:31 +01:00
wlr_input_device_is_libinput ( m . mouse ) ? libinput_device_config_accel_get_default_speed ( ( libinput_device * ) wlr_libinput_get_device_handle ( m . mouse ) ) : 0.f ) ;
2022-07-12 19:57:33 +02:00
}
2022-06-02 13:59:33 +02:00
2023-05-24 17:46:56 +02:00
trimTrailingComma ( result ) ;
2022-07-12 19:57:33 +02:00
result + = " \n ], \n " ;
result + = " \" keyboards \" : [ \n " ;
for ( auto & k : g_pInputManager - > m_lKeyboards ) {
2022-08-16 16:10:20 +02:00
const auto KM = g_pInputManager - > getActiveLayoutForKeyboard ( & k ) ;
2022-07-12 19:57:33 +02:00
result + = getFormat (
2023-09-06 12:51:36 +02:00
R " #( {{
" address " : " 0x{:x} " ,
" name " : " {} " ,
" rules " : " {} " ,
" model " : " {} " ,
" layout " : " {} " ,
" variant " : " {} " ,
" options " : " {} " ,
" active_keymap " : " {} " ,
" main " : { }
} } , ) # " ,
2023-09-06 21:45:37 +02:00
( uintptr_t ) & k , escapeJSONStrings ( k . name ) , escapeJSONStrings ( k . currentRules . rules ) , escapeJSONStrings ( k . currentRules . model ) ,
escapeJSONStrings ( k . currentRules . layout ) , escapeJSONStrings ( k . currentRules . variant ) , escapeJSONStrings ( k . currentRules . options ) , escapeJSONStrings ( KM ) ,
( k . active ? " true " : " false " ) ) ;
2022-07-12 19:57:33 +02:00
}
2022-06-02 13:59:33 +02:00
2023-05-24 17:46:56 +02:00
trimTrailingComma ( result ) ;
2022-07-12 19:57:33 +02:00
result + = " \n ], \n " ;
2022-06-02 13:59:33 +02:00
2022-07-12 19:57:33 +02:00
result + = " \" tablets \" : [ \n " ;
2022-06-02 13:59:33 +02:00
2022-07-12 19:57:33 +02:00
for ( auto & d : g_pInputManager - > m_lTabletPads ) {
result + = getFormat (
2023-09-06 12:51:36 +02:00
R " #( {{
" address " : " 0x{:x} " ,
2022-07-12 19:57:33 +02:00
" type " : " tabletPad " ,
2023-09-06 12:51:36 +02:00
" belongsTo " : { {
" address " : " 0x{:x} " ,
" name " : " {} "
} }
} } , ) # " ,
2023-09-06 21:45:37 +02:00
( uintptr_t ) & d , ( uintptr_t ) d . pTabletParent , escapeJSONStrings ( d . pTabletParent ? d . pTabletParent - > name : " " ) ) ;
2022-07-12 19:57:33 +02:00
}
2022-06-09 19:25:26 +02:00
2022-07-12 19:57:33 +02:00
for ( auto & d : g_pInputManager - > m_lTablets ) {
result + = getFormat (
2023-09-06 12:51:36 +02:00
R " #( {{
" address " : " 0x{:x} " ,
" name " : " {} "
} } , ) # " ,
2023-09-06 21:45:37 +02:00
( uintptr_t ) & d , escapeJSONStrings ( d . name ) ) ;
2022-07-12 19:57:33 +02:00
}
2022-06-09 19:25:26 +02:00
2022-07-12 19:57:33 +02:00
for ( auto & d : g_pInputManager - > m_lTabletTools ) {
result + = getFormat (
2023-09-06 12:51:36 +02:00
R " #( {{
" address " : " 0x{:x} " ,
2022-07-12 19:57:33 +02:00
" type " : " tabletTool " ,
2023-09-06 12:51:36 +02:00
" belongsTo " : " 0x{:x} "
} } , ) # " ,
( uintptr_t ) & d , d . wlrTabletTool ? d . wlrTabletTool - > data : 0 ) ;
2022-07-12 19:57:33 +02:00
}
2023-05-24 17:46:56 +02:00
trimTrailingComma ( result ) ;
2022-09-21 15:39:25 +02:00
result + = " \n ], \n " ;
result + = " \" touch \" : [ \n " ;
for ( auto & d : g_pInputManager - > m_lTouchDevices ) {
result + = getFormat (
2023-09-06 12:51:36 +02:00
R " #( {{
" address " : " 0x{:x} " ,
" name " : " {} "
} } , ) # " ,
2023-09-06 21:45:37 +02:00
( uintptr_t ) & d , d . name ) ;
2022-09-21 15:39:25 +02:00
}
2023-05-24 17:46:56 +02:00
trimTrailingComma ( result ) ;
2022-10-04 21:07:21 +02:00
result + = " \n ], \n " ;
result + = " \" switches \" : [ \n " ;
for ( auto & d : g_pInputManager - > m_lSwitches ) {
result + = getFormat (
2023-09-06 12:51:36 +02:00
R " #( {{
" address " : " 0x{:x} " ,
" name " : " {} "
} } , ) # " ,
( uintptr_t ) & d , d . pWlrDevice ? d . pWlrDevice - > name : " " ) ;
2022-10-04 21:07:21 +02:00
}
2023-05-24 17:46:56 +02:00
trimTrailingComma ( result ) ;
2022-07-12 19:57:33 +02:00
result + = " \n ] \n " ;
2022-06-09 19:25:26 +02:00
2022-07-12 19:57:33 +02:00
result + = " } \n " ;
} else {
result + = " mice: \n " ;
for ( auto & m : g_pInputManager - > m_lMice ) {
2022-12-16 18:17:31 +01:00
result + = getFormat (
2023-09-06 21:45:37 +02:00
" \t Mouse at {:x}: \n \t \t {} \n \t \t \t default speed: {:.5f} \n " , ( uintptr_t ) & m , m . name ,
2022-12-16 18:17:31 +01:00
( wlr_input_device_is_libinput ( m . mouse ) ? libinput_device_config_accel_get_default_speed ( ( libinput_device * ) wlr_libinput_get_device_handle ( m . mouse ) ) : 0.f ) ) ;
2022-07-12 19:57:33 +02:00
}
result + = " \n \n Keyboards: \n " ;
for ( auto & k : g_pInputManager - > m_lKeyboards ) {
2022-08-16 16:10:20 +02:00
const auto KM = g_pInputManager - > getActiveLayoutForKeyboard ( & k ) ;
2023-09-06 21:45:37 +02:00
result + =
getFormat ( " \t Keyboard at {:x}: \n \t \t {} \n \t \t \t rules: r \" {} \" , m \" {} \" , l \" {} \" , v \" {} \" , o \" {} \" \n \t \t \t active keymap: {} \n \t \t \t main: {} \n " , ( uintptr_t ) & k ,
k . name , k . currentRules . rules , k . currentRules . model , k . currentRules . layout , k . currentRules . variant , k . currentRules . options , KM , ( k . active ? " yes " : " no " ) ) ;
2022-07-12 19:57:33 +02:00
}
result + = " \n \n Tablets: \n " ;
for ( auto & d : g_pInputManager - > m_lTabletPads ) {
2023-09-06 21:45:37 +02:00
result + = getFormat ( " \t Tablet Pad at {:x} (belongs to {:x} -> {}) \n " , ( uintptr_t ) & d , ( uintptr_t ) d . pTabletParent , d . pTabletParent ? d . pTabletParent - > name : " " ) ;
2022-07-12 19:57:33 +02:00
}
for ( auto & d : g_pInputManager - > m_lTablets ) {
2023-09-06 21:45:37 +02:00
result + = getFormat ( " \t Tablet at {:x}: \n \t \t {} \n " , ( uintptr_t ) & d , d . name ) ;
2022-07-12 19:57:33 +02:00
}
for ( auto & d : g_pInputManager - > m_lTabletTools ) {
2023-09-06 12:51:36 +02:00
result + = getFormat ( " \t Tablet Tool at {:x} (belongs to {:x}) \n " , ( uintptr_t ) & d , d . wlrTabletTool ? d . wlrTabletTool - > data : 0 ) ;
2022-07-12 19:57:33 +02:00
}
2022-09-21 15:39:25 +02:00
result + = " \n \n Touch: \n " ;
for ( auto & d : g_pInputManager - > m_lTouchDevices ) {
2023-09-06 21:45:37 +02:00
result + = getFormat ( " \t Touch Device at {:x}: \n \t \t {} \n " , ( uintptr_t ) & d , d . name ) ;
2022-09-21 15:39:25 +02:00
}
2022-10-04 21:07:21 +02:00
result + = " \n \n Switches: \n " ;
for ( auto & d : g_pInputManager - > m_lSwitches ) {
2023-09-06 12:51:36 +02:00
result + = getFormat ( " \t Switch Device at {:x}: \n \t \t {} \n " , ( uintptr_t ) & d , d . pWlrDevice ? d . pWlrDevice - > name : " " ) ;
2022-10-04 21:07:21 +02:00
}
2022-06-09 19:25:26 +02:00
}
2022-06-02 13:59:33 +02:00
return result ;
}
2023-01-25 16:16:28 +01:00
std : : string animationsRequest ( HyprCtl : : eHyprCtlOutputFormat format ) {
std : : string ret = " " ;
if ( format = = HyprCtl : : eHyprCtlOutputFormat : : FORMAT_NORMAL ) {
ret + = " animations: \n " ;
for ( auto & ac : g_pConfigManager - > getAnimationConfig ( ) ) {
2023-09-06 21:45:37 +02:00
ret + = getFormat ( " \n \t name: {} \n \t \t overriden: {} \n \t \t bezier: {} \n \t \t enabled: {} \n \t \t speed: {:.2f} \n \t \t style: {} \n " , ac . first , ( int ) ac . second . overridden ,
ac . second . internalBezier , ac . second . internalEnabled , ac . second . internalSpeed , ac . second . internalStyle ) ;
2023-01-25 16:16:28 +01:00
}
ret + = " beziers: \n " ;
for ( auto & bz : g_pAnimationManager - > getAllBeziers ( ) ) {
2023-09-06 21:45:37 +02:00
ret + = getFormat ( " \n \t name: {} \n " , bz . first ) ;
2023-01-25 16:16:28 +01:00
}
} else {
// json
ret + = " [[ " ;
for ( auto & ac : g_pConfigManager - > getAnimationConfig ( ) ) {
ret + = getFormat ( R " #(
2023-09-06 12:51:36 +02:00
{ {
" name " : " {} " ,
" overridden " : { } ,
" bezier " : " {} " ,
" enabled " : { } ,
" speed " : { : .2f } ,
" style " : " {} "
} } , ) # " ,
2023-09-06 21:45:37 +02:00
ac . first , ac . second . overridden ? " true " : " false " , ac . second . internalBezier , ac . second . internalEnabled ? " true " : " false " , ac . second . internalSpeed ,
ac . second . internalStyle ) ;
2023-01-25 16:16:28 +01:00
}
ret [ ret . length ( ) - 1 ] = ' ] ' ;
ret + = " , \n [ " ;
for ( auto & bz : g_pAnimationManager - > getAllBeziers ( ) ) {
ret + = getFormat ( R " #(
2023-09-06 12:51:36 +02:00
{ {
" name " : " {} "
} } , ) # " ,
2023-09-06 21:45:37 +02:00
bz . first ) ;
2023-01-25 16:16:28 +01:00
}
2023-05-24 17:46:56 +02:00
trimTrailingComma ( ret ) ;
2023-01-25 16:16:28 +01:00
2023-02-11 21:54:32 +01:00
ret + = " ]] " ;
2023-01-25 16:16:28 +01:00
}
return ret ;
}
2023-04-09 14:48:20 +02:00
std : : string globalShortcutsRequest ( HyprCtl : : eHyprCtlOutputFormat format ) {
std : : string ret = " " ;
const auto SHORTCUTS = g_pProtocolManager - > m_pGlobalShortcutsProtocolManager - > getAllShortcuts ( ) ;
if ( format = = HyprCtl : : eHyprCtlOutputFormat : : FORMAT_NORMAL ) {
for ( auto & sh : SHORTCUTS )
2023-09-06 21:45:37 +02:00
ret + = getFormat ( " {}:{} -> {} \n " , sh . appid , sh . id , sh . description ) ;
2023-04-09 14:48:20 +02:00
} else {
ret + = " [ " ;
for ( auto & sh : SHORTCUTS ) {
ret + = getFormat ( R " #(
2023-09-06 12:51:36 +02:00
{ {
" name " : " {} " ,
" description " : " {} "
} } , ) # " ,
2023-09-06 21:45:37 +02:00
escapeJSONStrings ( sh . appid + " : " + sh . id ) , escapeJSONStrings ( sh . description ) ) ;
2023-04-09 14:48:20 +02:00
}
2023-05-24 17:46:56 +02:00
trimTrailingComma ( ret ) ;
2023-04-09 14:48:20 +02:00
ret + = " ] \n " ;
}
return ret ;
}
2023-01-06 14:32:25 +01:00
std : : string bindsRequest ( HyprCtl : : eHyprCtlOutputFormat format ) {
std : : string ret = " " ;
if ( format = = HyprCtl : : eHyprCtlOutputFormat : : FORMAT_NORMAL ) {
for ( auto & kb : g_pKeybindManager - > m_lKeybinds ) {
ret + = " bind " ;
if ( kb . locked )
ret + = " l " ;
if ( kb . mouse )
ret + = " m " ;
if ( kb . release )
ret + = " r " ;
if ( kb . repeat )
ret + = " e " ;
2023-06-14 13:08:56 +02:00
if ( kb . nonConsuming )
ret + = " n " ;
2023-01-06 14:32:25 +01:00
2023-09-06 21:45:37 +02:00
ret + = getFormat ( " \n \t modmask: {} \n \t submap: {} \n \t key: {} \n \t keycode: {} \n \t dispatcher: {} \n \t arg: {} \n \n " , kb . modmask , kb . submap , kb . key , kb . keycode , kb . handler ,
kb . arg ) ;
2023-01-06 14:32:25 +01:00
}
} else {
// json
ret + = " [ " ;
for ( auto & kb : g_pKeybindManager - > m_lKeybinds ) {
ret + = getFormat (
R " #(
2023-09-06 12:51:36 +02:00
{ {
" locked " : { } ,
" mouse " : { } ,
" release " : { } ,
" repeat " : { } ,
" non_consuming " : { } ,
" modmask " : { } ,
" submap " : " {} " ,
" key " : " {} " ,
" keycode " : { } ,
" dispatcher " : " {} " ,
" arg " : " {} "
} } , ) # " ,
2023-06-14 13:08:56 +02:00
kb . locked ? " true " : " false " , kb . mouse ? " true " : " false " , kb . release ? " true " : " false " , kb . repeat ? " true " : " false " , kb . nonConsuming ? " true " : " false " ,
2023-09-06 21:45:37 +02:00
kb . modmask , escapeJSONStrings ( kb . submap ) , escapeJSONStrings ( kb . key ) , kb . keycode , escapeJSONStrings ( kb . handler ) , escapeJSONStrings ( kb . arg ) ) ;
2023-01-06 14:32:25 +01:00
}
2023-05-24 17:46:56 +02:00
trimTrailingComma ( ret ) ;
2023-01-06 14:32:25 +01:00
ret + = " ] " ;
}
return ret ;
}
2022-08-11 21:28:37 +02:00
std : : string versionRequest ( HyprCtl : : eHyprCtlOutputFormat format ) {
2023-07-23 19:43:15 +02:00
auto commitMsg = removeBeginEndSpacesTabs ( GIT_COMMIT_MESSAGE ) ;
std : : replace ( commitMsg . begin ( ) , commitMsg . end ( ) , ' # ' , ' ' ) ;
2022-08-11 21:28:37 +02:00
if ( format = = HyprCtl : : eHyprCtlOutputFormat : : FORMAT_NORMAL ) {
2023-07-23 19:43:15 +02:00
std : : string result = " Hyprland, built from branch " + std : : string ( GIT_BRANCH ) + " at commit " + GIT_COMMIT_HASH + " " + GIT_DIRTY + " ( " + commitMsg +
" ). \n Tag: " + GIT_TAG + " \n \n flags: (if any) \n " ;
2022-04-22 18:14:25 +02:00
# ifdef LEGACY_RENDERER
2022-08-11 21:28:37 +02:00
result + = " legacyrenderer \n " ;
2022-04-22 18:14:25 +02:00
# endif
# ifndef NDEBUG
2022-08-11 21:28:37 +02:00
result + = " debug \n " ;
2022-04-22 18:14:25 +02:00
# endif
2022-06-18 13:09:38 +02:00
# ifdef HYPRLAND_DEBUG
2022-12-16 18:17:31 +01:00
result + = " debug \n " ;
2022-06-18 13:09:38 +02:00
# endif
2022-04-22 18:14:25 +02:00
# ifdef NO_XWAYLAND
2022-08-11 21:28:37 +02:00
result + = " no xwayland \n " ;
2022-04-22 18:14:25 +02:00
# endif
2022-08-11 21:28:37 +02:00
return result ;
} else {
std : : string result = getFormat (
2023-09-06 12:51:36 +02:00
R " #({{
" branch " : " {} " ,
" commit " : " {} " ,
" dirty " : { } ,
" commit_message " : " {} " ,
" tag " : " {} " ,
2022-12-16 18:17:31 +01:00
" flags " : [ ) # " ,
2023-09-06 21:45:37 +02:00
GIT_BRANCH , GIT_COMMIT_HASH , ( strcmp ( GIT_DIRTY , " dirty " ) = = 0 ? " true " : " false " ) , escapeJSONStrings ( commitMsg ) , GIT_TAG ) ;
2022-08-11 21:28:37 +02:00
# ifdef LEGACY_RENDERER
result + = " \" legacyrenderer \" , " ;
# endif
# ifndef NDEBUG
result + = " \" debug \" , " ;
# endif
# ifdef HYPRLAND_DEBUG
2022-12-16 18:17:31 +01:00
result + = " \" debug \" , " ;
2022-08-11 21:28:37 +02:00
# endif
# ifdef NO_XWAYLAND
result + = " \" no xwayland \" , " ;
# endif
2023-05-24 17:46:56 +02:00
trimTrailingComma ( result ) ;
2022-08-11 21:28:37 +02:00
result + = " ] \n } " ;
return result ;
}
return " " ; // make the compiler happy
2022-04-22 18:14:25 +02:00
}
2022-04-21 16:11:29 +02:00
std : : string dispatchRequest ( std : : string in ) {
// get rid of the dispatch keyword
in = in . substr ( in . find_first_of ( ' ' ) + 1 ) ;
const auto DISPATCHSTR = in . substr ( 0 , in . find_first_of ( ' ' ) ) ;
2023-07-21 17:20:23 +02:00
auto DISPATCHARG = std : : string ( ) ;
if ( ( int ) in . find_first_of ( ' ' ) ! = - 1 )
DISPATCHARG = in . substr ( in . find_first_of ( ' ' ) + 1 ) ;
2022-04-21 16:11:29 +02:00
const auto DISPATCHER = g_pKeybindManager - > m_mDispatchers . find ( DISPATCHSTR ) ;
if ( DISPATCHER = = g_pKeybindManager - > m_mDispatchers . end ( ) )
return " Invalid dispatcher " ;
DISPATCHER - > second ( DISPATCHARG ) ;
2023-09-06 21:45:37 +02:00
Debug : : log ( LOG , " Hyprctl: dispatcher {} : {} " , DISPATCHSTR , DISPATCHARG ) ;
2022-04-21 21:48:37 +02:00
2022-04-21 16:11:29 +02:00
return " ok " ;
}
2022-04-21 16:56:27 +02:00
std : : string dispatchKeyword ( std : : string in ) {
// get rid of the keyword keyword
in = in . substr ( in . find_first_of ( ' ' ) + 1 ) ;
2022-12-16 18:17:31 +01:00
const auto COMMAND = in . substr ( 0 , in . find_first_of ( ' ' ) ) ;
2022-04-21 16:56:27 +02:00
2022-12-16 18:17:31 +01:00
const auto VALUE = in . substr ( in . find_first_of ( ' ' ) + 1 ) ;
2022-04-21 16:56:27 +02:00
std : : string retval = g_pConfigManager - > parseKeyword ( COMMAND , VALUE , true ) ;
2022-04-21 21:36:45 +02:00
if ( COMMAND = = " monitor " )
g_pConfigManager - > m_bWantsMonitorReload = true ; // for monitor keywords
2022-04-21 17:36:28 +02:00
2022-08-20 18:57:30 +02:00
if ( COMMAND . contains ( " input " ) | | COMMAND . contains ( " device: " ) ) {
2022-12-16 18:17:31 +01:00
g_pInputManager - > setKeyboardLayout ( ) ; // update kb layout
g_pInputManager - > setPointerConfigs ( ) ; // update mouse cfgs
2022-10-07 16:03:52 +02:00
g_pInputManager - > setTouchDeviceConfigs ( ) ; // update touch device cfgs
2022-12-21 16:11:39 +01:00
g_pInputManager - > setTabletConfigs ( ) ; // update tablets
2022-08-20 18:57:30 +02:00
}
2022-04-22 14:11:52 +02:00
2022-07-16 22:44:29 +02:00
if ( COMMAND . contains ( " general:layout " ) )
2022-12-16 18:17:31 +01:00
g_pLayoutManager - > switchToLayout ( g_pConfigManager - > getString ( " general:layout " ) ) ; // update layout
2022-12-03 15:40:12 +01:00
if ( COMMAND . contains ( " decoration:screen_shader " ) )
g_pHyprOpenGL - > m_bReloadScreenShader = true ;
2022-07-16 22:44:29 +02:00
2022-12-18 16:05:34 +01:00
if ( COMMAND . contains ( " blur " ) ) {
for ( auto & [ m , rd ] : g_pHyprOpenGL - > m_mMonitorRenderResources ) {
rd . blurFBDirty = true ;
}
}
2023-01-12 12:14:57 +01:00
// decorations will probably need a repaint
2023-08-01 18:08:53 +02:00
if ( COMMAND . contains ( " decoration: " ) | | COMMAND . contains ( " border " ) | | COMMAND = = " workspace " | | COMMAND . contains ( " cursor_zoom_factor " ) ) {
2023-01-24 15:04:01 +01:00
for ( auto & m : g_pCompositor - > m_vMonitors ) {
2023-01-12 12:14:57 +01:00
g_pHyprRenderer - > damageMonitor ( m . get ( ) ) ;
2023-01-24 15:04:01 +01:00
g_pLayoutManager - > getCurrentLayout ( ) - > recalculateMonitor ( m - > ID ) ;
}
2023-01-12 12:14:57 +01:00
}
2023-09-06 21:45:37 +02:00
Debug : : log ( LOG , " Hyprctl: keyword {} : {} " , COMMAND , VALUE ) ;
2022-04-21 21:48:37 +02:00
2022-09-25 20:07:48 +02:00
if ( retval = = " " )
2022-04-21 16:56:27 +02:00
return " ok " ;
return retval ;
}
2022-12-16 18:17:31 +01:00
std : : string reloadRequest ( const std : : string & request ) {
2022-09-25 20:07:48 +02:00
2022-08-14 23:26:18 +02:00
const auto REQMODE = request . substr ( request . find_last_of ( ' ' ) + 1 ) ;
2022-05-08 15:28:45 +02:00
g_pConfigManager - > m_bForceReload = true ;
2022-08-14 23:26:18 +02:00
if ( REQMODE = = " config-only " ) {
g_pConfigManager - > m_bNoMonitorReload = true ;
}
2022-09-13 15:36:49 +02:00
g_pConfigManager - > tick ( ) ;
2022-05-08 15:28:45 +02:00
return " ok " ;
}
2022-06-27 13:42:20 +02:00
std : : string killRequest ( ) {
g_pInputManager - > setClickMode ( CLICKMODE_KILL ) ;
return " ok " ;
}
2022-07-10 15:41:26 +02:00
std : : string splashRequest ( ) {
return g_pCompositor - > m_szCurrentSplash ;
}
2022-10-26 14:19:37 +02:00
std : : string cursorPosRequest ( HyprCtl : : eHyprCtlOutputFormat format ) {
const auto CURSORPOS = g_pInputManager - > getMouseCoordsInternal ( ) . floor ( ) ;
if ( format = = HyprCtl : : FORMAT_NORMAL ) {
2023-09-06 12:51:36 +02:00
return getFormat ( " {}, {} " , ( int ) CURSORPOS . x , ( int ) CURSORPOS . y ) ;
2022-10-26 14:19:37 +02:00
} else {
return getFormat ( R " #(
2023-09-06 12:51:36 +02:00
{ {
" x " : { } ,
" y " : { }
} }
2022-12-16 18:17:31 +01:00
) # " ,
( int ) CURSORPOS . x , ( int ) CURSORPOS . y ) ;
2022-10-26 14:19:37 +02:00
}
return " error " ;
}
2022-04-29 19:44:09 +02:00
std : : string getReply ( std : : string ) ;
std : : string dispatchBatch ( std : : string request ) {
// split by ;
2022-12-16 18:17:31 +01:00
request = request . substr ( 9 ) ;
2022-04-29 19:44:09 +02:00
std : : string curitem = " " ;
2022-12-16 18:17:31 +01:00
std : : string reply = " " ;
2022-04-29 19:44:09 +02:00
2022-12-16 18:17:31 +01:00
auto nextItem = [ & ] ( ) {
2022-04-29 19:44:09 +02:00
auto idx = request . find_first_of ( ' ; ' ) ;
if ( idx ! = std : : string : : npos ) {
curitem = request . substr ( 0 , idx ) ;
request = request . substr ( idx + 1 ) ;
} else {
curitem = request ;
request = " " ;
}
curitem = removeBeginEndSpacesTabs ( curitem ) ;
} ;
nextItem ( ) ;
while ( curitem ! = " " ) {
reply + = getReply ( curitem ) ;
nextItem ( ) ;
}
return reply ;
}
2022-08-10 21:22:11 +02:00
std : : string dispatchSetCursor ( std : : string request ) {
2023-05-02 15:51:52 +02:00
CVarList vars ( request , 0 , ' ' ) ;
2023-04-21 00:59:31 +02:00
2023-05-02 15:51:52 +02:00
const auto SIZESTR = vars [ vars . size ( ) - 1 ] ;
std : : string theme = " " ;
2023-04-21 00:59:31 +02:00
for ( size_t i = 1 ; i < vars . size ( ) - 1 ; + + i )
theme + = vars [ i ] + " " ;
theme . pop_back ( ) ;
int size = 0 ;
try {
size = std : : stoi ( SIZESTR ) ;
2023-05-02 15:51:52 +02:00
} catch ( . . . ) { return " size not int " ; }
2022-08-10 21:22:11 +02:00
2023-04-21 00:59:31 +02:00
if ( size < = 0 )
return " size not positive " ;
2022-08-10 21:22:11 +02:00
wlr_xcursor_manager_destroy ( g_pCompositor - > m_sWLRXCursorMgr ) ;
2023-04-21 00:59:31 +02:00
g_pCompositor - > m_sWLRXCursorMgr = wlr_xcursor_manager_create ( theme . c_str ( ) , size ) ;
2022-08-10 21:22:11 +02:00
2023-04-21 00:59:31 +02:00
setenv ( " XCURSOR_SIZE " , SIZESTR . c_str ( ) , true ) ;
setenv ( " XCURSOR_THEME " , theme . c_str ( ) , true ) ;
2022-08-10 21:22:11 +02:00
for ( auto & m : g_pCompositor - > m_vMonitors ) {
wlr_xcursor_manager_load ( g_pCompositor - > m_sWLRXCursorMgr , m - > scale ) ;
}
return " ok " ;
}
2022-12-16 18:17:31 +01:00
std : : string switchXKBLayoutRequest ( const std : : string & request ) {
CVarList vars ( request , 0 , ' ' ) ;
2022-12-03 16:56:07 +01:00
2022-12-16 18:17:31 +01:00
const auto KB = vars [ 1 ] ;
2022-12-03 16:56:07 +01:00
const auto CMD = vars [ 2 ] ;
// get kb
2022-12-16 18:17:31 +01:00
const auto PKEYBOARD = std : : find_if ( g_pInputManager - > m_lKeyboards . begin ( ) , g_pInputManager - > m_lKeyboards . end ( ) ,
[ & ] ( const SKeyboard & other ) { return other . name = = g_pInputManager - > deviceNameToInternalString ( KB ) ; } ) ;
2022-12-03 16:56:07 +01:00
if ( PKEYBOARD = = g_pInputManager - > m_lKeyboards . end ( ) )
return " device not found " ;
2022-12-16 18:17:31 +01:00
const auto PWLRKEYBOARD = wlr_keyboard_from_input_device ( PKEYBOARD - > keyboard ) ;
const auto LAYOUTS = xkb_keymap_num_layouts ( PWLRKEYBOARD - > keymap ) ;
2022-12-03 16:56:07 +01:00
xkb_layout_index_t activeLayout = 0 ;
while ( activeLayout < LAYOUTS ) {
if ( xkb_state_layout_index_is_active ( PWLRKEYBOARD - > xkb_state , activeLayout , XKB_STATE_LAYOUT_EFFECTIVE ) )
break ;
activeLayout + + ;
}
if ( CMD = = " next " ) {
2022-12-16 18:17:31 +01:00
wlr_keyboard_notify_modifiers ( PWLRKEYBOARD , PWLRKEYBOARD - > modifiers . depressed , PWLRKEYBOARD - > modifiers . latched , PWLRKEYBOARD - > modifiers . locked ,
activeLayout > LAYOUTS ? 0 : activeLayout + 1 ) ;
2022-12-03 16:56:07 +01:00
} else if ( CMD = = " prev " ) {
2022-12-16 18:17:31 +01:00
wlr_keyboard_notify_modifiers ( PWLRKEYBOARD , PWLRKEYBOARD - > modifiers . depressed , PWLRKEYBOARD - > modifiers . latched , PWLRKEYBOARD - > modifiers . locked ,
activeLayout = = 0 ? LAYOUTS - 1 : activeLayout - 1 ) ;
2022-12-03 16:56:07 +01:00
} else {
2022-12-16 18:17:31 +01:00
2022-12-03 16:56:07 +01:00
int requestedLayout = 0 ;
try {
requestedLayout = std : : stoi ( CMD ) ;
2022-12-16 18:17:31 +01:00
} catch ( std : : exception & e ) { return " invalid arg 2 " ; }
2022-12-03 16:56:07 +01:00
if ( requestedLayout < 0 | | ( uint64_t ) requestedLayout > LAYOUTS - 1 ) {
return " layout idx out of range of " + std : : to_string ( LAYOUTS ) ;
}
2022-12-16 18:17:31 +01:00
wlr_keyboard_notify_modifiers ( PWLRKEYBOARD , PWLRKEYBOARD - > modifiers . depressed , PWLRKEYBOARD - > modifiers . latched , PWLRKEYBOARD - > modifiers . locked , requestedLayout ) ;
2022-12-03 16:56:07 +01:00
}
return " ok " ;
}
2023-01-22 16:38:17 +01:00
std : : string dispatchSeterror ( std : : string request ) {
CVarList vars ( request , 0 , ' ' ) ;
std : : string errorMessage = " " ;
if ( vars . size ( ) < 3 ) {
g_pHyprError - > destroy ( ) ;
2023-01-22 16:51:32 +01:00
if ( vars . size ( ) = = 2 & & ! vars [ 1 ] . find ( " dis " ) )
return " var 1 not color or disable " ;
2023-01-22 16:38:17 +01:00
return " ok " ;
}
const CColor COLOR = configStringToInt ( vars [ 1 ] ) ;
for ( size_t i = 2 ; i < vars . size ( ) ; + + i )
errorMessage + = vars [ i ] + ' ' ;
if ( errorMessage . empty ( ) ) {
g_pHyprError - > destroy ( ) ;
} else {
errorMessage . pop_back ( ) ; // pop last space
g_pHyprError - > queueCreate ( errorMessage , COLOR ) ;
}
return " ok " ;
}
2023-01-24 20:05:34 +01:00
std : : string dispatchSetProp ( std : : string request ) {
CVarList vars ( request , 0 , ' ' ) ;
if ( vars . size ( ) < 4 )
return " not enough args " ;
const auto PWINDOW = g_pCompositor - > getWindowByRegex ( vars [ 1 ] ) ;
if ( ! PWINDOW )
return " window not found " ;
const auto PROP = vars [ 2 ] ;
const auto VAL = vars [ 3 ] ;
bool lock = false ;
if ( vars . size ( ) > 4 ) {
if ( vars [ 4 ] . find ( " lock " ) = = 0 ) {
lock = true ;
}
}
try {
if ( PROP = = " animationstyle " ) {
PWINDOW - > m_sAdditionalConfigData . animationStyle = VAL ;
} else if ( PROP = = " rounding " ) {
2023-01-24 22:44:54 +01:00
PWINDOW - > m_sAdditionalConfigData . rounding . forceSetIgnoreLocked ( configStringToInt ( VAL ) , lock ) ;
2023-01-24 20:05:34 +01:00
} else if ( PROP = = " forcenoblur " ) {
2023-01-24 22:44:54 +01:00
PWINDOW - > m_sAdditionalConfigData . forceNoBlur . forceSetIgnoreLocked ( configStringToInt ( VAL ) , lock ) ;
2023-01-24 20:05:34 +01:00
} else if ( PROP = = " forceopaque " ) {
2023-01-24 22:44:54 +01:00
PWINDOW - > m_sAdditionalConfigData . forceOpaque . forceSetIgnoreLocked ( configStringToInt ( VAL ) , lock ) ;
2023-01-24 20:05:34 +01:00
} else if ( PROP = = " forceopaqueoverriden " ) {
2023-03-30 00:44:25 +02:00
PWINDOW - > m_sAdditionalConfigData . forceOpaqueOverridden . forceSetIgnoreLocked ( configStringToInt ( VAL ) , lock ) ;
2023-01-24 20:05:34 +01:00
} else if ( PROP = = " forceallowsinput " ) {
2023-01-24 22:44:54 +01:00
PWINDOW - > m_sAdditionalConfigData . forceAllowsInput . forceSetIgnoreLocked ( configStringToInt ( VAL ) , lock ) ;
2023-01-24 20:05:34 +01:00
} else if ( PROP = = " forcenoanims " ) {
2023-01-24 22:44:54 +01:00
PWINDOW - > m_sAdditionalConfigData . forceNoAnims . forceSetIgnoreLocked ( configStringToInt ( VAL ) , lock ) ;
2023-01-24 20:05:34 +01:00
} else if ( PROP = = " forcenoborder " ) {
2023-01-24 22:44:54 +01:00
PWINDOW - > m_sAdditionalConfigData . forceNoBorder . forceSetIgnoreLocked ( configStringToInt ( VAL ) , lock ) ;
2023-01-24 20:05:34 +01:00
} else if ( PROP = = " forcenoshadow " ) {
2023-01-24 22:44:54 +01:00
PWINDOW - > m_sAdditionalConfigData . forceNoShadow . forceSetIgnoreLocked ( configStringToInt ( VAL ) , lock ) ;
2023-05-31 21:11:20 +02:00
} else if ( PROP = = " forcenodim " ) {
PWINDOW - > m_sAdditionalConfigData . forceNoDim . forceSetIgnoreLocked ( configStringToInt ( VAL ) , lock ) ;
2023-01-24 20:05:34 +01:00
} else if ( PROP = = " windowdancecompat " ) {
2023-01-24 22:44:54 +01:00
PWINDOW - > m_sAdditionalConfigData . windowDanceCompat . forceSetIgnoreLocked ( configStringToInt ( VAL ) , lock ) ;
2023-01-24 20:05:34 +01:00
} else if ( PROP = = " nomaxsize " ) {
2023-01-24 22:44:54 +01:00
PWINDOW - > m_sAdditionalConfigData . noMaxSize . forceSetIgnoreLocked ( configStringToInt ( VAL ) , lock ) ;
2023-01-24 20:05:34 +01:00
} else if ( PROP = = " dimaround " ) {
2023-01-24 22:44:54 +01:00
PWINDOW - > m_sAdditionalConfigData . dimAround . forceSetIgnoreLocked ( configStringToInt ( VAL ) , lock ) ;
2023-01-24 20:05:34 +01:00
} else if ( PROP = = " alphaoverride " ) {
2023-01-24 22:44:54 +01:00
PWINDOW - > m_sSpecialRenderData . alphaOverride . forceSetIgnoreLocked ( configStringToInt ( VAL ) , lock ) ;
2023-01-24 20:05:34 +01:00
} else if ( PROP = = " alpha " ) {
PWINDOW - > m_sSpecialRenderData . alpha . forceSetIgnoreLocked ( std : : stof ( VAL ) , lock ) ;
} else if ( PROP = = " alphainactiveoverride " ) {
2023-01-24 22:44:54 +01:00
PWINDOW - > m_sSpecialRenderData . alphaInactiveOverride . forceSetIgnoreLocked ( configStringToInt ( VAL ) , lock ) ;
2023-01-24 20:05:34 +01:00
} else if ( PROP = = " alphainactive " ) {
PWINDOW - > m_sSpecialRenderData . alphaInactive . forceSetIgnoreLocked ( std : : stof ( VAL ) , lock ) ;
} else if ( PROP = = " activebordercolor " ) {
2023-01-24 22:44:54 +01:00
PWINDOW - > m_sSpecialRenderData . activeBorderColor . forceSetIgnoreLocked ( configStringToInt ( VAL ) , lock ) ;
2023-01-24 20:05:34 +01:00
} else if ( PROP = = " inactivebordercolor " ) {
2023-01-24 22:44:54 +01:00
PWINDOW - > m_sSpecialRenderData . inactiveBorderColor . forceSetIgnoreLocked ( configStringToInt ( VAL ) , lock ) ;
2023-03-26 03:00:24 +02:00
} else if ( PROP = = " forcergbx " ) {
PWINDOW - > m_sAdditionalConfigData . forceRGBX . forceSetIgnoreLocked ( configStringToInt ( VAL ) , lock ) ;
2023-06-04 21:29:38 +02:00
} else if ( PROP = = " bordersize " ) {
PWINDOW - > m_sSpecialRenderData . borderSize . forceSetIgnoreLocked ( configStringToInt ( VAL ) , lock ) ;
2023-08-08 18:52:20 +02:00
} else if ( PROP = = " keepaspectratio " ) {
PWINDOW - > m_sAdditionalConfigData . keepAspectRatio . forceSetIgnoreLocked ( configStringToInt ( VAL ) , lock ) ;
2023-01-24 20:05:34 +01:00
} else {
return " prop not found " ;
}
} catch ( std : : exception & e ) { return " error in parsing prop value: " + std : : string ( e . what ( ) ) ; }
2023-01-25 00:52:00 +01:00
g_pCompositor - > updateAllWindowsAnimatedDecorationValues ( ) ;
2023-06-04 21:35:17 +02:00
for ( auto & m : g_pCompositor - > m_vMonitors )
g_pLayoutManager - > getCurrentLayout ( ) - > recalculateMonitor ( m - > ID ) ;
2023-01-24 20:05:34 +01:00
return " ok " ;
}
2022-08-11 21:16:38 +02:00
std : : string dispatchGetOption ( std : : string request , HyprCtl : : eHyprCtlOutputFormat format ) {
std : : string curitem = " " ;
2022-12-16 18:17:31 +01:00
auto nextItem = [ & ] ( ) {
2022-08-11 21:16:38 +02:00
auto idx = request . find_first_of ( ' ' ) ;
if ( idx ! = std : : string : : npos ) {
curitem = request . substr ( 0 , idx ) ;
request = request . substr ( idx + 1 ) ;
} else {
curitem = request ;
request = " " ;
}
curitem = removeBeginEndSpacesTabs ( curitem ) ;
} ;
nextItem ( ) ;
nextItem ( ) ;
const auto PCFGOPT = g_pConfigManager - > getConfigValuePtrSafe ( curitem ) ;
if ( ! PCFGOPT )
return " no such option " ;
if ( format = = HyprCtl : : eHyprCtlOutputFormat : : FORMAT_NORMAL )
2023-09-06 12:51:36 +02:00
return getFormat ( " option {} \n \t int: {} \n \t float: {:.5f} \n \t str: \" {} \" \n \t data: {:x} " , curitem , PCFGOPT - > intValue , PCFGOPT - > floatValue , PCFGOPT - > strValue ,
( uintptr_t ) PCFGOPT - > data . get ( ) ) ;
2022-08-11 21:16:38 +02:00
else {
return getFormat (
2022-12-16 18:17:31 +01:00
R " #(
2023-09-06 12:51:36 +02:00
{ {
" option " : " {} " ,
" int " : { }
" float " : { : .5f } ,
" str " : " {} " ,
" data " : " 0x{:x} "
} }
2022-12-16 18:17:31 +01:00
) # " ,
2023-09-06 12:51:36 +02:00
curitem , PCFGOPT - > intValue , PCFGOPT - > floatValue , PCFGOPT - > strValue , ( uintptr_t ) PCFGOPT - > data . get ( ) ) ;
2022-08-11 21:16:38 +02:00
}
}
2022-11-05 19:04:44 +01:00
void createOutputIter ( wlr_backend * backend , void * data ) {
const auto DATA = ( std : : pair < std : : string , bool > * ) data ;
if ( DATA - > second )
return ;
if ( DATA - > first . empty ( ) | | DATA - > first = = " auto " ) {
if ( wlr_backend_is_wl ( backend ) ) {
wlr_wl_output_create ( backend ) ;
DATA - > second = true ;
} else if ( wlr_backend_is_x11 ( backend ) ) {
wlr_x11_output_create ( backend ) ;
DATA - > second = true ;
} else if ( wlr_backend_is_headless ( backend ) ) {
wlr_headless_add_output ( backend , 1920 , 1080 ) ;
DATA - > second = true ;
}
} else {
if ( wlr_backend_is_wl ( backend ) & & DATA - > first = = " wayland " ) {
wlr_wl_output_create ( backend ) ;
DATA - > second = true ;
} else if ( wlr_backend_is_x11 ( backend ) & & DATA - > first = = " x11 " ) {
wlr_x11_output_create ( backend ) ;
DATA - > second = true ;
} else if ( wlr_backend_is_headless ( backend ) & & DATA - > first = = " headless " ) {
wlr_headless_add_output ( backend , 1920 , 1080 ) ;
DATA - > second = true ;
}
}
}
std : : string dispatchOutput ( std : : string request ) {
std : : string curitem = " " ;
2022-12-16 18:17:31 +01:00
auto nextItem = [ & ] ( ) {
2022-11-05 19:04:44 +01:00
auto idx = request . find_first_of ( ' ' ) ;
if ( idx ! = std : : string : : npos ) {
curitem = request . substr ( 0 , idx ) ;
request = request . substr ( idx + 1 ) ;
} else {
curitem = request ;
request = " " ;
}
curitem = removeBeginEndSpacesTabs ( curitem ) ;
} ;
nextItem ( ) ;
nextItem ( ) ;
const auto MODE = curitem ;
nextItem ( ) ;
const auto NAME = curitem ;
if ( MODE = = " create " | | MODE = = " add " ) {
2022-12-16 18:17:31 +01:00
std : : pair < std : : string , bool > result = { NAME , false } ;
2022-11-05 19:04:44 +01:00
wlr_multi_for_each_backend ( g_pCompositor - > m_sWLRBackend , createOutputIter , & result ) ;
if ( ! result . second )
return " no backend replied to the request " ;
} else if ( MODE = = " destroy " | | MODE = = " remove " ) {
const auto PMONITOR = g_pCompositor - > getMonitorFromName ( NAME ) ;
if ( ! PMONITOR )
return " output not found " ;
if ( ! PMONITOR - > createdByUser )
return " cannot remove a real display. Use the monitor keyword. " ;
wlr_output_destroy ( PMONITOR - > output ) ;
}
return " ok " ;
}
2023-02-27 13:32:38 +01:00
std : : string dispatchPlugin ( std : : string request ) {
CVarList vars ( request , 0 , ' ' ) ;
if ( vars . size ( ) < 2 )
return " not enough args " ;
const auto OPERATION = vars [ 1 ] ;
const auto PATH = vars [ 2 ] ;
if ( OPERATION = = " load " ) {
if ( vars . size ( ) < 3 )
return " not enough args " ;
const auto PLUGIN = g_pPluginSystem - > loadPlugin ( PATH ) ;
if ( ! PLUGIN )
return " error in loading plugin " ;
} else if ( OPERATION = = " unload " ) {
if ( vars . size ( ) < 3 )
return " not enough args " ;
const auto PLUGIN = g_pPluginSystem - > getPluginByPath ( PATH ) ;
if ( ! PLUGIN )
return " plugin not loaded " ;
g_pPluginSystem - > unloadPlugin ( PLUGIN ) ;
} else if ( OPERATION = = " list " ) {
const auto PLUGINS = g_pPluginSystem - > getAllPlugins ( ) ;
std : : string list = " " ;
for ( auto & p : PLUGINS ) {
2023-09-06 21:45:37 +02:00
list + = getFormat ( " \n Plugin {} by {}: \n \t Handle: {:x} \n \t Version: {} \n \t Description: {} \n " , p - > name , p - > author , ( uintptr_t ) p - > m_pHandle , p - > version , p - > description ) ;
2023-02-27 13:32:38 +01:00
}
return list ;
} else {
return " unknown opt " ;
}
return " ok " ;
}
2023-03-20 17:00:54 +01:00
std : : string dispatchNotify ( std : : string request ) {
CVarList vars ( request , 0 , ' ' ) ;
if ( vars . size ( ) < 5 )
return " not enough args " ;
const auto ICON = vars [ 1 ] ;
if ( ! isNumber ( ICON ) )
return " invalid arg 1 " ;
int icon = - 1 ;
try {
icon = std : : stoi ( ICON ) ;
} catch ( std : : exception & e ) { return " invalid arg 1 " ; }
2023-04-08 19:53:54 +02:00
if ( icon > ICON_NONE | | icon < 0 ) {
2023-03-20 17:00:54 +01:00
icon = ICON_NONE ;
}
const auto TIME = vars [ 2 ] ;
int time = 0 ;
try {
time = std : : stoi ( TIME ) ;
} catch ( std : : exception & e ) { return " invalid arg 2 " ; }
CColor color = configStringToInt ( vars [ 3 ] ) ;
std : : string message = " " ;
for ( size_t i = 4 ; i < vars . size ( ) ; + + i ) {
message + = vars [ i ] + " " ;
}
message . pop_back ( ) ;
g_pHyprNotificationOverlay - > addNotification ( message , color , time , ( eIcons ) icon ) ;
return " ok " ;
}
2022-04-29 19:44:09 +02:00
std : : string getReply ( std : : string request ) {
2022-07-12 22:59:36 +02:00
auto format = HyprCtl : : FORMAT_NORMAL ;
2022-07-13 00:34:28 +02:00
// process flags for non-batch requests
2022-07-14 11:43:15 +02:00
if ( ! request . contains ( " [[BATCH]] " ) & & request . contains ( " / " ) ) {
2022-07-13 15:48:47 +02:00
long unsigned int sepIndex = 0 ;
2022-07-13 00:34:28 +02:00
for ( const auto & c : request ) {
if ( c = = ' / ' ) { // stop at separator
break ;
}
sepIndex + + ;
2022-09-25 20:07:48 +02:00
2022-07-13 00:34:28 +02:00
if ( c = = ' j ' )
format = HyprCtl : : FORMAT_JSON ;
2022-07-12 22:59:36 +02:00
}
2022-07-13 00:34:28 +02:00
if ( sepIndex < request . size ( ) )
request = request . substr ( sepIndex + 1 ) ; // remove flags and separator so we can compare the rest of the string
2022-07-12 22:59:36 +02:00
}
2022-04-29 19:44:09 +02:00
if ( request = = " monitors " )
2022-07-12 22:59:36 +02:00
return monitorsRequest ( format ) ;
2022-04-29 19:44:09 +02:00
else if ( request = = " workspaces " )
2022-07-12 22:59:36 +02:00
return workspacesRequest ( format ) ;
2023-05-02 15:51:52 +02:00
else if ( request = = " activeworkspace " )
return activeWorkspaceRequest ( format ) ;
2022-04-29 19:44:09 +02:00
else if ( request = = " clients " )
2022-07-12 22:59:36 +02:00
return clientsRequest ( format ) ;
2022-06-27 13:42:20 +02:00
else if ( request = = " kill " )
return killRequest ( ) ;
2022-04-29 19:44:09 +02:00
else if ( request = = " activewindow " )
2022-07-12 22:59:36 +02:00
return activeWindowRequest ( format ) ;
2022-04-29 19:44:09 +02:00
else if ( request = = " layers " )
2022-07-12 22:59:36 +02:00
return layersRequest ( format ) ;
2022-04-29 19:44:09 +02:00
else if ( request = = " version " )
2022-08-11 21:28:37 +02:00
return versionRequest ( format ) ;
2022-08-14 23:26:18 +02:00
else if ( request . find ( " reload " ) = = 0 )
return reloadRequest ( request ) ;
2022-06-02 13:59:33 +02:00
else if ( request = = " devices " )
2022-07-12 22:59:36 +02:00
return devicesRequest ( format ) ;
2022-07-10 15:41:26 +02:00
else if ( request = = " splash " )
return splashRequest ( ) ;
2022-10-26 14:19:37 +02:00
else if ( request = = " cursorpos " )
return cursorPosRequest ( format ) ;
2023-01-06 14:32:25 +01:00
else if ( request = = " binds " )
return bindsRequest ( format ) ;
2023-04-09 14:48:20 +02:00
else if ( request = = " globalshortcuts " )
return globalShortcutsRequest ( format ) ;
2023-01-25 16:16:28 +01:00
else if ( request = = " animations " )
return animationsRequest ( format ) ;
2023-02-27 13:32:38 +01:00
else if ( request . find ( " plugin " ) = = 0 )
return dispatchPlugin ( request ) ;
2023-03-20 17:00:54 +01:00
else if ( request . find ( " notify " ) = = 0 )
return dispatchNotify ( request ) ;
2023-01-24 20:05:34 +01:00
else if ( request . find ( " setprop " ) = = 0 )
return dispatchSetProp ( request ) ;
2023-01-22 16:38:17 +01:00
else if ( request . find ( " seterror " ) = = 0 )
return dispatchSeterror ( request ) ;
2022-12-03 16:56:07 +01:00
else if ( request . find ( " switchxkblayout " ) = = 0 )
return switchXKBLayoutRequest ( request ) ;
2022-11-05 19:04:44 +01:00
else if ( request . find ( " output " ) = = 0 )
return dispatchOutput ( request ) ;
2022-04-29 19:44:09 +02:00
else if ( request . find ( " dispatch " ) = = 0 )
return dispatchRequest ( request ) ;
else if ( request . find ( " keyword " ) = = 0 )
return dispatchKeyword ( request ) ;
2022-08-10 21:22:11 +02:00
else if ( request . find ( " setcursor " ) = = 0 )
return dispatchSetCursor ( request ) ;
2022-08-11 21:16:38 +02:00
else if ( request . find ( " getoption " ) = = 0 )
return dispatchGetOption ( request , format ) ;
2022-04-29 19:44:09 +02:00
else if ( request . find ( " [[BATCH]] " ) = = 0 )
return dispatchBatch ( request ) ;
return " unknown request " ;
}
2023-02-27 13:32:38 +01:00
std : : string HyprCtl : : makeDynamicCall ( const std : : string & input ) {
return getReply ( input ) ;
}
2022-09-10 21:21:28 +02:00
int hyprCtlFDTick ( int fd , uint32_t mask , void * data ) {
if ( mask & WL_EVENT_ERROR | | mask & WL_EVENT_HANGUP )
return 0 ;
sockaddr_in clientAddress ;
2022-12-16 18:17:31 +01:00
socklen_t clientSize = sizeof ( clientAddress ) ;
2022-09-10 21:21:28 +02:00
2023-07-06 11:39:02 +02:00
const auto ACCEPTEDCONNECTION = accept4 ( HyprCtl : : iSocketFD , ( sockaddr * ) & clientAddress , & clientSize , SOCK_CLOEXEC ) ;
2022-09-10 21:21:28 +02:00
2022-12-16 18:17:31 +01:00
char readBuffer [ 1024 ] ;
2022-09-10 21:21:28 +02:00
2023-07-21 17:20:23 +02:00
fd_set fdset ;
FD_ZERO ( & fdset ) ;
FD_SET ( ACCEPTEDCONNECTION , & fdset ) ;
timeval timeout = { . tv_sec = 0 , . tv_usec = 5000 } ;
auto success = select ( ACCEPTEDCONNECTION + 1 , & fdset , nullptr , nullptr , & timeout ) ;
if ( success < = 0 ) {
close ( ACCEPTEDCONNECTION ) ;
return 0 ;
}
auto messageSize = read ( ACCEPTEDCONNECTION , readBuffer , 1024 ) ;
2022-09-10 21:21:28 +02:00
readBuffer [ messageSize = = 1024 ? 1023 : messageSize ] = ' \0 ' ;
std : : string request ( readBuffer ) ;
2022-04-21 22:00:03 +02:00
std : : string reply = " " ;
try {
2022-04-29 19:44:09 +02:00
reply = getReply ( request ) ;
2022-04-21 22:00:03 +02:00
} catch ( std : : exception & e ) {
2023-09-06 12:51:36 +02:00
Debug : : log ( ERR , " Error in request: {} " , e . what ( ) ) ;
2022-04-21 22:00:03 +02:00
reply = " Err: " + std : : string ( e . what ( ) ) ;
}
2022-09-10 21:21:28 +02:00
write ( ACCEPTEDCONNECTION , reply . c_str ( ) , reply . length ( ) ) ;
2022-04-21 22:00:03 +02:00
2022-09-10 21:21:28 +02:00
close ( ACCEPTEDCONNECTION ) ;
2022-08-03 17:12:38 +02:00
if ( g_pConfigManager - > m_bWantsMonitorReload ) {
2023-04-03 23:52:09 +02:00
g_pConfigManager - > ensureMonitorStatus ( ) ;
2022-08-03 17:12:38 +02:00
}
2022-04-21 22:00:03 +02:00
2022-09-10 21:21:28 +02:00
return 0 ;
2022-04-21 22:00:03 +02:00
}
2022-03-21 18:29:41 +01:00
void HyprCtl : : startHyprCtlSocket ( ) {
2022-03-20 16:51:14 +01:00
2023-07-06 11:39:02 +02:00
iSocketFD = socket ( AF_UNIX , SOCK_STREAM | SOCK_CLOEXEC , 0 ) ;
2022-03-21 18:29:41 +01:00
2022-09-10 21:21:28 +02:00
if ( iSocketFD < 0 ) {
Debug : : log ( ERR , " Couldn't start the Hyprland Socket. (1) IPC will not work. " ) ;
return ;
}
2022-03-21 18:29:41 +01:00
2022-09-10 21:21:28 +02:00
sockaddr_un SERVERADDRESS = { . sun_family = AF_UNIX } ;
2022-03-21 18:29:41 +01:00
2022-09-10 21:21:28 +02:00
std : : string socketPath = " /tmp/hypr/ " + g_pCompositor - > m_szInstanceSignature + " /.socket.sock " ;
2022-03-21 18:29:41 +01:00
2022-09-10 21:21:28 +02:00
strcpy ( SERVERADDRESS . sun_path , socketPath . c_str ( ) ) ;
2022-03-21 18:29:41 +01:00
2022-12-16 18:17:31 +01:00
if ( bind ( iSocketFD , ( sockaddr * ) & SERVERADDRESS , SUN_LEN ( & SERVERADDRESS ) ) < 0 ) {
Debug : : log ( ERR , " Couldn't start the Hyprland Socket. (2) IPC will not work. " ) ;
return ;
}
2022-03-21 18:29:41 +01:00
2022-09-10 21:21:28 +02:00
// 10 max queued.
listen ( iSocketFD , 10 ) ;
2022-03-22 16:54:45 +01:00
2023-09-06 21:45:37 +02:00
Debug : : log ( LOG , " Hypr socket started at {} " , socketPath ) ;
2022-08-28 11:19:08 +02:00
2022-09-10 21:21:28 +02:00
wl_event_loop_add_fd ( g_pCompositor - > m_sWLEventLoop , iSocketFD , WL_EVENT_READABLE , hyprCtlFDTick , nullptr ) ;
2022-08-05 01:25:56 +02:00
}