├── doc ├── .gitignore ├── index.rst ├── README.md ├── man │ └── polybar.1.rst └── CMakeLists.txt ├── banner.png ├── src ├── events │ ├── signal_receiver.cpp │ └── signal_emitter.cpp ├── utils │ ├── factory.cpp │ ├── env.cpp │ ├── concurrency.cpp │ ├── throttle.cpp │ ├── http.cpp │ ├── i3.cpp │ ├── io.cpp │ ├── process.cpp │ └── inotify.cpp ├── x11 │ ├── registry.cpp │ ├── xresources.cpp │ ├── extensions │ │ └── composite.cpp │ ├── cursor.cpp │ ├── icccm.cpp │ └── window.cpp ├── modules │ ├── counter.cpp │ ├── text.cpp │ ├── systray.cpp │ ├── backlight.cpp │ └── date.cpp ├── drawtypes │ ├── iconset.cpp │ ├── ramp.cpp │ └── animation.cpp ├── components │ ├── ipc.cpp │ └── logger.cpp └── settings.cpp.cmake ├── tests ├── common │ └── test.hpp ├── unit_tests │ ├── utils │ │ ├── file.cpp │ │ ├── scope.cpp │ │ └── memory.cpp │ └── components │ │ ├── parser.cpp │ │ └── bar.cpp ├── CMakeLists.txt.in └── CMakeLists.txt ├── common ├── travis │ ├── build.sh │ ├── summary.sh │ └── configure.sh ├── clang-format.sh └── clang-tidy.sh ├── .gitignore ├── version.txt ├── contrib ├── bash │ ├── CMakeLists.txt │ └── polybar ├── zsh │ ├── CMakeLists.txt │ ├── _polybar_msg │ └── _polybar ├── polybar-git.aur │ ├── polybar.install │ └── PKGBUILD ├── vim │ ├── ftplugin │ │ ├── cpp.vim │ │ └── dosini.vim │ └── autoload │ │ └── ft │ │ └── cpphpp.vim ├── polybar.aur │ ├── polybar.install │ └── PKGBUILD └── rpm │ └── polybar.spec ├── .github └── ISSUE_TEMPLATE │ ├── config.yml │ ├── build.md │ ├── feature_request.md │ └── bug_report.md ├── .gitmodules ├── include ├── utils │ ├── functional.hpp │ ├── env.hpp │ ├── time.hpp │ ├── http.hpp │ ├── process.hpp │ ├── io.hpp │ ├── mixins.hpp │ ├── bspwm.hpp │ ├── cache.hpp │ ├── i3.hpp │ ├── inotify.hpp │ ├── factory.hpp │ ├── scope.hpp │ ├── memory.hpp │ ├── socket.hpp │ ├── concurrency.hpp │ ├── command.hpp │ ├── throttle.hpp │ └── file.hpp ├── cairo │ ├── fwd.hpp │ ├── types.hpp │ ├── utils.hpp │ └── surface.hpp ├── x11 │ ├── extensions │ │ ├── all.hpp │ │ ├── fwd.hpp │ │ ├── composite.hpp │ │ └── randr.hpp │ ├── registry.hpp │ ├── icccm.hpp │ ├── window.hpp │ ├── cursor.hpp │ ├── tray_client.hpp │ ├── xembed.hpp │ ├── ewmh.hpp │ ├── atoms.hpp │ └── xresources.hpp ├── modules │ ├── meta │ │ ├── input_handler.hpp │ │ ├── static_module.hpp │ │ ├── event_handler.hpp │ │ ├── timer_module.hpp │ │ ├── event_module.hpp │ │ └── inotify_module.hpp │ ├── text.hpp │ ├── counter.hpp │ ├── github.hpp │ ├── systray.hpp │ ├── backlight.hpp │ ├── ipc.hpp │ ├── date.hpp │ ├── script.hpp │ ├── menu.hpp │ ├── temperature.hpp │ ├── cpu.hpp │ ├── xwindow.hpp │ ├── memory.hpp │ ├── pulseaudio.hpp │ ├── network.hpp │ ├── xbacklight.hpp │ ├── fs.hpp │ ├── alsa.hpp │ ├── xkeyboard.hpp │ ├── bspwm.hpp │ ├── unsupported.hpp │ └── i3.hpp ├── drawtypes │ ├── iconset.hpp │ ├── ramp.hpp │ ├── animation.hpp │ ├── progressbar.hpp │ └── label.hpp ├── CMakeLists.txt ├── common.hpp ├── adapters │ ├── alsa │ │ ├── control.hpp │ │ ├── mixer.hpp │ │ └── generic.hpp │ └── pulseaudio.hpp ├── errors.hpp ├── components │ ├── ipc.hpp │ ├── screen.hpp │ ├── parser.hpp │ ├── taskqueue.hpp │ ├── builder.hpp │ └── command_line.hpp ├── events │ ├── types.hpp │ ├── signal_receiver.hpp │ └── signal_fwd.hpp ├── debug.hpp └── settings.hpp.cmake ├── .editorconfig ├── cmake ├── templates │ ├── userconfig.cmake.in │ └── uninstall.cmake.in ├── modules │ └── FindLibiw.cmake ├── 03-libs.cmake ├── 05-summary.cmake └── 04-targets.cmake ├── .clang-format ├── .codecov.yml ├── lib └── CMakeLists.txt ├── SUPPORT.md ├── LICENSE ├── .clang-tidy └── .valgrind-suppressions /doc/.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | -------------------------------------------------------------------------------- /banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyme5/polybar/master/banner.png -------------------------------------------------------------------------------- /src/events/signal_receiver.cpp: -------------------------------------------------------------------------------- 1 | #include "events/signal_receiver.hpp" 2 | -------------------------------------------------------------------------------- /tests/common/test.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "gtest/gtest.h" 4 | -------------------------------------------------------------------------------- /common/travis/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cd "${TRAVIS_BUILD_DIR}/build" || false 3 | make || exit $? 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /tags 3 | /compile_commands.json 4 | /config 5 | *.bak 6 | *.pyc 7 | *.swp 8 | *.tmp 9 | .tags 10 | -------------------------------------------------------------------------------- /version.txt: -------------------------------------------------------------------------------- 1 | # Polybar version information 2 | # Update this on every release 3 | # This is used to create the version string if a git repo is not available 4 | 3.4.0 5 | -------------------------------------------------------------------------------- /contrib/bash/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Bash completion template 3 | # 4 | install(FILES polybar 5 | DESTINATION ${CMAKE_INSTALL_DATADIR}/bash-completion/completions 6 | COMPONENT tools) 7 | -------------------------------------------------------------------------------- /contrib/zsh/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Zsh completion template 3 | # 4 | install(FILES _polybar _polybar_msg 5 | DESTINATION ${CMAKE_INSTALL_DATADIR}/zsh/site-functions 6 | COMPONENT tools) 7 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true 2 | contact_links: 3 | - name: Polybar subreddit 4 | url: https://www.reddit.com/r/polybar 5 | about: Please ask and answer questions here. 6 | -------------------------------------------------------------------------------- /src/utils/factory.cpp: -------------------------------------------------------------------------------- 1 | #include "utils/factory.hpp" 2 | 3 | POLYBAR_NS 4 | 5 | factory_util::detail::null_deleter factory_util::null_deleter{}; 6 | factory_util::detail::fd_deleter factory_util::fd_deleter{}; 7 | 8 | POLYBAR_NS_END 9 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lib/i3ipcpp"] 2 | path = lib/i3ipcpp 3 | url = https://github.com/polybar/i3ipcpp 4 | branch = master 5 | [submodule "lib/xpp"] 6 | path = lib/xpp 7 | url = https://github.com/polybar/xpp 8 | branch = master 9 | -------------------------------------------------------------------------------- /include/utils/functional.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "common.hpp" 6 | 7 | POLYBAR_NS 8 | 9 | template 10 | using callback = function; 11 | 12 | POLYBAR_NS_END 13 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | insert_final_newline = true 5 | trim_trailing_whitespace = true 6 | indent_style = space 7 | indent_size = 2 8 | charset = utf-8 9 | 10 | [Makefile] 11 | indent_style = tab 12 | indent_size = 2 13 | -------------------------------------------------------------------------------- /include/utils/env.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.hpp" 4 | 5 | POLYBAR_NS 6 | 7 | namespace env_util { 8 | bool has(const string& var); 9 | string get(const string& var, string fallback = ""); 10 | } 11 | 12 | POLYBAR_NS_END 13 | -------------------------------------------------------------------------------- /include/cairo/fwd.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.hpp" 4 | 5 | POLYBAR_NS 6 | 7 | namespace cairo { 8 | class context; 9 | class surface; 10 | class xcb_surface; 11 | class font; 12 | class font_fc; 13 | } 14 | 15 | POLYBAR_NS_END 16 | -------------------------------------------------------------------------------- /include/x11/extensions/all.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "settings.hpp" 4 | 5 | #if WITH_XRANDR 6 | #include "x11/extensions/randr.hpp" 7 | #endif 8 | #include "x11/extensions/composite.hpp" 9 | #if WITH_XKB 10 | #include "x11/extensions/xkb.hpp" 11 | #endif 12 | -------------------------------------------------------------------------------- /include/modules/meta/input_handler.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.hpp" 4 | 5 | POLYBAR_NS 6 | 7 | namespace modules { 8 | class input_handler { 9 | public: 10 | virtual ~input_handler() {} 11 | virtual bool input(string&& cmd) = 0; 12 | }; 13 | } 14 | 15 | POLYBAR_NS_END 16 | -------------------------------------------------------------------------------- /cmake/templates/userconfig.cmake.in: -------------------------------------------------------------------------------- 1 | set(USER_CONFIG_HOME "$ENV{XDG_CONFIG_HOME}") 2 | if(NOT USER_CONFIG_HOME) 3 | set(USER_CONFIG_HOME "$ENV{HOME}/.config") 4 | endif() 5 | set(USER_CONFIG_HOME "${USER_CONFIG_HOME}/polybar") 6 | 7 | file(INSTALL "@CMAKE_SOURCE_DIR@/config" 8 | DESTINATION "${USER_CONFIG_HOME}") 9 | -------------------------------------------------------------------------------- /src/x11/registry.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "x11/connection.hpp" 4 | #include "x11/extensions/all.hpp" 5 | #include "x11/registry.hpp" 6 | 7 | POLYBAR_NS 8 | 9 | registry::registry(connection& conn) : xpp::event::registry(conn) {} 10 | 11 | POLYBAR_NS_END 12 | -------------------------------------------------------------------------------- /common/travis/summary.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "${CXX} --version" 3 | eval "${CXX} --version" 4 | 5 | echo "cmake --version" 6 | cmake --version 7 | 8 | echo "PATH=${PATH}" 9 | echo "CXX=${CXX}" 10 | echo "CXXFLAGS=${CXXFLAGS}" 11 | echo "LDFLAGS=${LDFLAGS}" 12 | echo "LD_LIBRARY_PATH=${LD_LIBRARY_PATH}" 13 | echo "JOBS=${JOBS}" 14 | -------------------------------------------------------------------------------- /contrib/polybar-git.aur/polybar.install: -------------------------------------------------------------------------------- 1 | post_install() { 2 | cat << EOF 3 | 4 | Get started with the example configuration: 5 | 6 | $ install -Dm644 /usr/share/doc/polybar/config \$HOME/.config/polybar/config 7 | $ polybar example 8 | 9 | For more information, see https://github.com/polybar/polybar/wiki 10 | 11 | EOF 12 | } 13 | -------------------------------------------------------------------------------- /contrib/vim/ftplugin/cpp.vim: -------------------------------------------------------------------------------- 1 | " Swap between source/header 2 | nnoremap af :call ft#cpphpp#Swap('edit') 3 | nnoremap as :call ft#cpphpp#Swap('new') 4 | nnoremap av :call ft#cpphpp#Swap('vnew') 5 | 6 | " Code formatting using clang-format 7 | set formatprg=/usr/bin/clang-format 8 | nmap :ClangFormat 9 | -------------------------------------------------------------------------------- /src/x11/xresources.cpp: -------------------------------------------------------------------------------- 1 | #include "x11/xresources.hpp" 2 | 3 | POLYBAR_NS 4 | 5 | template <> 6 | string xresource_manager::convert(string&& value) const { 7 | return forward(value); 8 | } 9 | 10 | template <> 11 | double xresource_manager::convert(string&& value) const { 12 | return std::strtod(value.c_str(), nullptr); 13 | } 14 | 15 | POLYBAR_NS_END 16 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | Standard: Cpp11 4 | BasedOnStyle: Google 5 | ColumnLimit: 120 6 | NamespaceIndentation: All 7 | AlignAfterOpenBracket: DontAlign 8 | AllowShortFunctionsOnASingleLine: Empty 9 | AllowShortIfStatementsOnASingleLine: false 10 | BreakConstructorInitializersBeforeComma: true 11 | DerivePointerAlignment: false 12 | PointerAlignment: Left 13 | --- 14 | -------------------------------------------------------------------------------- /include/x11/extensions/fwd.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "settings.hpp" 4 | 5 | namespace xpp { 6 | #if WITH_XRANDR 7 | namespace randr { 8 | class extension; 9 | } 10 | #endif 11 | #if WITH_XCOMPOSITE 12 | namespace composite { 13 | class extension; 14 | } 15 | #endif 16 | #if WITH_XKB 17 | namespace xkb { 18 | class extension; 19 | } 20 | #endif 21 | } 22 | -------------------------------------------------------------------------------- /src/events/signal_emitter.cpp: -------------------------------------------------------------------------------- 1 | #include "events/signal_emitter.hpp" 2 | #include "utils/factory.hpp" 3 | 4 | POLYBAR_NS 5 | 6 | signal_receivers_t g_signal_receivers; 7 | 8 | /** 9 | * Create instance 10 | */ 11 | signal_emitter::make_type signal_emitter::make() { 12 | return static_cast(*factory_util::singleton()); 13 | } 14 | 15 | POLYBAR_NS_END 16 | -------------------------------------------------------------------------------- /include/modules/text.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "modules/meta/static_module.hpp" 4 | 5 | POLYBAR_NS 6 | 7 | namespace modules { 8 | class text_module : public static_module { 9 | public: 10 | explicit text_module(const bar_settings&, string); 11 | 12 | void update() {} 13 | string get_format() const; 14 | string get_output(); 15 | }; 16 | } 17 | 18 | POLYBAR_NS_END 19 | -------------------------------------------------------------------------------- /contrib/vim/ftplugin/dosini.vim: -------------------------------------------------------------------------------- 1 | " 2 | " Enables syntax folding for the configuration file. 3 | " Removes the need to clutter the file with fold markers. 4 | " 5 | " Put the file in $VIM/after/syntax/dosini.vim 6 | " 7 | syn region dosiniSection start="^\[" end="\(\n\+\[\)\@=" contains=dosiniLabel,dosiniHeader,dosiniComment keepend fold 8 | setlocal foldmethod=syntax 9 | 10 | " Uncomment to start with folds open 11 | "setlocal foldlevel=20 12 | -------------------------------------------------------------------------------- /tests/unit_tests/utils/file.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "common/test.hpp" 5 | #include "utils/command.hpp" 6 | #include "utils/file.hpp" 7 | 8 | using namespace polybar; 9 | 10 | TEST(File, expand) { 11 | auto cmd = command_util::make_command("echo $HOME"); 12 | cmd->exec(); 13 | cmd->tail([](string home) { 14 | EXPECT_EQ(home + "/test", file_util::expand("~/test")); 15 | }); 16 | } 17 | 18 | -------------------------------------------------------------------------------- /.codecov.yml: -------------------------------------------------------------------------------- 1 | coverage: 2 | status: 3 | project: 4 | default: 5 | # Coverage can drop by 0.1% without failing the status 6 | threshold: 0.1 7 | patch: 8 | default: 9 | # Patches don't need test coverage 10 | # TODO remove once we have proper testing infrastructure and documentation 11 | target: 0 12 | 13 | ignore: 14 | - "tests/*" 15 | - "lib/*" 16 | 17 | comment: 18 | require_changes: true 19 | -------------------------------------------------------------------------------- /include/x11/extensions/composite.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "settings.hpp" 4 | 5 | #if not WITH_XCOMPOSITE 6 | #error "X Composite extension is disabled..." 7 | #endif 8 | 9 | #include 10 | #include 11 | 12 | #include "common.hpp" 13 | 14 | POLYBAR_NS 15 | 16 | // fwd 17 | class connection; 18 | 19 | namespace composite_util { 20 | void query_extension(connection& conn); 21 | } 22 | 23 | POLYBAR_NS_END 24 | -------------------------------------------------------------------------------- /common/clang-format.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | main() { 4 | if [ $# -lt 1 ]; then 5 | echo "$0 DIR..." 1>&2 6 | exit 1 7 | fi 8 | 9 | # Search paths 10 | search="${*:-.}" 11 | 12 | echo "$0 in $search" 13 | 14 | # shellcheck disable=2086 15 | find $search -regex ".*.[c|h]pp" \ 16 | -exec printf "\\033[32;1m** \\033[0mFormatting %s\\n" {} \; \ 17 | -exec clang-format -style=file -i {} \; 18 | } 19 | 20 | main "$@" 21 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt.in: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.2) 2 | 3 | project(googletest-download NONE) 4 | 5 | include(ExternalProject) 6 | ExternalProject_Add(googletest 7 | GIT_REPOSITORY https://github.com/google/googletest.git 8 | GIT_TAG master 9 | SOURCE_DIR "${CMAKE_BINARY_DIR}/googletest-src" 10 | BINARY_DIR "${CMAKE_BINARY_DIR}/googletest-build" 11 | CONFIGURE_COMMAND "" 12 | BUILD_COMMAND "" 13 | INSTALL_COMMAND "" 14 | TEST_COMMAND "" 15 | ) 16 | -------------------------------------------------------------------------------- /tests/unit_tests/utils/scope.cpp: -------------------------------------------------------------------------------- 1 | #include "common/test.hpp" 2 | #include "utils/scope.hpp" 3 | 4 | using namespace polybar; 5 | 6 | TEST(Scope, onExit) { 7 | auto flag = false; 8 | { 9 | EXPECT_FALSE(flag); 10 | auto handler = scope_util::make_exit_handler<>([&] { flag = true; }); 11 | EXPECT_FALSE(flag); 12 | { 13 | auto handler = scope_util::make_exit_handler<>([&] { flag = true; }); 14 | } 15 | EXPECT_TRUE(flag); 16 | flag = false; 17 | } 18 | EXPECT_TRUE(flag); 19 | } 20 | -------------------------------------------------------------------------------- /include/modules/counter.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "modules/meta/timer_module.hpp" 4 | 5 | POLYBAR_NS 6 | 7 | namespace modules { 8 | class counter_module : public timer_module { 9 | public: 10 | explicit counter_module(const bar_settings&, string); 11 | 12 | bool update(); 13 | bool build(builder* builder, const string& tag) const; 14 | 15 | private: 16 | static constexpr auto TAG_COUNTER = ""; 17 | 18 | int m_counter{0}; 19 | }; 20 | } 21 | 22 | POLYBAR_NS_END 23 | -------------------------------------------------------------------------------- /include/x11/registry.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.hpp" 4 | #include "x11/extensions/fwd.hpp" 5 | 6 | // fwd 7 | namespace xpp { 8 | namespace event { 9 | template 10 | class registry; 11 | } 12 | } 13 | 14 | POLYBAR_NS 15 | 16 | class connection; 17 | 18 | class registry : public xpp::event::registry { 19 | public: 20 | using priority = unsigned int; 21 | 22 | explicit registry(connection& conn); 23 | }; 24 | 25 | POLYBAR_NS_END 26 | -------------------------------------------------------------------------------- /src/utils/env.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "utils/env.hpp" 7 | 8 | POLYBAR_NS 9 | 10 | namespace env_util { 11 | bool has(const string& var) { 12 | const char* env{std::getenv(var.c_str())}; 13 | return env != nullptr && std::strlen(env) > 0; 14 | } 15 | 16 | string get(const string& var, string fallback) { 17 | const char* value{std::getenv(var.c_str())}; 18 | return value != nullptr ? value : move(fallback); 19 | } 20 | } 21 | 22 | POLYBAR_NS_END 23 | -------------------------------------------------------------------------------- /include/utils/time.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "common.hpp" 6 | 7 | POLYBAR_NS 8 | 9 | namespace chrono = std::chrono; 10 | 11 | namespace time_util { 12 | using clock_t = chrono::high_resolution_clock; 13 | 14 | template 15 | auto measure(const T& expr) noexcept { 16 | auto start = clock_t::now(); 17 | expr(); 18 | auto finish = clock_t::now(); 19 | return chrono::duration_cast(finish - start).count(); 20 | } 21 | } 22 | 23 | POLYBAR_NS_END 24 | -------------------------------------------------------------------------------- /src/x11/extensions/composite.cpp: -------------------------------------------------------------------------------- 1 | #include "x11/extensions/composite.hpp" 2 | #include "errors.hpp" 3 | #include "x11/connection.hpp" 4 | 5 | POLYBAR_NS 6 | 7 | namespace composite_util { 8 | /** 9 | * Query for the XCOMPOSITE extension 10 | */ 11 | void query_extension(connection& conn) { 12 | conn.composite().query_version(XCB_COMPOSITE_MAJOR_VERSION, XCB_COMPOSITE_MINOR_VERSION); 13 | 14 | if (!conn.extension()->present) { 15 | throw application_error("Missing X extension: Composite"); 16 | } 17 | } 18 | } 19 | 20 | POLYBAR_NS_END 21 | -------------------------------------------------------------------------------- /common/clang-tidy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | main() { 4 | if [ $# -lt 2 ]; then 5 | echo "$0 build_path [-fix] DIR..." 1>&2 6 | exit 1 7 | fi 8 | 9 | args="-p $1"; shift 10 | 11 | if [ "$1" = "-fix" ]; then 12 | args="${args} -fix"; shift 13 | fi 14 | 15 | # Search paths 16 | search="${*:-.}" 17 | 18 | echo "$0 in $search" 19 | 20 | # shellcheck disable=2086 21 | find $search -iname "*.cpp" \ 22 | -exec printf "\\033[32;1m** \\033[0mProcessing %s\\n" {} \; \ 23 | -exec clang-tidy $args {} \; 24 | } 25 | 26 | main "$@" 27 | -------------------------------------------------------------------------------- /cmake/modules/FindLibiw.cmake: -------------------------------------------------------------------------------- 1 | # This module defines 2 | # LIBIW_FOUND - whether the libiw library was found 3 | # LIBIW_LIBRARIES - the libiw library 4 | # LIBIW_INCLUDE_DIR - the include path of the libiw library 5 | 6 | find_library(LIBIW_LIBRARY iw) 7 | 8 | if(LIBIW_LIBRARY) 9 | set(LIBIW_LIBRARIES ${LIBIW_LIBRARY}) 10 | endif(LIBIW_LIBRARY) 11 | 12 | find_path(LIBIW_INCLUDE_DIR NAMES iwlib.h) 13 | 14 | include(FindPackageHandleStandardArgs) 15 | find_package_handle_standard_args(Libiw DEFAULT_MSG LIBIW_LIBRARY LIBIW_INCLUDE_DIR) 16 | 17 | mark_as_advanced(LIBIW_INCLUDE_DIR LIBIW_LIBRARY) 18 | -------------------------------------------------------------------------------- /include/x11/icccm.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "common.hpp" 6 | 7 | POLYBAR_NS 8 | 9 | namespace icccm_util { 10 | string get_wm_name(xcb_connection_t* c, xcb_window_t w); 11 | string get_reply_string(xcb_icccm_get_text_property_reply_t* reply); 12 | 13 | void set_wm_name(xcb_connection_t* c, xcb_window_t w, const char* wmname, size_t l, const char* wmclass, size_t l2); 14 | void set_wm_protocols(xcb_connection_t* c, xcb_window_t w, vector flags); 15 | bool get_wm_urgency(xcb_connection_t* c, xcb_window_t w); 16 | } 17 | 18 | POLYBAR_NS_END 19 | -------------------------------------------------------------------------------- /contrib/vim/autoload/ft/cpphpp.vim: -------------------------------------------------------------------------------- 1 | " 2 | " Get the filename of the swap file 3 | " 4 | func! ft#cpphpp#GetFilename() 5 | let ext = expand('%:e') 6 | let root = expand('%:p:r') 7 | if (ext == 'cpp') 8 | return fnameescape(substitute(root, '\(src/.*/\)\?src/', '\1include/', '') . '.hpp') 9 | elseif (ext == 'hpp') 10 | return fnameescape(substitute(root, '\(include/.*/\)\?include/', '\1src/', '') . '.cpp') 11 | endif 12 | endfunc 13 | 14 | " 15 | " Swap between source/header using given cmd 16 | " 17 | func! ft#cpphpp#Swap(cmd) 18 | execute a:cmd . ' ' . ft#cpphpp#GetFilename() 19 | endfunc 20 | -------------------------------------------------------------------------------- /tests/unit_tests/utils/memory.cpp: -------------------------------------------------------------------------------- 1 | #include "common/test.hpp" 2 | #include "utils/memory.hpp" 3 | 4 | using namespace polybar; 5 | 6 | struct mytype { 7 | int x, y, z; 8 | }; 9 | 10 | TEST(Memory, makeMallocPtr) { 11 | auto ptr = memory_util::make_malloc_ptr(); 12 | EXPECT_EQ(sizeof(mytype*), sizeof(ptr.get())); 13 | ptr.reset(); 14 | EXPECT_EQ(nullptr, ptr.get()); 15 | } 16 | 17 | TEST(Memory, countof) { 18 | mytype A[3]{{}, {}, {}}; 19 | mytype B[8]{{}, {}, {}, {}, {}, {}, {}, {}}; 20 | 21 | EXPECT_EQ(memory_util::countof(A), size_t{3}); 22 | EXPECT_EQ(memory_util::countof(B), size_t{8}); 23 | } 24 | -------------------------------------------------------------------------------- /include/drawtypes/iconset.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "common.hpp" 6 | #include "drawtypes/label.hpp" 7 | #include "utils/mixins.hpp" 8 | 9 | POLYBAR_NS 10 | 11 | namespace drawtypes { 12 | class iconset : public non_copyable_mixin { 13 | public: 14 | void add(string id, label_t&& icon); 15 | bool has(const string& id); 16 | label_t get(const string& id, const string& fallback_id = "", bool fuzzy_match = false); 17 | operator bool(); 18 | 19 | protected: 20 | std::map m_icons; 21 | }; 22 | 23 | using iconset_t = shared_ptr; 24 | } 25 | 26 | POLYBAR_NS_END 27 | -------------------------------------------------------------------------------- /include/x11/window.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "common.hpp" 8 | 9 | POLYBAR_NS 10 | 11 | class connection; 12 | 13 | class window : public xpp::window { 14 | public: 15 | window(const window&) = default; 16 | using xpp::window::window; 17 | 18 | window reconfigure_geom(unsigned short int w, unsigned short int h, short int x = 0, short int y = 0); 19 | window reconfigure_pos(short int x, short int y); 20 | window reconfigure_struts(unsigned short int w, unsigned short int h, short int x, bool bottom = false); 21 | }; 22 | 23 | POLYBAR_NS_END 24 | -------------------------------------------------------------------------------- /include/modules/meta/static_module.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "modules/meta/base.hpp" 4 | 5 | POLYBAR_NS 6 | 7 | namespace modules { 8 | template 9 | class static_module : public module { 10 | public: 11 | using module::module; 12 | 13 | void start() { 14 | this->m_mainthread = thread([&] { 15 | this->m_log.trace("%s: Thread id = %i", this->name(), concurrency_util::thread_id(this_thread::get_id())); 16 | CAST_MOD(Impl)->update(); 17 | CAST_MOD(Impl)->broadcast(); 18 | }); 19 | } 20 | 21 | bool build(builder*, string) const { 22 | return true; 23 | } 24 | }; 25 | } 26 | 27 | POLYBAR_NS_END 28 | -------------------------------------------------------------------------------- /contrib/polybar.aur/polybar.install: -------------------------------------------------------------------------------- 1 | post_install() { 2 | cat << EOF 3 | 4 | Get started with the example configuration: 5 | 6 | $ install -Dm644 /usr/share/doc/polybar/config \$HOME/.config/polybar/config 7 | $ polybar example 8 | 9 | For more information, see https://github.com/polybar/polybar/wiki 10 | 11 | EOF 12 | } 13 | 14 | post_upgrade() { 15 | [ "$(vercmp "$2" "2.5.1-1")" = "-1" ] || exit 0 16 | cat << EOF 17 | 18 | The % suffix has been removed from percentage tokens. 19 | The suffix is instead added by the user, for example: 20 | 21 | format-charging = Capacity %percentage%% 22 | 23 | -- jaagr 24 | 25 | EOF 26 | } 27 | -------------------------------------------------------------------------------- /include/utils/http.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.hpp" 4 | #include "utils/factory.hpp" 5 | 6 | POLYBAR_NS 7 | 8 | class http_downloader { 9 | public: 10 | http_downloader(int connection_timeout = 5); 11 | ~http_downloader(); 12 | 13 | string get(const string& url); 14 | long response_code(); 15 | 16 | protected: 17 | static size_t write(void* p, size_t size, size_t bytes, void* stream); 18 | 19 | private: 20 | void* m_curl; 21 | }; 22 | 23 | namespace http_util { 24 | template 25 | decltype(auto) make_downloader(Args&&... args) { 26 | return factory_util::unique(forward(args)...); 27 | } 28 | } 29 | 30 | POLYBAR_NS_END 31 | -------------------------------------------------------------------------------- /include/utils/process.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.hpp" 4 | 5 | POLYBAR_NS 6 | 7 | namespace process_util { 8 | bool in_parent_process(pid_t pid); 9 | bool in_forked_process(pid_t pid); 10 | 11 | void exec(char* cmd, char** args); 12 | void exec_sh(const char* cmd); 13 | 14 | pid_t wait_for_completion(pid_t process_id, int* status_addr, int waitflags = 0); 15 | pid_t wait_for_completion(int* status_addr, int waitflags = 0); 16 | pid_t wait_for_completion(pid_t process_id); 17 | pid_t wait_for_completion_nohang(pid_t process_id, int* status); 18 | pid_t wait_for_completion_nohang(int* status); 19 | pid_t wait_for_completion_nohang(); 20 | 21 | bool notify_childprocess(); 22 | } 23 | 24 | POLYBAR_NS_END 25 | -------------------------------------------------------------------------------- /include/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Generate settings.hpp 3 | # 4 | 5 | list(APPEND dirs ${CMAKE_CURRENT_LIST_DIR}) 6 | 7 | if(WITH_XRANDR) 8 | list(APPEND XPP_EXTENSION_LIST xpp::randr::extension) 9 | endif() 10 | if(WITH_XCOMPOSITE) 11 | list(APPEND XPP_EXTENSION_LIST xpp::composite::extension) 12 | endif() 13 | if(WITH_XKB) 14 | list(APPEND XPP_EXTENSION_LIST xpp::xkb::extension) 15 | endif() 16 | string(REPLACE ";" ", " XPP_EXTENSION_LIST "${XPP_EXTENSION_LIST}") 17 | 18 | configure_file( 19 | ${CMAKE_CURRENT_LIST_DIR}/settings.hpp.cmake 20 | ${CMAKE_BINARY_DIR}/generated-sources/settings.hpp 21 | ESCAPE_QUOTES) 22 | 23 | list(APPEND dirs ${CMAKE_BINARY_DIR}/generated-sources/) 24 | set(APP_VERSION ${APP_VERSION} PARENT_SCOPE) 25 | set(dirs ${dirs} PARENT_SCOPE) 26 | -------------------------------------------------------------------------------- /include/utils/io.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.hpp" 4 | 5 | POLYBAR_NS 6 | 7 | namespace io_util { 8 | string read(int read_fd, size_t bytes_to_read); 9 | string readline(int read_fd); 10 | 11 | size_t write(int write_fd, size_t bytes_to_write, const string& data); 12 | size_t writeline(int write_fd, const string& data); 13 | 14 | void tail(int read_fd, const function& callback); 15 | void tail(int read_fd, int writeback_fd); 16 | 17 | bool poll(int fd, short int events, int timeout_ms = 0); 18 | bool poll_read(int fd, int timeout_ms = 0); 19 | bool poll_write(int fd, int timeout_ms = 0); 20 | 21 | bool interrupt_read(int write_fd); 22 | 23 | void set_block(int fd); 24 | void set_nonblock(int fd); 25 | } 26 | 27 | POLYBAR_NS_END 28 | -------------------------------------------------------------------------------- /include/utils/mixins.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.hpp" 4 | 5 | POLYBAR_NS 6 | 7 | /** 8 | * Base class for non copyable objects 9 | */ 10 | template 11 | class non_copyable_mixin { 12 | protected: 13 | non_copyable_mixin() {} 14 | ~non_copyable_mixin() {} 15 | 16 | private: 17 | non_copyable_mixin(const non_copyable_mixin&); 18 | non_copyable_mixin& operator=(const non_copyable_mixin&); 19 | }; 20 | 21 | /** 22 | * Base class for non movable objects 23 | */ 24 | template 25 | class non_movable_mixin { 26 | protected: 27 | non_movable_mixin() {} 28 | ~non_movable_mixin() {} 29 | 30 | private: 31 | non_movable_mixin(non_movable_mixin&&); 32 | non_movable_mixin& operator=(non_movable_mixin&&); 33 | }; 34 | 35 | POLYBAR_NS_END 36 | -------------------------------------------------------------------------------- /doc/index.rst: -------------------------------------------------------------------------------- 1 | Polybar Documentation 2 | ===================== 3 | 4 | .. note:: This is still very much a work-in-progress. Most information is still 5 | to be found on our `GitHub Wiki `_. 6 | We will migrate the wiki content step-by-step. 7 | 8 | 9 | Welcome to the official polybar documentation. 10 | 11 | .. toctree:: 12 | :maxdepth: 2 13 | :caption: Contents: 14 | 15 | .. toctree:: 16 | :maxdepth: 1 17 | :caption: Manual Pages: 18 | 19 | man/polybar.1 20 | 21 | Getting Help 22 | ============ 23 | 24 | * `Polybar Wiki `_ 25 | * `Gitter `_ 26 | * `/r/polybar `_ on reddit 27 | * ``#polybar`` on ``chat.freenode.net`` 28 | 29 | -------------------------------------------------------------------------------- /src/utils/concurrency.cpp: -------------------------------------------------------------------------------- 1 | #include "utils/concurrency.hpp" 2 | 3 | POLYBAR_NS 4 | 5 | bool spin_lock::no_backoff_strategy::operator()() { 6 | return true; 7 | } 8 | bool spin_lock::yield_backoff_strategy::operator()() { 9 | this_thread::yield(); 10 | return false; 11 | } 12 | void spin_lock::lock() noexcept { 13 | lock(no_backoff_strategy{}); 14 | } 15 | void spin_lock::unlock() noexcept { 16 | m_locked.clear(std::memory_order_release); 17 | } 18 | 19 | namespace concurrency_util { 20 | size_t thread_id(const thread::id id) { 21 | static size_t idx{1_z}; 22 | static mutex_wrapper> ids; 23 | std::lock_guard lock(ids); 24 | if (ids.find(id) == ids.end()) { 25 | ids[id] = idx++; 26 | } 27 | return ids[id]; 28 | } 29 | } 30 | 31 | POLYBAR_NS_END 32 | -------------------------------------------------------------------------------- /include/drawtypes/ramp.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.hpp" 4 | #include "components/config.hpp" 5 | #include "drawtypes/label.hpp" 6 | #include "utils/mixins.hpp" 7 | 8 | POLYBAR_NS 9 | 10 | namespace drawtypes { 11 | class ramp : public non_copyable_mixin { 12 | public: 13 | explicit ramp() = default; 14 | explicit ramp(vector&& icons) : m_icons(forward(icons)) {} 15 | 16 | void add(label_t&& icon); 17 | label_t get(size_t index); 18 | label_t get_by_percentage(float percentage); 19 | operator bool(); 20 | 21 | protected: 22 | vector m_icons; 23 | }; 24 | 25 | using ramp_t = shared_ptr; 26 | 27 | ramp_t load_ramp(const config& conf, const string& section, string name, bool required = true); 28 | } 29 | 30 | POLYBAR_NS_END 31 | -------------------------------------------------------------------------------- /src/x11/cursor.cpp: -------------------------------------------------------------------------------- 1 | #include "x11/cursor.hpp" 2 | 3 | POLYBAR_NS 4 | 5 | namespace cursor_util { 6 | bool valid(string name) { 7 | return (cursors.find(name) != cursors.end()); 8 | } 9 | 10 | bool set_cursor(xcb_connection_t *c, xcb_screen_t *screen, xcb_window_t w, string name) { 11 | xcb_cursor_t cursor = XCB_CURSOR_NONE; 12 | xcb_cursor_context_t *ctx; 13 | 14 | if (xcb_cursor_context_new(c, screen, &ctx) < 0) { 15 | return false; 16 | } 17 | for (auto&& cursor_name : cursors.at(name)) { 18 | cursor = xcb_cursor_load_cursor(ctx, cursor_name.c_str()); 19 | if (cursor != XCB_CURSOR_NONE) 20 | break; 21 | } 22 | xcb_change_window_attributes(c, w, XCB_CW_CURSOR, &cursor); 23 | xcb_cursor_context_free(ctx); 24 | return true; 25 | } 26 | } 27 | POLYBAR_NS_END 28 | -------------------------------------------------------------------------------- /src/modules/counter.cpp: -------------------------------------------------------------------------------- 1 | #include "modules/counter.hpp" 2 | 3 | #include "modules/meta/base.inl" 4 | 5 | POLYBAR_NS 6 | 7 | namespace modules { 8 | template class module; 9 | 10 | counter_module::counter_module(const bar_settings& bar, string name_) 11 | : timer_module(bar, move(name_)) { 12 | m_interval = m_conf.get(name(), "interval", m_interval); 13 | m_formatter->add(DEFAULT_FORMAT, TAG_COUNTER, {TAG_COUNTER}); 14 | } 15 | 16 | bool counter_module::update() { 17 | m_counter++; 18 | return true; 19 | } 20 | 21 | bool counter_module::build(builder* builder, const string& tag) const { 22 | if (tag == TAG_COUNTER) { 23 | builder->node(to_string(m_counter)); 24 | return true; 25 | } 26 | return false; 27 | } 28 | } 29 | 30 | POLYBAR_NS_END 31 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/build.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Build Issues 3 | about: Report issues while building polybar 4 | 5 | --- 6 | 7 | ## Build Process 8 | *Describe how you build polybar, list the exact commands you are using:* 9 | 10 | 11 | 12 | **If you build polybar directly from this repository:** 13 | 14 | * Output of `git describe --tags`: 15 | 16 | **If you use some other way (like the AUR):** 17 | 18 | *List exactly where you are building from and which version you are building.* 19 | 20 | 21 | ## Build Log 22 | *Post everything that is output to the terminal while building polybar below. This HAS to include the output of the `cmake` and `make` commands, if you used them.* 23 | ``` 24 | 25 | ``` 26 | 27 | ## Environment: 28 | * Distro (with Version): 29 | 30 | ## Additional context 31 | *Add any other context that you think is necessary about the problem here.* 32 | -------------------------------------------------------------------------------- /lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Configure libs 3 | # 4 | 5 | # Library: concurrentqueue {{{ 6 | 7 | add_library(concurrentqueue INTERFACE) 8 | target_include_directories(concurrentqueue INTERFACE 9 | $) 10 | list(APPEND libs concurrentqueue) 11 | 12 | # }}} 13 | # Library: xpp {{{ 14 | 15 | set(XCB_PROTOS xproto) 16 | 17 | if(WITH_XRANDR) 18 | list(APPEND XCB_PROTOS randr) 19 | endif() 20 | if(WITH_XCOMPOSITE) 21 | list(APPEND XCB_PROTOS composite) 22 | endif() 23 | if(WITH_XKB) 24 | list(APPEND XCB_PROTOS xkb) 25 | endif() 26 | 27 | add_subdirectory(xpp) 28 | list(APPEND libs xpp) 29 | 30 | # }}} 31 | # Library: i3ipcpp {{{ 32 | 33 | if(ENABLE_I3) 34 | add_subdirectory(i3ipcpp) 35 | list(APPEND libs ${I3IPCPP_LIBRARIES}) 36 | endif() 37 | 38 | # }}} 39 | 40 | set(libs ${libs} PARENT_SCOPE) 41 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | 5 | --- 6 | 7 | ## Is your feature request related to a problem? Please describe. 8 | *A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]* 9 | 10 | ## Why does polybar need this feature? 11 | *Describe why this feature would be useful to a large percentage of users (You need to convince us).* 12 | 13 | ## Describe the solution you'd like 14 | *A clear and concise description of how your solution would work. This includes possible config options that should be added.* 15 | 16 | ## Describe alternatives you've considered 17 | *A clear and concise description of any alternative solutions or features you've considered, if any.* 18 | 19 | ## Additional context 20 | *Add any other context or screenshots about the feature request here.* 21 | -------------------------------------------------------------------------------- /cmake/templates/uninstall.cmake.in: -------------------------------------------------------------------------------- 1 | set(INSTALL_MANIFEST "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") 2 | if(NOT EXISTS ${INSTALL_MANIFEST}) 3 | message(FATAL_ERROR "Cannot find install manifest: ${INSTALL_MANIFEST}") 4 | endif() 5 | 6 | file(READ ${INSTALL_MANIFEST} files) 7 | string(REGEX REPLACE "\n" ";" files "${files}") 8 | list(REVERSE files) 9 | 10 | foreach(file ${files}) 11 | message(STATUS "Uninstalling $ENV{DESTDIR}${file}") 12 | if(EXISTS "$ENV{DESTDIR}${file}") 13 | execute_process(COMMAND "@CMAKE_COMMAND@" 14 | -E remove "$ENV{DESTDIR}${file}" 15 | OUTPUT_VARIABLE rm_out 16 | RESULT_VARIABLE rm_retval) 17 | if(NOT ${rm_retval} EQUAL 0) 18 | message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") 19 | endif() 20 | else() 21 | message(STATUS "File $ENV{DESTDIR}${file} does not exist") 22 | endif() 23 | endforeach() 24 | -------------------------------------------------------------------------------- /include/modules/github.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "modules/meta/timer_module.hpp" 4 | #include "settings.hpp" 5 | #include "utils/http.hpp" 6 | 7 | POLYBAR_NS 8 | 9 | namespace modules { 10 | /** 11 | * Module used to query the GitHub API for notification count 12 | */ 13 | class github_module : public timer_module { 14 | public: 15 | explicit github_module(const bar_settings&, string); 16 | 17 | bool update(); 18 | bool build(builder* builder, const string& tag) const; 19 | 20 | private: 21 | void update_label(int); 22 | int get_number_of_notification(); 23 | string request(); 24 | static constexpr auto TAG_LABEL = "