mirror of
https://codeberg.org/tmayoff/.dotfiles.git
synced 2025-12-06 08:48:34 -05:00
added sketchybar config
This commit is contained in:
parent
87bb07f015
commit
95ebd7af03
38 changed files with 2329 additions and 0 deletions
58
dot_config/sketchybar/helpers/event_providers/cpu_load/cpu.h
Normal file
58
dot_config/sketchybar/helpers/event_providers/cpu_load/cpu.h
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
#include <mach/mach.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
struct cpu {
|
||||
host_t host;
|
||||
mach_msg_type_number_t count;
|
||||
host_cpu_load_info_data_t load;
|
||||
host_cpu_load_info_data_t prev_load;
|
||||
bool has_prev_load;
|
||||
|
||||
int user_load;
|
||||
int sys_load;
|
||||
int total_load;
|
||||
};
|
||||
|
||||
static inline void cpu_init(struct cpu* cpu) {
|
||||
cpu->host = mach_host_self();
|
||||
cpu->count = HOST_CPU_LOAD_INFO_COUNT;
|
||||
cpu->has_prev_load = false;
|
||||
}
|
||||
|
||||
static inline void cpu_update(struct cpu* cpu) {
|
||||
kern_return_t error = host_statistics(cpu->host,
|
||||
HOST_CPU_LOAD_INFO,
|
||||
(host_info_t)&cpu->load,
|
||||
&cpu->count );
|
||||
|
||||
if (error != KERN_SUCCESS) {
|
||||
printf("Error: Could not read cpu host statistics.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (cpu->has_prev_load) {
|
||||
uint32_t delta_user = cpu->load.cpu_ticks[CPU_STATE_USER]
|
||||
- cpu->prev_load.cpu_ticks[CPU_STATE_USER];
|
||||
|
||||
uint32_t delta_system = cpu->load.cpu_ticks[CPU_STATE_SYSTEM]
|
||||
- cpu->prev_load.cpu_ticks[CPU_STATE_SYSTEM];
|
||||
|
||||
uint32_t delta_idle = cpu->load.cpu_ticks[CPU_STATE_IDLE]
|
||||
- cpu->prev_load.cpu_ticks[CPU_STATE_IDLE];
|
||||
|
||||
cpu->user_load = (double)delta_user / (double)(delta_system
|
||||
+ delta_user
|
||||
+ delta_idle) * 100.0;
|
||||
|
||||
cpu->sys_load = (double)delta_system / (double)(delta_system
|
||||
+ delta_user
|
||||
+ delta_idle) * 100.0;
|
||||
|
||||
cpu->total_load = cpu->user_load + cpu->sys_load;
|
||||
}
|
||||
|
||||
cpu->prev_load = cpu->load;
|
||||
cpu->has_prev_load = true;
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
#include "cpu.h"
|
||||
#include "../sketchybar.h"
|
||||
|
||||
int main (int argc, char** argv) {
|
||||
float update_freq;
|
||||
if (argc < 3 || (sscanf(argv[2], "%f", &update_freq) != 1)) {
|
||||
printf("Usage: %s \"<event-name>\" \"<event_freq>\"\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
alarm(0);
|
||||
struct cpu cpu;
|
||||
cpu_init(&cpu);
|
||||
|
||||
// Setup the event in sketchybar
|
||||
char event_message[512];
|
||||
snprintf(event_message, 512, "--add event '%s'", argv[1]);
|
||||
sketchybar(event_message);
|
||||
|
||||
char trigger_message[512];
|
||||
for (;;) {
|
||||
// Acquire new info
|
||||
cpu_update(&cpu);
|
||||
|
||||
// Prepare the event message
|
||||
snprintf(trigger_message,
|
||||
512,
|
||||
"--trigger '%s' user_load='%d' sys_load='%02d' total_load='%02d'",
|
||||
argv[1],
|
||||
cpu.user_load,
|
||||
cpu.sys_load,
|
||||
cpu.total_load );
|
||||
|
||||
// Trigger the event
|
||||
sketchybar(trigger_message);
|
||||
|
||||
// Wait
|
||||
usleep(update_freq * 1000000);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
bin/cpu_load: cpu_load.c cpu.h ../sketchybar.h | bin
|
||||
clang -std=c99 -O3 $< -o $@
|
||||
|
||||
bin:
|
||||
mkdir bin
|
||||
3
dot_config/sketchybar/helpers/event_providers/makefile
Normal file
3
dot_config/sketchybar/helpers/event_providers/makefile
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
all:
|
||||
(cd cpu_load && $(MAKE))
|
||||
(cd network_load && $(MAKE))
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
bin/network_load: network_load.c network.h ../sketchybar.h | bin
|
||||
clang -std=c99 -O3 $< -o $@
|
||||
|
||||
bin:
|
||||
mkdir bin
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_mib.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
static char unit_str[3][6] = { { " Bps" }, { "KBps" }, { "MBps" }, };
|
||||
|
||||
enum unit {
|
||||
UNIT_BPS,
|
||||
UNIT_KBPS,
|
||||
UNIT_MBPS
|
||||
};
|
||||
struct network {
|
||||
uint32_t row;
|
||||
struct ifmibdata data;
|
||||
struct timeval tv_nm1, tv_n, tv_delta;
|
||||
|
||||
int up;
|
||||
int down;
|
||||
enum unit up_unit, down_unit;
|
||||
};
|
||||
|
||||
static inline void ifdata(uint32_t net_row, struct ifmibdata* data) {
|
||||
static size_t size = sizeof(struct ifmibdata);
|
||||
static int32_t data_option[] = { CTL_NET, PF_LINK, NETLINK_GENERIC, IFMIB_IFDATA, 0, IFDATA_GENERAL };
|
||||
data_option[4] = net_row;
|
||||
sysctl(data_option, 6, data, &size, NULL, 0);
|
||||
}
|
||||
|
||||
static inline void network_init(struct network* net, char* ifname) {
|
||||
memset(net, 0, sizeof(struct network));
|
||||
|
||||
static int count_option[] = { CTL_NET, PF_LINK, NETLINK_GENERIC, IFMIB_SYSTEM, IFMIB_IFCOUNT };
|
||||
uint32_t interface_count = 0;
|
||||
size_t size = sizeof(uint32_t);
|
||||
sysctl(count_option, 5, &interface_count, &size, NULL, 0);
|
||||
|
||||
for (int i = 0; i < interface_count; i++) {
|
||||
ifdata(i, &net->data);
|
||||
if (strcmp(net->data.ifmd_name, ifname) == 0) {
|
||||
net->row = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void network_update(struct network* net) {
|
||||
gettimeofday(&net->tv_n, NULL);
|
||||
timersub(&net->tv_n, &net->tv_nm1, &net->tv_delta);
|
||||
net->tv_nm1 = net->tv_n;
|
||||
|
||||
uint64_t ibytes_nm1 = net->data.ifmd_data.ifi_ibytes;
|
||||
uint64_t obytes_nm1 = net->data.ifmd_data.ifi_obytes;
|
||||
ifdata(net->row, &net->data);
|
||||
|
||||
double time_scale = (net->tv_delta.tv_sec + 1e-6*net->tv_delta.tv_usec);
|
||||
if (time_scale < 1e-6 || time_scale > 1e2) return;
|
||||
double delta_ibytes = (double)(net->data.ifmd_data.ifi_ibytes - ibytes_nm1)
|
||||
/ time_scale;
|
||||
double delta_obytes = (double)(net->data.ifmd_data.ifi_obytes - obytes_nm1)
|
||||
/ time_scale;
|
||||
|
||||
double exponent_ibytes = log10(delta_ibytes);
|
||||
double exponent_obytes = log10(delta_obytes);
|
||||
|
||||
if (exponent_ibytes < 3) {
|
||||
net->down_unit = UNIT_BPS;
|
||||
net->down = delta_ibytes;
|
||||
} else if (exponent_ibytes < 6) {
|
||||
net->down_unit = UNIT_KBPS;
|
||||
net->down = delta_ibytes / 1000.0;
|
||||
} else if (exponent_ibytes < 9) {
|
||||
net->down_unit = UNIT_MBPS;
|
||||
net->down = delta_ibytes / 1000000.0;
|
||||
}
|
||||
|
||||
if (exponent_obytes < 3) {
|
||||
net->up_unit = UNIT_BPS;
|
||||
net->up = delta_obytes;
|
||||
} else if (exponent_obytes < 6) {
|
||||
net->up_unit = UNIT_KBPS;
|
||||
net->up = delta_obytes / 1000.0;
|
||||
} else if (exponent_obytes < 9) {
|
||||
net->up_unit = UNIT_MBPS;
|
||||
net->up = delta_obytes / 1000000.0;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
#include <unistd.h>
|
||||
#include "network.h"
|
||||
#include "../sketchybar.h"
|
||||
|
||||
int main (int argc, char** argv) {
|
||||
float update_freq;
|
||||
if (argc < 4 || (sscanf(argv[3], "%f", &update_freq) != 1)) {
|
||||
printf("Usage: %s \"<interface>\" \"<event-name>\" \"<event_freq>\"\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
alarm(0);
|
||||
// Setup the event in sketchybar
|
||||
char event_message[512];
|
||||
snprintf(event_message, 512, "--add event '%s'", argv[2]);
|
||||
sketchybar(event_message);
|
||||
|
||||
struct network network;
|
||||
network_init(&network, argv[1]);
|
||||
char trigger_message[512];
|
||||
for (;;) {
|
||||
// Acquire new info
|
||||
network_update(&network);
|
||||
|
||||
// Prepare the event message
|
||||
snprintf(trigger_message,
|
||||
512,
|
||||
"--trigger '%s' upload='%03d%s' download='%03d%s'",
|
||||
argv[2],
|
||||
network.up,
|
||||
unit_str[network.up_unit],
|
||||
network.down,
|
||||
unit_str[network.down_unit]);
|
||||
|
||||
// Trigger the event
|
||||
sketchybar(trigger_message);
|
||||
|
||||
// Wait
|
||||
usleep(update_freq * 1000000);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
122
dot_config/sketchybar/helpers/event_providers/sketchybar.h
Normal file
122
dot_config/sketchybar/helpers/event_providers/sketchybar.h
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
#pragma once
|
||||
|
||||
#include <mach/arm/kern_return.h>
|
||||
#include <mach/mach.h>
|
||||
#include <mach/mach_port.h>
|
||||
#include <mach/message.h>
|
||||
#include <bootstrap.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef char* env;
|
||||
|
||||
#define MACH_HANDLER(name) void name(env env)
|
||||
typedef MACH_HANDLER(mach_handler);
|
||||
|
||||
struct mach_message {
|
||||
mach_msg_header_t header;
|
||||
mach_msg_size_t msgh_descriptor_count;
|
||||
mach_msg_ool_descriptor_t descriptor;
|
||||
};
|
||||
|
||||
struct mach_buffer {
|
||||
struct mach_message message;
|
||||
mach_msg_trailer_t trailer;
|
||||
};
|
||||
|
||||
static mach_port_t g_mach_port = 0;
|
||||
|
||||
static inline mach_port_t mach_get_bs_port() {
|
||||
mach_port_name_t task = mach_task_self();
|
||||
|
||||
mach_port_t bs_port;
|
||||
if (task_get_special_port(task,
|
||||
TASK_BOOTSTRAP_PORT,
|
||||
&bs_port ) != KERN_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
char* name = getenv("BAR_NAME");
|
||||
if (!name) name = "sketchybar";
|
||||
uint32_t lookup_len = 16 + strlen(name);
|
||||
|
||||
char buffer[lookup_len];
|
||||
snprintf(buffer, lookup_len, "git.felix.%s", name);
|
||||
|
||||
mach_port_t port;
|
||||
if (bootstrap_look_up(bs_port, buffer, &port) != KERN_SUCCESS) return 0;
|
||||
return port;
|
||||
}
|
||||
|
||||
static inline bool mach_send_message(mach_port_t port, char* message, uint32_t len) {
|
||||
if (!message || !port) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct mach_message msg = { 0 };
|
||||
msg.header.msgh_remote_port = port;
|
||||
msg.header.msgh_local_port = 0;
|
||||
msg.header.msgh_id = 0;
|
||||
msg.header.msgh_bits = MACH_MSGH_BITS_SET(MACH_MSG_TYPE_COPY_SEND,
|
||||
MACH_MSG_TYPE_MAKE_SEND,
|
||||
0,
|
||||
MACH_MSGH_BITS_COMPLEX );
|
||||
|
||||
msg.header.msgh_size = sizeof(struct mach_message);
|
||||
msg.msgh_descriptor_count = 1;
|
||||
msg.descriptor.address = message;
|
||||
msg.descriptor.size = len * sizeof(char);
|
||||
msg.descriptor.copy = MACH_MSG_VIRTUAL_COPY;
|
||||
msg.descriptor.deallocate = false;
|
||||
msg.descriptor.type = MACH_MSG_OOL_DESCRIPTOR;
|
||||
|
||||
kern_return_t err = mach_msg(&msg.header,
|
||||
MACH_SEND_MSG,
|
||||
sizeof(struct mach_message),
|
||||
0,
|
||||
MACH_PORT_NULL,
|
||||
MACH_MSG_TIMEOUT_NONE,
|
||||
MACH_PORT_NULL );
|
||||
|
||||
return err == KERN_SUCCESS;
|
||||
}
|
||||
|
||||
static inline uint32_t format_message(char* message, char* formatted_message) {
|
||||
// This is not actually robust, switch to stack based messaging.
|
||||
char outer_quote = 0;
|
||||
uint32_t caret = 0;
|
||||
uint32_t message_length = strlen(message) + 1;
|
||||
for (int i = 0; i < message_length; ++i) {
|
||||
if (message[i] == '"' || message[i] == '\'') {
|
||||
if (outer_quote && outer_quote == message[i]) outer_quote = 0;
|
||||
else if (!outer_quote) outer_quote = message[i];
|
||||
continue;
|
||||
}
|
||||
formatted_message[caret] = message[i];
|
||||
if (message[i] == ' ' && !outer_quote) formatted_message[caret] = '\0';
|
||||
caret++;
|
||||
}
|
||||
|
||||
if (caret > 0 && formatted_message[caret] == '\0'
|
||||
&& formatted_message[caret - 1] == '\0') {
|
||||
caret--;
|
||||
}
|
||||
formatted_message[caret] = '\0';
|
||||
return caret + 1;
|
||||
}
|
||||
|
||||
static inline void sketchybar(char* message) {
|
||||
char formatted_message[strlen(message) + 2];
|
||||
uint32_t length = format_message(message, formatted_message);
|
||||
if (!length) return;
|
||||
|
||||
if (!g_mach_port) g_mach_port = mach_get_bs_port();
|
||||
if (!mach_send_message(g_mach_port, formatted_message, length)) {
|
||||
g_mach_port = mach_get_bs_port();
|
||||
if (!mach_send_message(g_mach_port, formatted_message, length)) {
|
||||
// No sketchybar instance running, exit.
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue