Merge branch 'hotfix/3.5.1'
This commit is contained in:
commit
1c554dd0e0
98
.github/workflows/ci.yml
vendored
Normal file
98
.github/workflows/ci.yml
vendored
Normal file
@ -0,0 +1,98 @@
|
||||
name: CI
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
ref:
|
||||
description: 'ref'
|
||||
required: false
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
docs:
|
||||
runs-on: ubuntu-20.04
|
||||
env:
|
||||
COLOR: "ON"
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
ref: ${{ github.event.inputs.ref }}
|
||||
- name: Install Dependencies
|
||||
run: sudo apt-get install -y python3-sphinx
|
||||
- name: Build Documentation
|
||||
run: |
|
||||
mkdir -p doc/build
|
||||
cd doc/build
|
||||
cmake ..
|
||||
make doc
|
||||
|
||||
build:
|
||||
runs-on: ubuntu-20.04
|
||||
strategy:
|
||||
matrix:
|
||||
cxx: [g++, clang++]
|
||||
polybar_build_type: ["full"]
|
||||
build_type: ["Release"]
|
||||
include:
|
||||
- cxx: g++
|
||||
polybar_build_type: "tests"
|
||||
build_type: "Coverage"
|
||||
- cxx: g++
|
||||
polybar_build_type: "minimal"
|
||||
build_type: "Release"
|
||||
env:
|
||||
CXX: ${{ matrix.cxx }}
|
||||
BUILD_TYPE: ${{ matrix.build_type }}
|
||||
POLYBAR_BUILD_TYPE: ${{ matrix.polybar_build_type }}
|
||||
POLYBAR_DIR: ${{ github.workspace }}
|
||||
BUILD_DIR: "${{ github.workspace}}/build"
|
||||
MAKEFLAGS: "-j4"
|
||||
COLOR: "ON"
|
||||
steps:
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y \
|
||||
libxcb-composite0-dev \
|
||||
libxcb-ewmh-dev \
|
||||
libxcb-icccm4-dev \
|
||||
libxcb-image0-dev \
|
||||
libxcb-randr0-dev \
|
||||
libxcb-util0-dev \
|
||||
libxcb1-dev \
|
||||
libcairo2-dev \
|
||||
python3-xcbgen \
|
||||
xcb-proto
|
||||
|
||||
if [ "$POLYBAR_BUILD_TYPE" != "minimal" ]; then
|
||||
sudo apt-get install -y \
|
||||
libxcb-xkb-dev \
|
||||
libxcb-cursor-dev \
|
||||
libxcb-xrm-dev \
|
||||
i3-wm \
|
||||
libcurl4-openssl-dev \
|
||||
libjsoncpp-dev \
|
||||
libasound2-dev \
|
||||
libpulse-dev \
|
||||
libiw-dev \
|
||||
libmpdclient-dev
|
||||
fi
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
ref: ${{ github.event.inputs.ref }}
|
||||
- name: Summary
|
||||
run: ./common/ci/summary.sh
|
||||
- name: Configure
|
||||
run: ./common/ci/configure.sh
|
||||
- name: Build
|
||||
run: |
|
||||
cd $BUILD_DIR
|
||||
make
|
||||
- name: Tests
|
||||
if: ${{ matrix.polybar_build_type == 'tests' }}
|
||||
run: |
|
||||
cd $BUILD_DIR
|
||||
make check
|
||||
cd $POLYBAR_DIR
|
||||
bash <(curl -s https://codecov.io/bash) -F unittests -a "-ap" -Z
|
109
.travis.yml
109
.travis.yml
@ -1,109 +0,0 @@
|
||||
sudo: required
|
||||
dist: focal
|
||||
language: cpp
|
||||
|
||||
env:
|
||||
global:
|
||||
- JOBS=4
|
||||
- MAKEFLAGS="-j ${JOBS}"
|
||||
- POLYBAR_BUILD_TYPE="compile"
|
||||
|
||||
# Build configurations can either not specify anything for 'addon' and use this
|
||||
# default list of packages. Or they can pick and choose which package groups to
|
||||
# install
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- &base_deps
|
||||
- libxcb-composite0-dev
|
||||
- libxcb-ewmh-dev
|
||||
- libxcb-icccm4-dev
|
||||
- libxcb-image0-dev
|
||||
- libxcb-randr0-dev
|
||||
- libxcb-util0-dev
|
||||
- python3-xcbgen
|
||||
- xcb-proto
|
||||
- &optional_deps
|
||||
- libxcb-xkb-dev
|
||||
- libxcb-cursor-dev
|
||||
- libxcb-xrm-dev
|
||||
- libxcb1-dev
|
||||
- xutils-dev
|
||||
- i3-wm
|
||||
- libjsoncpp-dev
|
||||
- libasound2-dev
|
||||
- libpulse-dev
|
||||
- libcairo2-dev
|
||||
- libiw-dev
|
||||
- libmpdclient-dev
|
||||
|
||||
script: source ${TRAVIS_BUILD_DIR}/common/travis/build.sh
|
||||
|
||||
matrix:
|
||||
include:
|
||||
# Only builds the documentation
|
||||
- language: generic
|
||||
# Doesn't actually do anything, just used for the indicator on travis
|
||||
compiler: Sphinx
|
||||
addons: {apt: {packages: [python3-sphinx]}}
|
||||
before_script:
|
||||
- mkdir -p doc/build
|
||||
- cd doc/build
|
||||
- cmake ..
|
||||
script: make doc
|
||||
# Disable unnecessary commands
|
||||
cache:
|
||||
|
||||
- compiler: clang
|
||||
env: BUILD_TYPE=Release
|
||||
addons: {apt: {packages: [*base_deps, *optional_deps]}}
|
||||
|
||||
- compiler: gcc
|
||||
env: BUILD_TYPE=Coverage POLYBAR_BUILD_TYPE=tests BUILD_TESTS=ON
|
||||
addons: {apt: {packages: [*base_deps, *optional_deps]}}
|
||||
script: make check
|
||||
after_success:
|
||||
- cd ${TRAVIS_BUILD_DIR}
|
||||
- bash <(curl -s https://codecov.io/bash) -F unittests -a "-ap" -Z || echo "Codecov did not collect coverage reports"
|
||||
|
||||
- compiler: gcc
|
||||
env: BUILD_TYPE=Release
|
||||
addons: {apt: {packages: [*base_deps, *optional_deps]}}
|
||||
|
||||
# Minimal build, contains no optional dependencies. This makes sure that
|
||||
# we properly remove files from compilation that depend on libraries that
|
||||
# are not installed
|
||||
- compiler: gcc
|
||||
env: BUILD_TYPE=Release POLYBAR_BUILD_TYPE=minimal
|
||||
addons: {apt: {packages: [*base_deps]}}
|
||||
|
||||
cache:
|
||||
ccache: true
|
||||
apt: true
|
||||
|
||||
before_script:
|
||||
- source ${TRAVIS_BUILD_DIR}/common/travis/summary.sh
|
||||
- source ${TRAVIS_BUILD_DIR}/common/travis/configure.sh
|
||||
|
||||
# Only fetch the newest 5 commits instead of 50
|
||||
git:
|
||||
depth: 5
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
irc:
|
||||
channels:
|
||||
- "irc.freenode.org#polybar"
|
||||
template:
|
||||
- " %{repository_slug}(%{branch})#%{build_number} | \"%{commit_subject}\" by %{author} | Commit #%{commit} %{result}: %{build_url}"
|
||||
use_notice: true
|
||||
on_success: never
|
||||
on_failure: change
|
||||
on_start: never
|
||||
webhooks:
|
||||
urls:
|
||||
# For the https://gitter.im/polybar/polybar gitter room
|
||||
- https://webhooks.gitter.im/e/10bdbe25961312646ace
|
||||
on_success: never
|
||||
on_failure: always
|
||||
on_start: never
|
@ -8,8 +8,8 @@ A fast and easy-to-use tool for creating status bars.
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/polybar/polybar/releases"><img src="https://img.shields.io/github/release/polybar/polybar.svg"></a>
|
||||
<a href="https://github.com/polybar/polybar/actions?query=workflow%3ACI"><img src="https://github.com/polybar/polybar/workflows/CI/badge.svg"></a>
|
||||
<a href="https://github.com/polybar/polybar/actions?query=workflow%3A%22Release+Workflow%22"><img src="https://github.com/polybar/polybar/workflows/Release%20Workflow/badge.svg?branch=master"></a>
|
||||
<a href="https://travis-ci.com/polybar/polybar"><img src="https://travis-ci.com/polybar/polybar.svg?branch=master"></a>
|
||||
<a href="https://polybar.readthedocs.io"><img src="https://readthedocs.org/projects/polybar/badge/?version=latest"></a>
|
||||
<a href="https://gitter.im/polybar/polybar"><img src="https://badges.gitter.im/polybar/polybar.svg"></a>
|
||||
<a href="https://codecov.io/gh/polybar/polybar/branch/master"><img src="https://codecov.io/gh/polybar/polybar/branch/master/graph/badge.svg"></a>
|
||||
|
46
common/ci/configure.sh
Executable file
46
common/ci/configure.sh
Executable file
@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -eo pipefail
|
||||
|
||||
if [ -d "$BUILD_DIR" ]; then
|
||||
rm -Rf "$BUILD_DIR"
|
||||
fi
|
||||
|
||||
mkdir -p "${BUILD_DIR}"
|
||||
cd "${BUILD_DIR}"
|
||||
|
||||
if [ "$POLYBAR_BUILD_TYPE" != "minimal" ]; then
|
||||
ENABLE_PULSEAUDIO=ON
|
||||
ENABLE_NETWORK=ON
|
||||
ENABLE_MPD=ON
|
||||
ENABLE_CURL=ON
|
||||
ENABLE_ALSA=ON
|
||||
ENABLE_I3=ON
|
||||
WITH_XRM=ON
|
||||
WITH_XKB=ON
|
||||
WITH_XRANDR_MONITORS=ON
|
||||
WITH_XCURSOR=ON
|
||||
fi
|
||||
|
||||
if [ "$POLYBAR_BUILD_TYPE" = "tests" ]; then
|
||||
BUILD_TESTS=ON
|
||||
fi
|
||||
|
||||
cmake \
|
||||
-DCMAKE_CXX_COMPILER="${CXX}" \
|
||||
-DCMAKE_CXX_FLAGS="${CXXFLAGS} -Werror" \
|
||||
-DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
|
||||
-DBUILD_TESTS:BOOL="${BUILD_TESTS:-OFF}" \
|
||||
-DBUILD_DOC:BOOL="${BUILD_DOC:-OFF}" \
|
||||
-DWITH_XRANDR=ON \
|
||||
-DENABLE_PULSEAUDIO="${ENABLE_PULSEAUDIO:-OFF}" \
|
||||
-DENABLE_NETWORK="${ENABLE_NETWORK:-OFF}" \
|
||||
-DENABLE_MPD="${ENABLE_MPD:-OFF}" \
|
||||
-DENABLE_CURL="${ENABLE_CURL:-OFF}" \
|
||||
-DENABLE_ALSA="${ENABLE_ALSA:-OFF}" \
|
||||
-DENABLE_I3="${ENABLE_I3:-OFF}" \
|
||||
-DWITH_XRM="${WITH_XRM:-OFF}" \
|
||||
-DWITH_XKB="${WITH_XKB:-OFF}" \
|
||||
-DWITH_XRANDR_MONITORS="${WITH_XRANDR_MONITORS:-OFF}" \
|
||||
-DWITH_XCURSOR="${WITH_XCURSOR:-OFF}" \
|
||||
..
|
19
common/ci/summary.sh
Executable file
19
common/ci/summary.sh
Executable file
@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -eo pipefail
|
||||
|
||||
set -x
|
||||
|
||||
"${CXX}" --version
|
||||
cmake --version
|
||||
|
||||
set +x
|
||||
|
||||
echo "PATH=${PATH}"
|
||||
echo "CXX=${CXX}"
|
||||
echo "CXXFLAGS=${CXXFLAGS}"
|
||||
echo "LDFLAGS=${LDFLAGS}"
|
||||
echo "LD_LIBRARY_PATH=${LD_LIBRARY_PATH}"
|
||||
echo "MAKEFLAGS=${MAKEFLAGS}"
|
||||
echo "POLYBAR_BUILD_TYPE=${POLYBAR_BUILD_TYPE}"
|
||||
echo "CMAKE_BUILD_TYPE=${BUILD_TYPE}"
|
@ -1,3 +0,0 @@
|
||||
#!/bin/bash
|
||||
cd "${TRAVIS_BUILD_DIR}/build" || false
|
||||
make || exit $?
|
@ -1,32 +0,0 @@
|
||||
#!/bin/bash
|
||||
mkdir -p "${TRAVIS_BUILD_DIR}/build"
|
||||
cd "${TRAVIS_BUILD_DIR}/build" || false
|
||||
|
||||
FLAGS=""
|
||||
|
||||
# Disable all extra modules and X extensions for minimal builds
|
||||
# Most of these should already be turned off because their libraries are not
|
||||
# installed, but some may not be
|
||||
if [ "$POLYBAR_BUILD_TYPE" == "minimal" ]; then
|
||||
FLAGS=(
|
||||
"-DENABLE_PULSEAUDIO=OFF"
|
||||
"-DENABLE_NETWORK=OFF"
|
||||
"-DENABLE_MPD=OFF"
|
||||
"-DENABLE_CURL=OFF"
|
||||
"-DENABLE_ALSA=OFF"
|
||||
"-DENABLE_I3=OFF"
|
||||
"-DWITH_XRM=OFF"
|
||||
"-DWITH_XKB=OFF"
|
||||
"-DWITH_XRANDR_MONITORS=OFF"
|
||||
"-DWITH_XCURSOR=OFF"
|
||||
"-DWITH_XRANDR=ON"
|
||||
)
|
||||
fi
|
||||
|
||||
cmake \
|
||||
-DCMAKE_CXX_COMPILER="${CXX}" \
|
||||
-DCMAKE_CXX_FLAGS="${CXXFLAGS} -Werror" \
|
||||
-DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
|
||||
-DBUILD_TESTS:BOOL="${BUILD_TESTS:-OFF}" \
|
||||
-DBUILD_DOC:BOOL="${BUILD_DOC:-OFF}" \
|
||||
"${FLAGS[@]}" ..
|
@ -1,13 +0,0 @@
|
||||
#!/bin/bash
|
||||
echo "${CXX} --version"
|
||||
eval "${CXX} --version"
|
||||
|
||||
echo "cmake --version"
|
||||
cmake --version
|
||||
|
||||
echo "PATH=${PATH}"
|
||||
echo "CXX=${CXX}"
|
||||
echo "CXXFLAGS=${CXXFLAGS}"
|
||||
echo "LDFLAGS=${LDFLAGS}"
|
||||
echo "LD_LIBRARY_PATH=${LD_LIBRARY_PATH}"
|
||||
echo "JOBS=${JOBS}"
|
@ -63,7 +63,7 @@ class pulseaudio {
|
||||
pa_cvolume cv;
|
||||
bool muted{false};
|
||||
// default sink name
|
||||
static constexpr auto DEFAULT_SINK{"@DEFAULT_SINK@"};
|
||||
static constexpr auto DEFAULT_SINK = "@DEFAULT_SINK@";
|
||||
|
||||
pa_context* m_context{nullptr};
|
||||
pa_threaded_mainloop* m_mainloop{nullptr};
|
||||
|
@ -100,7 +100,8 @@ class logger {
|
||||
/**
|
||||
* Convert string
|
||||
*/
|
||||
const char* convert(string arg) const; // NOLINT
|
||||
const char* convert(string& arg) const;
|
||||
const char* convert(const string& arg) const;
|
||||
|
||||
/**
|
||||
* Convert thread id
|
||||
|
@ -48,7 +48,7 @@ namespace modules {
|
||||
|
||||
template <typename Impl>
|
||||
string module<Impl>::type() const {
|
||||
return string(CONST_MOD(Impl).TYPE);
|
||||
return string(module<Impl>::TYPE);
|
||||
}
|
||||
|
||||
template <typename Impl>
|
||||
|
@ -17,6 +17,20 @@ namespace modules {
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Loads and sets the interval for this module.
|
||||
*
|
||||
* Will throw an exception if a non-positive (<= 0) number is given.
|
||||
*/
|
||||
void set_interval(interval_t def) {
|
||||
m_interval = this->m_conf.template get<decltype(m_interval)>(this->name(), "interval", def);
|
||||
|
||||
if (m_interval <= 0s) {
|
||||
throw module_error(
|
||||
this->name() + ": 'interval' must be larger than 0 (got '" + to_string(m_interval.count()) + "s')");
|
||||
}
|
||||
}
|
||||
|
||||
void runner() {
|
||||
this->m_log.trace("%s: Thread id = %i", this->name(), concurrency_util::thread_id(this_thread::get_id()));
|
||||
|
||||
|
@ -110,8 +110,6 @@ namespace modules {
|
||||
// The following mutex is here to protect the data of this modules.
|
||||
// This can't be achieved using m_buildlock since we "CRTP override" get_output().
|
||||
mutable mutex m_workspace_mutex;
|
||||
|
||||
event_timer m_timer{0L, 25L};
|
||||
};
|
||||
} // namespace modules
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
POLYBAR_NS
|
||||
@ -10,11 +12,14 @@ namespace process_util {
|
||||
|
||||
void redirect_stdio_to_dev_null();
|
||||
|
||||
pid_t fork_detached(std::function<void()> const& lambda);
|
||||
pid_t spawn_async(std::function<void()> const& lambda);
|
||||
void fork_detached(std::function<void()> const& lambda);
|
||||
|
||||
void exec(char* cmd, char** args);
|
||||
void exec_sh(const char* cmd);
|
||||
|
||||
int wait(pid_t pid);
|
||||
|
||||
pid_t wait_for_completion(pid_t process_id, int* status_addr = nullptr, int waitflags = 0);
|
||||
pid_t wait_for_completion(int* status_addr, int waitflags = 0);
|
||||
pid_t wait_for_completion_nohang(pid_t process_id, int* status);
|
||||
|
@ -72,37 +72,61 @@ void config::warn_deprecated(const string& section, const string& key, string re
|
||||
* Look for sections set up to inherit from a base section
|
||||
* and copy the missing parameters
|
||||
*
|
||||
* Multiple sections can be specified, separated by a space.
|
||||
*
|
||||
* [sub/section]
|
||||
* inherit = base/section
|
||||
* inherit = section1 section2
|
||||
*/
|
||||
void config::copy_inherited() {
|
||||
for (auto&& section : m_sections) {
|
||||
std::vector<string> inherit_sections;
|
||||
|
||||
// Collect all sections to be inherited
|
||||
for (auto&& param : section.second) {
|
||||
if (param.first == "inherit") {
|
||||
// Get name of base section
|
||||
string key_name = param.first;
|
||||
if (key_name == "inherit") {
|
||||
auto inherit = param.second;
|
||||
if ((inherit = dereference<string>(section.first, param.first, inherit, inherit)).empty()) {
|
||||
throw value_error("Invalid section \"\" defined for \"" + section.first + ".inherit\"");
|
||||
inherit = dereference<string>(section.first, key_name, inherit, inherit);
|
||||
|
||||
std::vector<string> sections = string_util::split(std::move(inherit), ' ');
|
||||
|
||||
inherit_sections.insert(inherit_sections.end(), sections.begin(), sections.end());
|
||||
|
||||
} else if (key_name.find("inherit") == 0) {
|
||||
// Legacy support for keys that just start with 'inherit'
|
||||
m_log.warn(
|
||||
"\"%s.%s\": Using anything other than 'inherit' for inheriting section keys is deprecated. "
|
||||
"The 'inherit' key supports multiple section names separated by a space.",
|
||||
section.first, key_name);
|
||||
|
||||
auto inherit = param.second;
|
||||
inherit = dereference<string>(section.first, key_name, inherit, inherit);
|
||||
if (inherit.empty() || m_sections.find(inherit) == m_sections.end()) {
|
||||
throw value_error(
|
||||
"Invalid section \"" + inherit + "\" defined for \"" + section.first + "." + key_name + "\"");
|
||||
}
|
||||
|
||||
// Find and validate base section
|
||||
auto base_section = m_sections.find(inherit);
|
||||
inherit_sections.push_back(std::move(inherit));
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& base_name : inherit_sections) {
|
||||
const auto base_section = m_sections.find(base_name);
|
||||
if (base_section == m_sections.end()) {
|
||||
throw value_error("Invalid section \"" + inherit + "\" defined for \"" + section.first + ".inherit\"");
|
||||
throw value_error("Invalid section \"" + base_name + "\" defined for \"" + section.first + ".inherit\"");
|
||||
}
|
||||
|
||||
m_log.trace("config: Copying missing params (sub=\"%s\", base=\"%s\")", section.first, inherit);
|
||||
m_log.trace("config: Inheriting keys from \"%s\" in \"%s\"", base_name, section.first);
|
||||
|
||||
/*
|
||||
* Iterate the base and copy the parameters that haven't been defined
|
||||
* for the sub-section
|
||||
* yet.
|
||||
*/
|
||||
for (auto&& base_param : base_section->second) {
|
||||
section.second.emplace(base_param.first, base_param.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "components/logger.hpp"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include "components/logger.hpp"
|
||||
#include "errors.hpp"
|
||||
#include "settings.hpp"
|
||||
#include "utils/concurrency.hpp"
|
||||
@ -12,7 +13,11 @@ POLYBAR_NS
|
||||
/**
|
||||
* Convert string
|
||||
*/
|
||||
const char* logger::convert(string arg) const { // NOLINT
|
||||
const char* logger::convert(string& arg) const {
|
||||
return arg.c_str();
|
||||
}
|
||||
|
||||
const char* logger::convert(const string& arg) const {
|
||||
return arg.c_str();
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@ namespace modules {
|
||||
|
||||
counter_module::counter_module(const bar_settings& bar, string name_)
|
||||
: timer_module<counter_module>(bar, move(name_)) {
|
||||
m_interval = m_conf.get(name(), "interval", m_interval);
|
||||
set_interval(1s);
|
||||
m_formatter->add(DEFAULT_FORMAT, TAG_COUNTER, {TAG_COUNTER});
|
||||
}
|
||||
|
||||
@ -25,6 +25,6 @@ namespace modules {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} // namespace modules
|
||||
|
||||
POLYBAR_NS_END
|
||||
|
@ -16,7 +16,7 @@ namespace modules {
|
||||
template class module<cpu_module>;
|
||||
|
||||
cpu_module::cpu_module(const bar_settings& bar, string name_) : timer_module<cpu_module>(bar, move(name_)) {
|
||||
m_interval = m_conf.get<decltype(m_interval)>(name(), "interval", 1s);
|
||||
set_interval(1s);
|
||||
m_totalwarn = m_conf.get(name(), "warn-percentage", m_totalwarn);
|
||||
m_ramp_padding = m_conf.get<decltype(m_ramp_padding)>(name(), "ramp-coreload-spacing", 1);
|
||||
|
||||
|
@ -22,7 +22,7 @@ namespace modules {
|
||||
throw module_error("No date or time format specified");
|
||||
}
|
||||
|
||||
m_interval = m_conf.get<decltype(m_interval)>(name(), "interval", 1s);
|
||||
set_interval(1s);
|
||||
|
||||
m_formatter->add(DEFAULT_FORMAT, TAG_LABEL, {TAG_LABEL, TAG_DATE});
|
||||
|
||||
|
@ -31,7 +31,7 @@ namespace modules {
|
||||
m_perc_used_warn = m_conf.get(name(), "warn-percentage", 90);
|
||||
m_fixed = m_conf.get(name(), "fixed-values", m_fixed);
|
||||
m_spacing = m_conf.get(name(), "spacing", m_spacing);
|
||||
m_interval = m_conf.get<decltype(m_interval)>(name(), "interval", 30s);
|
||||
set_interval(30s);
|
||||
|
||||
// Add formats and elements
|
||||
m_formatter->add(
|
||||
|
@ -23,7 +23,7 @@ namespace modules {
|
||||
m_api_url += '/';
|
||||
}
|
||||
|
||||
m_interval = m_conf.get<decltype(m_interval)>(name(), "interval", 60s);
|
||||
set_interval(60s);
|
||||
m_empty_notifications = m_conf.get(name(), "empty-notifications", m_empty_notifications);
|
||||
|
||||
m_formatter->add(DEFAULT_FORMAT, TAG_LABEL, {TAG_LABEL});
|
||||
|
@ -16,7 +16,7 @@ namespace modules {
|
||||
template class module<memory_module>;
|
||||
|
||||
memory_module::memory_module(const bar_settings& bar, string name_) : timer_module<memory_module>(bar, move(name_)) {
|
||||
m_interval = m_conf.get<decltype(m_interval)>(name(), "interval", 1s);
|
||||
set_interval(1s);
|
||||
m_perc_memused_warn = m_conf.get(name(), "warn-percentage", 90);
|
||||
|
||||
m_formatter->add(DEFAULT_FORMAT, TAG_LABEL, {TAG_LABEL, TAG_BAR_USED, TAG_BAR_FREE, TAG_RAMP_USED, TAG_RAMP_FREE,
|
||||
|
@ -140,7 +140,7 @@ namespace modules {
|
||||
m_log.info("%s: Opening menu level '%i'", name(), static_cast<int>(m_level));
|
||||
|
||||
if (static_cast<size_t>(m_level) >= m_levels.size()) {
|
||||
m_log.warn("%s: Cannot open unexisting menu level '%i'", name(), level);
|
||||
m_log.warn("%s: Cannot open unexisting menu level '%s'", name(), level);
|
||||
m_level = -1;
|
||||
}
|
||||
} else if (action == EVENT_CLOSE) {
|
||||
|
@ -19,7 +19,7 @@ namespace modules {
|
||||
m_ping_nth_update = m_conf.get(name(), "ping-interval", m_ping_nth_update);
|
||||
m_udspeed_minwidth = m_conf.get(name(), "udspeed-minwidth", m_udspeed_minwidth);
|
||||
m_accumulate = m_conf.get(name(), "accumulate-stats", m_accumulate);
|
||||
m_interval = m_conf.get<decltype(m_interval)>(name(), "interval", 1s);
|
||||
set_interval(1s);
|
||||
m_unknown_up = m_conf.get<bool>(name(), "unknown-as-up", false);
|
||||
m_udspeed_unit = m_conf.get<string>(name(), "speed-unit", m_udspeed_unit);
|
||||
|
||||
|
@ -19,7 +19,7 @@ namespace modules {
|
||||
m_path = m_conf.get(name(), "hwmon-path", ""s);
|
||||
m_tempbase = m_conf.get(name(), "base-temperature", 0);
|
||||
m_tempwarn = m_conf.get(name(), "warn-temperature", 80);
|
||||
m_interval = m_conf.get<decltype(m_interval)>(name(), "interval", 1s);
|
||||
set_interval(1s);
|
||||
m_units = m_conf.get(name(), "units", m_units);
|
||||
|
||||
if (m_path.empty()) {
|
||||
|
@ -126,10 +126,8 @@ namespace modules {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_timer.allow(evt->time)) {
|
||||
broadcast();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rebuild the list of managed clients
|
||||
|
@ -33,7 +33,7 @@ command<output_policy::IGNORED>::~command() {
|
||||
* Execute the command
|
||||
*/
|
||||
int command<output_policy::IGNORED>::exec(bool wait_for_completion) {
|
||||
m_forkpid = process_util::fork_detached([m_cmd = m_cmd] { process_util::exec_sh(m_cmd.c_str()); });
|
||||
m_forkpid = process_util::spawn_async([m_cmd = m_cmd] { process_util::exec_sh(m_cmd.c_str()); });
|
||||
if (wait_for_completion) {
|
||||
auto status = wait();
|
||||
m_forkpid = -1;
|
||||
|
@ -45,15 +45,11 @@ namespace process_util {
|
||||
}
|
||||
|
||||
/**
|
||||
* Forks a child process and completely detaches it.
|
||||
* Forks a child process and executes the given lambda function in it.
|
||||
*
|
||||
* In the child process, the given lambda function is executed.
|
||||
*
|
||||
* Use this if you want to run a command and just forget about it.
|
||||
*
|
||||
* \returns The PID of the child process
|
||||
* Processes spawned this way need to be waited on by the caller.
|
||||
*/
|
||||
pid_t fork_detached(std::function<void()> const& lambda) {
|
||||
pid_t spawn_async(std::function<void()> const& lambda) {
|
||||
pid_t pid = fork();
|
||||
switch (pid) {
|
||||
case -1:
|
||||
@ -71,6 +67,50 @@ namespace process_util {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Forks a child process and completely detaches it.
|
||||
*
|
||||
* In the child process, the given lambda function is executed.
|
||||
* We fork twice so that the first forked process can exit and it's child is
|
||||
* reparented to the init process.
|
||||
*
|
||||
* Ref: https://web.archive.org/web/20120914180018/http://www.steve.org.uk/Reference/Unix/faq_2.html#SEC16
|
||||
*
|
||||
* Use this if you want to run a command and just forget about it.
|
||||
*
|
||||
* \returns The PID of the child process
|
||||
*/
|
||||
void fork_detached(std::function<void()> const& lambda) {
|
||||
pid_t pid = fork();
|
||||
switch (pid) {
|
||||
case -1:
|
||||
throw runtime_error("fork_detached: Unable to fork: " + string(strerror(errno)));
|
||||
case 0:
|
||||
// Child
|
||||
setsid();
|
||||
|
||||
pid = fork();
|
||||
switch (pid) {
|
||||
case -1:
|
||||
throw runtime_error("fork_detached: Unable to fork: " + string(strerror(errno)));
|
||||
case 0:
|
||||
// Child
|
||||
umask(0);
|
||||
redirect_stdio_to_dev_null();
|
||||
lambda();
|
||||
_Exit(0);
|
||||
}
|
||||
|
||||
_Exit(0);
|
||||
default:
|
||||
/*
|
||||
* The first fork immediately exits and we have to collect its exit
|
||||
* status
|
||||
*/
|
||||
wait(pid);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute command
|
||||
*/
|
||||
@ -92,6 +132,15 @@ namespace process_util {
|
||||
}
|
||||
}
|
||||
|
||||
int wait(pid_t pid) {
|
||||
int forkstatus;
|
||||
do {
|
||||
process_util::wait_for_completion(pid, &forkstatus, WCONTINUED | WUNTRACED);
|
||||
} while (!WIFEXITED(forkstatus) && !WIFSIGNALED(forkstatus));
|
||||
|
||||
return WEXITSTATUS(forkstatus);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for child process
|
||||
*/
|
||||
|
@ -12,8 +12,8 @@
|
||||
using namespace polybar;
|
||||
using namespace process_util;
|
||||
|
||||
TEST(ForkDetached, is_detached) {
|
||||
pid_t pid = fork_detached([] { exec_sh("sleep 0.1"); });
|
||||
TEST(SpawnAsync, is_async) {
|
||||
pid_t pid = spawn_async([] { exec_sh("sleep 0.1"); });
|
||||
int status;
|
||||
|
||||
pid_t res = process_util::wait_for_completion_nohang(pid, &status);
|
||||
@ -23,8 +23,8 @@ TEST(ForkDetached, is_detached) {
|
||||
EXPECT_FALSE(WIFEXITED(status));
|
||||
}
|
||||
|
||||
TEST(ForkDetached, exit_code) {
|
||||
pid_t pid = fork_detached([] { exec_sh("exit 42"); });
|
||||
TEST(SpawnAsync, exit_code) {
|
||||
pid_t pid = spawn_async([] { exec_sh("exit 42"); });
|
||||
int status = 0;
|
||||
pid_t res = waitpid(pid, &status, 0);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Polybar version information
|
||||
# Update this on every release
|
||||
# This is used to create the version string if a git repo is not available
|
||||
3.5.0
|
||||
3.5.1
|
||||
|
Loading…
Reference in New Issue
Block a user