fix urgent window icons
This commit is contained in:
@@ -15,12 +15,12 @@
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
constexpr const char *kWatcherBusName = "org.kde.StatusNotifierWatcher";
|
||||
constexpr const char *kWatcherObjectPath = "/StatusNotifierWatcher";
|
||||
constexpr const char *kWatcherInterface = "org.kde.StatusNotifierWatcher";
|
||||
constexpr const char *kItemInterface = "org.kde.StatusNotifierItem";
|
||||
constexpr const char *kWatcherBusName = "org.kde.StatusNotifierWatcher";
|
||||
constexpr const char *kWatcherObjectPath = "/StatusNotifierWatcher";
|
||||
constexpr const char *kWatcherInterface = "org.kde.StatusNotifierWatcher";
|
||||
constexpr const char *kItemInterface = "org.kde.StatusNotifierItem";
|
||||
constexpr const char *kDBusPropertiesIface = "org.freedesktop.DBus.Properties";
|
||||
constexpr const char *kDBusMenuInterface = "com.canonical.dbusmenu";
|
||||
constexpr const char *kDBusMenuInterface = "com.canonical.dbusmenu";
|
||||
|
||||
const char *kWatcherIntrospection =
|
||||
R"(<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-Bus Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||
@@ -55,25 +55,25 @@ ParsedService parse_service_identifier(const Glib::ustring &sender,
|
||||
ParsedService parsed;
|
||||
|
||||
if (service.empty()) {
|
||||
parsed.busName = sender;
|
||||
parsed.busName = sender;
|
||||
parsed.objectPath = "/StatusNotifierItem";
|
||||
return parsed;
|
||||
}
|
||||
|
||||
if (service.front() == '/') {
|
||||
parsed.busName = sender;
|
||||
parsed.busName = sender;
|
||||
parsed.objectPath = service;
|
||||
return parsed;
|
||||
}
|
||||
|
||||
const auto slash = service.find('/');
|
||||
if (slash == std::string::npos) {
|
||||
parsed.busName = service;
|
||||
parsed.busName = service;
|
||||
parsed.objectPath = "/StatusNotifierItem";
|
||||
return parsed;
|
||||
}
|
||||
|
||||
parsed.busName = service.substr(0, slash);
|
||||
parsed.busName = service.substr(0, slash);
|
||||
parsed.objectPath = service.substr(slash);
|
||||
|
||||
if (parsed.busName.empty()) {
|
||||
@@ -90,8 +90,8 @@ ParsedService parse_service_identifier(const Glib::ustring &sender,
|
||||
GVariant *create_property_list_variant() {
|
||||
GVariantBuilder builder;
|
||||
g_variant_builder_init(&builder, G_VARIANT_TYPE("as"));
|
||||
const char *properties[] = {"label", "label-markup", "enabled",
|
||||
"visible", "children-display", "type",
|
||||
const char *properties[] = {"label", "label-markup", "enabled",
|
||||
"visible", "children-display", "type",
|
||||
"toggle-type", "toggle-state"};
|
||||
for (const char *prop : properties) {
|
||||
g_variant_builder_add(&builder, "s", prop);
|
||||
@@ -106,7 +106,7 @@ void call_about_to_show(const Glib::RefPtr<Gio::DBus::Connection> &connection,
|
||||
return;
|
||||
}
|
||||
|
||||
GError *error = nullptr;
|
||||
GError *error = nullptr;
|
||||
GVariant *result = g_dbus_connection_call_sync(
|
||||
connection->gobj(), busName.c_str(), menuPath.c_str(),
|
||||
kDBusMenuInterface, "AboutToShow", g_variant_new("(i)", id), nullptr,
|
||||
@@ -137,7 +137,7 @@ GVariant *call_get_layout(const Glib::RefPtr<Gio::DBus::Connection> &connection,
|
||||
GVariant *params = g_variant_new("(ii@as)", 0, -1, properties);
|
||||
g_variant_ref_sink(properties);
|
||||
|
||||
GError *error = nullptr;
|
||||
GError *error = nullptr;
|
||||
GVariant *result = g_dbus_connection_call_sync(
|
||||
connection->gobj(), busName.c_str(), menuPath.c_str(),
|
||||
kDBusMenuInterface, "GetLayout", params, nullptr,
|
||||
@@ -174,15 +174,15 @@ void parse_menu_node(GVariant *tuple, TrayService::MenuNode &outNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
int id = 0;
|
||||
GVariant *propsVariant = nullptr;
|
||||
int id = 0;
|
||||
GVariant *propsVariant = nullptr;
|
||||
GVariant *childrenVariant = nullptr;
|
||||
|
||||
g_variant_get(tuple, "(i@a{sv}@av)", &id, &propsVariant, &childrenVariant);
|
||||
|
||||
outNode.id = id;
|
||||
outNode.enabled = true;
|
||||
outNode.visible = true;
|
||||
outNode.id = id;
|
||||
outNode.enabled = true;
|
||||
outNode.visible = true;
|
||||
outNode.separator = false;
|
||||
outNode.label.clear();
|
||||
|
||||
@@ -190,7 +190,7 @@ void parse_menu_node(GVariant *tuple, TrayService::MenuNode &outNode) {
|
||||
GVariantIter iter;
|
||||
g_variant_iter_init(&iter, propsVariant);
|
||||
const gchar *key = nullptr;
|
||||
GVariant *value = nullptr;
|
||||
GVariant *value = nullptr;
|
||||
|
||||
while (g_variant_iter_next(&iter, "{sv}", &key, &value)) {
|
||||
if (!key || !value) {
|
||||
@@ -214,13 +214,13 @@ void parse_menu_node(GVariant *tuple, TrayService::MenuNode &outNode) {
|
||||
if (std::strcmp(key, "label") == 0) {
|
||||
if (g_variant_is_of_type(unboxed, G_VARIANT_TYPE_STRING)) {
|
||||
const gchar *str = g_variant_get_string(unboxed, nullptr);
|
||||
outNode.label = str ? str : "";
|
||||
outNode.label = str ? str : "";
|
||||
}
|
||||
} else if (std::strcmp(key, "label-markup") == 0 &&
|
||||
outNode.label.empty()) {
|
||||
if (g_variant_is_of_type(unboxed, G_VARIANT_TYPE_STRING)) {
|
||||
const gchar *str = g_variant_get_string(unboxed, nullptr);
|
||||
outNode.label = str ? str : "";
|
||||
outNode.label = str ? str : "";
|
||||
}
|
||||
} else if (std::strcmp(key, "enabled") == 0) {
|
||||
if (g_variant_is_of_type(unboxed, G_VARIANT_TYPE_BOOLEAN)) {
|
||||
@@ -362,7 +362,7 @@ void TrayService::activate(const std::string &id, int32_t x, int32_t y) {
|
||||
return;
|
||||
}
|
||||
|
||||
GError *error = nullptr;
|
||||
GError *error = nullptr;
|
||||
GVariant *result = g_dbus_connection_call_sync(
|
||||
connection->gobj(), it->second->publicData.busName.c_str(),
|
||||
it->second->publicData.objectPath.c_str(), kItemInterface, "Activate",
|
||||
@@ -387,7 +387,7 @@ void TrayService::secondaryActivate(const std::string &id, int32_t x,
|
||||
return;
|
||||
}
|
||||
|
||||
GError *error = nullptr;
|
||||
GError *error = nullptr;
|
||||
GVariant *result = g_dbus_connection_call_sync(
|
||||
connection->gobj(), it->second->publicData.busName.c_str(),
|
||||
it->second->publicData.objectPath.c_str(), kItemInterface,
|
||||
@@ -411,7 +411,7 @@ void TrayService::contextMenu(const std::string &id, int32_t x, int32_t y) {
|
||||
return;
|
||||
}
|
||||
|
||||
GError *error = nullptr;
|
||||
GError *error = nullptr;
|
||||
GVariant *result = g_dbus_connection_call_sync(
|
||||
connection->gobj(), it->second->publicData.busName.c_str(),
|
||||
it->second->publicData.objectPath.c_str(), kItemInterface,
|
||||
@@ -566,7 +566,7 @@ bool TrayService::activate_menu_item(const std::string &id, int itemId) {
|
||||
"(isvu)", itemId, "clicked", g_variant_new_variant(emptyData),
|
||||
static_cast<guint32>(g_get_monotonic_time() / 1000));
|
||||
|
||||
GError *error = nullptr;
|
||||
GError *error = nullptr;
|
||||
GVariant *result = g_dbus_connection_call_sync(
|
||||
connection->gobj(), item.publicData.busName.c_str(),
|
||||
item.publicData.menuPath.c_str(), kDBusMenuInterface, "Event", params,
|
||||
@@ -723,16 +723,16 @@ void TrayService::register_item(const Glib::ustring &sender,
|
||||
}
|
||||
|
||||
const std::string id = parsed.busName + parsed.objectPath;
|
||||
auto existing = items.find(id);
|
||||
auto existing = items.find(id);
|
||||
if (existing != items.end()) {
|
||||
refresh_item(*existing->second);
|
||||
itemUpdatedSignal.emit(existing->second->publicData);
|
||||
return;
|
||||
}
|
||||
|
||||
auto item = std::make_unique<TrackedItem>();
|
||||
item->publicData.id = id;
|
||||
item->publicData.busName = parsed.busName;
|
||||
auto item = std::make_unique<TrackedItem>();
|
||||
item->publicData.id = id;
|
||||
item->publicData.busName = parsed.busName;
|
||||
item->publicData.objectPath = parsed.objectPath;
|
||||
|
||||
refresh_item(*item);
|
||||
@@ -789,7 +789,7 @@ void TrayService::refresh_item(TrackedItem &item) {
|
||||
return;
|
||||
}
|
||||
|
||||
GError *error = nullptr;
|
||||
GError *error = nullptr;
|
||||
GVariant *reply = g_dbus_connection_call_sync(
|
||||
connection->gobj(), item.publicData.busName.c_str(),
|
||||
item.publicData.objectPath.c_str(), kDBusPropertiesIface, "GetAll",
|
||||
@@ -816,7 +816,7 @@ void TrayService::refresh_item(TrackedItem &item) {
|
||||
g_variant_iter_init(&iter, dictVariant);
|
||||
|
||||
const gchar *key = nullptr;
|
||||
GVariant *value = nullptr;
|
||||
GVariant *value = nullptr;
|
||||
|
||||
Glib::RefPtr<Gdk::Paintable> iconTexture;
|
||||
Glib::RefPtr<Gdk::Paintable> attentionTexture;
|
||||
@@ -836,23 +836,23 @@ void TrayService::refresh_item(TrackedItem &item) {
|
||||
|
||||
if (std::strcmp(key, "Title") == 0) {
|
||||
const gchar *str = g_variant_get_string(value, nullptr);
|
||||
title = str ? str : "";
|
||||
title = str ? str : "";
|
||||
} else if (std::strcmp(key, "Status") == 0) {
|
||||
const gchar *str = g_variant_get_string(value, nullptr);
|
||||
status = str ? str : "";
|
||||
status = str ? str : "";
|
||||
} else if (std::strcmp(key, "Menu") == 0) {
|
||||
if (g_variant_is_of_type(value, G_VARIANT_TYPE_OBJECT_PATH)) {
|
||||
const gchar *str = g_variant_get_string(value, nullptr);
|
||||
menuPath = str ? str : "";
|
||||
menuPath = str ? str : "";
|
||||
} else {
|
||||
const gchar *str = g_variant_get_string(value, nullptr);
|
||||
menuPath = str ? str : "";
|
||||
menuPath = str ? str : "";
|
||||
}
|
||||
} else if (std::strcmp(key, "IconName") == 0) {
|
||||
const gchar *str = g_variant_get_string(value, nullptr);
|
||||
iconName = str ? str : "";
|
||||
iconName = str ? str : "";
|
||||
} else if (std::strcmp(key, "AttentionIconName") == 0) {
|
||||
const gchar *str = g_variant_get_string(value, nullptr);
|
||||
const gchar *str = g_variant_get_string(value, nullptr);
|
||||
attentionIconName = str ? str : "";
|
||||
} else if (std::strcmp(key, "IconPixmap") == 0) {
|
||||
iconTexture = parse_icon_pixmap(value);
|
||||
@@ -864,10 +864,10 @@ void TrayService::refresh_item(TrackedItem &item) {
|
||||
}
|
||||
|
||||
g_variant_unref(dictVariant);
|
||||
const bool menuPathChanged = (item.publicData.menuPath != menuPath);
|
||||
item.publicData.title = title;
|
||||
item.publicData.status = status;
|
||||
item.publicData.menuPath = menuPath;
|
||||
const bool menuPathChanged = (item.publicData.menuPath != menuPath);
|
||||
item.publicData.title = title;
|
||||
item.publicData.status = status;
|
||||
item.publicData.menuPath = menuPath;
|
||||
item.publicData.menuAvailable = !menuPath.empty();
|
||||
|
||||
if (menuPathChanged || !item.publicData.menuAvailable) {
|
||||
@@ -1029,7 +1029,7 @@ Glib::RefPtr<Gdk::Paintable> TrayService::parse_icon_pixmap(GVariant *variant) {
|
||||
return {};
|
||||
}
|
||||
|
||||
int32_t width = 0;
|
||||
int32_t width = 0;
|
||||
int32_t height = 0;
|
||||
g_variant_get_child(entry, 0, "i", &width);
|
||||
g_variant_get_child(entry, 1, "i", &height);
|
||||
@@ -1045,7 +1045,7 @@ Glib::RefPtr<Gdk::Paintable> TrayService::parse_icon_pixmap(GVariant *variant) {
|
||||
return {};
|
||||
}
|
||||
|
||||
gsize rawLength = 0;
|
||||
gsize rawLength = 0;
|
||||
const guint8 *rawBytes = static_cast<const guint8 *>(
|
||||
g_variant_get_fixed_array(bytesVariant, &rawLength, sizeof(guint8)));
|
||||
if (!rawBytes || rawLength < static_cast<gsize>(width * height * 4)) {
|
||||
@@ -1062,16 +1062,16 @@ Glib::RefPtr<Gdk::Paintable> TrayService::parse_icon_pixmap(GVariant *variant) {
|
||||
const guint32 *pixels = reinterpret_cast<const guint32 *>(rawBytes);
|
||||
for (std::size_t idx = 0; idx < pixelCount; ++idx) {
|
||||
const guint32 pixel = pixels[idx];
|
||||
const guint8 a = static_cast<guint8>((pixel >> 24) & 0xFF);
|
||||
const guint8 r = static_cast<guint8>((pixel >> 16) & 0xFF);
|
||||
const guint8 g = static_cast<guint8>((pixel >> 8) & 0xFF);
|
||||
const guint8 b = static_cast<guint8>(pixel & 0xFF);
|
||||
const guint8 a = static_cast<guint8>((pixel >> 24) & 0xFF);
|
||||
const guint8 r = static_cast<guint8>((pixel >> 16) & 0xFF);
|
||||
const guint8 g = static_cast<guint8>((pixel >> 8) & 0xFF);
|
||||
const guint8 b = static_cast<guint8>(pixel & 0xFF);
|
||||
|
||||
const std::size_t base = idx * 4;
|
||||
rgba[base + 0] = r;
|
||||
rgba[base + 1] = g;
|
||||
rgba[base + 2] = b;
|
||||
rgba[base + 3] = a;
|
||||
rgba[base + 0] = r;
|
||||
rgba[base + 1] = g;
|
||||
rgba[base + 2] = b;
|
||||
rgba[base + 3] = a;
|
||||
}
|
||||
|
||||
auto pixbuf =
|
||||
@@ -1082,9 +1082,9 @@ Glib::RefPtr<Gdk::Paintable> TrayService::parse_icon_pixmap(GVariant *variant) {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto *dest = pixbuf->get_pixels();
|
||||
auto *dest = pixbuf->get_pixels();
|
||||
const int destRowstride = pixbuf->get_rowstride();
|
||||
const int srcRowstride = width * 4;
|
||||
const int srcRowstride = width * 4;
|
||||
|
||||
for (int y = 0; y < height; ++y) {
|
||||
std::memcpy(dest + y * destRowstride,
|
||||
|
||||
Reference in New Issue
Block a user