| 9 | } |
| 10 | |
| 11 | auto waybar::modules::Memory::update() -> void { |
| 12 | parseMeminfo(); |
| 13 | |
| 14 | unsigned long memtotal = meminfo_["MemTotal"]; |
| 15 | unsigned long swaptotal = 0; |
| 16 | if (meminfo_.count("SwapTotal")) { |
| 17 | swaptotal = meminfo_["SwapTotal"]; |
| 18 | } |
| 19 | unsigned long memfree; |
| 20 | unsigned long swapfree = 0; |
| 21 | if (meminfo_.count("SwapFree")) { |
| 22 | swapfree = meminfo_["SwapFree"]; |
| 23 | } |
| 24 | if (meminfo_.count("MemAvailable")) { |
| 25 | // New kernels (3.4+) have an accurate available memory field. |
| 26 | memfree = meminfo_["MemAvailable"] + meminfo_["zfs_size"]; |
| 27 | } else { |
| 28 | // Old kernel; give a best-effort approximation of available memory. |
| 29 | memfree = meminfo_["MemFree"] + meminfo_["Buffers"] + meminfo_["Cached"] + |
| 30 | meminfo_["SReclaimable"] - meminfo_["Shmem"] + meminfo_["zfs_size"]; |
| 31 | } |
| 32 | |
| 33 | if (memtotal > 0 && memfree >= 0) { |
| 34 | float total_ram_gigabytes = |
| 35 | 0.01 * round(memtotal / 10485.76); // 100*10485.76 = 2^20 = 1024^2 = GiB/KiB |
| 36 | float total_swap_gigabytes = 0.01 * round(swaptotal / 10485.76); |
| 37 | int used_ram_percentage = 100 * (memtotal - memfree) / memtotal; |
| 38 | int used_swap_percentage = 0; |
| 39 | if (swaptotal) { |
| 40 | used_swap_percentage = 100 * (swaptotal - swapfree) / swaptotal; |
| 41 | } |
| 42 | float used_ram_gigabytes = 0.01 * round((memtotal - memfree) / 10485.76); |
| 43 | float used_swap_gigabytes = 0.01 * round((swaptotal - swapfree) / 10485.76); |
| 44 | float available_ram_gigabytes = 0.01 * round(memfree / 10485.76); |
| 45 | float available_swap_gigabytes = 0.01 * round(swapfree / 10485.76); |
| 46 | |
| 47 | auto format = format_; |
| 48 | auto state = getState(used_ram_percentage); |
| 49 | if (!state.empty() && config_["format-" + state].isString()) { |
| 50 | format = config_["format-" + state].asString(); |
| 51 | } |
| 52 | |
| 53 | if (format.empty()) { |
| 54 | event_box_.hide(); |
| 55 | } else { |
| 56 | event_box_.show(); |
| 57 | auto icons = std::vector<std::string>{state}; |
| 58 | label_.set_markup(fmt::format( |
| 59 | fmt::runtime(format), used_ram_percentage, |
| 60 | fmt::arg("icon", getIcon(used_ram_percentage, icons)), |
| 61 | fmt::arg("total", total_ram_gigabytes), fmt::arg("swapTotal", total_swap_gigabytes), |
| 62 | fmt::arg("percentage", used_ram_percentage), |
| 63 | fmt::arg("swapState", swaptotal == 0 ? "Off" : "On"), |
| 64 | fmt::arg("swapPercentage", used_swap_percentage), fmt::arg("used", used_ram_gigabytes), |
| 65 | fmt::arg("swapUsed", used_swap_gigabytes), fmt::arg("avail", available_ram_gigabytes), |
| 66 | fmt::arg("swapAvail", available_swap_gigabytes))); |
| 67 | } |
| 68 | |