Merge remote-tracking branch 'origin/master' into finitemonkey/master
This commit is contained in:
@@ -4,6 +4,8 @@
|
|||||||
#include <gtkmm/label.h>
|
#include <gtkmm/label.h>
|
||||||
#include <json/json.h>
|
#include <json/json.h>
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "AModule.hpp"
|
#include "AModule.hpp"
|
||||||
|
|
||||||
namespace waybar {
|
namespace waybar {
|
||||||
@@ -25,12 +27,19 @@ class ALabel : public AModule {
|
|||||||
bool alt_ = false;
|
bool alt_ = false;
|
||||||
std::string default_format_;
|
std::string default_format_;
|
||||||
|
|
||||||
|
bool setLabelMarkup(const Glib::ustring& markup);
|
||||||
|
bool setTooltipMarkup(const Glib::ustring& markup);
|
||||||
|
|
||||||
bool handleToggle(GdkEventButton* const& e) override;
|
bool handleToggle(GdkEventButton* const& e) override;
|
||||||
virtual std::string getState(uint8_t value, bool lesser = false);
|
virtual std::string getState(uint8_t value, bool lesser = false);
|
||||||
|
|
||||||
std::map<std::string, GtkMenuItem*> submenus_;
|
std::map<std::string, GtkMenuItem*> submenus_;
|
||||||
std::map<std::string, std::string> menuActionsMap_;
|
std::map<std::string, std::string> menuActionsMap_;
|
||||||
static void handleGtkMenuEvent(GtkMenuItem* menuitem, gpointer data);
|
static void handleGtkMenuEvent(GtkMenuItem* menuitem, gpointer data);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::optional<Glib::ustring> last_label_markup_;
|
||||||
|
std::optional<Glib::ustring> last_tooltip_markup_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar
|
} // namespace waybar
|
||||||
|
|||||||
@@ -57,6 +57,11 @@ Addressed by *wlr/taskbar*
|
|||||||
default: false ++
|
default: false ++
|
||||||
If set to true, group tasks by their app_id. Cannot be used with 'active-first'.
|
If set to true, group tasks by their app_id. Cannot be used with 'active-first'.
|
||||||
|
|
||||||
|
*expand*: ++
|
||||||
|
typeof: bool ++
|
||||||
|
default: false ++
|
||||||
|
If set to true, task buttons stretch to fill the available space in the taskbar and long titles are ellipsized to fit. Only takes effect on a horizontal bar; on a vertical bar the buttons keep their content-based size. If set to false, buttons are sized to their content.
|
||||||
|
|
||||||
*on-click*: ++
|
*on-click*: ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
The action which should be triggered when clicking on the application button with the left mouse button.
|
The action which should be triggered when clicking on the application button with the left mouse button.
|
||||||
|
|||||||
@@ -168,6 +168,7 @@ The visual display elements for waybar use a CSS stylesheet, see *waybar-styles(
|
|||||||
# MODULE FORMAT
|
# MODULE FORMAT
|
||||||
|
|
||||||
You can use PangoMarkupFormat (See https://developer.gnome.org/pango/stable/PangoMarkupFormat.html#PangoMarkupFormat).
|
You can use PangoMarkupFormat (See https://developer.gnome.org/pango/stable/PangoMarkupFormat.html#PangoMarkupFormat).
|
||||||
|
Tooltip appearance is generally controlled globally via CSS and cannot be truly scoped per module. Some modules (such as the clock) provide limited workarounds for customization.
|
||||||
|
|
||||||
e.g.
|
e.g.
|
||||||
|
|
||||||
|
|||||||
@@ -139,6 +139,26 @@ ALabel::ALabel(const Json::Value& config, const std::string& name, const std::st
|
|||||||
|
|
||||||
auto ALabel::update() -> void { AModule::update(); }
|
auto ALabel::update() -> void { AModule::update(); }
|
||||||
|
|
||||||
|
bool ALabel::setLabelMarkup(const Glib::ustring& markup) {
|
||||||
|
if (last_label_markup_ == markup) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
label_.set_markup(markup);
|
||||||
|
last_label_markup_ = markup;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ALabel::setTooltipMarkup(const Glib::ustring& markup) {
|
||||||
|
if (last_tooltip_markup_ == markup) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
label_.set_tooltip_markup(markup);
|
||||||
|
last_tooltip_markup_ = markup;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
std::string ALabel::getIcon(uint16_t percentage, const std::string& alt, uint16_t max) {
|
std::string ALabel::getIcon(uint16_t percentage, const std::string& alt, uint16_t max) {
|
||||||
auto format_icons = config_["format-icons"];
|
auto format_icons = config_["format-icons"];
|
||||||
if (format_icons.isObject()) {
|
if (format_icons.isObject()) {
|
||||||
|
|||||||
@@ -402,8 +402,13 @@ auto waybar::modules::Clock::get_calendar(const year_month_day& today, const yea
|
|||||||
data = g_utf8_find_next_char(data, end);
|
data = g_utf8_find_next_char(data, end);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Note: the stream's default fill character is already a space (L' ' on
|
||||||
|
// libstdc++'s wide FormatStream, ' ' on libc++'s narrow one), so no
|
||||||
|
// std::setfill is needed. Passing std::setfill(' ')/std::setfill(L' ')
|
||||||
|
// here is not portable because the fill char type must match the
|
||||||
|
// FormatStream's char type, which differs between standard libraries.
|
||||||
os << Glib::ustring::format(
|
os << Glib::ustring::format(
|
||||||
(cldWPos_ != WS::LEFT || line == 0) ? std::left : std::right, std::setfill(L' '),
|
(cldWPos_ != WS::LEFT || line == 0) ? std::left : std::right,
|
||||||
std::setw(cldMonColLen_ + ((line < 2) ? cldWnLen_ - wideCharCount : 0)),
|
std::setw(cldMonColLen_ + ((line < 2) ? cldWnLen_ - wideCharCount : 0)),
|
||||||
calendarLine);
|
calendarLine);
|
||||||
|
|
||||||
|
|||||||
@@ -223,7 +223,11 @@ void Workspace::setActiveWindow(WindowAddress const& addr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto activeWindowPos = m_workspaceManager.activeWindowPosition();
|
auto activeWindowPos = m_workspaceManager.activeWindowPosition();
|
||||||
if (activeIdx.has_value() && activeWindowPos != Workspaces::ActiveWindowPosition::NONE) {
|
const bool has_active_window =
|
||||||
|
activeIdx.has_value() &&
|
||||||
|
activeWindowPos != Workspaces::ActiveWindowPosition::NONE;
|
||||||
|
|
||||||
|
if (has_active_window) {
|
||||||
auto window = std::move(m_windowMap[*activeIdx]);
|
auto window = std::move(m_windowMap[*activeIdx]);
|
||||||
m_windowMap.erase(m_windowMap.begin() + *activeIdx);
|
m_windowMap.erase(m_windowMap.begin() + *activeIdx);
|
||||||
if (activeWindowPos == Workspaces::ActiveWindowPosition::FIRST) {
|
if (activeWindowPos == Workspaces::ActiveWindowPosition::FIRST) {
|
||||||
@@ -238,7 +242,10 @@ void Workspace::insertWindow(WindowCreationPayload create_window_payload) {
|
|||||||
if (!create_window_payload.isEmpty(m_workspaceManager)) {
|
if (!create_window_payload.isEmpty(m_workspaceManager)) {
|
||||||
auto repr = create_window_payload.repr(m_workspaceManager);
|
auto repr = create_window_payload.repr(m_workspaceManager);
|
||||||
|
|
||||||
if (!repr.empty() || m_workspaceManager.enableTaskbar()) {
|
const bool should_display =
|
||||||
|
!repr.empty() || m_workspaceManager.enableTaskbar();
|
||||||
|
|
||||||
|
if (should_display) {
|
||||||
auto addr = create_window_payload.getAddress();
|
auto addr = create_window_payload.getAddress();
|
||||||
auto it = std::ranges::find_if(
|
auto it = std::ranges::find_if(
|
||||||
m_windowMap, [&addr](const auto& window) { return window.address == addr; });
|
m_windowMap, [&addr](const auto& window) { return window.address == addr; });
|
||||||
@@ -250,7 +257,7 @@ void Workspace::insertWindow(WindowCreationPayload create_window_payload) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
bool Workspace::onWindowOpened(WindowCreationPayload const& create_window_payload) {
|
bool Workspace::onWindowOpened(WindowCreationPayload const& create_window_payload) {
|
||||||
if (create_window_payload.getWorkspaceName() == name()) {
|
if (create_window_payload.getWorkspaceName() == name()) {
|
||||||
@@ -390,7 +397,9 @@ void Workspace::update(const std::string& workspace_icon) {
|
|||||||
|
|
||||||
bool Workspace::isEmpty() const {
|
bool Workspace::isEmpty() const {
|
||||||
auto ignore_list = m_workspaceManager.getIgnoredWindows();
|
auto ignore_list = m_workspaceManager.getIgnoredWindows();
|
||||||
if (ignore_list.empty()) {
|
const bool no_ignore_rules = ignore_list.empty();
|
||||||
|
|
||||||
|
if (no_ignore_rules) {
|
||||||
return m_windows == 0;
|
return m_windows == 0;
|
||||||
}
|
}
|
||||||
// If there are windows but they are all ignored, consider the workspace empty
|
// If there are windows but they are all ignored, consider the workspace empty
|
||||||
@@ -472,7 +481,9 @@ void Workspace::updateTaskbar(const std::string& workspace_icon) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto formatAfter = m_workspaceManager.formatAfter();
|
auto formatAfter = m_workspaceManager.formatAfter();
|
||||||
if (!formatAfter.empty()) {
|
const bool has_format_after = !formatAfter.empty();
|
||||||
|
|
||||||
|
if (has_format_after) {
|
||||||
m_labelAfter.set_markup(fmt::format(fmt::runtime(formatAfter), fmt::arg("id", id()),
|
m_labelAfter.set_markup(fmt::format(fmt::runtime(formatAfter), fmt::arg("id", id()),
|
||||||
fmt::arg("name", name()),
|
fmt::arg("name", name()),
|
||||||
fmt::arg("icon", workspace_icon)));
|
fmt::arg("icon", workspace_icon)));
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ void waybar::modules::MPD::setLabel() {
|
|||||||
? config_["format-disconnected"].asString()
|
? config_["format-disconnected"].asString()
|
||||||
: "disconnected";
|
: "disconnected";
|
||||||
if (format.empty()) {
|
if (format.empty()) {
|
||||||
label_.set_markup(format);
|
setLabelMarkup(format);
|
||||||
label_.show();
|
label_.show();
|
||||||
} else {
|
} else {
|
||||||
label_.hide();
|
label_.hide();
|
||||||
@@ -97,7 +97,7 @@ void waybar::modules::MPD::setLabel() {
|
|||||||
? config_["tooltip-format-disconnected"].asString()
|
? config_["tooltip-format-disconnected"].asString()
|
||||||
: "MPD (disconnected)";
|
: "MPD (disconnected)";
|
||||||
// Nothing to format
|
// Nothing to format
|
||||||
label_.set_tooltip_markup(tooltip_format);
|
setTooltipMarkup(tooltip_format);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -124,8 +124,9 @@ void waybar::modules::MPD::setLabel() {
|
|||||||
label_.get_style_context()->add_class("playing");
|
label_.get_style_context()->add_class("playing");
|
||||||
label_.get_style_context()->remove_class("paused");
|
label_.get_style_context()->remove_class("paused");
|
||||||
} else if (paused()) {
|
} else if (paused()) {
|
||||||
format = config_["format-paused"].isString() ? config_["format-paused"].asString()
|
if (config_["format-paused"].isString()) {
|
||||||
: config_["format"].asString();
|
format = config_["format-paused"].asString();
|
||||||
|
}
|
||||||
label_.get_style_context()->add_class("paused");
|
label_.get_style_context()->add_class("paused");
|
||||||
label_.get_style_context()->remove_class("playing");
|
label_.get_style_context()->remove_class("playing");
|
||||||
}
|
}
|
||||||
@@ -168,7 +169,7 @@ void waybar::modules::MPD::setLabel() {
|
|||||||
label_.hide();
|
label_.hide();
|
||||||
} else {
|
} else {
|
||||||
label_.show();
|
label_.show();
|
||||||
label_.set_markup(text);
|
setLabelMarkup(text);
|
||||||
}
|
}
|
||||||
} catch (fmt::format_error const& e) {
|
} catch (fmt::format_error const& e) {
|
||||||
spdlog::warn("mpd: format error: {}", e.what());
|
spdlog::warn("mpd: format error: {}", e.what());
|
||||||
@@ -188,7 +189,7 @@ void waybar::modules::MPD::setLabel() {
|
|||||||
fmt::arg("stateIcon", stateIcon), fmt::arg("consumeIcon", consumeIcon),
|
fmt::arg("stateIcon", stateIcon), fmt::arg("consumeIcon", consumeIcon),
|
||||||
fmt::arg("randomIcon", randomIcon), fmt::arg("repeatIcon", repeatIcon),
|
fmt::arg("randomIcon", randomIcon), fmt::arg("repeatIcon", repeatIcon),
|
||||||
fmt::arg("singleIcon", singleIcon), fmt::arg("filename", filename), fmt::arg("uri", uri));
|
fmt::arg("singleIcon", singleIcon), fmt::arg("filename", filename), fmt::arg("uri", uri));
|
||||||
label_.set_tooltip_markup(tooltip_text);
|
setTooltipMarkup(tooltip_text);
|
||||||
} catch (fmt::format_error const& e) {
|
} catch (fmt::format_error const& e) {
|
||||||
spdlog::warn("mpd: format error (tooltip): {}", e.what());
|
spdlog::warn("mpd: format error (tooltip): {}", e.what());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,12 +94,12 @@ auto Window::update() -> void {
|
|||||||
old_app_id_ = app_id_;
|
old_app_id_ = app_id_;
|
||||||
}
|
}
|
||||||
|
|
||||||
label_.set_markup(waybar::util::rewriteString(
|
setLabelMarkup(waybar::util::rewriteString(
|
||||||
fmt::format(fmt::runtime(format_), fmt::arg("title", window_), fmt::arg("app_id", app_id_),
|
fmt::format(fmt::runtime(format_), fmt::arg("title", window_), fmt::arg("app_id", app_id_),
|
||||||
fmt::arg("shell", shell_), fmt::arg("marks", marks_)),
|
fmt::arg("shell", shell_), fmt::arg("marks", marks_)),
|
||||||
config_["rewrite"]));
|
config_["rewrite"]));
|
||||||
if (tooltipEnabled()) {
|
if (tooltipEnabled()) {
|
||||||
label_.set_tooltip_markup(window_);
|
setTooltipMarkup(window_);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateAppIcon();
|
updateAppIcon();
|
||||||
|
|||||||
@@ -94,9 +94,35 @@ Task::Task(const waybar::Bar& bar, const Json::Value& config, Taskbar* tbar,
|
|||||||
|
|
||||||
button.set_relief(Gtk::RELIEF_NONE);
|
button.set_relief(Gtk::RELIEF_NONE);
|
||||||
|
|
||||||
content_.add(text_before_);
|
/* When "expand" is enabled the buttons stretch to fill the taskbar and the
|
||||||
content_.add(icon_);
|
* titles ellipsize to fit within the available space. This only makes sense
|
||||||
content_.add(text_after_);
|
* on a horizontal bar; on a vertical bar the box grows along the vertical
|
||||||
|
* axis, so ellipsizing/forcing width_chars(1) would truncate every title to
|
||||||
|
* "…". Keep the historical behavior (buttons sized to their content) as the
|
||||||
|
* default and when the bar is vertical. */
|
||||||
|
bool expand = config_["expand"].isBool() && config_["expand"].asBool();
|
||||||
|
bool horizontal = bar.orientation == Gtk::ORIENTATION_HORIZONTAL;
|
||||||
|
|
||||||
|
if (expand && horizontal) {
|
||||||
|
button.set_hexpand(true);
|
||||||
|
content_.set_hexpand(true);
|
||||||
|
text_before_.set_ellipsize(Pango::ELLIPSIZE_END);
|
||||||
|
text_before_.set_single_line_mode(true);
|
||||||
|
text_before_.set_width_chars(1);
|
||||||
|
text_before_.set_xalign(0.0);
|
||||||
|
text_after_.set_ellipsize(Pango::ELLIPSIZE_END);
|
||||||
|
text_after_.set_single_line_mode(true);
|
||||||
|
text_after_.set_width_chars(1);
|
||||||
|
text_after_.set_xalign(0.0);
|
||||||
|
|
||||||
|
content_.pack_start(text_before_, true, true, 0);
|
||||||
|
content_.pack_start(icon_, false, false, 0);
|
||||||
|
content_.pack_start(text_after_, true, true, 0);
|
||||||
|
} else {
|
||||||
|
content_.add(text_before_);
|
||||||
|
content_.add(icon_);
|
||||||
|
content_.add(text_after_);
|
||||||
|
}
|
||||||
|
|
||||||
content_.show();
|
content_.show();
|
||||||
button.add(content_);
|
button.add(content_);
|
||||||
@@ -718,7 +744,15 @@ void Taskbar::handle_finished() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Taskbar::add_button(Gtk::Button& bt) {
|
void Taskbar::add_button(Gtk::Button& bt) {
|
||||||
box_.pack_start(bt, false, false);
|
/* Only let the buttons expand to fill the taskbar when "expand" is enabled
|
||||||
|
* and the bar is horizontal (see the Task constructor for details). */
|
||||||
|
bool expand = config_["expand"].isBool() && config_["expand"].asBool();
|
||||||
|
bool horizontal = bar_.orientation == Gtk::ORIENTATION_HORIZONTAL;
|
||||||
|
if (expand && horizontal) {
|
||||||
|
box_.pack_start(bt, true, true);
|
||||||
|
} else {
|
||||||
|
box_.pack_start(bt, false, false);
|
||||||
|
}
|
||||||
box_.get_style_context()->remove_class("empty");
|
box_.get_style_context()->remove_class("empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user