Я пытаюсь добавить поддержку настроек просмотра для отдельных каталогов в файловый браузер Thunar на рабочем столе Xfce. Так, например, если пользователь предпочитает просматривать содержимое каталога в виде списка, а не в виде сетки значков, этот параметр запоминается для этого каталога и будет использоваться при каждом просмотре этого каталога.
Теперь Thunar построен на GLib, и механизм, который мы выбрали для его реализации, заключается в хранении метаданных с использованием атрибутов GFile с использованием таких методов, как g_file_set_attributes_async для хранения ключей с такими именами, как metadata :: thunar-view-type. Функция для каждого каталога может быть включена или отключена пользователем с помощью флажка в диалоговом окне настроек. Мои знания о GIO и GLib довольно ограничены, но теперь мне удалось заставить все это работать должным образом (вы можете увидеть мой запрос на слияние здесь, если вам интересно).
Насколько я понимаю, функциональность, которую я здесь использую, зависит от чего-то, что называется метаданными GVfs, и, насколько я понимаю, это может быть доступно не во всех системах. В системах, где метаданные GVfs недоступны, я хочу отключить эту функцию и, в частности, сделать флажок в диалоговом окне настроек нечувствительным (т. Е. Выделенным серым цветом). Таким образом, мне нужно написать функцию для определения, доступна ли поддержка метаданных gvfs, под этим я подразумеваю, могу ли я использовать такие функции, как g_file_set_attributes_async, для успешного сохранения метаданных, чтобы они были доступны в будущем.
Thunar написан на C, поэтому эта функция должна быть написана на C с использованием C API для GLib, GIO и т. Д. Функция, которую я придумал (из большого чтения документации API, изменения найденных фрагментов кода и экспериментов ) как следует.
gboolean
thunar_g_vfs_metadata_is_supported (void)
{
GDBusMessage *send, *reply;
GDBusConnection *conn;
GVariant *v1, *v2;
GError *error = NULL;
const gchar **service_names;
gboolean metadata_found;
/* connect to the session bus */
conn = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
/* check that the connection was opened sucessfully */
if (error != NULL)
{
g_error_free (error);
return FALSE;
}
/* create the message to send to list the available services */
send = g_dbus_message_new_method_call ("org.freedesktop.DBus",
"/org/freedesktop/DBus",
"org.freedesktop.DBus",
"ListNames");
/* send the message and wait for the reply */
reply = g_dbus_connection_send_message_with_reply_sync (conn, send, G_DBUS_SEND_MESSAGE_FLAGS_NONE,
-1, NULL, NULL, &error);
/* release the connection and the sent message */
g_object_unref (send);
g_object_unref (conn);
/* check if we got a sucessful reply */
if (error != NULL)
{
g_error_free (error);
return FALSE;
}
/* extract the GVariant with the array of strings describing the available services */
v1 = g_dbus_message_get_body (reply); /* v1 belongs to reply and must not be freed */
if (v1 == NULL || !g_variant_is_container (v1) || g_variant_n_children (v1) < 1)
{
g_object_unref (reply);
return FALSE;
}
v2 = g_variant_get_child_value (v1, 0);
g_object_unref (reply);
/* check that the GVariant we have been given does contain an array of strings */
if (!g_variant_is_of_type (v2, G_VARIANT_TYPE_STRING_ARRAY))
{
g_variant_unref (v2);
return FALSE;
}
/* search through the list of service names to see if gvfs metadata is present */
metadata_found = FALSE;
service_names = g_variant_get_strv (v2, NULL);
for (int i=0; service_names[i] != NULL; i++)
if (g_strcmp0 (service_names[i], "org.gtk.vfs.Metadata") == 0)
metadata_found = TRUE;
g_free (service_names);
g_variant_unref (v2);
return metadata_found;
}
Как видите, эта функция использует DBus для запроса имен служб, чтобы узнать, доступна ли необходимая служба. Насколько я могу проверить, эта функция работает так, как я хочу. Однако во время обзора кода возник вопрос, можно ли это сделать, не полагаясь на DBus (который сам по себе может быть недоступен, даже если есть метаданные GVfs).
Итак (наконец!) Мой вопрос: каков наилучший (т.е. самый надежный и точный) способ проверить поддержку метаданных GVfs через C API для GLib, GIO и т. Д.?. Как я сказал выше, под поддержкой метаданных GVfs я имею в виду, могу ли я использовать такие функции, как g_file_set_attributes_async, для успешного сохранения метаданных, чтобы они были доступны в будущем ?.
Один из рассмотренных мной методов - это просмотр списка запущенных процессов с именем gvfsd-metadata, но мне это кажется немного запутанным.
Кроме того, как упоминалось выше, я новичок в этих технологиях, поэтому вполне возможно, что я неправильно понял здесь материал, поэтому, если вы заметите какие-либо ошибки в утверждениях, которые я сделал выше, сообщите мне.
Спасибо!
(И да, обычная история, я давно читаю SO & co, но впервые задаю вопрос, поэтому, пожалуйста, не стесняйтесь редактировать или дайте мне знать, если я сделал что-то не так / плохо)