├── .editorconfig ├── .gitignore ├── LICENSE.txt ├── README.md ├── _doc └── convert-to-png.png ├── meson.build └── src ├── meson.build ├── nautilus-png-convert-module.c ├── nautilus-png-convert.c └── nautilus-png-convert.h /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = false 9 | insert_final_newline = true 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /.vscode 3 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | ok if you're into that sort of thing 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nautilus-png-convert 2 | 3 | A right-click context menu for Nautilus to convert images to PNG via ImageMagick. 4 | 5 | ![A screenshot of the context menu when this extension is installed](./_doc/convert-to-png.png) 6 | 7 | ## Alternatives 8 | 9 | If you don't want to use this extension, you can simply use ImageMagick terminal commands: 10 | 11 | ```shell 12 | $ # Convert a single file: 13 | $ magick my_file.webp my_file.png 14 | ``` 15 | 16 | ```shell 17 | $ # Or if you want to do lots of files at once: 18 | $ magick mogrify -format PNG *.webp 19 | ``` 20 | 21 | ## Building 22 | 23 | ```shell 24 | $ meson setup build . 25 | $ meson compile -C build 26 | $ 27 | $ # Install to system's nautilus extensions dir: 28 | $ meson install -C build 29 | ``` 30 | -------------------------------------------------------------------------------- /_doc/convert-to-png.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/char/nautilus-png-convert/375dbeaff13cc1146f6842fedab2e25338ff457b/_doc/convert-to-png.png -------------------------------------------------------------------------------- /meson.build: -------------------------------------------------------------------------------- 1 | project('nautilus-png-convert', 'c', version: '0.5.0', 2 | meson_version: '>= 0.59.0', 3 | default_options: [ 4 | 'buildtype=debugoptimized', 5 | 'warning_level=3', 6 | 'c_std=c18', 7 | ], 8 | ) 9 | 10 | config_h = configuration_data() 11 | config_h.set_quoted('PACKAGE_NAME', meson.project_name()) 12 | config_h.set_quoted('PACKAGE_VERSION', meson.project_version()) 13 | config_h.set_quoted('PACKAGE_STRING', '@0@ @1@'.format(meson.project_name(), meson.project_version())) 14 | 15 | configure_file( 16 | output: 'nautilus-png-convert-config.h', 17 | configuration: config_h, 18 | ) 19 | 20 | add_project_arguments([ '-I' + meson.project_build_root(), ], language: 'c') 21 | 22 | subdir('src') 23 | -------------------------------------------------------------------------------- /src/meson.build: -------------------------------------------------------------------------------- 1 | nautilus_png_convert_sources = [ 2 | 'nautilus-png-convert-module.c', 3 | 'nautilus-png-convert.c', 4 | ] 5 | 6 | nautilus_png_convert_headers = [ 7 | 'nautilus-png-convert.h', 8 | ] 9 | 10 | libnautilus_extension = dependency('libnautilus-extension', version: '>= 42.2') 11 | nautilus_ext_dir = libnautilus_extension.get_variable('extensiondir') 12 | 13 | nautilus_png_convert_deps = [ 14 | dependency('glib-2.0', version: '>= 2.44'), 15 | libnautilus_extension, 16 | ] 17 | 18 | cc = meson.get_compiler('c') 19 | 20 | add_project_arguments( 21 | cc.get_supported_arguments( 22 | [ 23 | '-Wno-unused-parameter', 24 | ], 25 | ), 26 | language: 'c', 27 | ) 28 | 29 | nautilus_png_convert_lib = shared_library('nautilus-png-convert', 30 | nautilus_png_convert_sources, 31 | nautilus_png_convert_headers, 32 | dependencies: nautilus_png_convert_deps, 33 | install: true, 34 | install_dir: nautilus_ext_dir, 35 | ) 36 | -------------------------------------------------------------------------------- /src/nautilus-png-convert-module.c: -------------------------------------------------------------------------------- 1 | #include "nautilus-png-convert.h" 2 | #include "nautilus-png-convert-config.h" 3 | 4 | #include 5 | #include 6 | 7 | void nautilus_module_initialize(GTypeModule *module) { 8 | nautilus_png_convert_register_type(module); 9 | } 10 | 11 | void nautilus_module_shutdown(void) { 12 | } 13 | 14 | void nautilus_module_list_types(const GType **types, int *num_types) { 15 | static GType provider_type_list[1]; 16 | provider_type_list[0] = NAUTILUS_PNG_CONVERT_TYPE; 17 | 18 | *types = provider_type_list; 19 | *num_types = G_N_ELEMENTS(provider_type_list); 20 | } 21 | -------------------------------------------------------------------------------- /src/nautilus-png-convert.c: -------------------------------------------------------------------------------- 1 | #include "nautilus-png-convert.h" 2 | #include "nautilus-png-convert-config.h" 3 | 4 | #include 5 | #include 6 | 7 | static GType png_convert_type = 0; 8 | static GObjectClass *parent_class; 9 | 10 | static void convert_file(NautilusFileInfo *file_info) { 11 | GFile *file = nautilus_file_info_get_location(file_info); 12 | gchar *path = g_file_get_path(file); 13 | 14 | gchar *without_ext = g_strdup(path); 15 | gchar *extension = strrchr(without_ext, '.'); 16 | if (extension != NULL) 17 | extension = '\0'; 18 | 19 | gchar *png_path = g_strdup_printf("%s.png", without_ext); 20 | g_free(without_ext); 21 | 22 | gchar *argv[4]; 23 | argv[0] = "/usr/bin/magick"; 24 | argv[1] = path; 25 | argv[2] = png_path; 26 | argv[3] = NULL; 27 | 28 | pid_t pid; 29 | if (!g_spawn_async(NULL, argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, NULL)) 30 | return; 31 | 32 | g_free(path); 33 | g_free(png_path); 34 | g_object_unref(file); 35 | } 36 | 37 | static void image_convert_callback(NautilusMenuItem *item, GList *files) { 38 | for (GList *file_info = files; file_info != NULL; file_info = file_info->next) { 39 | convert_file(file_info->data); 40 | } 41 | 42 | nautilus_file_info_list_free(files); 43 | } 44 | 45 | static gboolean nautilus_png_convert_file_is_image(NautilusFileInfo *file_info) { 46 | gboolean maybe_image = TRUE; 47 | 48 | gchar *uri_scheme = nautilus_file_info_get_uri_scheme(file_info); 49 | if (strcmp(uri_scheme, "file") != 0) 50 | maybe_image = FALSE; 51 | g_free(uri_scheme); 52 | 53 | gchar *mime_type = nautilus_file_info_get_mime_type(file_info); 54 | if (g_str_has_prefix(mime_type, "image/")) 55 | maybe_image = FALSE; 56 | // We also don't want to convert PNGs to PNG: 57 | if (strcmp("image/png", mime_type) == 0) 58 | maybe_image = FALSE; 59 | g_free(mime_type); 60 | 61 | return maybe_image; 62 | } 63 | 64 | static GList* nautilus_png_convert_get_file_items(NautilusMenuProvider *provider, GtkWidget *window, GList *files) { 65 | GList *items = NULL; 66 | NautilusMenuItem *item; 67 | 68 | for (GList *file = files; file != NULL; file = file->next) { 69 | if (!nautilus_png_convert_file_is_image(file->data)) 70 | return NULL; 71 | } 72 | 73 | for (GList *file = files; file != NULL; file = file->next) { 74 | item = nautilus_menu_item_new("NautilusPNGConvert::convert", "Convert to PNG", "Convert each selected image to PNG", "camera-photo"); 75 | g_signal_connect(item, "activate", G_CALLBACK(image_convert_callback), nautilus_file_info_list_copy(files)); 76 | items = g_list_append(items, item); 77 | 78 | return items; 79 | } 80 | 81 | return NULL; 82 | } 83 | 84 | static GList* nautilus_png_convert_get_background_items(NautilusMenuProvider *provider, GtkWidget *window, NautilusFileInfo *file_info) { 85 | return NULL; 86 | } 87 | 88 | static void nautilus_png_convert_menu_provider_iface_init(NautilusMenuProviderIface *iface, gpointer _iface_data) { 89 | iface->get_background_items = nautilus_png_convert_get_background_items; 90 | iface->get_file_items = nautilus_png_convert_get_file_items; 91 | } 92 | 93 | static void nautilus_png_convert_class_init(NautilusPNGConvertClass *nautilus_png_convert_class, gpointer class_data) { 94 | parent_class = g_type_class_peek_parent(nautilus_png_convert_class); 95 | } 96 | 97 | void nautilus_png_convert_register_type(GTypeModule *module) { 98 | static const GTypeInfo info = { 99 | sizeof(NautilusPNGConvertClass), 100 | (GBaseInitFunc) NULL, 101 | (GBaseFinalizeFunc) NULL, 102 | (GClassInitFunc) nautilus_png_convert_class_init, 103 | (GClassFinalizeFunc) NULL, 104 | NULL, 105 | sizeof(NautilusPNGConvert), 106 | 0, 107 | (GInstanceInitFunc) NULL, 108 | (GTypeValueTable *) NULL 109 | }; 110 | 111 | static const GInterfaceInfo menu_provider_iface_info = { 112 | (GInterfaceInitFunc) nautilus_png_convert_menu_provider_iface_init, 113 | NULL, 114 | NULL 115 | }; 116 | 117 | png_convert_type = g_type_module_register_type( 118 | module, 119 | G_TYPE_OBJECT, 120 | "NautilusPNGConvert", 121 | &info, 122 | 0 123 | ); 124 | 125 | g_type_module_add_interface( 126 | module, 127 | png_convert_type, 128 | NAUTILUS_TYPE_MENU_PROVIDER, 129 | &menu_provider_iface_info 130 | ); 131 | } 132 | 133 | GType nautilus_png_convert_get_type(void) { 134 | return png_convert_type; 135 | } 136 | -------------------------------------------------------------------------------- /src/nautilus-png-convert.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | G_BEGIN_DECLS 6 | 7 | #define NAUTILUS_PNG_CONVERT_TYPE (nautilus_png_convert_get_type()) 8 | #define NAUTILUS_PNG_CONVERT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), NAUTILUS_PNG_CONVERT_TYPE, NautilusPNGConvert)) 9 | #define NAUTILUS_PNG_CONVERT_IS_NAUTILUS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), NAUTILUS_PNG_CONVERT_TYPE)) 10 | 11 | typedef struct _NautilusPNGConvert NautilusPNGConvert; 12 | typedef struct _NautilusPNGConvertClass NautilusPNGConvertClass; 13 | 14 | struct _NautilusPNGConvert { 15 | GObject __parent; 16 | }; 17 | 18 | struct _NautilusPNGConvertClass { 19 | GObjectClass __parent; 20 | }; 21 | 22 | void nautilus_png_convert_register_type(GTypeModule *module); 23 | GType nautilus_png_convert_get_type(void); 24 | 25 | G_END_DECLS 26 | --------------------------------------------------------------------------------