Указание изображения значка с диска для org.freedesktop.portal.notification Portal?Linux

Ответить
Anonymous
 Указание изображения значка с диска для org.freedesktop.portal.notification Portal?

Сообщение Anonymous »

Я пытаюсь использовать портал org.freedesktop.portal.notification для создания настольных уведомлений.

Код: Выделить всё

    std::string id = "notif-0";

std::map notif;
notif["title"] = sdbus::Variant(info.title);
notif["body"]  = sdbus::Variant(info.body);

m_proxy->callMethod("AddNotification")
.onInterface("org.freedesktop.portal.Notification")
.withArguments(id, notif);
< /code>
(я использую библиотеку SDBUS-CPP для упрощения интерфейса SD-BUS) < /p>
Это работает нормально, но уведомление показывает общий иконку, который я хотел бы заменить на логотип своей программы. Значок существует как изображение PNG на диске. Вот что в документации говорится о том, как указать значок: < /p>

icon (v) < /p>
сериализованный значок для добавления в уведомление. Значок должен пройти значок
valytation
для использования. Формат для сериализованного значка представляет собой кортеж (SV)
со следующими поддерживаемыми ключами: < /p>
[list]
[*]  тематическое (as) < /p>
Тематическое значок, содержащий массив строков. В момент
, но эта совместимость может измениться в будущем. < /p>
< /li>
  Bytes (ay) < /p>
Поскольку версия 2 это снижается и не должно использоваться. Пожалуйста, используйте опцию тематического или файлового деприктор, чтобы установить значок. Файл изображения в форме PNG, JPEG или SVG. Используемый файл-дискриптор должен быть герметизирован, в настоящее время это только
возможно для дескрипторов файлов, созданных с помощью memfd_create () < /code> с
MFD_ALLOW_SEALING
Набор флагов.

[/list]

Он выглядит как указание пути файла непосредственно, и вам нужно вместо этого использовать рукоятку memfd_create . Я предполагаю, что вы должны загрузить данные необработанного файла в память, но это не совсем ясно. В любом случае, вот моя попытка: < /p>
std::optional load_png_into_memfd(const char *path) {
std::ifstream in{path, std::ios::binary | std::ios::ate};
if (!in)
return {};
auto size = in.tellg();
in.seekg(0, std::ios::beg);

std::vector buf(static_cast(size));
if (!in.read(buf.data(), size))
return {};

int mfd = memfd_create("png_mem", MFD_CLOEXEC | MFD_ALLOW_SEALING);
if (mfd < 0)
return {};

if (ftruncate(mfd, size) < 0) {
close(mfd);
return {};
}

ssize_t written = write(mfd, buf.data(), buf.size());
if (written < 0 || static_cast(written) != buf.size()) {
close(mfd);
return {};
}
return mfd;
}

[...]

std::map notif;
notif["title"] = sdbus::Variant(info.title);
notif["body"] = sdbus::Variant(info.body);

auto f = load_png_into_memfd("path/to/icon.png");
assert(f != std::nullopt);
sdbus::UnixFd fd(*f);
auto fdVariant = sdbus::Variant(fd);
auto fdStruct = sdbus::make_struct(
std::string("file-descriptor"),
fdVariant
);
notif["icon"] = sdbus::Variant(fdVariant);

m_proxy->callMethod("AddNotification")
.onInterface("org.freedesktop.portal.Notification")
.withArguments(id, notif);
< /code>
, который приводит к: < /p>
std::runtime_error: '[org.freedesktop.portal.Error.InvalidArgument] invalid notification: invalid icon'
< /code>
Значок составляет 512x512 пикселей, а размер файла составляет 85 КБ, поэтому он выполняет требования, указанные в документации. Любая помощь будет очень оценена!


Подробнее здесь: https://stackoverflow.com/questions/797 ... ion-portal
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Linux»