mirror of
https://github.com/Alexays/Waybar.git
synced 2026-04-01 04:13:38 +00:00
Merge pull request #4913 from khaneliman/tray
fix(tray): complete attention/overlay implementation
This commit is contained in:
@ -16,7 +16,7 @@ class Host {
|
||||
public:
|
||||
Host(const std::size_t id, const Json::Value&, const Bar&,
|
||||
const std::function<void(std::unique_ptr<Item>&)>&,
|
||||
const std::function<void(std::unique_ptr<Item>&)>&);
|
||||
const std::function<void(std::unique_ptr<Item>&)>&, const std::function<void()>&);
|
||||
~Host();
|
||||
|
||||
private:
|
||||
@ -28,6 +28,10 @@ class Host {
|
||||
static void registerHost(GObject*, GAsyncResult*, gpointer);
|
||||
static void itemRegistered(SnWatcher*, const gchar*, gpointer);
|
||||
static void itemUnregistered(SnWatcher*, const gchar*, gpointer);
|
||||
void itemReady(Item&);
|
||||
void itemInvalidated(Item&);
|
||||
void removeItem(std::vector<std::unique_ptr<Item>>::iterator);
|
||||
void clearItems();
|
||||
|
||||
std::tuple<std::string, std::string> getBusNameAndObjectPath(const std::string);
|
||||
void addRegisteredItem(const std::string& service);
|
||||
@ -43,6 +47,7 @@ class Host {
|
||||
const Bar& bar_;
|
||||
const std::function<void(std::unique_ptr<Item>&)> on_add_;
|
||||
const std::function<void(std::unique_ptr<Item>&)> on_remove_;
|
||||
const std::function<void()> on_update_;
|
||||
};
|
||||
|
||||
} // namespace waybar::modules::SNI
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
#include <libdbusmenu-gtk/dbusmenu-gtk.h>
|
||||
#include <sigc++/trackable.h>
|
||||
|
||||
#include <functional>
|
||||
#include <set>
|
||||
#include <string_view>
|
||||
|
||||
@ -25,9 +26,13 @@ struct ToolTip {
|
||||
|
||||
class Item : public sigc::trackable {
|
||||
public:
|
||||
Item(const std::string&, const std::string&, const Json::Value&, const Bar&);
|
||||
Item(const std::string&, const std::string&, const Json::Value&, const Bar&,
|
||||
const std::function<void(Item&)>&, const std::function<void(Item&)>&,
|
||||
const std::function<void()>&);
|
||||
~Item();
|
||||
|
||||
bool isReady() const;
|
||||
|
||||
std::string bus_name;
|
||||
std::string object_path;
|
||||
|
||||
@ -43,7 +48,9 @@ class Item : public sigc::trackable {
|
||||
Glib::RefPtr<Gdk::Pixbuf> icon_pixmap;
|
||||
Glib::RefPtr<Gtk::IconTheme> icon_theme;
|
||||
std::string overlay_icon_name;
|
||||
Glib::RefPtr<Gdk::Pixbuf> overlay_icon_pixmap;
|
||||
std::string attention_icon_name;
|
||||
Glib::RefPtr<Gdk::Pixbuf> attention_icon_pixmap;
|
||||
std::string attention_movie_name;
|
||||
std::string icon_theme_path;
|
||||
std::string menu;
|
||||
@ -62,6 +69,8 @@ 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 setReady();
|
||||
void invalidate();
|
||||
void setCustomIcon(const std::string& id);
|
||||
void getUpdatedProperties();
|
||||
void processUpdatedProperties(Glib::RefPtr<Gio::AsyncResult>& result);
|
||||
@ -69,8 +78,13 @@ class Item : public sigc::trackable {
|
||||
const Glib::VariantContainerBase& arguments);
|
||||
|
||||
void updateImage();
|
||||
Glib::RefPtr<Gdk::Pixbuf> extractPixBuf(GVariant* variant);
|
||||
static Glib::RefPtr<Gdk::Pixbuf> extractPixBuf(GVariant* variant);
|
||||
Glib::RefPtr<Gdk::Pixbuf> getIconPixbuf();
|
||||
Glib::RefPtr<Gdk::Pixbuf> getAttentionIconPixbuf();
|
||||
Glib::RefPtr<Gdk::Pixbuf> getOverlayIconPixbuf();
|
||||
Glib::RefPtr<Gdk::Pixbuf> loadIconFromNameOrFile(const std::string& name, bool log_failure);
|
||||
static Glib::RefPtr<Gdk::Pixbuf> overlayPixbufs(const Glib::RefPtr<Gdk::Pixbuf>&,
|
||||
const Glib::RefPtr<Gdk::Pixbuf>&);
|
||||
Glib::RefPtr<Gdk::Pixbuf> getIconByName(const std::string& name, int size);
|
||||
double getScaledIconSize();
|
||||
static void onMenuDestroyed(Item* self, GObject* old_menu_pointer);
|
||||
@ -86,8 +100,13 @@ class Item : public sigc::trackable {
|
||||
gdouble distance_scrolled_y_ = 0;
|
||||
// visibility of items with Status == Passive
|
||||
bool show_passive_ = false;
|
||||
bool ready_ = false;
|
||||
Glib::ustring status_ = "active";
|
||||
|
||||
const Bar& bar_;
|
||||
const std::function<void(Item&)> on_ready_;
|
||||
const std::function<void(Item&)> on_invalidate_;
|
||||
const std::function<void()> on_updated_;
|
||||
|
||||
Glib::RefPtr<Gio::DBus::Proxy> proxy_;
|
||||
Glib::RefPtr<Gio::Cancellable> cancellable_;
|
||||
|
||||
@ -19,6 +19,7 @@ class Tray : public AModule {
|
||||
private:
|
||||
void onAdd(std::unique_ptr<Item>& item);
|
||||
void onRemove(std::unique_ptr<Item>& item);
|
||||
void queueUpdate();
|
||||
|
||||
static inline std::size_t nb_hosts_ = 0;
|
||||
bool show_passive_ = false;
|
||||
|
||||
@ -8,7 +8,8 @@ namespace waybar::modules::SNI {
|
||||
|
||||
Host::Host(const std::size_t id, const Json::Value& config, const Bar& bar,
|
||||
const std::function<void(std::unique_ptr<Item>&)>& on_add,
|
||||
const std::function<void(std::unique_ptr<Item>&)>& on_remove)
|
||||
const std::function<void(std::unique_ptr<Item>&)>& on_remove,
|
||||
const std::function<void()>& on_update)
|
||||
: bus_name_("org.kde.StatusNotifierHost-" + std::to_string(getpid()) + "-" +
|
||||
std::to_string(id)),
|
||||
object_path_("/StatusNotifierHost/" + std::to_string(id)),
|
||||
@ -17,7 +18,8 @@ Host::Host(const std::size_t id, const Json::Value& config, const Bar& bar,
|
||||
config_(config),
|
||||
bar_(bar),
|
||||
on_add_(on_add),
|
||||
on_remove_(on_remove) {}
|
||||
on_remove_(on_remove),
|
||||
on_update_(on_update) {}
|
||||
|
||||
Host::~Host() {
|
||||
if (bus_name_id_ > 0) {
|
||||
@ -54,7 +56,7 @@ void Host::nameVanished(const Glib::RefPtr<Gio::DBus::Connection>& conn, const G
|
||||
g_cancellable_cancel(cancellable_);
|
||||
g_clear_object(&cancellable_);
|
||||
g_clear_object(&watcher_);
|
||||
items_.clear();
|
||||
clearItems();
|
||||
}
|
||||
|
||||
void Host::proxyReady(GObject* src, GAsyncResult* res, gpointer data) {
|
||||
@ -117,13 +119,50 @@ void Host::itemUnregistered(SnWatcher* watcher, const gchar* service, gpointer d
|
||||
auto [bus_name, object_path] = host->getBusNameAndObjectPath(service);
|
||||
for (auto it = host->items_.begin(); it != host->items_.end(); ++it) {
|
||||
if ((*it)->bus_name == bus_name && (*it)->object_path == object_path) {
|
||||
host->on_remove_(*it);
|
||||
host->items_.erase(it);
|
||||
host->removeItem(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Host::itemReady(Item& item) {
|
||||
auto it = std::find_if(items_.begin(), items_.end(),
|
||||
[&item](const auto& candidate) { return candidate.get() == &item; });
|
||||
if (it != items_.end() && (*it)->isReady()) {
|
||||
on_add_(*it);
|
||||
}
|
||||
}
|
||||
|
||||
void Host::itemInvalidated(Item& item) {
|
||||
auto it = std::find_if(items_.begin(), items_.end(),
|
||||
[&item](const auto& candidate) { return candidate.get() == &item; });
|
||||
if (it != items_.end()) {
|
||||
removeItem(it);
|
||||
}
|
||||
}
|
||||
|
||||
void Host::removeItem(std::vector<std::unique_ptr<Item>>::iterator it) {
|
||||
if ((*it)->isReady()) {
|
||||
on_remove_(*it);
|
||||
}
|
||||
items_.erase(it);
|
||||
}
|
||||
|
||||
void Host::clearItems() {
|
||||
bool removed_ready_item = false;
|
||||
for (auto& item : items_) {
|
||||
if (item->isReady()) {
|
||||
on_remove_(item);
|
||||
removed_ready_item = true;
|
||||
}
|
||||
}
|
||||
bool had_items = !items_.empty();
|
||||
items_.clear();
|
||||
if (had_items && !removed_ready_item) {
|
||||
on_update_();
|
||||
}
|
||||
}
|
||||
|
||||
std::tuple<std::string, std::string> Host::getBusNameAndObjectPath(const std::string service) {
|
||||
auto it = service.find('/');
|
||||
if (it != std::string::npos) {
|
||||
@ -139,8 +178,9 @@ void Host::addRegisteredItem(const std::string& service) {
|
||||
return bus_name == item->bus_name && object_path == item->object_path;
|
||||
});
|
||||
if (it == items_.end()) {
|
||||
items_.emplace_back(new Item(bus_name, object_path, config_, bar_));
|
||||
on_add_(items_.back());
|
||||
items_.emplace_back(new Item(
|
||||
bus_name, object_path, config_, bar_, [this](Item& item) { itemReady(item); },
|
||||
[this](Item& item) { itemInvalidated(item); }, on_update_));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
#include <gtkmm/tooltip.h>
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
@ -37,13 +38,18 @@ namespace waybar::modules::SNI {
|
||||
static const Glib::ustring SNI_INTERFACE_NAME = sn_item_interface_info()->name;
|
||||
static const unsigned UPDATE_DEBOUNCE_TIME = 10;
|
||||
|
||||
Item::Item(const std::string& bn, const std::string& op, const Json::Value& config, const Bar& bar)
|
||||
Item::Item(const std::string& bn, const std::string& op, const Json::Value& config, const Bar& bar,
|
||||
const std::function<void(Item&)>& on_ready,
|
||||
const std::function<void(Item&)>& on_invalidate, const std::function<void()>& on_updated)
|
||||
: bus_name(bn),
|
||||
object_path(op),
|
||||
icon_size(16),
|
||||
effective_icon_size(0),
|
||||
icon_theme(Gtk::IconTheme::create()),
|
||||
bar_(bar) {
|
||||
bar_(bar),
|
||||
on_ready_(on_ready),
|
||||
on_invalidate_(on_invalidate),
|
||||
on_updated_(on_updated) {
|
||||
if (config["icon-size"].isUInt()) {
|
||||
icon_size = config["icon-size"].asUInt();
|
||||
}
|
||||
@ -85,6 +91,8 @@ Item::~Item() {
|
||||
}
|
||||
}
|
||||
|
||||
bool Item::isReady() const { return ready_; }
|
||||
|
||||
bool Item::handleMouseEnter(GdkEventCrossing* const& e) {
|
||||
event_box.set_state_flags(Gtk::StateFlags::STATE_FLAG_PRELIGHT);
|
||||
return false;
|
||||
@ -112,14 +120,18 @@ void Item::proxyReady(Glib::RefPtr<Gio::AsyncResult>& result) {
|
||||
|
||||
if (this->id.empty() || this->category.empty()) {
|
||||
spdlog::error("Invalid Status Notifier Item: {}, {}", bus_name, object_path);
|
||||
invalidate();
|
||||
return;
|
||||
}
|
||||
this->updateImage();
|
||||
setReady();
|
||||
|
||||
} catch (const Glib::Error& err) {
|
||||
spdlog::error("Failed to create DBus Proxy for {} {}: {}", bus_name, object_path, err.what());
|
||||
invalidate();
|
||||
} catch (const std::exception& err) {
|
||||
spdlog::error("Failed to create DBus Proxy for {} {}: {}", bus_name, object_path, err.what());
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@ -184,11 +196,11 @@ void Item::setProperty(const Glib::ustring& name, Glib::VariantBase& value) {
|
||||
} else if (name == "OverlayIconName") {
|
||||
overlay_icon_name = get_variant<std::string>(value);
|
||||
} else if (name == "OverlayIconPixmap") {
|
||||
// TODO: overlay_icon_pixmap
|
||||
overlay_icon_pixmap = extractPixBuf(value.gobj());
|
||||
} else if (name == "AttentionIconName") {
|
||||
attention_icon_name = get_variant<std::string>(value);
|
||||
} else if (name == "AttentionIconPixmap") {
|
||||
// TODO: attention_icon_pixmap
|
||||
attention_icon_pixmap = extractPixBuf(value.gobj());
|
||||
} else if (name == "AttentionMovieName") {
|
||||
attention_movie_name = get_variant<std::string>(value);
|
||||
} else if (name == "ToolTip") {
|
||||
@ -217,18 +229,35 @@ void Item::setProperty(const Glib::ustring& name, Glib::VariantBase& value) {
|
||||
}
|
||||
|
||||
void Item::setStatus(const Glib::ustring& value) {
|
||||
Glib::ustring lower = value.lowercase();
|
||||
event_box.set_visible(show_passive_ || lower.compare("passive") != 0);
|
||||
status_ = value.lowercase();
|
||||
event_box.set_visible(show_passive_ || status_.compare("passive") != 0);
|
||||
|
||||
auto style = event_box.get_style_context();
|
||||
for (const auto& class_name : style->list_classes()) {
|
||||
style->remove_class(class_name);
|
||||
}
|
||||
if (lower.compare("needsattention") == 0) {
|
||||
auto css_class = status_;
|
||||
if (css_class.compare("needsattention") == 0) {
|
||||
// convert status to dash-case for CSS
|
||||
lower = "needs-attention";
|
||||
css_class = "needs-attention";
|
||||
}
|
||||
style->add_class(lower);
|
||||
style->add_class(css_class);
|
||||
on_updated_();
|
||||
}
|
||||
|
||||
void Item::setReady() {
|
||||
if (ready_) {
|
||||
return;
|
||||
}
|
||||
ready_ = true;
|
||||
on_ready_(*this);
|
||||
}
|
||||
|
||||
void Item::invalidate() {
|
||||
if (ready_) {
|
||||
ready_ = false;
|
||||
}
|
||||
on_invalidate_(*this);
|
||||
}
|
||||
|
||||
void Item::setCustomIcon(const std::string& id) {
|
||||
@ -287,8 +316,8 @@ void Item::processUpdatedProperties(Glib::RefPtr<Gio::AsyncResult>& _result) {
|
||||
static const std::map<std::string_view, std::set<std::string_view>> signal2props = {
|
||||
{"NewTitle", {"Title"}},
|
||||
{"NewIcon", {"IconName", "IconPixmap"}},
|
||||
// {"NewAttentionIcon", {"AttentionIconName", "AttentionIconPixmap", "AttentionMovieName"}},
|
||||
// {"NewOverlayIcon", {"OverlayIconName", "OverlayIconPixmap"}},
|
||||
{"NewAttentionIcon", {"AttentionIconName", "AttentionIconPixmap", "AttentionMovieName"}},
|
||||
{"NewOverlayIcon", {"OverlayIconName", "OverlayIconPixmap"}},
|
||||
{"NewIconThemePath", {"IconThemePath"}},
|
||||
{"NewToolTip", {"ToolTip"}},
|
||||
{"NewStatus", {"Status"}},
|
||||
@ -378,36 +407,24 @@ void Item::updateImage() {
|
||||
pixbuf = pixbuf->scale_simple(width, scaled_icon_size, Gdk::InterpType::INTERP_BILINEAR);
|
||||
}
|
||||
|
||||
pixbuf = overlayPixbufs(pixbuf, getOverlayIconPixbuf());
|
||||
|
||||
auto surface =
|
||||
Gdk::Cairo::create_surface_from_pixbuf(pixbuf, image.get_scale_factor(), image.get_window());
|
||||
image.set(surface);
|
||||
}
|
||||
|
||||
Glib::RefPtr<Gdk::Pixbuf> Item::getIconPixbuf() {
|
||||
if (!icon_name.empty()) {
|
||||
try {
|
||||
std::ifstream temp(icon_name);
|
||||
if (temp.is_open()) {
|
||||
return Gdk::Pixbuf::create_from_file(icon_name);
|
||||
}
|
||||
} catch (Glib::Error& e) {
|
||||
// Ignore because we want to also try different methods of getting an icon.
|
||||
//
|
||||
// But a warning is logged, as the file apparently exists, but there was
|
||||
// a failure in creating a pixbuf out of it.
|
||||
|
||||
spdlog::warn("Item '{}': {}", id, static_cast<std::string>(e.what()));
|
||||
}
|
||||
|
||||
try {
|
||||
// Will throw if it can not find an icon.
|
||||
return getIconByName(icon_name, getScaledIconSize());
|
||||
} catch (Glib::Error& e) {
|
||||
spdlog::trace("Item '{}': {}", id, static_cast<std::string>(e.what()));
|
||||
if (status_ == "needsattention") {
|
||||
if (auto attention_pixbuf = getAttentionIconPixbuf()) {
|
||||
return attention_pixbuf;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the pixmap only if an icon for the given name could not be found.
|
||||
if (auto pixbuf = loadIconFromNameOrFile(icon_name, true)) {
|
||||
return pixbuf;
|
||||
}
|
||||
|
||||
if (icon_pixmap) {
|
||||
return icon_pixmap;
|
||||
}
|
||||
@ -422,6 +439,77 @@ Glib::RefPtr<Gdk::Pixbuf> Item::getIconPixbuf() {
|
||||
return getIconByName("image-missing", getScaledIconSize());
|
||||
}
|
||||
|
||||
Glib::RefPtr<Gdk::Pixbuf> Item::getAttentionIconPixbuf() {
|
||||
if (auto pixbuf = loadIconFromNameOrFile(attention_icon_name, false)) {
|
||||
return pixbuf;
|
||||
}
|
||||
if (auto pixbuf = loadIconFromNameOrFile(attention_movie_name, false)) {
|
||||
return pixbuf;
|
||||
}
|
||||
return attention_icon_pixmap;
|
||||
}
|
||||
|
||||
Glib::RefPtr<Gdk::Pixbuf> Item::getOverlayIconPixbuf() {
|
||||
if (auto pixbuf = loadIconFromNameOrFile(overlay_icon_name, false)) {
|
||||
return pixbuf;
|
||||
}
|
||||
return overlay_icon_pixmap;
|
||||
}
|
||||
|
||||
Glib::RefPtr<Gdk::Pixbuf> Item::loadIconFromNameOrFile(const std::string& name, bool log_failure) {
|
||||
if (name.empty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
try {
|
||||
std::ifstream temp(name);
|
||||
if (temp.is_open()) {
|
||||
return Gdk::Pixbuf::create_from_file(name);
|
||||
}
|
||||
} catch (const Glib::Error& e) {
|
||||
if (log_failure) {
|
||||
spdlog::warn("Item '{}': {}", id, static_cast<std::string>(e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return getIconByName(name, getScaledIconSize());
|
||||
} catch (const Glib::Error& e) {
|
||||
if (log_failure) {
|
||||
spdlog::trace("Item '{}': {}", id, static_cast<std::string>(e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Glib::RefPtr<Gdk::Pixbuf> Item::overlayPixbufs(const Glib::RefPtr<Gdk::Pixbuf>& base,
|
||||
const Glib::RefPtr<Gdk::Pixbuf>& overlay) {
|
||||
if (!base || !overlay) {
|
||||
return base;
|
||||
}
|
||||
|
||||
auto composed = base->copy();
|
||||
if (!composed) {
|
||||
return base;
|
||||
}
|
||||
|
||||
int overlay_target_size =
|
||||
std::max(1, std::min(composed->get_width(), composed->get_height()) / 2);
|
||||
auto scaled_overlay = overlay->scale_simple(overlay_target_size, overlay_target_size,
|
||||
Gdk::InterpType::INTERP_BILINEAR);
|
||||
if (!scaled_overlay) {
|
||||
return composed;
|
||||
}
|
||||
|
||||
int dest_x = std::max(0, composed->get_width() - scaled_overlay->get_width());
|
||||
int dest_y = std::max(0, composed->get_height() - scaled_overlay->get_height());
|
||||
scaled_overlay->composite(composed, dest_x, dest_y, scaled_overlay->get_width(),
|
||||
scaled_overlay->get_height(), dest_x, dest_y, 1.0, 1.0,
|
||||
Gdk::InterpType::INTERP_BILINEAR, 255);
|
||||
return composed;
|
||||
}
|
||||
|
||||
Glib::RefPtr<Gdk::Pixbuf> Item::getIconByName(const std::string& name, int request_size) {
|
||||
if (!icon_theme_path.empty()) {
|
||||
auto icon_info = icon_theme->lookup_icon(name.c_str(), request_size,
|
||||
@ -464,6 +552,9 @@ void Item::makeMenu() {
|
||||
}
|
||||
|
||||
bool Item::handleClick(GdkEventButton* const& ev) {
|
||||
if (!proxy_) {
|
||||
return false;
|
||||
}
|
||||
auto parameters = Glib::VariantContainerBase::create_tuple(
|
||||
{Glib::Variant<int>::create(ev->x_root + bar_.x_global),
|
||||
Glib::Variant<int>::create(ev->y_root + bar_.y_global)});
|
||||
@ -491,6 +582,9 @@ bool Item::handleClick(GdkEventButton* const& ev) {
|
||||
}
|
||||
|
||||
bool Item::handleScroll(GdkEventScroll* const& ev) {
|
||||
if (!proxy_) {
|
||||
return false;
|
||||
}
|
||||
int dx = 0, dy = 0;
|
||||
switch (ev->direction) {
|
||||
case GDK_SCROLL_UP:
|
||||
|
||||
@ -13,7 +13,8 @@ Tray::Tray(const std::string& id, const Bar& bar, const Json::Value& config)
|
||||
box_(bar.orientation, 0),
|
||||
watcher_(SNI::Watcher::getInstance()),
|
||||
host_(nb_hosts_, config, bar, std::bind(&Tray::onAdd, this, std::placeholders::_1),
|
||||
std::bind(&Tray::onRemove, this, std::placeholders::_1)) {
|
||||
std::bind(&Tray::onRemove, this, std::placeholders::_1),
|
||||
std::bind(&Tray::queueUpdate, this)) {
|
||||
box_.set_name("tray");
|
||||
event_box_.add(box_);
|
||||
if (!id.empty()) {
|
||||
@ -33,6 +34,8 @@ Tray::Tray(const std::string& id, const Bar& bar, const Json::Value& config)
|
||||
dp.emit();
|
||||
}
|
||||
|
||||
void Tray::queueUpdate() { dp.emit(); }
|
||||
|
||||
void Tray::onAdd(std::unique_ptr<Item>& item) {
|
||||
if (config_["reverse-direction"].isBool() && config_["reverse-direction"].asBool()) {
|
||||
box_.pack_end(item->event_box);
|
||||
|
||||
@ -69,7 +69,7 @@ gboolean Watcher::handleRegisterHost(Watcher* obj, GDBusMethodInvocation* invoca
|
||||
if (watch != nullptr) {
|
||||
g_warning("Status Notifier Host with bus name '%s' and object path '%s' is already registered",
|
||||
bus_name, object_path);
|
||||
sn_watcher_complete_register_item(obj->watcher_, invocation);
|
||||
sn_watcher_complete_register_host(obj->watcher_, invocation);
|
||||
return TRUE;
|
||||
}
|
||||
watch = gfWatchNew(GF_WATCH_TYPE_HOST, service, bus_name, object_path, obj);
|
||||
@ -98,8 +98,8 @@ gboolean Watcher::handleRegisterItem(Watcher* obj, GDBusMethodInvocation* invoca
|
||||
}
|
||||
auto watch = gfWatchFind(obj->items_, bus_name, object_path);
|
||||
if (watch != nullptr) {
|
||||
g_warning("Status Notifier Item with bus name '%s' and object path '%s' is already registered",
|
||||
bus_name, object_path);
|
||||
spdlog::debug("Ignoring duplicate Status Notifier Item registration for '{}' at '{}'", bus_name,
|
||||
object_path);
|
||||
sn_watcher_complete_register_item(obj->watcher_, invocation);
|
||||
return TRUE;
|
||||
}
|
||||
@ -158,7 +158,7 @@ void Watcher::nameVanished(GDBusConnection* connection, const char* name, gpoint
|
||||
watch->watcher->hosts_ = g_slist_remove(watch->watcher->hosts_, watch);
|
||||
if (watch->watcher->hosts_ == nullptr) {
|
||||
sn_watcher_set_is_host_registered(watch->watcher->watcher_, FALSE);
|
||||
sn_watcher_emit_host_registered(watch->watcher->watcher_);
|
||||
sn_watcher_emit_host_unregistered(watch->watcher->watcher_);
|
||||
}
|
||||
} else if (watch->type == GF_WATCH_TYPE_ITEM) {
|
||||
watch->watcher->items_ = g_slist_remove(watch->watcher->items_, watch);
|
||||
@ -167,6 +167,7 @@ void Watcher::nameVanished(GDBusConnection* connection, const char* name, gpoint
|
||||
sn_watcher_emit_item_unregistered(watch->watcher->watcher_, tmp);
|
||||
g_free(tmp);
|
||||
}
|
||||
gfWatchFree(watch);
|
||||
}
|
||||
|
||||
void Watcher::updateRegisteredItems(SnWatcher* obj) {
|
||||
|
||||
Reference in New Issue
Block a user