Merge branch 'Alexays:master' into hyprland/windowcount

This commit is contained in:
Khiet Tam Nguyen
2024-10-06 00:34:20 +10:00
committed by GitHub
18 changed files with 130 additions and 65 deletions

View File

@ -8,6 +8,7 @@ on:
jobs: jobs:
build-and-push: build-and-push:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: github.repository == 'Alexays/Waybar'
strategy: strategy:
fail-fast: false # don't fail the other jobs if one of the images fails to build fail-fast: false # don't fail the other jobs if one of the images fails to build
matrix: matrix:

View File

@ -9,6 +9,7 @@ on:
jobs: jobs:
lockfile: lockfile:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: github.event_name != 'schedule' || github.repository == 'Alexays/Waybar'
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v4

6
flake.lock generated
View File

@ -18,11 +18,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1724819573, "lastModified": 1727634051,
"narHash": "sha256-GnR7/ibgIH1vhoy8cYdmXE6iyZqKqFxQSVkFgosBh6w=", "narHash": "sha256-S5kVU7U82LfpEukbn/ihcyNt2+EvG7Z5unsKW9H/yFA=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "71e91c409d1e654808b2621f28a327acfdad8dc2", "rev": "06cf0e1da4208d3766d898b7fdab6513366d45b9",
"type": "github" "type": "github"
}, },
"original": { "original": {

View File

@ -42,7 +42,7 @@ struct bar_margins {
}; };
struct bar_mode { struct bar_mode {
std::optional<bar_layer> layer; bar_layer layer;
bool exclusive; bool exclusive;
bool passthrough; bool passthrough;
bool visible; bool visible;

View File

@ -39,6 +39,7 @@ class Cava final : public ALabel {
std::chrono::seconds suspend_silence_delay_{0}; std::chrono::seconds suspend_silence_delay_{0};
bool silence_{false}; bool silence_{false};
bool hide_on_silence_{false}; bool hide_on_silence_{false};
std::string format_silent_{""};
int sleep_counter_{0}; int sleep_counter_{0};
// Cava method // Cava method
void pause_resume(); void pause_resume();

View File

@ -81,6 +81,11 @@ The *backlight* module displays the current backlight level.
default: 1.0 ++ default: 1.0 ++
The speed at which to change the brightness when scrolling. The speed at which to change the brightness when scrolling.
*min-brightness*: ++
typeof: double ++
default: 0.0 ++
The minimum brightness of the backlight.
*menu*: ++ *menu*: ++
typeof: string ++ typeof: string ++
Action that popups the menu. Action that popups the menu.

View File

@ -64,6 +64,10 @@ libcava lives in:
:[ bool :[ bool
:[ false :[ false
:[ Hides the widget if no input (after sleep_timer elapsed) :[ 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* |[ *method*
:[ string :[ string
:[ pulse :[ 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

View File

@ -55,8 +55,8 @@ Addressed by *custom/<name>*
*format*: ++ *format*: ++
typeof: string ++ typeof: string ++
default: {} ++ default: {text} ++
The format, how information should be displayed. On {} data gets inserted. The format, how information should be displayed. On {text} data gets inserted.
*format-icons*: ++ *format-icons*: ++
typeof: array ++ typeof: array ++
@ -160,7 +160,7 @@ $text\\n$tooltip\\n$class*
# FORMAT REPLACEMENTS # FORMAT REPLACEMENTS
*{}*: Output of the script. *{text}*: Output of the script.
*{percentage}* Percentage which can be set via a json return type. *{percentage}* Percentage which can be set via a json return type.
@ -172,7 +172,7 @@ $text\\n$tooltip\\n$class*
``` ```
"custom/spotify": { "custom/spotify": {
"format": " {}", "format": " {text}",
"max-length": 40, "max-length": 40,
"interval": 30, // Remove this if your script is endless and write in loop "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 "exec": "$HOME/.config/waybar/mediaplayer.sh 2> /dev/null", // Script in resources folder
@ -185,7 +185,7 @@ $text\\n$tooltip\\n$class*
``` ```
"custom/mpd": { "custom/mpd": {
"format": "♪ {}", "format": "♪ {text}",
//"max-length": 15, //"max-length": 15,
"interval": 10, "interval": 10,
"exec": "mpc current", "exec": "mpc current",
@ -199,7 +199,7 @@ $text\\n$tooltip\\n$class*
``` ```
"custom/cmus": { "custom/cmus": {
"format": "♪ {}", "format": "♪ {text}",
//"max-length": 15, //"max-length": 15,
"interval": 10, "interval": 10,
"exec": "cmus-remote -C \"format_print '%a - %t'\"", // artist - title "exec": "cmus-remote -C \"format_print '%a - %t'\"", // artist - title
@ -214,7 +214,7 @@ $text\\n$tooltip\\n$class*
``` ```
"custom/pacman": { "custom/pacman": {
"format": "{} ", "format": "{text} ",
"interval": "once", "interval": "once",
"exec": "pacman_packages", "exec": "pacman_packages",
"on-click": "update-system", "on-click": "update-system",
@ -226,7 +226,7 @@ $text\\n$tooltip\\n$class*
``` ```
"custom/pacman": { "custom/pacman": {
"format": "{} ", "format": "{text} ",
"interval": 3600, // every hour "interval": 3600, // every hour
"exec": "checkupdates | wc -l", // # of updates "exec": "checkupdates | wc -l", // # of updates
"exec-if": "exit 0", // always run; consider advanced run conditions "exec-if": "exit 0", // always run; consider advanced run conditions

View File

@ -106,7 +106,7 @@ if libsndio.found()
endif endif
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'], default_options: ['introspection=false', 'vapi=false'],
fallback: ['gtk-layer-shell', 'gtk_layer_shell']) fallback: ['gtk-layer-shell', 'gtk_layer_shell'])
systemd = dependency('systemd', required: get_option('systemd')) systemd = dependency('systemd', required: get_option('systemd'))
@ -483,7 +483,7 @@ if get_option('experimental')
endif endif
cava = dependency('cava', cava = dependency('cava',
version : '>=0.10.2', version : '>=0.10.3',
required: get_option('cava'), required: get_option('cava'),
fallback : ['cava', 'cava_dep'], fallback : ['cava', 'cava_dep'],
not_found_message: 'cava is not found. Building waybar without cava') not_found_message: 'cava is not found. Building waybar without cava')

View File

@ -5,12 +5,12 @@
}: }:
let let
libcava = rec { libcava = rec {
version = "0.10.2"; version = "0.10.3";
src = pkgs.fetchFromGitHub { src = pkgs.fetchFromGitHub {
owner = "LukashonakV"; owner = "LukashonakV";
repo = "cava"; repo = "cava";
rev = version; rev = version;
hash = "sha256-jU7RQV2txruu/nUUl0TzjK4nai7G38J1rcTjO7UXumY="; hash = "sha256-ZDFbI69ECsUTjbhlw2kHRufZbQMu+FQSMmncCJ5pagg=";
}; };
}; };
in in
@ -25,6 +25,9 @@ in
mesonFlags = lib.remove "-Dgtk-layer-shell=enabled" oldAttrs.mesonFlags; mesonFlags = lib.remove "-Dgtk-layer-shell=enabled" oldAttrs.mesonFlags;
# downstream patch should not affect upstream
patches = [];
buildInputs = (builtins.filter (p: p.pname != "wireplumber") oldAttrs.buildInputs) ++ [ buildInputs = (builtins.filter (p: p.pname != "wireplumber") oldAttrs.buildInputs) ++ [
pkgs.wireplumber pkgs.wireplumber
]; ];

View File

@ -189,7 +189,7 @@
"on-click": "pavucontrol" "on-click": "pavucontrol"
}, },
"custom/media": { "custom/media": {
"format": "{icon} {}", "format": "{icon} {text}",
"return-type": "json", "return-type": "json",
"max-length": 40, "max-length": 40,
"format-icons": { "format-icons": {

View File

@ -154,6 +154,15 @@ void AAppIconLabel::updateAppIcon() {
update_app_icon_ = false; update_app_icon_ = false;
if (app_icon_name_.empty()) { if (app_icon_name_.empty()) {
image_.set_visible(false); 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 { } else {
image_.set_from_icon_name(app_icon_name_, Gtk::ICON_SIZE_INVALID); image_.set_from_icon_name(app_icon_name_, Gtk::ICON_SIZE_INVALID);
image_.set_visible(true); image_.set_visible(true);

View File

@ -37,19 +37,19 @@ const Bar::bar_mode_map Bar::PRESET_MODES = { //
.visible = true}}, .visible = true}},
{"hide", {"hide",
{// {//
.layer = bar_layer::TOP, .layer = bar_layer::OVERLAY,
.exclusive = false, .exclusive = false,
.passthrough = false, .passthrough = false,
.visible = true}}, .visible = true}},
{"invisible", {"invisible",
{// {//
.layer = std::nullopt, .layer = bar_layer::BOTTOM,
.exclusive = false, .exclusive = false,
.passthrough = true, .passthrough = true,
.visible = false}}, .visible = false}},
{"overlay", {"overlay",
{// {//
.layer = bar_layer::TOP, .layer = bar_layer::OVERLAY,
.exclusive = false, .exclusive = false,
.passthrough = true, .passthrough = true,
.visible = true}}}; .visible = true}}};
@ -59,7 +59,7 @@ const std::string Bar::MODE_INVISIBLE = "invisible";
const std::string_view DEFAULT_BAR_ID = "bar-0"; const std::string_view DEFAULT_BAR_ID = "bar-0";
/* Deserializer for enum bar_layer */ /* 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") { if (j == "bottom") {
l = bar_layer::BOTTOM; l = bar_layer::BOTTOM;
} else if (j == "top") { } 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) waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config)
: output(w_output), : output(w_output),
config(w_config), config(w_config),
surface(nullptr),
window{Gtk::WindowType::WINDOW_TOPLEVEL}, window{Gtk::WindowType::WINDOW_TOPLEVEL},
x_global(0), x_global(0),
y_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) { void waybar::Bar::setMode(const struct bar_mode& mode) {
auto* gtk_window = window.gobj(); auto* gtk_window = window.gobj();
if (mode.layer == bar_layer::BOTTOM) { auto layer = GTK_LAYER_SHELL_LAYER_BOTTOM;
gtk_layer_set_layer(gtk_window, GTK_LAYER_SHELL_LAYER_BOTTOM); if (mode.layer == bar_layer::TOP) {
} else if (mode.layer == bar_layer::TOP) { layer = GTK_LAYER_SHELL_LAYER_TOP;
gtk_layer_set_layer(gtk_window, GTK_LAYER_SHELL_LAYER_TOP);
} else if (mode.layer == bar_layer::OVERLAY) { } 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) { if (mode.exclusive) {
gtk_layer_auto_exclusive_zone_enable(gtk_window); 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.get_style_context()->add_class("hidden");
window.set_opacity(0); 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) { void waybar::Bar::setPassThrough(bool passthrough) {

View File

@ -112,6 +112,14 @@ bool waybar::modules::Backlight::handleScroll(GdkEventScroll *e) {
step = config_["scroll-step"].asDouble(); 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); backend.set_brightness(preferred_device_, ct, step);
return true; return true;

View File

@ -59,6 +59,7 @@ waybar::modules::Cava::Cava(const std::string& id, const Json::Value& config)
if (config_["input_delay"].isInt()) if (config_["input_delay"].isInt())
fetch_input_delay_ = std::chrono::seconds(config_["input_delay"].asInt()); fetch_input_delay_ = std::chrono::seconds(config_["input_delay"].asInt());
if (config_["hide_on_silence"].isBool()) hide_on_silence_ = config_["hide_on_silence"].asBool(); if (config_["hide_on_silence"].isBool()) hide_on_silence_ = config_["hide_on_silence"].asBool();
if (config_["format_silent"].isString()) format_silent_ = config_["format_silent"].asString();
// Make cava parameters configuration // Make cava parameters configuration
plan_ = new cava::cava_plan{}; plan_ = new cava::cava_plan{};
@ -172,10 +173,19 @@ auto waybar::modules::Cava::update() -> void {
label_.set_markup(text_); label_.set_markup(text_);
label_.show(); label_.show();
ALabel::update(); ALabel::update();
label_.get_style_context()->add_class("updated");
} }
label_.get_style_context()->remove_class("silent");
} else { } else {
upThreadDelay(frame_time_milsec_, suspend_silence_delay_); upThreadDelay(frame_time_milsec_, suspend_silence_delay_);
if (hide_on_silence_) label_.hide(); if (hide_on_silence_)
label_.hide();
else if (config_["format_silent"].isString())
label_.set_markup(format_silent_);
label_.get_style_context()->add_class("silent");
label_.get_style_context()->remove_class("updated");
} }
} }

View File

@ -24,6 +24,7 @@ waybar::modules::Clock::Clock(const std::string& id, const Json::Value& config)
m_tlpFmt_{(config_["tooltip-format"].isString()) ? config_["tooltip-format"].asString() : ""}, m_tlpFmt_{(config_["tooltip-format"].isString()) ? config_["tooltip-format"].asString() : ""},
m_tooltip_{new Gtk::Label()}, m_tooltip_{new Gtk::Label()},
cldInTooltip_{m_tlpFmt_.find("{" + kCldPlaceholder + "}") != std::string::npos}, cldInTooltip_{m_tlpFmt_.find("{" + kCldPlaceholder + "}") != std::string::npos},
cldYearShift_{January / 1 / 1900},
tzInTooltip_{m_tlpFmt_.find("{" + kTZPlaceholder + "}") != std::string::npos}, tzInTooltip_{m_tlpFmt_.find("{" + kTZPlaceholder + "}") != std::string::npos},
tzCurrIdx_{0}, tzCurrIdx_{0},
ordInTooltip_{m_tlpFmt_.find("{" + kOrdPlaceholder + "}") != std::string::npos} { ordInTooltip_{m_tlpFmt_.find("{" + kOrdPlaceholder + "}") != std::string::npos} {

View File

@ -159,43 +159,52 @@ auto waybar::modules::Custom::update() -> void {
parseOutputRaw(); parseOutputRaw();
} }
auto str = fmt::format(fmt::runtime(format_), text_, fmt::arg("alt", alt_), try {
fmt::arg("icon", getIcon(percentage_, alt_)), auto str = fmt::format(fmt::runtime(format_), fmt::arg("text", text_), fmt::arg("alt", alt_),
fmt::arg("percentage", percentage_)); fmt::arg("icon", getIcon(percentage_, alt_)),
if ((config_["hide-empty-text"].asBool() && text_.empty()) || str.empty()) { fmt::arg("percentage", percentage_));
event_box_.hide(); if ((config_["hide-empty-text"].asBool() && text_.empty()) || str.empty()) {
} else { event_box_.hide();
label_.set_markup(str); } else {
if (tooltipEnabled()) { label_.set_markup(str);
if (tooltip_format_enabled_) { if (tooltipEnabled()) {
auto tooltip = config_["tooltip-format"].asString(); if (tooltip_format_enabled_) {
tooltip = fmt::format(fmt::runtime(tooltip), text_, fmt::arg("alt", alt_), auto tooltip = config_["tooltip-format"].asString();
fmt::arg("icon", getIcon(percentage_, alt_)), tooltip = fmt::format(
fmt::arg("percentage", percentage_)); fmt::runtime(tooltip), fmt::arg("text", text_), fmt::arg("alt", alt_),
label_.set_tooltip_markup(tooltip); fmt::arg("icon", getIcon(percentage_, alt_)), fmt::arg("percentage", percentage_));
} else if (text_ == tooltip_) { label_.set_tooltip_markup(tooltip);
if (label_.get_tooltip_markup() != str) { } else if (text_ == tooltip_) {
label_.set_tooltip_markup(str); if (label_.get_tooltip_markup() != str) {
} label_.set_tooltip_markup(str);
} else { }
if (label_.get_tooltip_markup() != tooltip_) { } else {
label_.set_tooltip_markup(tooltip_); if (label_.get_tooltip_markup() != tooltip_) {
label_.set_tooltip_markup(tooltip_);
}
} }
} }
auto style = label_.get_style_context();
auto classes = style->list_classes();
for (auto const& c : classes) {
if (c == id_) continue;
style->remove_class(c);
}
for (auto const& c : class_) {
style->add_class(c);
}
style->add_class("flat");
style->add_class("text-button");
style->add_class(MODULE_CLASS);
event_box_.show();
} }
auto style = label_.get_style_context(); } catch (const fmt::format_error& e) {
auto classes = style->list_classes(); if (std::strcmp(e.what(), "cannot switch from manual to automatic argument indexing") != 0)
for (auto const& c : classes) { throw;
if (c == id_) continue;
style->remove_class(c); throw fmt::format_error(
} "mixing manual and automatic argument indexing is no longer supported; "
for (auto const& c : class_) { "try replacing \"{}\" with \"{text}\" in your format specifier");
style->add_class(c);
}
style->add_class("flat");
style->add_class("text-button");
style->add_class(MODULE_CLASS);
event_box_.show();
} }
} }
// Call parent update // Call parent update

View File

@ -1,7 +1,7 @@
[wrap-file] [wrap-file]
directory = cava-0.10.2 directory = cava-0.10.3
source_url = https://github.com/LukashonakV/cava/archive/0.10.2.tar.gz source_url = https://github.com/LukashonakV/cava/archive/0.10.3.tar.gz
source_filename = cava-0.10.2.tar.gz source_filename = cava-0.10.3.tar.gz
source_hash = dff78c4787c9843583086408a0a6e5bde7a5dee1fa17ae526847366846cb19c3 source_hash = aab0a4ed3f999e8461ad9de63ef8a77f28b6b2011f7dd0c69ba81819d442f6f9
[provide] [provide]
cava = cava_dep cava = cava_dep