Merge branch 'master' into river-tags-monitor-focus
This commit is contained in:
@@ -16,4 +16,5 @@ jobs:
|
||||
with:
|
||||
source: "."
|
||||
extensions: "hpp,h,cpp,c"
|
||||
clangFormatVersion: 16
|
||||
style: "file:.clang-format"
|
||||
clangFormatVersion: 19
|
||||
|
||||
@@ -8,6 +8,7 @@ on:
|
||||
jobs:
|
||||
build-and-push:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'Alexays/Waybar'
|
||||
strategy:
|
||||
fail-fast: false # don't fail the other jobs if one of the images fails to build
|
||||
matrix:
|
||||
|
||||
@@ -14,18 +14,17 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Test in FreeBSD VM
|
||||
uses: cross-platform-actions/action@v0.23.0
|
||||
uses: cross-platform-actions/action@v0.25.0
|
||||
timeout-minutes: 180
|
||||
env:
|
||||
CPPFLAGS: '-isystem/usr/local/include'
|
||||
LDFLAGS: '-L/usr/local/lib'
|
||||
with:
|
||||
operating_system: freebsd
|
||||
version: "13.2"
|
||||
version: "14.1"
|
||||
environment_variables: CPPFLAGS LDFLAGS
|
||||
sync_files: runner-to-vm
|
||||
run: |
|
||||
sudo sed -i '' 's/quarterly/latest/' /etc/pkg/FreeBSD.conf
|
||||
sudo pkg install -y git # subprojects/date
|
||||
sudo pkg install -y catch evdev-proto gtk-layer-shell gtkmm30 jsoncpp \
|
||||
libdbusmenu libevdev libfmt libmpdclient libudev-devd meson \
|
||||
|
||||
@@ -9,6 +9,7 @@ on:
|
||||
jobs:
|
||||
lockfile:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name != 'schedule' || github.repository == 'Alexays/Waybar'
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 Alex
|
||||
Copyright (c) 2025 Alex
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
- Sway (Workspaces, Binding mode, Focused window name)
|
||||
- River (Mapping mode, Tags, Focused window name)
|
||||
- Hyprland (Window Icons, Workspaces, Focused window name)
|
||||
- DWL (Tags, Focused window name) [requires dwl ipc patch](https://github.com/djpohly/dwl/wiki/ipc)
|
||||
- Niri (Workspaces, Focused window name, Language)
|
||||
- DWL (Tags, Focused window name) [requires dwl ipc patch](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/ipc)
|
||||
- Tray [#21](https://github.com/Alexays/Waybar/issues/21)
|
||||
- Local time
|
||||
- Battery
|
||||
|
||||
Generated
+6
-6
@@ -3,11 +3,11 @@
|
||||
"flake-compat": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1696426674,
|
||||
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
|
||||
"lastModified": 1733328505,
|
||||
"narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=",
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
|
||||
"rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -18,11 +18,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1719506693,
|
||||
"narHash": "sha256-C8e9S7RzshSdHB7L+v9I51af1gDM5unhJ2xO1ywxNH8=",
|
||||
"lastModified": 1740560979,
|
||||
"narHash": "sha256-Vr3Qi346M+8CjedtbyUevIGDZW8LcA1fTG0ugPY/Hic=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "b2852eb9365c6de48ffb0dc2c9562591f652242a",
|
||||
"rev": "5135c59491985879812717f4c9fea69604e7f26f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
+4
-1
@@ -16,13 +16,15 @@ class AModule : public IModule {
|
||||
|
||||
~AModule() override;
|
||||
auto update() -> void override;
|
||||
virtual auto refresh(int shouldRefresh) -> void{};
|
||||
virtual auto refresh(int shouldRefresh) -> void {};
|
||||
operator Gtk::Widget &() override;
|
||||
auto doAction(const std::string &name) -> void override;
|
||||
|
||||
/// Emitting on this dispatcher triggers a update() call
|
||||
Glib::Dispatcher dp;
|
||||
|
||||
bool expandEnabled() const;
|
||||
|
||||
protected:
|
||||
// Don't need to make an object directly
|
||||
// Derived classes are able to use it
|
||||
@@ -50,6 +52,7 @@ class AModule : public IModule {
|
||||
private:
|
||||
bool handleUserEvent(GdkEventButton *const &ev);
|
||||
const bool isTooltip;
|
||||
const bool isExpand;
|
||||
bool hasUserEvents_;
|
||||
std::vector<int> pid_;
|
||||
gdouble distance_scrolled_y_;
|
||||
|
||||
+3
-3
@@ -42,7 +42,7 @@ struct bar_margins {
|
||||
};
|
||||
|
||||
struct bar_mode {
|
||||
std::optional<bar_layer> layer;
|
||||
bar_layer layer;
|
||||
bool exclusive;
|
||||
bool passthrough;
|
||||
bool visible;
|
||||
@@ -54,7 +54,7 @@ class BarIpcClient;
|
||||
}
|
||||
#endif // HAVE_SWAY
|
||||
|
||||
class Bar {
|
||||
class Bar : public sigc::trackable {
|
||||
public:
|
||||
using bar_mode_map = std::map<std::string, struct bar_mode>;
|
||||
static const bar_mode_map PRESET_MODES;
|
||||
@@ -66,7 +66,7 @@ class Bar {
|
||||
~Bar();
|
||||
|
||||
void setMode(const std::string &mode);
|
||||
void setVisible(bool visible);
|
||||
void setVisible(bool value);
|
||||
void toggle();
|
||||
void handleSignal(int);
|
||||
|
||||
|
||||
@@ -20,6 +20,9 @@ class Config {
|
||||
static std::optional<std::string> findConfigPath(
|
||||
const std::vector<std::string> &names, const std::vector<std::string> &dirs = CONFIG_DIRS);
|
||||
|
||||
static std::vector<std::string> tryExpandPath(const std::string &base,
|
||||
const std::string &filename);
|
||||
|
||||
Config() = default;
|
||||
|
||||
void load(const std::string &config);
|
||||
|
||||
+5
-1
@@ -12,7 +12,7 @@ namespace waybar {
|
||||
class Group : public AModule {
|
||||
public:
|
||||
Group(const std::string &, const std::string &, const Json::Value &, bool);
|
||||
virtual ~Group() = default;
|
||||
~Group() override = default;
|
||||
auto update() -> void override;
|
||||
operator Gtk::Widget &() override;
|
||||
|
||||
@@ -25,9 +25,13 @@ class Group : public AModule {
|
||||
Gtk::Revealer revealer;
|
||||
bool is_first_widget = true;
|
||||
bool is_drawer = false;
|
||||
bool click_to_reveal = false;
|
||||
std::string add_class_to_drawer_children;
|
||||
bool handleMouseEnter(GdkEventCrossing *const &ev) override;
|
||||
bool handleMouseLeave(GdkEventCrossing *const &ev) override;
|
||||
bool handleToggle(GdkEventButton *const &ev) override;
|
||||
void show_group();
|
||||
void hide_group();
|
||||
};
|
||||
|
||||
} // namespace waybar
|
||||
|
||||
@@ -23,11 +23,11 @@ class Cava final : public ALabel {
|
||||
util::SleeperThread thread_;
|
||||
util::SleeperThread thread_fetch_input_;
|
||||
|
||||
struct cava::error_s error_ {}; // cava errors
|
||||
struct cava::config_params prm_ {}; // cava parameters
|
||||
struct cava::audio_raw audio_raw_ {}; // cava handled raw audio data(is based on audio_data)
|
||||
struct cava::audio_data audio_data_ {}; // cava audio data
|
||||
struct cava::cava_plan* plan_; //{new cava_plan{}};
|
||||
struct cava::error_s error_{}; // cava errors
|
||||
struct cava::config_params prm_{}; // cava parameters
|
||||
struct cava::audio_raw audio_raw_{}; // cava handled raw audio data(is based on audio_data)
|
||||
struct cava::audio_data audio_data_{}; // cava audio data
|
||||
struct cava::cava_plan* plan_; //{new cava_plan{}};
|
||||
// Cava API to read audio source
|
||||
cava::ptr input_source_;
|
||||
// Delay to handle audio source
|
||||
@@ -39,11 +39,12 @@ class Cava final : public ALabel {
|
||||
std::chrono::seconds suspend_silence_delay_{0};
|
||||
bool silence_{false};
|
||||
bool hide_on_silence_{false};
|
||||
std::string format_silent_{""};
|
||||
int sleep_counter_{0};
|
||||
// Cava method
|
||||
void pause_resume();
|
||||
// ModuleActionMap
|
||||
static inline std::map<const std::string, void (waybar::modules::Cava::*const)()> actionMap_{
|
||||
static inline std::map<const std::string, void (waybar::modules::Cava::* const)()> actionMap_{
|
||||
{"mode", &waybar::modules::Cava::pause_resume}};
|
||||
};
|
||||
} // namespace waybar::modules
|
||||
|
||||
@@ -79,7 +79,7 @@ class Clock final : public ALabel {
|
||||
void tz_up();
|
||||
void tz_down();
|
||||
// Module Action Map
|
||||
static inline std::map<const std::string, void (waybar::modules::Clock::*const)()> actionMap_{
|
||||
static inline std::map<const std::string, void (waybar::modules::Clock::* const)()> actionMap_{
|
||||
{"mode", &waybar::modules::Clock::cldModeSwitch},
|
||||
{"shift_up", &waybar::modules::Clock::cldShift_up},
|
||||
{"shift_down", &waybar::modules::Clock::cldShift_down},
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
#include <filesystem>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
|
||||
#include "util/json.hpp"
|
||||
@@ -19,7 +19,9 @@ class EventHandler {
|
||||
|
||||
class IPC {
|
||||
public:
|
||||
IPC() { startIPC(); }
|
||||
IPC();
|
||||
~IPC();
|
||||
static IPC& inst();
|
||||
|
||||
void registerForIPC(const std::string& ev, EventHandler* ev_handler);
|
||||
void unregisterForIPC(EventHandler* handler);
|
||||
@@ -32,14 +34,16 @@ class IPC {
|
||||
static std::filesystem::path socketFolder_;
|
||||
|
||||
private:
|
||||
void startIPC();
|
||||
void socketListener();
|
||||
void parseIPC(const std::string&);
|
||||
|
||||
std::thread ipcThread_;
|
||||
std::mutex callbackMutex_;
|
||||
util::JsonParser parser_;
|
||||
std::list<std::pair<std::string, EventHandler*>> callbacks_;
|
||||
int socketfd_; // the hyprland socket file descriptor
|
||||
bool running_ = true;
|
||||
};
|
||||
|
||||
inline std::unique_ptr<IPC> gIPC;
|
||||
inline bool modulesReady = false;
|
||||
}; // namespace waybar::modules::hyprland
|
||||
|
||||
@@ -37,6 +37,8 @@ class Language : public waybar::ALabel, public EventHandler {
|
||||
util::JsonParser parser_;
|
||||
|
||||
Layout layout_;
|
||||
|
||||
IPC& m_ipc;
|
||||
};
|
||||
|
||||
} // namespace waybar::modules::hyprland
|
||||
|
||||
@@ -28,6 +28,8 @@ class Submap : public waybar::ALabel, public EventHandler {
|
||||
std::string submap_;
|
||||
bool always_on_ = false;
|
||||
std::string default_submap_ = "Default";
|
||||
|
||||
IPC& m_ipc;
|
||||
};
|
||||
|
||||
} // namespace waybar::modules::hyprland
|
||||
|
||||
@@ -60,6 +60,8 @@ class Window : public waybar::AAppIconLabel, public EventHandler {
|
||||
bool swallowing_;
|
||||
bool fullscreen_;
|
||||
bool focused_;
|
||||
|
||||
IPC& m_ipc;
|
||||
};
|
||||
|
||||
} // namespace waybar::modules::hyprland
|
||||
|
||||
@@ -83,6 +83,7 @@ class Workspace {
|
||||
Gtk::Button m_button;
|
||||
Gtk::Box m_content;
|
||||
Gtk::Label m_label;
|
||||
IPC& m_ipc;
|
||||
};
|
||||
|
||||
} // namespace waybar::modules::hyprland
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -55,7 +56,7 @@ class Workspaces : public AModule, public EventHandler {
|
||||
|
||||
static Json::Value createMonitorWorkspaceData(std::string const& name,
|
||||
std::string const& monitor);
|
||||
void removeWorkspace(std::string const& name);
|
||||
void removeWorkspace(std::string const& workspaceString);
|
||||
void setUrgentWorkspace(std::string const& windowaddress);
|
||||
|
||||
// Config
|
||||
@@ -74,10 +75,11 @@ class Workspaces : public AModule, public EventHandler {
|
||||
void onWorkspaceActivated(std::string const& payload);
|
||||
void onSpecialWorkspaceActivated(std::string const& payload);
|
||||
void onWorkspaceDestroyed(std::string const& payload);
|
||||
void onWorkspaceCreated(std::string const& workspaceName,
|
||||
void onWorkspaceCreated(std::string const& payload,
|
||||
Json::Value const& clientsData = Json::Value::nullRef);
|
||||
void onWorkspaceMoved(std::string const& payload);
|
||||
void onWorkspaceRenamed(std::string const& payload);
|
||||
static std::optional<int> parseWorkspaceId(std::string const& workspaceIdStr);
|
||||
|
||||
// monitor events
|
||||
void onMonitorFocused(std::string const& payload);
|
||||
@@ -93,11 +95,18 @@ class Workspaces : public AModule, public EventHandler {
|
||||
|
||||
int windowRewritePriorityFunction(std::string const& window_rule);
|
||||
|
||||
// event payload management
|
||||
template <typename... Args>
|
||||
static std::string makePayload(Args const&... args);
|
||||
static std::pair<std::string, std::string> splitDoublePayload(std::string const& payload);
|
||||
static std::tuple<std::string, std::string, std::string> splitTriplePayload(
|
||||
std::string const& payload);
|
||||
|
||||
// Update methods
|
||||
void doUpdate();
|
||||
void removeWorkspacesToRemove();
|
||||
void createWorkspacesToCreate();
|
||||
static std::vector<std::string> getVisibleWorkspaces();
|
||||
static std::vector<int> getVisibleWorkspaces();
|
||||
void updateWorkspaceStates();
|
||||
bool updateWindowsToCreate();
|
||||
|
||||
@@ -138,7 +147,7 @@ class Workspaces : public AModule, public EventHandler {
|
||||
|
||||
bool m_withIcon;
|
||||
uint64_t m_monitorId;
|
||||
std::string m_activeWorkspaceName;
|
||||
int m_activeWorkspaceId;
|
||||
std::string m_activeSpecialWorkspaceName;
|
||||
std::vector<std::unique_ptr<Workspace>> m_workspaces;
|
||||
std::vector<std::pair<Json::Value, Json::Value>> m_workspacesToCreate;
|
||||
@@ -150,6 +159,7 @@ class Workspaces : public AModule, public EventHandler {
|
||||
std::mutex m_mutex;
|
||||
const Bar& m_bar;
|
||||
Gtk::Box m_box;
|
||||
IPC& m_ipc;
|
||||
};
|
||||
|
||||
} // namespace waybar::modules::hyprland
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#include "util/rfkill.hpp"
|
||||
#endif
|
||||
|
||||
enum ip_addr_pref : uint8_t { IPV4, IPV6, IPV4_6 };
|
||||
|
||||
namespace waybar::modules {
|
||||
|
||||
class Network : public ALabel {
|
||||
@@ -40,6 +42,7 @@ class Network : public ALabel {
|
||||
void parseEssid(struct nlattr**);
|
||||
void parseSignal(struct nlattr**);
|
||||
void parseFreq(struct nlattr**);
|
||||
void parseBssid(struct nlattr**);
|
||||
bool associatedOrJoined(struct nlattr**);
|
||||
bool checkInterface(std::string name);
|
||||
auto getInfo() -> void;
|
||||
@@ -49,7 +52,7 @@ class Network : public ALabel {
|
||||
std::optional<std::pair<unsigned long long, unsigned long long>> readBandwidthUsage();
|
||||
|
||||
int ifid_;
|
||||
sa_family_t family_;
|
||||
ip_addr_pref addr_pref_;
|
||||
struct sockaddr_nl nladdr_ = {0};
|
||||
struct nl_sock* sock_ = nullptr;
|
||||
struct nl_sock* ev_sock_ = nullptr;
|
||||
@@ -69,12 +72,16 @@ class Network : public ALabel {
|
||||
|
||||
std::string state_;
|
||||
std::string essid_;
|
||||
std::string bssid_;
|
||||
bool carrier_;
|
||||
std::string ifname_;
|
||||
std::string ipaddr_;
|
||||
std::string ipaddr6_;
|
||||
std::string gwaddr_;
|
||||
std::string netmask_;
|
||||
std::string netmask6_;
|
||||
int cidr_;
|
||||
int cidr6_;
|
||||
int32_t signal_strength_dbm_;
|
||||
uint8_t signal_strength_;
|
||||
std::string signal_strength_app_;
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
|
||||
#include <list>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "util/json.hpp"
|
||||
|
||||
namespace waybar::modules::niri {
|
||||
|
||||
class EventHandler {
|
||||
public:
|
||||
virtual void onEvent(const Json::Value& ev) = 0;
|
||||
virtual ~EventHandler() = default;
|
||||
};
|
||||
|
||||
class IPC {
|
||||
public:
|
||||
IPC() { startIPC(); }
|
||||
|
||||
void registerForIPC(const std::string& ev, EventHandler* ev_handler);
|
||||
void unregisterForIPC(EventHandler* handler);
|
||||
|
||||
static Json::Value send(const Json::Value& request);
|
||||
|
||||
// The data members are only safe to access while dataMutex_ is locked.
|
||||
std::lock_guard<std::mutex> lockData() { return std::lock_guard(dataMutex_); }
|
||||
const std::vector<Json::Value>& workspaces() const { return workspaces_; }
|
||||
const std::vector<Json::Value>& windows() const { return windows_; }
|
||||
const std::vector<std::string>& keyboardLayoutNames() const { return keyboardLayoutNames_; }
|
||||
unsigned keyboardLayoutCurrent() const { return keyboardLayoutCurrent_; }
|
||||
|
||||
private:
|
||||
void startIPC();
|
||||
static int connectToSocket();
|
||||
void parseIPC(const std::string&);
|
||||
|
||||
std::mutex dataMutex_;
|
||||
std::vector<Json::Value> workspaces_;
|
||||
std::vector<Json::Value> windows_;
|
||||
std::vector<std::string> keyboardLayoutNames_;
|
||||
unsigned keyboardLayoutCurrent_;
|
||||
|
||||
util::JsonParser parser_;
|
||||
std::mutex callbackMutex_;
|
||||
std::list<std::pair<std::string, EventHandler*>> callbacks_;
|
||||
};
|
||||
|
||||
inline std::unique_ptr<IPC> gIPC;
|
||||
|
||||
}; // namespace waybar::modules::niri
|
||||
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "ALabel.hpp"
|
||||
#include "bar.hpp"
|
||||
#include "modules/niri/backend.hpp"
|
||||
|
||||
namespace waybar::modules::niri {
|
||||
|
||||
class Language : public ALabel, public EventHandler {
|
||||
public:
|
||||
Language(const std::string &, const Bar &, const Json::Value &);
|
||||
~Language() override;
|
||||
void update() override;
|
||||
|
||||
private:
|
||||
void updateFromIPC();
|
||||
void onEvent(const Json::Value &ev) override;
|
||||
void doUpdate();
|
||||
|
||||
struct Layout {
|
||||
std::string full_name;
|
||||
std::string short_name;
|
||||
std::string variant;
|
||||
std::string short_description;
|
||||
};
|
||||
|
||||
static Layout getLayout(const std::string &fullName);
|
||||
|
||||
std::mutex mutex_;
|
||||
const Bar &bar_;
|
||||
|
||||
std::vector<Layout> layouts_;
|
||||
unsigned current_idx_;
|
||||
};
|
||||
|
||||
} // namespace waybar::modules::niri
|
||||
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtkmm/button.h>
|
||||
#include <json/value.h>
|
||||
|
||||
#include "AAppIconLabel.hpp"
|
||||
#include "bar.hpp"
|
||||
#include "modules/niri/backend.hpp"
|
||||
|
||||
namespace waybar::modules::niri {
|
||||
|
||||
class Window : public AAppIconLabel, public EventHandler {
|
||||
public:
|
||||
Window(const std::string &, const Bar &, const Json::Value &);
|
||||
~Window() override;
|
||||
void update() override;
|
||||
|
||||
private:
|
||||
void onEvent(const Json::Value &ev) override;
|
||||
void doUpdate();
|
||||
void setClass(const std::string &className, bool enable);
|
||||
|
||||
const Bar &bar_;
|
||||
|
||||
std::string oldAppId_;
|
||||
};
|
||||
|
||||
} // namespace waybar::modules::niri
|
||||
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtkmm/button.h>
|
||||
#include <json/value.h>
|
||||
|
||||
#include "AModule.hpp"
|
||||
#include "bar.hpp"
|
||||
#include "modules/niri/backend.hpp"
|
||||
|
||||
namespace waybar::modules::niri {
|
||||
|
||||
class Workspaces : public AModule, public EventHandler {
|
||||
public:
|
||||
Workspaces(const std::string &, const Bar &, const Json::Value &);
|
||||
~Workspaces() override;
|
||||
void update() override;
|
||||
|
||||
private:
|
||||
void onEvent(const Json::Value &ev) override;
|
||||
void doUpdate();
|
||||
Gtk::Button &addButton(const Json::Value &ws);
|
||||
std::string getIcon(const std::string &value, const Json::Value &ws);
|
||||
|
||||
const Bar &bar_;
|
||||
Gtk::Box box_;
|
||||
// Map from niri workspace id to button.
|
||||
std::unordered_map<uint64_t, Gtk::Button> buttons_;
|
||||
};
|
||||
|
||||
} // namespace waybar::modules::niri
|
||||
@@ -13,7 +13,7 @@ namespace waybar::modules::privacy {
|
||||
|
||||
class Privacy : public AModule {
|
||||
public:
|
||||
Privacy(const std::string &, const Json::Value &, const std::string &pos);
|
||||
Privacy(const std::string &, const Json::Value &, Gtk::Orientation, const std::string &pos);
|
||||
auto update() -> void override;
|
||||
|
||||
void onPrivacyNodesChanged();
|
||||
|
||||
@@ -17,8 +17,8 @@ namespace waybar::modules::privacy {
|
||||
class PrivacyItem : public Gtk::Revealer {
|
||||
public:
|
||||
PrivacyItem(const Json::Value &config_, enum PrivacyNodeType privacy_type_,
|
||||
std::list<PrivacyNodeInfo *> *nodes, const std::string &pos, const uint icon_size,
|
||||
const uint transition_duration);
|
||||
std::list<PrivacyNodeInfo *> *nodes, Gtk::Orientation orientation,
|
||||
const std::string &pos, const uint icon_size, const uint transition_duration);
|
||||
|
||||
enum PrivacyNodeType privacy_type;
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include <json/json.h>
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
class IconManager {
|
||||
public:
|
||||
static IconManager& instance() {
|
||||
static IconManager instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
void setIconsConfig(const Json::Value& icons_config) {
|
||||
if (icons_config.isObject()) {
|
||||
for (const auto& key : icons_config.getMemberNames()) {
|
||||
std::string app_name = key;
|
||||
const Json::Value& icon_value = icons_config[key];
|
||||
|
||||
if (icon_value.isString()) {
|
||||
std::string icon_path = icon_value.asString();
|
||||
icons_map_[app_name] = icon_path;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
spdlog::warn("Invalid icon config format.");
|
||||
}
|
||||
}
|
||||
|
||||
std::string getIconForApp(const std::string& app_name) const {
|
||||
auto it = icons_map_.find(app_name);
|
||||
if (it != icons_map_.end()) {
|
||||
return it->second;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private:
|
||||
IconManager() = default;
|
||||
std::unordered_map<std::string, std::string> icons_map_;
|
||||
};
|
||||
@@ -62,6 +62,7 @@ class Item : public sigc::trackable {
|
||||
void proxyReady(Glib::RefPtr<Gio::AsyncResult>& result);
|
||||
void setProperty(const Glib::ustring& name, Glib::VariantBase& value);
|
||||
void setStatus(const Glib::ustring& value);
|
||||
void setCustomIcon(const std::string& id);
|
||||
void getUpdatedProperties();
|
||||
void processUpdatedProperties(Glib::RefPtr<Gio::AsyncResult>& result);
|
||||
void onSignal(const Glib::ustring& sender_name, const Glib::ustring& signal_name,
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace waybar::modules::sway {
|
||||
class Workspaces : public AModule, public sigc::trackable {
|
||||
public:
|
||||
Workspaces(const std::string&, const waybar::Bar&, const Json::Value&);
|
||||
virtual ~Workspaces() = default;
|
||||
~Workspaces() override = default;
|
||||
auto update() -> void override;
|
||||
|
||||
private:
|
||||
@@ -38,10 +38,10 @@ class Workspaces : public AModule, public sigc::trackable {
|
||||
Gtk::Button& addButton(const Json::Value&);
|
||||
void onButtonReady(const Json::Value&, Gtk::Button&);
|
||||
std::string getIcon(const std::string&, const Json::Value&);
|
||||
const std::string getCycleWorkspace(std::vector<Json::Value>::iterator, bool prev) const;
|
||||
std::string getCycleWorkspace(std::vector<Json::Value>::iterator, bool prev) const;
|
||||
uint16_t getWorkspaceIndex(const std::string& name) const;
|
||||
std::string trimWorkspaceName(std::string);
|
||||
bool handleScroll(GdkEventScroll*) override;
|
||||
static std::string trimWorkspaceName(std::string);
|
||||
bool handleScroll(GdkEventScroll* /*unused*/) override;
|
||||
|
||||
const Bar& bar_;
|
||||
std::vector<Json::Value> workspaces_;
|
||||
@@ -49,7 +49,6 @@ class Workspaces : public AModule, public sigc::trackable {
|
||||
std::vector<std::string> workspaces_order_;
|
||||
Gtk::Box box_;
|
||||
std::string m_formatWindowSeperator;
|
||||
std::string m_windowRewriteDefault;
|
||||
util::RegexCollection m_windowRewriteRules;
|
||||
util::JsonParser parser_;
|
||||
std::unordered_map<std::string, Gtk::Button> buttons_;
|
||||
|
||||
@@ -18,6 +18,7 @@ class Temperature : public ALabel {
|
||||
private:
|
||||
float getTemperature();
|
||||
bool isCritical(uint16_t);
|
||||
bool isWarning(uint16_t);
|
||||
|
||||
std::string file_path_;
|
||||
util::SleeperThread thread_;
|
||||
|
||||
@@ -18,7 +18,7 @@ class Wireplumber : public ALabel {
|
||||
|
||||
private:
|
||||
void asyncLoadRequiredApiModules();
|
||||
void prepare();
|
||||
void prepare(waybar::modules::Wireplumber* self);
|
||||
void activatePlugins();
|
||||
static void updateVolume(waybar::modules::Wireplumber* self, uint32_t id);
|
||||
static void updateNodeName(waybar::modules::Wireplumber* self, uint32_t id);
|
||||
@@ -32,6 +32,8 @@ class Wireplumber : public ALabel {
|
||||
|
||||
bool handleScroll(GdkEventScroll* e) override;
|
||||
|
||||
static std::list<waybar::modules::Wireplumber*> modules;
|
||||
|
||||
WpCore* wp_core_;
|
||||
GPtrArray* apis_;
|
||||
WpObjectManager* om_;
|
||||
@@ -44,6 +46,7 @@ class Wireplumber : public ALabel {
|
||||
double min_step_;
|
||||
uint32_t node_id_{0};
|
||||
std::string node_name_;
|
||||
gchar* type_;
|
||||
};
|
||||
|
||||
} // namespace waybar::modules
|
||||
|
||||
@@ -24,6 +24,10 @@
|
||||
|
||||
namespace waybar::modules::wlr {
|
||||
|
||||
struct widget_geometry {
|
||||
int x, y, w, h;
|
||||
};
|
||||
|
||||
class Taskbar;
|
||||
|
||||
class Task {
|
||||
@@ -42,6 +46,7 @@ class Task {
|
||||
};
|
||||
// made public so TaskBar can reorder based on configuration.
|
||||
Gtk::Button button;
|
||||
struct widget_geometry minimize_hint;
|
||||
|
||||
private:
|
||||
static uint32_t global_id;
|
||||
@@ -82,6 +87,8 @@ class Task {
|
||||
private:
|
||||
std::string repr() const;
|
||||
std::string state_string(bool = false) const;
|
||||
void set_minimize_hint();
|
||||
void on_button_size_allocated(Gtk::Allocation &alloc);
|
||||
void set_app_info_from_app_id_list(const std::string &app_id_list);
|
||||
bool image_load_icon(Gtk::Image &image, const Glib::RefPtr<Gtk::IconTheme> &icon_theme,
|
||||
Glib::RefPtr<Gio::DesktopAppInfo> app_info, int size);
|
||||
|
||||
@@ -38,6 +38,8 @@ class AudioBackend {
|
||||
std::string desc_;
|
||||
std::string monitor_;
|
||||
std::string current_sink_name_;
|
||||
std::string default_sink_name;
|
||||
bool default_sink_running_;
|
||||
bool current_sink_running_;
|
||||
// SOURCE
|
||||
uint32_t source_idx_{0};
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
class pow_format {
|
||||
public:
|
||||
pow_format(long long val, std::string&& unit, bool binary = false)
|
||||
: val_(val), unit_(unit), binary_(binary){};
|
||||
: val_(val), unit_(unit), binary_(binary) {};
|
||||
|
||||
long long val_;
|
||||
std::string unit_;
|
||||
@@ -92,7 +92,7 @@ struct formatter<pow_format> {
|
||||
template <>
|
||||
struct formatter<Glib::ustring> : formatter<std::string> {
|
||||
template <typename FormatContext>
|
||||
auto format(const Glib::ustring& value, FormatContext& ctx) {
|
||||
auto format(const Glib::ustring& value, FormatContext& ctx) const {
|
||||
return formatter<std::string>::format(static_cast<std::string>(value), ctx);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -31,6 +31,11 @@ The brightness can be controlled by dragging the slider across the bar or clicki
|
||||
typeof: string ++
|
||||
The name of the preferred device to control. If left empty, a device will be chosen automatically.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# EXAMPLES
|
||||
|
||||
```
|
||||
|
||||
@@ -38,7 +38,7 @@ The *backlight* module displays the current backlight level.
|
||||
|
||||
*rotate*: ++
|
||||
typeof: integer ++
|
||||
Positive value to rotate the text label.
|
||||
Positive value to rotate the text label (in 90 degree increments).
|
||||
|
||||
*states*: ++
|
||||
typeof: object ++
|
||||
@@ -81,6 +81,11 @@ The *backlight* module displays the current backlight level.
|
||||
default: 1.0 ++
|
||||
The speed at which to change the brightness when scrolling.
|
||||
|
||||
*min-brightness*: ++
|
||||
typeof: double ++
|
||||
default: 0.0 ++
|
||||
The minimum brightness of the backlight.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
@@ -94,6 +99,11 @@ The *backlight* module displays the current backlight level.
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# EXAMPLE:
|
||||
|
||||
```
|
||||
|
||||
@@ -69,7 +69,7 @@ The *battery* module displays the current capacity and state (eg. charging) of y
|
||||
|
||||
*rotate*: ++
|
||||
typeof: integer++
|
||||
Positive value to rotate the text label.
|
||||
Positive value to rotate the text label (in 90 degree increments).
|
||||
|
||||
*on-click*: ++
|
||||
typeof: string ++
|
||||
@@ -122,6 +122,11 @@ The *battery* module displays the current capacity and state (eg. charging) of y
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{capacity}*: Capacity in percentage
|
||||
|
||||
@@ -54,7 +54,7 @@ Addressed by *bluetooth*
|
||||
|
||||
*rotate*: ++
|
||||
typeof: integer ++
|
||||
Positive value to rotate the text label.
|
||||
Positive value to rotate the text label (in 90 degree increments).
|
||||
|
||||
*max-length*: ++
|
||||
typeof: integer ++
|
||||
@@ -142,6 +142,11 @@ Addressed by *bluetooth*
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{status}*: Status of the bluetooth device.
|
||||
|
||||
@@ -64,6 +64,10 @@ libcava lives in:
|
||||
:[ bool
|
||||
:[ false
|
||||
:[ Hides the widget if no input (after sleep_timer elapsed)
|
||||
|[ *format_silent*
|
||||
:[ string
|
||||
:[
|
||||
:[ Widget's text after sleep_timer elapsed (hide_on_silence has to be false)
|
||||
|[ *method*
|
||||
:[ string
|
||||
:[ pulse
|
||||
@@ -196,3 +200,8 @@ In case when cava releases new version and you're wanna get it, it should be rai
|
||||
}
|
||||
},
|
||||
```
|
||||
# STYLE
|
||||
|
||||
- *#cava*
|
||||
- *#cava.silent* Applied after no sound has been detected for sleep_timer seconds
|
||||
- *#cava.updated* Applied when a new frame is shown
|
||||
|
||||
@@ -15,6 +15,11 @@ Addressed by *cffi/<name>*
|
||||
typeof: string ++
|
||||
The path to the dynamic library to load to control the widget.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
Some additional configuration may be required depending on the cffi dynamic library being used.
|
||||
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ $XDG_CONFIG_HOME/waybar/config ++
|
||||
|[ *rotate*
|
||||
:[ integer
|
||||
:[
|
||||
:[ Positive value to rotate the text label
|
||||
:[ Positive value to rotate the text label (in 90 degree increments)
|
||||
|[ *on-click*
|
||||
:[ string
|
||||
:[
|
||||
@@ -96,6 +96,10 @@ $XDG_CONFIG_HOME/waybar/config ++
|
||||
:[ array
|
||||
:[
|
||||
:[ The actions corresponding to the buttons of the menu.
|
||||
|[ *expand*:
|
||||
:[ bool
|
||||
:[ false
|
||||
:[ Enables this module to consume all left over space dynamically.
|
||||
|
||||
View all valid format options in *strftime(3)* or have a look https://en.cppreference.com/w/cpp/chrono/duration/formatter
|
||||
|
||||
@@ -113,7 +117,7 @@ View all valid format options in *strftime(3)* or have a look https://en.cpprefe
|
||||
:[ 3
|
||||
:[ Relevant for *mode=year*. Count of months per row
|
||||
|[ *weeks-pos*
|
||||
:[ integer
|
||||
:[ string
|
||||
:[
|
||||
:[ The position where week numbers should be displayed. Disabled when is empty.
|
||||
Possible values: left|right
|
||||
|
||||
@@ -43,7 +43,7 @@ The *cpu* module displays the current CPU utilization.
|
||||
|
||||
*rotate*: ++
|
||||
typeof: integer ++
|
||||
Positive value to rotate the text label.
|
||||
Positive value to rotate the text label (in 90 degree increments).
|
||||
|
||||
*states*: ++
|
||||
typeof: object ++
|
||||
@@ -82,6 +82,11 @@ The *cpu* module displays the current CPU utilization.
|
||||
default: true ++
|
||||
Option to disable tooltip on hover.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{load}*: Current CPU load.
|
||||
|
||||
+14
-9
@@ -55,8 +55,8 @@ Addressed by *custom/<name>*
|
||||
|
||||
*format*: ++
|
||||
typeof: string ++
|
||||
default: {} ++
|
||||
The format, how information should be displayed. On {} data gets inserted.
|
||||
default: {text} ++
|
||||
The format, how information should be displayed. On {text} data gets inserted.
|
||||
|
||||
*format-icons*: ++
|
||||
typeof: array ++
|
||||
@@ -64,7 +64,7 @@ Addressed by *custom/<name>*
|
||||
|
||||
*rotate*: ++
|
||||
typeof: integer ++
|
||||
Positive value to rotate the text label.
|
||||
Positive value to rotate the text label (in 90 degree increments).
|
||||
|
||||
*max-length*: ++
|
||||
typeof: integer ++
|
||||
@@ -138,6 +138,11 @@ Addressed by *custom/<name>*
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# RETURN-TYPE
|
||||
|
||||
When *return-type* is set to *json*, Waybar expects the *exec*-script to output its data in JSON format.
|
||||
@@ -160,7 +165,7 @@ $text\\n$tooltip\\n$class*
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{}*: Output of the script.
|
||||
*{text}*: Output of the script.
|
||||
|
||||
*{percentage}* Percentage which can be set via a json return type.
|
||||
|
||||
@@ -172,7 +177,7 @@ $text\\n$tooltip\\n$class*
|
||||
|
||||
```
|
||||
"custom/spotify": {
|
||||
"format": " {}",
|
||||
"format": " {text}",
|
||||
"max-length": 40,
|
||||
"interval": 30, // Remove this if your script is endless and write in loop
|
||||
"exec": "$HOME/.config/waybar/mediaplayer.sh 2> /dev/null", // Script in resources folder
|
||||
@@ -185,7 +190,7 @@ $text\\n$tooltip\\n$class*
|
||||
|
||||
```
|
||||
"custom/mpd": {
|
||||
"format": "♪ {}",
|
||||
"format": "♪ {text}",
|
||||
//"max-length": 15,
|
||||
"interval": 10,
|
||||
"exec": "mpc current",
|
||||
@@ -199,7 +204,7 @@ $text\\n$tooltip\\n$class*
|
||||
|
||||
```
|
||||
"custom/cmus": {
|
||||
"format": "♪ {}",
|
||||
"format": "♪ {text}",
|
||||
//"max-length": 15,
|
||||
"interval": 10,
|
||||
"exec": "cmus-remote -C \"format_print '%a - %t'\"", // artist - title
|
||||
@@ -214,7 +219,7 @@ $text\\n$tooltip\\n$class*
|
||||
```
|
||||
|
||||
"custom/pacman": {
|
||||
"format": "{} ",
|
||||
"format": "{text} ",
|
||||
"interval": "once",
|
||||
"exec": "pacman_packages",
|
||||
"on-click": "update-system",
|
||||
@@ -226,7 +231,7 @@ $text\\n$tooltip\\n$class*
|
||||
|
||||
```
|
||||
"custom/pacman": {
|
||||
"format": "{} ",
|
||||
"format": "{text} ",
|
||||
"interval": 3600, // every hour
|
||||
"exec": "checkupdates | wc -l", // # of updates
|
||||
"exec-if": "exit 0", // always run; consider advanced run conditions
|
||||
|
||||
@@ -29,7 +29,7 @@ Addressed by *disk*
|
||||
|
||||
*rotate*: ++
|
||||
typeof: integer ++
|
||||
Positive value to rotate the text label.
|
||||
Positive value to rotate the text label (in 90 degree increments).
|
||||
|
||||
*states*: ++
|
||||
typeof: object ++
|
||||
@@ -106,6 +106,11 @@ Addressed by *disk*
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{percentage_used}*: Percentage of disk in use.
|
||||
|
||||
@@ -26,6 +26,11 @@ Addressed by *dwl/tags*
|
||||
default: false ++
|
||||
If set to false, you can left-click to set focused tag. Right-click to toggle tag focus. If set to true this behaviour is disabled.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# EXAMPLE
|
||||
|
||||
```
|
||||
|
||||
@@ -19,7 +19,7 @@ Addressed by *dwl/window*
|
||||
|
||||
*rotate*: ++
|
||||
typeof: integer ++
|
||||
Positive value to rotate the text label.
|
||||
Positive value to rotate the text label (in 90 degree increments).
|
||||
|
||||
*max-length*: ++
|
||||
typeof: integer ++
|
||||
@@ -84,6 +84,11 @@ Addressed by *dwl/window*
|
||||
default: 24 ++
|
||||
Option to change the size of the application icon.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{title}*: The title of the focused window.
|
||||
|
||||
@@ -61,6 +61,11 @@ Feral Gamemode optimizations.
|
||||
default: 4 ++
|
||||
Defines the spacing between the icon and the text.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{glyph}*: The string icon glyph to use instead.
|
||||
|
||||
@@ -38,6 +38,11 @@ Addressed by *hyprland/language*
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
@@ -54,9 +59,9 @@ Addressed by *hyprland/language*
|
||||
|
||||
```
|
||||
"hyprland/language": {
|
||||
"format": "Lang: {long}"
|
||||
"format-en": "AMERICA, HELL YEAH!"
|
||||
"format-tr": "As bayrakları"
|
||||
"format": "Lang: {long}",
|
||||
"format-en": "AMERICA, HELL YEAH!",
|
||||
"format-tr": "As bayrakları",
|
||||
"keyboard-name": "at-translated-set-2-keyboard"
|
||||
}
|
||||
```
|
||||
|
||||
@@ -19,7 +19,7 @@ Addressed by *hyprland/submap*
|
||||
|
||||
*rotate*: ++
|
||||
typeof: integer ++
|
||||
Positive value to rotate the text label.
|
||||
Positive value to rotate the text label (in 90 degree increments).
|
||||
|
||||
*max-length*: ++
|
||||
typeof: integer ++
|
||||
@@ -93,6 +93,11 @@ Addressed by *hyprland/submap*
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
|
||||
# EXAMPLES
|
||||
|
||||
|
||||
@@ -35,6 +35,11 @@ Addressed by *hyprland/window*
|
||||
default: 24 ++
|
||||
Option to change the size of the application icon.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
See the output of "hyprctl clients" for examples
|
||||
|
||||
|
||||
@@ -78,6 +78,11 @@ Addressed by *hyprland/workspaces*
|
||||
If set to id, workspaces will sort by id.
|
||||
If none of those, workspaces will sort with default behavior.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{id}*: id of workspace assigned by compositor
|
||||
|
||||
@@ -21,7 +21,7 @@ screensaver, also known as "presentation mode".
|
||||
|
||||
*rotate*: ++
|
||||
typeof: integer ++
|
||||
Positive value to rotate the text label.
|
||||
Positive value to rotate the text label (in 90 degree increments).
|
||||
|
||||
*max-length*: ++
|
||||
typeof: integer ++
|
||||
@@ -102,6 +102,11 @@ screensaver, also known as "presentation mode".
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{status}*: status (*activated* or *deactivated*)
|
||||
|
||||
@@ -64,6 +64,11 @@ The *image* module displays an image from a path.
|
||||
default: true ++
|
||||
Option to enable tooltip on hover.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# SCRIPT OUTPUT
|
||||
|
||||
Similar to the *custom* module, output values of the script are *newline* separated.
|
||||
|
||||
@@ -25,7 +25,7 @@ See *systemd-inhibit*(1) for more information.
|
||||
|
||||
*rotate*: ++
|
||||
typeof: integer ++
|
||||
Positive value to rotate the text label.
|
||||
Positive value to rotate the text label (in 90 degree increments).
|
||||
|
||||
*max-length*: ++
|
||||
typeof: integer ++
|
||||
@@ -89,6 +89,11 @@ See *systemd-inhibit*(1) for more information.
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{status}*: status (*activated* or *deactivated*)
|
||||
|
||||
@@ -51,7 +51,7 @@ Addressed by *jack*
|
||||
|
||||
*rotate*: ++
|
||||
typeof: integer ++
|
||||
Positive value to rotate the text label.
|
||||
Positive value to rotate the text label (in 90 degree increments).
|
||||
|
||||
*max-length*: ++
|
||||
typeof: integer ++
|
||||
@@ -98,6 +98,11 @@ Addressed by *jack*
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{load}*: The current CPU load estimated by JACK.
|
||||
|
||||
@@ -53,6 +53,11 @@ You must be a member of the input group to use this module.
|
||||
default: [58, 69, 70] ++
|
||||
Customize the key to trigger this module, the key number can be found in /usr/include/linux/input-event-codes.h or running sudo libinput debug-events --show-keycodes.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{name}*: Caps, Num, or Scroll.
|
||||
|
||||
@@ -29,7 +29,7 @@ Addressed by *memory*
|
||||
|
||||
*rotate*: ++
|
||||
typeof: integer ++
|
||||
Positive value to rotate the text label.
|
||||
Positive value to rotate the text label (in 90 degree increments).
|
||||
|
||||
*states*: ++
|
||||
typeof: object ++
|
||||
@@ -97,6 +97,11 @@ Addressed by *memory*
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{percentage}*: Percentage of memory in use.
|
||||
|
||||
@@ -91,7 +91,7 @@ Addressed by *mpd*
|
||||
|
||||
*rotate*: ++
|
||||
typeof: integer ++
|
||||
Positive value to rotate the text label.
|
||||
Positive value to rotate the text label (in 90 degree increments).
|
||||
|
||||
*max-length*: ++
|
||||
typeof: integer ++
|
||||
@@ -175,6 +175,11 @@ Addressed by *mpd*
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
## WHEN PLAYING/PAUSED
|
||||
|
||||
@@ -107,7 +107,7 @@ The *mpris* module displays currently playing media via libplayerctl.
|
||||
|
||||
*rotate*: ++
|
||||
typeof: integer ++
|
||||
Positive value to rotate the text label.
|
||||
Positive value to rotate the text label (in 90 degree increments).
|
||||
|
||||
*max-length*: ++
|
||||
typeof: integer ++
|
||||
@@ -148,6 +148,11 @@ The *mpris* module displays currently playing media via libplayerctl.
|
||||
typeof: map[string]string ++
|
||||
Allows setting _{status_icon}_ based on player status (playing, paused, stopped).
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ Addressed by *network*
|
||||
*family*: ++
|
||||
typeof: string ++
|
||||
default: *ipv4* ++
|
||||
The address family that is used for the format replacement {ipaddr} and to determine if a network connection is present.
|
||||
The address family that is used for the format replacement {ipaddr} and to determine if a network connection is present. Set it to ipv4_6 to display both.
|
||||
|
||||
*format*: ++
|
||||
typeof: string ++
|
||||
@@ -58,7 +58,7 @@ Addressed by *network*
|
||||
|
||||
*rotate*: ++
|
||||
typeof: integer ++
|
||||
Positive value to rotate the text label.
|
||||
Positive value to rotate the text label (in 90 degree increments).
|
||||
|
||||
*max-length*: ++
|
||||
typeof: integer ++
|
||||
@@ -142,6 +142,11 @@ Addressed by *network*
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{ifname}*: Name of the network interface.
|
||||
@@ -150,12 +155,18 @@ Addressed by *network*
|
||||
|
||||
*{gwaddr}*: The default gateway for the interface
|
||||
|
||||
*{netmask}*: The subnetmask corresponding to the IP.
|
||||
*{netmask}*: The subnetmask corresponding to the IP(V4).
|
||||
|
||||
*{cidr}*: The subnetmask corresponding to the IP in CIDR notation.
|
||||
*{netmask6}*: The subnetmask corresponding to the IP(V6).
|
||||
|
||||
*{cidr}*: The subnetmask corresponding to the IP(V4) in CIDR notation.
|
||||
|
||||
*{cidr6}*: The subnetmask corresponding to the IP(V6) in CIDR notation.
|
||||
|
||||
*{essid}*: Name (SSID) of the wireless network.
|
||||
|
||||
*{bssid}*: MAC address (BSSID) of the wireless access point.
|
||||
|
||||
*{signalStrength}*: Signal strength of the wireless network.
|
||||
|
||||
*{signaldBm}*: Signal strength of the wireless network in dBm.
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
waybar-niri-language(5)
|
||||
|
||||
# NAME
|
||||
|
||||
waybar - niri language module
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
The *language* module displays the currently selected language in niri.
|
||||
|
||||
# CONFIGURATION
|
||||
|
||||
Addressed by *niri/language*
|
||||
|
||||
*format*: ++
|
||||
typeof: string ++
|
||||
default: {} ++
|
||||
The format, how information should be displayed.
|
||||
|
||||
*format-<lang>* ++
|
||||
typeof: string++
|
||||
Provide an alternative name to display per language where <lang> is the language of your choosing. Can be passed multiple times with multiple languages as shown by the example below.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{short}*: Short name of layout (e.g. "us"). Equals to {}.
|
||||
|
||||
*{shortDescription}*: Short description of layout (e.g. "en").
|
||||
|
||||
*{long}*: Long name of layout (e.g. "English (Dvorak)").
|
||||
|
||||
*{variant}*: Variant of layout (e.g. "dvorak").
|
||||
|
||||
# EXAMPLES
|
||||
|
||||
```
|
||||
"niri/language": {
|
||||
"format": "Lang: {long}"
|
||||
"format-en": "AMERICA, HELL YEAH!"
|
||||
"format-tr": "As bayrakları"
|
||||
}
|
||||
```
|
||||
|
||||
# STYLE
|
||||
|
||||
- *#language*
|
||||
@@ -0,0 +1,86 @@
|
||||
waybar-niri-window(5)
|
||||
|
||||
# NAME
|
||||
|
||||
waybar - niri window module
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
The *window* module displays the title of the currently focused window in niri.
|
||||
|
||||
# CONFIGURATION
|
||||
|
||||
Addressed by *niri/window*
|
||||
|
||||
*format*: ++
|
||||
typeof: string ++
|
||||
default: {title} ++
|
||||
The format, how information should be displayed. On {} the current window title is displayed.
|
||||
|
||||
*rewrite*: ++
|
||||
typeof: object ++
|
||||
Rules to rewrite window title. See *rewrite rules*.
|
||||
|
||||
*separate-outputs*: ++
|
||||
typeof: bool ++
|
||||
Show the active window of the monitor the bar belongs to, instead of the focused window.
|
||||
|
||||
*icon*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Option to hide the application icon.
|
||||
|
||||
*icon-size*: ++
|
||||
typeof: integer ++
|
||||
default: 24 ++
|
||||
Option to change the size of the application icon.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
See the output of "niri msg windows" for examples
|
||||
|
||||
*{title}*: The current title of the focused window.
|
||||
|
||||
*{app_id}*: The current app ID of the focused window.
|
||||
|
||||
# REWRITE RULES
|
||||
|
||||
*rewrite* is an object where keys are regular expressions and values are
|
||||
rewrite rules if the expression matches. Rules may contain references to
|
||||
captures of the expression.
|
||||
|
||||
Regular expression and replacement follow ECMA-script rules.
|
||||
|
||||
If no expression matches, the title is left unchanged.
|
||||
|
||||
Invalid expressions (e.g., mismatched parentheses) are skipped.
|
||||
|
||||
# EXAMPLES
|
||||
|
||||
```
|
||||
"niri/window": {
|
||||
"format": "{}",
|
||||
"rewrite": {
|
||||
"(.*) - Mozilla Firefox": "🌎 $1",
|
||||
"(.*) - zsh": "> [$1]"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
# STYLE
|
||||
|
||||
- *#window*
|
||||
- *window#waybar.empty #window* When no windows are on the workspace
|
||||
|
||||
The following classes are applied to the entire Waybar rather than just the
|
||||
window widget:
|
||||
|
||||
- *window#waybar.empty* When no windows are in the workspace
|
||||
- *window#waybar.solo* When only one window is on the workspace
|
||||
- *window#waybar.<app-id>* Where *app-id* is the app ID of the only window on
|
||||
the workspace
|
||||
@@ -0,0 +1,102 @@
|
||||
waybar-niri-workspaces(5)
|
||||
|
||||
# NAME
|
||||
|
||||
waybar - niri workspaces module
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
The *workspaces* module displays the currently used workspaces in niri.
|
||||
|
||||
# CONFIGURATION
|
||||
|
||||
Addressed by *niri/workspaces*
|
||||
|
||||
*all-outputs*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
If set to false, workspaces will only be shown on the output they are on. If set to true all workspaces will be shown on every output.
|
||||
|
||||
*format*: ++
|
||||
typeof: string ++
|
||||
default: {value} ++
|
||||
The format, how information should be displayed.
|
||||
|
||||
*format-icons*: ++
|
||||
typeof: array ++
|
||||
Based on the workspace name, index and state, the corresponding icon gets selected. See *icons*.
|
||||
|
||||
*disable-click*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
If set to false, you can click to change workspace. If set to true this behaviour is disabled.
|
||||
|
||||
*disable-markup*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
If set to true, button label will escape pango markup.
|
||||
|
||||
*current-only*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
If set to true, only the active or focused workspace will be shown.
|
||||
|
||||
*on-update*: ++
|
||||
typeof: string ++
|
||||
Command to execute when the module is updated.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{value}*: Name of the workspace, or index for unnamed workspaces,
|
||||
as defined by niri.
|
||||
|
||||
*{name}*: Name of the workspace for named workspaces.
|
||||
|
||||
*{icon}*: Icon, as defined in *format-icons*.
|
||||
|
||||
*{index}*: Index of the workspace on its output.
|
||||
|
||||
*{output}*: Output where the workspace is located.
|
||||
|
||||
# ICONS
|
||||
|
||||
Additional to workspace name matching, the following *format-icons* can be set.
|
||||
|
||||
- *default*: Will be shown, when no string matches are found.
|
||||
- *focused*: Will be shown, when workspace is focused.
|
||||
- *active*: Will be shown, when workspace is active on its output.
|
||||
|
||||
# EXAMPLES
|
||||
|
||||
```
|
||||
"niri/workspaces": {
|
||||
"format": "{icon}",
|
||||
"format-icons": {
|
||||
// Named workspaces
|
||||
// (you need to configure them in niri)
|
||||
"browser": "",
|
||||
"discord": "",
|
||||
"chat": "<b></b>",
|
||||
|
||||
// Icons by state
|
||||
"active": "",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
# Style
|
||||
|
||||
- *#workspaces button*
|
||||
- *#workspaces button.focused*: The single focused workspace.
|
||||
- *#workspaces button.active*: The workspace is active (visible) on its output.
|
||||
- *#workspaces button.empty*: The workspace is empty.
|
||||
- *#workspaces button.current_output*: The workspace is from the same output as
|
||||
the bar that it is displayed on.
|
||||
- *#workspaces button#niri-workspace-<name>*: Workspaces named this, or index
|
||||
for unnamed workspaces.
|
||||
@@ -35,6 +35,13 @@ $XDG_CONFIG_HOME/waybar/config
|
||||
:[ object
|
||||
:[ See default value in the example below.
|
||||
:[ Icons used to represent the various power-profile. *Note*: the default configuration uses the font-awesome icons. You may want to override it if you don't have this font installed on your system.
|
||||
|[ *expand*:
|
||||
:[ bool
|
||||
:[ false
|
||||
:[ Enables this module to consume all left over space dynamically.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# CONFIGURATION EXAMPLES
|
||||
|
||||
@@ -32,6 +32,11 @@ the screen or playing audio.
|
||||
Which privacy modules to monitor. See *MODULES CONFIGURATION* for++
|
||||
more information.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# MODULES CONFIGURATION
|
||||
|
||||
*type*: ++
|
||||
|
||||
@@ -27,6 +27,11 @@ The volume can be controlled by dragging the slider across the bar or clicking o
|
||||
default: horizontal ++
|
||||
The orientation of the slider. Can be either `horizontal` or `vertical`.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# EXAMPLES
|
||||
|
||||
```
|
||||
|
||||
@@ -40,7 +40,7 @@ Additionally, you can control the volume by scrolling *up* or *down* while the c
|
||||
|
||||
*rotate*: ++
|
||||
typeof: integer ++
|
||||
Positive value to rotate the text label.
|
||||
Positive value to rotate the text label (in 90 degree increments).
|
||||
|
||||
*states*: ++
|
||||
typeof: object ++
|
||||
@@ -126,6 +126,11 @@ Additionally, you can control the volume by scrolling *up* or *down* while the c
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{desc}*: Pulseaudio port's description, for bluetooth it'll be the device name.
|
||||
|
||||
@@ -21,7 +21,7 @@ Addressed by *river/layout*
|
||||
|
||||
*rotate*: ++
|
||||
typeof: integer ++
|
||||
Positive value to rotate the text label.
|
||||
Positive value to rotate the text label (in 90 degree increments).
|
||||
|
||||
*max-length*: ++
|
||||
typeof: integer ++
|
||||
@@ -64,6 +64,11 @@ Addressed by *river/layout*
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# EXAMPLE
|
||||
|
||||
```
|
||||
|
||||
@@ -19,7 +19,7 @@ Addressed by *river/mode*
|
||||
|
||||
*rotate*: ++
|
||||
typeof: integer ++
|
||||
Positive value to rotate the text label.
|
||||
Positive value to rotate the text label (in 90 degree increments).
|
||||
|
||||
*max-length*: ++
|
||||
typeof: integer ++
|
||||
@@ -78,6 +78,11 @@ Addressed by *river/mode*
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# EXAMPLES
|
||||
|
||||
```
|
||||
|
||||
@@ -26,6 +26,16 @@ Addressed by *river/tags*
|
||||
default: false ++
|
||||
If set to false, you can left-click to set focused tag. Right-click to toggle tag focus. If set to true this behaviour is disabled.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
*hide-vacant*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Only show relevant tags: tags that are either focused or have a window on them.
|
||||
|
||||
# EXAMPLE
|
||||
|
||||
```
|
||||
|
||||
@@ -19,7 +19,7 @@ Addressed by *river/window*
|
||||
|
||||
*rotate*: ++
|
||||
typeof: integer ++
|
||||
Positive value to rotate the text label.
|
||||
Positive value to rotate the text label (in 90 degree increments).
|
||||
|
||||
*max-length*: ++
|
||||
typeof: integer ++
|
||||
@@ -62,6 +62,11 @@ Addressed by *river/window*
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# EXAMPLES
|
||||
|
||||
```
|
||||
|
||||
@@ -20,7 +20,7 @@ cursor is over the module, and clicking on the module toggles mute.
|
||||
|
||||
*rotate*: ++
|
||||
typeof: integer ++
|
||||
Positive value to rotate the text label.
|
||||
Positive value to rotate the text label (in 90 degree increments).
|
||||
|
||||
*max-length*: ++
|
||||
typeof: integer ++
|
||||
@@ -87,6 +87,11 @@ cursor is over the module, and clicking on the module toggles mute.
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{volume}*: Volume in percentage.
|
||||
|
||||
@@ -39,6 +39,40 @@ You can apply special styling to any module for when the cursor hovers it.
|
||||
}
|
||||
```
|
||||
|
||||
## Setting cursor style
|
||||
|
||||
Most, if not all, module types support setting the `cursor` option. This is
|
||||
configured in your `config.jsonc`. If set to `false`, when hovering the module a
|
||||
"pointer"(as commonly known from web CSS styling `cursor: pointer`) style cursor
|
||||
will not be shown. Default behavior is to indicate an interaction event is
|
||||
available.
|
||||
|
||||
There are more cursor types to choose from by setting the `cursor` option to
|
||||
a number, see Gdk3 official docs for all possible cursor types:
|
||||
https://docs.gtk.org/gdk3/enum.CursorType.html.
|
||||
However, note that not all cursor options listed may be available on
|
||||
your system. If you attempt to use a cursor which is not available, the
|
||||
application will crash.
|
||||
|
||||
Example of disabling pointer(`Gdk::Hand2`) cursor type on a custom module:
|
||||
|
||||
```
|
||||
"custom/my-custom-module": {
|
||||
...
|
||||
"cursor": false,
|
||||
}
|
||||
```
|
||||
|
||||
Example of setting cursor type to `Gdk::Boat`(according to
|
||||
https://docs.gtk.org/gdk3/enum.CursorType.html#boat):
|
||||
|
||||
```
|
||||
"custom/my-custom-module": {
|
||||
...
|
||||
"cursor": 8,
|
||||
}
|
||||
```
|
||||
|
||||
# SEE ALSO
|
||||
|
||||
- *waybar(5)*
|
||||
|
||||
@@ -45,6 +45,11 @@ Addressed by *sway/language*
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{short}*: Short name of layout (e.g. "us"). Equals to {}.
|
||||
|
||||
@@ -19,7 +19,7 @@ Addressed by *sway/mode*
|
||||
|
||||
*rotate*: ++
|
||||
typeof: integer ++
|
||||
Positive value to rotate the text label.
|
||||
Positive value to rotate the text label (in 90 degree increments).
|
||||
|
||||
*max-length*: ++
|
||||
typeof: integer ++
|
||||
@@ -83,6 +83,11 @@ Addressed by *sway/mode*
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# EXAMPLES
|
||||
|
||||
```
|
||||
|
||||
@@ -49,6 +49,11 @@ Addressed by *sway/scratchpad*
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{icon}*: Icon, as defined in *format-icons*.
|
||||
|
||||
@@ -19,7 +19,7 @@ Addressed by *sway/window*
|
||||
|
||||
*rotate*: ++
|
||||
typeof: integer ++
|
||||
Positive value to rotate the text label.
|
||||
Positive value to rotate the text label (in 90 degree increments).
|
||||
|
||||
*max-length*: ++
|
||||
typeof: integer ++
|
||||
@@ -103,6 +103,11 @@ Addressed by *sway/window*
|
||||
default: 24 ++
|
||||
Option to change the size of the application icon.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{title}*: The title of the focused window.
|
||||
|
||||
@@ -87,6 +87,8 @@ warp-on-scroll: ++
|
||||
Regex rules to map window class to an icon or preferred method of representation for a workspace's window.
|
||||
Keys are the rules, while the values are the methods of representation.
|
||||
Rules may specify `class<...>`, `title<...>`, or both in order to fine-tune the matching.
|
||||
You may assign an empty value to a rule to have it ignored from generating any representation in workspaces.
|
||||
For Wayland windows `class` is matched against the `app_id`, and for X11 windows against the `class` property.
|
||||
|
||||
*window-rewrite-default*:
|
||||
typeof: string ++
|
||||
@@ -98,6 +100,11 @@ warp-on-scroll: ++
|
||||
default: " " ++
|
||||
The separator to be used between windows in a workspace.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
|
||||
@@ -49,6 +49,11 @@ Addressed by *systemd-failed-units*
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{nr_failed_system}*: Number of failed units from systemwide (PID=1) systemd.
|
||||
|
||||
@@ -31,6 +31,10 @@ Addressed by *temperature*
|
||||
typeof: string ++
|
||||
The temperature filename of your *hwmon-path-abs*, e.g. *temp1_input*
|
||||
|
||||
*warning-threshold*: ++
|
||||
typeof: integer ++
|
||||
The threshold before it is considered warning (Celsius).
|
||||
|
||||
*critical-threshold*: ++
|
||||
typeof: integer ++
|
||||
The threshold before it is considered critical (Celsius).
|
||||
@@ -40,6 +44,10 @@ Addressed by *temperature*
|
||||
default: 10 ++
|
||||
The interval in which the information gets polled.
|
||||
|
||||
*format-warning*: ++
|
||||
typeof: string ++
|
||||
The format to use when temperature is considered warning
|
||||
|
||||
*format-critical*: ++
|
||||
typeof: string ++
|
||||
The format to use when temperature is considered critical
|
||||
@@ -60,7 +68,7 @@ Addressed by *temperature*
|
||||
|
||||
*rotate*: ++
|
||||
typeof: integer ++
|
||||
Positive value to rotate the text label.
|
||||
Positive value to rotate the text label (in 90 degree increments).
|
||||
|
||||
*max-length*: ++
|
||||
typeof: integer ++
|
||||
@@ -124,6 +132,11 @@ Addressed by *temperature*
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{temperatureC}*: Temperature in Celsius.
|
||||
|
||||
+10
-1
@@ -37,12 +37,21 @@ Addressed by *tray*
|
||||
typeof: string ++
|
||||
Command to execute when the module is updated.
|
||||
|
||||
*expand*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables this module to consume all left over space dynamically.
|
||||
|
||||
# EXAMPLES
|
||||
|
||||
```
|
||||
"tray": {
|
||||
"icon-size": 21,
|
||||
"spacing": 10
|
||||
"spacing": 10,
|
||||
"icons": {
|
||||
"blueman": "bluetooth",
|
||||
"TelegramDesktop": "$HOME/.local/share/icons/hicolor/16x16/apps/telegram.png"
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
@@ -19,6 +19,11 @@ The *wireplumber* module displays the current volume reported by WirePlumber.
|
||||
typeof: string ++
|
||||
This format is used when the sound is muted.
|
||||
|
||||
*node-type*: ++
|
||||
typeof: string ++
|
||||
default: *Audio/Sink* ++
|
||||
The WirePlumber node type to attach to. Use *Audio/Source* to manage microphones etc.
|
||||
|
||||
*tooltip*: ++
|
||||
typeof: bool ++
|
||||
default: *true* ++
|
||||
@@ -31,7 +36,7 @@ The *wireplumber* module displays the current volume reported by WirePlumber.
|
||||
|
||||
*rotate*: ++
|
||||
typeof: integer ++
|
||||
Positive value to rotate the text label.
|
||||
Positive value to rotate the text label (in 90 degree increments).
|
||||
|
||||
*states*: ++
|
||||
typeof: object ++
|
||||
@@ -108,6 +113,8 @@ The *wireplumber* module displays the current volume reported by WirePlumber.
|
||||
|
||||
# EXAMPLES
|
||||
|
||||
## Basic:
|
||||
|
||||
```
|
||||
"wireplumber": {
|
||||
"format": "{volume}%",
|
||||
@@ -116,6 +123,26 @@ The *wireplumber* module displays the current volume reported by WirePlumber.
|
||||
}
|
||||
```
|
||||
|
||||
## Separate Sink and Source Widgets
|
||||
|
||||
```
|
||||
"wireplumber#sink": {
|
||||
"format": "{volume}% {icon}",
|
||||
"format-muted": "",
|
||||
"format-icons": ["", "", ""],
|
||||
"on-click": "helvum",
|
||||
"on-click-right": "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle",
|
||||
"scroll-step": 5
|
||||
},
|
||||
"wireplumber#source": {
|
||||
"node-type": "Audio/Source",
|
||||
"format": "{volume}% ",
|
||||
"format-muted": "",
|
||||
"on-click-right": "wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle",
|
||||
"scroll-step": 5
|
||||
}
|
||||
```
|
||||
|
||||
# STYLE
|
||||
|
||||
- *#wireplumber*
|
||||
|
||||
@@ -23,6 +23,21 @@ The visual display elements for waybar use a CSS stylesheet, see *waybar-styles(
|
||||
|
||||
# BAR CONFIGURATION
|
||||
|
||||
*expand-center* ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables the modules-center to consume all left over space dynamically.
|
||||
|
||||
*expand-left* ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables the modules-left to consume all left over space dynamically.
|
||||
|
||||
*expand-right* ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Enables the modules-left to consume all left over space dynamically.
|
||||
|
||||
*layer* ++
|
||||
typeof: string ++
|
||||
default: bottom ++
|
||||
@@ -68,6 +83,11 @@ The visual display elements for waybar use a CSS stylesheet, see *waybar-styles(
|
||||
typeof: integer ++
|
||||
Margins value without units.
|
||||
|
||||
*no-center* ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Option to disable the center modules fully usefull together with expand-\*.
|
||||
|
||||
*spacing* ++
|
||||
typeof: integer ++
|
||||
Size of gaps in between the different modules.
|
||||
@@ -181,6 +201,19 @@ A minimal *config* file could look like this:
|
||||
}
|
||||
```
|
||||
|
||||
# SIGNALS
|
||||
|
||||
Waybar accepts the following signals:
|
||||
|
||||
*SIGUSR1*
|
||||
Toggles the bar visibility (hides if shown, shows if hidden)
|
||||
*SIGUSR2*
|
||||
Reloads (resets) the bar
|
||||
*SIGINT*
|
||||
Quits the bar
|
||||
|
||||
For example, to toggle the bar programmatically, you can invoke `killall -SIGUSR1 waybar`.
|
||||
|
||||
# MULTI OUTPUT CONFIGURATION
|
||||
|
||||
## Limit a configuration to some outputs
|
||||
@@ -278,6 +311,11 @@ A group may hide all but one element, showing them only on mouse hover. In order
|
||||
default: "hidden" ++
|
||||
Defines the CSS class to be applied to the hidden elements.
|
||||
|
||||
*click-to-reveal*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Whether left click should reveal the content rather than mouse over. Note that grouped modules may still process their own on-click events.
|
||||
|
||||
*transition-left-to-right*: ++
|
||||
typeof: bool ++
|
||||
default: true ++
|
||||
@@ -318,6 +356,9 @@ A group may hide all but one element, showing them only on mouse hover. In order
|
||||
- *waybar-hyprland-submap(5)*
|
||||
- *waybar-hyprland-window(5)*
|
||||
- *waybar-hyprland-workspaces(5)*
|
||||
- *waybar-niri-language(5)*
|
||||
- *waybar-niri-window(5)*
|
||||
- *waybar-niri-workspaces(5)*
|
||||
- *waybar-idle-inhibitor(5)*
|
||||
- *waybar-image(5)*
|
||||
- *waybar-inhibitor(5)*
|
||||
|
||||
+23
-4
@@ -1,6 +1,6 @@
|
||||
project(
|
||||
'waybar', 'cpp', 'c',
|
||||
version: '0.10.3',
|
||||
version: '0.12.0',
|
||||
license: 'MIT',
|
||||
meson_version: '>= 0.59.0',
|
||||
default_options : [
|
||||
@@ -69,7 +69,7 @@ is_openbsd = host_machine.system() == 'openbsd'
|
||||
|
||||
thread_dep = dependency('threads')
|
||||
fmt = dependency('fmt', version : ['>=8.1.1'], fallback : ['fmt', 'fmt_dep'])
|
||||
spdlog = dependency('spdlog', version : ['>=1.10.0'], fallback : ['spdlog', 'spdlog_dep'], default_options : ['external_fmt=enabled'])
|
||||
spdlog = dependency('spdlog', version : ['>=1.10.0'], fallback : ['spdlog', 'spdlog_dep'], default_options : ['external_fmt=enabled', 'std_format=disabled', 'tests=disabled'])
|
||||
wayland_client = dependency('wayland-client')
|
||||
wayland_cursor = dependency('wayland-cursor')
|
||||
wayland_protos = dependency('wayland-protocols')
|
||||
@@ -106,7 +106,7 @@ if libsndio.found()
|
||||
endif
|
||||
endif
|
||||
|
||||
gtk_layer_shell = dependency('gtk-layer-shell-0', version: ['>=0.6.0'],
|
||||
gtk_layer_shell = dependency('gtk-layer-shell-0', version: ['>=0.9.0'],
|
||||
default_options: ['introspection=false', 'vapi=false'],
|
||||
fallback: ['gtk-layer-shell', 'gtk_layer_shell'])
|
||||
systemd = dependency('systemd', required: get_option('systemd'))
|
||||
@@ -318,6 +318,25 @@ if true
|
||||
)
|
||||
endif
|
||||
|
||||
if get_option('niri')
|
||||
add_project_arguments('-DHAVE_NIRI', language: 'cpp')
|
||||
src_files += files(
|
||||
'src/modules/niri/backend.cpp',
|
||||
'src/modules/niri/language.cpp',
|
||||
'src/modules/niri/window.cpp',
|
||||
'src/modules/niri/workspaces.cpp',
|
||||
)
|
||||
man_files += files(
|
||||
'man/waybar-niri-language.5.scd',
|
||||
'man/waybar-niri-window.5.scd',
|
||||
'man/waybar-niri-workspaces.5.scd',
|
||||
)
|
||||
endif
|
||||
|
||||
if get_option('login-proxy')
|
||||
add_project_arguments('-DHAVE_LOGIN_PROXY', language: 'cpp')
|
||||
endif
|
||||
|
||||
if libnl.found() and libnlgen.found()
|
||||
add_project_arguments('-DHAVE_LIBNL', language: 'cpp')
|
||||
src_files += files('src/modules/network.cpp')
|
||||
@@ -467,7 +486,7 @@ if get_option('experimental')
|
||||
endif
|
||||
|
||||
cava = dependency('cava',
|
||||
version : '>=0.10.2',
|
||||
version : '>=0.10.3',
|
||||
required: get_option('cava'),
|
||||
fallback : ['cava', 'cava_dep'],
|
||||
not_found_message: 'cava is not found. Building waybar without cava')
|
||||
|
||||
@@ -19,3 +19,5 @@ option('experimental', type : 'boolean', value : false, description: 'Enable exp
|
||||
option('jack', type: 'feature', value: 'auto', description: 'Enable support for JACK')
|
||||
option('wireplumber', type: 'feature', value: 'auto', description: 'Enable support for WirePlumber')
|
||||
option('cava', type: 'feature', value: 'auto', description: 'Enable support for Cava')
|
||||
option('niri', type: 'boolean', description: 'Enable support for niri')
|
||||
option('login-proxy', type: 'boolean', description: 'Enable interfacing with dbus login interface')
|
||||
|
||||
+7
-2
@@ -5,12 +5,12 @@
|
||||
}:
|
||||
let
|
||||
libcava = rec {
|
||||
version = "0.10.2";
|
||||
version = "0.10.3";
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "LukashonakV";
|
||||
repo = "cava";
|
||||
rev = version;
|
||||
hash = "sha256-jU7RQV2txruu/nUUl0TzjK4nai7G38J1rcTjO7UXumY=";
|
||||
hash = "sha256-ZDFbI69ECsUTjbhlw2kHRufZbQMu+FQSMmncCJ5pagg=";
|
||||
};
|
||||
};
|
||||
in
|
||||
@@ -25,6 +25,11 @@ in
|
||||
|
||||
mesonFlags = lib.remove "-Dgtk-layer-shell=enabled" oldAttrs.mesonFlags;
|
||||
|
||||
# downstream patch should not affect upstream
|
||||
patches = [];
|
||||
# nixpkgs checks version, no need when building locally
|
||||
nativeInstallCheckInputs = [];
|
||||
|
||||
buildInputs = (builtins.filter (p: p.pname != "wireplumber") oldAttrs.buildInputs) ++ [
|
||||
pkgs.wireplumber
|
||||
];
|
||||
|
||||
@@ -104,7 +104,11 @@
|
||||
},
|
||||
"tray": {
|
||||
// "icon-size": 21,
|
||||
"spacing": 10
|
||||
"spacing": 10,
|
||||
// "icons": {
|
||||
// "blueman": "bluetooth",
|
||||
// "TelegramDesktop": "$HOME/.local/share/icons/hicolor/16x16/apps/telegram.png"
|
||||
// }
|
||||
},
|
||||
"clock": {
|
||||
// "timezone": "America/New_York",
|
||||
@@ -189,7 +193,7 @@
|
||||
"on-click": "pavucontrol"
|
||||
},
|
||||
"custom/media": {
|
||||
"format": "{icon} {}",
|
||||
"format": "{icon} {text}",
|
||||
"return-type": "json",
|
||||
"max-length": 40,
|
||||
"format-icons": {
|
||||
|
||||
@@ -17,7 +17,7 @@ void onclicked(GtkButton* button) {
|
||||
}
|
||||
|
||||
// You must
|
||||
const size_t wbcffi_version = 1;
|
||||
const size_t wbcffi_version = 2;
|
||||
|
||||
void* wbcffi_init(const wbcffi_init_info* init_info, const wbcffi_config_entry* config_entries,
|
||||
size_t config_entries_len) {
|
||||
@@ -67,4 +67,4 @@ void wbcffi_refresh(void* instance, int signal) {
|
||||
|
||||
void wbcffi_doaction(void* instance, const char* name) {
|
||||
printf("cffi_example inst=%p: doAction(%s)\n", instance, name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// Waybar ABI version. 1 is the latest version
|
||||
/// Waybar ABI version. 2 is the latest version
|
||||
extern const size_t wbcffi_version;
|
||||
|
||||
/// Private Waybar CFFI module
|
||||
@@ -35,7 +35,13 @@ typedef struct {
|
||||
typedef struct {
|
||||
/// Entry key
|
||||
const char* key;
|
||||
/// Entry value as string. JSON object and arrays are serialized.
|
||||
/// Entry value
|
||||
///
|
||||
/// In ABI version 1, this may be either a bare string if the value is a
|
||||
/// string, or the JSON representation of any other JSON object as a string.
|
||||
///
|
||||
/// From ABI version 2 onwards, this is always the JSON representation of the
|
||||
/// value as a string.
|
||||
const char* value;
|
||||
} wbcffi_config_entry;
|
||||
|
||||
|
||||
@@ -154,6 +154,15 @@ void AAppIconLabel::updateAppIcon() {
|
||||
update_app_icon_ = false;
|
||||
if (app_icon_name_.empty()) {
|
||||
image_.set_visible(false);
|
||||
} else if (app_icon_name_.front() == '/') {
|
||||
auto pixbuf = Gdk::Pixbuf::create_from_file(app_icon_name_);
|
||||
int scaled_icon_size = app_icon_size_ * image_.get_scale_factor();
|
||||
pixbuf = Gdk::Pixbuf::create_from_file(app_icon_name_, scaled_icon_size, scaled_icon_size);
|
||||
|
||||
auto surface = Gdk::Cairo::create_surface_from_pixbuf(pixbuf, image_.get_scale_factor(),
|
||||
image_.get_window());
|
||||
image_.set(surface);
|
||||
image_.set_visible(true);
|
||||
} else {
|
||||
image_.set_from_icon_name(app_icon_name_, Gtk::ICON_SIZE_INVALID);
|
||||
image_.set_visible(true);
|
||||
|
||||
+13
-1
@@ -6,6 +6,8 @@
|
||||
#include <iostream>
|
||||
#include <util/command.hpp>
|
||||
|
||||
#include "config.hpp"
|
||||
|
||||
namespace waybar {
|
||||
|
||||
ALabel::ALabel(const Json::Value& config, const std::string& name, const std::string& id,
|
||||
@@ -43,6 +45,8 @@ ALabel::ALabel(const Json::Value& config, const std::string& name, const std::st
|
||||
|
||||
if (config_["rotate"].isUInt()) {
|
||||
rotate = config["rotate"].asUInt();
|
||||
if (not(rotate == 0 || rotate == 90 || rotate == 180 || rotate == 270))
|
||||
spdlog::warn("'rotate' is only supported in 90 degree increments {} is not valid.", rotate);
|
||||
label_.set_angle(rotate);
|
||||
}
|
||||
|
||||
@@ -61,6 +65,14 @@ ALabel::ALabel(const Json::Value& config, const std::string& name, const std::st
|
||||
try {
|
||||
// Check that the file exists
|
||||
std::string menuFile = config_["menu-file"].asString();
|
||||
|
||||
// there might be "~" or "$HOME" in original path, try to expand it.
|
||||
auto result = Config::tryExpandPath(menuFile, "");
|
||||
if (result.empty()) {
|
||||
throw std::runtime_error("Failed to expand file: " + menuFile);
|
||||
}
|
||||
|
||||
menuFile = result.front();
|
||||
// Read the menu descriptor file
|
||||
std::ifstream file(menuFile);
|
||||
if (!file.is_open()) {
|
||||
@@ -170,7 +182,7 @@ bool waybar::ALabel::handleToggle(GdkEventButton* const& e) {
|
||||
return AModule::handleToggle(e);
|
||||
}
|
||||
|
||||
void ALabel::handleGtkMenuEvent(GtkMenuItem* menuitem, gpointer data) {
|
||||
void ALabel::handleGtkMenuEvent(GtkMenuItem* /*menuitem*/, gpointer data) {
|
||||
waybar::util::command::res res = waybar::util::command::exec((char*)data, "GtkMenu");
|
||||
}
|
||||
|
||||
|
||||
+36
-4
@@ -1,9 +1,13 @@
|
||||
#include "AModule.hpp"
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
#include <util/command.hpp>
|
||||
|
||||
#include "gdk/gdk.h"
|
||||
#include "gdkmm/cursor.h"
|
||||
|
||||
namespace waybar {
|
||||
|
||||
AModule::AModule(const Json::Value& config, const std::string& name, const std::string& id,
|
||||
@@ -11,6 +15,7 @@ AModule::AModule(const Json::Value& config, const std::string& name, const std::
|
||||
: name_(name),
|
||||
config_(config),
|
||||
isTooltip{config_["tooltip"].isBool() ? config_["tooltip"].asBool() : true},
|
||||
isExpand{config_["expand"].isBool() ? config_["expand"].asBool() : false},
|
||||
distance_scrolled_y_(0.0),
|
||||
distance_scrolled_x_(0.0) {
|
||||
// Configure module action Map
|
||||
@@ -64,6 +69,17 @@ AModule::AModule(const Json::Value& config, const std::string& name, const std::
|
||||
event_box_.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK);
|
||||
event_box_.signal_scroll_event().connect(sigc::mem_fun(*this, &AModule::handleScroll));
|
||||
}
|
||||
|
||||
// Respect user configuration of cursor
|
||||
if (config_.isMember("cursor")) {
|
||||
if (config_["cursor"].isBool() && config_["cursor"].asBool()) {
|
||||
setCursor(Gdk::HAND2);
|
||||
} else if (config_["cursor"].isInt()) {
|
||||
setCursor(Gdk::CursorType(config_["cursor"].asInt()));
|
||||
} else {
|
||||
spdlog::warn("unknown cursor option configured on module {}", name_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AModule::~AModule() {
|
||||
@@ -91,9 +107,20 @@ auto AModule::doAction(const std::string& name) -> void {
|
||||
}
|
||||
|
||||
void AModule::setCursor(Gdk::CursorType const& c) {
|
||||
auto cursor = Gdk::Cursor::create(c);
|
||||
auto gdk_window = event_box_.get_window();
|
||||
gdk_window->set_cursor(cursor);
|
||||
if (gdk_window) {
|
||||
auto cursor = Gdk::Cursor::create(c);
|
||||
gdk_window->set_cursor(cursor);
|
||||
} else {
|
||||
// window may not be accessible yet, in this case,
|
||||
// schedule another call for setting the cursor in 1 sec
|
||||
Glib::signal_timeout().connect_seconds(
|
||||
[this, c]() {
|
||||
setCursor(c);
|
||||
return false;
|
||||
},
|
||||
1);
|
||||
}
|
||||
}
|
||||
|
||||
bool AModule::handleMouseEnter(GdkEventCrossing* const& e) {
|
||||
@@ -101,9 +128,11 @@ bool AModule::handleMouseEnter(GdkEventCrossing* const& e) {
|
||||
module->set_state_flags(Gtk::StateFlags::STATE_FLAG_PRELIGHT);
|
||||
}
|
||||
|
||||
if (hasUserEvents_) {
|
||||
// Default behavior indicating event availability
|
||||
if (hasUserEvents_ && !config_.isMember("cursor")) {
|
||||
setCursor(Gdk::HAND2);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -112,9 +141,11 @@ bool AModule::handleMouseLeave(GdkEventCrossing* const& e) {
|
||||
module->unset_state_flags(Gtk::StateFlags::STATE_FLAG_PRELIGHT);
|
||||
}
|
||||
|
||||
if (hasUserEvents_) {
|
||||
// Default behavior indicating event availability
|
||||
if (hasUserEvents_ && !config_.isMember("cursor")) {
|
||||
setCursor(Gdk::ARROW);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -243,6 +274,7 @@ bool AModule::handleScroll(GdkEventScroll* e) {
|
||||
}
|
||||
|
||||
bool AModule::tooltipEnabled() const { return isTooltip; }
|
||||
bool AModule::expandEnabled() const { return isExpand; }
|
||||
|
||||
AModule::operator Gtk::Widget&() { return event_box_; }
|
||||
|
||||
|
||||
+45
-20
@@ -37,19 +37,19 @@ const Bar::bar_mode_map Bar::PRESET_MODES = { //
|
||||
.visible = true}},
|
||||
{"hide",
|
||||
{//
|
||||
.layer = bar_layer::TOP,
|
||||
.layer = bar_layer::OVERLAY,
|
||||
.exclusive = false,
|
||||
.passthrough = false,
|
||||
.visible = true}},
|
||||
{"invisible",
|
||||
{//
|
||||
.layer = std::nullopt,
|
||||
.layer = bar_layer::BOTTOM,
|
||||
.exclusive = false,
|
||||
.passthrough = true,
|
||||
.visible = false}},
|
||||
{"overlay",
|
||||
{//
|
||||
.layer = bar_layer::TOP,
|
||||
.layer = bar_layer::OVERLAY,
|
||||
.exclusive = false,
|
||||
.passthrough = true,
|
||||
.visible = true}}};
|
||||
@@ -59,7 +59,7 @@ const std::string Bar::MODE_INVISIBLE = "invisible";
|
||||
const std::string_view DEFAULT_BAR_ID = "bar-0";
|
||||
|
||||
/* Deserializer for enum bar_layer */
|
||||
void from_json(const Json::Value& j, std::optional<bar_layer>& l) {
|
||||
void from_json(const Json::Value& j, bar_layer& l) {
|
||||
if (j == "bottom") {
|
||||
l = bar_layer::BOTTOM;
|
||||
} else if (j == "top") {
|
||||
@@ -132,6 +132,7 @@ void from_json(const Json::Value& j, std::map<Key, Value>& m) {
|
||||
waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config)
|
||||
: output(w_output),
|
||||
config(w_config),
|
||||
surface(nullptr),
|
||||
window{Gtk::WindowType::WINDOW_TOPLEVEL},
|
||||
x_global(0),
|
||||
y_global(0),
|
||||
@@ -316,13 +317,13 @@ void waybar::Bar::setMode(const std::string& mode) {
|
||||
void waybar::Bar::setMode(const struct bar_mode& mode) {
|
||||
auto* gtk_window = window.gobj();
|
||||
|
||||
if (mode.layer == bar_layer::BOTTOM) {
|
||||
gtk_layer_set_layer(gtk_window, GTK_LAYER_SHELL_LAYER_BOTTOM);
|
||||
} else if (mode.layer == bar_layer::TOP) {
|
||||
gtk_layer_set_layer(gtk_window, GTK_LAYER_SHELL_LAYER_TOP);
|
||||
auto layer = GTK_LAYER_SHELL_LAYER_BOTTOM;
|
||||
if (mode.layer == bar_layer::TOP) {
|
||||
layer = GTK_LAYER_SHELL_LAYER_TOP;
|
||||
} else if (mode.layer == bar_layer::OVERLAY) {
|
||||
gtk_layer_set_layer(gtk_window, GTK_LAYER_SHELL_LAYER_OVERLAY);
|
||||
layer = GTK_LAYER_SHELL_LAYER_OVERLAY;
|
||||
}
|
||||
gtk_layer_set_layer(gtk_window, layer);
|
||||
|
||||
if (mode.exclusive) {
|
||||
gtk_layer_auto_exclusive_zone_enable(gtk_window);
|
||||
@@ -339,6 +340,13 @@ void waybar::Bar::setMode(const struct bar_mode& mode) {
|
||||
window.get_style_context()->add_class("hidden");
|
||||
window.set_opacity(0);
|
||||
}
|
||||
/*
|
||||
* All the changes above require `wl_surface_commit`.
|
||||
* gtk-layer-shell schedules a commit on the next frame event in GTK, but this could fail in
|
||||
* certain scenarios, such as fully occluded bar.
|
||||
*/
|
||||
gtk_layer_try_force_commit(gtk_window);
|
||||
wl_display_flush(Client::inst()->wl_display);
|
||||
}
|
||||
|
||||
void waybar::Bar::setPassThrough(bool passthrough) {
|
||||
@@ -404,7 +412,8 @@ void waybar::Bar::onMap(GdkEventAny* /*unused*/) {
|
||||
setPassThrough(passthrough_);
|
||||
}
|
||||
|
||||
void waybar::Bar::setVisible(bool visible) {
|
||||
void waybar::Bar::setVisible(bool value) {
|
||||
visible = value;
|
||||
if (auto mode = config.get("mode", {}); mode.isString()) {
|
||||
setMode(visible ? config["mode"].asString() : MODE_INVISIBLE);
|
||||
} else {
|
||||
@@ -525,13 +534,22 @@ void waybar::Bar::getModules(const Factory& factory, const std::string& pos,
|
||||
|
||||
auto waybar::Bar::setupWidgets() -> void {
|
||||
window.add(box_);
|
||||
box_.pack_start(left_, false, false);
|
||||
if (config["fixed-center"].isBool() ? config["fixed-center"].asBool() : true) {
|
||||
box_.set_center_widget(center_);
|
||||
} else {
|
||||
box_.pack_start(center_, true, false);
|
||||
|
||||
bool expand_left = config["expand-left"].isBool() ? config["expand-left"].asBool() : false;
|
||||
bool expand_center = config["expand-center"].isBool() ? config["expand-center"].asBool() : false;
|
||||
bool expand_right = config["expand-right"].isBool() ? config["expand-right"].asBool() : false;
|
||||
bool no_center = config["no-center"].isBool() ? config["no-center"].asBool() : false;
|
||||
|
||||
box_.pack_start(left_, expand_left, expand_left);
|
||||
if (!no_center) {
|
||||
if (config["fixed-center"].isBool() ? config["fixed-center"].asBool() : true) {
|
||||
box_.set_center_widget(center_);
|
||||
} else {
|
||||
spdlog::error("No fixed center_");
|
||||
box_.pack_start(center_, true, expand_center);
|
||||
}
|
||||
}
|
||||
box_.pack_end(right_, false, false);
|
||||
box_.pack_end(right_, expand_right, expand_right);
|
||||
|
||||
// Convert to button code for every module that is used.
|
||||
setupAltFormatKeyForModuleList("modules-left");
|
||||
@@ -540,14 +558,21 @@ auto waybar::Bar::setupWidgets() -> void {
|
||||
|
||||
Factory factory(*this, config);
|
||||
getModules(factory, "modules-left");
|
||||
getModules(factory, "modules-center");
|
||||
if (!no_center) {
|
||||
getModules(factory, "modules-center");
|
||||
}
|
||||
getModules(factory, "modules-right");
|
||||
|
||||
for (auto const& module : modules_left_) {
|
||||
left_.pack_start(*module, false, false);
|
||||
left_.pack_start(*module, module->expandEnabled(), module->expandEnabled());
|
||||
}
|
||||
for (auto const& module : modules_center_) {
|
||||
center_.pack_start(*module, false, false);
|
||||
|
||||
if (!no_center) {
|
||||
for (auto const& module : modules_center_) {
|
||||
center_.pack_start(*module, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
std::reverse(modules_right_.begin(), modules_right_.end());
|
||||
for (auto const& module : modules_right_) {
|
||||
right_.pack_end(*module, false, false);
|
||||
|
||||
+2
-1
@@ -123,7 +123,8 @@ void waybar::Client::handleMonitorAdded(Glib::RefPtr<Gdk::Monitor> monitor) {
|
||||
}
|
||||
|
||||
void waybar::Client::handleMonitorRemoved(Glib::RefPtr<Gdk::Monitor> monitor) {
|
||||
spdlog::debug("Output removed: {} {}", monitor->get_manufacturer().c_str(), monitor->get_model().c_str());
|
||||
spdlog::debug("Output removed: {} {}", monitor->get_manufacturer().c_str(),
|
||||
monitor->get_model().c_str());
|
||||
/* This event can be triggered from wl_display_roundtrip called by GTK or our code.
|
||||
* Defer destruction of bars for the output to the next iteration of the event loop to avoid
|
||||
* deleting objects referenced by currently executed code.
|
||||
|
||||
+20
-13
@@ -21,7 +21,8 @@ const std::vector<std::string> Config::CONFIG_DIRS = {
|
||||
|
||||
const char *Config::CONFIG_PATH_ENV = "WAYBAR_CONFIG_DIR";
|
||||
|
||||
std::optional<std::string> tryExpandPath(const std::string &base, const std::string &filename) {
|
||||
std::vector<std::string> Config::tryExpandPath(const std::string &base,
|
||||
const std::string &filename) {
|
||||
fs::path path;
|
||||
|
||||
if (!filename.empty()) {
|
||||
@@ -32,33 +33,35 @@ std::optional<std::string> tryExpandPath(const std::string &base, const std::str
|
||||
|
||||
spdlog::debug("Try expanding: {}", path.string());
|
||||
|
||||
std::vector<std::string> results;
|
||||
wordexp_t p;
|
||||
if (wordexp(path.c_str(), &p, 0) == 0) {
|
||||
if (access(*p.we_wordv, F_OK) == 0) {
|
||||
std::string result = *p.we_wordv;
|
||||
wordfree(&p);
|
||||
spdlog::debug("Found config file: {}", path.string());
|
||||
return result;
|
||||
for (size_t i = 0; i < p.we_wordc; i++) {
|
||||
if (access(p.we_wordv[i], F_OK) == 0) {
|
||||
results.emplace_back(p.we_wordv[i]);
|
||||
spdlog::debug("Found config file: {}", p.we_wordv[i]);
|
||||
}
|
||||
}
|
||||
wordfree(&p);
|
||||
}
|
||||
return std::nullopt;
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
std::optional<std::string> Config::findConfigPath(const std::vector<std::string> &names,
|
||||
const std::vector<std::string> &dirs) {
|
||||
if (const char *dir = std::getenv(Config::CONFIG_PATH_ENV)) {
|
||||
for (const auto &name : names) {
|
||||
if (auto res = tryExpandPath(dir, name); res) {
|
||||
return res;
|
||||
if (auto res = tryExpandPath(dir, name); !res.empty()) {
|
||||
return res.front();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto &dir : dirs) {
|
||||
for (const auto &name : names) {
|
||||
if (auto res = tryExpandPath(dir, name); res) {
|
||||
return res;
|
||||
if (auto res = tryExpandPath(dir, name); !res.empty()) {
|
||||
return res.front();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -91,11 +94,15 @@ void Config::resolveConfigIncludes(Json::Value &config, int depth) {
|
||||
if (includes.isArray()) {
|
||||
for (const auto &include : includes) {
|
||||
spdlog::info("Including resource file: {}", include.asString());
|
||||
setupConfig(config, tryExpandPath(include.asString(), "").value_or(""), ++depth);
|
||||
for (const auto &match : tryExpandPath(include.asString(), "")) {
|
||||
setupConfig(config, match, depth + 1);
|
||||
}
|
||||
}
|
||||
} else if (includes.isString()) {
|
||||
spdlog::info("Including resource file: {}", includes.asString());
|
||||
setupConfig(config, tryExpandPath(includes.asString(), "").value_or(""), ++depth);
|
||||
for (const auto &match : tryExpandPath(includes.asString(), "")) {
|
||||
setupConfig(config, match, depth + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+17
-1
@@ -36,6 +36,11 @@
|
||||
#include "modules/hyprland/window.hpp"
|
||||
#include "modules/hyprland/workspaces.hpp"
|
||||
#endif
|
||||
#ifdef HAVE_NIRI
|
||||
#include "modules/niri/language.hpp"
|
||||
#include "modules/niri/window.hpp"
|
||||
#include "modules/niri/workspaces.hpp"
|
||||
#endif
|
||||
#if defined(__FreeBSD__) || defined(__linux__)
|
||||
#include "modules/battery.hpp"
|
||||
#endif
|
||||
@@ -135,7 +140,7 @@ waybar::AModule* waybar::Factory::makeModule(const std::string& name,
|
||||
#endif
|
||||
#ifdef HAVE_PIPEWIRE
|
||||
if (ref == "privacy") {
|
||||
return new waybar::modules::privacy::Privacy(id, config_[name], pos);
|
||||
return new waybar::modules::privacy::Privacy(id, config_[name], bar_.orientation, pos);
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_MPRIS
|
||||
@@ -205,6 +210,17 @@ waybar::AModule* waybar::Factory::makeModule(const std::string& name,
|
||||
if (ref == "hyprland/workspaces") {
|
||||
return new waybar::modules::hyprland::Workspaces(id, bar_, config_[name]);
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_NIRI
|
||||
if (ref == "niri/language") {
|
||||
return new waybar::modules::niri::Language(id, bar_, config_[name]);
|
||||
}
|
||||
if (ref == "niri/window") {
|
||||
return new waybar::modules::niri::Window(id, bar_, config_[name]);
|
||||
}
|
||||
if (ref == "niri/workspaces") {
|
||||
return new waybar::modules::niri::Workspaces(id, bar_, config_[name]);
|
||||
}
|
||||
#endif
|
||||
if (ref == "idle_inhibitor") {
|
||||
return new waybar::modules::IdleInhibitor(id, bar_, config_[name]);
|
||||
|
||||
+29
-4
@@ -9,7 +9,7 @@
|
||||
|
||||
namespace waybar {
|
||||
|
||||
const Gtk::RevealerTransitionType getPreferredTransitionType(bool is_vertical) {
|
||||
Gtk::RevealerTransitionType getPreferredTransitionType(bool is_vertical) {
|
||||
/* The transition direction of a drawer is not actually determined by the transition type,
|
||||
* but rather by the order of 'box' and 'revealer_box':
|
||||
* 'REVEALER_TRANSITION_TYPE_SLIDE_LEFT' and 'REVEALER_TRANSITION_TYPE_SLIDE_RIGHT'
|
||||
@@ -62,6 +62,7 @@ Group::Group(const std::string& name, const std::string& id, const Json::Value&
|
||||
const bool left_to_right = (drawer_config["transition-left-to-right"].isBool()
|
||||
? drawer_config["transition-left-to-right"].asBool()
|
||||
: true);
|
||||
click_to_reveal = drawer_config["click-to-reveal"].asBool();
|
||||
|
||||
auto transition_type = getPreferredTransitionType(vertical);
|
||||
|
||||
@@ -83,18 +84,42 @@ Group::Group(const std::string& name, const std::string& id, const Json::Value&
|
||||
event_box_.add(box);
|
||||
}
|
||||
|
||||
bool Group::handleMouseEnter(GdkEventCrossing* const& e) {
|
||||
void Group::show_group() {
|
||||
box.set_state_flags(Gtk::StateFlags::STATE_FLAG_PRELIGHT);
|
||||
revealer.set_reveal_child(true);
|
||||
}
|
||||
|
||||
void Group::hide_group() {
|
||||
box.unset_state_flags(Gtk::StateFlags::STATE_FLAG_PRELIGHT);
|
||||
revealer.set_reveal_child(false);
|
||||
}
|
||||
|
||||
bool Group::handleMouseEnter(GdkEventCrossing* const& e) {
|
||||
if (!click_to_reveal) {
|
||||
show_group();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Group::handleMouseLeave(GdkEventCrossing* const& e) {
|
||||
box.unset_state_flags(Gtk::StateFlags::STATE_FLAG_PRELIGHT);
|
||||
revealer.set_reveal_child(false);
|
||||
if (!click_to_reveal && e->detail != GDK_NOTIFY_INFERIOR) {
|
||||
hide_group();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Group::handleToggle(GdkEventButton* const& e) {
|
||||
if (!click_to_reveal || e->button != 1) {
|
||||
return false;
|
||||
}
|
||||
if ((box.get_state_flags() & Gtk::StateFlags::STATE_FLAG_PRELIGHT) != 0U) {
|
||||
hide_group();
|
||||
} else {
|
||||
show_group();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
auto Group::update() -> void {
|
||||
// noop
|
||||
}
|
||||
|
||||
@@ -107,6 +107,10 @@ int main(int argc, char* argv[]) {
|
||||
ret = client->main(argc, argv);
|
||||
} while (reload);
|
||||
|
||||
std::signal(SIGUSR1, SIG_IGN);
|
||||
std::signal(SIGUSR2, SIG_IGN);
|
||||
std::signal(SIGINT, SIG_IGN);
|
||||
|
||||
delete client;
|
||||
return ret;
|
||||
} catch (const std::exception& e) {
|
||||
|
||||
@@ -112,6 +112,14 @@ bool waybar::modules::Backlight::handleScroll(GdkEventScroll *e) {
|
||||
step = config_["scroll-step"].asDouble();
|
||||
}
|
||||
|
||||
double min_brightness = 0;
|
||||
if (config_["min-brightness"].isDouble()) {
|
||||
min_brightness = config_["min-brightness"].asDouble();
|
||||
}
|
||||
if (backend.get_scaled_brightness(preferred_device_) <= min_brightness &&
|
||||
ct == util::ChangeType::Decrease) {
|
||||
return true;
|
||||
}
|
||||
backend.set_brightness(preferred_device_, ct, step);
|
||||
|
||||
return true;
|
||||
|
||||
+11
-3
@@ -273,14 +273,18 @@ waybar::modules::Battery::getInfos() {
|
||||
// Scale these by the voltage to get μW/μWh.
|
||||
|
||||
uint32_t current_now = 0;
|
||||
int32_t _current_now_int = 0;
|
||||
bool current_now_exists = false;
|
||||
if (fs::exists(bat / "current_now")) {
|
||||
current_now_exists = true;
|
||||
std::ifstream(bat / "current_now") >> current_now;
|
||||
std::ifstream(bat / "current_now") >> _current_now_int;
|
||||
} else if (fs::exists(bat / "current_avg")) {
|
||||
current_now_exists = true;
|
||||
std::ifstream(bat / "current_avg") >> current_now;
|
||||
std::ifstream(bat / "current_avg") >> _current_now_int;
|
||||
}
|
||||
// Documentation ABI allows a negative value when discharging, positive
|
||||
// value when charging.
|
||||
current_now = std::abs(_current_now_int);
|
||||
|
||||
if (fs::exists(bat / "time_to_empty_now")) {
|
||||
time_to_empty_now_exists = true;
|
||||
@@ -324,11 +328,15 @@ waybar::modules::Battery::getInfos() {
|
||||
}
|
||||
|
||||
uint32_t power_now = 0;
|
||||
int32_t _power_now_int = 0;
|
||||
bool power_now_exists = false;
|
||||
if (fs::exists(bat / "power_now")) {
|
||||
power_now_exists = true;
|
||||
std::ifstream(bat / "power_now") >> power_now;
|
||||
std::ifstream(bat / "power_now") >> _power_now_int;
|
||||
}
|
||||
// Some drivers (example: Qualcomm) exposes use a negative value when
|
||||
// discharging, positive value when charging.
|
||||
power_now = std::abs(_power_now_int);
|
||||
|
||||
uint32_t energy_now = 0;
|
||||
bool energy_now_exists = false;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user