This commit is contained in:
end-4
2024-02-22 15:35:06 +07:00
commit 8db26e9707
4220 changed files with 208544 additions and 0 deletions
+12
View File
@@ -0,0 +1,12 @@
#!/usr/bin/bash
hyprctl activewindow -j | gojq -c -M
if [ "$1" == "--once" ]; then
exit 0
else
socat -u UNIX-CONNECT:/tmp/hypr/"$HYPRLAND_INSTANCE_SIGNATURE"/.socket2.sock - | rg --line-buffered "window>>" | while read -r line; do
hyprctl activewindow -j | gojq -c -M
done
fi
+17
View File
@@ -0,0 +1,17 @@
#!/usr/bin/bash
hyprctl activeworkspace -j | gojq '.id'
if [ "$1" == "--once" ]; then
exit 0
else
socat -u UNIX-CONNECT:/tmp/hypr/"$HYPRLAND_INSTANCE_SIGNATURE"/.socket2.sock - | rg --line-buffered "workspace>>" | while read -r line; do
case ${line%>>*} in
"workspace")
focusedws=${line#*>>}
echo "$focusedws"
;;
esac
done
fi
+31
View File
@@ -0,0 +1,31 @@
#!/bin/sh
STATUS="$(rfkill list | sed -n 2p | awk '{print $3}')"
icon() {
if [[ $STATUS == "no" ]]; then
echo ""
else
echo ""
fi
}
toggle() {
if [[ $STATUS == "no" ]]; then
rfkill block all
notify-send --urgency=normal -i airplane-mode-symbolic "Airplane Mode" "Airplane mode has been turned on!"
else
rfkill unblock all
notify-send --urgency=normal -i airplane-mode-disabled-symbolic "Airplane Mode" "Airplane mode has been turned off!"
fi
}
if [[ $1 == "toggle" ]]; then
toggle
else
while true; do
STATUS="$(rfkill list | sed -n 2p | awk '{print $3}')"
icon
sleep 3;
done
fi
+137
View File
@@ -0,0 +1,137 @@
#include <pwd.h>
#include <unistd.h>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include "nlohmann/json.hpp"
using namespace std;
using json = nlohmann::json;
// A simple struct to store the name and exec properties of a desktop entry
struct DesktopEntry {
string name;
string exec;
string icon;
bool show;
};
string username;
vector<DesktopEntry> allApps;
json apps;
int mode = 0; // 0: Object, 1: Array
// A function that reads a .desktop file and returns a DesktopEntry struct
DesktopEntry read_desktop_file(const string& filename) {
DesktopEntry entry;
entry.show = true;
ifstream file(filename);
if (file.is_open()) {
string line;
while (getline(file, line)) {
// Skip comments and empty lines
if (line.empty() || line[0] == '#') {
continue;
}
if (line.substr(0, 1) == "[" &&
line.substr(0, 15) == "[Desktop Action")
break;
// Split the line by '=' and store the key-value pair
size_t pos = line.find('=');
if (pos != string::npos) {
string key = line.substr(0, pos);
string value = line.substr(pos + 1);
// Store the name and exec properties
if (key == "Name") {
entry.name = value;
} else if (key == "Exec") {
entry.exec = value;
} else if (key == "Icon") {
entry.icon = value;
} else if (key == "NoDisplay" && value == "true") {
entry.show = false;
}
}
}
// cout << entry.name << " " << entry.exec << " " << entry.icon << "\n";
file.close();
}
return entry;
}
bool lf(DesktopEntry a, DesktopEntry b) { return a.name < b.name; }
// A function that prints out all desktop entry names and exec properties in a
// given directory
void getDesktopEntries(const string& dirname) {
// Check if the directory exists
if (!filesystem::exists(dirname) || !filesystem::is_directory(dirname)) {
return;
}
// Iterate over all files in the directory
for (const auto& entry : filesystem::directory_iterator(dirname)) {
// Check if the file has a .desktop extension
if (entry.path().extension() == ".desktop") {
DesktopEntry thisEntry = read_desktop_file(entry.path());
if (thisEntry.show) allApps.push_back(thisEntry);
}
}
}
void to_json() {
sort(allApps.begin(), allApps.end(), lf);
for (const auto& entry : allApps) {
json thisApp;
thisApp["name"] = entry.name;
thisApp["icon"] = entry.icon;
thisApp["exec"] = entry.exec;
// Get
if (mode == 0)
apps[entry.name] = thisApp;
else
apps.push_back(thisApp);
}
}
string get_username() {
uid_t uid = geteuid();
struct passwd* pw = getpwuid(uid);
return pw->pw_name;
}
int main(int argc, char* argv[]) {
ios::sync_with_stdio(false);
cin.tie(nullptr);
if (argc == 3 && string(argv[1]) == "--mode") {
if (string(argv[2]) == "object")
mode = 0;
else if (string(argv[2]) == "array")
mode = 1;
else
mode = stoi(string(argv[2]));
}
username = get_username();
// Print all desktop entries in /usr/share/applications/
string entryDirs[3] = {"/usr/share/applications/",
"/home/" + username + "/.local/share/applications",
"/var/lib/flatpak/exports/share/applications"};
for (string directory : entryDirs) {
if (filesystem::exists(directory))
getDesktopEntries(directory);
}
// Get em in the json object
to_json();
// Print
for (const auto& entry : allApps) {
cout << entry.name << '\n';
}
return 0;
}
+254
View File
@@ -0,0 +1,254 @@
#include <pwd.h>
#include <sys/stat.h>
#include <unistd.h>
#include <algorithm>
#include <cctype>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include "nlohmann/json.hpp"
using namespace std;
using json = nlohmann::json;
// A simple struct to store the name and exec properties of a desktop entry
struct DesktopEntry {
string name;
string exec;
string icon;
string filename;
string filepath;
bool show;
};
string username;
vector<DesktopEntry> allApps;
json apps;
int mode = 0; // 0: Object, 1: Array, 2: Start (Contains JSON for letters)
string iconTheme = "";
// Returns the file name from a path
std::string getFileName(const std::string& path) {
// Find the last position of '/' or '\' in the path
size_t pos = path.find_last_of("/\\");
// If none is found, return the whole path
if (pos == std::string::npos) return path;
// Otherwise, return the substring after the last slash
return path.substr(pos + 1);
}
// Returns the file name without extension from a path
string getFileNameNoExt(const string& path) {
string filename = getFileName(path); // Get file name (with extension)
size_t pos = filename.find_last_of(".");
if (pos == string::npos) return filename; // Name found
return filename.substr(0, pos);
}
// Function to check if file exists, if yes read it
string readIfExists(const string& name) {
ifstream f(name.c_str());
stringstream buffer;
if (f) { // check if the file was opened successfully
buffer << f.rdbuf(); // read the whole file into a string stream
f.close(); // close the file when done
}
return buffer.str(); // return the string stream as a string
}
void writeToFile(const string& name, const string& content) {
ofstream f(name.c_str(), ios::app); // open the file in append mode
if (f) { // check if the file was opened successfully
f << content << "\n"; // write the content to the file
f.close(); // close the file when done
} else {
cerr << "Error: could not open " << name
<< "\n"; // print an error message to the standard error
}
}
string exec(const char* cmd) {
array<char, 128> buffer;
string result;
unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose);
if (!pipe) {
throw runtime_error("popen() failed!");
}
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
result += buffer.data();
}
return result;
}
string getIconPath(string iconname) {
if (iconTheme == "") {
iconTheme =
exec(string("gsettings get org.gnome.desktop.interface icon-theme")
.c_str());
iconTheme.pop_back();
// cout << "icon theme: " << iconTheme << '\n';
}
if (iconname.size() == 0) {
return "";
} else if (iconname[0] == '/') {
return iconname; // Already absolute path
} else if (iconname[0] == '\n') {
return ""; // wtf
}
string path = readIfExists("/home/" + username + "/.config/eww/scripts/cache/" + iconname);
if (path == "") {
path = exec(string("geticons -t " + iconTheme + " " + string(iconname) +
" | head -n 1")
.c_str());
// cout << "path: " << path << '\n';
writeToFile("/home/" + username + "/.config/eww/scripts/cache/" + iconname, path);
// cout << "icon name: " << iconname << '\n';
// cout << "path: " << path << '\n';
}
while (path.size() > 0 && *path.rbegin() == '\n')
path.pop_back(); // Remove '\n'
return path;
}
// A function that reads a .desktop file and returns a DesktopEntry struct
DesktopEntry readDesktopFile(const string& filename) {
DesktopEntry entry;
entry.show = true;
entry.filename = getFileNameNoExt(filename);
entry.filepath = filename;
ifstream file(filename);
if (file.is_open()) {
string line;
while (getline(file, line)) {
// Skip comments and empty lines
if (line.empty() || line[0] == '#') {
continue;
}
if (line.substr(0, 1) == "[" &&
line.substr(0, 15) == "[Desktop Action")
break;
// Split the line by '=' and store the key-value pair
size_t pos = line.find('=');
if (pos != string::npos) {
string key = line.substr(0, pos);
string value = line.substr(pos + 1);
// Store properties
if (key == "Name") {
entry.name = value;
} else if (key == "Exec") {
entry.exec = value;
} else if (key == "Icon") {
entry.icon = getIconPath(value);
} else if (key == "NoDisplay" && value == "true") {
entry.show = false;
}
}
}
file.close();
}
return entry;
}
string lowercaseOf(string s) {
for (char& c : s) {
c = tolower(c);
}
return s;
}
bool lf(DesktopEntry a, DesktopEntry b) {
if (tolower(a.name[0]) == tolower(b.name[0]))
return a.name < b.name;
else
return tolower(a.name[0]) < tolower(b.name[0]);
}
// A function that prints out all desktop entry names and exec properties in a
// given directory
void getDesktopEntries(const string& dirname) {
// Iterate over all files in the directory
for (const auto& entry : filesystem::directory_iterator(dirname)) {
// Check if the file has a .desktop extension
if (entry.path().extension() == ".desktop") {
// Read the file and print its name and exec properties
DesktopEntry thisEntry = readDesktopFile(entry.path());
// cout << thisEntry.name << " [icon: " << thisEntry.icon << "]\n";
if (thisEntry.show) allApps.push_back(thisEntry);
}
}
}
void toJson() {
sort(allApps.begin(), allApps.end(), lf);
int i = -1;
for (const auto& entry : allApps) {
i++;
// cout << entry.name << ", ";
json thisApp;
thisApp["name"] = entry.name;
thisApp["icon"] = entry.icon;
thisApp["exec"] = entry.exec;
if (mode != 2) {
thisApp["filename"] = entry.filename;
thisApp["filepath"] = entry.filepath;
}
// Get
if (mode == 0)
apps[entry.name] = thisApp;
else if (mode == 1)
apps.push_back(thisApp);
else if (mode == 2) {
apps.push_back(thisApp);
}
}
cout << apps << '\n';
}
string getUsername() {
uid_t uid = geteuid();
struct passwd* pw = getpwuid(uid);
return pw->pw_name;
}
void addLetters() {
for (char c = 'A'; c <= 'Z'; c++) {
DesktopEntry thisLetter;
thisLetter.name = c;
thisLetter.exec = "";
thisLetter.icon = "_letter";
allApps.push_back(thisLetter);
}
}
int main(int argc, char* argv[]) {
ios::sync_with_stdio(false);
cin.tie(nullptr);
if (argc == 3 && string(argv[1]) == "--mode") {
if (string(argv[2]) == "object")
mode = 0;
else if (string(argv[2]) == "array")
mode = 1;
else if (string(argv[2]) == "start")
mode = 2;
else
mode = stoi(string(argv[2]));
}
username = getUsername();
// Print all desktop entries in common locations
string entryDirs[3] = {"/usr/share/applications/",
"/home/" + username + "/.local/share/applications",
"/var/lib/flatpak/exports/share/applications"};
for (string directory : entryDirs) {
if (filesystem::exists(directory))
getDesktopEntries(directory);
}
if (mode == 2) addLetters();
// Get a json and print
toJson();
}
+68
View File
@@ -0,0 +1,68 @@
#!/usr/bin/env bash
cd "$HOME/.config/eww" || exit
filelist=$(ls 'images/svg/template/' | grep -v /)
colorscss=$(cat css/_material.scss)
colornames=$(cat css/_material.scss | cut -d: -f1)
colorstrings=$(cat css/_material.scss | cut -d: -f2 | cut -d ' ' -f2 | cut -d ";" -f1)
IFS=$'\n'
filearr=( $filelist ) # Get colors
colorlist=( $colornames ) # Array of color names
colorvalues=( $colorstrings ) # Array of color values
apply_svgs() {
for i in "${!filearr[@]}"; do # Loop through folders
colorvalue=$(echo "$colorscss" | grep "${filearr[$i]}" | awk '{print $2}' | cut -d ";" -f1)
for file in images/svg/template/"${filearr[$i]}"/*; do # Loop through files
cp "$file" images/svg/
sed -i "s/black/$colorvalue/g" images/svg/"${file##*/}"
done
done
}
apply_gtklock() {
# Check if $HOME/.config/eww/scripts/templates/gtklock/style.css exists
if [ ! -f "$HOME/.config/eww/scripts/templates/gtklock/style.css" ]; then
echo "Template file not found for Gtklock. Skipping that."
return
fi
# Copy template to style.css
cp "$HOME/.config/eww/scripts/templates/gtklock/style.css" "$HOME/.config/gtklock/style.css"
# Apply colors
for i in "${!colorlist[@]}"; do
sed -i "s/${colorlist[$i]};/${colorvalues[$i]};/g" "$HOME/.config/gtklock/style.css"
done
}
apply_fuzzel() {
# Check if $HOME/.config/eww/scripts/templates/fuzzel/fuzzel.ini exists
if [ ! -f "$HOME/.config/eww/scripts/templates/fuzzel/fuzzel.ini" ]; then
echo "Template file not found for Fuzzel. Skipping that."
return
fi
# Copy template to style.css
cp "$HOME/.config/eww/scripts/templates/fuzzel/fuzzel.ini" "$HOME/.config/fuzzel/fuzzel.ini"
# Apply colors
for i in "${!colorlist[@]}"; do
sed -i "s/${colorlist[$i]}ff/${colorvalues[$i]#\#}ff/g" "$HOME/.config/fuzzel/fuzzel.ini" # note: ff because theyre opaque
done
}
apply_foot() {
# Check if $HOME/.config/eww/scripts/templates/fuzzel/fuzzel.ini exists
if [ ! -f "$HOME/.config/eww/scripts/templates/foot/foot.ini" ]; then
echo "Template file not found for Foot. Skipping that."
return
fi
# Copy template to style.css
cp "$HOME/.config/eww/scripts/templates/foot/foot.ini" "$HOME/.config/foot/foot.ini"
# Apply colors
for i in "${!colorlist[@]}"; do
sed -i "s/=${colorlist[$i]} #/=${colorvalues[$i]#\#}/g" "$HOME/.config/foot/foot.ini" # note: ff because theyre opaque
done
}
apply_svgs
apply_gtklock
apply_fuzzel
apply_foot
+203
View File
@@ -0,0 +1,203 @@
#include <array>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
#include <vector>
#include "nlohmann/json.hpp"
using namespace std;
using json = nlohmann::json;
string searchTerm;
string results;
vector<string> entryNames;
json appEntries;
bool updateInfo = false;
void splitString(const std::string& str, const char delimiter,
std::vector<std::string>& result) {
std::string line;
std::istringstream stream(str);
while (std::getline(stream, line)) {
if (!line.empty()) {
if (line.back() == delimiter) {
line.pop_back();
}
result.push_back(line);
}
}
}
string exec(const char* cmd) {
array<char, 128> buffer;
string result;
unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose);
if (!pipe) {
throw runtime_error("popen() failed!");
}
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
result += buffer.data();
}
return result;
}
bool likelyNotMath(const string& expression) {
char firstChar = expression[0];
if (firstChar >= '0' && firstChar <= '9') return false;
return true;
}
void calcPrompt() {
cout << "[{\"name\":\"Calculator - Type "
"something!\",\"icon\":\"images/svg/dark/"
"calculator.svg\",\"exec\":\"wl-copy \\\"Clipboard contents "
";)\\\"\"}]";
exec(
"eww update winsearch_actions='{\"name\":\"Calculator - Type "
"something!\",\"icon\":\"images/svg/dark/"
"calculator.svg\",\"exec\":\"wl-copy \\\"Clipboard contents "
";)\\\"\"}' &");
exec("eww update winsearch_actions_type='Math result' &");
exit(0);
}
void getAppNames() {
string searchCommand =
"cat 'scripts/cache/entrynames.txt' | fzf --filter=\"" + searchTerm +
"\" | head -n 10";
string results = exec(&searchCommand[0]);
splitString(results, '\n', entryNames);
}
void getAppJson() {
ifstream file("scripts/cache/entries.txt");
file >> appEntries;
}
void tryThemeCmd() {
if (searchTerm.size() >= 6)
searchTerm = searchTerm.substr(6);
else
searchTerm = " ";
string searchCommand =
"ls css/savedcolors/ | grep .txt | sed 's/_iconcolor_//g' | sed "
"'s/.txt//g' | fzf --filter='" +
searchTerm + "'";
string results = exec(&searchCommand[0]);
splitString(results, '\n', entryNames);
cout << '[';
for (int i = 0; i < entryNames.size(); i++) {
string entryName = entryNames[i];
cout << '{';
cout << "\"name\":\"" << entryName << "\",\"exec\":\">load "
<< entryName << "\"";
cout << '}';
if (i < entryNames.size() - 1) cout << ',';
}
cout << ']' << endl;
if (updateInfo) {
string entryName = entryNames[0];
string updateCmd = "eww update winsearch_actions='{\"name\":\"" +
entryName + "\",\"exec\":\">load " + entryName +
"\"}'";
exec(&updateCmd[0]);
exec("eww update winsearch_actions_type='Color theme'");
}
exit(0);
}
void tryAppSearch() {
if (entryNames.size() == 0) return; // No app found, skip it
cout << '[';
for (int i = 0; i < entryNames.size(); i++) {
string entryName = entryNames[i];
cout << appEntries[entryName];
if (i < entryNames.size() - 1) cout << ',';
}
cout << ']' << endl;
if (updateInfo) {
string updateCmd = "eww update winsearch_actions='" +
string(appEntries[entryNames[0]].dump()) + "'";
exec(&updateCmd[0]);
exec("eww update winsearch_actions_type='Application'");
}
exit(0);
}
void tryCalculate() {
if (likelyNotMath(searchTerm)) return;
string calcCommand = "qalc '" + searchTerm + "'";
string results = exec(&calcCommand[0]);
results = results.substr(results.find_first_of("=") + 2);
if(results.back() == '\n') results.pop_back();
// cout << results << '\n';
cout
<< "[{\"name\":\"" << results
<< "\",\"icon\":\"images/svg/dark/calculator.svg\",\"exec\":\"wl-copy '"
<< results << "'\"}]" << endl;
if (updateInfo) {
string updateCmd =
"eww update "
"winsearch_actions='{\"name\":\"'\"" +
results +
"\"'\",\"icon\":\"images/svg/dark/"
"calculator.svg\",\"exec\":\"wl-copy '" +
results + "'\"}'";
exec(&updateCmd[0]);
exec("eww update winsearch_actions_type='Math result'");
}
exit(0);
}
void commandOnly() {
cout << "[]" << endl;
if (updateInfo) {
string updateCmd =
"eww update "
"winsearch_actions='{\"name\":\"'\"" +
searchTerm +
"\"'\",\"icon\":\"images/svg/dark/"
"protocol.svg\",\"exec\":\"" +
searchTerm + "\"}'";
exec(&updateCmd[0]);
exec("eww update winsearch_actions_type='Run command'");
}
exit(0);
}
int main(int argc, char* argv[]) {
ios::sync_with_stdio(false);
cin.tie(nullptr);
// Arguments
if (argc == 1) {
cout << "[{\"name\": \"Type something!\"}]";
return 0;
}
if (argc > 2 && string(argv[2]) == "--updateinfo") updateInfo = true;
searchTerm = argv[1];
// Special commands
if (searchTerm == "--calculator") calcPrompt();
if (searchTerm[0] == '>') {
if (searchTerm.find(">load") != string::npos)
tryThemeCmd();
else {
cout << "[]" << endl;
exit(0);
}
}
// Get app names and entries
getAppNames();
getAppJson();
// Attempt searches in order. Each search will exit if success
tryCalculate();
tryAppSearch();
commandOnly();
cout << results;
}
+137
View File
@@ -0,0 +1,137 @@
#include <array>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
#include <vector>
#include "nlohmann/json.hpp"
using namespace std;
using json = nlohmann::json;
string clients;
json clientjson, apps;
string iconTheme = "";
string exec(const char* cmd) {
array<char, 128> buffer;
string result;
unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose);
if (!pipe) {
throw runtime_error("popen() failed!");
}
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
result += buffer.data();
}
return result;
}
// Function to check if file exists, if yes read it
string readIfExists(const string& name) {
ifstream f(name.c_str());
stringstream buffer;
if (f) { // check if the file was opened successfully
buffer << f.rdbuf(); // read the whole file into a string stream
f.close(); // close the file when done
}
return buffer.str(); // return the string stream as a string
}
void writeToFile(const string& name, const string& content) {
ofstream f(name.c_str(), ios::app); // open the file in append mode
if (f) { // check if the file was opened successfully
f << content << "\n"; // write the content to the file
f.close(); // close the file when done
} else {
cerr << "Error: could not open " << name
<< "\n"; // print an error message to the standard error
}
}
string getIconPath(string iconname) {
if (iconTheme == "") {
iconTheme =
exec(string("gsettings get org.gnome.desktop.interface icon-theme")
.c_str());
iconTheme.pop_back();
// cout << "icon theme: " << iconTheme << '\n';
}
if (iconname.size() == 0) {
return "";
} else if (iconname[0] == '/') {
return iconname; // Already absolute path
} else if (iconname[0] == '\n') {
return ""; // wtf
}
string path = readIfExists("scripts/cache/" + iconname);
if (path == "") {
path = exec(string("geticons -t " + iconTheme + " " + string(iconname) +
" | head -n 1")
.c_str());
writeToFile("scripts/cache/" + iconname, path);
// cout << "icon name: " << iconname << '\n';
// cout << "path: " << path << '\n';
}
while (path.size() > 0 && *path.rbegin() == '\n')
path.pop_back(); // Remove '\n'
return path;
}
void addApp(json& client) {
string volumestr = client["volume"]["front-left"]["value_percent"];
volumestr.pop_back();
int volume = stoi(volumestr);
client = client["properties"];
bool found = false;
for (json& obj : apps) {
auto it = obj.find("name");
if (it != obj.end() && *it == client["application.name"]) {
found = true;
obj["count"] = int(obj["count"]) + 1;
obj["clients"].push_back(
json{{"serial", client["object.serial"]},
{"volume", volume},
{"title", client["media.name"]}});
break;
}
}
if (!found) {
json newApp =
R"({"name": "", "count": 1, "clients": [], "icon": "", "title": []})"_json;
newApp["name"] = client["application.name"];
newApp["clients"].push_back(json{{"serial", client["object.serial"]},
{"volume", volume},
{"title", client["media.name"]}});
string iconpath;
auto it = client.find("application.icon_name");
if (it != client.end())
iconpath = getIconPath(client["application.icon_name"]);
else {
iconpath = getIconPath(client["application.process.binary"]);
}
newApp["icon"] = iconpath;
apps.push_back(newApp);
}
}
void getAudioClients() {
clients = exec("pactl --format json list sink-inputs 2>/dev/null");
clientjson = json::parse(clients);
for (json client : clientjson) {
addApp(client);
// cout << client << '\n';
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
getAudioClients();
cout << apps << '\n';
}
+84
View File
@@ -0,0 +1,84 @@
#!/usr/bin/bash
dostuff(){
sinks=$(pactl list sink-inputs \
| grep -e "Sink Input" \
| sed 's/Sink Input #//')
names=$(pactl list sink-inputs \
| sed 's/"//g' \
| sed 's/application-name://' \
| grep -e "application.name" \
| sed 's/application.name = //' \
| sed 's/\t\t//' )
vols=$(pactl list sink-inputs \
| grep -e "Volume:" \
| sed 's/Volume: front-left: //' \
| sed 's/front-right: //' \
| sed 's/front-right: //' \
| tr " " "\n" \
| grep -e % \
| sed 's/%//g' )
binaries=$(pactl list sink-inputs \
| grep -e 'application.process.binary' -e 'application.icon_name' \
| sed 's/\t//g' \
| sed 's/application.process.binary = //g' \
| sed 's/application.icon_name = //g' \
| sed 's/"//g' )
# echo "-=-=-=-=-=-=-=-=- Debug: Raw value -=-=-=-=-=-=-=-=-"
# echo "$sinks"
# echo "$names"
# echo "$vols"
IFS=$'\n'
sinkarr=($(echo "$sinks"))
namearr=($(echo "$names"))
volarr=($(echo "$vols"))
iconarr=($(echo "$binaries"))
# Get icons
for i in "${!iconarr[@]}"; do
iconarr[$i]=$(geticons -t "$(gsettings get org.gnome.desktop.interface icon-theme | sed "s/'//g")" ${iconarr[i]} | head -n 1)
done
# Functions
sanitize() {
echo "$1" | sed 's/"/\"/g'
}
geticon() {
# notify-send "${volarr[$((i*2))]}"
if [ "${volarr[$(($1*2))]}" -eq "0" ]; then
echo ""
else
echo ""
fi
}
# Print final JSON
printf '['
for i in "${!sinkarr[@]}"; do
if [ $i -ne 0 ]; then
printf ', '
fi
echo -n '{''"sink": "'"${sinkarr[$i]}"'", "name": "'"${namearr[$i]}"'", "volume": "'"${volarr[$((i*2))]}"'"}'
# echo -n '{''"sink": "'"${sinkarr[$i]}"'", "icon": "'"${iconarr[$i]}"'", "name": "'"${namearr[$i]}"'", "volume": "'"${volarr[$((i*2))]}"'"}'
done
printf ']\n'
# echo "$sinks"
# echo "$names"
# echo "$vols"
}
cd ~/.config/eww
# dostuff
scripts/audioapps
if [ "$1" == "--once" ]; then
exit 0
else
pactl subscribe | rg --line-buffered "on sink" | while read -r _; do
scripts/audioapps
done
fi
+132
View File
@@ -0,0 +1,132 @@
#!/usr/bin/env bash
icons=("" "" "" "" "" "" "" "")
gettime() {
# FULL=$(cat /sys/class/power_supply/*/uevent | grep 'POWER_SUPPLY_CHARGE_FULL=' | cut -d '=' -f2)
# NOW=$(cat /sys/class/power_supply/*/uevent | grep 'POWER_SUPPLY_CHARGE_NOW=' | cut -d '=' -f2)
# RATE=$(cat /sys/class/power_supply/*/uevent | grep 'POWER_SUPPLY_VOLTAGE_NOW=' | cut -d '=' -f2)
if [ "$RATE" -gt 0 ]; then
if [ "$STATE" = "Discharging" ]; then
upower -e | grep battery | while read line; do upower -i $line; done | grep 'time to empty:' | cut -d ':' -f2 | sed 's/ //g' | sed 's/ours//g' | sed 's/inutes//g'
else
upower -e | grep battery | while read line; do upower -i $line; done | grep 'time to full:' | cut -d ':' -f2 | sed 's/ //g' | sed 's/ours//g' | sed 's/inutes//g'
fi
date -u -d@"$(bc -l <<< "$EX * 3600")" +%H:%M
fi
}
geticon() {
if [ "$STATE" = "Charging" ]; then
level=$(awk -v n="$CAPACITY" 'BEGIN{print int((n-1)/12)}')
echo "${icons[$level]}"
else
level=$(awk -v n="$CAPACITY" 'BEGIN{print int((n-1)/12)}')
echo "${icons[$level]}"
fi
}
status() {
if [ "$STATE" = "Charging" ]; then
if [ "$RATE" -gt 0 ]; then
echo "$(gettime) to full"
else
echo ""
fi
elif [ "$STATE" = "Discharging" ]; then
echo "$(gettime) left"
else
echo "fully charged"
fi
}
statch() {
if [ "$STATE" = "Discharging" ]; then #Not charging, below 20%
if [ "$CAPACITY" -le 5 ]; then
echo 'deadly'
elif [ "$CAPACITY" -le 10 ]; then
echo 'critical'
elif [ "$CAPACITY" -le 30 ]; then
echo 'low'
else
echo 'normal'
fi
else
echo 'charging'
fi
}
chargestatus() {
if [ "$STATE" = "Charging" ]; then
echo -n ""
elif [ "$STATE" = "Discharging" ]; then
echo -n ""
fi
}
circolor() {
if [[ "$CAPACITY" -le 20 && "$STATE" = "Discharging" ]]; then
cat css/_iconcolor.txt | head -1
else
cat css/_iconcolor.txt | head -1
fi
}
cirbgcolor() {
if [[ "$CAPACITY" -le 20 && "$STATE" = "Discharging" ]]; then
echo '#EF738A'
else
echo 'transparent'
fi
}
color() {
if [ "$CAPACITY" -le 20 ]; then
echo '#EF738A'
else
echo 'white'
fi
}
bgcolor() {
if [ "$CAPACITY" -le 20 ]; then
echo '#EF738A'
else
echo 'transparent'
fi
}
wattage() {
echo "$(bc -l <<< "scale=1; $RATE / 1000000") W"
}
warnedlow=0
while true; do
RATE=$(cat /sys/class/power_supply/*/voltage_now | head -1)
CAPACITY=$(cat /sys/class/power_supply/*/capacity | head -1)
STATE=$(cat /sys/class/power_supply/*/status | head -1)
if [[ "$CAPACITY" -le 5 && "$STATE" = "Discharging" ]]; then
if [ $warnedlow == 0 ]; then
warnedlow=1
notify-send 'FREAKING PLUG IN THE CHARGER ALREADY' '!!111!!1!123!!!' -u critical -a 'eww'
fi
elif [[ "$CAPACITY" -le 10 && "$STATE" = "Discharging" ]]; then
if [ $warnedlow == 0 ]; then
warnedlow=1
notify-send 'Battery verrry low' 'Hello?' -u critical -a 'eww'
fi
elif [[ "$CAPACITY" -le 20 && "$STATE" = "Discharging" ]]; then
if [ $warnedlow == 0 ]; then
warnedlow=1
notify-send 'Battery low' 'Plug in your charger pweeeeaaase :>' -u critical -a 'eww'
fi
else
warnedlow=0
fi
echo '{"quickicon": "'"$(chargestatus)"'", "percentage": '"$CAPACITY"', "status": "'"$(status)"'"}'
sleep 3
done
+51
View File
@@ -0,0 +1,51 @@
#!/usr/bin/env bash
declare -A baticon=([10]="󰤾" [20]="󰤿" [30]="󰥀" [40]="󰥁" [50]="󰥂" [60]="󰥃" [70]="󰥄" [80]="󰥅" [90]="󰥆" [100]="󰥈")
toggle() {
status=$(rfkill -J | jq -r '.rfkilldevices[] | select(.type == "bluetooth") | .soft' | head -1)
if [ "$status" = "unblocked" ]; then
rfkill block bluetooth
else
rfkill unblock bluetooth
fi
}
if [ "$1" = "toggle" ]; then
toggle
else
while true; do
powered=$(bluetoothctl show | rg Powered | cut -f 2- -d ' ')
status=$(bluetoothctl info)
name=$(echo "$status" | rg Name | cut -f 2- -d ' ')
mac=$(echo "$status" | head -1 | awk '{print $2}' | tr ':' '_')
if [[ "$(echo "$status" | rg Percentage)" != "" ]]; then
battery=$(upower -i /org/freedesktop/UPower/devices/headset_dev_"$mac" | rg percentage | awk '{print $2}' | cut -f 1 -d '%')
batt_icon=${baticon[$battery]}
else
batt_icon=""
fi
if [ "$powered" = "yes" ]; then
if [ "$status" != "Missing device address argument" ]; then
text="$name"
icon=""
color="#89b4fa"
else
icon=""
text="Disconnected"
color="#45475a"
fi
else
icon=""
text="Bluetooth off"
color="#45475a"
fi
echo '{ "icon": "'"$icon"'", "batt_icon": "'"$batt_icon"'", "text": "'"$text"'", "color": "'"$color"'" }'
sleep 3
done
fi
+59
View File
@@ -0,0 +1,59 @@
#!/usr/bin/env bash
cd ~/.config/eww
icons=("" "" "")
XDG_CACHE_HOME="$HOME/.cache"
date="$XDG_CACHE_HOME/eww/osd_brightness.date"
lock=0
showhide() {
# get dates
rundate=$(cat "$date")
currentdate=$(date +%s)
# handle showing
if [ "$rundate" = "$currentdate" ] && [ "$lock" -eq 0 ]; then
scripts/toggle-osd-bright.sh --open
lock=1
elif [ $((currentdate - rundate)) -ge 2 ] && [ "$lock" -eq 1 ]; then
scripts/toggle-osd-bright.sh --close > /dev/null
lock=0
fi
}
osd() {
if [ ! -f "$date" ]; then
mkdir -p "$XDG_CACHE_HOME/eww"
fi
date +%s > "$date"
# showhide
}
osd_handler() {
lock=0
rundate=0
if [ ! -f "$date" ]; then
mkdir -p "$XDG_CACHE_HOME/eww"
echo 0 > "$date"
fi
while true; do
showhide
sleep 0.1
done
}
if [ "$1" = "osd" ]; then
osd
else
# initial
icon=${icons[$(awk -v n="$(light)" 'BEGIN{print int(n/34)}')]}
echo '{ "level": '"$(light)"', "icon": "'"$icon"'" }'
osd_handler &
udevadm monitor | rg --line-buffered "backlight" | while read -r _; do
icon="${icons[$(awk -v n="$(light)" 'BEGIN{print int(n/34)}')]}"
echo '{ "level": '"$(light)"', "icon": "'"$icon"'" }'
done
fi
+138
View File
@@ -0,0 +1,138 @@
#include <chrono>
#include <ctime>
#include <iostream>
#include <string>
using namespace std;
int year, month, day, weekday, weekdayOfMonthFirst;
bool leapYear;
int daysInMonth, daysInLastMonth, daysInNextMonth;
bool highlight = true;
int calendar[6][7];
int today[6][7];
void getTime() {
// Time
time_t now = time(0);
tm* ltm = localtime(&now);
// To vars
year = 1900 + ltm->tm_year;
month = 1 + ltm->tm_mon;
day = ltm->tm_mday;
weekday = ltm->tm_wday - 1;
weekdayOfMonthFirst = (weekday + 35 - (day - 1)) % 7;
// cout << weekday << ", " << day << '/' << month << '/' << year << '\n';
}
void setTime(int wd, int d, int m, int y) {
wd--;
highlight = false;
year = y;
month = m;
day = d;
weekday = wd;
weekdayOfMonthFirst = (weekday + 35 - (day - 1)) % 7;
// cout << weekday << ", " << day << '/' << month << '/' << year << '\n';
}
void checkLeapYear() {
if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))
leapYear = true;
else
leapYear = false;
}
void getMonthDays() {
// Days in this month
if ((month <= 7 && month % 2 == 1) || (month >= 8 && month % 2 == 0))
daysInMonth = 31;
else if (month == 2 && leapYear)
daysInMonth = 29;
else if (month == 2 && !leapYear)
daysInMonth = 28;
else
daysInMonth = 30;
// Days in next month
if (month == 1 && leapYear)
daysInNextMonth = 29;
else if (month == 1 && !leapYear)
daysInNextMonth = 28;
else if ((month <= 7 && month % 2 == 1) || (month >= 8 && month % 2 == 0))
daysInNextMonth = 30;
else
daysInNextMonth = 31;
// Days in last month
if (month == 3 && leapYear)
daysInLastMonth = 29;
else if (month == 3 && !leapYear)
daysInLastMonth = 28;
else if ((month <= 7 && month % 2 == 1) || (month >= 8 && month % 2 == 0))
daysInLastMonth = 30;
else
daysInLastMonth = 31;
}
void calcCalendar() {
int monthDiff = (weekdayOfMonthFirst == 0 ? 0 : -1);
int dim = daysInLastMonth;
int i = 0, j = 0;
int toFill = (weekdayOfMonthFirst == 0
? 1
: (daysInLastMonth - (weekdayOfMonthFirst - 1)));
while (i < 6 && j < 7) {
// Fill it
calendar[i][j] = toFill;
if (toFill == day && monthDiff == 0 && highlight)
today[i][j] = 1;
else if (monthDiff == 0)
today[i][j] = 0;
else
today[i][j] = -1;
// Next day
toFill++;
if (toFill > dim) {
monthDiff++;
if (monthDiff == 0)
dim = daysInMonth;
else if (monthDiff == 1)
dim = daysInNextMonth;
toFill = 1;
}
// Next tile
j++;
if (j == 7) {
j = 0;
i++;
}
}
}
void printCalendar() {
cout << '[';
for (int i = 0; i < 6; i++) {
cout << '[';
for (int j = 0; j < 7; j++) {
cout << "{\"day\":" << calendar[i][j]
<< ",\"today\":" << today[i][j] << "}";
if (j < 7 - 1) cout << ',';
}
cout << ']';
if (i < 6 - 1) cout << ',';
}
cout << ']';
}
int main(int argc, char* argv[]) {
if (argc == 1)
getTime();
else if(argc == 5)
setTime(stoi(argv[1]), stoi(argv[2]), stoi(argv[3]), stoi(argv[4]));
else
cout << " - Run \"calendarlayout\" to get calendar for today\n - Run\"calendarlayout <weekday> <day> <month> <year>\" to get calendar of the day specified";
checkLeapYear();
getMonthDays();
calcCalendar();
printCalendar();
}
+42
View File
@@ -0,0 +1,42 @@
#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/iostreams/stream.hpp>
#include <cstdio>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
void cavaToJson(std::string& s) {
int cnt = 0;
std::string newStr = "[";
for (int i = 0; i < s.size(); i++) {
if (s[i] == ';') {
s[i] = ',';
newStr += std::string(',' + std::to_string(cnt++) + "],[");
} else {
newStr.push_back(s[i]);
}
}
newStr.pop_back();
newStr.pop_back();
s = newStr;
}
int main() {
std::unique_ptr<FILE, decltype(&pclose)> pipe(
popen("cava -p ~/.config/eww/scripts/custom_configs/cava", "r"),
pclose);
if (!pipe) {
throw std::runtime_error("popen() failed!");
}
boost::iostreams::file_descriptor_source fd(
fileno(pipe.get()), boost::iostreams::never_close_handle);
boost::iostreams::stream<boost::iostreams::file_descriptor_source> is(fd);
std::string line;
while (std::getline(is, line)) {
cavaToJson(line);
std::cout << '[' << line << ']'
<< std::endl; // print the output line by line
}
return 0;
}
+89
View File
@@ -0,0 +1,89 @@
#!/usr/bin/bash
cd ~/.config/eww || exit
OPACITY=0.75
IMGPATH=$1
coverurl=$2
coverpath=$(echo "$IMGPATH" | sed 's/"//g')
# Generate colors
wal -c
lightdark=$(cat scripts/workdir/__mode_light_dark.txt)
wal -i "$IMGPATH" -n -t -s -e $lightdark -q
themejson=$(cat ~/.cache/wal/colors.json | gojq -c -M)
themejson="${themejson::-1}"
themejson="$themejson"',"source":"'"$3"'"}'
# echo "$themejson"
maincol="$(printf "$themejson" | gojq -c -M -r '.colors.color4')"
generated_material=$(scripts/material_colors.py --color "$maincol" "$lightdark")
echo "$generated_material" > scripts/cache/_material.colorpallete &
cp scripts/cache/_material.colorpallete ~/.config/ags/scss/_material.scss
onPrimaryContainer=$(echo "$generated_material" | grep '$onPrimaryContainer: ' | sed 's/$onPrimaryContainer: //g' | sed 's/;//g')
primaryContainer=$(echo "$generated_material" | grep '$primaryContainer: ' | sed 's/$primaryContainer: //g' | sed 's/;//g')
onSecondaryContainer=$(echo "$generated_material" | grep '$onSecondaryContainer: ' | sed 's/$onSecondaryContainer: //g' | sed 's/;//g')
secondaryContainer=$(echo "$generated_material" | grep '$secondaryContainer: ' | sed 's/$secondaryContainer: //g' | sed 's/;//g')
tertiary=$(echo "$generated_material" | grep '$tertiary: ' | sed 's/$tertiary: //g' | sed 's/;//g')
onPrimary=$(echo "$generated_material" | grep '$onPrimary: ' | sed 's/$onPrimary: //g' | sed 's/;//g')
primary=$(echo "$generated_material" | grep '$primary: ' | sed 's/$primary: //g' | sed 's/;//g')
printf '{"image": "'$coverpath'", "color": '"$themejson"', "materialcolor": {"onPrimaryContainer": "'"$onPrimaryContainer"'", "primaryContainer": "'"$primaryContainer"'", "onPrimary": "'"$onPrimary"'", "primary": "'"$primary"'", "secondaryContainer": "'"$secondaryContainer"'", "onSecondaryContainer": "'"$onSecondaryContainer"'"}}\n'
# Get color in rgb
colorsreg=$(cat ~/.cache/wal/colors-putty.reg)
rgb_bg=$(echo $colorsreg | tr ' ' '\n' | grep 'Colour3')
rgb_bg="${rgb_bg#*=}"
rgb_bg="${rgb_bg#*\"}"
rgb_bg="${rgb_bg::-1}"
rgb_bg='rgba('"$rgb_bg"','"$OPACITY"')'
# echo $rgb_bg
# notify-send 'eww' 'i found a url!'
# Write to scss
echo '//Auto generated color theme for image at:' "$coverurl" > './scripts/cache/_colorscheme.colorpallete'
printf '$colorbarbg: ' >> './scripts/cache/_colorscheme.colorpallete'
printf "$themejson" | gojq -r '.special.background' | tr '\n' ';' >> './scripts/cache/_colorscheme.colorpallete'
echo '' >> './scripts/cache/_colorscheme.colorpallete'
printf '$colorbg: ' >> './scripts/cache/_colorscheme.colorpallete'
printf "$rgb_bg"';' >> './scripts/cache/_colorscheme.colorpallete'
echo '' >> './scripts/cache/_colorscheme.colorpallete'
printf '$colortext: ' >> './scripts/cache/_colorscheme.colorpallete'
printf "$themejson" | gojq -r '.special.foreground' | tr '\n' ';' >> './scripts/cache/_colorscheme.colorpallete'
echo '' >> './scripts/cache/_colorscheme.colorpallete'
printf '$color0: ' >> './scripts/cache/_colorscheme.colorpallete'
printf "$themejson" | gojq -r '.colors.color1' | tr '\n' ';' >> './scripts/cache/_colorscheme.colorpallete'
echo '' >> './scripts/cache/_colorscheme.colorpallete'
printf '$color1: ' >> './scripts/cache/_colorscheme.colorpallete'
printf "$themejson" | gojq -r '.colors.color2' | tr '\n' ';' >> './scripts/cache/_colorscheme.colorpallete'
echo '' >> './scripts/cache/_colorscheme.colorpallete'
printf '$color2: ' >> './scripts/cache/_colorscheme.colorpallete'
printf "$themejson" | gojq -r '.colors.color3' | tr '\n' ';' >> './scripts/cache/_colorscheme.colorpallete'
echo '' >> './scripts/cache/_colorscheme.colorpallete'
printf '$color3: ' >> './scripts/cache/_colorscheme.colorpallete'
printf "$themejson" | gojq -r '.colors.color4' | tr '\n' ';' >> './scripts/cache/_colorscheme.colorpallete'
echo '' >> './scripts/cache/_colorscheme.colorpallete'
printf '$color4: ' >> './scripts/cache/_colorscheme.colorpallete'
printf "$themejson" | gojq -r '.colors.color5' | tr '\n' ';' >> './scripts/cache/_colorscheme.colorpallete'
echo '' >> './scripts/cache/_colorscheme.colorpallete'
printf '$color5: ' >> './scripts/cache/_colorscheme.colorpallete'
printf "$themejson" | gojq -r '.colors.color6' | tr '\n' ';' >> './scripts/cache/_colorscheme.colorpallete'
echo '' >> './scripts/cache/_colorscheme.colorpallete'
printf '$color6: ' >> './scripts/cache/_colorscheme.colorpallete'
printf "$themejson" | gojq -r '.colors.color7' | tr '\n' ';' >> './scripts/cache/_colorscheme.colorpallete'
echo '' >> './scripts/cache/_colorscheme.colorpallete'
printf '$color7: ' >> './scripts/cache/_colorscheme.colorpallete'
printf "$themejson" | gojq -r '.colors.color4' | tr '\n' ';' >> './scripts/cache/_colorscheme.colorpallete'
echo '' >> './scripts/cache/_colorscheme.colorpallete'
# Write hyprland color config
echo '# Auto generated color theme for image at:' "$coverurl" > './scripts/cache/colors_generated.conf'
echo 'general {' >> './scripts/cache/colors_generated.conf'
echo ' col.active_border = rgba('"${primary#*#}FF"') 45deg' >> './scripts/cache/colors_generated.conf'
echo ' col.inactive_border = rgba(555555AA)' >> './scripts/cache/colors_generated.conf'
echo '}' >> './scripts/cache/colors_generated.conf'
# Print json to stdout
cp "$HOME/.cache/wal/colors.json" 'scripts/cache/_iconcolor.txt'
+40
View File
@@ -0,0 +1,40 @@
#!/usr/bin/bash
cd ~/.config/eww/ || exit
if [ $1 == "get" ]; then
hyprctl keyword misc:disable_autoreload true
cp 'scripts/cache/_iconcolor.txt' './css/_iconcolor.txt'
cp 'scripts/cache/_colorscheme.colorpallete' './css/_colorscheme.scss'
cp 'scripts/cache/_material.colorpallete' './css/_material.scss'
cp 'scripts/cache/colors_generated.conf' ~/.config/hypr/colors.conf
applycolor=$(cat './css/_iconcolor.txt' | head -1)
scripts/applycolor "$applycolor"
elif [ $1 == "default" ]; then
hyprctl keyword misc:disable_autoreload true
cp './css/_iconcolor_default.txt' './css/_iconcolor.txt'
cp css/_colorscheme_default.scss css/_colorscheme.scss
cp css/_material_default.scss css/_material.scss
cp ~/.config/hypr/colors_default.conf ~/.config/hypr/colors.conf
applycolor=$(cat css/_iconcolor.txt | head -1)
scripts/applycolor "$applycolor"
elif [ $1 == "save" ]; then
eww close themer
eww update themer_open=false
cp "css/_iconcolor.txt" "css/savedcolors/_iconcolor_$2.txt"
cp "css/_colorscheme.scss" "css/savedcolors/_colorscheme_$2.scss"
cp "css/_material.scss" "css/savedcolors/_material_$2.scss"
cp ~/.config/hypr/colors.conf ~/.config/hypr/savedcolors/colors_$2.conf
elif [ $1 == "load" ]; then
hyprctl keyword misc:disable_autoreload true
eww close themer
eww update themer_open=false
cp "css/savedcolors/_iconcolor_$2.txt" "css/_iconcolor.txt"
cp "css/savedcolors/_colorscheme_$2.scss" "css/_colorscheme.scss"
cp "css/savedcolors/_material_$2.scss" "css/_material.scss"
cp ~/.config/hypr/savedcolors/colors_$2.conf ~/.config/hypr/colors.conf
applycolor=$(cat css/_iconcolor.txt | head -1)
scripts/applycolor "$applycolor"
fi
hyprctl reload
+21
View File
@@ -0,0 +1,21 @@
[general]
mode = normal
framerate = 60
autosens = 1
bars = 70
[output]
method = raw
raw_target = /dev/stdout
data_format = ascii
[smoothing]
monstercat = 1
gravity = 1000000
noise_reduction = 34
[input]
method = pulse
source = auto
@@ -0,0 +1,78 @@
{
"layer": "top",
"height": 30,
"position": "bottom",
"spacing": 0,
"exclusive": false,
"margin-bottom": 50,
"margin-right": 253,
"margin-left": 1556,
"fixed-center": false,
"modules-left": [
],
"modules-center": [
"tray",
],
"modules-right": [
],
"custom/weather": {
"exec": "curl 'https://wttr.in/?format=1' | tr -d '+'",
"interval": 1800
},
"custom/start": {
"format": " ",
"on-click": "~/.config/eww/scripts/toggle-overview.sh"
},
"wlr/taskbar": {
"format": "{icon}",
"icon-size": 24,
"tooltip-format": "{title}",
"on-click": "activate",
"on-click-middle": "close",
},
"clock": {
"format": " {:%I:%M %p%n%e/%m/%G}",
"tooltip-format": "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>",
"format-alt": " {:%Y-%m-%d}"
},
"tray": {
"spacing": 8
},
"pulseaudio": {
"format": "{icon}",
"format-bluetooth": "{volume}% {icon} {format_source}",
"format-bluetooth-muted": " {icon} {format_source}",
"format-muted": " {format_source}",
"format-source": " {volume}",
"format-source-muted": "",
"format-icons": {
"headphone": "",
"hands-free": "",
"headset": "",
"phone": "",
"portable": "",
"car": "",
"default": ["", "", ""]
},
"tooltip-format": "{format_source}%",
"on-click": "easyeffects"
},
"network": {
"format-wifi": "",
"format-ethernet": "",
"tooltip-format": "{ifname} via {gwaddr} ",
"format-linked": "{ifname} (No IP) ",
"format-disconnected": "Disconnected ⚠",
"on-click": "alacritty -e nmtui"
},
}
@@ -0,0 +1,69 @@
* {
color: #f3f9ff;
font-size: 11px;
font-family: 'Lexend';
font-weight: 500;
}
window#waybar {
background: transparent;
}
tooltip {
background: #141414;
border-radius: 4px;
}
#tray {
min-width: 20px;
min-height: 20px;
font-size: 20px;
font-weight: 200;
padding: 4px;
min-width: 100px;
min-height: 37px;
background: rgba(45, 46, 48, 1);
background-image: url('images/textures/acrylic.png');
border-radius: 9px;
border: 1px solid rgba(34, 35, 38, 0.5);
margin: 14px;
box-shadow: 0px 2px 3px rgba(0, 0, 0, 0.65);
}
#window,
#pulseaudio,
#network,
#bluetooth {
font-size: 14px;
font-weight: 200;
padding: 4px;
}
#custom-weather {
padding-left: 12px;
font-size: 11px;
}
#custom-start {
background-image: url("./win.png");
background-size: 24px 24px;
background-position: center;
background-repeat: no-repeat;
}
#taskbar {
border-radius: 6px;
min-width: 45px;
min-height: 45px;
/* border-top: 1px solid rgba(64, 64, 64, 0.8); */
}
#tray,
#pulseaudio {
padding-right: 12px;
}
#clock {
padding-left: 3px;
padding-right: 18px;
}
+79
View File
@@ -0,0 +1,79 @@
#include <array>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
#include <vector>
#include "nlohmann/json.hpp"
using namespace std;
using json = nlohmann::json;
int workspace_a, workspace_b;
string clients;
json clientjson;
vector<string> windows_a, windows_b;
bool output = false;
string exec(const char* cmd) {
array<char, 128> buffer;
string result;
unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose);
if (!pipe) {
throw runtime_error("popen() failed!");
}
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
result += buffer.data();
}
return result;
}
void tryAddApp(const json& client) {
if (int(client["workspace"]["id"]) == workspace_a)
windows_a.push_back(client["address"]);
else if (int(client["workspace"]["id"]) == workspace_b)
windows_b.push_back(client["address"]);
}
void getApps() {
// Get clients
clients = exec("hyprctl clients -j | gojq -c -M");
clientjson = json::parse(clients);
// Access the values
for (json client : clientjson) {
tryAddApp(client);
}
}
void dumptoWorkspace() {
for (string address : windows_a) {
string cmd = "hyprctl dispatch movetoworkspacesilent " +
to_string(workspace_b) + ",address:" + address;
if (output) cout << cmd << '\n';
exec(&cmd[0]);
}
}
int main(int argc, char* argv[]) {
ios::sync_with_stdio(false);
if (argc < 3) {
cout << "Usage: dumptows [WORKSPACE_NUMBER_1] [WORKSPACE_NUMBER_2]"
<< endl;
return 0;
}
if (argc == 4 && string(argv[3]) == "--output") output = true;
workspace_a = stoi(string(argv[1]));
workspace_b = stoi(string(argv[2]));
if (workspace_a <= 0 || workspace_b <= 0 || workspace_a == workspace_b) {
cout << "Nahhh that's stupid" << endl;
return 0;
}
getApps();
dumptoWorkspace();
}
+14
View File
@@ -0,0 +1,14 @@
#!/usr/bin/bash
if [ "$1" == "enable" ]; then
hyprctl keyword bindm ,mouse:273,resizewindow
hyprctl keyword bindm ,mouse:274,movewindow
hyprctl keyword bind ,mouse_up,workspace,+1
hyprctl keyword bind ,mouse_down,workspace,-1
eww update editing=true
elif [ "$1" == "disable" ]; then
hyprctl keyword unbind ,mouse:273
hyprctl keyword unbind ,mouse:274
hyprctl keyword unbind ,mouse_up
hyprctl keyword unbind ,mouse_down
eww update editing=false
fi
+6
View File
@@ -0,0 +1,6 @@
#!/usr/bin/bash
if [[ $1 == '_none' ]]; then
hyprctl dispatch workspace $2
else
hyprctl dispatch focuswindow address:$1
fi
+77
View File
@@ -0,0 +1,77 @@
#!/usr/bin/bash
cd ~/.config/eww
getwins() {
hyprctlclients=$(hyprctl clients -j \
| grep -v '"mapped": ' \
| grep -v '"hidden": ' \
| grep -v '"floating": ' \
| grep -v '"monitor": ' \
| grep -v '"pid": ' \
| grep -v '"xwayland": ' \
| grep -v '"pinned":' \
| grep -v '"fullscreen": ' \
| grep -v '"fullscreenMode": ' \
| grep -v '"fakeFullscreen": ' \
| grep -v '"grouped": ')
# echo $hyprctlclients | gojq -c '.[]'
IFS=$'\n'
clientsarr=( $(echo $hyprctlclients | gojq -c -M '.[]') )
#For every window
for client in "${clientsarr[@]}"; do
iconpath=''
clientclass=$(echo "$client" | gojq -r '.class')
if [[ "$clientclass" == "" ]]; then
continue
fi
# Get app icon
if [ -f "scripts/cache/$clientclass" ]; then
iconpath=$(cat scripts/cache/$clientclass)
if [ ! -f "${iconpath}" ]; then # Cache refresh if icon doesnt exist
iconpath=$(geticons -t $(gsettings get org.gnome.desktop.interface icon-theme | sed "s/'//g") "$clientclass" | head -n 1)
echo "${iconpath}" > "scripts/cache/$clientclass"
fi
else
iconpath=$(geticons -t $(gsettings get org.gnome.desktop.interface icon-theme | sed "s/'//g") "$clientclass" | head -n 1)
echo "${iconpath}" > "scripts/cache/$clientclass"
fi
if [[ ${iconpath} == "" ]]; then
# Retry with lowercase if icon not found
iconpath=$(geticons -t $(gsettings get org.gnome.desktop.interface icon-theme | sed "s/'//g") $(echo "$clientclass" | tr '[:upper:]' '[:lower:]' | sed 's/\ /-/g') | head -n 1)
if [[ ! ${iconpath} = "" ]]; then
rm "scripts/cache/$clientclass"
echo "${iconpath}" > "scripts/cache/$clientclass"
else
newname=$(scripts/iconpatch $clientclass)
iconpath=$(geticons -t $(gsettings get org.gnome.desktop.interface icon-theme | sed "s/'//g") "$newname" | head -n 1)
if [[ ! ${iconpath} = "" ]]; then
rm "scripts/cache/$clientclass"
echo "${iconpath}" > "scripts/cache/$clientclass"
else
# Fallback app icon, replace the path below to the fallback icon of your choice
# iconpath="/usr/share/icons/Win11-dark/mimes/48/application-x-executable.svg"
iconpath=$(geticons -t $(gsettings get org.gnome.desktop.interface icon-theme | sed "s/'//g") "application-x-executable" | head -n 1)
rm "scripts/cache/$clientclass"
echo "${iconpath}" > "scripts/cache/$clientclass"
fi
fi
fi
done
}
# Do stuff here
getwins
if [ "$1" == "--once" ]; then
exit 0
else
socat -u UNIX-CONNECT:/tmp/hypr/"$HYPRLAND_INSTANCE_SIGNATURE"/.socket2.sock - | rg --line-buffered "window>>" | while read -r line; do
getwins
done
fi
+39
View File
@@ -0,0 +1,39 @@
#!/bin/bash
# Thanks Bing!
# Check if the argument is a valid number
if [[ ! $1 =~ ^-?[0-9]+$ ]]; then
echo "Invalid argument: $1"
echo "Usage: getfirstdayofmonth [NUMBER]"
exit 1
fi
# Get the current month and year
current_month=$(date +%m)
current_year=$(date +%Y)
# Add the argument to the current month and adjust the year if needed
if [[ $1 -gt 0 ]]; then
next_month=$((current_month + $1))
next_year=$((current_year + ((next_month-1) / 12)))
next_month=$((current_month + ($1 % 12)))
else
next_month=$((current_month + $1))
next_year=$((current_year + ((next_month-12) / 12)))
next_month=$((current_month + ($1 % 12)))
fi
if ((next_month > 12)); then
next_month=$((next_month % 12))
elif ((next_month == 0)); then
next_month=12
# next_year=$((next_year - 1))
elif ((next_month < 1)); then
next_month=$(( (next_month + 12) % 12 ))
fi
# Get the weekday name (%A), day number (%d), month name (%B) and year (%Y) of the first day of the next month
first_day=$(date -d "$next_year-$next_month-01" '+%u %d %m %Y')
# Print the result
echo $first_day
+55
View File
@@ -0,0 +1,55 @@
#!/usr/bin/bash
getoptions(){
rounding=$(hyprctl getoption decoration:rounding -j | gojq -r -c '.int')
gaps_in=$(hyprctl getoption general:gaps_in -j | gojq -r -c '.int')
gaps_out=$(hyprctl getoption general:gaps_out -j | gojq -r -c '.int')
border_size=$(hyprctl getoption general:border_size -j | gojq -r -c '.int')
force_no_accel=$(hyprctl getoption input:force_no_accel -j | gojq -r -c '.int')
input_sensitivity=$(hyprctl getoption input:sensitivity -j | gojq -r -c '.float')
touchpad_disable_while_typing=$(hyprctl getoption input:touchpad:disable_while_typing -j | gojq -r -c '.int')
touchpad_clickfinger_behavior=$(hyprctl getoption input:touchpad:clickfinger_behavior -j | gojq -r -c '.int')
blur=$(hyprctl getoption decoration:blur:enabled -j | gojq -r -c '.int')
blur_size=$(hyprctl getoption decoration:blur:size -j | gojq -r -c '.int')
blur_passes=$(hyprctl getoption decoration:blur:passes -j | gojq -r -c '.int')
blur_xray=$(hyprctl getoption decoration:blur:xray -j | gojq -r -c '.int')
nightlight=$(hyprctl getoption decoration:screen_shader -j | gojq -r -c '.str')
overlay=$(hyprctl getoption debug:overlay -j | gojq -r -c '.int')
damage_tracking=$(hyprctl getoption debug:damage_tracking -j | gojq -r -c '.int')
if [[ "$nightlight" == *"nothing.frag" || "$nightlight" == "[[EMPTY]]" || "$nightlight" == "" ]]; then
nightlight='false'
else
nightlight='true'
fi
echo -n '{'
echo -n "\"rounding\":$rounding,"
echo -n "\"gaps_in\":$gaps_in,"
echo -n "\"gaps_out\":$gaps_out,"
echo -n "\"border_size\":$border_size,"
echo -n "\"force_no_accel\":$force_no_accel,"
echo -n "\"input_sensitivity\":$input_sensitivity,"
echo -n "\"touchpad_disable_while_typing\":$touchpad_disable_while_typing,"
echo -n "\"touchpad_clickfinger_behavior\":$touchpad_clickfinger_behavior,"
echo -n "\"blur\":$blur,"
echo -n "\"blur_size\":$blur_size,"
echo -n "\"blur_passes\":$blur_passes,"
echo -n "\"blur_xray\":$blur_xray,"
echo -n "\"nightlight\":$nightlight,"
echo -n "\"overlay\":$overlay,"
echo -n "\"damage_tracking\":$damage_tracking,"
echo '"dummy":0}'
}
getoptions
if [ "$1" == "--once" ]; then
exit 0
elif [ "$1" == "tickle" ]; then
hyprctl keyword input:force_no_accel $(hyprctl getoption input:force_no_accel -j | gojq -r -c '.int')
else
socat -u UNIX-CONNECT:/tmp/hypr/"$HYPRLAND_INSTANCE_SIGNATURE"/.socket2.sock - | rg --line-buffered "activelayout>>" | while read -r line; do
# echo $line
getoptions
done
fi
+10
View File
@@ -0,0 +1,10 @@
#!/usr/bin/bash
geticons -t $(gsettings get org.gnome.desktop.interface icon-theme | sed "s/'//g") "firefox" | head -n 1
socat -u UNIX-CONNECT:/tmp/hypr/"$HYPRLAND_INSTANCE_SIGNATURE"/.socket2.sock - | while read -r line; do
echo "$line"
done
+14
View File
@@ -0,0 +1,14 @@
#!/usr/bin/bash
appname=$1
if [[ "$1" == "code-url-handler" ]];then
echo 'code'
elif [[ "$1" == "gnome-tweaks" ]];then
echo 'org.gnome.tweaks'
elif [[ "$1" == "org."* ]];then
appname="${appname#*.}"
appname="${appname#*.}"
echo $appname
fi
+99
View File
@@ -0,0 +1,99 @@
#include <unistd.h>
#include <array>
#include <chrono>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
#include <thread>
#include <vector>
#include "nlohmann/json.hpp"
#define SLEEP_SECONDS 5
using namespace std;
using json = nlohmann::json;
string fileContents, currentLang;
json languages;
string readIfExists(const string& name) {
ifstream f(name.c_str());
stringstream buffer;
if (f) { // check if the file was opened successfully
buffer << f.rdbuf(); // read the whole file into a string stream
f.close(); // close the file when done
}
return buffer.str(); // return the string stream as a string
}
string exec(const char* cmd) {
array<char, 128> buffer;
string result;
unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose);
if (!pipe) {
throw runtime_error("popen() failed!");
}
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
result += buffer.data();
}
return result;
}
void switchLang(const json& langJson) {
string cmd;
cmd = "ibus engine " + string(langJson["name_ibus"]);
exec(&cmd[0]);
cmd = "eww update lang_ibus='" + string(langJson.dump()) + "'";
exec(&cmd[0]);
}
void cycleLang() {
for (int i = 0; i < languages.size(); i++) {
json lang = languages[i];
if (string(lang["name_ibus"]) == currentLang) {
json toSwitchTo = languages[(i + 1) % int(languages.size())];
switchLang(toSwitchTo);
}
}
}
void getCurrentLang() {
for (json lang : languages) {
if (string(lang["name_ibus"]) == currentLang) {
cout << lang << '\n';
break;
}
}
}
int main(int argc, char* argv[]) {
// Change workdir
string workdir = string(getenv("HOME")) + "/.config/eww";
chdir(&workdir[0]);
// Get lang list, current lang
fileContents = readIfExists("json/langs.json");
languages = json::parse(fileContents);
currentLang = exec("ibus engine");
currentLang.pop_back(); // Remove trailing newline
// Cycle?
if (argc > 1 && string(argv[1]) == "--cycle") {
cycleLang();
return 0;
}
if (argc > 2 && string(argv[1]) == "--switch") {
switchLang(json::parse(string(argv[2])));
return 0;
}
cout << "{\"name\":\"English (United "
"States)\",\"name_abbr\":\"ENG\",\"name_ibus\":\"xkb:us::eng\"}\n";
while (true) {
getCurrentLang();
sleep(5);
}
}
+50
View File
@@ -0,0 +1,50 @@
#!/usr/bin/bash
~/.config/eww/scripts/toggle-powerview.sh --close &
if [[ "$1" == ">"* ]]; then
args=( $1 )
if [[ "${args[0]}" == ">music" ]]; then
scripts/colormanage get
elif [[ "${args[0]}" == ">load" ]]; then
scripts/colormanage load "${args[1]}"
elif [[ "${args[0]}" == ">save" ]]; then
scripts/colormanage save "${args[1]}"
elif [[ "${args[0]}" == ">swr" ]]; then # basic rice switching
~/.local/bin/switchrice.sh "${args[1]}" "${args[2]}"
elif [[ "${args[0]}" == ">light" ]]; then
scripts/togglelight light
elif [[ "${args[0]}" == ">dark" ]]; then
scripts/togglelight dark
elif [[ "${args[0]}" == ">multi" ]]; then
echo -n 'multi' > 'scripts/workdir/__mode_colors.txt'
elif [[ "${args[0]}" == ">one" ]]; then
echo -n 'one' > 'scripts/workdir/__mode_colors.txt'
elif [[ "${args[0]}" == ">wall" ]]; then
scripts/colorgen 'images/wallpaper' '[Local wallpaper]' ''
scripts/colormanage get
elif [[ "${args[0]}" == ">img" ]]; then
scripts/switchwall
elif [[ "${args[0]}" == ">segs" ]]; then
eww update waifu="$(python3 scripts/waifu-get.py --segs ero)"
elif [[ "${args[0]}" == ">uwu" ]]; then
eww update waifu="$(python3 scripts/waifu-get.py)"
elif [[ "${args[0]}" == ">r" ]]; then
pkill eww && eww daemon && eww open bar && eww open bgdecor
elif [[ "${args[0]}" == ">todo" ]]; then
scripts/todo add "${1#*>todo }"
eww update todolist="$(cat json/todo.json | gojq -c -M)"
elif [[ "${args[0]}" == ">raw" ]]; then
hyprctl keyword input:force_no_accel $(( 1 - $(hyprctl getoption input:force_no_accel -j | gojq '.int') ))
else
# notify-send 'eww' 'Invalid command!'
false
fi
else
cd ~
app=$1
eval "${app%\%*}" &
pkill launchapp
fi
+26
View File
@@ -0,0 +1,26 @@
#!/bin/python3
import sys
def limit_length(s, newlength):
# Use len() function to get number of characters in s
char_count = 0
newstr = ''
# Use unicodedata.east_asian_width() function to check for double-width characters
import unicodedata
for c in s:
char_count += 1
if unicodedata.east_asian_width(c) == 'W':
char_count += 1
if char_count <= newlength:
newstr += c
else:
newstr = newstr + '...'
break
# Add double-width count to character count to get display length
return newstr
original = sys.argv[1]
newlen = int(sys.argv[2])
newstr = limit_length(original, newlen)
print(newstr)
+71
View File
@@ -0,0 +1,71 @@
#!/usr/bin/python3
import desktop_entry_lib
import os
import json
import subprocess
full_output = {}
def read(target_file) -> None:
entry = desktop_entry_lib.DesktopEntry.from_file(target_file)
print("Name: " + str(entry.Name.default_text))
print("Comment: " + str(entry.Comment.default_text))
print("Exec: " + str(entry.Exec))
def getProperties(target_file) -> None:
entry = desktop_entry_lib.DesktopEntry.from_file(target_file)
# iconcmd = "/usr/bin/geticons " + str(entry.Icon)
# iconcmd = "/usr/bin/geticons"
# iconpath = str(subprocess.check_output(str(iconcmd), shell=True))
dirs = target_file.split('/')
entryname = dirs[-1]
# return
props = {
"name": str(entry.Name.default_text),
# "icon": str(entry.Icon),
"exec": str('gtk-launch ' + entryname)
}
return props
if __name__ == "__main__":
entryFile = open("scripts/cache/entries.txt", "w")
# Get files
entries = list(str(s) for s in os.listdir("/usr/share/applications"))
entries_flatpak = list(str(s) for s in os.listdir("/var/lib/flatpak/exports/share/applications"))
entries_local = list(str('../../.local/share/applications/' + s) for s in os.listdir("../../.local/share/applications/"))
for app in entries:
alreadythere = False
for localized in entries_local:
if app in localized:
alreadythere = True
if not(alreadythere):
entries_local.append(str('/usr/share/applications/'+app))
for app in entries_flatpak:
alreadythere = False
for localized in entries_local:
if app in localized:
alreadythere = True
if not(alreadythere):
entries_local.append(str('/var/lib/flatpak/exports/share/applications/'+app))
# Get properties
for app in entries_local:
if app.find('.desktop') == -1: # Skip files that aren't desktop entries
continue
this_entry = getProperties(app)
full_output[this_entry['name']] = (this_entry)
# output=json.dumps(this_entry)
# print(output)
entryFile.write(json.dumps(full_output))
+63
View File
@@ -0,0 +1,63 @@
#!/usr/bin/python3
import desktop_entry_lib
import os
import json
# from fuzzysearch import find_near_matches
def read(target_file) -> None:
entry = desktop_entry_lib.DesktopEntry.from_file(target_file)
print("Name: " + str(entry.Name.default_text))
print("Comment: " + str(entry.Comment.default_text))
print("Exec: " + str(entry.Exec))
def getProperties(target_file) -> None:
entry = desktop_entry_lib.DesktopEntry.from_file(target_file)
# return
props = {
"name": str(entry.Name.default_text),
"comment": str(entry.Comment.default_text),
"exec": str(entry.Exec),
"icon": str(entry.Icon)
}
return props
if __name__ == "__main__":
entryFile = open("scripts/cache/entrynames.txt", "w")
# Get files
entries = list(str(s) for s in os.listdir("/usr/share/applications"))
entries_flatpak = list(str(s) for s in os.listdir("/var/lib/flatpak/exports/share/applications"))
entries_local = list(str('../../.local/share/applications/' + s) for s in os.listdir("../../.local/share/applications/"))
for app in entries:
alreadythere = False
for localized in entries_local:
if app in localized:
alreadythere = True
if not(alreadythere):
entries_local.append(str('/usr/share/applications/'+app))
for app in entries_flatpak:
alreadythere = False
for localized in entries_local:
if app in localized:
alreadythere = True
if not(alreadythere):
entries_local.append(str('/var/lib/flatpak/exports/share/applications/'+app))
# Get properties
for app in entries_local:
if app.find('.desktop') == -1: # Skip files that aren't desktop entries
continue
thisEntry = getProperties(app)
entryFile.write(thisEntry['name'])
entryFile.write('\n')
+88
View File
@@ -0,0 +1,88 @@
#!/bin/python3
from material_color_utilities_python import *
from pathlib import Path
import sys
img = 0
newtheme=0
if len(sys.argv) > 1 and sys.argv[1] == '--path':
img = Image.open(sys.argv[2])
basewidth = 64
wpercent = (basewidth/float(img.size[0]))
hsize = int((float(img.size[1])*float(wpercent)))
img = img.resize((basewidth,hsize),Image.Resampling.LANCZOS)
newtheme = themeFromImage(img)
elif len(sys.argv) > 1 and sys.argv[1] == '--color':
colorstr = sys.argv[2]
newtheme = themeFromSourceColor(argbFromHex(colorstr))
else:
img = Image.open(str(Path.home())+'/.config/eww/images/wallpaper')
basewidth = 64
wpercent = (basewidth/float(img.size[0]))
hsize = int((float(img.size[1])*float(wpercent)))
img = img.resize((basewidth,hsize),Image.Resampling.LANCZOS)
newtheme = themeFromImage(img)
colorscheme=0
if("-l" in sys.argv):
colorscheme = newtheme.get('schemes').get('light')
else:
colorscheme = newtheme.get('schemes').get('dark')
primary = colorscheme.get_primary()
onPrimary = colorscheme.get_onPrimary()
primaryContainer = colorscheme.get_primaryContainer()
onPrimaryContainer = colorscheme.get_onPrimaryContainer()
secondary = colorscheme.get_secondary()
onSecondary = colorscheme.get_onSecondary()
secondaryContainer = colorscheme.get_secondaryContainer()
onSecondaryContainer = colorscheme.get_onSecondaryContainer()
tertiary = colorscheme.get_tertiary()
onTertiary = colorscheme.get_onTertiary()
tertiaryContainer = colorscheme.get_tertiaryContainer()
onTertiaryContainer = colorscheme.get_onTertiaryContainer()
error = colorscheme.get_error()
onError = colorscheme.get_onError()
errorContainer = colorscheme.get_errorContainer()
onErrorContainer = colorscheme.get_onErrorContainer()
background = colorscheme.get_background()
onBackground = colorscheme.get_onBackground()
surface = colorscheme.get_surface()
onSurface = colorscheme.get_onSurface()
surfaceVariant = colorscheme.get_surfaceVariant()
onSurfaceVariant = colorscheme.get_onSurfaceVariant()
outline = colorscheme.get_outline()
shadow = colorscheme.get_shadow()
inverseSurface = colorscheme.get_inverseSurface()
inverseOnSurface = colorscheme.get_inverseOnSurface()
inversePrimary = colorscheme.get_inversePrimary()
print('$primary: ' + hexFromArgb(primary) + ';')
print('$onPrimary: ' + hexFromArgb(onPrimary) + ';')
print('$primaryContainer: ' + hexFromArgb(primaryContainer) + ';')
print('$onPrimaryContainer: ' + hexFromArgb(onPrimaryContainer) + ';')
print('$secondary: ' + hexFromArgb(secondary) + ';')
print('$onSecondary: ' + hexFromArgb(onSecondary) + ';')
print('$secondaryContainer: ' + hexFromArgb(secondaryContainer) + ';')
print('$onSecondaryContainer: ' + hexFromArgb(onSecondaryContainer) + ';')
print('$tertiary: ' + hexFromArgb(tertiary) + ';')
print('$onTertiary: ' + hexFromArgb(onTertiary) + ';')
print('$tertiaryContainer: ' + hexFromArgb(tertiaryContainer) + ';')
print('$onTertiaryContainer: ' + hexFromArgb(onTertiaryContainer) + ';')
print('$error: ' + hexFromArgb(error) + ';')
print('$onError: ' + hexFromArgb(onError) + ';')
print('$errorContainer: ' + hexFromArgb(errorContainer) + ';')
print('$onErrorContainer: ' + hexFromArgb(onErrorContainer) + ';')
print('$colorbarbg: ' + hexFromArgb(background) + ';')
print('$background: ' + hexFromArgb(background) + ';')
print('$onBackground: ' + hexFromArgb(onBackground) + ';')
print('$surface: ' + hexFromArgb(surface) + ';')
print('$onSurface: ' + hexFromArgb(onSurface) + ';')
print('$surfaceVariant: ' + hexFromArgb(surfaceVariant) + ';')
print('$onSurfaceVariant: ' + hexFromArgb(onSurfaceVariant) + ';')
print('$outline: ' + hexFromArgb(outline) + ';')
print('$shadow: ' + hexFromArgb(shadow) + ';')
print('$inverseSurface: ' + hexFromArgb(inverseSurface) + ';')
print('$inverseOnSurface: ' + hexFromArgb(inverseOnSurface) + ';')
print('$inversePrimary: ' + hexFromArgb(inversePrimary) + ';')
+30
View File
@@ -0,0 +1,30 @@
#!/usr/bin/env bash
while true; do
# human-readable
freeH=$(free -h --si | rg "Mem:")
swapfreeH=$(free -h --si | rg "Swap:")
# non-human-readable
freeN=$(free --mega | rg "Mem:")
swapfreeN=$(free --mega | rg "Swap:")
total="$(echo "$freeH" | awk '{ print $2 }')"
used="$(echo "$freeH" | awk '{ print $3 }')"
t="$(echo "$freeN" | awk '{ print $2 }')"
u="$(echo "$freeN" | awk '{ print $3 }')"
swaptotal="$(echo "$swapfreeH" | awk '{ print $2 }')"
swapused="$(echo "$swapfreeH" | awk '{ print $3 }')"
swapt="$(echo "$swapfreeN" | awk '{ print $2 }')"
swapu="$(echo "$swapfreeN" | awk '{ print $3 }')"
free=$(printf '%.1fG' "$(bc -l <<< "($t - $u) / 1000")")
perc=$(printf '%.1f' "$(free -m | rg Mem | awk '{print ($3/$2)*100}')")
swapfree=$(printf '%.1fG' "$(bc -l <<< "($swapt - $swapu) / 1000")")
swapperc=$(printf '%.1f' "$(free -m | rg Swap | awk '{print ($2!=0) ? ($3/$2)*100 : 0}')")
echo '{ "total": "'"$total"'", "used": "'"$used"'", "free": "'"$free"'", "swaptotal": "'"$swaptotal"'", "swapused": "'"$swapused"'", "swappercentage": '"$swapperc"', "swapfree": "'"$swapfree"'", "percentage": '"$perc"' }'
sleep 3
done
+52
View File
@@ -0,0 +1,52 @@
#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/iostreams/stream.hpp>
#include <cstdio>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
using namespace std;
void cavaToJson(std::string& s) {
for(int i = 0; i < s.size(); i++){
if(s[i] == ';') s[i] = ',';
}
s.pop_back();
}
void cursorPosToJson(std::string& s) {
for(int i = 0; i < s.size(); i++){
if(s[i] == ';') s[i] = ',';
}
s.pop_back();
}
string exec(const char* cmd) {
array<char, 128> buffer;
string result;
unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose);
if (!pipe) {
throw runtime_error("popen() failed!");
}
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
result += buffer.data();
}
return result;
}
int main()
{
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen("cava -p ~/.config/eww/scripts/custom_configs/cava", "r"), pclose);
if (!pipe) {
throw std::runtime_error("popen() failed!");
}
boost::iostreams::file_descriptor_source fd(fileno(pipe.get()), boost::iostreams::never_close_handle);
boost::iostreams::stream<boost::iostreams::file_descriptor_source> is(fd);
std::string line;
while (std::getline(is, line)) {
string st = exec("hyprctl cursorpos");
st.pop_back();
cout << '[' << st << ']' << endl;
}
return 0;
}
+175
View File
@@ -0,0 +1,175 @@
#!/usr/bin/env bash
get_status() {
s=$1
if [ "$s" = "Playing" ]; then
echo ""
else
echo ""
fi
}
get_length_sec() {
len=$1
if [ -z "$len" ]; then
echo 0
else
bc <<< "$len / 1000000"
fi
}
get_length_time() {
len=$1
if [ -n "$len" ]; then
len=$(bc <<< "$len / 1000000 + 1")
date -d@"$len" +%M:%S
else
echo ""
fi
}
get_position() {
pos=$1
len=$2
if [ -n "$pos" ]; then
bc -l <<< "$pos / $len * 100"
else
echo 0
fi
}
get_position_time() {
pos=$1
if [ -n "$pos" ]; then
date -d@"$(bc <<< "$pos / 1000000")" +%M:%S
else
echo ""
fi
}
get_cover() {
# COVER_URL=$1
mkdir -p "eww_covers"
cd "eww_covers" || exit
IMGPATH="cover_art"
# echo '{"image": "null", "color": {"alpha":"100","colors":{"color0":"null","color1":"null","color10":"null","color11":"null","color12":"null","color13":"null","color14":"null","color15":"null","color2":"null","color3":"null","color4":"null","color5":"null","color6":"null","color7":"null","color8":"null","color9":"null"},"special":{"background":"null","cursor":"null","foreground":"null"},"wallpaper":"~/.config/eww/eww_covers/cover_art","source":"󱛟"},"materialcolor":{"onPrimary":"null","onPrimaryContainer":"null","onSecondaryContainer":"null","primary":"null","primaryContainer":"null","secondaryContainer":"null"}}'
# echo '{"image": "eww_covers/cover_art_default","source":"󱛟"}}'
playerctl -F metadata mpris:artUrl 2>/dev/null | while read -r COVER_URL; do
music_source='󰐍'
COVER_URL=${COVER_URL//blob:/}
COVER_URL=${COVER_URL//file:\/\//}
COVER_URL=${COVER_URL//%20/ }
if [[ "$COVER_URL" = *"https"* ]]; then
music_source='󰖟'
coverurl="$(playerctl metadata mpris:artUrl)"
coverurl_highres_yt="${coverurl/hqdefault/maxresdefault}"
coverurl_highres_soundcloud="${coverurl/80x80/500x500}"
# SoundCloud
if [[ "$coverurl" == *"sndcdn"* ]]; then
music_source='󰓀'
curl --silent --output "$IMGPATH""_soundcloud" "$coverurl_highres_soundcloud" -q read-timeout=0.1
cp "$IMGPATH""_soundcloud" "$IMGPATH"
imgsize=$(echo $(du -b ~/.config/eww/eww_covers/cover_art | tr '\t' '\n' | grep -v 'cover_art'))
# Youtube
elif [[ "$coverurl" == *"ytimg"* ]]; then
music_source='󰗃'
curl --silent --output "$IMGPATH""_yt" "$coverurl_highres_yt" -q read-timeout=0.1
cp "$IMGPATH""_yt" "$IMGPATH"
imgsize=$(echo $(du -b ~/.config/eww/eww_covers/cover_art | tr '\t' '\n' | grep -v 'cover_art'))
# Likely YT Music
elif [[ "$coverurl" == *"googleusercontent"* ]]; then
music_source=''
curl --silent --output "$IMGPATH""_other" "$coverurl" -q read-timeout=0.1
cp "$IMGPATH""_other" "$IMGPATH"
imgsize=$(echo $(du -b ~/.config/eww/eww_covers/cover_art | tr '\t' '\n' | grep -v 'cover_art'))
elif [[ "$coverurl" == *"spotify"* ]]; then
music_source='󰓇'
curl --silent --output "$IMGPATH""_other" "$coverurl" -q read-timeout=0.1
cp "$IMGPATH""_other" "$IMGPATH"
imgsize=$(echo $(du -b ~/.config/eww/eww_covers/cover_art | tr '\t' '\n' | grep -v 'cover_art'))
# Any other
else
curl --silent --output "$IMGPATH""_other" "$coverurl" -q read-timeout=0.1
cp "$IMGPATH""_other" "$IMGPATH"
imgsize=$(echo $(du -b ~/.config/eww/eww_covers/cover_art | tr '\t' '\n' | grep -v 'cover_art'))
fi
# Fallback
if [ "$imgsize" == "0" ] || [ ! "$(diff ~/.config/eww/eww_covers/cover_art ~/.config/eww/eww_covers/cover_art_error)" ]; then
curl --silent --output "$IMGPATH""_lowres" "$coverurl" -q read-timeout=0.1
cp "$IMGPATH""_lowres" "$IMGPATH"
fi
#Generate colors
cd ..
scripts/colorgen 'eww_covers/'$IMGPATH $coverurl "$music_source"
cd "eww_covers"
elif [ "$COVER_URL" = "" ]; then
echo '{"image": "", "color": "$bg"}'
else
music_source='󱛟'
cp "$COVER_URL" "$IMGPATH"
cd ..
scripts/colorgen '"eww_covers/'$IMGPATH'"' $coverurl "$music_source"
cd "eww_covers"
fi
done
}
# SANITIZE FIX
sanitize() {
echo "$1" | sed 's/"/\"/g'
}
if [ "$1" = "cover" ]; then
get_cover
elif [ "$1" == "name" ]; then
lentolimit=41
if [ "$2" != "" ]; then
lentolimit=$2
fi
# echo '{"artist": "", "title": ""}'
playerctl -F metadata -f '{{title}}\{{artist}}\' 2>/dev/null | while IFS="$(printf '\\')" read -r title artist; do
if [[ "$title" == *" - YouTube"* && "$artist" == "" ]]; then
continue
elif [[ "$title" == *"YouTube Music" && "$artist" == "" ]]; then
continue
fi
# title=$(echo "$title" | cut -d '-' -f2)
title=$(scripts/limitlen.py "$title" "$lentolimit")
artist=$(scripts/limitlen.py "$artist" "$lentolimit")
gojq --null-input -r -c \
--arg artist "$(sanitize "$artist")" \
--arg title "$(sanitize "$title")" \
'{"artist": $artist, "title": $title}'
done
else
# echo '{"artist": "", "title": "", "status": "", "position": "", "position_time": "", "length": ""}'
playerctl -F metadata -f '{{title}}\{{artist}}\{{status}}\{{position}}\' 2>/dev/null | while IFS="$(printf '\\')" read -r title artist status position; do
if [[ "$title" == *" - YouTube" && "$artist" == "" ]]; then
continue
elif [[ "$title" == *"YouTube Music" && "$artist" == "" ]]; then
continue
fi
len=$(playerctl metadata mpris:length)
# title=$(echo "$title" | cut -d '-' -f2)
title=$(scripts/limitlen.py "$title" 40)
artist=$(scripts/limitlen.py "$artist" 40)
gojq --null-input -r -c \
--arg artist "$(sanitize "$artist")" \
--arg title "$(sanitize "$title")" \
--arg status "$(get_status "$status")" \
--arg pos "$(get_position "$position" "$len")" \
--arg pos_time "$(get_position_time "$position")" \
--arg length "$(get_length_time "$len")" \
'{"artist": $artist, "title": $title, "status": $status, "position": $pos, "position_time": $pos_time, "length": $length}'
done
fi
+40
View File
@@ -0,0 +1,40 @@
#!/usr/bin/env bash
toggle() {
status=$(rfkill -J | gojq -r '.rfkilldevices[] | select(.type == "wlan") | .soft' | head -1)
if [ "$status" = "unblocked" ]; then
rfkill block wlan
else
rfkill unblock wlan
fi
}
if [ "$1" = "toggle" ]; then
toggle
else
while true; do
status=$(nmcli g | tail -n 1 | awk '{print $1}')
signal=$(nmcli -f in-use,signal dev wifi | rg "\*" | awk '{ print $2 }')
essid=$(nmcli -t -f NAME connection show --active | head -n1 | sed 's/\"/\\"/g')
icons=("" "" "" "" "")
if [ "$status" = "disconnected" ] ; then
icon=""
color="#988ba2"
else
level=$(awk -v n="$signal" 'BEGIN{print int((n-1)/20)}')
if [ "$level" -gt 4 ]; then
level=4
fi
icon=${icons[$level]}
color="#cba6f7"
fi
echo '{ "essid": "'"$essid"'", "icon": "'"$icon"'", "color": "'"$color"'", "level": "'"$level"'" }'
sleep 4
done
fi
+98
View File
@@ -0,0 +1,98 @@
#include <array>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
#include <vector>
#include "nlohmann/json.hpp"
using namespace std;
using json = nlohmann::json;
string dunstOutput;
json allNotifs, notifApps;
string exec(const char* cmd) {
array<char, 128> buffer;
string result;
unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose);
if (!pipe) {
throw runtime_error("popen() failed!");
}
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
result += buffer.data();
}
return result;
}
// Function to check if file exists, if yes read it
string readIfExists(const string& name) {
ifstream f(name.c_str());
stringstream buffer;
if (f) { // check if the file was opened successfully
buffer << f.rdbuf(); // read the whole file into a string stream
f.close(); // close the file when done
}
return buffer.str(); // return the string stream as a string
}
void writeToFile(const string& name, const string& content) {
ofstream f(name.c_str(), ios::app); // open the file in append mode
if (f) { // check if the file was opened successfully
f << content << "\n"; // write the content to the file
f.close(); // close the file when done
} else {
cerr << "Error: could not open " << name
<< "\n"; // print an error message to the standard error
}
}
inline void getDunstNotifs() {
dunstOutput = exec("dunstctl history | gojq -c -M");
allNotifs = json::parse(dunstOutput)["data"][0];
}
void addNotif(const json& newNotification) {
notifApps["count"] = int(notifApps["count"]) + 1;
bool found = false;
for (json& existingApp : notifApps["data"]) {
auto it = existingApp.find("name");
if (it != existingApp.end() &&
*it == newNotification["appname"]["data"]) {
found = true;
existingApp["count"] = int(existingApp["count"]) + 1;
existingApp["content"].push_back(
json::array({newNotification["summary"]["data"],
newNotification["body"]["data"]}));
break;
}
}
// Not found? A new app it is
if (!found) {
json newApp = R"({"name": "", "count": 1, "content": []})"_json;
newApp["name"] = string(newNotification["appname"]["data"]);
newApp["content"].push_back(
json::array({newNotification["summary"]["data"],
newNotification["body"]["data"]}));
notifApps["data"].push_back(newApp);
}
}
inline void groupNotifs() {
for (json notification : allNotifs) {
addNotif(notification);
}
}
int main() {
// ios::sync_with_stdio(false);
notifApps["data"] = json::array();
notifApps["count"] = 0;
getDunstNotifs();
groupNotifs();
cout << notifApps << '\n';
}
+10
View File
@@ -0,0 +1,10 @@
#!/usr/bin/bash
# eww update dynamicright_module_page=2
# eww update flash_notif=true
# sleep 4
# eww update dynamicright_module_page=1
# eww update flash_notif=false
scripts/toggle-notificationspopup.sh --open
eww update notification_revcnt=$(eww get notifications | gojq 'length')
+91
View File
@@ -0,0 +1,91 @@
#!/usr/bin/env bash
tmp=scripts/cache/dunst-history.json
lock="scripts/cache/dunst-toggle.lock"
lockinfo="scripts/cache/dunst-lock-info"
touch $lockinfo
declare ids
export toggle_icon=""
sanitize() {
retstr=$(echo $1 | sed 's/\\\\/\\\\\\\\/g' | sed 's/"/\\"/g')
# echo "original: $1"
echo "$retstr"
# echo 'sanitized'
}
get_ids() {
mapfile -t ids < <(dunstctl history | gojq -r ".data[] | .[] | select(.appname.data != \"Spotify\") | .id.data")
}
get_notif() {
echo -n '['
for id in "${ids[@]}"; do
mapfile -t n < <(gojq -r ".data[] | .[] | select(.id.data == $id) | .appname.data, .summary.data, .body.data" "$tmp" | sed -r '/^\s*$/d' | sed -e 's/\%/ percent/g')
ohkay=$(sanitize "${n[1]}")
# echo $ohkay
echo -n ''$([ $id -eq ${ids[0]} ] || echo ,)' { '
echo -n '"id": "'"$id"'", "appname": "'"${n[0]}"'", "summary": "'"$ohkay"'", "body": "'"${n[2]}"'"'
echo -n '}'
done
echo ']'
}
toggle() {
dunstctl set-paused toggle
if [ ! -f "$lock" ]; then
export toggle_icon=""
touch "$lock"
else
export toggle_icon=""
rm "$lock"
fi
echo "icon_change" > $lockinfo
}
clear() {
dunstctl history-clear
echo "icon_change" > $lockinfo
}
get_icon() {
if [ ${#ids[@]} -eq 0 ]; then
echo ""
else
echo ""
fi
}
if [ "$1" == "toggle" ]; then
toggle
dunstctl history > "$tmp"
elif [ "$1" == "clear" ]; then
clear
dunstctl history > "$tmp"
elif [ "$1" == "icons" ]; then
dunstctl history > "$tmp"
get_ids
is_paused=$(dunstctl is-paused)
echo '{"toggle_icon": "'"$toggle_icon"'", "paused": '$is_paused', "icon": "'"$(get_icon)"'"}'
tail -f "$lockinfo" | while read -r; do
get_ids
is_paused=$(dunstctl is-paused)
echo '{"toggle_icon": "'"$toggle_icon"'", "paused": '$is_paused', "icon": "'"$(get_icon)"'"}'
done
else
cd ~/.config/eww
dunstctl history > "$tmp"
get_ids
scripts/notifget
# tail -f "$tmp" 2>/dev/null | rg --line-buffered "aa\{sv\}" | while read -r; do
# get_ids
# scripts/notifget
# done
fi
+11
View File
@@ -0,0 +1,11 @@
#!/usr/bin/bash
scripts/overview "$1"
if [ "$1" == "--once" ]; then
exit 0
else
socat -u UNIX-CONNECT:/tmp/hypr/"$HYPRLAND_INSTANCE_SIGNATURE"/.socket2.sock - | while read -r line; do
scripts/overview "$1"
done
fi
+14
View File
@@ -0,0 +1,14 @@
#!/usr/bin/bash
scripts/overview --row 1
if [ "$1" == "--once" ]; then
exit 0
else
socat -u UNIX-CONNECT:/tmp/hypr/"$HYPRLAND_INSTANCE_SIGNATURE"/.socket2.sock - | rg --line-buffered "window>>" | while read -r line; do
# This sleep is necessary
# It prevents the script from being faster than hyprctl
sleep 0.025
scripts/overview --row 1
done
fi
+14
View File
@@ -0,0 +1,14 @@
#!/usr/bin/bash
scripts/overview --row 2
if [ "$1" == "--once" ]; then
exit 0
else
socat -u UNIX-CONNECT:/tmp/hypr/"$HYPRLAND_INSTANCE_SIGNATURE"/.socket2.sock - | rg --line-buffered "window>>" | while read -r line; do
# This sleep is necessary
# It prevents the script from being faster than hyprctl
sleep 0.025
scripts/overview --row 2
done
fi
+105
View File
@@ -0,0 +1,105 @@
#include <array>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <memory>
#include <regex>
#include <stdexcept>
#include <string>
#include "nlohmann/json.hpp"
using namespace std;
using json = nlohmann::json;
#define ROWS 2
#define COLS 5
string clients;
json clientjson, apps;
json workspaces;
string workspaceInitTemplate =
"[{\"address\":\"_none\",\"at\":[0,0],\"class\":\"workspace\",\"size\":["
"1920,1080],\"title\":\"__WORKSPACE_ID\",\"workspace\":{\"id\":__WORKSPACE_"
"ID,\"name\":\"__WORKSPACE_ID\"}}]";
vector<string> appnames;
string exec(const char* cmd) {
array<char, 128> buffer;
string result;
unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose);
if (!pipe) {
throw runtime_error("popen() failed!");
}
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
result += buffer.data();
}
return result;
}
void initWorkspaces() {
for (int i = 0; i < ROWS; i++) {
workspaces.push_back(json::array({})); // []
for (int j = 0; j < COLS; j++) {
int workspaceNum = i * COLS + j + 1; // Note: Workspaces are 1-base
string workspaceInitString =
regex_replace(workspaceInitTemplate, regex("__WORKSPACE_ID"),
to_string(workspaceNum));
json thisWorkspaceInit = json::parse(workspaceInitString);
workspaces[i].push_back(thisWorkspaceInit);
}
}
}
void addApp(json& client) {
// Calculate position in overview tile
int workspaceNum = int(client["workspace"]["id"]) - 1; // 1-base to 0-base
if(workspaceNum < 0) return; //Skip scratchpads/specials, as they have negative ids
int i = workspaceNum / COLS, j = workspaceNum % COLS;
// New JSON for app
json newApp =
R"({"class": "", "workspace": {"id": 8, "name": "8"}, "title": "", "at": [0, 0], "size": [0, 0], "address": [], "icon": ""})"_json;
// Add normal stuff
newApp["class"] = client["class"];
newApp["address"] = client["address"];
newApp["workspace"] = client["workspace"];
newApp["title"] = client["title"];
newApp["at"] = client["at"];
newApp["size"] = client["size"];
// Icon path
if(string(client["class"]) == "") {
client["class"] = "dummy";
}
string filename = string("./scripts/cache/" + string(client["class"]));
std::ifstream ifs(filename);
std::string iconpath((std::istreambuf_iterator<char>(ifs)),
(std::istreambuf_iterator<char>()));
while (iconpath.size() > 0 && *iconpath.rbegin() == '\n') iconpath.pop_back(); // Remove '\n'
newApp["icon"] = iconpath;
workspaces[i][j].push_back(newApp);
}
void getApps() {
// Get clients
clients = exec("hyprctl clients -j | gojq -c -M");
clientjson = json::parse(clients);
// Access the values
for (json client : clientjson) {
addApp(client);
}
}
int main(int argc, char* argv[]) {
ios::sync_with_stdio(false);
cin.tie(nullptr);
initWorkspaces();
getApps();
if (argc == 2) cout << workspaces[0][stoi(argv[1]) - 1] << '\n';
if (argc == 3 && string(argv[1]) == "--row" && stoi(argv[2]) >= 1 && stoi(argv[2]) <= ROWS) {
cout << workspaces[stoi(argv[2]) - 1] << '\n';
} else
cout << workspaces << '\n';
}
+13
View File
@@ -0,0 +1,13 @@
#!/usr/bin/bash
offset=$(eww get quote_index)
total=$(eww get quote_content | gojq 'length')
# total=25
# shown=7
if [ "$1" == "up" ]; then
eww update quote_index=$(( ("$offset" + "$total" - 1) % "$total" ))
else
eww update quote_index=$(( ("$offset" + 1) % "$total" ))
fi
+10
View File
@@ -0,0 +1,10 @@
#!/usr/bin/bash
offset=$(eww get scroll_offset_settings)
total=$(eww get DASHBOARD_SETTINGS_PAGES)
if [ "$1" == "up" ]; then
eww update scroll_offset_settings=$(( ("$offset" + "$total" - 1) % "$total" ))
else
eww update scroll_offset_settings=$(( ("$offset" + 1) % "$total" ))
fi
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/bash
offset=$(eww get scroll_offset_waifu)
# total=$(eww get WAIFU_TAG_ID | gojq 'length')
# shown=$(eww get SCROLL_TOSHOW_WAIFUTAGS)
total=20
shown=13
# I'm sorry but I have to hard code or it'll be slow asf
if [ "$1" == "up" ]; then
if [ "$offset" -gt 0 ]; then
eww update scroll_offset_waifu=$(( "$offset" - 2 ))
fi
else
if [ "$offset" -lt $(( "$total" - "$shown" - 1 )) ]; then
eww update scroll_offset_waifu=$(( "$offset" + 2 ))
fi
fi
+21
View File
@@ -0,0 +1,21 @@
#!/usr/bin/env bash
# Get month diff
diffmonth=$(eww get monthshift)
if [[ "$1" == "up" ]]; then
diffmonth=$(( $diffmonth - 1 ))
else
diffmonth=$(( $diffmonth + 1 ))
fi
eww update monthshift="$diffmonth" &
# Get dates
dates=$(scripts/getfirstdayofmonth "$diffmonth")
dateSplitted=( $dates )
newTitle=$(date -d "${dateSplitted[3]}-${dateSplitted[2]}-${dateSplitted[1]}" "+%B %Y")
if [[ "$diffmonth" == "0" ]]; then
dates=''
fi
eww update calendartitle="$newTitle" &
eww update calendar="$(scripts/calendarlayout $dates)"
+1
View File
@@ -0,0 +1 @@
(box :orientation "v" :spacing 5 :class "apps" :halign "center" :valign "center" (button :class "item" :onclick "4channels &" "4channels") (button :class "item" :onclick "7za &" "7za") (button :class "item" :onclick "a52dec &" "a52dec") (button :class "item" :onclick "aafire &" "aafire") (button :class "item" :onclick "aainfo &" "aainfo") (button :class "item" :onclick "aalib-config &" "aalib-config") (button :class "item" :onclick "aasavefont &" "aasavefont") (button :class "item" :onclick "aatest &" "aatest") (button :class "item" :onclick "abw2html &" "abw2html") (button :class "item" :onclick "abw2raw &" "abw2raw"))
+14
View File
@@ -0,0 +1,14 @@
#!/usr/bin/bash
selected=$(eval $2 get selected)
if [[ $selected == "_none" ]] || [[ $selected == "" ]]; then
eval "$2 update selected=$1"
selected=$(eval $2 get selected)
else
hyprctl dispatch movetoworkspacesilent $3,address:$selected
eval "$2 update selected=_none"
selected=$(eval $2 get selected)
fi
+85
View File
@@ -0,0 +1,85 @@
#include <array>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
#include <vector>
#include "nlohmann/json.hpp"
using namespace std;
using json = nlohmann::json;
int workspace_a, workspace_b;
string clients;
json clientjson;
vector<string> windows_a, windows_b;
bool output = false;
string exec(const char* cmd) {
array<char, 128> buffer;
string result;
unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose);
if (!pipe) {
throw runtime_error("popen() failed!");
}
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
result += buffer.data();
}
return result;
}
void tryAddApp(const json& client) {
if (int(client["workspace"]["id"]) == workspace_a)
windows_a.push_back(client["address"]);
else if (int(client["workspace"]["id"]) == workspace_b)
windows_b.push_back(client["address"]);
}
void getApps() {
// Get clients
clients = exec("hyprctl clients -j | gojq -c -M");
clientjson = json::parse(clients);
// Access the values
for (json client : clientjson) {
tryAddApp(client);
}
}
void swapWorkspaces() {
for (string address : windows_a) {
string cmd = "hyprctl dispatch movetoworkspacesilent " +
to_string(workspace_b) + ",address:" + address;
if (output) cout << cmd << '\n';
exec(&cmd[0]);
}
for (string address : windows_b) {
string cmd = "hyprctl dispatch movetoworkspacesilent " +
to_string(workspace_a) + ",address:" + address;
if (output) cout << cmd << '\n';
exec(&cmd[0]);
}
}
int main(int argc, char* argv[]) {
ios::sync_with_stdio(false);
if (argc < 3) {
cout << "Usage: swapws [WORKSPACE_NUMBER_1] [WORKSPACE_NUMBER_2]"
<< endl;
return 0;
}
if (argc == 4 && string(argv[3]) == "--output") output = true;
workspace_a = stoi(string(argv[1]));
workspace_b = stoi(string(argv[2]));
if (workspace_a <= 0 || workspace_b <= 0 || workspace_a == workspace_b) {
cout << "Nahhh that's stupid" << endl;
return 0;
}
getApps();
swapWorkspaces();
}
+26
View File
@@ -0,0 +1,26 @@
#!/usr/bin/bash
# Switches swww wallpaper
# Select
cd "$HOME/Pictures"
imgpath=$(yad --width 1200 --height 800 --file --title='Choose wallpaper')
screensizey=$(xrandr --current | grep '*' | uniq | awk '{print $1}' | cut -d 'x' -f2 | head -1)
cursorposx=$(hyprctl cursorpos -j | gojq '.x')
cursorposy=$(hyprctl cursorpos -j | gojq '.y')
cursorposy_inverted=$(( screensizey - cursorposy ))
if [ "$imgpath" == '' ]; then
echo 'Aborted'
exit 0
fi
echo Sending "$imgpath" to swww. Cursor pos: ["$cursorposx, $cursorposy_inverted"] &
# Change swww img
swww img "$imgpath" --transition-step 230 --transition-fps 60 \
--transition-type grow --transition-angle 30 --transition-duration 1 \
--transition-pos "$cursorposx, $cursorposy_inverted" &
# Generate colors for eww n stuff
cp "$imgpath" "$HOME/.config/eww/images/wallpaper"
cd "$HOME/.config/eww" || exit
./scripts/launchapp '>wall'
+97
View File
@@ -0,0 +1,97 @@
#include <pwd.h>
#include <sys/stat.h>
#include <unistd.h>
#include <array>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
#include <vector>
#include "nlohmann/json.hpp"
using namespace std;
using json = nlohmann::json;
string clients, pinned, username;
json clientjson, apps;
vector<string> appnames;
string getUsername() {
uid_t uid = geteuid();
struct passwd* pw = getpwuid(uid);
return pw->pw_name;
}
string exec(const char* cmd) {
array<char, 128> buffer;
string result;
unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose);
if (!pipe) {
throw runtime_error("popen() failed!");
}
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
result += buffer.data();
}
return result;
}
void addApp(json& client) {
if (client["class"] == "") return;
bool found = false;
for (json& obj : apps) {
auto it = obj.find("class");
if (it != obj.end() && *it == client["class"]) {
found = true;
obj["count"] = int(obj["count"]) + 1;
obj["address"].push_back(client["address"]);
obj["workspace"].push_back(client["workspace"]["id"]);
break;
}
}
if (!found) {
json newApp =
R"({"class": "", "count": 1, "workspace": [], "address": [], "icon": ""})"_json;
newApp["class"] = client["class"];
newApp["address"].push_back(client["address"]);
newApp["workspace"].push_back(client["workspace"]["id"]);
string filename = string("./scripts/cache/" + string(client["class"]));
std::ifstream ifs(filename);
std::string iconpath((std::istreambuf_iterator<char>(ifs)),
(std::istreambuf_iterator<char>()));
// cout << "PATH: " << filename << " | ICON PATH: " << iconpath << '\n';
while (iconpath.size() > 0 && *iconpath.rbegin() == '\n')
iconpath.pop_back(); // Remove '\n'
newApp["icon"] = iconpath;
apps.push_back(newApp);
}
}
void getAppNameAndCount() {
// Get clients
clients = exec("hyprctl clients -j | gojq -c -M");
pinned = exec(&string("cat /home/" + username +
"/.config/eww/json/taskbar.json | gojq -c -M")[0]);
clientjson = json::parse(clients);
apps = json::parse(pinned);
// Access the values
for (json client : clientjson) {
addApp(client);
// cout << client << '\n';
}
}
void getAppIcon() {}
int main() {
// ios::sync_with_stdio(false);
// cin.tie(nullptr);
username = getUsername();
getAppNameAndCount();
getAppIcon();
cout << apps << '\n';
}
+13
View File
@@ -0,0 +1,13 @@
#!/usr/bin/bash
scripts/taskbar
if [ "$1" == "--once" ]; then
scripts/taskbar
exit 0
else
socat -u UNIX-CONNECT:/tmp/hypr/"$HYPRLAND_INSTANCE_SIGNATURE"/.socket2.sock - | rg --line-buffered "window>>" | while read -r line; do
scripts/taskbar
echo
done
fi
+14
View File
@@ -0,0 +1,14 @@
#!/usr/bin/bash
scripts/taskviewlayout
if [ "$1" == "--once" ]; then
exit 0
else
socat -u UNIX-CONNECT:/tmp/hypr/"$HYPRLAND_INSTANCE_SIGNATURE"/.socket2.sock - | rg --line-buffered "window>>" | while read -r line; do
# This sleep is necessary
# It prevents the script from being faster than hyprctl
sleep 0.025
scripts/taskviewlayout
done
fi
+186
View File
@@ -0,0 +1,186 @@
#include <array> // This script tries to show windows of workspaces
#include <cmath> // in a reasonable way in Task View
#include <filesystem> //
#include <fstream> // Goal: all windows on the same row have equal height
#include <iostream> //
#include <memory> //
#include <regex> // binary search -> ok scale
#include <stdexcept> // -> sort small-wide windows -> match pairs -> rows
#include <string>
#include "nlohmann/json.hpp"
using namespace std;
using json = nlohmann::json;
#define COLS 10
#define RES_WIDTH 1920
#define RES_HEIGHT 1080
#define RESERVED_BOTTOM 250
#define SPACING 30
#define TITLEBAR_AND_BORDER_HEIGHT 51
#define MIN_ROW_HEIGHT 186 // 100px (else scroll down)
#define MAX_ROW_HEIGHT 300 // 100px (else scroll down)
const json EMPTY_JSON = R"([])"_json;
const string workspaceInitTemplate = "[]";
int numOfApps[COLS] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
string clients;
json clientjson, workspaces;
json workspacesArranged;
string exec(const char* cmd) {
array<char, 128> buffer;
string result;
unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose);
if (!pipe) {
throw runtime_error("popen() failed!");
}
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
result += buffer.data();
}
return result;
}
void initWorkspaces() {
int i = 0;
for (int j = 0; j < COLS; j++) {
int workspaceNum = i * COLS + j + 1; // Note: Workspaces are 1-base
string workspaceInitString =
regex_replace(workspaceInitTemplate, regex("__WORKSPACE_ID"),
to_string(workspaceNum));
json thisWorkspaceInit = json::parse(workspaceInitString);
workspaces.push_back(thisWorkspaceInit);
}
}
void addApp(json& client) {
// Calculate position in overview tile
int workspaceNum = int(client["workspace"]["id"]) - 1; // 1-base to 0-base
if (workspaceNum < 0)
return; // Skip scratchpads/specials, as they have negative ids
int i = workspaceNum / COLS, j = workspaceNum % COLS;
// New JSON for app
json newApp =
R"({"class": "", "workspace": {"id": 8, "name": "8"}, "title": "", "at": [0, 0], "size": [0, 0], "address": [], "icon": ""})"_json;
// Add normal stuff
newApp["class"] = client["class"];
newApp["address"] = client["address"];
newApp["workspace"] = client["workspace"];
newApp["title"] = client["title"];
newApp["size"] = client["size"];
// Icon path
string filename = string("./scripts/cache/" + string(client["class"]));
std::ifstream ifs(filename);
std::string iconpath((std::istreambuf_iterator<char>(ifs)),
(std::istreambuf_iterator<char>()));
while (iconpath.size() > 0 && *iconpath.rbegin() == '\n')
iconpath.pop_back(); // Remove '\n'
newApp["icon"] = iconpath;
// Counting
int size_x = int(newApp["size"][0]);
int size_y = int(newApp["size"][1]);
if (size_x <= size_y * 2) { // Normal
newApp["countAs"] = 1; // count as 1 window
} else { // Very wide
newApp["countAs"] = 2; // count as 2 windows
}
numOfApps[int(newApp["workspace"]["id"]) - 1] += int(newApp["countAs"]);
// Push
workspaces[j].push_back(newApp);
}
void getApps() {
// Get clients
clients = exec("hyprctl clients -j | gojq -c -M");
clientjson = json::parse(clients);
// Access the values
for (json client : clientjson) {
addApp(client);
}
}
void scaleWindows() {
for (int i = 0; i < workspaces.size(); i++) {
if (workspaces[i].size() == 0) {
workspacesArranged.push_back(EMPTY_JSON);
continue;
}
// Declare
int numOfRows = numOfApps[i] > 3 ? int(ceil(sqrt(numOfApps[i]))) : 1;
int winsPerRow = (numOfApps[i] + (numOfRows - 1)) / numOfRows; // ceil
json thisWorkspace = EMPTY_JSON;
for (int i = 0; i < numOfRows; i++) thisWorkspace.push_back(EMPTY_JSON);
int rowHeight =
min(max(MIN_ROW_HEIGHT,
(RES_HEIGHT - RESERVED_BOTTOM - SPACING) / numOfRows -
TITLEBAR_AND_BORDER_HEIGHT - SPACING),
MAX_ROW_HEIGHT);
int thisRowCnt = 0, rowsDone = 0;
// cout << "Workspace " << i + 1 << " | Rows: " << numOfRows
// << " | Per row: " << winsPerRow << '\n';
// Scale
for (json& window : workspaces[i]) {
int cntAs = int(window["countAs"]);
if (cntAs == 1) {
window["size"][0] = int(window["size"][0]) /
(float(window["size"][1]) / rowHeight);
window["size"][1] = rowHeight;
} else { // cntAs == 2
window["size"][1] =
int(float(window["size"][1]) /
(float(window["size"][0]) / (rowHeight * 2)));
window["size"][0] = rowHeight * 2;
}
// int minWidth = string(window["title"]).size() * 9;
// cout << "Window: " << string(window["title"])
// << ", min width: " << minWidth << '\n';
// if (window["size"][0] < minWidth) {
// window["size"][1] = int(window["size"][1]) *
// (float(minWidth) /
// int(window["size"][0]));
// window["size"][0] = minWidth;
// }
// cout << " --> " << window["size"][0] << "x" << window["size"][1]
// << '\n';
thisWorkspace[rowsDone].push_back(window);
thisRowCnt += int(window["countAs"]);
if (thisRowCnt >= winsPerRow) {
rowsDone++;
thisRowCnt = 0;
}
}
workspacesArranged.push_back(thisWorkspace);
}
}
int main(int argc, char* argv[]) {
ios::sync_with_stdio(false);
// Get windows in workspaces, counting
initWorkspaces();
getApps();
// cout << ">>>>>>>> [DEBUG INGO START] >>>>>>>>" << '\n';
// cout << workspaces << '\n';
// cout << "<<<<<<<< [DEBUG INGO END] <<<<<<<<" << '\n' << '\n';
// cout << "# of apps: ";
// for (int i = 0; i < COLS; i++) cout << numOfApps[i] << ' ';
// cout << '\n';
// Scaling, arranging
scaleWindows();
cout << workspacesArranged << '\n';
}
+156
View File
@@ -0,0 +1,156 @@
# -*- conf -*-
shell=fish
# term=foot (or xterm-256color if built with -Dterminfo=disabled)
term=xterm-256color
# login-shell=no
# app-id=foot
title=foot
# locked-title=no
font=JetBrainsMono Nerd Font:size=12
# font-bold=<bold variant of regular font>
# font-italic=<italic variant of regular font>
# font-bold-italic=<bold+italic variant of regular font>
# line-height=<font metrics>
letter-spacing=0
# horizontal-letter-offset=0
# vertical-letter-offset=0
# underline-offset=<font metrics>
# box-drawings-uses-font-glyphs=no
dpi-aware=no
# initial-window-size-pixels=700x500 # Or,
# initial-window-size-chars=<COLSxROWS>
# initial-window-mode=windowed
pad=25x25 # optionally append 'center'
# resize-delay-ms=100
# notify=notify-send -a ${app-id} -i ${app-id} ${title} ${body}
bold-text-in-bright=no
# word-delimiters=,│`|:"'()[]{}<>
# selection-target=primary
# workers=<number of logical CPUs>
[bell]
# urgent=no
# notify=no
# command=
# command-focused=no
[scrollback]
lines=10000
# multiplier=3.0
# indicator-position=relative
# indicator-format=
[url]
# launch=xdg-open ${url}
# label-letters=sadfjklewcmpgh
# osc8-underline=url-mode
# protocols=http, https, ftp, ftps, file, gemini, gopher
# uri-characters=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.,~:;/?#@!$&%*+="'
[cursor]
style=beam
# color=111111 dcdccc
color=282a36 f8f8f2
# blink=no
beam-thickness=1.5
# underline-thickness=<font underline thickness>
[mouse]
# hide-when-typing=no
# alternate-scroll-mode=yes
[colors]
alpha=0.7
background=$background #
foreground=$onBackground #
regular0=$background #
regular1=$error #
regular2=$inversePrimary #
regular3=$tertiary #
regular4=$onPrimaryContainer #
regular5=$onSecondaryContainer #
regular6=$primary #
regular7=$onBackground #
bright0=$background #
bright1=$error #
bright2=$inversePrimary #
bright3=$tertiary #
bright4=$onPrimaryContainer #
bright5=$onSecondaryContainer #
bright6=$primary #
bright7=$onBackground #
[csd]
# preferred=server
# size=26
# font=<primary font>
# color=<foreground color>
# button-width=26
# button-color=<background color>
# button-minimize-color=<regular4>
# button-maximize-color=<regular2>
# button-close-color=<regular1>
[key-bindings]
scrollback-up-page=Page_Up
# scrollback-up-half-page=none
# scrollback-up-line=none
scrollback-down-page=Page_Down
# scrollback-down-half-page=none
# scrollback-down-line=none
clipboard-copy=Control+c
clipboard-paste=Control+v
# primary-paste=Shift+Insert
search-start=Control+f
# font-increase=Control+plus Control+equal Control+KP_Add
# font-decrease=Control+minus Control+KP_Subtract
# font-reset=Control+0 Control+KP_0
# spawn-terminal=Control+Shift+n
# minimize=none
# maximize=none
# fullscreen=none
# pipe-visible=[sh -c "xurls | fuzzel | xargs -r firefox"] none
# pipe-scrollback=[sh -c "xurls | fuzzel | xargs -r firefox"] none
# pipe-selected=[xargs -r firefox] none
# show-urls-launch=Control+Shift+u
# show-urls-copy=none
[search-bindings]
# cancel=Control+g Control+c Escape
# commit=Return
# find-prev=Control+r
# find-next=Control+s
# cursor-left=Left Control+b
# cursor-left-word=Control+Left Mod1+b
# cursor-right=Right Control+f
# cursor-right-word=Control+Right Mod1+f
# cursor-home=Home Control+a
# cursor-end=End Control+e
# delete-prev=BackSpace
# delete-prev-word=Control+BackSpace
# delete-next=Delete
# delete-next-word=Mod1+d Control+Delete
# extend-to-word-boundary=Control+w
# extend-to-next-whitespace=Control+Shift+w
# clipboard-paste=Control+v Control+y
# primary-paste=Shift+Insert
[url-bindings]
# cancel=Control+g Control+c Control+d Escape
# toggle-url-visible=t
[mouse-bindings]
# primary-paste=BTN_MIDDLE
# select-begin=BTN_LEFT
# select-begin-block=Control+BTN_LEFT
# select-extend=BTN_RIGHT
# select-extend-character-wise=Control+BTN_RIGHT
# select-word=BTN_LEFT-2
# select-word-whitespace=Control+BTN_LEFT-2
# select-row=BTN_LEFT-3
+21
View File
@@ -0,0 +1,21 @@
font=Lexend
terminal=foot -e
prompt=">> "
layer=overlay
[colors]
background=$backgroundff
text=$onBackgroundff
selection=$surfaceVariantff
selection-text=$onSurfaceVariantff
border=$surfaceVariantff
match=$primaryff
selection-match=$primaryff
[border]
radius=17
width=2
[dmenu]
exit-immediately-if-empty=yes
+101
View File
@@ -0,0 +1,101 @@
/* Gtklock css */
* {
all: unset;
border: 0px;
}
window {
background: rgba(0, 0, 0, 0.5);
background-size: cover;
background-repeat: no-repeat;
background-position: center;
}
#window-box {
border-radius: 1.5rem;
padding: 1.5rem;
border: 0px solid black;
}
#input-label {
font-size: 1.5rem;
color: transparent;
background-color: transparent;
margin: -20rem;
}
#input-field {
background-color: $secondaryContainer;
color: $onSecondaryContainer;
border-radius: 999px;
font-size: 1.3rem;
padding: 0.341rem 1.364rem;
margin: 0.477rem;
box-shadow: 2px 2px 4px rgba(22, 22, 22, 0.5);
min-height: 2.727rem;
}
#unlock-button {
margin: -20rem;
color: transparent;
background-color: transparent;
}
#error-label {
color: $error;
}
#clock-label {
font-family: 'Lexend';
font-size: 6rem;
border-radius: 1.2rem;
padding: 0.5rem;
margin: 0.6rem;
margin-top: -35rem;
color: $primary;
text-shadow: 1px 1px 2px rgba(22, 22, 30, 0.5);
}
#user-image {}
#powerbar-box {}
#poweroff-button {
background-color: $secondaryContainer;
color: $onSecondaryContainer;
min-width: 3rem;
min-height: 3rem;
margin: 10px;
border-radius: 99px;
}
#suspend-button {
background-color: $secondaryContainer;
color: $onSecondaryContainer;
min-width: 3rem;
min-height: 3rem;
margin: 10px;
border-radius: 99px;
}
#reboot-button {
background-color: $secondaryContainer;
color: $onSecondaryContainer;
min-width: 3rem;
min-height: 3rem;
margin: 10px;
border-radius: 99px;
}
#poweroff-button:hover,
#reboot-button:hover,
#suspend-button:hover {
background: rgba(200, 200, 200, 0.3);
}
#poweroff-button:active,
#reboot-button:active,
#suspend-button:active {
background: rgba(200, 200, 200, 0.5);
}
+92
View File
@@ -0,0 +1,92 @@
#include <pwd.h>
#include <sys/stat.h>
#include <unistd.h>
#include <algorithm>
#include <cctype>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include "nlohmann/json.hpp"
using namespace std;
using json = nlohmann::json;
string rawTodo;
json todo;
// Function to check if file exists, if yes read it
string readIfExists(const string& name) {
ifstream f(name.c_str());
stringstream buffer;
if (f) { // check if the file was opened successfully
buffer << f.rdbuf(); // read the whole file into a string stream
f.close(); // close the file when done
}
return buffer.str(); // return the string stream as a string
}
void writeToFile(const string& name, const string& content) {
ofstream f(name.c_str(), ios::app); // open the file in append mode
if (f) { // check if the file was opened successfully
f << content << "\n"; // write the content to the file
f.close(); // close the file when done
} else {
cerr << "Error: could not open " << name
<< "\n"; // print an error message to the standard error
}
}
string exec(const char* cmd) {
array<char, 128> buffer;
string result;
unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose);
if (!pipe) {
throw runtime_error("popen() failed!");
}
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
result += buffer.data();
}
return result;
}
void delItem(const string& stringToDelete) {
cout << " [i] Full list: '" << todo << "'\n";
cout << " [x] Deleting item: '" << stringToDelete << "'\n\n";
for (int i = 0; i < todo.size(); i++) {
const string& thisEntry = todo[i];
cout << "Compare: \"" << thisEntry << "\" and \"" << stringToDelete << "\"\n";
if (thisEntry == stringToDelete) {
cout << "yes\n";
todo.erase(i);
break;
}
}
}
void addItem(const string& stringToAdd) {
cout << "adding\n";
todo.push_back(stringToAdd);
}
int main(int argc, char* argv[]) {
if (argc == 1) {
cout << "Usage: todo del [ STRING ]";
return 0;
}
rawTodo = readIfExists("json/todo.json");
todo = json::parse(rawTodo);
if (argc > 2 && string(argv[1]) == "del") {
delItem(string(argv[2]));
exec("echo '' > json/todo.json");
writeToFile("json/todo.json", todo.dump());
}
else if (argc > 2 && string(argv[1]) == "add") {
addItem(string(argv[2]));
exec("echo '' > json/todo.json");
writeToFile("json/todo.json", todo.dump());
}
}
+14
View File
@@ -0,0 +1,14 @@
#!/usr/bin/bash
state=$(eww get open_cheatsheet)
if [[ "$state" -gt "0" || "$1" == "--close" ]]; then
eww update open_cheatsheet=false
eww close cheatsheet
else
eww open cheatsheet
eww update open_cheatsheet=1
sleep 0.04
eww update open_cheatsheet=2
sleep 0.04
eww update open_cheatsheet=3
fi
+25
View File
@@ -0,0 +1,25 @@
#!/usr/bin/bash
state=$(eww get open_dashboard)
if [[ "$state" -gt "0" || "$1" == "--close" ]]; then
eww close dashboard
eww update open_dashboard=0
sleep 0.1
eww update cavajson=''
else
eww open dashboard
sleep 0.05
eww update open_dashboard=1
sleep 0.05
eww update open_dashboard=2
sleep 0.05
eww update open_dashboard=3
sleep 0.05
eww update open_dashboard=4
sleep 0.05
eww update open_dashboard=5
sleep 0.05
eww update open_dashboard=6
sleep 0.05
eww update open_dashboard=7
fi
+14
View File
@@ -0,0 +1,14 @@
#!/usr/bin/bash
state=$(eww get rev_mixer)
if [[ "$state" == "true" || "$1" == "--close" ]]; then
eww update open_sideleft=false
sleep 0.15
eww update rev_mixer=false
else
cd ~/.config/eww || exit
eww update rev_mixer=true
eww open sideleft
eww update open_sideleft=true
eww update open_sideright=false
fi
+11
View File
@@ -0,0 +1,11 @@
#!/usr/bin/bash
currentshader=$(hyprctl getoption decoration:screen_shader -j | gojq -r '.str')
if [[ "$currentshader" != *"extradark.frag" ]]; then
hyprctl keyword decoration:screen_shader '~/.config/hypr/shaders/extradark.frag'
else
hyprctl keyword decoration:screen_shader ''
hyprctl reload
fi
scripts/hyprsettings tickle
+17
View File
@@ -0,0 +1,17 @@
#!/usr/bin/bash
if [[ "$1" == "--open" ]]; then
eww open notificationspopup
eww update open_notificationspopup=true
exit
fi
state=$(eww get open_notificationspopup)
if [[ "$state" == "true" || "$1" == "--close" ]]; then
eww update open_notificationspopup=false
sleep 0.15
eww close notificationspopup
else
cd ~/.config/eww || exit
eww open notificationspopup
eww update open_notificationspopup=true
fi
+11
View File
@@ -0,0 +1,11 @@
#!/usr/bin/bash
cd ~/.config/eww
state=$(eww get osd_vol)
if [[ "$1" == "--open" ]]; then
eww update osd_bright=true
elif [[ "$1" == "--close" ]]; then
eww update osd_bright=false
else
eww update osd_bright=true
fi
+11
View File
@@ -0,0 +1,11 @@
#!/usr/bin/bash
cd ~/.config/eww
state=$(eww get osd_bright)
if [[ "$1" == "--open" ]]; then
eww update osd_vol=true
elif [[ "$1" == "--close" ]]; then
eww update osd_vol=false
else
eww update osd_vol=true
fi
+20
View File
@@ -0,0 +1,20 @@
#!/usr/bin/bash
cd ~/.config/eww || exit
mkdir -p ~/.config/eww/scripts/cache/
state=$(eww get open_powerview)
if [[ "$state" == "true" || "$1" == "--close" ]]; then
hyprctl dispatch submap reset
eww close powerview 2>/dev/null &
eww update overview_query='' &
eww update open_powerview=false &
else
scripts/allapps > scripts/cache/entries.txt &
scripts/allappnames > scripts/cache/entrynames.txt &
eww update overview_query='' &
eww update overview_hover_name='{"class":"LMB: Focus | MMB: Close | RMB: Select/Move","title":"Powerview","workspace":{"id":0,"name":"0"},"icon": "/usr/share/icons/breeze-dark/actions/16/window.svg", "size": [0,0], "at": [0,0]}' &
eww open powerview
eww update open_powerview=true
hyprctl dispatch submap powerview
fi
+13
View File
@@ -0,0 +1,13 @@
#!/usr/bin/bash
state=$(eww get open_sideleft)
if [[ "$state" == "true" || "$1" == "--close" ]]; then
eww update open_sideleft=false
sleep 0.15
eww update rev_mixer=false
else
cd ~/.config/eww || exit
eww open sideleft
eww update open_sideleft=true
eww update open_sideright=false
fi
+11
View File
@@ -0,0 +1,11 @@
#!/usr/bin/bash
state=$(eww get open_sideright)
if [[ "$state" == "true" || "$1" == "--close" ]]; then
eww update open_sideright=false
else
cd ~/.config/eww || exit
eww open sideright
eww update open_sideright=true
eww update open_sideleft=false
fi
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/bash
BAR_HEIGHT_NORMAL='40'
BAR_HEIGHT_NORMAL_BOTTOM='60'
bar_height=$(eww get BAR_HEIGHT)
if [ "$1" == "bottom" ] || [ "$bar_height" == "$BAR_HEIGHT_NORMAL" ]; then
eww close bar
eww update BAR_HEIGHT=0
eww update BAR_HEIGHT_BOTTOM=$BAR_HEIGHT_NORMAL_BOTTOM
eww open barbottom
hyprctl keyword monitor ,addreserved,0,$BAR_HEIGHT_NORMAL_BOTTOM,0,0
else
eww close barbottom
eww update BAR_HEIGHT=$BAR_HEIGHT_NORMAL
eww update BAR_HEIGHT_BOTTOM=0
eww open bar
hyprctl keyword monitor ,addreserved,$BAR_HEIGHT_NORMAL,0,0,0
fi
+13
View File
@@ -0,0 +1,13 @@
#!/usr/bin/bash
state=$(eww get open_visualizer)
if [[ "$state" == "true" || "$1" == "--close" ]]; then
eww update open_visualizer=false
sleep 0.15
eww close visualizer
eww update cavajson='[]'
else
cd ~/.config/eww || exit
eww open visualizer
eww update open_visualizer=true
fi
+9
View File
@@ -0,0 +1,9 @@
#!/usr/bin/bash
if [ "$1" == "light" ]; then
echo -n '-l' > 'scripts/workdir/__mode_light_dark.txt'
cp css/savedcolors/_iconcolor_default.txt css/_iconcolor_default.txt
else
echo -n '' > 'scripts/workdir/__mode_light_dark.txt'
cp css/savedcolors/_iconcolor_default.txt css/_iconcolor_default.txt
fi
+137
View File
@@ -0,0 +1,137 @@
#!/usr/bin/env bash
cd ~/.config/eww
volicons=("" "" "")
XDG_CACHE_HOME="$HOME/.cache"
date="$XDG_CACHE_HOME/eww/osd_vol.date"
lock=0
showhide() {
# get dates
rundate=$(cat "$date")
currentdate=$(date +%s)
# handle showing
if [ "$rundate" = "$currentdate" ] && [ "$lock" -eq 0 ]; then
scripts/toggle-osd-vol.sh --open
lock=1
elif [ $((currentdate - rundate)) -ge 2 ] && [ "$lock" -eq 1 ]; then
scripts/toggle-osd-vol.sh --close > /dev/null
lock=0
fi
}
osd() {
if [ ! -f "$date" ]; then
mkdir -p "$XDG_CACHE_HOME/eww"
fi
date +%s > "$date"
showhide
}
osd_handler() {
lock=0
rundate=0
if [ ! -f "$date" ]; then
mkdir -p "$XDG_CACHE_HOME/eww"
echo 0 > "$date"
fi
while true; do
showhide
sleep 0.1
done
}
vol() {
wpctl get-volume @DEFAULT_AUDIO_$1@ | awk '{print int($2*100)}'
}
ismuted() {
wpctl get-volume @DEFAULT_AUDIO_"$1"@ | rg -i muted
echo $?
}
setvol() {
wpctl set-volume @DEFAULT_AUDIO_"$1"@ "$(awk -v n="$2" 'BEGIN{print (n / 100)}')"
}
setmute() {
wpctl set-mute @DEFAULT_AUDIO_"$1"@ toggle
}
if [ "$1" = "--once" ]; then
lvl=$(awk -v n="$(vol "SINK")" 'BEGIN{print int(n/34)}')
ismuted=$(ismuted "SINK")
if [ "$ismuted" = 1 ]; then
icon="${volicons[$lvl]}"
else
icon=""
fi
audio=1
if [ "$(wpctl status | grep 'MUTED')" == "" ]; then
audio=1
else
audio=0
fi
echo '{"icon":"'"$icon"'","audio":"'"$audio"'","percent":"'"$(vol "SINK")"'","microphone":"'"$(vol "SOURCE")"'"}'
exit 0
fi
if [ "$1" = "mute" ]; then
if [ "$2" != "SOURCE" ] && [ "$2" != "SINK" ]; then
echo "Can only mute SINK or SOURCE"; exit 1
fi
setmute "$2"
elif [ "$1" = "setvol" ]; then
if [ "$2" != "SOURCE" ] && [ "$2" != "SINK" ]; then
echo "Can only set volume for SINK or SOURCE"; exit 1
elif [ "$3" -lt 1 ] || [ "$3" -gt 100 ]; then
echo "Volume must be between 1 and 100"; exit 1
fi
setvol "$2" "$3"
elif [ "$1" = "osd" ]; then
osd
else
# initial values
lvl=$(awk -v n="$(vol "SINK")" 'BEGIN{print int(n/34)}')
ismuted=$(ismuted "SINK")
device=$(pactl --format=json list | gojq -r '.["sinks"][0]["active_port"]' | sed 's/\[Out] //g')
device=$(echo "$device" | tail -1)
if [ "$ismuted" = 1 ]; then
icon="${volicons[$lvl]}"
else
icon=""
fi
audio=1
if [ "$(wpctl status | grep 'MUTED')" == "" ]; then
audio=1
else
audio=0
fi
echo '{"icon":"'"$icon"'","audio":"'"$audio"'","device":"'"$device"'","percent":"'"$(vol "SINK")"'","microphone":"'"$(vol "SOURCE")"'"}'
osd_handler &
# event loop
pactl subscribe | rg --line-buffered "on sink" | while read -r _; do
lvl=$(awk -v n="$(vol "SINK")" 'BEGIN{print int(n/34)}')
ismuted=$(ismuted "SINK")
device=$(pactl --format=json list | gojq -r '.["sinks"][0]["active_port"]' | sed 's/\[Out] //g')
device=$(echo "$device" | tail -1)
if [ "$ismuted" = 1 ]; then
icon="${volicons[$lvl]}"
else
icon=""
fi
audio=1
if [ "$(wpctl status | grep 'MUTED')" == "" ]; then
audio=1
else
audio=0
fi
echo '{"icon":"'"$icon"'","audio":"'"$audio"'","device":"'"$device"'","percent":"'"$(vol "SINK")"'","microphone":"'"$(vol "SOURCE")"'"}'
done
fi
+139
View File
@@ -0,0 +1,139 @@
#!/usr/bin/python3
import requests
import json
import os
import sys
from PIL import Image
def printhelp():
print('''
Usage: waifu-get.py [OPTION]... [TAG]...
Options:
--segs\tForce NSFW images
--im\tUse waifu.im API. You can use many tags
--pics\tUse waifu.pics API. Use 1 tag only.
--nekos\tUse nekos.life (old) API. No tags.
Tags:
waifu.im (type):
maid waifu marin-kitagawa mori-calliope raiden-shogun oppai selfies uniform
waifu.im (nsfw tags):
ecchi hentai ero ass paizuri oral milf
''')
exit()
###### help ######
if len(sys.argv) == 1:
printhelp()
###### variables ######
api_name = {'im': 'waifu.im', 'nekos': 'nekos.life', 'pics': 'waifu.pics', 'moe': 'nekos.moe'}
debug = False
mode = 'im' # either 'im' (waifu.im), 'nekos' (nekos.life), or 'pics' (waifu.pics)
taglist = []
segs = False
output = {}
headers = {}
###### arguments ######
for i in range(1, len(sys.argv)): # Add tags
if sys.argv[i] == '--debug':
debug = True
elif sys.argv[i] == '--segs':
segs = True
elif sys.argv[i] == '--im':
mode = 'im'
elif sys.argv[i] == '--neko':
mode = 'nekos'
elif sys.argv[i] == '--pics':
mode = 'pics'
elif sys.argv[i] == '--moe':
mode = 'moe'
elif sys.argv[i] == '--help' or sys.argv[i] == '-h':
printhelp()
else:
taglist.append(sys.argv[i])
###### prepare request ######
if mode == 'im':
url = 'https://api.waifu.im/search'
headers = {'Accept-Version': 'v5'}
elif mode == 'nekos':
if segs:
url = 'https://nekos.life/api/lewd/neko'
else:
url = 'https://nekos.life/api/neko'
elif mode == 'pics':
if segs:
url = 'https://api.waifu.pics/nsfw/'
else:
url = 'https://api.waifu.pics/sfw/'
if len(taglist) > 0:
url += taglist[0]
else:
url += 'waifu'
elif mode == 'moe':
url = 'https://nekos.moe/api/v1/random/image'
if segs:
url += '?nsfw=true'
else: # default: waifu.im
url = 'https://api.waifu.im/search'
headers = {'Accept-Version': 'v5'}
params = {
'included_tags': taglist,
'height': '>=600',
'nsfw': segs
}
os.system('eww update rev_waifustatus=true')
os.system('eww update waifu_status=\'Requesting {0} API\''.format(api_name[mode]))
response = requests.get(url, params=params, headers=headers)
if debug:
print(json.dumps(response.json()))
exit()
###### processing ######
if response.status_code == 200:
data = response.json()
# Process the response data as needed
if mode == 'im':
output['link'] = data['images'][0]['url']
output['sauce'] = data['images'][0]['source']
elif mode == 'nekos':
output['link'] = data['neko']
output['sauce'] = data['neko']
elif mode == 'moe':
image_id = data['images'][0]['id']
output['link'] = str('https://nekos.moe/image/' + image_id)
output['sauce'] = str('https://nekos.moe/post/' + image_id)
elif mode == 'pics':
output['link'] = data['url']
output['sauce'] = data['url']
else: # default: waifu.im
output['link'] = data['images'][0]['url']
output['sauce'] = data['images'][0]['source']
os.system('eww update waifu_status=\'Downloading image\'')
os.system('wget -O "{0}" "{1}" -q read-timeout=0.1'.format('eww_covers/waifu_tmp', output['link']))
os.system('eww update waifu=\'{"name":"eww_covers/waifu_loading", "size": [0, 100]}\'')
os.system('mv ./eww_covers/waifu_tmp ./eww_covers/waifu')
with Image.open('./eww_covers/waifu') as img:
output['size'] = img.size
output['path'] = 'eww_covers/waifu'
output['ext'] = str('.' + img.format.lower())
print(json.dumps(output))
os.system('eww update rev_waifustatus=false')
else:
print('Request failed with status code:', response.status_code)
+1
View File
@@ -0,0 +1 @@
one
+154
View File
@@ -0,0 +1,154 @@
#!/usr/bin/env bash
# define colors
colors=("#FFFFFF" "#fab387" "#a6e3a1" "#89b4fa") # Active Workspaces
dimmed=("rgba(154,152,162,0.7)" "#f9e2af" "#94e2d5" "#b4befe") # Inactive workspaces
empty='empty' # Empty workspaces
# get initial focused workspace
focusedws=$(hyprctl -j monitors | gojq -r '.[] | select(.focused == true) | .activeWorkspace.id')
declare -A o=([1]=0 [2]=0 [3]=0 [4]=0 [5]=0 [6]=0 [7]=0 [8]=0 [9]=0 [10]=0)
declare -A monitormap
declare -A workspaces
# set color for each workspace
status() {
if [ "${o[$1]}" -eq 1 ]; then
mon=${monitormap[${workspaces[$1]}]}
echo -n "true"
else
echo -n "false"
fi
}
status_activity() {
if [ "${o[$1]}" -eq 1 ]; then
mon=${monitormap[${workspaces[$1]}]}
if [ $focusedws -eq "$1" ]; then
echo -n "active"
else
echo -n "inactive"
fi
else
echo -n "empty"
fi
}
# handle workspace create/destroy
workspace_event() {
if (( $1 <= 10 )); then
o[$1]=$2
while read -r k v; do workspaces[$k]="$v"; done < <(hyprctl -j workspaces | gojq -r '.[]|"\(.id) \(.monitor)"')
fi
if [ "$2" == "0" ]; then
unset "workspaces[$1]"
fi
}
# handle monitor (dis)connects
monitor_event() {
while read -r k v; do monitormap["$k"]=$v; done < <(hyprctl -j monitors | gojq -r '.[]|"\(.name) \(.id) "')
}
# generate the json for eww
generate() {
echo -n '['
for i in {1..10}; do
echo -n ''$([ $i -eq 1 ] || echo ,)'{"num":"'$i'","haswins":"'$(status "$i")'"}'
done
echo ']'
}
# setup
# add monitors
monitor_event
# add workspaces
while read -r k v; do workspaces[$k]="$v"; done < <(hyprctl -j workspaces | gojq -r '.[]|"\(.id) \(.monitor)"')
# check occupied workspaces
for num in "${!workspaces[@]}"; do
o[$num]=1
done
# generate initial widget
generate
if [ "$1" == "--once" ]; then
exit
fi
socat -u UNIX-CONNECT:/tmp/hypr/"$HYPRLAND_INSTANCE_SIGNATURE"/.socket2.sock - | while read -r line; do
# echo "${#workspaces[@]} ${#o[@]}"
# echo $line
case ${line%>>*} in
"focusedmon")
focusedws=${line#*,}
generate
;;
"createworkspace")
# workspace_event "${line#*>>}" 1
o=([1]=0 [2]=0 [3]=0 [4]=0 [5]=0 [6]=0 [7]=0 [8]=0 [9]=0 [10]=0)
workspaces=()
# add workspaces
while read -r k v; do workspaces[$k]="$v"; done < <(hyprctl -j workspaces | gojq -r '.[]|"\(.id) \(.monitor)"')
# check occupied workspaces
for num in "${!workspaces[@]}"; do
o[$num]=1
done
# focusedws=${line#*>>}
generate
;;
"movewindow")
generate
;;
"destroyworkspace")
# workspace_event "${line#*>>}" 0
o=([1]=0 [2]=0 [3]=0 [4]=0 [5]=0 [6]=0 [7]=0 [8]=0 [9]=0 [10]=0)
workspaces=()
# add workspaces
while read -r k v; do workspaces[$k]="$v"; done < <(hyprctl -j workspaces | gojq -r '.[]|"\(.id) \(.monitor)"')
# check occupied workspaces
for num in "${!workspaces[@]}"; do
o[$num]=1
done
generate
;;
"monitor"*)
monitor_event
generate
;;
esac
# echo $line
# generate
done
# main loop
# socat -u UNIX-CONNECT:/tmp/hypr/"$HYPRLAND_INSTANCE_SIGNATURE"/.socket2.sock - | rg --line-buffered "workspace|mon(itor)?" | while read -r line; do
# case ${line%>>*} in
# "workspace")
# focusedws=${line#*>>}
# generate
# ;;
# "focusedmon")
# focusedws=${line#*,}
# generate
# ;;
# "createworkspace")
# workspace_event "${line#*>>}" 1
# focusedws=${line#*>>}
# # generate
# ;;
# "destroyworkspace")
# workspace_event "${line#*>>}" 0
# generate
# ;;
# "monitor"*)
# monitor_event
# generate
# ;;
# esac
# done