Compare commits

..

18 Commits
0.0.1 ... 0.0.2

Author SHA1 Message Date
3690e7ac55 chore: v0.0.2 2018-08-11 13:19:26 +02:00
b381e2a596 feat(battery): capacity icons 2018-08-11 13:15:31 +02:00
67fa8bd4c3 style(battery): animates background when battery is in a critical state 2018-08-11 13:03:35 +02:00
6ff296a4b0 refactor(bar): prefer standard unique_ptr 2018-08-11 12:49:28 +02:00
8d5b61a9fd refactor(bar): default width is 0 2018-08-11 10:25:21 +02:00
3c66f4baa7 feat(config): can force width 2018-08-11 09:59:35 +02:00
04183dc696 refactor(modules): prefer sigc::mem_fun 2018-08-11 02:40:13 +02:00
14053d61fc feat(workspace): catch ipc errors 2018-08-11 02:09:39 +02:00
424ebb3c9b feat(workspace): only show workspaces which are on same output as bar 2018-08-11 00:32:59 +02:00
2512d51564 fix(gtk): use idle to avoid mutex 2018-08-10 23:21:21 +02:00
95f1ab471a feat(config): add some comments 2018-08-10 18:57:46 +02:00
c792871f6e feat(bar): choose height from config file 2018-08-10 18:46:31 +02:00
8b0cdc5f4b feat(bar): choose between layers used 2018-08-10 18:30:13 +02:00
7d05f6c612 fix(bar): now use bottom layer 2018-08-10 18:25:07 +02:00
679aafa9e8 refactor(pulseaudio): remove signal init 2018-08-10 18:16:11 +02:00
9b2c551f2e fix(battery): typo 2018-08-10 18:04:48 +02:00
d728de2dd7 fix(battery): check for battries :( 2018-08-10 18:02:12 +02:00
4d3879f26f refactor: avoid useless has_class check 2018-08-10 17:05:12 +02:00
28 changed files with 193 additions and 1620 deletions

View File

@ -3,6 +3,7 @@
#include <json/json.h>
#include <gtkmm.h>
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
#include "xdg-output-unstable-v1-client-protocol.h"
namespace waybar {
@ -17,17 +18,19 @@ namespace waybar {
struct zwlr_layer_surface_v1 *layerSurface;
std::unique_ptr<struct wl_output *> output;
bool visible = true;
auto setWidth(int) -> void;
std::string outputName;
auto setWidth(uint32_t) -> void;
auto toggle() -> void;
private:
static void _handleGeometry(void *data, struct wl_output *wl_output,
int32_t x, int32_t y, int32_t physical_width, int32_t physical_height,
int32_t subpixel, const char *make, const char *model, int32_t transform);
static void _handleMode(void *data, struct wl_output *wl_output,
uint32_t f, int32_t w, int32_t h, int32_t refresh);
static void _handleDone(void *data, struct wl_output *);
static void _handleScale(void *data, struct wl_output *wl_output,
int32_t factor);
static void _handleLogicalPosition(void *data,
struct zxdg_output_v1 *zxdg_output_v1, int32_t x, int32_t y);
static void _handleLogicalSize(void *data,
struct zxdg_output_v1 *zxdg_output_v1, int32_t width, int32_t height);
static void _handleDone(void *data, struct zxdg_output_v1 *zxdg_output_v1);
static void _handleName(void *data, struct zxdg_output_v1 *xdg_output,
const char *name);
static void _handleDescription(void *data,
struct zxdg_output_v1 *zxdg_output_v1, const char *description);
static void _layerSurfaceHandleConfigure(void *data,
struct zwlr_layer_surface_v1 *surface, uint32_t serial, uint32_t width,
uint32_t height);
@ -36,10 +39,12 @@ namespace waybar {
auto _setupConfig() -> void;
auto _setupWidgets() -> void;
auto _setupCss() -> void;
int _width = 10;
uint32_t _width = 0;
uint32_t _height = 30;
Json::Value _config;
Glib::RefPtr<Gtk::StyleContext> _styleContext;
Glib::RefPtr<Gtk::CssProvider> _cssProvider;
struct zxdg_output_v1 *_xdgOutput;
};
}

View File

@ -12,9 +12,6 @@
#include <wayland-client.h>
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
#include "idle-client-protocol.h"
#include "util/ptr_vec.hpp"
#include <gdk/gdkwayland.h>
@ -23,7 +20,6 @@
namespace waybar {
struct Client {
uint32_t height = 30;
std::string cssFile;
std::string configFile;
@ -33,9 +29,9 @@ namespace waybar {
struct wl_display *wlDisplay;
struct wl_registry *registry;
struct zwlr_layer_shell_v1 *layer_shell;
struct org_kde_kwin_idle *idle_manager;
struct zxdg_output_manager_v1 *xdg_output_manager;
struct wl_seat *seat;
util::ptr_vec<Bar> bars;
std::vector<std::unique_ptr<Bar>> bars;
Client(int argc, char* argv[]);
void bind_interfaces();

View File

@ -19,6 +19,7 @@ namespace waybar::modules {
auto update() -> void;
operator Gtk::Widget&();
private:
std::string _getIcon(uint32_t percentage);
static inline const fs::path _data_dir = "/sys/class/power_supply/";
std::vector<fs::path> _batteries;
util::SleeperThread _thread;

View File

@ -3,7 +3,6 @@
#include <json/json.h>
#include <gtkmm.h>
#include <fmt/format.h>
#include <thread>
#include "util/chrono.hpp"
#include "IModule.hpp"

View File

@ -4,7 +4,6 @@
#include <gtkmm.h>
#include <fmt/format.h>
#include <sys/sysinfo.h>
#include <thread>
#include "util/chrono.hpp"
#include "IModule.hpp"

View File

@ -3,7 +3,6 @@
#include <json/json.h>
#include <gtkmm.h>
#include <fmt/format.h>
#include <thread>
#include "util/chrono.hpp"
#include "IModule.hpp"

View File

@ -4,7 +4,6 @@
#include <gtkmm.h>
#include <fmt/format.h>
#include <sys/sysinfo.h>
#include <thread>
#include "util/chrono.hpp"
#include "IModule.hpp"

View File

@ -9,7 +9,6 @@
#include <json/json.h>
#include <gtkmm.h>
#include <fmt/format.h>
#include <thread>
#include "util/chrono.hpp"
#include "IModule.hpp"

View File

@ -14,20 +14,14 @@ namespace waybar::modules {
auto update() -> void;
operator Gtk::Widget &();
private:
void _updateThread();
static void _handle_idle(void *data,
struct org_kde_kwin_idle_timeout *timer);
static void _handle_resume(void *data,
struct org_kde_kwin_idle_timeout *timer);
void _addWorkspace(Json::Value node);
Json::Value _getWorkspaces();
Bar &_bar;
util::SleeperThread *_thread;
Gtk::Box *_box;
waybar::util::SleeperThread _thread;
Gtk::Box _box;
std::unordered_map<int, Gtk::Button> _buttons;
int _ipcSocketfd;
int _ipcEventSocketfd;
struct org_kde_kwin_idle_timeout *_idle_timer;
};
}

View File

@ -1,823 +0,0 @@
#pragma once
#include <algorithm>
#include <functional>
#include <initializer_list>
#include <numeric>
#include <string>
#include <string_view>
namespace waybar::util {
/// Joins a sequence of strings, separating them using `js`
template<class StrIterator> // Models InputIterator<std::string>
std::string join_strings(StrIterator b, StrIterator e, std::string_view js = ", ")
{
std::string result;
std::for_each(b, e, [&](auto&& s) {
if (!result.empty()) {
result.append(js);
}
result.append(s);
});
return result;
}
inline const char* nonull(const char* str) {
if (str == nullptr) return "";
return str;
};
inline bool iequals(std::string_view a, std::string_view b)
{
return std::equal(a.begin(), a.end(), b.begin(), b.end(),
[](char a, char b) { return tolower(a) == tolower(b); });
}
inline bool starts_with(std::string_view prefix, std::string_view a)
{
return a.compare(0, prefix.size(), prefix) == 0;
}
inline bool ends_with(std::string_view prefix, std::string_view a)
{
return a.compare(a.size() - prefix.size(), prefix.size(), prefix) == 0;
}
/// Return a closure which compares the adress any reference to T to the address of t
template<typename T>
constexpr auto addr_eq(T&& t) {
return [&t] (auto&& t2) {
return &t == &t2;
};
}
template<typename T>
bool erase_this(std::vector<T>& cont, T* el)
{
if (el < cont.data() && el >= cont.data() + cont.size()) return false;
cont.erase(cont.begin() + (el - cont.data()));
return true;
}
template<typename T>
bool erase_this(std::vector<T>& cont, T& el)
{
return erase_this(cont, &el);
}
namespace detail {
template<class Func, int... ns>
constexpr auto generate_array_impl(std::integer_sequence<int, ns...>&&, Func&& gen)
{
return std::array<std::decay_t<decltype(std::invoke(gen, std::declval<int>()))>,
sizeof...(ns)>{{std::invoke(gen, ns)...}};
}
} // namespace detail
template<int n, class Func>
constexpr auto generate_array(Func&& gen)
{
auto intseq = std::make_integer_sequence<int, n>();
return detail::generate_array_impl(std::move(intseq), std::forward<Func>(gen));
}
namespace view {
namespace detail {
template<typename T>
using store_or_ref_t = std::conditional_t<std::is_rvalue_reference_v<T>, std::decay_t<T>, T&>;
}
template<typename Cont>
struct reverse {
reverse(Cont&& cont) noexcept : _container(std::forward<Cont>(cont)) {}
auto begin()
{
return std::rbegin(_container);
}
auto end()
{
return std::rend(_container);
}
auto begin() const
{
return std::rbegin(_container);
}
auto end() const
{
return std::rend(_container);
}
auto cbegin() const
{
return std::crbegin(_container);
}
auto cend() const
{
return std::crend(_container);
}
detail::store_or_ref_t<Cont&&> _container;
};
template<typename ContRef>
reverse(ContRef&& cont) -> reverse<ContRef&&>;
template<typename Cont>
struct constant {
constant(Cont&& cont) noexcept : _container(std::forward<Cont>(cont)){};
auto begin() const
{
return std::cbegin(_container);
}
auto end() const
{
return std::cend(_container);
}
auto cbegin() const
{
return std::cbegin(_container);
}
auto cend() const
{
return std::cend(_container);
}
detail::store_or_ref_t<Cont&&> _container;
};
template<typename ContRef>
constant(ContRef&& cont) -> constant<ContRef&&>;
} // namespace view
/*
* Range algorithms
*/
template<typename InputIt, typename Size, typename F>
constexpr InputIt for_each_n(InputIt&& first, Size n, F&& f)
{
for (Size i = 0; i < n; ++first, ++i) {
std::invoke(f, *first);
}
return first;
}
/// `for_each` with access to an index value. Function called as `f(*it, i)`
///
/// For each item in range `[first, last)`, invoke `f` with args
/// `*iter, i` where `iter` is the current iterator, and `i` is
/// an incrementing value, starting at zero. Use this instead of
/// raw indexed loops wherever possible.
///
/// \param first Input iterator to the begining of the range
/// \param last Input iterator to the end of the range
/// \param f Must be invocable with arguments `value_type`, `std::size_t`
/// \returns The number of iterations performed
template<typename InputIt, typename F>
constexpr std::size_t indexed_for(InputIt&& first, InputIt&& last, F&& f)
{
std::size_t i = 0;
std::for_each(std::forward<InputIt>(first), std::forward<InputIt>(last), [&](auto&& a) {
std::invoke(f, a, i);
i++;
});
return i;
}
template<typename Rng, typename F>
constexpr std::size_t indexed_for(Rng&& rng, F&& f)
{
return indexed_for(std::begin(rng), std::end(rng), std::forward<F>(f));
}
/// `for_each_n` with access to an index value. Function called as `f(*it, i)`
///
/// for `n` iterations, invoke `f` with args `*iter, i`
/// where `iter` is the current iterator starting with `first`,
/// and `i` is an incrementing value, starting at zero.
/// Use this instead of raw indexed loops wherever possible.
///
/// \param first Input iterator to the begining of the range
/// \param n Number of iterations to go through
/// \param f Must be invocable with arguments `value_type`, `std::size_t`
/// \returns An iterator one past the last one visited
template<class InputIt, class Size, class F>
constexpr InputIt indexed_for_n(InputIt first, Size n, F&& f)
{
for (Size i = 0; i < n; ++first, ++i) {
std::invoke(f, *first, i);
}
return first;
}
template<class Rng, class Size, class F>
constexpr std::size_t indexed_for_n(Rng&& rng, Size n, F&& f)
{
return indexed_for_n(std::begin(rng), std::end(rng), n, std::forward<F>(f));
}
template<typename Iter1, typename Iter2, typename F>
constexpr void for_both(Iter1&& f1, Iter1&& l1, Iter2&& f2, Iter2&& l2, F&& f)
{
Iter1 i1 = std::forward<Iter1>(f1);
Iter2 i2 = std::forward<Iter2>(f2);
for (; i1 != l1 && i2 != l2; i1++, i2++) {
std::invoke(f, *i1, *i2);
}
}
template<typename Rng1, typename Rng2, typename F>
constexpr void for_both(Rng1&& r1, Rng2&& r2, F&& f)
{
for_both(std::begin(r1), std::end(r1), std::begin(r2), std::end(r2), std::forward<F>(f));
}
/*
* Range based standard algorithms
*
* Thanks, chris from SO!
*/
template<typename Cont, typename T>
constexpr auto accumulate(Cont&& cont, T&& init)
{
// TODO C++20: std::accumulate is constexpr
using std::begin, std::end;
auto first = begin(cont);
auto last = end(cont);
for (; first != last; ++first) init = init + *first;
return init;
}
template<typename Cont, typename T, typename BinaryOperation>
constexpr auto accumulate(Cont&& cont, T&& init, BinaryOperation&& op)
{
// TODO C++20: std::accumulate is constexpr
using std::begin, std::end;
auto first = begin(cont);
auto last = end(cont);
for (; first != last; ++first) init = op(init, *first);
return init;
}
template<typename Cont, typename OutputIterator>
decltype(auto) adjacent_difference(Cont&& cont, OutputIterator&& first)
{
using std::begin;
using std::end;
return std::adjacent_difference(begin(cont), end(cont), std::forward<OutputIterator>(first));
}
template<typename Cont>
decltype(auto) prev_permutation(Cont&& cont)
{
using std::begin;
using std::end;
return std::prev_permutation(begin(cont), end(cont));
}
template<typename Cont, typename Compare>
decltype(auto) prev_permutation(Cont&& cont, Compare&& comp)
{
using std::begin;
using std::end;
return std::prev_permutation(begin(cont), end(cont), std::forward<Compare>(comp));
}
template<typename Cont>
decltype(auto) push_heap(Cont&& cont)
{
using std::begin;
using std::end;
return std::push_heap(begin(cont), end(cont));
}
template<typename Cont, typename Compare>
decltype(auto) push_heap(Cont&& cont, Compare&& comp)
{
using std::begin;
using std::end;
return std::push_heap(begin(cont), end(cont), std::forward<Compare>(comp));
}
template<typename Cont, typename T>
decltype(auto) remove(Cont&& cont, T&& value)
{
using std::begin;
using std::end;
return std::remove(begin(cont), end(cont), std::forward<T>(value));
}
template<typename Cont, typename OutputIterator, typename T>
decltype(auto) remove_copy(Cont&& cont, OutputIterator&& first, T&& value)
{
using std::begin;
using std::end;
return std::remove_copy(begin(cont), end(cont), std::forward<OutputIterator>(first),
std::forward<T>(value));
}
template<typename Cont, typename OutputIterator, typename UnaryPredicate>
decltype(auto) remove_copy_if(Cont&& cont, OutputIterator&& first, UnaryPredicate&& p)
{
using std::begin;
using std::end;
return std::remove_copy_if(begin(cont), end(cont), std::forward<OutputIterator>(first),
std::forward<UnaryPredicate>(p));
}
template<typename Cont, typename UnaryPredicate>
decltype(auto) remove_if(Cont&& cont, UnaryPredicate&& p)
{
using std::begin;
using std::end;
return std::remove_if(begin(cont), end(cont), std::forward<UnaryPredicate>(p));
}
template<typename Cont, typename T, typename T2>
decltype(auto) replace(Cont&& cont, T&& old_value, T2&& new_value)
{
using std::begin;
using std::end;
return std::replace(begin(cont), end(cont), std::forward<T>(old_value),
std::forward<T2>(new_value));
}
template<typename Cont, typename OutputIterator, typename T, typename T2>
decltype(auto) replace_copy(Cont&& cont, OutputIterator&& first, T&& old_value, T2&& new_value)
{
using std::begin;
using std::end;
return std::replace_copy(begin(cont), end(cont), std::forward<OutputIterator>(first),
std::forward<T>(old_value), std::forward<T2>(old_value));
}
template<typename Cont, typename OutputIterator, typename UnaryPredicate, typename T>
decltype(auto) replace_copy_if(Cont&& cont,
OutputIterator&& first,
UnaryPredicate&& p,
T&& new_value)
{
using std::begin;
using std::end;
return std::replace_copy(begin(cont), end(cont), std::forward<OutputIterator>(first),
std::forward<UnaryPredicate>(p), std::forward<T>(new_value));
}
template<typename Cont, typename UnaryPredicate, typename T>
decltype(auto) replace_if(Cont&& cont, UnaryPredicate&& p, T&& new_value)
{
using std::begin;
using std::end;
return std::replace_if(begin(cont), end(cont), std::forward<UnaryPredicate>(p),
std::forward<T>(new_value));
}
template<typename Cont>
decltype(auto) reverse(Cont&& cont)
{
using std::begin;
using std::end;
return std::reverse(begin(cont), end(cont));
}
template<typename Cont, typename OutputIterator>
decltype(auto) reverse_copy(Cont&& cont, OutputIterator&& first)
{
using std::begin;
using std::end;
return std::reverse_copy(begin(cont), end(cont), std::forward<OutputIterator>(first));
}
template<typename Cont, typename ForwardIterator>
decltype(auto) rotate(Cont&& cont, ForwardIterator&& new_first)
{
using std::begin;
using std::end;
return std::rotate(begin(cont), std::forward<ForwardIterator>(new_first), end(cont));
}
template<typename Cont, typename ForwardIterator, typename OutputIterator>
decltype(auto) rotate_copy(Cont&& cont, ForwardIterator&& new_first, OutputIterator&& first)
{
using std::begin;
using std::end;
return std::rotate_copy(begin(cont), std::forward<ForwardIterator>(new_first), end(cont),
std::forward<OutputIterator>(first));
}
template<typename Cont, typename Cont2>
decltype(auto) search(Cont&& cont, Cont2&& cont2)
{
using std::begin;
using std::end;
return std::search(begin(cont), end(cont), begin(cont2), end(cont2));
}
template<typename Cont, typename Cont2, typename BinaryPredicate>
decltype(auto) search(Cont&& cont, Cont2&& cont2, BinaryPredicate&& p)
{
using std::begin;
using std::end;
return std::search(begin(cont), end(cont), begin(cont2), end(cont2),
std::forward<BinaryPredicate>(p));
}
template<typename Cont, typename Size, typename T>
decltype(auto) search_n(Cont&& cont, Size count, T&& value)
{
using std::begin;
using std::end;
return std::search_n(begin(cont), end(cont), count, std::forward<T>(value));
}
template<typename Cont, typename Size, typename T, typename BinaryPredicate>
decltype(auto) search_n(Cont&& cont, Size count, T&& value, BinaryPredicate&& p)
{
using std::begin;
using std::end;
return std::search_n(begin(cont), end(cont), count, std::forward<T>(value),
std::forward<BinaryPredicate>(p));
}
template<typename Cont, typename Cont2, typename OutputIterator>
decltype(auto) set_difference(Cont&& cont, Cont2&& cont2, OutputIterator&& first)
{
using std::begin;
using std::end;
return std::set_difference(begin(cont), end(cont), begin(cont2), end(cont2),
std::forward<OutputIterator>(first));
}
template<typename Cont, typename Cont2, typename OutputIterator, typename Compare>
decltype(auto) set_difference(Cont&& cont, Cont2&& cont2, OutputIterator&& first, Compare&& comp)
{
using std::begin;
using std::end;
return std::set_difference(begin(cont), end(cont), begin(cont2), end(cont2),
std::forward<OutputIterator>(first), std::forward<Compare>(comp));
}
template<typename Cont, typename Cont2, typename OutputIterator>
decltype(auto) set_intersection(Cont&& cont, Cont2&& cont2, OutputIterator&& first)
{
using std::begin;
using std::end;
return std::set_intersection(begin(cont), end(cont), begin(cont2), end(cont2),
std::forward<OutputIterator>(first));
}
template<typename Cont, typename Cont2, typename OutputIterator, typename Compare>
decltype(auto) set_intersection(Cont&& cont,
Cont2&& cont2,
OutputIterator&& first,
Compare&& comp)
{
using std::begin;
using std::end;
return std::set_intersection(begin(cont), end(cont), begin(cont2), end(cont2),
std::forward<OutputIterator>(first), std::forward<Compare>(comp));
}
template<typename Cont, typename Cont2, typename OutputIterator>
decltype(auto) set_symmetric_difference(Cont&& cont, Cont2&& cont2, OutputIterator&& first)
{
using std::begin;
using std::end;
return std::set_symmetric_difference(begin(cont), end(cont), begin(cont2), end(cont2),
std::forward<OutputIterator>(first));
}
template<typename Cont, typename Cont2, typename OutputIterator, typename Compare>
decltype(auto) set_symmetric_difference(Cont&& cont,
Cont2&& cont2,
OutputIterator&& first,
Compare&& comp)
{
using std::begin;
using std::end;
return std::set_symmetric_difference(begin(cont), end(cont), begin(cont2), end(cont2),
std::forward<OutputIterator>(first),
std::forward<Compare>(comp));
}
template<typename Cont, typename Cont2, typename OutputIterator>
decltype(auto) set_union(Cont&& cont, Cont2&& cont2, OutputIterator&& first)
{
using std::begin;
using std::end;
return std::set_union(begin(cont), end(cont), begin(cont2), end(cont2),
std::forward<OutputIterator>(first));
}
template<typename Cont, typename Cont2, typename OutputIterator, typename Compare>
decltype(auto) set_union(Cont&& cont, Cont2&& cont2, OutputIterator&& first, Compare&& comp)
{
using std::begin;
using std::end;
return std::set_union(begin(cont), end(cont), begin(cont2), end(cont2),
std::forward<OutputIterator>(first), std::forward<Compare>(comp));
}
template<typename Cont, typename UniformRandomNumberGenerator>
decltype(auto) shuffle(Cont&& cont, UniformRandomNumberGenerator&& g)
{
using std::begin;
using std::end;
return std::shuffle(begin(cont), end(cont), std::forward<UniformRandomNumberGenerator>(g));
}
template<typename Cont>
decltype(auto) sort(Cont&& cont)
{
using std::begin;
using std::end;
return std::sort(begin(cont), end(cont));
}
template<typename Cont, typename Compare>
decltype(auto) sort(Cont&& cont, Compare&& comp)
{
using std::begin;
using std::end;
return std::sort(begin(cont), end(cont), std::forward<Compare>(comp));
}
template<typename Cont>
decltype(auto) sort_heap(Cont&& cont)
{
using std::begin;
using std::end;
return std::sort_heap(begin(cont), end(cont));
}
template<typename Cont, typename Compare>
decltype(auto) sort_heap(Cont&& cont, Compare&& comp)
{
using std::begin;
using std::end;
return std::sort_heap(begin(cont), end(cont), std::forward<Compare>(comp));
}
template<typename Cont, typename UnaryPredicate>
decltype(auto) stable_partition(Cont&& cont, UnaryPredicate&& p)
{
using std::begin;
using std::end;
return std::stable_partition(begin(cont), end(cont), std::forward<UnaryPredicate>(p));
}
template<typename Cont>
decltype(auto) stable_sort(Cont&& cont)
{
using std::begin;
using std::end;
return std::stable_sort(begin(cont), end(cont));
}
template<typename Cont, typename Compare>
decltype(auto) stable_sort(Cont&& cont, Compare&& comp)
{
using std::begin;
using std::end;
return std::stable_sort(begin(cont), end(cont), std::forward<Compare>(comp));
}
template<typename Cont, typename ForwardIterator>
decltype(auto) swap_ranges(Cont&& cont, ForwardIterator&& first)
{
using std::begin;
using std::end;
return std::swap_ranges(begin(cont), end(cont), std::forward<ForwardIterator>(first));
}
template<typename Cont, typename Cont2, typename F>
auto transform(Cont&& cont, Cont2&& cont2, F&& f) -> decltype(begin(cont2))
{
using std::begin;
using std::end;
return std::transform(begin(cont), end(cont), begin(cont2), std::forward<F>(f));
}
template<typename Cont, typename Iter, typename F>
decltype(auto) transform(Cont&& cont, Iter&& iter, F&& f)
{
using std::begin;
using std::end;
return std::transform(begin(cont), end(cont), std::forward<Iter>(iter), std::forward<F>(f));
}
template<typename Cont, typename Cont2, typename Cont3, typename BinaryPredicate>
auto transform(Cont&& cont, Cont2&& cont2, Cont3&& cont3, BinaryPredicate&& f)
-> decltype(begin(cont2), begin(cont3))
{
using std::begin;
using std::end;
return std::transform(begin(cont), end(cont), begin(cont2), begin(cont3),
std::forward<BinaryPredicate>(f));
}
template<typename Cont, typename InputIterator, typename Cont3, typename BinaryPredicate>
auto transform(Cont&& cont, InputIterator&& iter, Cont3&& cont3, BinaryPredicate&& f)
-> decltype(begin(cont), begin(cont3))
{
using std::begin;
using std::end;
return std::transform(begin(cont), end(cont), std::forward<InputIterator>(iter), begin(cont3),
std::forward<BinaryPredicate>(f));
}
template<typename Cont, typename Cont2, typename InputIterator, typename BinaryPredicate>
auto transform(Cont&& cont, Cont2&& cont2, InputIterator&& iter, BinaryPredicate&& f)
-> decltype(begin(cont), begin(cont2), iter)
{
using std::begin;
using std::end;
return std::transform(begin(cont), end(cont), begin(cont2), std::forward<InputIterator>(iter),
std::forward<BinaryPredicate>(f));
}
template<typename Cont, typename InputIterator, typename OutputIterator, typename BinaryOperation>
decltype(auto) transform(Cont&& cont,
InputIterator&& firstIn,
OutputIterator&& firstOut,
BinaryOperation&& op)
{
using std::begin;
using std::end;
return std::transform(begin(cont), end(cont), std::forward<InputIterator>(firstIn),
std::forward<OutputIterator>(firstOut),
std::forward<BinaryOperation>(op));
}
template<typename Cont>
decltype(auto) unique(Cont&& cont)
{
using std::begin;
using std::end;
return std::unique(begin(cont), end(cont));
}
template<typename Cont, typename BinaryPredicate>
decltype(auto) unique(Cont&& cont, BinaryPredicate&& p)
{
using std::begin;
using std::end;
return std::unique(begin(cont), end(cont), std::forward<BinaryPredicate>(p));
}
template<typename Cont, typename OutputIterator>
decltype(auto) unique_copy(Cont&& cont, OutputIterator&& first)
{
using std::begin;
using std::end;
return std::unique_copy(begin(cont), end(cont), std::forward<OutputIterator>(first));
}
template<typename Cont, typename OutputIterator, typename BinaryPredicate>
decltype(auto) unique_copy(Cont&& cont, OutputIterator&& first, BinaryPredicate&& p)
{
using std::begin;
using std::end;
return std::unique_copy(begin(cont), end(cont), std::forward<OutputIterator>(first),
std::forward<BinaryPredicate>(p));
}
template<typename Cont, typename T>
decltype(auto) upper_bound(Cont&& cont, T&& value)
{
using std::begin;
using std::end;
return std::upper_bound(begin(cont), end(cont), std::forward<T>(value));
}
template<typename Cont, typename T, typename Compare>
decltype(auto) upper_bound(Cont&& cont, T&& value, Compare&& comp)
{
using std::begin;
using std::end;
return std::upper_bound(begin(cont), end(cont), std::forward<T>(value),
std::forward<Compare>(comp));
}
template<typename Cont, typename OutputIterator>
decltype(auto) copy(Cont&& cont, OutputIterator&& first)
{
using std::begin;
using std::end;
return std::copy(begin(cont), end(cont), std::forward<OutputIterator>(first));
}
template<typename Cont, typename OutputIterator, typename UnaryPredicate>
decltype(auto) copy_if(Cont&& cont, OutputIterator&& first, UnaryPredicate&& p)
{
using std::begin;
using std::end;
return std::copy_if(begin(cont), end(cont), std::forward<OutputIterator>(first),
std::forward<UnaryPredicate>(p));
}
template<typename Cont, typename T>
decltype(auto) fill(Cont&& cont, T&& value)
{
using std::begin;
using std::end;
return std::fill(begin(cont), end(cont), std::forward<T>(value));
}
template<typename Cont, typename T>
decltype(auto) fill_n(Cont&& cont, std::size_t n, T&& value)
{
using std::begin;
using std::end;
return std::fill_n(begin(cont), n, std::forward<T>(value));
}
template<typename Cont, typename UnaryPredicate>
decltype(auto) any_of(Cont&& cont, UnaryPredicate&& p)
{
using std::begin;
using std::end;
return std::any_of(begin(cont), end(cont), std::forward<UnaryPredicate>(p));
}
template<typename Cont, typename UnaryPredicate>
decltype(auto) all_of(Cont&& cont, UnaryPredicate&& p)
{
using std::begin;
using std::end;
return std::all_of(begin(cont), end(cont), std::forward<UnaryPredicate>(p));
}
template<typename Cont, typename UnaryPredicate>
decltype(auto) none_of(Cont&& cont, UnaryPredicate&& p)
{
using std::begin;
using std::end;
return std::none_of(begin(cont), end(cont), std::forward<UnaryPredicate>(p));
}
template<typename Cont>
decltype(auto) max_element(Cont&& cont)
{
using std::begin;
using std::end;
return std::max_element(begin(cont), end(cont));
}
template<typename Cont>
decltype(auto) min_element(Cont&& cont)
{
using std::begin;
using std::end;
return std::min_element(begin(cont), end(cont));
}
template<typename Cont, typename Compare>
decltype(auto) min_element(Cont&& cont, Compare&& f)
{
using std::begin;
using std::end;
return std::min_element(begin(cont), end(cont), std::forward<Compare>(f));
}
template<typename Cont, typename Compare>
decltype(auto) max_element(Cont&& cont, Compare&& f)
{
using std::begin;
using std::end;
return std::max_element(begin(cont), end(cont), std::forward<Compare>(f));
}
template<typename Cont, typename T>
decltype(auto) find(Cont&& cont, T&& t)
{
using std::begin;
using std::end;
return std::find(begin(cont), end(cont), std::forward<T>(t));
}
template<typename Cont, typename UnaryPredicate>
decltype(auto) find_if(Cont&& cont, UnaryPredicate&& f)
{
using std::begin;
using std::end;
return std::find_if(begin(cont), end(cont), std::forward<UnaryPredicate>(f));
}
} // namespace waybar::util

View File

@ -1,581 +0,0 @@
#pragma once
#include <cassert>
#include <memory>
#include <type_traits>
#include <vector>
#include "algorithm.hpp"
namespace waybar::util {
/// An iterator wrapper that dereferences twice.
template<typename Iter>
struct double_iterator {
using wrapped = Iter;
using value_type = std::decay_t<decltype(*std::declval<typename wrapped::value_type>())>;
using difference_type = typename wrapped::difference_type;
using reference = value_type&;
using pointer = value_type*;
using iterator_category = std::random_access_iterator_tag;
using self_t = double_iterator<Iter>;
double_iterator(wrapped w) : _iter(std::move(w)) {}
double_iterator() : _iter() {}
reference operator*() const
{
return (**_iter);
}
pointer operator->() const
{
return &(**_iter);
}
self_t& operator++()
{
_iter.operator++();
return *this;
}
self_t operator++(int i)
{
return _iter.operator++(i);
}
self_t& operator--()
{
_iter.operator--();
return *this;
}
self_t operator--(int i)
{
return _iter.operator--(i);
}
auto operator==(const self_t& rhs) const noexcept
{
return _iter == rhs._iter;
}
auto operator!=(const self_t& rhs) const noexcept
{
return _iter != rhs._iter;
}
auto operator<(const self_t& rhs) const noexcept
{
return _iter < rhs._iter;
}
auto operator>(const self_t& rhs) const noexcept
{
return _iter > rhs._iter;
}
auto operator<=(const self_t& rhs) const noexcept
{
return _iter <= rhs._iter;
}
auto operator>=(const self_t& rhs) const noexcept
{
return _iter >= rhs._iter;
}
self_t operator+(difference_type d) const noexcept
{
return _iter + d;
}
self_t operator-(difference_type d) const noexcept
{
return _iter - d;
}
auto operator-(const self_t& rhs) const noexcept
{
return _iter - rhs._iter;
}
self_t& operator+=(difference_type d)
{
_iter += d;
return *this;
}
self_t& operator-=(difference_type d)
{
_iter -= d;
return *this;
}
operator wrapped&()
{
return _iter;
}
operator const wrapped&() const
{
return _iter;
}
wrapped& data()
{
return _iter;
}
const wrapped& data() const
{
return _iter;
}
private:
wrapped _iter;
};
template<typename Iter>
auto operator+(typename double_iterator<Iter>::difference_type diff, double_iterator<Iter> iter)
{
return iter + diff;
}
/// To avoid clients being moved, they are stored in unique_ptrs, which are
/// moved around in a vector. This class is purely for convenience, to still
/// have iterator semantics, and a few other utility functions
template<typename T>
struct ptr_vec {
using value_type = T;
std::vector<std::unique_ptr<value_type>> _order;
using iterator = double_iterator<typename decltype(_order)::iterator>;
using const_iterator = double_iterator<typename decltype(_order)::const_iterator>;
using reverse_iterator = double_iterator<typename decltype(_order)::reverse_iterator>;
using const_reverse_iterator =
double_iterator<typename decltype(_order)::const_reverse_iterator>;
value_type& push_back(const value_type& v)
{
auto ptr = std::make_unique<value_type>(v);
auto res = ptr.get();
_order.push_back(std::move(ptr));
return *res;
}
value_type& push_back(value_type&& v)
{
auto ptr = std::make_unique<value_type>(std::move(v));
auto res = ptr.get();
_order.push_back(std::move(ptr));
return *res;
}
value_type& push_back(std::unique_ptr<value_type> ptr)
{
auto res = ptr.get();
_order.push_back(std::move(ptr));
return *res;
}
template<typename... Args>
value_type& emplace_back(Args&&... args)
{
return push_back(std::make_unique<value_type>(std::forward<Args>(args)...));
}
std::unique_ptr<value_type> erase(const value_type& v)
{
auto iter =
std::find_if(_order.begin(), _order.end(), [&v](auto&& uptr) { return uptr.get() == &v; });
if (iter != _order.end()) {
auto uptr = std::move(*iter);
_order.erase(iter);
return uptr;
}
return nullptr;
}
iterator rotate_to_back(const value_type& v)
{
auto iter =
std::find_if(_order.begin(), _order.end(), [&v](auto&& uptr) { return uptr.get() == &v; });
return rotate_to_back(iter);
}
iterator rotate_to_back(iterator iter)
{
if (iter != _order.end()) {
{
return std::rotate(iter.data(), iter.data() + 1, _order.end());
}
}
return end();
}
iterator rotate_to_front(const value_type& v)
{
auto iter =
std::find_if(_order.begin(), _order.end(), [&v](auto&& uptr) { return uptr.get() == &v; });
return rotate_to_front(iter);
}
iterator rotate_to_front(iterator iter)
{
if (iter != _order.end()) {
{
return std::rotate(_order.begin(), iter.data(), iter.data() + 1);
}
}
return end();
}
std::size_t size() const noexcept
{
return _order.size();
}
bool empty() const noexcept
{
return _order.empty();
}
std::size_t capacity() const noexcept
{
return _order.capacity();
}
std::size_t max_size() const noexcept
{
return _order.max_size();
}
void reserve(std::size_t new_cap)
{
_order.reserve(new_cap);
}
void shrink_to_fit()
{
_order.shrink_to_fit();
}
value_type& operator[](std::size_t n)
{
return *_order[n];
}
const value_type& operator[](std::size_t n) const
{
return *_order[n];
}
value_type& at(std::size_t n)
{
return *_order.at(n);
}
const value_type& at(std::size_t n) const
{
return *_order.at(n);
}
iterator begin()
{
return _order.begin();
}
iterator end()
{
return _order.end();
}
const_iterator begin() const
{
return _order.begin();
}
const_iterator end() const
{
return _order.end();
}
reverse_iterator rbegin()
{
return _order.rbegin();
}
reverse_iterator rend()
{
return _order.rend();
}
const_reverse_iterator rbegin() const
{
return _order.rbegin();
}
const_reverse_iterator rend() const
{
return _order.rend();
}
value_type& front()
{
return *_order.front();
}
value_type& back()
{
return *_order.back();
}
const value_type& front() const
{
return *_order.front();
}
const value_type& back() const
{
return *_order.back();
}
std::vector<std::unique_ptr<value_type>>& underlying() {
return _order;
}
};
template<typename T, typename T2>
std::unique_ptr<T> erase_this(ptr_vec<T>& vec, T2* el)
{
return vec.erase(*el);
}
template<typename T, typename T2>
std::unique_ptr<T> erase_this(ptr_vec<T>& vec, T2& el)
{
return vec.erase(el);
}
template<typename T>
struct non_null_ptr {
non_null_ptr() = delete;
constexpr non_null_ptr(T* ptr) : _ptr(ptr)
{
assert(ptr != nullptr);
}
non_null_ptr(std::nullptr_t) = delete;
constexpr non_null_ptr(const non_null_ptr&) = default;
constexpr non_null_ptr(non_null_ptr&&) = default;
constexpr non_null_ptr& operator=(const non_null_ptr&) = default;
constexpr non_null_ptr& operator=(non_null_ptr&&) = default;
constexpr T& operator*() const noexcept
{
return *_ptr;
}
constexpr T* operator->() const noexcept
{
return _ptr;
}
constexpr operator T*() noexcept
{
return _ptr;
}
constexpr operator T* const() const noexcept
{
return _ptr;
}
private:
T* _ptr;
};
template<typename T>
struct ref_vec {
using value_type = T;
std::vector<value_type*> _order;
using iterator = double_iterator<typename decltype(_order)::iterator>;
using const_iterator = double_iterator<typename decltype(_order)::const_iterator>;
using reverse_iterator = double_iterator<typename decltype(_order)::reverse_iterator>;
using const_reverse_iterator =
double_iterator<typename decltype(_order)::const_reverse_iterator>;
ref_vec() = default;
ref_vec(std::initializer_list<value_type*> lst) : _order {lst} { };
template<typename InputIter, typename = std::enable_if_t<std::is_same_v<decltype(*std::declval<InputIter>()), value_type&>>>
ref_vec(InputIter iter1, InputIter iter2) {
_order.reserve(std::distance(iter1, iter2));
std::transform(iter1, iter2, std::back_inserter(_order), [] (auto& v) {return &v; });
}
template<typename Range, typename = std::enable_if_t<std::is_same_v<decltype(*std::declval<Range>().begin()), value_type&>>>
ref_vec(Range&& rng) : ref_vec (std::begin(rng), std::end(rng)) { }
value_type& push_back(value_type& v)
{
_order.push_back(&v);
return v;
}
value_type& push_back(non_null_ptr<value_type> ptr)
{
_order.push_back(ptr);
return *ptr;
}
value_type& emplace_back(value_type& v)
{
return push_back(v);
}
std::unique_ptr<value_type> erase(const value_type& v)
{
auto iter =
std::find_if(_order.begin(), _order.end(), [&v](auto&& ptr) { return ptr == &v; });
if (iter != _order.end()) {
auto uptr = std::move(*iter);
_order.erase(iter);
return uptr;
}
return nullptr;
}
iterator rotate_to_back(const value_type& v)
{
auto iter =
std::find_if(_order.begin(), _order.end(), [&v](auto&& ptr) { return ptr == &v; });
return rotate_to_back(iter);
}
iterator rotate_to_back(iterator iter)
{
if (iter != _order.end()) {
{
return std::rotate(iter.data(), iter.data() + 1, _order.end());
}
}
return end();
}
iterator rotate_to_front(const value_type& v)
{
auto iter =
std::find_if(_order.begin(), _order.end(), [&v](auto&& ptr) { return ptr == &v; });
return rotate_to_front(iter);
}
iterator rotate_to_front(iterator iter)
{
if (iter != _order.end()) {
{
return std::rotate(_order.begin(), iter.data(), iter.data() + 1);
}
}
return end();
}
std::size_t size() const noexcept
{
return _order.size();
}
bool empty() const noexcept
{
return _order.empty();
}
std::size_t capacity() const noexcept
{
return _order.capacity();
}
std::size_t max_size() const noexcept
{
return _order.max_size();
}
void reserve(std::size_t new_cap)
{
_order.reserve(new_cap);
}
void shrink_to_fit()
{
_order.shrink_to_fit();
}
value_type& operator[](std::size_t n)
{
return *_order[n];
}
const value_type& operator[](std::size_t n) const
{
return *_order[n];
}
value_type& at(std::size_t n)
{
return *_order.at(n);
}
const value_type& at(std::size_t n) const
{
return *_order.at(n);
}
iterator begin()
{
return _order.begin();
}
iterator end()
{
return _order.end();
}
const_iterator begin() const
{
return _order.begin();
}
const_iterator end() const
{
return _order.end();
}
reverse_iterator rbegin()
{
return _order.rbegin();
}
reverse_iterator rend()
{
return _order.rend();
}
const_reverse_iterator rbegin() const
{
return _order.rbegin();
}
const_reverse_iterator rend() const
{
return _order.rend();
}
value_type& front()
{
return *_order.front();
}
value_type& back()
{
return *_order.back();
}
const value_type& front() const
{
return *_order.front();
}
const value_type& back() const
{
return *_order.back();
}
std::vector<value_type*>& underlying() {
return _order;
}
};
} // namespace waybar::util

View File

@ -1,6 +1,6 @@
project(
'waybar', 'cpp', 'c',
version: '0.0.1',
version: '0.0.2',
license: 'MIT',
default_options : ['cpp_std=c++17'],
)

View File

@ -1,49 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="idle">
<copyright><![CDATA[
Copyright (C) 2015 Martin Gräßlin
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
]]></copyright>
<interface name="org_kde_kwin_idle" version="1">
<description summary="User idle time manager">
This interface allows to monitor user idle time on a given seat. The interface
allows to register timers which trigger after no user activity was registered
on the seat for a given interval. It notifies when user activity resumes.
This is useful for applications wanting to perform actions when the user is not
interacting with the system, e.g. chat applications setting the user as away, power
management features to dim screen, etc..
</description>
<request name="get_idle_timeout">
<arg name="id" type="new_id" interface="org_kde_kwin_idle_timeout"/>
<arg name="seat" type="object" interface="wl_seat"/>
<arg name="timeout" type="uint" summary="The idle timeout in msec"/>
</request>
</interface>
<interface name="org_kde_kwin_idle_timeout" version="1">
<request name="release" type="destructor">
<description summary="release the timeout object"/>
</request>
<request name="simulate_user_activity">
<description summary="Simulates user activity for this timeout, behaves just like real user activity on the seat"/>
</request>
<event name="idle">
<description summary="Triggered when there has not been any user activity in the requested idle time interval"/>
</event>
<event name="resumed">
<description summary="Triggered on the first user activity after an idle event"/>
</event>
</interface>
</protocol>

View File

@ -23,8 +23,8 @@ wayland_scanner_client = generator(
client_protocols = [
[wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'],
[wl_protocol_dir, 'unstable/xdg-output/xdg-output-unstable-v1.xml'],
['wlr-layer-shell-unstable-v1.xml'],
['idle.xml'],
]
client_protos_src = []

View File

@ -1,6 +1,12 @@
{
// "layer": "top", // Waybar at top layer
// "position": "bottom", // Waybar at the bottom of your screen
// "height": 30, // Waybar height
// "width": 1280, // Waybar width
// Choose the order of the modules
"modules-left": ["workspaces", "custom/spotify"],
"modules-right": ["pulseaudio", "network", "cpu", "memory", "battery", "clock"],
// Modules configuration
"cpu": {
"format": "{}% "
},
@ -8,7 +14,8 @@
"format": "{}% "
},
"battery": {
"format": "{}% "
"format": "{value}% {icon}",
"format-icons": ["", "", "", "", ""]
},
"network": {
"interface": "wlp2s0",

View File

@ -42,6 +42,23 @@ window {
background-color: #26A65B;
}
@keyframes blink {
to {
background-color: #ffffff;
color: black;
}
}
.battery.warning {
background: #f53c3c;
color: white;
animation-name: blink;
animation-duration: 0.5s;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-direction: alternate;
}
.cpu {
background: #2ecc71;
color: #000000;

View File

@ -5,38 +5,42 @@
#include "bar.hpp"
#include "client.hpp"
#include "factory.hpp"
#include "util/chrono.hpp"
waybar::Bar::Bar(Client &client, std::unique_ptr<struct wl_output *> &&p_output)
: client(client), window{Gtk::WindowType::WINDOW_TOPLEVEL},
output(std::move(p_output))
{
static const struct wl_output_listener outputListener = {
.geometry = _handleGeometry,
.mode = _handleMode,
static const struct zxdg_output_v1_listener xdgOutputListener = {
.logical_position = _handleLogicalPosition,
.logical_size = _handleLogicalSize,
.done = _handleDone,
.scale = _handleScale,
.name = _handleName,
.description = _handleDescription,
};
wl_output_add_listener(*output, &outputListener, this);
_xdgOutput =
zxdg_output_manager_v1_get_xdg_output(client.xdg_output_manager, *output);
zxdg_output_v1_add_listener(_xdgOutput, &xdgOutputListener, this);
window.set_title("waybar");
window.set_decorated(false);
_setupConfig();
_setupCss();
_setupWidgets();
bool positionBottom = (_config["position"] == "bottom");
if (_config["height"])
_height = _config["height"].asUInt();
bool positionBottom = _config["position"] == "bottom";
bool layerTop = _config["layer"] == "top";
gtk_widget_realize(GTK_WIDGET(window.gobj()));
GdkWindow *gdkWindow = gtk_widget_get_window(GTK_WIDGET(window.gobj()));
gdk_wayland_window_set_use_custom_surface(gdkWindow);
surface = gdk_wayland_window_get_wl_surface(gdkWindow);
layerSurface = zwlr_layer_shell_v1_get_layer_surface(
client.layer_shell, surface, *output,
(positionBottom ? ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM : ZWLR_LAYER_SHELL_V1_LAYER_TOP),
(layerTop ? ZWLR_LAYER_SHELL_V1_LAYER_TOP : ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM),
"waybar");
zwlr_layer_surface_v1_set_anchor(layerSurface,
ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT |
(positionBottom ? ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM : ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP));
zwlr_layer_surface_v1_set_size(layerSurface, _width, client.height);
zwlr_layer_surface_v1_set_size(layerSurface, _width, _height);
static const struct zwlr_layer_surface_v1_listener layerSurfaceListener = {
.configure = _layerSurfaceHandleConfigure,
.closed = _layerSurfaceHandleClosed,
@ -46,27 +50,32 @@ waybar::Bar::Bar(Client &client, std::unique_ptr<struct wl_output *> &&p_output)
wl_surface_commit(surface);
}
void waybar::Bar::_handleGeometry(void *data, struct wl_output *wl_output,
int32_t x, int32_t y, int32_t physical_width, int32_t physical_height,
int32_t subpixel, const char *make, const char *model, int32_t transform)
void waybar::Bar::_handleLogicalPosition(void *data,
struct zxdg_output_v1 *zxdg_output_v1, int32_t x, int32_t y)
{
// Nothing here
}
void waybar::Bar::_handleMode(void *data, struct wl_output *wl_output,
uint32_t f, int32_t w, int32_t h, int32_t refresh)
{
auto o = reinterpret_cast<waybar::Bar *>(data);
o->setWidth(w);
}
void waybar::Bar::_handleDone(void *data, struct wl_output *)
void waybar::Bar::_handleLogicalSize(void *data,
struct zxdg_output_v1 *zxdg_output_v1, int32_t width, int32_t height)
{
// Nothing here
}
void waybar::Bar::_handleScale(void *data, struct wl_output *wl_output,
int32_t factor)
void waybar::Bar::_handleDone(void *data, struct zxdg_output_v1 *zxdg_output_v1)
{
// Nothing here
}
void waybar::Bar::_handleName(void *data, struct zxdg_output_v1 *xdg_output,
const char *name)
{
auto o = reinterpret_cast<waybar::Bar *>(data);
o->outputName = name;
}
void waybar::Bar::_handleDescription(void *data,
struct zxdg_output_v1 *zxdg_output_v1, const char *description)
{
// Nothing here
}
@ -77,12 +86,12 @@ void waybar::Bar::_layerSurfaceHandleConfigure(
{
auto o = reinterpret_cast<waybar::Bar *>(data);
o->window.show_all();
o->setWidth(o->_config["width"] ? o->_config["width"].asUInt() : width);
zwlr_layer_surface_v1_ack_configure(surface, serial);
if (o->client.height != height)
{
height = o->client.height;
if (o->_height != height) {
height = o->_height;
std::cout << fmt::format("New Height: {}", height) << std::endl;
zwlr_layer_surface_v1_set_size(surface, width, height);
zwlr_layer_surface_v1_set_size(surface, o->_width, height);
zwlr_layer_surface_v1_set_exclusive_zone(surface, o->visible ? height : 0);
wl_surface_commit(o->surface);
}
@ -99,21 +108,21 @@ void waybar::Bar::_layerSurfaceHandleClosed(void *data,
o->window.close();
}
auto waybar::Bar::setWidth(int width) -> void
auto waybar::Bar::setWidth(uint32_t width) -> void
{
if (width == this->_width) return;
std::cout << fmt::format("Bar width configured: {}", width) << std::endl;
this->_width = width;
window.set_size_request(width);
window.resize(width, client.height);
zwlr_layer_surface_v1_set_size(layerSurface, width, 40);
window.resize(width, _height);
zwlr_layer_surface_v1_set_size(layerSurface, width, _height + 1);
wl_surface_commit(surface);
}
auto waybar::Bar::toggle() -> void
{
visible = !visible;
auto zone = visible ? client.height : 0;
auto zone = visible ? _height : 0;
zwlr_layer_surface_v1_set_exclusive_zone(layerSurface, zone);
wl_surface_commit(surface);
}

View File

@ -49,14 +49,16 @@ void waybar::Client::_handle_global(void *data, struct wl_registry *registry,
auto output = std::make_unique<struct wl_output *>();
*output = (struct wl_output *)wl_registry_bind(registry, name,
&wl_output_interface, version);
o->bars.emplace_back(*o, std::move(output));
} else if (!strcmp(interface, org_kde_kwin_idle_interface.name)) {
o->idle_manager = (org_kde_kwin_idle *)wl_registry_bind(registry, name,
&org_kde_kwin_idle_interface, version);
o->bars.emplace_back(std::make_unique<Bar>(*o, std::move(output)));
} else if (!strcmp(interface, wl_seat_interface.name)) {
o->seat = (struct wl_seat *)wl_registry_bind(registry, name,
&wl_seat_interface, version);
}
} else if (!strcmp(interface, zxdg_output_manager_v1_interface.name)
&& version >= ZXDG_OUTPUT_V1_NAME_SINCE_VERSION) {
o->xdg_output_manager =
(struct zxdg_output_manager_v1 *)wl_registry_bind(registry, name,
&zxdg_output_manager_v1_interface, ZXDG_OUTPUT_V1_NAME_SINCE_VERSION);
}
}
void waybar::Client::_handle_global_remove(void *data,

View File

@ -95,7 +95,6 @@ std::string ipc_single_command(int socketfd, uint32_t type, const char *payload,
}
struct ipc_response resp = ipc_recv_response(socketfd);
std::string response = resp.payload;
*len = resp.size;
return response;
return resp.payload;
}

View File

@ -15,7 +15,7 @@ int main(int argc, char* argv[])
waybar::client = &c;
std::signal(SIGUSR1, [] (int signal) {
for (auto& bar : waybar::client->bars) {
bar.toggle();
bar.get()->toggle();
}
});

View File

@ -14,11 +14,16 @@ waybar::modules::Battery::Battery(Json::Value config)
std::cerr << e.what() << std::endl;
}
_label.get_style_context()->add_class("battery");
if (!_batteries.size()) {
std::cerr << "No batteries." << std::endl;
return;
}
_thread = [this] {
update();
_thread.sleep_for(chrono::minutes(1));
_label.get_style_context()->add_class("battery");
int interval = _config["interval"] ? _config["inveral"].asInt() : 1;
_thread = [this, interval] {
Glib::signal_idle().connect_once(sigc::mem_fun(*this, &Battery::update));
_thread.sleep_for(chrono::seconds(interval));
};
}
@ -37,19 +42,31 @@ auto waybar::modules::Battery::update() -> void
charging = true;
}
}
if (charging == true) {
_label.get_style_context()->add_class("charging");
} else {
_label.get_style_context()->remove_class("charging");
}
auto format = _config["format"] ? _config["format"].asString() : "{}%";
_label.set_text(fmt::format(format, total / _batteries.size()));
auto value = total / _batteries.size();
_label.set_text(fmt::format(format, fmt::arg("value", value),
fmt::arg("icon", _getIcon(value))));
_label.set_tooltip_text(charging ? "Charging" : "Discharging");
if (charging)
_label.get_style_context()->add_class("charging");
else
_label.get_style_context()->remove_class("charging");
if (value < 16 && !charging)
_label.get_style_context()->add_class("warning");
else
_label.get_style_context()->remove_class("warning");
} catch (std::exception &e) {
std::cerr << e.what() << std::endl;
}
}
std::string waybar::modules::Battery::_getIcon(uint32_t percentage)
{
if (!_config["format-icons"] || !_config["format-icons"].isArray()) return "";
auto step = 100 / _config["format-icons"].size();
return _config["format-icons"][percentage / step].asString();
}
waybar::modules::Battery::operator Gtk::Widget &()
{
return _label;

View File

@ -5,7 +5,7 @@ waybar::modules::Clock::Clock(Json::Value config)
{
_label.get_style_context()->add_class("clock");
_thread = [this] {
update();
Glib::signal_idle().connect_once(sigc::mem_fun(*this, &Clock::update));
auto now = waybar::chrono::clock::now();
auto timeout =
std::chrono::floor<std::chrono::minutes>(now + std::chrono::minutes(1));

View File

@ -4,9 +4,9 @@ waybar::modules::Cpu::Cpu(Json::Value config)
: _config(config)
{
_label.get_style_context()->add_class("cpu");
_thread = [this] {
update();
int interval = _config["interval"] ? _config["inveral"].asInt() : 10;
int interval = _config["interval"] ? _config["inveral"].asInt() : 10;
_thread = [this, interval] {
Glib::signal_idle().connect_once(sigc::mem_fun(*this, &Cpu::update));
_thread.sleep_for(chrono::seconds(interval));
};
};

View File

@ -4,14 +4,13 @@
waybar::modules::Custom::Custom(std::string name, Json::Value config)
: _name(name), _config(config)
{
_label.get_style_context()->add_class("custom-" + name);
if (!_config["exec"]) {
std::cerr << name + " has no exec path." << std::endl;
return;
}
_thread = [this] {
update();
int interval = _config["interval"] ? _config["inveral"].asInt() : 30;
int interval = _config["interval"] ? _config["inveral"].asInt() : 30;
_thread = [this, interval] {
Glib::signal_idle().connect_once(sigc::mem_fun(*this, &Custom::update));
_thread.sleep_for(chrono::seconds(interval));
};
};
@ -36,9 +35,11 @@ auto waybar::modules::Custom::update() -> void
}
// Hide label if output is empty
if (output.empty())
if (output.empty()) {
_label.get_style_context()->remove_class("custom-" + _name);
_label.hide();
else {
} else {
_label.get_style_context()->add_class("custom-" + _name);
auto format = _config["format"] ? _config["format"].asString() : "{}";
_label.set_text(fmt::format(format, output));
_label.show();

View File

@ -4,9 +4,9 @@ waybar::modules::Memory::Memory(Json::Value config)
: _config(config)
{
_label.get_style_context()->add_class("memory");
_thread = [this] {
update();
int interval = _config["interval"] ? _config["inveral"].asInt() : 30;
int interval = _config["interval"] ? _config["inveral"].asInt() : 30;
_thread = [this, interval] {
Glib::signal_idle().connect_once(sigc::mem_fun(*this, &Memory::update));
_thread.sleep_for(chrono::seconds(interval));
};
};

View File

@ -4,8 +4,9 @@ waybar::modules::Network::Network(Json::Value config)
: _config(config), _ifid(if_nametoindex(config["interface"].asString().c_str()))
{
_label.get_style_context()->add_class("network");
_thread = [this] {
update();
int interval = _config["interval"] ? _config["inveral"].asInt() : 30;
_thread = [this, interval] {
Glib::signal_idle().connect_once(sigc::mem_fun(*this, &Network::update));
_thread.sleep_for(chrono::minutes(1));
};
};

View File

@ -10,8 +10,6 @@ waybar::modules::Pulseaudio::Pulseaudio(Json::Value config)
throw std::runtime_error("pa_mainloop_new() failed.");
pa_threaded_mainloop_lock(_mainloop);
_mainloop_api = pa_threaded_mainloop_get_api(_mainloop);
if (pa_signal_init(_mainloop_api) != 0)
throw std::runtime_error("pa_signal_init() failed.");
_context = pa_context_new(_mainloop_api, "waybar");
if (!_context)
throw std::runtime_error("pa_context_new() failed.");
@ -82,7 +80,7 @@ void waybar::modules::Pulseaudio::_sinkInfoCb(pa_context *context,
pa->_volume = volume * 100.0f;
pa->_muted = i->mute;
pa->_desc = i->description;
pa->update();
Glib::signal_idle().connect_once(sigc::mem_fun(*pa, &Pulseaudio::update));
}
}
@ -103,9 +101,8 @@ auto waybar::modules::Pulseaudio::update() -> void
if (_muted) {
format =
_config["format-muted"] ? _config["format-muted"].asString() : format;
if (!_label.get_style_context()->has_class("muted"))
_label.get_style_context()->add_class("muted");
} else if (_label.get_style_context()->has_class("muted"))
_label.get_style_context()->add_class("muted");
} else
_label.get_style_context()->remove_class("muted");
_label.set_label(fmt::format(format, _volume));
_label.set_tooltip_text(_desc);

View File

@ -2,96 +2,76 @@
#include "ipc/client.hpp"
waybar::modules::Workspaces::Workspaces(Bar &bar)
: _bar(bar), _thread(nullptr), _box(Gtk::manage(new Gtk::Box))
: _bar(bar)
{
_box->get_style_context()->add_class("workspaces");
std::string socketPath = get_socketpath();
_ipcSocketfd = ipc_open_socket(socketPath);
_ipcEventSocketfd = ipc_open_socket(socketPath);
const char *subscribe = "[ \"workspace\", \"mode\" ]";
uint32_t len = strlen(subscribe);
ipc_single_command(_ipcEventSocketfd, IPC_SUBSCRIBE, subscribe, &len);
_idle_timer =
org_kde_kwin_idle_get_idle_timeout(_bar.client.idle_manager,
_bar.client.seat, 10000); // 10 seconds
static const struct org_kde_kwin_idle_timeout_listener idle_timer_listener = {
.idle = _handle_idle,
.resumed = _handle_resume,
_box.get_style_context()->add_class("workspaces");
try {
std::string socketPath = get_socketpath();
_ipcSocketfd = ipc_open_socket(socketPath);
_ipcEventSocketfd = ipc_open_socket(socketPath);
const char *subscribe = "[ \"workspace\", \"mode\" ]";
uint32_t len = strlen(subscribe);
ipc_single_command(_ipcEventSocketfd, IPC_SUBSCRIBE, subscribe, &len);
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
return;
}
_thread = [this] {
Glib::signal_idle().connect_once(sigc::mem_fun(*this, &Workspaces::update));
_thread.sleep_for(chrono::milliseconds(250));
};
org_kde_kwin_idle_timeout_add_listener(_idle_timer,
&idle_timer_listener, this);
_updateThread();
}
auto waybar::modules::Workspaces::update() -> void
{
if (_bar.outputName.empty()) return;
Json::Value workspaces = _getWorkspaces();
bool hided = false;
bool needReorder = false;
for (auto it = _buttons.begin(); it != _buttons.end(); ++it) {
auto ws = std::find_if(workspaces.begin(), workspaces.end(),
[it](auto node) -> bool { return node["num"].asInt() == it->first; });
if (ws == workspaces.end()) {
it->second.hide();
hided = true;
it = _buttons.erase(it);
needReorder = true;
}
}
for (auto node : workspaces) {
auto it = _buttons.find(node["num"].asInt());
if (it == _buttons.end()) {
if (it == _buttons.end() && _bar.outputName == node["output"].asString()) {
_addWorkspace(node);
needReorder = true;
} else {
auto styleContext = it->second.get_style_context();
bool isCurrent = node["focused"].asBool();
if (styleContext->has_class("current") && !isCurrent) {
if (!isCurrent) {
styleContext->remove_class("current");
} else if (!styleContext->has_class("current") && isCurrent) {
} else if (isCurrent) {
styleContext->add_class("current");
}
if (hided) {
_box->reorder_child(it->second, node["num"].asInt() - 1);
}
if (needReorder)
_box.reorder_child(it->second, node["num"].asInt() - 1);
it->second.show();
}
}
}
void waybar::modules::Workspaces::_updateThread()
{
_thread = new waybar::util::SleeperThread([this] {
update();
_thread->sleep_for(waybar::chrono::milliseconds(150));
});
}
void waybar::modules::Workspaces::_handle_idle(void *data,
struct org_kde_kwin_idle_timeout *timer) {
auto o = reinterpret_cast<waybar::modules::Workspaces *>(data);
if (o->_thread) {
delete o->_thread;
o->_thread = nullptr;
}
}
void waybar::modules::Workspaces::_handle_resume(void *data,
struct org_kde_kwin_idle_timeout *timer) {
auto o = reinterpret_cast<waybar::modules::Workspaces *>(data);
if (!o->_thread) {
o->_updateThread();
}
}
void waybar::modules::Workspaces::_addWorkspace(Json::Value node)
{
auto pair = _buttons.emplace(node["num"].asInt(), node["name"].asString());
auto &button = pair.first->second;
_box.pack_start(button, false, false, 0);
button.set_relief(Gtk::RELIEF_NONE);
button.signal_clicked().connect([this, pair] {
auto value = fmt::format("workspace \"{}\"", pair.first->first);
uint32_t size = value.size();
ipc_single_command(_ipcSocketfd, IPC_COMMAND, value.c_str(), &size);
try {
auto value = fmt::format("workspace \"{}\"", pair.first->first);
uint32_t size = value.size();
ipc_single_command(_ipcSocketfd, IPC_COMMAND, value.c_str(), &size);
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
}
});
_box->pack_start(button, false, false, 0);
_box->reorder_child(button, node["num"].asInt() - 1);
_box.reorder_child(button, node["num"].asInt() - 1);
if (node["focused"].asBool()) {
button.get_style_context()->add_class("current");
}
@ -104,18 +84,23 @@ Json::Value waybar::modules::Workspaces::_getWorkspaces()
Json::Value root;
Json::CharReaderBuilder builder;
Json::CharReader* reader = builder.newCharReader();
std::string err;
std::string str = ipc_single_command(_ipcSocketfd, IPC_GET_WORKSPACES,
nullptr, &len);
bool res = reader->parse(str.c_str(), str.c_str() + str.size(), &root, &err);
delete reader;
if (!res) {
std::cerr << err << std::endl;
return nullptr;
try {
std::string str = ipc_single_command(_ipcSocketfd, IPC_GET_WORKSPACES,
nullptr, &len);
std::string err;
bool res =
reader->parse(str.c_str(), str.c_str() + str.size(), &root, &err);
delete reader;
if (!res) {
std::cerr << err << std::endl;
return root;
}
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
}
return root;
}
waybar::modules::Workspaces::operator Gtk::Widget &() {
return *_box;
return _box;
}