Merge branch 'Alexays:master' into hyprland-window-rewrite
commit
f72c1a54d3
|
@ -27,7 +27,7 @@
|
||||||
#include "modules/hyprland/language.hpp"
|
#include "modules/hyprland/language.hpp"
|
||||||
#include "modules/hyprland/window.hpp"
|
#include "modules/hyprland/window.hpp"
|
||||||
#endif
|
#endif
|
||||||
#if defined(__linux__) && !defined(NO_FILESYSTEM)
|
#if defined(__FreeBSD__) || (defined(__linux__) && !defined(NO_FILESYSTEM))
|
||||||
#include "modules/battery.hpp"
|
#include "modules/battery.hpp"
|
||||||
#endif
|
#endif
|
||||||
#if defined(HAVE_CPU_LINUX) || defined(HAVE_CPU_BSD)
|
#if defined(HAVE_CPU_LINUX) || defined(HAVE_CPU_BSD)
|
||||||
|
|
|
@ -6,7 +6,9 @@
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#endif
|
#endif
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
#if defined(__linux__)
|
||||||
#include <sys/inotify.h>
|
#include <sys/inotify.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
|
@ -152,6 +152,7 @@ class WorkspaceManager : public AModule {
|
||||||
|
|
||||||
bool sort_by_name_ = true;
|
bool sort_by_name_ = true;
|
||||||
bool sort_by_coordinates_ = true;
|
bool sort_by_coordinates_ = true;
|
||||||
|
bool sort_by_number_ = false;
|
||||||
bool all_outputs_ = false;
|
bool all_outputs_ = false;
|
||||||
bool active_only_ = false;
|
bool active_only_ = false;
|
||||||
bool creation_delayed_ = false;
|
bool creation_delayed_ = false;
|
||||||
|
|
|
@ -33,6 +33,11 @@ Addressed by *wlr/workspaces*
|
||||||
Note that if both *sort-by-name* and *sort-by-coordinates* are true sort by name will be first.
|
Note that if both *sort-by-name* and *sort-by-coordinates* are true sort by name will be first.
|
||||||
If both are false - sort by id will be performed.
|
If both are false - sort by id will be performed.
|
||||||
|
|
||||||
|
*sort-by-number*: ++
|
||||||
|
typeof: bool ++
|
||||||
|
default: false ++
|
||||||
|
If set to true, workspace names will be sorted numerically. Takes presedence over any other sort-by option.
|
||||||
|
|
||||||
*all-outputs*: ++
|
*all-outputs*: ++
|
||||||
typeof: bool ++
|
typeof: bool ++
|
||||||
default: false ++
|
default: false ++
|
||||||
|
@ -75,7 +80,8 @@ Additional to workspace name matching, the following *format-icons* can be set.
|
||||||
"5": "",
|
"5": "",
|
||||||
"focused": "",
|
"focused": "",
|
||||||
"default": ""
|
"default": ""
|
||||||
}
|
},
|
||||||
|
"sort-by-number": true
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -179,6 +179,11 @@ elif is_dragonfly or is_freebsd or is_netbsd or is_openbsd
|
||||||
'src/modules/memory/bsd.cpp',
|
'src/modules/memory/bsd.cpp',
|
||||||
'src/modules/memory/common.cpp',
|
'src/modules/memory/common.cpp',
|
||||||
)
|
)
|
||||||
|
if is_freebsd
|
||||||
|
src_files += files(
|
||||||
|
'src/modules/battery.cpp',
|
||||||
|
)
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
add_project_arguments('-DHAVE_SWAY', language: 'cpp')
|
add_project_arguments('-DHAVE_SWAY', language: 'cpp')
|
||||||
|
|
|
@ -7,7 +7,7 @@ waybar::AModule* waybar::Factory::makeModule(const std::string& name) const {
|
||||||
auto hash_pos = name.find('#');
|
auto hash_pos = name.find('#');
|
||||||
auto ref = name.substr(0, hash_pos);
|
auto ref = name.substr(0, hash_pos);
|
||||||
auto id = hash_pos != std::string::npos ? name.substr(hash_pos + 1) : "";
|
auto id = hash_pos != std::string::npos ? name.substr(hash_pos + 1) : "";
|
||||||
#if defined(__linux__) && !defined(NO_FILESYSTEM)
|
#if defined(__FreeBSD__) || (defined(__linux__) && !defined(NO_FILESYSTEM))
|
||||||
if (ref == "battery") {
|
if (ref == "battery") {
|
||||||
return new waybar::modules::Battery(id, config_[name]);
|
return new waybar::modules::Battery(id, config_[name]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
#include "modules/battery.hpp"
|
#include "modules/battery.hpp"
|
||||||
|
#if defined(__FreeBSD__)
|
||||||
|
#include <sys/sysctl.h>
|
||||||
|
#endif
|
||||||
#include <spdlog/spdlog.h>
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
waybar::modules::Battery::Battery(const std::string& id, const Json::Value& config)
|
waybar::modules::Battery::Battery(const std::string& id, const Json::Value& config)
|
||||||
: AButton(config, "battery", id, "{capacity}%", 60) {
|
: AButton(config, "battery", id, "{capacity}%", 60) {
|
||||||
|
#if defined(__Linux__)
|
||||||
battery_watch_fd_ = inotify_init1(IN_CLOEXEC);
|
battery_watch_fd_ = inotify_init1(IN_CLOEXEC);
|
||||||
if (battery_watch_fd_ == -1) {
|
if (battery_watch_fd_ == -1) {
|
||||||
throw std::runtime_error("Unable to listen batteries.");
|
throw std::runtime_error("Unable to listen batteries.");
|
||||||
|
@ -19,11 +23,12 @@ waybar::modules::Battery::Battery(const std::string& id, const Json::Value& conf
|
||||||
if (global_watch < 0) {
|
if (global_watch < 0) {
|
||||||
throw std::runtime_error("Could not watch for battery plug/unplug");
|
throw std::runtime_error("Could not watch for battery plug/unplug");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
worker();
|
worker();
|
||||||
}
|
}
|
||||||
|
|
||||||
waybar::modules::Battery::~Battery() {
|
waybar::modules::Battery::~Battery() {
|
||||||
|
#if defined(__linux__)
|
||||||
std::lock_guard<std::mutex> guard(battery_list_mutex_);
|
std::lock_guard<std::mutex> guard(battery_list_mutex_);
|
||||||
|
|
||||||
if (global_watch >= 0) {
|
if (global_watch >= 0) {
|
||||||
|
@ -39,9 +44,16 @@ waybar::modules::Battery::~Battery() {
|
||||||
batteries_.erase(it);
|
batteries_.erase(it);
|
||||||
}
|
}
|
||||||
close(battery_watch_fd_);
|
close(battery_watch_fd_);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void waybar::modules::Battery::worker() {
|
void waybar::modules::Battery::worker() {
|
||||||
|
#if defined(__FreeBSD__)
|
||||||
|
thread_timer_ = [this] {
|
||||||
|
dp.emit();
|
||||||
|
thread_timer_.sleep_for(interval_);
|
||||||
|
};
|
||||||
|
#else
|
||||||
thread_timer_ = [this] {
|
thread_timer_ = [this] {
|
||||||
// Make sure we eventually update the list of batteries even if we miss an
|
// Make sure we eventually update the list of batteries even if we miss an
|
||||||
// inotify event for some reason
|
// inotify event for some reason
|
||||||
|
@ -68,9 +80,11 @@ void waybar::modules::Battery::worker() {
|
||||||
refreshBatteries();
|
refreshBatteries();
|
||||||
dp.emit();
|
dp.emit();
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void waybar::modules::Battery::refreshBatteries() {
|
void waybar::modules::Battery::refreshBatteries() {
|
||||||
|
#if defined(__linux__)
|
||||||
std::lock_guard<std::mutex> guard(battery_list_mutex_);
|
std::lock_guard<std::mutex> guard(battery_list_mutex_);
|
||||||
// Mark existing list of batteries as not necessarily found
|
// Mark existing list of batteries as not necessarily found
|
||||||
std::map<fs::path, bool> check_map;
|
std::map<fs::path, bool> check_map;
|
||||||
|
@ -135,6 +149,7 @@ void waybar::modules::Battery::refreshBatteries() {
|
||||||
batteries_.erase(check.first);
|
batteries_.erase(check.first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unknown > Full > Not charging > Discharging > Charging
|
// Unknown > Full > Not charging > Discharging > Charging
|
||||||
|
@ -156,6 +171,58 @@ const std::tuple<uint8_t, float, std::string, float> waybar::modules::Battery::g
|
||||||
std::lock_guard<std::mutex> guard(battery_list_mutex_);
|
std::lock_guard<std::mutex> guard(battery_list_mutex_);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
#if defined(__FreeBSD__)
|
||||||
|
/* Allocate state of battery units reported via ACPI. */
|
||||||
|
int battery_units = 0;
|
||||||
|
size_t battery_units_size = sizeof battery_units;
|
||||||
|
if (sysctlbyname("hw.acpi.battery.units", &battery_units, &battery_units_size, NULL, 0) != 0) {
|
||||||
|
throw std::runtime_error("sysctl hw.acpi.battery.units failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (battery_units < 0) {
|
||||||
|
throw std::runtime_error("No battery units");
|
||||||
|
}
|
||||||
|
|
||||||
|
int capacity;
|
||||||
|
size_t size_capacity = sizeof capacity;
|
||||||
|
if (sysctlbyname("hw.acpi.battery.life", &capacity, &size_capacity, NULL, 0) != 0) {
|
||||||
|
throw std::runtime_error("sysctl hw.acpi.battery.life failed");
|
||||||
|
}
|
||||||
|
int time;
|
||||||
|
size_t size_time = sizeof time;
|
||||||
|
if (sysctlbyname("hw.acpi.battery.time", &time, &size_time, NULL, 0) != 0) {
|
||||||
|
throw std::runtime_error("sysctl hw.acpi.battery.time failed");
|
||||||
|
}
|
||||||
|
int rate;
|
||||||
|
size_t size_rate = sizeof rate;
|
||||||
|
if (sysctlbyname("hw.acpi.battery.rate", &rate, &size_rate, NULL, 0) != 0) {
|
||||||
|
throw std::runtime_error("sysctl hw.acpi.battery.rate failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto status = getAdapterStatus(capacity);
|
||||||
|
// Handle full-at
|
||||||
|
if (config_["full-at"].isUInt()) {
|
||||||
|
auto full_at = config_["full-at"].asUInt();
|
||||||
|
if (full_at < 100) {
|
||||||
|
capacity = 100.f * capacity / full_at;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (capacity > 100.f) {
|
||||||
|
// This can happen when the battery is calibrating and goes above 100%
|
||||||
|
// Handle it gracefully by clamping at 100%
|
||||||
|
capacity = 100.f;
|
||||||
|
}
|
||||||
|
uint8_t cap = round(capacity);
|
||||||
|
if (cap == 100 && status == "Plugged") {
|
||||||
|
// If we've reached 100% just mark as full as some batteries can stay
|
||||||
|
// stuck reporting they're still charging but not yet done
|
||||||
|
status = "Full";
|
||||||
|
}
|
||||||
|
|
||||||
|
// spdlog::info("{} {} {} {}", capacity,time,status,rate);
|
||||||
|
return {capacity, time / 60.0, status, rate};
|
||||||
|
|
||||||
|
#elif defined(__linux__)
|
||||||
uint32_t total_power = 0; // μW
|
uint32_t total_power = 0; // μW
|
||||||
bool total_power_exists = false;
|
bool total_power_exists = false;
|
||||||
uint32_t total_energy = 0; // μWh
|
uint32_t total_energy = 0; // μWh
|
||||||
|
@ -456,6 +523,7 @@ const std::tuple<uint8_t, float, std::string, float> waybar::modules::Battery::g
|
||||||
if (cap == 100 && status == "Charging") status = "Full";
|
if (cap == 100 && status == "Charging") status = "Full";
|
||||||
|
|
||||||
return {cap, time_remaining, status, total_power / 1e6};
|
return {cap, time_remaining, status, total_power / 1e6};
|
||||||
|
#endif
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
spdlog::error("Battery: {}", e.what());
|
spdlog::error("Battery: {}", e.what());
|
||||||
return {0, 0, "Unknown", 0};
|
return {0, 0, "Unknown", 0};
|
||||||
|
@ -463,11 +531,22 @@ const std::tuple<uint8_t, float, std::string, float> waybar::modules::Battery::g
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string waybar::modules::Battery::getAdapterStatus(uint8_t capacity) const {
|
const std::string waybar::modules::Battery::getAdapterStatus(uint8_t capacity) const {
|
||||||
|
#if defined(__FreeBSD__)
|
||||||
|
int state;
|
||||||
|
size_t size_state = sizeof state;
|
||||||
|
if (sysctlbyname("hw.acpi.battery.state", &state, &size_state, NULL, 0) != 0) {
|
||||||
|
throw std::runtime_error("sysctl hw.acpi.battery.state failed");
|
||||||
|
}
|
||||||
|
bool online = state == 2;
|
||||||
|
std::string status{"Unknown"}; // TODO: add status in FreeBSD
|
||||||
|
{
|
||||||
|
#else
|
||||||
if (!adapter_.empty()) {
|
if (!adapter_.empty()) {
|
||||||
bool online;
|
bool online;
|
||||||
std::string status;
|
std::string status;
|
||||||
std::ifstream(adapter_ / "online") >> online;
|
std::ifstream(adapter_ / "online") >> online;
|
||||||
std::getline(std::ifstream(adapter_ / "status"), status);
|
std::getline(std::ifstream(adapter_ / "status"), status);
|
||||||
|
#endif
|
||||||
if (capacity == 100) {
|
if (capacity == 100) {
|
||||||
return "Full";
|
return "Full";
|
||||||
}
|
}
|
||||||
|
@ -497,10 +576,12 @@ const std::string waybar::modules::Battery::formatTimeRemaining(float hoursRemai
|
||||||
}
|
}
|
||||||
|
|
||||||
auto waybar::modules::Battery::update() -> void {
|
auto waybar::modules::Battery::update() -> void {
|
||||||
|
#if defined(__linux__)
|
||||||
if (batteries_.empty()) {
|
if (batteries_.empty()) {
|
||||||
event_box_.hide();
|
event_box_.hide();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
auto [capacity, time_remaining, status, power] = getInfos();
|
auto [capacity, time_remaining, status, power] = getInfos();
|
||||||
if (status == "Unknown") {
|
if (status == "Unknown") {
|
||||||
status = getAdapterStatus(capacity);
|
status = getAdapterStatus(capacity);
|
||||||
|
|
|
@ -60,7 +60,10 @@ std::string Window::getLastWindowTitle(uint workspaceID) {
|
||||||
auto workspace = std::find_if(json.begin(), json.end(), [&](Json::Value workspace) {
|
auto workspace = std::find_if(json.begin(), json.end(), [&](Json::Value workspace) {
|
||||||
return workspace["id"].as<uint>() == workspaceID;
|
return workspace["id"].as<uint>() == workspaceID;
|
||||||
});
|
});
|
||||||
assert(workspace != std::end(json));
|
|
||||||
|
if (workspace != std::end(json)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
return (*workspace)["lastwindowtitle"].as<std::string>();
|
return (*workspace)["lastwindowtitle"].as<std::string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,11 @@ WorkspaceManager::WorkspaceManager(const std::string &id, const waybar::Bar &bar
|
||||||
sort_by_coordinates_ = config_sort_by_coordinates.asBool();
|
sort_by_coordinates_ = config_sort_by_coordinates.asBool();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto config_sort_by_number = config_["sort-by-number"];
|
||||||
|
if (config_sort_by_number.isBool()) {
|
||||||
|
sort_by_number_ = config_sort_by_number.asBool();
|
||||||
|
}
|
||||||
|
|
||||||
auto config_all_outputs = config_["all-outputs"];
|
auto config_all_outputs = config_["all-outputs"];
|
||||||
if (config_all_outputs.isBool()) {
|
if (config_all_outputs.isBool()) {
|
||||||
all_outputs_ = config_all_outputs.asBool();
|
all_outputs_ = config_all_outputs.asBool();
|
||||||
|
@ -61,6 +66,12 @@ auto WorkspaceManager::workspace_comparator() const
|
||||||
auto is_name_less = lhs->get_name() < rhs->get_name();
|
auto is_name_less = lhs->get_name() < rhs->get_name();
|
||||||
auto is_name_eq = lhs->get_name() == rhs->get_name();
|
auto is_name_eq = lhs->get_name() == rhs->get_name();
|
||||||
auto is_coords_less = lhs->get_coords() < rhs->get_coords();
|
auto is_coords_less = lhs->get_coords() < rhs->get_coords();
|
||||||
|
auto is_number_less = std::stoi(lhs->get_name()) < std::stoi(rhs->get_name());
|
||||||
|
|
||||||
|
if (sort_by_number_) {
|
||||||
|
return is_number_less;
|
||||||
|
}
|
||||||
|
|
||||||
if (sort_by_name_) {
|
if (sort_by_name_) {
|
||||||
if (sort_by_coordinates_) {
|
if (sort_by_coordinates_) {
|
||||||
return is_name_eq ? is_coords_less : is_name_less;
|
return is_name_eq ? is_coords_less : is_name_less;
|
||||||
|
|
Loading…
Reference in New Issue