Как создать расширения nautilus C
Я пытаюсь создать расширение Nautilus в C, но есть только примеры Python и помогает.
почти никакой документации и буквально никаких примеров, но только некоторые полные расширения, которые долго и трудно понять для новичка.
мне нужен простой пример кода, который создает новый столбец в списке "Наутилуса". Как написать и скомпилировать его.
код, который я пробовал-это:
#include <libnautilus-extension/nautilus-column-provider.h>
typedef struct _FooExtension FooExtension;
typedef struct _FooExtensionClass FooExtensionClass;
struct _FooExtension
{
GObject parent_slot;
};
struct _FooExtensionClass
{
GObjectClass parent_slot;
};
static void foo_extension_class_init (FooExtensionClass *class);
static void foo_extension_instance_init (FooExtension *img);
static void foo_extension_class_init(FooExtensionClass *class)
{
}
static void foo_extension_instance_init(FooExtension *img)
{
}
static GType provider_types[1];
static GType foo_extension_type;
static void foo_extension_register_type(GTypeModule *module)
{
static const GTypeInfo info = {
sizeof(FooExtensionClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) foo_extension_class_init,
NULL,
NULL,
sizeof (FooExtension),
0,
(GInstanceInitFunc) foo_extension_instance_init,
};
foo_extension_type = g_type_module_register_type(module,
G_TYPE_OBJECT,
"FooExtension",
&info, 0);
/* ... add interfaces ... */
}
GType foo_extension_get_type(void)
{
return foo_extension_type;
}
static GList *foo_extension_get_columns(NautilusColumnProvider *provider)
{
NautilusColumn *column;
GList *ret;
column = nautilus_column_new("FooExtension::foo_data_column", "FooExtension::foo_data", "Foo Data", "Foo Description");
/* _("Foo Data"),
_("Information from the Foo Extension"));*/
ret = g_list_append(NULL, column);
return ret;
}
void nautilus_module_initialize (GTypeModule *module)
{
foo_extension_register_type(module);
provider_types[0] = foo_extension_get_type();
}
void nautilus_module_shutdown(void)
{
/* Any module-specific shutdown */
}
void nautilus_module_list_types (const GType **types, int *num_types)
{
*types = provider_types;
*num_types = G_N_ELEMENTS (provider_types);
}
и я построил его с:
gcc-c foo_extension.c -o foo_extension.o -fPIC $(pkg-config libnautilus-extension --libs --cflags)
gcc -shared foo_extension.o -o foo_extension.so $(pkg-config libnautilus-extension --libs --cflags)
и я скопировал его в /usr/lib/nautilus/extensions-2.0/
, тогда я попробовал nautilus -q
но это не работает.
1 ответов
вы также можете получить документацию, указанную в Вики расширения Nautilus С копия в archive.org. Копия в archive.org имеет примеры В C.
EDIT: я добавил полный рабочий пример, а также объяснение недостающих частей в вашем коде.
вы упускаете две вещи:
- добавить интерфейсы. Для поставщика столбцов будет foo_extension_column_provider_iface_init, и там вам нужно связать ссылку интерфейсов, ожидаемых с вашей реализацией. В данном конкретном случае get_columns.
- с предыдущим, вы получите только столбец, но с неизвестным значением для каждого файла. Поэтому вы должны использовать инфо-провайдера тоже. В частности, интерфейс update_file_info. В этом интерфейсе вы можете связать атрибут для вашего столбца с каждым файлом через nautilus_file_info_add_string_attribute.
ниже у вас есть рабочий пример. Остерегайтесь NautilusFileInfoProvider является частью асинхронной системы ввода-вывода Nautilus. Следовательно, если операции будут медленными, вы заблокируете Nautilus. В приведенном ниже примере я просто установил фиксированную строку для каждого файла ("Фу"). Однако, если вам нужно собрать другую информацию, то вы должны снабдить также доводы update_complete и дескриптор и cancel_update интерфейс. Проверьте документация, копия которой доступна в archive.org
#include <libnautilus-extension/nautilus-column-provider.h>
#include <libnautilus-extension/nautilus-info-provider.h>
typedef struct _FooExtension FooExtension;
typedef struct _FooExtensionClass FooExtensionClass;
typedef struct {
GClosure *update_complete;
NautilusInfoProvider *provider;
NautilusFileInfo *file;
int operation_handle;
gboolean cancelled;
} UpdateHandle;
struct _FooExtension
{
GObject parent_slot;
};
struct _FooExtensionClass
{
GObjectClass parent_slot;
};
static void foo_extension_class_init (FooExtensionClass *class);
static void foo_extension_instance_init (FooExtension *img);
static GList *foo_extension_get_columns (NautilusColumnProvider *provider);
static NautilusOperationResult foo_extension_update_file_info (
NautilusInfoProvider *provider,
NautilusFileInfo *file,
GClosure *update_complete,
NautilusOperationHandle **handle);
/* Interfaces */
static void
foo_extension_column_provider_iface_init (NautilusColumnProviderIface *iface) {
iface->get_columns = foo_extension_get_columns;
return;
}
static void
foo_extension_info_provider_iface_init (NautilusInfoProviderIface *iface) {
iface->update_file_info = foo_extension_update_file_info;
return;
}
/* Extension */
static void foo_extension_class_init(FooExtensionClass *class)
{
}
static void foo_extension_instance_init(FooExtension *img)
{
}
static GType provider_types[1];
static GType foo_extension_type;
static void foo_extension_register_type(GTypeModule *module)
{
static const GTypeInfo info = {
sizeof(FooExtensionClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) foo_extension_class_init,
NULL,
NULL,
sizeof (FooExtension),
0,
(GInstanceInitFunc) foo_extension_instance_init,
};
static const GInterfaceInfo column_provider_iface_info = {
(GInterfaceInitFunc) foo_extension_column_provider_iface_init,
NULL,
NULL
};
static const GInterfaceInfo info_provider_iface_info = {
(GInterfaceInitFunc) foo_extension_info_provider_iface_init,
NULL,
NULL
};
foo_extension_type = g_type_module_register_type(module,
G_TYPE_OBJECT,
"FooExtension",
&info, 0);
/* ... add interfaces ... */
g_type_module_add_interface (module,
foo_extension_type,
NAUTILUS_TYPE_COLUMN_PROVIDER,
&column_provider_iface_info);
g_type_module_add_interface (module,
foo_extension_type,
NAUTILUS_TYPE_INFO_PROVIDER,
&info_provider_iface_info);
}
GType foo_extension_get_type(void)
{
return foo_extension_type;
}
/* Column interfaces */
static GList *foo_extension_get_columns(NautilusColumnProvider *provider)
{
NautilusColumn *column;
GList *ret;
column = nautilus_column_new ("FooExtension::foo_data_column",
"FooExtension::foo_data",
"Foo Data",
"Foo Description");
ret = g_list_append(NULL, column);
return ret;
}
/* Info interfaces */
static NautilusOperationResult
foo_extension_update_file_info (NautilusInfoProvider *provider,
NautilusFileInfo *file,
GClosure *update_complete,
NautilusOperationHandle **handle)
{
char *data;
/* Check if we've previously cached the file info */
data = g_object_get_data (G_OBJECT (file), "foo_extension_data");
/* get and provide the information associated with the column.
If the operation is not fast enough, we should use the arguments
update_complete and handle for asyncrhnous operation. */
if (!data) {
data = g_strdup ("Foo");
}
nautilus_file_info_add_string_attribute (file,
"FooExtension::foo_data",
data);
return NAUTILUS_OPERATION_COMPLETE;
}
/* Extension initialization */
void nautilus_module_initialize (GTypeModule *module)
{
foo_extension_register_type(module);
provider_types[0] = foo_extension_get_type();
}
void nautilus_module_shutdown(void)
{
/* Any module-specific shutdown */
}
void nautilus_module_list_types (const GType **types, int *num_types)
{
*types = provider_types;
*num_types = G_N_ELEMENTS (provider_types);
}
скомпилировать его:
$ gcc -c foo-extension.c -o foo-extension.o -fPIC $(pkg-config libnautilus-extension --cflags)
$ gcc -shared foo-extension.o -o foo-extension.so $(pkg-config libnautilus-extension --libs)
для тестирования расширения сначала необходимо остановить любой запущенный экземпляр nautilus и повторно запустить nautilus. То есть:
$ nautilus -q
$ nautilus
обратите внимание, что без параметра - q вы использовали, что для quit.
если вы хотите проверить, если Наутилус загружает ваше расширение, вы можете использовать strace следующим образом:
$ strace -e trace=open nautilus
и посмотреть, какие библиотеки и файлы Наутилус загрузки/открытия.
во время работы в вашем расширении, вместо копирования файла расширения в [libdir] / nautilus / extensions-3.0, вы можете создать символическую ссылку в свой рабочий каталог. Если вы используете Наутилус 2.x, Используйте [libdir] / nautilus / extensions-2.0.