Create default config (#2511)

* Create default config and install to /etc/polybar

Closes #2405

* Search for config in /etc

We search in XDG_CONFIG_DIRS, /etc/xdg, and /etc but only for config.ini

Closes #2016

* Remove config installation from build.sh

* Remove userconfig cmake file

* Cleanup

* Cleanup default config

* Update CHANGELOG.md

Co-authored-by: dvermd <315743+dvermd@users.noreply.github.com>

* Update src/main.cpp

Co-authored-by: dvermd <315743+dvermd@users.noreply.github.com>

* Add tests for string functions

* Support loading bars from fallbacks in /etc

* Combine duplicate string_util::contains test

Co-authored-by: dvermd <315743+dvermd@users.noreply.github.com>
This commit is contained in:
Patrick Ziegler 2021-10-05 13:07:19 +02:00 committed by GitHub
parent 98dffc292a
commit 282b0f4e73
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 316 additions and 649 deletions

View File

@ -42,7 +42,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `BUILD_DOC=ON` - Builds the documentation - `BUILD_DOC=ON` - Builds the documentation
- `BUILD_DOC_HTML=BUILD_DOC` - Builds the html documentation (depends on `BUILD_DOC`) - `BUILD_DOC_HTML=BUILD_DOC` - Builds the html documentation (depends on `BUILD_DOC`)
- `BUILD_DOC_MAN=BUILD_DOC` - Builds the manpages (depends on `BUILD_DOC`) - `BUILD_DOC_MAN=BUILD_DOC` - Builds the manpages (depends on `BUILD_DOC`)
- `BUILD_CONFIG=ON` - Generates sample config - `BUILD_CONFIG=ON` - Generates the default config
- `BUILD_SHELL=ON` - Generates shell completion files - `BUILD_SHELL=ON` - Generates shell completion files
- `DISABLE_ALL=OFF` - Disables all above targets by default. Individual - `DISABLE_ALL=OFF` - Disables all above targets by default. Individual
targets can still be enabled explicitly. targets can still be enabled explicitly.
@ -52,12 +52,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
whatever folder you invoked `cmake` from instead of in the root folder of the whatever folder you invoked `cmake` from instead of in the root folder of the
repository. repository.
- The `POLYBAR_FLAGS` cmake variable can be used to pass extra C++ compiler flags. - The `POLYBAR_FLAGS` cmake variable can be used to pass extra C++ compiler flags.
- The sample config file has been removed.
- Polybar now ships a default config that is installed to
`/etc/polybar/config.ini`, it lives in `doc/config.ini`.
It will also be placed in the `examples` directory in the documentation folder.
[`#2405`](https://github.com/polybar/polybar/issues/2405)
- The `userconfig` target has been removed, you can no longer use `make
userconfig`. As an alternative, you can copy the default config from
`/etc/polybar/config.ini`.
### Deprecated ### Deprecated
- `[settings]`: `throttle-output` and `throttle-output-for` have been removed. - `[settings]`: `throttle-output` and `throttle-output-for` have been removed.
The new event loop already does a similar thing where it coalesces update The new event loop already does a similar thing where it coalesces update
triggers if they happen directly after one another, leading to only a single triggers if they happen directly after one another, leading to only a single
bar update. bar update.
- When not specifying the config file with `--config`, naming your config file
`config` is deprecated. Rename your config file to `config.ini`.
### Removed ### Removed
- `DEBUG_SHADED` cmake variable and its associated functionality. - `DEBUG_SHADED` cmake variable and its associated functionality.
@ -94,8 +104,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
speeds are displayed. speeds are displayed.
- `internal/xkeyboard`: `%variant%` can be used to parse the layout variant - `internal/xkeyboard`: `%variant%` can be used to parse the layout variant
([`#316`](https://github.com/polybar/polybar/issues/316)) ([`#316`](https://github.com/polybar/polybar/issues/316))
- Added .ini extension check to the default config search.
([`#2323`](https://github.com/polybar/polybar/issues/2323))
- Config option to hide a certain module - Config option to hide a certain module
(`hidden = false`) (`hidden = false`)
([`#2108`](https://github.com/polybar/polybar/issues/2108)) ([`#2108`](https://github.com/polybar/polybar/issues/2108))
@ -126,6 +134,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
([`#2414`](https://github.com/polybar/polybar/issues/2414)) ([`#2414`](https://github.com/polybar/polybar/issues/2414))
### Changed ### Changed
- Polybar now also reads `config.ini` when searching for config files.
([`#2323`](https://github.com/polybar/polybar/issues/2323))
- Polybar additionally searches in `XDG_CONFIG_DIRS/polybar` (or
`/etc/xdg/polybar` if it is not set) and `/etc/polybar` for config files
(only `config.ini`).
([`#2016`](https://github.com/polybar/polybar/issues/2016))
- We rewrote polybar's main event loop. This shouldn't change any behavior for - We rewrote polybar's main event loop. This shouldn't change any behavior for
the user, but be on the lookout for X events, click events, or ipc messages the user, but be on the lookout for X events, click events, or ipc messages
not arriving and the bar not shutting down/restarting properly and let us not arriving and the bar not shutting down/restarting properly and let us

View File

@ -60,8 +60,11 @@ if(BUILD_TESTS)
add_subdirectory(tests) add_subdirectory(tests)
endif() endif()
if(BUILD_CONFIG) if(BUILD_CONFIG)
add_subdirectory(config) install(FILES ${CMAKE_SOURCE_DIR}/doc/config.ini
DESTINATION /etc/${PROJECT_NAME}
COMPONENT config)
endif() endif()
include(05-summary) include(05-summary)

View File

@ -23,14 +23,8 @@ A fast and easy-to-use tool for creating status bars.
**Polybar** aims to help users build beautiful and highly customizable status bars **Polybar** aims to help users build beautiful and highly customizable status bars
for their desktop environment, without the need of having a black belt in shell scripting. for their desktop environment, without the need of having a black belt in shell scripting.
Here are a few screenshots showing you what it can look like:
[![sample screenshot](https://i.imgur.com/xvlw9iHt.png)](https://i.imgur.com/xvlw9iH.png) ![sample screenshot](doc/_static/default.png)
[![sample screenshot](https://i.imgur.com/cYQOuRrt.png)](https://i.imgur.com/cYQOuRr.png)
[![sample screenshot](https://i.imgur.com/A6spiZZt.png)](https://i.imgur.com/A6spiZZ.png)
[![sample screenshot](https://i.imgur.com/TY5a5r9t.png)](https://i.imgur.com/TY5a5r9.png)
You can find polybar configs for these example images (and other configs) [here](https://github.com/jaagr/dots/tree/master/.local/etc/themer/themes).
## Table of Contents ## Table of Contents
@ -139,14 +133,13 @@ If you can't find your distro here, you will have to [build from source](https:/
Details on how to setup and configure the bar and each module have been moved to [the wiki](https://github.com/polybar/polybar/wiki/Configuration). Details on how to setup and configure the bar and each module have been moved to [the wiki](https://github.com/polybar/polybar/wiki/Configuration).
#### Install the example configuration #### Install the example configuration
Run the following inside the build directory:
**WARNING:** This will overwrite your current configuration file! For a normal installation, polybar will install the example config to
`/usr/share/doc/polybar/config` or ` /usr/local/share/doc/polybar/config`
(depending on your install parameters)
~~~ sh From there you can copy it to `~/.config/polybar/config` to get started (make
$ make userconfig sure to backup any existing config file there).
~~~
Or you can copy the example config from `/usr/share/doc/polybar/config` or ` /usr/local/share/doc/polybar/config` (depending on your install parameters)
**Note:** This example file is meant to showcase available modules and **Note:** This example file is meant to showcase available modules and
configuration options. configuration options.

View File

@ -46,8 +46,6 @@ usage() {
Remove existing build dir; disabled by default. Remove existing build dir; disabled by default.
${COLORS[GREEN]}-I, --no-install${COLORS[OFF]} ${COLORS[GREEN]}-I, --no-install${COLORS[OFF]}
Do not execute 'sudo make install'; enabled by default. Do not execute 'sudo make install'; enabled by default.
${COLORS[GREEN]}-C, --install-config${COLORS[OFF]}
Install example configuration; disabled by default.
${COLORS[GREEN]}-A, --auto${COLORS[OFF]} ${COLORS[GREEN]}-A, --auto${COLORS[OFF]}
Automatic, non-interactive installation; disabled by default. Automatic, non-interactive installation; disabled by default.
When set, script defaults options not explicitly set. When set, script defaults options not explicitly set.
@ -70,7 +68,6 @@ install() {
if [[ "$AUTO" == ON ]]; then if [[ "$AUTO" == ON ]]; then
[[ -z "$INSTALL" ]] && INSTALL="ON" [[ -z "$INSTALL" ]] && INSTALL="ON"
[[ -z "$INSTALL_CONF" ]] && INSTALL_CONF="OFF"
fi fi
if [[ -z "$INSTALL" ]]; then if [[ -z "$INSTALL" ]]; then
@ -78,19 +75,9 @@ install() {
[[ "${p^^}" != "N" ]] && INSTALL="ON" || INSTALL="OFF" [[ "${p^^}" != "N" ]] && INSTALL="ON" || INSTALL="OFF"
fi fi
if [[ -z "$INSTALL_CONF" ]]; then
read -r -p "$(msg "Install example configuration? [y/N]: ")" -n 1 p && echo
[[ "${p^^}" != "Y" ]] && INSTALL_CONF="OFF" || INSTALL_CONF="ON"
fi
if [[ "$INSTALL" == ON ]]; then if [[ "$INSTALL" == ON ]]; then
sudo make install || msg_err "Failed to install executables..." sudo make install || msg_err "Failed to install executables..."
fi fi
if [[ "$INSTALL_CONF" == ON ]]; then
make userconfig || msg_err "Failed to install user configuration..."
fi
} }
set_build_opts() { set_build_opts() {
@ -253,8 +240,6 @@ while [[ "$1" == -* ]]; do
REMOVE_BUILD_DIR=ON; shift ;; REMOVE_BUILD_DIR=ON; shift ;;
-I|--no-install) -I|--no-install)
INSTALL=OFF; shift ;; INSTALL=OFF; shift ;;
-C|--install-config)
INSTALL_CONF=ON; shift ;;
-A|--auto) -A|--auto)
AUTO=ON; shift ;; AUTO=ON; shift ;;
-h|--help) -h|--help)

View File

@ -26,48 +26,6 @@ endfunction()
# }}} # }}}
# queryfont {{{
function(queryfont output_variable fontname)
set(multi_value_args FIELDS)
cmake_parse_arguments(ARG "" "" "${multi_value_args}" ${ARGN})
find_program(BIN_FCLIST fc-list)
if(NOT BIN_FCLIST)
message_colored(WARNING "Failed to locate `fc-list`" "33;1")
return()
endif()
string(REPLACE ";" " " FIELDS "${ARG_FIELDS}")
if(NOT FIELDS)
set(FIELDS family)
endif()
execute_process(
COMMAND sh -c "${BIN_FCLIST} : ${FIELDS}"
RESULT_VARIABLE status
OUTPUT_VARIABLE output
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
STRING(REGEX REPLACE ";" "\\\\;" output "${output}")
STRING(REGEX REPLACE "\n" ";" output "${output}")
STRING(TOLOWER "${output}" output)
foreach(match LISTS ${output})
if(${match} MATCHES ".*${fontname}.*$")
list(APPEND matches ${match})
endif()
endforeach()
if(matches)
list(GET matches 0 fst_match)
set(${output_variable} "${fst_match}" PARENT_SCOPE)
message(STATUS "Found font: ${fst_match}")
else()
message_colored(STATUS "Font not found: ${fontname}" "33;1")
endif()
endfunction()
# }}}
# find_package_impl {{{ # find_package_impl {{{
# Uses PkgConfig to search for pkg_config_name # Uses PkgConfig to search for pkg_config_name

View File

@ -1,8 +0,0 @@
set(USER_CONFIG_HOME "$ENV{XDG_CONFIG_HOME}")
if(NOT USER_CONFIG_HOME)
set(USER_CONFIG_HOME "$ENV{HOME}/.config")
endif()
set(USER_CONFIG_HOME "${USER_CONFIG_HOME}/polybar")
file(INSTALL "@CMAKE_BINARY_DIR@/generated-sources/config"
DESTINATION "${USER_CONFIG_HOME}")

View File

@ -1,106 +0,0 @@
#
# Generate configuration file
#
set(MODULES_LEFT "bspwm;i3")
set(MODULES_CENTER "mpd")
set(MODULES_RIGHT "filesystem;backlight-acpi;alsa;pulseaudio;xkeyboard;memory;cpu;wlan;eth;battery;temperature;date;powermenu")
set(FONT_FIXED "fixed:pixelsize=10")
set(FONT_UNIFONT "unifont:fontformat=truetype")
set(FONT_SIJI "siji:pixelsize=10")
queryfont(FONT_FIXED ${FONT_FIXED} FIELDS family pixelsize)
queryfont(FONT_UNIFONT ${FONT_UNIFONT} FIELDS family fontformat)
queryfont(FONT_SIJI ${FONT_SIJI} FIELDS family pixelsize)
# Strip disabled modules {{{
if(NOT ENABLE_PULSEAUDIO)
list(REMOVE_ITEM MODULES_RIGHT "pulseaudio")
endif()
if(NOT ENABLE_ALSA)
list(REMOVE_ITEM MODULES_RIGHT "alsa")
endif()
if(NOT ENABLE_I3)
list(REMOVE_ITEM MODULES_LEFT "i3")
endif()
if(NOT ENABLE_MPD)
list(REMOVE_ITEM MODULES_CENTER "mpd")
endif()
if(NOT ENABLE_NETWORK)
list(REMOVE_ITEM MODULES_RIGHT "wlan" "eth")
endif()
if(NOT WITH_XKB)
list(REMOVE_ITEM MODULES_RIGHT "xkeyboard")
endif()
string(REPLACE ";" " " MODULES_LEFT "${MODULES_LEFT}")
string(REPLACE ";" " " MODULES_CENTER "${MODULES_CENTER}")
string(REPLACE ";" " " MODULES_RIGHT "${MODULES_RIGHT}")
# }}}
# Get battery/adapter name {{{
string(REGEX REPLACE /%battery%.* "" PATH_BAT ${SETTING_PATH_BATTERY})
string(REGEX REPLACE /%adapter%.* "" PATH_ADP ${SETTING_PATH_ADAPTER})
file(GLOB BAT_LIST RELATIVE ${PATH_BAT} ${PATH_ADP}/B*)
file(GLOB ADP_LIST RELATIVE ${PATH_ADP} ${PATH_ADP}/A*)
if(BAT_LIST)
list(GET BAT_LIST 0 BATTERY)
else()
set(BATTERY BAT0)
endif()
if(ADP_LIST)
list(GET ADP_LIST 0 ADAPTER)
else()
set(ADAPTER ADP1)
endif()
# }}}
# Get network interfaces {{{
if(ENABLE_NETWORK)
file(GLOB IFLIST RELATIVE /sys/class/net /sys/class/net/*)
foreach(INTERFACE ${IFLIST})
if(NOT ${INTERFACE} STREQUAL "lo")
file(GLOB IS_WIRELESS /sys/class/net/${INTERFACE}/wireless)
if(IS_WIRELESS)
set(INTERFACE_WLAN ${INTERFACE})
else()
set(INTERFACE_ETH ${INTERFACE})
endif()
endif()
endforeach()
if(NOT INTERFACE_ETH)
set(INTERFACE_ETH net0)
endif()
if(NOT INTERFACE_WLAN)
set(INTERFACE_WLAN net1)
endif()
endif()
# }}}
# Configure and install {{{
configure_file(
${CMAKE_CURRENT_LIST_DIR}/config.cmake
${CMAKE_BINARY_DIR}/generated-sources/config
ESCAPE_QUOTES @ONLY)
install(FILES ${CMAKE_BINARY_DIR}/generated-sources/config
DESTINATION ${CMAKE_INSTALL_DOCDIR}
COMPONENT config)
# }}}
# Target: userconfig {{{
configure_file(
${PROJECT_SOURCE_DIR}/cmake/templates/userconfig.cmake.in
${PROJECT_BINARY_DIR}/cmake/userconfig.cmake
ESCAPE_QUOTES @ONLY)
add_custom_target(userconfig
COMMAND ${CMAKE_COMMAND} -P ${PROJECT_BINARY_DIR}/cmake/userconfig.cmake)
# }}}

View File

@ -1,428 +0,0 @@
;==========================================================
;
;
;
;
;
;
;
;
;
;
; To learn more about how to configure Polybar
; go to https://github.com/polybar/polybar
;
; The README contains a lot of information
;
;==========================================================
[colors]
;background = ${xrdb:color0:#222}
background = #222
background-alt = #444
;foreground = ${xrdb:color7:#222}
foreground = #dfdfdf
foreground-alt = #555
primary = #ffb52a
secondary = #e60053
alert = #bd2c40
[bar/example]
;monitor = ${env:MONITOR:HDMI-1}
width = 100%
height = 27
;offset-x = 1%
;offset-y = 1%
radius = 6.0
fixed-center = false
background = ${colors.background}
foreground = ${colors.foreground}
line-size = 3
line-color = #f00
border-size = 4
border-color = #00000000
padding-left = 0
padding-right = 2
module-margin-left = 1
module-margin-right = 2
font-0 = @FONT_FIXED@;1
font-1 = @FONT_UNIFONT@:size=8:antialias=false;0
font-2 = @FONT_SIJI@;1
modules-left = @MODULES_LEFT@
modules-center = @MODULES_CENTER@
modules-right = @MODULES_RIGHT@
tray-position = right
tray-padding = 2
;tray-background = #0063ff
;wm-restack = generic
;wm-restack = bspwm
;wm-restack = i3
;override-redirect = true
;scroll-up = bspwm-desknext
;scroll-down = bspwm-deskprev
;scroll-up = i3wm-wsnext
;scroll-down = i3wm-wsprev
cursor-click = pointer
cursor-scroll = ns-resize
enable-ipc = true
[module/xwindow]
type = internal/xwindow
label = %title:0:30:...%
[module/xkeyboard]
type = internal/xkeyboard
blacklist-0 = num lock
format-prefix = " "
format-prefix-foreground = ${colors.foreground-alt}
format-prefix-underline = ${colors.secondary}
label-layout = %layout%
label-layout-underline = ${colors.secondary}
label-indicator-padding = 2
label-indicator-margin = 1
label-indicator-background = ${colors.secondary}
label-indicator-underline = ${colors.secondary}
[module/filesystem]
type = internal/fs
interval = 25
mount-0 = /
label-mounted = %{F#0a81f5}%mountpoint%%{F-}: %percentage_used%%
label-unmounted = %mountpoint% not mounted
label-unmounted-foreground = ${colors.foreground-alt}
[module/bspwm]
type = internal/bspwm
label-focused = %index%
label-focused-background = ${colors.background-alt}
label-focused-underline= ${colors.primary}
label-focused-padding = 2
label-occupied = %index%
label-occupied-padding = 2
label-urgent = %index%!
label-urgent-background = ${colors.alert}
label-urgent-padding = 2
label-empty = %index%
label-empty-foreground = ${colors.foreground-alt}
label-empty-padding = 2
; Separator in between workspaces
; label-separator = |
[module/i3]
type = internal/i3
format = <label-state> <label-mode>
index-sort = true
wrapping-scroll = false
; Only show workspaces on the same output as the bar
;pin-workspaces = true
label-mode-padding = 2
label-mode-foreground = #000
label-mode-background = ${colors.primary}
; focused = Active workspace on focused monitor
label-focused = %index%
label-focused-background = ${colors.background-alt}
label-focused-underline= ${colors.primary}
label-focused-padding = 2
; unfocused = Inactive workspace on any monitor
label-unfocused = %index%
label-unfocused-padding = 2
; visible = Active workspace on unfocused monitor
label-visible = %index%
label-visible-background = ${self.label-focused-background}
label-visible-underline = ${self.label-focused-underline}
label-visible-padding = ${self.label-focused-padding}
; urgent = Workspace with urgency hint set
label-urgent = %index%
label-urgent-background = ${colors.alert}
label-urgent-padding = 2
; Separator in between workspaces
; label-separator = |
[module/mpd]
type = internal/mpd
format-online = <label-song> <icon-prev> <icon-stop> <toggle> <icon-next>
icon-prev =
icon-stop =
icon-play =
icon-pause =
icon-next =
label-song-maxlen = 25
label-song-ellipsis = true
[module/xbacklight]
type = internal/xbacklight
format = <label> <bar>
label = BL
bar-width = 10
bar-indicator = |
bar-indicator-foreground = #fff
bar-indicator-font = 2
bar-fill =
bar-fill-font = 2
bar-fill-foreground = #9f78e1
bar-empty =
bar-empty-font = 2
bar-empty-foreground = ${colors.foreground-alt}
[module/backlight-acpi]
inherit = module/xbacklight
type = internal/backlight
card = intel_backlight
[module/cpu]
type = internal/cpu
interval = 2
format-prefix = " "
format-prefix-foreground = ${colors.foreground-alt}
format-underline = #f90000
label = %percentage:2%%
[module/memory]
type = internal/memory
interval = 2
format-prefix = " "
format-prefix-foreground = ${colors.foreground-alt}
format-underline = #4bffdc
label = %percentage_used%%
[module/wlan]
type = internal/network
interface = @INTERFACE_WLAN@
interval = 3.0
format-connected = <ramp-signal> <label-connected>
format-connected-underline = #9f78e1
label-connected = %essid%
format-disconnected =
;format-disconnected = <label-disconnected>
;format-disconnected-underline = ${self.format-connected-underline}
;label-disconnected = %ifname% disconnected
;label-disconnected-foreground = ${colors.foreground-alt}
ramp-signal-0 =
ramp-signal-1 =
ramp-signal-2 =
ramp-signal-3 =
ramp-signal-4 =
ramp-signal-foreground = ${colors.foreground-alt}
[module/eth]
type = internal/network
interface = @INTERFACE_ETH@
interval = 3.0
format-connected-underline = #55aa55
format-connected-prefix = " "
format-connected-prefix-foreground = ${colors.foreground-alt}
label-connected = %local_ip%
format-disconnected =
;format-disconnected = <label-disconnected>
;format-disconnected-underline = ${self.format-connected-underline}
;label-disconnected = %ifname% disconnected
;label-disconnected-foreground = ${colors.foreground-alt}
[module/date]
type = internal/date
interval = 5
date =
date-alt = " %Y-%m-%d"
time = %H:%M
time-alt = %H:%M:%S
format-prefix =
format-prefix-foreground = ${colors.foreground-alt}
format-underline = #0a6cf5
label = %date% %time%
;hidden = true
[module/pulseaudio]
type = internal/pulseaudio
format-volume = <label-volume> <bar-volume>
label-volume = VOL %percentage%%
label-volume-foreground = ${root.foreground}
label-muted = 🔇 muted
label-muted-foreground = #666
bar-volume-width = 10
bar-volume-foreground-0 = #55aa55
bar-volume-foreground-1 = #55aa55
bar-volume-foreground-2 = #55aa55
bar-volume-foreground-3 = #55aa55
bar-volume-foreground-4 = #55aa55
bar-volume-foreground-5 = #f5a70a
bar-volume-foreground-6 = #ff5555
bar-volume-gradient = false
bar-volume-indicator = |
bar-volume-indicator-font = 2
bar-volume-fill =
bar-volume-fill-font = 2
bar-volume-empty =
bar-volume-empty-font = 2
bar-volume-empty-foreground = ${colors.foreground-alt}
[module/alsa]
type = internal/alsa
format-volume = <label-volume> <bar-volume>
label-volume = VOL
label-volume-foreground = ${root.foreground}
format-muted-prefix = " "
format-muted-foreground = ${colors.foreground-alt}
label-muted = sound muted
bar-volume-width = 10
bar-volume-foreground-0 = #55aa55
bar-volume-foreground-1 = #55aa55
bar-volume-foreground-2 = #55aa55
bar-volume-foreground-3 = #55aa55
bar-volume-foreground-4 = #55aa55
bar-volume-foreground-5 = #f5a70a
bar-volume-foreground-6 = #ff5555
bar-volume-gradient = false
bar-volume-indicator = |
bar-volume-indicator-font = 2
bar-volume-fill =
bar-volume-fill-font = 2
bar-volume-empty =
bar-volume-empty-font = 2
bar-volume-empty-foreground = ${colors.foreground-alt}
[module/battery]
type = internal/battery
battery = @BATTERY@
adapter = @ADAPTER@
full-at = 98
format-charging = <animation-charging> <label-charging>
format-charging-underline = #ffb52a
format-discharging = <animation-discharging> <label-discharging>
format-discharging-underline = ${self.format-charging-underline}
format-full-prefix = " "
format-full-prefix-foreground = ${colors.foreground-alt}
format-full-underline = ${self.format-charging-underline}
ramp-capacity-0 =
ramp-capacity-1 =
ramp-capacity-2 =
ramp-capacity-foreground = ${colors.foreground-alt}
animation-charging-0 =
animation-charging-1 =
animation-charging-2 =
animation-charging-foreground = ${colors.foreground-alt}
animation-charging-framerate = 750
animation-discharging-0 =
animation-discharging-1 =
animation-discharging-2 =
animation-discharging-foreground = ${colors.foreground-alt}
animation-discharging-framerate = 750
[module/temperature]
type = internal/temperature
thermal-zone = 0
warn-temperature = 60
format = <ramp> <label>
format-underline = #f50a4d
format-warn = <ramp> <label-warn>
format-warn-underline = ${self.format-underline}
label = %temperature-c%
label-warn = %temperature-c%
label-warn-foreground = ${colors.secondary}
ramp-0 =
ramp-1 =
ramp-2 =
ramp-foreground = ${colors.foreground-alt}
[module/powermenu]
type = custom/menu
expand-right = true
format-spacing = 1
label-open =
label-open-foreground = ${colors.secondary}
label-close = cancel
label-close-foreground = ${colors.secondary}
label-separator = |
label-separator-foreground = ${colors.foreground-alt}
menu-0-0 = reboot
menu-0-0-exec = menu-open-1
menu-0-1 = power off
menu-0-1-exec = menu-open-2
menu-1-0 = cancel
menu-1-0-exec = menu-open-0
menu-1-1 = reboot
menu-1-1-exec = sudo reboot
menu-2-0 = power off
menu-2-0-exec = sudo poweroff
menu-2-1 = cancel
menu-2-1-exec = menu-open-0
[settings]
screenchange-reload = true
;compositing-background = xor
;compositing-background = screen
;compositing-foreground = source
;compositing-border = over
;pseudo-transparency = false
[global/wm]
margin-top = 5
margin-bottom = 5
; vim:ft=dosini

View File

@ -1,28 +1,41 @@
_polybar_config_file() { _polybar_default_file() {
local config_path=${XDG_CONFIG_HOME:-$HOME/.config}/polybar/config local suffix=/polybar/config.ini
local home_path=${XDG_CONFIG_HOME:-$HOME/.config}${suffix}
local etc_xdg_path=${XDG_CONFIG_DIRS:-/etc/xdg}${suffix}
local etc_path=/etc${suffix}
if [ -r "$home_path" ]; then
echo "$home_path"
elif [ -r "$etc_xdg_path" ]; then
echo "$etc_xdg_path"
elif [ -r "$etc_path" ]; then
echo "$etc_path"
fi
}
_polybar_config_file() {
for ((i = 0; i < COMP_CWORD; i++)); do for ((i = 0; i < COMP_CWORD; i++)); do
case ${COMP_WORDS[i]} in case ${COMP_WORDS[i]} in
--config) --config)
config_path=${COMP_WORDS[i + 2]} echo "${COMP_WORDS[i + 2]}"
break return
;; ;;
-c) -c)
config_path=${COMP_WORDS[i + 1]} echo "${COMP_WORDS[i + 1]}"
break return
;; ;;
esac esac
done done
# Use eval + cd for to get bash's parameter/tilde expansion etc _polybar_default_file
(eval cd $(dirname "$config_path"); echo $PWD/$(basename "$config_path"))
} }
_polybar_bars() { _polybar_bars() {
local config_file=$(_polybar_config_file) local config_file=$(_polybar_config_file)
if [ -r "$config_file" ]; then if [ -r "$config_file" ]; then
grep -Po '\[bar/\K(.*)(?=\])' "$config_file" sed -nE 's|[[:space:]]*\[bar/([^\]+)\][[:space:]]*$|\1|p' "$config_file"
fi fi
} }
@ -72,7 +85,6 @@ _polybar() {
COMPREPLY=( $(compgen -f -X "!*.png" "$cur") ) COMPREPLY=( $(compgen -f -X "!*.png" "$cur") )
return 0 return 0
;; ;;
# TODO: read properties of the selected bar from config
-d|--dump) -d|--dump)
return 0 return 0
;; ;;

View File

@ -29,6 +29,22 @@ _polybar() {
'::bar name:_polybar_list_names' '::bar name:_polybar_list_names'
} }
(( $+functions[_polybar_default_file] )) || _polybar_default_file() {
local suffix=/polybar/config.ini
local home_path=${XDG_CONFIG_HOME:-$HOME/.config}${suffix}
local etc_xdg_path=${XDG_CONFIG_DIRS:-/etc/xdg}${suffix}
local etc_path=/etc${suffix}
if [ -r "$home_path" ]; then
echo "$home_path"
elif [ -r "$etc_xdg_path" ]; then
echo "$etc_xdg_path"
elif [ -r "$etc_path" ]; then
echo "$etc_path"
fi
}
(( $+functions[_polybar_list_names] )) || _polybar_list_names() { (( $+functions[_polybar_list_names] )) || _polybar_list_names() {
local conf local conf
if (( $+opt_args[-c] )); then if (( $+opt_args[-c] )); then
@ -36,9 +52,9 @@ _polybar() {
elif (( $+opt_args[--config] )); then elif (( $+opt_args[--config] )); then
conf=${(e)opt_args[--config]} conf=${(e)opt_args[--config]}
else else
conf=${XDG_CONFIG_HOME:-$HOME/.config}/polybar/config conf=$(_polybar_default_file)
fi fi
local names; names=(${(f)"$(sed -nr 's|\[bar/([^\]+)\]$|\1|p' ${conf} 2>/dev/null)"}) local names; names=(${(f)"$(sed -nE 's|[[:space:]]*\[bar/([^\]+)\][[:space:]]*$|\1|p' ${conf} 2>/dev/null)"})
_describe -t names 'configuration name' names _describe -t names 'configuration name' names
} }

View File

@ -58,6 +58,10 @@ install(FILES ${CMAKE_SOURCE_DIR}/CHANGELOG.md
DESTINATION ${CMAKE_INSTALL_DOCDIR} DESTINATION ${CMAKE_INSTALL_DOCDIR}
COMPONENT doc) COMPONENT doc)
install(FILES ${CMAKE_CURRENT_LIST_DIR}/config.ini
DESTINATION ${CMAKE_INSTALL_DOCDIR}/examples
COMPONENT doc)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/man/polybar.1 install(FILES ${CMAKE_CURRENT_BINARY_DIR}/man/polybar.1
DESTINATION ${CMAKE_INSTALL_MANDIR}/man1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1
COMPONENT doc) COMPONENT doc)

BIN
doc/_static/default.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

170
doc/config.ini Normal file
View File

@ -0,0 +1,170 @@
;==========================================================
;
;
; ██████╗ ██████╗ ██╗ ██╗ ██╗██████╗ █████╗ ██████╗
; ██╔══██╗██╔═══██╗██║ ╚██╗ ██╔╝██╔══██╗██╔══██╗██╔══██╗
; ██████╔╝██║ ██║██║ ╚████╔╝ ██████╔╝███████║██████╔╝
; ██╔═══╝ ██║ ██║██║ ╚██╔╝ ██╔══██╗██╔══██║██╔══██╗
; ██║ ╚██████╔╝███████╗██║ ██████╔╝██║ ██║██║ ██║
; ╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝
;
;
; To learn more about how to configure Polybar
; go to https://github.com/polybar/polybar
;
; The README contains a lot of information
;
;==========================================================
[colors]
background = #282A2E
background-alt = #373B41
foreground = #C5C8C6
primary = #F0C674
secondary = #8ABEB7
alert = #A54242
disabled = #707880
[bar/example]
width = 100%
height = 2.5%
radius = 6
background = ${colors.background}
foreground = ${colors.foreground}
line-size = 3
border-size = 4
border-color = #00000000
padding-left = 0
padding-right = 1
module-margin = 1
separator = |
separator-foreground = ${colors.disabled}
font-0 = monospace;2
modules-left = xworkspaces xwindow
modules-right = filesystem pulseaudio xkeyboard memory cpu wlan eth date
cursor-click = pointer
cursor-scroll = ns-resize
enable-ipc = true
; tray-position = right
; wm-restack = generic
; wm-restack = bspwm
; wm-restack = i3
; override-redirect = true
[module/xworkspaces]
type = internal/xworkspaces
label-active = %name%
label-active-background = ${colors.background-alt}
label-active-underline= ${colors.primary}
label-active-padding = 1
label-occupied = %name%
label-occupied-padding = 1
label-urgent = %name%
label-urgent-background = ${colors.alert}
label-urgent-padding = 1
label-empty = %name%
label-empty-foreground = ${colors.disabled}
label-empty-padding = 1
[module/xwindow]
type = internal/xwindow
label = %title:0:60:...%
[module/filesystem]
type = internal/fs
interval = 25
mount-0 = /
label-mounted = %{F#F0C674}%mountpoint%%{F-} %percentage_used%%
label-unmounted = %mountpoint% not mounted
label-unmounted-foreground = ${colors.disabled}
[module/pulseaudio]
type = internal/pulseaudio
format-volume-prefix = "VOL "
format-volume-prefix-foreground = ${colors.primary}
format-volume = <label-volume>
label-volume = %percentage%%
label-muted = muted
label-muted-foreground = ${colors.disabled}
[module/xkeyboard]
type = internal/xkeyboard
blacklist-0 = num lock
label-layout = %layout%
label-layout-foreground = ${colors.primary}
label-indicator-padding = 2
label-indicator-margin = 1
label-indicator-foreground = ${colors.background}
label-indicator-background = ${colors.secondary}
[module/memory]
type = internal/memory
interval = 2
format-prefix = "RAM "
format-prefix-foreground = ${colors.primary}
label = %percentage_used:2%%
[module/cpu]
type = internal/cpu
interval = 2
format-prefix = "CPU "
format-prefix-foreground = ${colors.primary}
label = %percentage:2%%
[network-base]
type = internal/network
interval = 5
format-connected = <label-connected>
format-disconnected = <label-disconnected>
label-disconnected = %{F#F0C674}%ifname%%{F#707880} disconnected
[module/wlan]
inherit = network-base
interface-type = wireless
label-connected = %{F#F0C674}%ifname%%{F-} %essid% %local_ip%
[module/eth]
inherit = network-base
interface-type = wired
label-connected = %{F#F0C674}%ifname%%{F-} %local_ip%
[module/date]
type = internal/date
interval = 1
date = %H:%M
date-alt = %Y-%m-%d %H:%M:%S
label = %date%
label-foreground = ${colors.primary}
[settings]
screenchange-reload = true
pseudo-transparency = true
; vim:ft=dosini

View File

@ -32,9 +32,13 @@ OPTIONS
Specify the path to the configuration file. By default, the configuration file is loaded from: Specify the path to the configuration file. By default, the configuration file is loaded from:
| * ``$XDG_CONFIG_HOME/polybar/config``
| **$XDG_CONFIG_HOME/polybar/config** * ``$XDG_CONFIG_HOME/polybar/config.ini``
| **$HOME/.config/polybar/config** * ``$HOME/.config/polybar/config``
* ``$HOME/.config/polybar/config.ini``
* ``$XDG_CONFIG_DIRS/polybar/config.ini``
* ``/etc/xdg/polybar/config.ini`` (only if ``XDG_CONFIG_DIRS`` is not set)
* ``/etc/polybar/config.ini``
.. option:: -r, --reload .. option:: -r, --reload
Reload the application when the config file has been modified Reload the application when the config file has been modified

View File

@ -35,6 +35,9 @@ places in the following order:
* ``$XDG_CONFIG_HOME/polybar/config.ini`` * ``$XDG_CONFIG_HOME/polybar/config.ini``
* ``$HOME/.config/polybar/config`` * ``$HOME/.config/polybar/config``
* ``$HOME/.config/polybar/config.ini`` * ``$HOME/.config/polybar/config.ini``
* ``$XDG_CONFIG_DIRS/polybar/config.ini``
* ``/etc/xdg/polybar/config.ini`` (only if ``XDG_CONFIG_DIRS`` is not set)
* ``/etc/polybar/config.ini``
Syntax Syntax
------ ------

View File

@ -63,6 +63,7 @@ namespace string_util {
bool contains(const string& haystack, const string& needle); bool contains(const string& haystack, const string& needle);
bool contains_ignore_case(const string& haystack, const string& needle); bool contains_ignore_case(const string& haystack, const string& needle);
bool ends_with(const string& haystack, const string& suffix);
string upper(const string& s); string upper(const string& s);
string lower(const string& s); string lower(const string& s);
bool compare(const string& s1, const string& s2); bool compare(const string& s1, const string& s2);

View File

@ -111,6 +111,13 @@ int main(int argc, char** argv) {
confpath = cli->get("config"); confpath = cli->get("config");
} else { } else {
confpath = file_util::get_config_path(); confpath = file_util::get_config_path();
if (string_util::ends_with(confpath, "config")) {
logger::make().warn(
"Naming your config file 'config' is deprecated when using the --config flag, the expected name is "
"'config.ini'.",
confpath);
}
} }
if (confpath.empty()) { if (confpath.empty()) {
throw application_error("Define configuration using --config=PATH"); throw application_error("Define configuration using --config=PATH");

View File

@ -269,30 +269,47 @@ namespace file_util {
* Search for polybar config and returns the path if found * Search for polybar config and returns the path if found
*/ */
string get_config_path() { string get_config_path() {
string confpath; const static string suffix = "/polybar/config";
if (env_util::has("XDG_CONFIG_HOME")) {
confpath = env_util::get("XDG_CONFIG_HOME") + "/polybar/config";
if (exists(confpath)) {
return confpath;
}
string iniConfPath = confpath.append(".ini"); vector<string> possible_paths;
if (exists(iniConfPath)) {
return iniConfPath; if (env_util::has("XDG_CONFIG_HOME")) {
} auto path = env_util::get("XDG_CONFIG_HOME") + suffix;
possible_paths.push_back(path);
possible_paths.push_back(path + ".ini");
} }
if (env_util::has("HOME")) { if (env_util::has("HOME")) {
confpath = env_util::get("HOME") + "/.config/polybar/config"; auto path = env_util::get("HOME") + "/.config" + suffix;
if (exists(confpath)) {
return confpath; possible_paths.push_back(path);
possible_paths.push_back(path + ".ini");
} }
string iniConfPath = confpath.append(".ini"); vector<string> xdg_config_dirs;
if (exists(iniConfPath)) {
return iniConfPath; /*
*Ref: https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
*/
if (env_util::has("XDG_CONFIG_DIRS")) {
xdg_config_dirs = string_util::split(env_util::get("XDG_CONFIG_DIRS"), ':');
} else {
xdg_config_dirs.push_back("/etc/xdg");
}
for (const string& xdg_config_dir : xdg_config_dirs) {
possible_paths.push_back(xdg_config_dir + suffix + ".ini");
}
possible_paths.push_back("/etc" + suffix + ".ini");
for (const string& p : possible_paths) {
if (exists(p)) {
return p;
} }
} }
return ""; return "";
} }

View File

@ -15,6 +15,14 @@ namespace string_util {
return haystack.find(needle) != string::npos; return haystack.find(needle) != string::npos;
} }
bool ends_with(const string& haystack, const string& suffix) {
if (haystack.length() < suffix.length()) {
return false;
}
return haystack.compare(haystack.length() - suffix.length(), suffix.length(), suffix) == 0;
}
/** /**
* Check if haystack contains needle ignoring case * Check if haystack contains needle ignoring case
*/ */

View File

@ -4,6 +4,15 @@
using namespace polybar; using namespace polybar;
TEST(String, ends_with) {
EXPECT_TRUE(string_util::ends_with("foo", "foo"));
EXPECT_TRUE(string_util::ends_with("foobar", "bar"));
EXPECT_TRUE(string_util::ends_with("foobar", ""));
EXPECT_FALSE(string_util::ends_with("foo", "bar"));
EXPECT_FALSE(string_util::ends_with("foo", "Foo"));
EXPECT_FALSE(string_util::ends_with("", "Foo"));
}
TEST(String, upper) { TEST(String, upper) {
EXPECT_EQ("FOO", string_util::upper("FOO")); EXPECT_EQ("FOO", string_util::upper("FOO"));
EXPECT_EQ("FOO", string_util::upper("FoO")); EXPECT_EQ("FOO", string_util::upper("FoO"));
@ -25,8 +34,13 @@ TEST(String, contains) {
EXPECT_TRUE(string_util::contains("fooooobar", "foo")); EXPECT_TRUE(string_util::contains("fooooobar", "foo"));
EXPECT_TRUE(string_util::contains("barrrrrrfoo", "foo")); EXPECT_TRUE(string_util::contains("barrrrrrfoo", "foo"));
EXPECT_TRUE(string_util::contains("barrfoobazzz", "foo")); EXPECT_TRUE(string_util::contains("barrfoobazzz", "foo"));
EXPECT_TRUE(string_util::contains("foo", "foo"));
EXPECT_TRUE(string_util::contains("foobar", "foo"));
EXPECT_TRUE(string_util::contains("foobar", "bar"));
EXPECT_FALSE(string_util::contains("foo", "Foo")); EXPECT_FALSE(string_util::contains("foo", "Foo"));
EXPECT_FALSE(string_util::contains("foo", "bar")); EXPECT_FALSE(string_util::contains("foo", "bar"));
EXPECT_FALSE(string_util::contains("foobar", "baz"));
EXPECT_FALSE(string_util::contains("foobAr", "bar"));
} }
TEST(String, contains_ignore_case) { TEST(String, contains_ignore_case) {