A workspace is occupied if it is not active and there is at least one window managed by the WM (`_NET_CLIENT_LIST`) that has set `_NET_WM_DESKTOP` to that workspace.
The behavior when `_NET_WM_DESKTOP` is not set is not yet clear but this is unlikely to happen since most WMs will position windows on some desktop.
Closes#874Fixes#1444Fixes#1033
* Set Desktop OCCUPIED if a window moves there
This covers more of an edge-case. I did this first by accident, it might
vanish later on.
* Replace tracking change of WS with currently used WS
* Untrack occupied workspaces
* Track windows and their desktops in pairs
* Match type of occupied_desktops with current_desktop
Because the index needs to be matched later on, type mismatches would be non-ideal.
* Recreate the occupied desktops everytime and remove duplicates
* Readd support for moving windows to other desktops
* Use less characters to empty the vector
* Rename variable storing the desktops
* Recount windows on every occasion
This alone simplifies the management and the lookup for occupation of a
workspace
* Keep track of number of windows in every workspace
* Add debugging output that shall be removed before merging
* Remove obsolete TODO
* m_client_list should always be diff'd, since the desktop may change
Therefore we update the desktop-count tally every time the client_list
changes. It may just be a desktop-change without a change of
clients.size()...
* Add more logging-spam to understand window/desktop lifecycle
* Lock event-handler to serialize handling of events
* Fix occupied workspace counting and change to bool array
Also, performance improvements when diffing new and old client lists
* Fix crash when all clients are removed
* Conform to linter and styleguide
* Shorten conditional as it is standard enough
Since this only guards against 0-divisions, it can be shortened
without risking too much confusion down the road.
* Guard against multiple threads accessing and modifying data
Fixes#1444
Modification of internal data happens through the handle-method, while
the build-method tries to access the data structures for display. Since
some modifications clear e.g. the m_viewports, references may become
invalid between looping over them an accessing them.
The mutex should guard against this simultanuous access.
* Do not 'adopt_lock', because calls come from very different threads
To my understanding, adopt_lock has some dependency on the mutex-ownership. Since
the lock is once called from the inside (in handle) and once from the outside (in
build), there might be a problem. After brief testing, the segfaults happened fewer
times.
See #1444
* Also listen to _NET_WM_DESKTOP
In order to move a window from one desktop to another, it is sufficient
to set the desktop-property of that window. xmonad fires a lot of events
in the case of moving a window, herbstluftwm only updates the
_NET_WM_DESKTOP-atom of the window.
This change reloads the clientlist in order to correctly set the
desktop state "occupied".
* Describe need and use of mutex
It might be possible to relieve the guard in xworkspaces_module::handle,
but I am unsure about this. Since xmonad emits a lot of events on almost
every minor change, I would let the guard keep its post, avoiding
race-conditions in event-handling.
* Give temporary variables better names
* Clarify purpose of loop
About 80% of this comment are taken from
https://github.com/jaagr/polybar/pull/882#discussion_r255317363
* Remove merge-remainder
* Use a simpler method to list occupied desktops.
Co-authored-by: Jérôme Boulmier <jerome.boulmier@outlook.fr>
* Document m_clients field
While an update was forced whenever polybar was made visible, the
`m_lastinput` variable was still set to the same value as when the bar
became hidden because updates to it were prevented.
Fixes#1875
This fixes a regression introduced in
56e24992df where relative config file
paths weren't recognized because file_util::expand just added a slash
to the beginning.
That is calling `polybar -c config example` would try to load the config
file at `/config` instead of using the relative path as before.
In all other cases where expand is used this change shouldn't matter
because polybar only accepts absolute paths everyhwere else.
Theoretically this would now allow relative paths (relative to the cwd
where polybar was called) but this shouldn't used (or documented)
because that behavior will change when merging #1523 which would make
paths relative to the polybar config.
Ref #1523
Ref 56e24992df
The %{PR} tag is introduced for this. It resets all colors as well as
the activation of the underline and overline and font.
This has become necessary because we don't track what raw tags a user
injects into the formatting string and otherwise their raw tags could
bleed through.
This doesn't touch action tags because even before raw action tags
weren't being tracked. Action tags also have the requirement that they
have to be used in pairs, so closing them prematurely could break things
(for example with click actions for the entire bar)
When adding a string to the builder directly, it would parse the string
for formatting tags, delete them and readd them with the methods in the
builder that keep track of open tags so that we can properly close them
when flushing.
This parser has a bug, it parses multiple formatting tags in a single
block as a single tag, e.g.
%{F#000000 u#FFFFFF +u}
would be parsed as an `F` tag with value `#000000 u#FFFFFF +u` which is
of course wrong.
Removing the parsing step fixes this problem in the simplest way
possible. This has two benefits:
* Building of modules is sped up because we don't have to do the parsing
step in the builder and many modules use this function to add strings
from a progressbar (which already has properly closed tags).
* We don't have parser logic in two places. Until now both `parser.cpp`
and `builder.cpp` actually parsed formatting tags. This leads to a lot
of code duplication and, as we've seen, bugs.
All of the modules that use this function to add text already make sure
that they properly close formatting tags (mostly by using the builder to
generate the strings)
NOTE: This change slightly changes polybar's behavior. Raw tags (tags
added by the user through the config) can now have their effects reach
neighboring modules because the builder doesn't track and thus doesn't
close them on each flush. This can (and will) be resolved by resetting
all tags at module borders.
Fixes#1555
There really is no reason to also close over/underline tags when we have
a right margin and a non-black over/underline color.
The git blame for these lines also doesn't give us any insights as to
why it was done this way.
Using a bit vector to track the active attributes does not really give a
significant speed increase, especially for only two attributes
Checking if a syntaxtag or an attribute exists in the map just adds
unnecessary code
Was around since the first commit but no documentation why. It was only
used in the text module and doesn't appear in any public documentation,
so this doesn't break anything.
This is the next step to merge #1237 in stages.
Currently there are barely any restrictions on how the config can be
written. This causes things like config files with DOS line endings to
not be parsed properly (#1366) because polybar splits by `\n` and when
parsing section headers, it can't deal with the `\r` at the end of the
line and thus doesn't recognize any section headers.
With this PR we introduce some rules as to what characters are allowed
in section names and keys.
Note: When talking about spaces I refer to any character for which
`isspace()` returns `true`.
The rules are as follows:
* A section name or a key name cannot contain any spaces as well as any
of there characters:`"'=;#[](){}:.$\%`
* Spaces at the beginning and end of lines are always ignored when
parsing
* Comment lines start with `;` or `#` and last for the whole line. The
whole line will be ignored by the parser. You cannot start a comment at
the end of a line.
* Section headers have the following form `[HEADER_NAME]`
* Key-value lines look like this:
`KEY_NAME{SPACES}={SPACES}VALUE_STRING` where `{SPACES}` represents any
number of spaces. `VALUE_STRING` can contain any characters. If it is
*surrounded* with double quotes (`"`), those quotes will be removed,
this can be used to add spaces to the beginning or end of the value
* Empty lines are lines with only spaces in them
* If the line has any other form, it is a syntax error
This will introduce the following breaking changes because of how
underdefined the config syntax was before:
* `key = ""` will get treated as an empty string instead of the literal
* string `""`
* Any section or key name with forbidden characters will now be syntax
errors.
* Certain strings will be forbidden as section names: `self`, `root`,
* `BAR`. Because they have a special meaning inside references and so a
* section `[root]` can never be referenced.
This replaces the current parser implementation with a new more robust
one that will later be expanded to also check for dependency cycles and
allow for values that contain references mixed with other strings.
This PR also now expands the config paths given over the command line so
that `--config=~/.config/polybar/config` resolves properly.
Closes#1032Closes#1694
* config_parser: Add skeleton with tests
First step in the config_parser develoment. Only tests functions that
are easily testable without many outside dependencies. Integration tests
will follow.
* config_parser: Implement parse_header
* config_parser: Implement get_line_type
* feat(string): Add trim functions with predicate
Not only trimming based on single character matching but based on a
freely specifiable predicate. Will be used to trim all spaces (based on
isspace)
* config_parser: Implement parse_key
* config_parser: Implement parse_line for valid lines
* config_parser: Throw exception on invalid lines
* config_parser: Remove line_no and file_index from parse_line
Cleaner to let the caller catch and fill in the line number and file
path
* string: Clear up misleading description of trim
Before, trim would remove all characters that *didn't* match the
predicate and thus the predicate isspace wouldn't work correctly. But
because we used the inverse (isnospace_pred) it all worked out, but if
the function was used with any other function, it wouldn't have given
the desired output
* config_parser: Implement parse_file
* config_parser: Switch operation to config_parser
This changes the way the config is invoked. Now main.cpp creates a
config_parser object which then returns the singleton config object from
the parse method. Subsequent calls to config::make will return the
already created config object as before
The config_parser does not yet have all the functionality of the old
parser: `inherit` directives are not yet resolved. Other than that all
the old functionality is implemented (creating sectionmap and applying
include-file)
Any sort of dependency detection (except for include-file) are still
missing
* config: Move xrm initialization to constructor
config_parser handles the detection of xrdb references and passes that
info to the config object.
This finally allows us to delete the config::parse_file function because
everything in it has been implemented (except for xrdb detection and
file error handling)
* refactor(config_parser): Cleanup
* config_parser: Set config data after initialization
Looks much cleaner this way
* config_parser: Expand include-file paths
* config_parser: Init xrm if the config uses %{xrdb references
* config_parser: Use same type of maps as in old impl
Polybar has some weird, not yet fixed, inheriting behaviour and it
changes depending on the order in which the config stores its data.
Using the same type of maps ensures that the behaviour stays the same.
* refactor(config_parser): Clearer invalid name error message
* config_parser: Don't allow reserved section names
Sections with the names 'self', 'BAR', 'root' could never be referenced
because those strings have a special meaning inside references
* config_parser: Handle inherit directives
This uses the old copy_inherited function, so this still suffers from
crashes if there are cyclic dependencies.
This also fixes the behaviour where any key that starts with 'inherit'
would be treated as an inherit directive
* config_parser: Clearer dependency cycle error message
* refactor(config_parser): Handle file errors when parsing
This removes the need to check if the file exists separately
* fix(config): expand config file path
Now paths using ~ and environment variables can be used as the config
path
* fix(config): Properly recognize xrdb references
* config_parser: Make messages more informative
* doc(config): Improve commenting
Comments now describe what the config_parser actually does instead of
what it will do.
We also now follow the rule that single line comments inside functions
should use `//` comments
* refactor: Move else on same line as curly braces
* fix(config_parser): Don't duplicate paths in `files`
* refactor(config_parser): Use else if for clarity
* fix(config): Undefined behavior in syntax_error
Before the custom what() method produced undefined behavior because the
returned string became invalid once the function returned.
* refactor(config): descriptive name for useless lines
is_valid could easily be confused as meaning syntactically invalid
without it being clarified in a comment
* refactor(config): Use separate strings instead of key_value
Takes just as much space and is much better to read
* fix(config_parser): TestCase -> TestSuite and fix macro call
Ref: #1644
* config_parser: use const string& in method args
* config_parser: Improve comments
* config_parser: Incorporate review comments
Previously, when volume was in close proximity to n_max_volume, a larger
increase would not do anything. After this patch, volume is set to
m_max_volume in such scenarios. If the volume already is at
n_max_volume, we mirror the old behavior and emit a warning.
So, for example, consider m_max_volume was 100%, but the volume prior
to the increase was 96%. An increase of 5% would do nothing (emit a
warning, even) instead of setting the volume to 100%.
Note that this might happen even if the volume is at 95% according to
%percentage% due to rounding errors.
Displays real percentage instead of being set to 100 if percentage > full-at
* battery: added percentage_raw token, which ignores full-at
* battery: current_percentage returns raw, added clamping function instead
* battery: clamp percentage used by build()
Made clamp_percentage() const to allow its usage inside build()
* battery: read and return percentage in one line
Fixes compilation under GCC 9
The default copy constructor implicit generation is deprecated by C++ standard.
The window& operator=(const xcb_window_t win); operator seems to be useless.
Fixes#1728
Ref jaagr/xpp#16
We need to have the version string available in multiple places not just
the source code. It is now hardcoded in the root CMakeLists.txt and all
files that need it will be configured with cmake.
This also removed the unecessary duality of GIT_TAG and APP_VERSION and
GIT_TAG_NAMESPACE and APP_VERSION_NAMESPACE.
To avoid polybar from being killed by SIGUSR1 during reloading, SIGUSR1 is ignored until the signal is registered in the new polybar process.
As stated in signal(7) man page, the ignored signals are still ignored after a call to a function of the execvX family.
During an execve(2), the dispositions of handled signals are reset to the default;
the dispositions of ignored signals are left unchanged.
Fixes#428
* `layout-icon-*` list that maps layouts to icons.
* `indicator-icon-*` list that maps indicators to off and on icons
* `label-indicator-off`
* `label-indicator-on` which replaces the now deprecated `label-indicator`
* `label-indicator-[on|off]-*` for each indicator. Overrides `label-indicator-on` and `label-indicator-off`
Fixes#1558Closes#1048
* add icon support for xkeyboard layouts
* removed unneeded #include
* add sperate %icon% token that can be used in <label-layout>
* removed unneeded #include
* added caps lock indicator (was mentioned in wiki, but not actually implememnted) and support for indicator icons
* a few more fixes to make sure existing user configs are not broken
* ready to go
* Added an option to replace xkb indicator names
* Added labels for each indicator state
* Removed print left on accident
* Fixed review comments
* Update src/modules/xkeyboard.cpp
Co-Authored-By: Gilnaa <gilad@naaman.io>
Polybar had issues when there is no background set or set by a tool like imagemagick which doesn't add the root pixmap to the root window properties.
There's not much we can do about it, but at least polybar doesn't crash anymore.
Fixes#1582Fixes#1585
* fix(tray_manager): only enable transparency if neccessary
Previously, we always enabled transparency
* fix(background_manager): avoid needless fetching
* fix(renderer): move logging message to correct place
* fix(background_manager): handle dummy pixmap (_XSETROOT_ID) right
* fix(background_manager): more initialization + don't free on error
Freeing on error is incorrect, since we could still be called again later in
which case we still need the resources.
* fix(background_manager): add more infos to trace logs
* fix(background): correct typo (XROOTMAP -> XROOTPMAP)
* fix(background_manager): do not report "no background" as error
* style(background_manager): use braces for if
Co-Authored-By: bennofs <benno.fuenfstueck@gmail.com>
* fix(background_manager): better error message for dummy pixmap
Co-Authored-By: bennofs <benno.fuenfstueck@gmail.com>
* style(background): some more style fixes
* fix(connection): initialize pixmap in all cases in root_pixmap()
* style(connection): improve readability using early return
This adds `monitor-exact = true` in the bar section
This also properly does best-match instead of first-match if multiple
matches exists. For example if there are two monitors HDMI2 and HDMI-2
and we try to match HDMI-2 with monitor-exact = false, until now HDMI2
would be matched. Now exact matches are always preferred.
Fixes#1532
This adds a new label in the bspwm module `label-marked`
This flag for focused nodes of a focused desktop was introduced in [1]
and released with bspwm 0.9.4
It adds the `M` flag to `G` type items in bspwm's report format
Resolves#1552
[1]: d0138af475
This patch adds support for observing multiple slices of the desktop background.
This is used for the tray so that it doesn't have to rely on the bar's rect to
get the desktop background. In particular, it now handles the case where the
tray is not contained fully within the bar's outer rect (for example, when using tray-offset-{x,y})
Co-Authored-By: bennofs <benno.fuenfstueck@gmail.com>
* Clean up CMake logic
- removed logic to find CppUnit (no longer used)
- removed "dirs" variable used to pass include directories
- removed add_library function (no longer used)
- removed make_executable function
* only used in 2 places (polybar and polybar-msg)
* it was more general than needed, logic is simpler without it
- split polybar into static library and executable
* this allows linking unit tests to the library
* rename library
* add coverage build
- Added a CMake build type "Coverage" that builds C and C++
code with the "--coverage" flag (recognized by both GCC and Clang)
- removed "-Wno-missing-field-initializers" from test flags,
since it didn't seem to be needed any more
- removed logic from tests/CMakeLists to disable "-Werror" and "-pedantic-errors"
since there didn't seem to be any warnings during the build
* fix whitespace
* update travis
* remove O2 from defalt flags
* allow tests to be built by default make target
* disable Werror for debug builds
wireless_tools 29 redefines inline in iwlib.h as:
#define inline inline __attribute__((always_inline))
which conflicts with POLYBAR_NS, which is defined as:
#define POLYBAR_NS \
namespace polybar { \
inline namespace APP_VERSION_NAMESPACE {
In version 30.pre9 this #define is moved into a source file and thus
cannot conflict.
The error only occurs when building with clang, so it seems gcc and
clang handle this differently
Fixes#1492
If a tailed command is used polybar would generate two action tags, one
with %counter% replaced and one with %pid% replaced, but never both
This is a bug that was introduced in #934
The idea is that pseudo-transparency should behave like real transparency as
much as possible. To achieve this, we now render the bar the same way in both
cases. The only part where pseudo-transparency differs is at the very end, where
the rendered bar is captured and composited against the desktop background
image. This should ensure that both modes behave the same.
This reverts some behaviour differences introduced by the pseudo-transparency
implementation. The new implementation is much closer to the
non-pseudo-transparent case and thus keeps original behaviour.
For the new method we simply fill the bar with the background image fetched from
the root window if in pseudo-transparent mode, otherwise we do nothing. This
means that everything will work as in the fully-transparent mode.
We need to use positions relative to the position of the bar for indexing into
the background image slice, but the code used absolute ones.
This worked fine as long as absolute positions are the same as relative
positions (this is the case for a bar located at (0,0), so if bottom = false).
But for bottom bars (where the bar position is not (0,0)) this was wrong which
caused the tray background to be black (out of bounds for the background slice).
The systray only supports pseudo transparency (real transparency would require
much larger changes) so the real transparency should only be used for the bar itself.
This option is no longer necessary because the tray background color can now
simply be set to any (semi-)transparent color (just like the bar background).
We now take the bar position that the window manager gives us instead of trying
to calculate it ourselves. This is more correct when multiple bars are attached
to the same edge, as the window manager may move some of them in that
case (assuming override redirect is not enabled)
We need to fetch the outer area from the root window, not just the inner area
because we paint the background below the borders as well.
This has the nice effect of supporting semi-transparency for borders as well.
Now all the tokens in the memory module also have ramp and bar counterparts.
These can be used exactly the same as `bar-used` and `ramp-used`, they are named `<bar-swap-used>`, `<bar-swap-free>`, `<ramp-swap-used>`, and `<ramp-swap-free>`
Trimming the quotes in labels and the date module are not needed at all,
because surrounding quotes are removed when loading the values from the
config.
Removing the quotes in the builder also doesn't seem to serve any
purpose at all.
The check of the maxlen and ellipsis condition was also moved to the
label creation, this way get_label_text doesn't need to care about the
restrictions placed on maxlen and ellipsis
The repeatone button doesn't influence repeating behaviour at all, so
the name is misleading.
This deprecates icon-repeatone for now, until we can completely remove
it
Fixes#1279
This patch enables support for nl80211. In case the libnl-genl-3.0
library isn't found, it will fall back to Wext instead.
The library to use can also be manually set with the CMake option
WITH_LIBNL.
The Wireless-Extensions (WE or Wext) are deprecated and long replaced
by cfg80211.
Although Wext isn't used by WiFi drivers anymore, CFG80211_WEXT allows
old tools to communicate with modern drivers by providing a wrapper
API.
The only reason polybar couldn't build without xkb is because the
xkeyboard module's source file was not removed during compilation.
xkeyboard already has an entry in unsupported.hpp
This effectively makes xcb-util-xkb optional
When xrm was disabled, main.cpp was missing the complete defintion of
connection from connection.hpp, which was included xresources.hpp when
xrm was enabled.
It's queried the same way ipv4 addresses are queried, but here it displays globally routable addresses. If there are multiple such addresses, it picks one (same as with ipv4). It's possible that an address discovered this way is not in fact globally reachable but still marked as global.
Using brace initialization here causes bar.hpp to not compile when
included on its own, forcing all clients to also include
tray_manager.hpp and so on, which defeats the purpose of forward
declaring those classes.
This also allows us to remove the tray_manager.hpp, renderer.hpp and
parser.hpp includes from the clients of bar.hpp
As mentioned in #1215, gcc >=8 will complain, if strncpy truncates the
source string or gcc can prove there is no NUL terminating byte.
This also updates the i3ipcpp submodule where there was a similar error
Fixes#1215
atoi, atof and so on have undefined behavior if anything goes wrong. We
now use strto*, but without error checking. In most places overflows and
the like *should* not happen. String to number conversions are only used
when reading data from other applications or from the config, if another
application gives unparsable strings or too large numbers, then most
likely there is something wrong with that application. If the error
comes from the user config, then the user has to live with values
provided by strto* on error (which are very reasonable)
Fixes#1201
There have now been several instances of people reporting that their
bars are not found and polybar not printing the config file name because
the error is thrown first, making it very difficult to debug
Before, polybar would crash, trying to throw a server error because
mpd_connection_get_server_error asserts that the error is of type server
error, but it isn't because it was cleared
When using the same token multiple times in the same label with
different length properties, polybar would always use the settings for
the first token. This now replaces the tokens one by one, so that a new
token object is used for the length settings each time a token is used
again. Because the token objects are added in order, the replacement
always uses the right token object for the token that is replaced.
Fixes#971
Only updating when an mpd event occurred would cause issues when mpd was
playing and the machine was put to sleep because the elapsed time was
calculated by taking the time difference of the last update and now
which would give you wrong numbers, if the machine was in standby in
between.
Since the update function on the module is only called once a second (or
when an event happens), we can just update the data every time without a
huge performance hit.
Fixes#915
Fixes#759 by only drawing text background when its color is different from the background color of the bar itself.
Explicitly setting a module's background to `background-0` now stops working.
For nested actions, the inner action should override the outer action.
But because the list of actions was not iterated in reverse the outer
action was matched first.
Fixes#760
The changes introduced in 389bae2669 to
address #551 did not consider the left border
Now center modules are centered regardless of border (left or right)
settings or tray position
Fixes#672
expand-right defaults to true to preserve the current functionality
If set to false, the items in the menu will be added to the left of the
toggle label (instead of the right side)
Should resolve the issue discussed in #655
Curl removed that header in 73a2fcea0b4adea6ba342cd7ed1149782c214ae3
([1])
http.cpp doesn't use anything from that header and compilation works for
fine with curl 7.54.1
Fixes#647
Ref:
[1]: 73a2fcea0b
When focusing a desktop with the urgent flag, two events are received
from `bspc` simultaneously, separated by a newline character.
This was not handled correctly and the second event was discarded causing
the urgent style to be removed, but the focused style would remain on the
previously focused desktop.
This fixes the problem by handling any number of events that arrive at the
same time (separated by newlines).
This helps ensure that when a string is truncated it is not done in the
middle of a utf8 multi-byte sequence. This doesn't 100% correspond to
user-perceived characters, but it should be pretty close in most cases.
Since 3.4, `/proc/meminfo` contains a `MemAvailable` field, which polybar uses to determine
`(gb|mb)_free` and `(gb|mb)_used`. This commit adds a fallback for when `MemAvailable` does
not exist, allowing a fairly-accurate approximation on older kernels.
This commit also removes the reliance on the exact order fields appear in `/proc/meminfo`.
This tries to mimic the old renderer's behavior as closely as possible.
In the absence of any information, DPI is assumed to be 96x96. DPI can
be configured on a per-bar basis using the configuration key "dpi".
To use the DPI configuration from Xresources (if built with support),
one can specify the following in the bar config:
dpi = ${xrdb:Xft.dpi:96}
This fixes a "bug" where polybar wouldn't reload on a configuration
file change on some configurations of vim, which don't actually issue
any IN_MODIFY events because they choose to move the file, replace it
with a new one, and then delete the file instead.
To work around this, we now also listen for IN_IGNORED which fires when
the file we are watching is destroyed. When this happens, we re-attach
the configuration file watcher to the new file and reload.
Added support for fuzzy matching workspace names when assigning icons.
This feature is enabled/disabled through a new option, 'fuzzy-match'.
It is disabled by default.