@@ -1160,6 +1160,99 @@ pub fn get_monitor(monitor_index: usize) -> String {
11601160 ) )
11611161 }
11621162
1163+ fn parse_xrandr_monitors ( ) -> Vec < String > {
1164+ let output = Command :: new ( "xrandr" )
1165+ . arg ( "--query" )
1166+ . output ( )
1167+ . expect ( "Failed to execute xrandr" ) ;
1168+
1169+ if !output. status . success ( ) {
1170+ return vec ! [ "Failed to run xrandr" . to_string( ) ] ;
1171+ }
1172+
1173+ let stdout = String :: from_utf8_lossy ( & output. stdout ) ;
1174+ let mut lines = stdout. lines ( ) ;
1175+
1176+ let mut results = Vec :: new ( ) ;
1177+
1178+ while let Some ( line) = lines. next ( ) {
1179+ if line. contains ( " connected" ) {
1180+ let parts: Vec < & str > = line. split_whitespace ( ) . collect ( ) ;
1181+ let connector_full = parts[ 0 ] ;
1182+ let resolution_part = parts
1183+ . iter ( )
1184+ . find ( |s| s. contains ( '+' ) && s. contains ( 'x' ) )
1185+ . unwrap_or ( & "Unknown" ) ;
1186+ let connector_short = connector_full. split ( '-' ) . next ( ) . unwrap_or ( "Unknown" ) ;
1187+ let location = if connector_full. starts_with ( "eDP" ) {
1188+ "Internal"
1189+ } else {
1190+ "External"
1191+ } ;
1192+
1193+ let resolution = resolution_part. split ( '+' ) . next ( ) . unwrap_or ( "Unknown" ) ;
1194+
1195+ let mut width_mm = 0.0 ;
1196+ let mut height_mm = 0.0 ;
1197+
1198+ for i in 0 ..parts. len ( ) {
1199+ if parts[ i] . ends_with ( "mm" ) {
1200+ if width_mm == 0.0 {
1201+ width_mm = parts[ i]
1202+ . trim_end_matches ( "mm" )
1203+ . parse :: < f32 > ( )
1204+ . unwrap_or ( 0.0 ) ;
1205+ } else if height_mm == 0.0 {
1206+ height_mm = parts[ i]
1207+ . trim_end_matches ( "mm" )
1208+ . parse :: < f32 > ( )
1209+ . unwrap_or ( 0.0 ) ;
1210+ break ;
1211+ }
1212+ }
1213+ }
1214+
1215+ let mut refresh_hz = "??" . to_string ( ) ;
1216+
1217+ while let Some ( mode_line) = lines. next ( ) {
1218+ if mode_line. trim ( ) . is_empty ( ) || mode_line. contains ( "connected" ) {
1219+ break ;
1220+ }
1221+
1222+ let mode_parts: Vec < & str > = mode_line. trim ( ) . split_whitespace ( ) . collect ( ) ;
1223+ if mode_parts. len ( ) >= 2 && mode_parts[ 0 ] == resolution {
1224+ refresh_hz = mode_parts[ 1 ]
1225+ . trim_end_matches ( |c : char | c == '*' || c == '+' )
1226+ . to_string ( ) ;
1227+ break ;
1228+ }
1229+ }
1230+
1231+ let width_in = width_mm / 25.4 ;
1232+ let height_in = height_mm / 25.4 ;
1233+ let diagonal_in = if width_in > 0.0 && height_in > 0.0 {
1234+ ( ( width_in. powi ( 2 ) + height_in. powi ( 2 ) ) . sqrt ( ) * 10.0 ) . round ( ) / 10.0
1235+ } else {
1236+ 0.0
1237+ } ;
1238+
1239+ let line = if diagonal_in > 0.0 {
1240+ format ! (
1241+ "({connector_short}): {resolution} @ {refresh_hz} Hz in {diagonal_in:.1}\" [{location}]"
1242+ )
1243+ } else {
1244+ format ! (
1245+ "({connector_short}): {resolution} @ {refresh_hz} Hz [No size] [{location}]"
1246+ )
1247+ } ;
1248+
1249+ results. push ( line) ;
1250+ }
1251+ }
1252+
1253+ results
1254+ }
1255+
11631256 let drm_dir = Path :: new ( "/sys/class/drm" ) ;
11641257 let mut all_of_things = Vec :: new ( ) ;
11651258
@@ -1236,7 +1329,7 @@ pub fn get_monitor(monitor_index: usize) -> String {
12361329
12371330 all_of_things. push ( line) ;
12381331 } else {
1239- all_of_things. push ( format ! ( "({connector}): Failed to parse EDID" ) ) ;
1332+ all_of_things. push ( parse_xrandr_monitors ( ) [ monitor_index ] . to_string ( ) ) ;
12401333 }
12411334 }
12421335
0 commit comments