Yippe i was not lazy

This commit is contained in:
MrEidam
2026-02-04 10:09:09 +01:00
commit 1c5e714b51
4 changed files with 25806 additions and 0 deletions

278
status.cpp Normal file
View File

@@ -0,0 +1,278 @@
#include <iostream>
#include <fstream>
#include <sstream>
#include <thread>
#include <chrono>
#include <iomanip>
#include <string>
#include <vector>
#include <map>
#include <filesystem>
#include <cstdio>
#include <cstdlib>
#include <poll.h>
#include <nlohmann/json.hpp> // include with: sudo apt install nlohmann-json3-dev
using json = nlohmann::json;
using namespace std;
// Utility to execute shell commands and capture output
string execCmd(const string &cmd){
array<char,128> buffer;
string result;
FILE* pipe=popen(cmd.c_str(),"r");
if(!pipe)return "";
while(fgets(buffer.data(),buffer.size(),pipe)!=nullptr)result+=buffer.data();
pclose(pipe);
if(!result.empty()&&result.back()=='\n')result.pop_back();
return result;
}
// ----- Module functions -----
string getBattery(){
string percent=execCmd("cat /sys/class/power_supply/BAT*/capacity 2>/dev/null");
string status=execCmd("cat /sys/class/power_supply/BAT*/status 2>/dev/null");
string energyNow=execCmd("cat /sys/class/power_supply/BAT*/energy_now 2>/dev/null");
string powerNow=execCmd("cat /sys/class/power_supply/BAT*/power_now 2>/dev/null");
string energyFull=execCmd("cat /sys/class/power_supply/BAT*/energy_full 2>/dev/null");
int val=percent.empty()?0:stoi(percent);
string icon;
if(status=="Charging")icon="󰂄";
else if(val>90)icon="󰁹";
else if(val>70)icon="󰂀";
else if(val>50)icon="󰁾";
else if(val>30)icon="󰁼";
else icon="󰁺";
string timeLeft;
if(!energyNow.empty()&&!powerNow.empty()){
double eNow=stod(energyNow);
double pNow=stod(powerNow);
double eFull=energyFull.empty()?eNow:eNow+1000;
if(pNow>0){
double hours=0;
if(status=="Charging")hours=(eFull-eNow)/pNow;
else if(status=="Discharging")hours=eNow/pNow;
int h=(int)hours;
int m=(int)((hours-h)*60);
stringstream tss;
tss<<" ("<<h<<"h "<<m<<"m"<<(status=="Charging"?" until full":" left")<<")";
timeLeft=tss.str();
}
}
return " "+icon+" "+percent+"% "+status+timeLeft+" ";
}
string getPowerMode(){
string mode=execCmd("powerprofilesctl get 2>/dev/null");
if(mode=="performance")return " 󰓅 Performance ";
if(mode=="balanced")return " 󰾅 Balanced ";
if(mode=="power-saver")return " 󰾆 Power Saver ";
return " 󰾆 Unknown ";
}
string getSound(){
string vol=execCmd("pamixer --get-volume 2>/dev/null");
string mute=execCmd("pamixer --get-mute 2>/dev/null");
string icon=(mute=="true")?" 󰝟":" 󰕾";
return icon+" "+(vol.empty()?"0":vol)+"% ";
}
string getMic(){
string vol=execCmd("pamixer --default-source --get-volume 2>/dev/null");
string mute=execCmd("pamixer --default-source --get-mute 2>/dev/null");
string icon=(mute=="true")?" 󰍭":" 󰍬";
return icon+" "+(vol.empty()?"0":vol)+"% ";
}
string getDunst(){
string status=execCmd("dunstctl is-paused 2>/dev/null");
return (status=="true")?" 󰂛 Off ":" 󰂚 On ";
}
string getBrightness(){
namespace fs = std::filesystem;
string path;
for(const auto& dir: fs::directory_iterator("/sys/class/backlight/")){
path = dir.path();
break;
}
if(path.empty()) return " 🌞 N/A ";
string cur = execCmd("cat "+path+"/brightness");
string max = execCmd("cat "+path+"/max_brightness");
if(cur.empty() || max.empty()) return " 🌞 N/A ";
double perc = stod(cur) / stod(max) * 100.0;
string icon = (perc > 75) ? "󰃠" : (perc > 50) ? "󰃡" : (perc > 25) ? "󰃢" : "󰃣";
stringstream ss;
ss << " " << icon << " " << fixed << setprecision(0) << perc << "% ";
return ss.str();
}
double getCpuUsage() {
static long long lastTotal=0, lastIdle=0;
std::ifstream file("/proc/stat");
std::string line;
getline(file,line); // first line: "cpu …"
std::istringstream ss(line);
std::string cpu;
long long user, nice, system, idle, iowait, irq, softirq, steal;
ss >> cpu >> user >> nice >> system >> idle >> iowait >> irq >> softirq >> steal;
long long idleTime = idle + iowait;
long long total = user+nice+system+idle+iowait+irq+softirq+steal;
long long diffIdle = idleTime - lastIdle;
long long diffTotal = total - lastTotal;
lastIdle = idleTime;
lastTotal = total;
if(diffTotal==0)return 0.0;
return (double)(diffTotal - diffIdle) / diffTotal * 100.0;
}
string getCPU(){
string temp=execCmd("sensors | grep 'Package id 0:' | awk '{print $4}' | tr -d '+'");
double usage = getCpuUsage(); //execCmd("mpstat 1 1 | awk '/all/ {print 100-$12}'");
stringstream ss;
ss<<" 󰍛 "<<fixed<<setprecision(1)<<usage<<"% "<<(temp.empty()?"N/A":temp)<<" ";
return ss.str();
}
string getRAM(){
ifstream meminfo("/proc/meminfo");
long total=0,free=0,avail=0;
string key;
long val;
string unit;
while(meminfo>>key>>val>>unit){
if(key=="MemTotal:")total=val;
if(key=="MemAvailable:")avail=val;
}
long used=total-avail;
double usedGB=used/1024.0/1024.0;
double totalGB=total/1024.0/1024.0;
string icon=" 󰍛";
stringstream ss;
ss<<icon<<" "<<fixed<<setprecision(2)<<usedGB<<"/"<<setprecision(1)<<totalGB<<"GiB ";
return ss.str();
}
string getNetwork(){
string wifi=execCmd("iwgetid -r 2>/dev/null");
string eth=execCmd("ip link show | grep 'state UP' | grep eth | awk '{print $2}' | tr -d ':'");
string ip=execCmd("hostname -I | awk '{print $1}'");
string out;
if(!wifi.empty()){
string strength=execCmd("awk 'NR==3 {print int($3)}' /proc/net/wireless 2>/dev/null");
out+="󰖩 "+wifi;
if(!strength.empty())out+=" ("+strength+"%)";
if(!ip.empty())out+=" "+ip;
}else out+="󰖪 Wi-Fi Off";
if(!eth.empty()){
if(!out.empty())out+=" | ";
out+="󰈀 "+eth;
if(!ip.empty())out+=" "+ip;
}else{
if(out.find("Wi-Fi Off")==string::npos){
// only show 'no eth' if not both off
out+=" | 󰌙 No ETH";
}
}
if(out.find("󰖩")==string::npos&&out.find("󰈀")==string::npos)
out="󰖪 Offline";
return " "+out+" ";
}
string getStorage(){
string df=execCmd("df -h /home/ | awk 'NR==2 {print $3\"/\"$2}'");
return " 󰋊 "+df+" ";
}
string getDateTime(){
time_t t=time(nullptr);
tm* now=localtime(&t);
stringstream ss;
const char* days[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
ss<<" 󰃭 "<<days[now->tm_wday]<<" "<<put_time(now,"%d %b %Y")<<" 󰅐 "<<put_time(now,"%H:%M:%S ");
return ss.str();
}
// ----- JSON Output -----
json makeBlock(const string&id,const string&text,const string&color,const string&bg){
json j;
j["name"]=id;
j["full_text"]=text;
j["color"]=color;
j["background"]=bg;
j["separator"]=false;
j["separator_block_width"]=0;
return j;
}
// ----- Main -----
int main(){
ios::sync_with_stdio(false);
cout<<"{\"version\":1,\"click_events\":true}"<<endl; // i3bar header
cout<<"["<<endl; // Start infinite array
bool first=true;
while(true){
vector<json> blocks; // TEXT | BACK
blocks.push_back(makeBlock("battery",getBattery(),"#cdd6f4","#000000")); //313244
blocks.push_back(makeBlock("power",getPowerMode(),"#f9e2af","#000000")); //45475a
blocks.push_back(makeBlock("sound",getSound(),"#a6e3a1","#000000")); //313244
// blocks.push_back(makeBlock("mic",getMic(),"#f38ba8","#000000")); //313244
// blocks.push_back(makeBlock("dunst",getDunst(),"#b4befe","#313244"));
blocks.push_back(makeBlock("brightness", getBrightness(), "#f38ba8", "#000000")); //313244
blocks.push_back(makeBlock("cpu",getCPU(),"#89b4fa","#000000")); //45475a
blocks.push_back(makeBlock("ram",getRAM(),"#fab387","#000000")); //313244
blocks.push_back(makeBlock("net",getNetwork(),"#94e2d5","#000000")); //45475a
blocks.push_back(makeBlock("storage",getStorage(),"#f5c2e7","#000000")); //313244
blocks.push_back(makeBlock("clock",getDateTime(),"#f2cdcd","#000000")); //45475a
if(!first)cout<<","<<endl;
first=false;
cout<<blocks<<endl;
cout.flush();
// ---- Handle click events properly ----
struct pollfd fds[1];
fds[0].fd=STDIN_FILENO;
fds[0].events=POLLIN;
int ret=poll(fds,1,50);
if(ret>0 && (fds[0].revents&POLLIN)){
string line;
if(getline(cin,line)){
try{
json click=json::parse(line);
string name=click.value("name","");
if(name=="power")system("~/Projects/C+++/statusBar/scripts/toggle_performance.sh &");
// else if(name=="dunst")system("~/Projects/C+++/statusBar/scripts/toggle_dunst.sh &");
else if(name=="mic")system("~/Projects/C+++/statusBar/scripts/toggle_mic.sh &");
else if(name=="sound")system("~/Projects/C+++/statusBar/scripts/toggle_sound.sh &");
else if(name=="net")system("alacritty -e nmtui &");
}catch(...){
// ignore malformed input
}
}
}
this_thread::sleep_for(chrono::milliseconds(500));
}
}