@ -181,6 +181,9 @@ net_sync=$net_sync
#* If the network graphs color gradient should scale to bandwith usage or auto scale, bandwith usage is based on "net_download" and "net_upload" values
net_color_fixed = $ net_color_fixed
#* Show battery stats in top right if battery is present
show_battery = $ show_battery
#* Show init screen at startup, the init screen is purely cosmetical
show_init = $ show_init
@ -361,7 +364,8 @@ class Config:
''' Holds all config variables and functions for loading from and saving to disk '''
keys : List [ str ] = [ " color_theme " , " update_ms " , " proc_sorting " , " proc_reversed " , " proc_tree " , " check_temp " , " draw_clock " , " background_update " , " custom_cpu_name " ,
" proc_colors " , " proc_gradient " , " proc_per_core " , " proc_mem_bytes " , " disks_filter " , " update_check " , " log_level " , " mem_graphs " , " show_swap " ,
" swap_disk " , " show_disks " , " net_download " , " net_upload " , " net_auto " , " net_color_fixed " , " show_init " , " view_mode " , " theme_background " , " net_sync " ]
" swap_disk " , " show_disks " , " net_download " , " net_upload " , " net_auto " , " net_color_fixed " , " show_init " , " view_mode " , " theme_background " ,
" net_sync " , " show_battery " ]
conf_dict : Dict [ str , Union [ str , int , bool ] ] = { }
color_theme : str = " Default "
theme_background : bool = True
@ -388,6 +392,7 @@ class Config:
net_color_fixed : bool = False
net_auto : bool = True
net_sync : bool = False
show_battery : bool = True
show_init : bool = True
view_mode : str = " full "
log_level : str = " WARNING "
@ -1419,14 +1424,16 @@ class Meter:
color_inactive : Color
gradient_name : str
width : int
invert : bool
saved : Dict [ int , str ]
def __init__ ( self , value : int , width : int , gradient_name : str ):
def __init__ ( self , value : int , width : int , gradient_name : str , invert : bool = False ):
self . gradient_name = gradient_name
self . color_gradient = THEME . gradient [ gradient_name ]
self . color_inactive = THEME . meter_bg
self . width = width
self . saved = { }
self . invert = invert
self . out = self . _create ( value )
def __call__ ( self , value : Union [ int , None ] ) - > str :
@ -1451,7 +1458,7 @@ class Meter:
out : str = " "
for i in range ( 1 , self . width + 1 ) :
if value > = round ( i * 100 / self . width ) :
out + = f ' { self . color_gradient [ round ( i * 100 / self . width ) ] } { Symbol . meter } '
out + = f ' { self . color_gradient [ round ( i * 100 / self . width ) if not self . invert else round ( 100 - ( i * 100 / self . width ) ) ] } { Symbol . meter } '
else :
out + = self . color_inactive ( Symbol . meter * ( self . width + 1 - i ) )
break
@ -1463,6 +1470,7 @@ class Meter:
class Meters :
cpu : Meter
battery : Meter
mem : Dict [ str , Union [ Meter , Graph ] ] = { }
swap : Dict [ str , Union [ Meter , Graph ] ] = { }
disks_used : Dict [ str , Meter ] = { }
@ -1506,7 +1514,12 @@ class Box:
Draw . buffer ( " update_ms! " if now and not Menu . active else " update_ms " ,
f ' { Mv . to ( CpuBox . y , xpos ) } { THEME . cpu_box ( Symbol . h_line * 7 , Symbol . title_left ) } { Fx . b } { THEME . hi_fg ( " + " ) } ' ,
f ' { THEME . title ( update_string ) } { THEME . hi_fg ( " - " ) } { Fx . ub } { THEME . cpu_box ( Symbol . title_right ) } ' , only_save = Menu . active , once = True )
if now and not Menu . active : Draw . clear ( " update_ms " )
if now and not Menu . active :
Draw . clear ( " update_ms " )
if CONFIG . show_battery and CpuBox . battery_present :
CpuBox . redraw = True
CpuBox . _draw_fg ( )
Draw . out ( " cpu " )
@classmethod
def draw_clock ( cls , force : bool = False ) :
@ -1543,6 +1556,9 @@ class CpuBox(Box, SubBox):
resized : bool = True
redraw : bool = False
buffer : str = " cpu "
battery_percent : int = 1000
old_battery_pos = 0
battery_present : bool = True if hasattr ( psutil , " sensors_battery " ) and psutil . sensors_battery ( ) else False
clock_block : bool = True
Box . buffers . append ( buffer )
@ -1613,6 +1629,24 @@ class CpuBox(Box, SubBox):
Graphs . temps [ n ] = Graph ( 5 , 1 , None , cpu . cpu_temp [ n ] , max_value = cpu . cpu_temp_crit , offset = - 23 )
Draw . buffer ( " cpu_misc " , out_misc , only_save = True )
if CONFIG . show_battery and cls . battery_present and psutil . sensors_battery ( ) . percent != cls . battery_percent :
if isinstance ( psutil . sensors_battery ( ) . secsleft , int ) :
battery_secs : int = psutil . sensors_battery ( ) . secsleft
else :
battery_secs = 0
cls . battery_percent = psutil . sensors_battery ( ) . percent
if not hasattr ( Meters , " battery " ) or cls . resized :
Meters . battery = Meter ( cls . battery_percent , 10 , " cpu " , invert = True )
battery_symbol : str = " ▼ " if not psutil . sensors_battery ( ) . power_plugged else " ▲ "
battery_pos = cls . width - len ( f ' { CONFIG . update_ms } ' ) - 17 - ( 11 if cls . width > = 100 else 0 ) - ( 6 if battery_secs else 0 ) - len ( f ' { cls . battery_percent } ' )
if battery_pos != cls . old_battery_pos and cls . old_battery_pos > 0 and not cls . resized :
out + = f ' { Mv . to ( y - 1 , cls . old_battery_pos ) } { THEME . cpu_box ( Symbol . h_line * ( 15 if cls . width > = 100 else 5 ) ) } '
cls . old_battery_pos = battery_pos
out + = ( f ' { Mv . to ( y - 1 , battery_pos ) } { THEME . cpu_box ( Symbol . title_left ) } { Fx . b } { THEME . title } BAT { battery_symbol } { cls . battery_percent } % ' +
( " " if cls . width < 100 else f ' { Fx . ub } { Meters . battery ( cls . battery_percent ) } { Fx . b } ' ) +
( " " if not battery_secs else f ' { THEME . title } { battery_secs / / 3600 : 02 } : { ( battery_secs % 3600 ) / / 60 : 02 } ' ) +
f ' { Fx . ub } { THEME . cpu_box ( Symbol . title_right ) } ' )
cx = cy = cc = 0
ccw = ( bw + 1 ) / / cls . box_columns
if cpu . cpu_freq :
@ -3752,6 +3786,11 @@ class Menu:
' The bandwidth usage is based on the ' ,
' " net_download " and " net_upload " values set ' ,
' above. ' ] ,
" show_battery " : [
' Show battery stats. ' ,
' ' ,
' Show battery stats in the top right corner ' ,
' if a battery is present. ' ] ,
" show_init " : [
' Show init screen at startup. ' ,
' ' ,