Merge branch 'master' into master

This commit is contained in:
nullobsi
2021-02-10 09:39:03 -08:00
committed by GitHub
29 changed files with 282 additions and 26 deletions

View File

@ -20,7 +20,7 @@ ALabel::ALabel(const Json::Value& config, const std::string& name, const std::st
}
event_box_.add(label_);
if (config_["max-length"].isUInt()) {
label_.set_max_width_chars(config_["max-length"].asUInt());
label_.set_max_width_chars(config_["max-length"].asInt());
label_.set_ellipsize(Pango::EllipsizeMode::ELLIPSIZE_END);
label_.set_single_line_mode(true);
} else if (ellipsize && label_.get_max_width_chars() == -1) {
@ -28,9 +28,28 @@ ALabel::ALabel(const Json::Value& config, const std::string& name, const std::st
label_.set_single_line_mode(true);
}
if (config_["rotate"].isUInt()) {
label_.set_angle(config["rotate"].asUInt());
if (config_["min-length"].isUInt()) {
label_.set_width_chars(config_["min-length"].asUInt());
}
uint rotate = 0;
if (config_["rotate"].isUInt()) {
rotate = config["rotate"].asUInt();
label_.set_angle(rotate);
}
if (config_["align"].isDouble()) {
auto align = config_["align"].asFloat();
if (rotate == 90 || rotate == 270) {
label_.set_yalign(align);
} else {
label_.set_xalign(align);
}
}
}
auto ALabel::update() -> void {

View File

@ -120,17 +120,26 @@ void waybar::Client::handleOutputDone(void *data, struct zxdg_output_v1 * /*xdg_
auto client = waybar::Client::inst();
try {
auto &output = client->getOutput(data);
spdlog::debug("Output detection done: {} ({})", output.name, output.identifier);
/**
* Multiple .done events may arrive in batch. In this case libwayland would queue
* xdg_output.destroy and dispatch all pending events, triggering this callback several times
* for the same output. .done events can also arrive after that for a scale or position changes.
* We wouldn't want to draw a duplicate bar for each such event either.
*
* All the properties we care about are immutable so it's safe to delete the xdg_output object
* on the first event and use the ptr value to check that the callback was already invoked.
*/
if (output.xdg_output) {
output.xdg_output.reset();
spdlog::debug("Output detection done: {} ({})", output.name, output.identifier);
auto configs = client->getOutputConfigs(output);
if (!configs.empty()) {
wl_display_roundtrip(client->wl_display);
for (const auto &config : configs) {
client->bars.emplace_back(std::make_unique<Bar>(&output, config));
auto configs = client->getOutputConfigs(output);
if (!configs.empty()) {
for (const auto &config : configs) {
client->bars.emplace_back(std::make_unique<Bar>(&output, config));
}
}
}
// unsubscribe
output.xdg_output.reset();
} catch (const std::exception &e) {
std::cerr << e.what() << std::endl;
}

View File

@ -5,6 +5,7 @@
#include <sstream>
#include <type_traits>
#include "util/ustring_clen.hpp"
#ifdef HAVE_LANGINFO_1STDAY
#include <langinfo.h>
#include <locale.h>
@ -154,12 +155,14 @@ auto waybar::modules::Clock::weekdays_header(const date::weekday& first_dow, std
do {
if (wd != first_dow) os << ' ';
Glib::ustring wd_ustring(date::format(locale_, "%a", wd));
auto wd_len = wd_ustring.length();
if (wd_len > 2) {
wd_ustring = wd_ustring.substr(0, 2);
wd_len = 2;
auto clen = ustring_clen(wd_ustring);
auto wd_len = wd_ustring.length();
while (clen > 2) {
wd_ustring = wd_ustring.substr(0, wd_len-1);
wd_len--;
clen = ustring_clen(wd_ustring);
}
const std::string pad(2 - wd_len, ' ');
const std::string pad(2 - clen, ' ');
os << pad << wd_ustring;
} while (++wd != first_dow);
os << "\n";

View File

@ -12,6 +12,10 @@ waybar::modules::IdleInhibitor::IdleInhibitor(const std::string& id, const Bar&
bar_(bar),
idle_inhibitor_(nullptr),
pid_(-1) {
if (waybar::Client::inst()->idle_inhibit_manager == nullptr) {
throw std::runtime_error("idle-inhibit not available");
}
event_box_.add_events(Gdk::BUTTON_PRESS_MASK);
event_box_.signal_button_press_event().connect(
sigc::mem_fun(*this, &IdleInhibitor::handleToggle));

View File

@ -56,7 +56,8 @@ auto Window::update() -> void {
bar_.window.get_style_context()->remove_class("solo");
bar_.window.get_style_context()->remove_class("empty");
}
label_.set_markup(fmt::format(format_, window_));
label_.set_markup(fmt::format(format_, fmt::arg("title", window_),
fmt::arg("app_id", app_id_)));
if (tooltipEnabled()) {
label_.set_tooltip_text(window_);
}

View File

@ -257,11 +257,19 @@ Gtk::Button &Workspaces::addButton(const Json::Value &node) {
ipc_.sendCmd(
IPC_COMMAND,
fmt::format(workspace_switch_cmd_ + "; move workspace to output \"{}\"; " + workspace_switch_cmd_,
"--no-auto-back-and-forth",
node["name"].asString(),
node["target_output"].asString(),
"--no-auto-back-and-forth",
node["name"].asString()));
} else {
ipc_.sendCmd(IPC_COMMAND, fmt::format(workspace_switch_cmd_, node["name"].asString()));
ipc_.sendCmd(
IPC_COMMAND,
fmt::format("workspace {} \"{}\"",
config_["disable-auto-back-and-forth"].asBool()
? "--no-auto-back-and-forth"
: "",
node["name"].asString()));
}
} catch (const std::exception &e) {
spdlog::error("Workspaces: {}", e.what());
@ -322,7 +330,9 @@ bool Workspaces::handleScroll(GdkEventScroll *e) {
}
}
try {
ipc_.sendCmd(IPC_COMMAND, fmt::format(workspace_switch_cmd_, name));
ipc_.sendCmd(
IPC_COMMAND,
fmt::format(workspace_switch_cmd_, "--no-auto-back-and-forth", name));
} catch (const std::exception &e) {
spdlog::error("Workspaces: {}", e.what());
}

View File

@ -1,5 +1,7 @@
#include "modules/wlr/taskbar.hpp"
#include "glibmm/error.h"
#include "glibmm/fileutils.h"
#include "glibmm/refptr.h"
#include "util/format.hpp"
@ -15,6 +17,7 @@
#include <gtkmm/icontheme.h>
#include <giomm/desktopappinfo.h>
#include <gio/gdesktopappinfo.h>
#include <spdlog/spdlog.h>
@ -64,12 +67,25 @@ static std::vector<std::string> search_prefix()
} while(end != std::string::npos);
}
std::string home_dir = std::getenv("HOME");
prefixes.push_back(home_dir + "/.local/share/");
for (auto& p : prefixes)
spdlog::debug("Using 'desktop' search path prefix: {}", p);
return prefixes;
}
static Glib::RefPtr<Gdk::Pixbuf> load_icon_from_file(std::string icon_path, int size)
{
try {
auto pb = Gdk::Pixbuf::create_from_file(icon_path, size, size);
return pb;
} catch(...) {
return {};
}
}
/* Method 1 - get the correct icon name from the desktop file */
static std::string get_from_desktop_app_info(const std::string &app_id)
{
@ -111,6 +127,33 @@ static std::string get_from_icon_theme(const Glib::RefPtr<Gtk::IconTheme>& icon_
return "";
}
/* Method 3 - as last resort perform a search for most appropriate desktop info file */
static std::string get_from_desktop_app_info_search(const std::string &app_id)
{
std::string desktop_file = "";
gchar*** desktop_list = g_desktop_app_info_search(app_id.c_str());
if (desktop_list != nullptr && desktop_list[0] != nullptr) {
for (size_t i=0; desktop_list[0][i]; i++) {
if (desktop_file == "") {
desktop_file = desktop_list[0][i];
} else {
auto tmp_info = Gio::DesktopAppInfo::create(desktop_list[0][i]);
auto startup_class = tmp_info->get_startup_wm_class();
if (startup_class == app_id) {
desktop_file = desktop_list[0][i];
break;
}
}
}
g_strfreev(desktop_list[0]);
}
g_free(desktop_list);
return get_from_desktop_app_info(desktop_file);
}
static bool image_load_icon(Gtk::Image& image, const Glib::RefPtr<Gtk::IconTheme>& icon_theme,
const std::string &app_id_list, int size)
{
@ -142,11 +185,23 @@ static bool image_load_icon(Gtk::Image& image, const Glib::RefPtr<Gtk::IconTheme
icon_name = get_from_desktop_app_info(lower_app_id);
if (icon_name.empty())
icon_name = get_from_desktop_app_info(app_name);
if (icon_name.empty())
icon_name = get_from_desktop_app_info_search(app_id);
if (icon_name.empty())
continue;
icon_name = "unknown";
Glib::RefPtr<Gdk::Pixbuf> pixbuf;
try {
pixbuf = icon_theme->load_icon(icon_name, size, Gtk::ICON_LOOKUP_FORCE_SIZE);
} catch(...) {
if (Glib::file_test(icon_name, Glib::FILE_TEST_EXISTS))
pixbuf = load_icon_from_file(icon_name, size);
else
pixbuf = {};
}
auto pixbuf = icon_theme->load_icon(icon_name, size, Gtk::ICON_LOOKUP_FORCE_SIZE);
if (pixbuf) {
image.set(pixbuf);
found = true;

View File

@ -0,0 +1,9 @@
#include "util/ustring_clen.hpp"
int ustring_clen(const Glib::ustring &str){
int total = 0;
for (auto i = str.begin(); i != str.end(); ++i) {
total += g_unichar_iswide(*i) + 1;
}
return total;
}