From ac2b62ff077a2592c7e4e879545ba1319f202bfe Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Thu, 20 Mar 2025 20:10:12 -0400 Subject: [PATCH 1/2] Use GResources for GtkBuilder and System INX files To improve speed on systems where reading lots of small files is slow, we compile our shipped data into the binary itself using Glib's GIO GResources. --- CMakeLists.txt | 2 - buildtools/generate-gresource-xml.py | 56 ++++++ share/inkscape.gresources.xml | 253 +++++++++++++++++++++++++++ src/CMakeLists.txt | 32 ++++ src/extension/init.cpp | 9 +- src/extension/system.cpp | 25 +++ src/extension/system.h | 1 + src/io/resource.cpp | 43 +++++ src/io/resource.h | 5 + src/ui/builder-utils.cpp | 11 +- src/ui/builder-utils.h | 4 + src/xml/repr-io.cpp | 14 ++ src/xml/repr.h | 1 + 13 files changed, 450 insertions(+), 6 deletions(-) create mode 100755 buildtools/generate-gresource-xml.py create mode 100644 share/inkscape.gresources.xml diff --git a/CMakeLists.txt b/CMakeLists.txt index c64887a8c3..b94ef9c98d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -160,8 +160,6 @@ if(NOT WIN32) add_subdirectory(man) endif() - - # ----------------------------------------------------------------------------- # Check License Headers # ----------------------------------------------------------------------------- diff --git a/buildtools/generate-gresource-xml.py b/buildtools/generate-gresource-xml.py new file mode 100755 index 0000000000..2efa1678f7 --- /dev/null +++ b/buildtools/generate-gresource-xml.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-3.0-or-later +# Resource xml generator +# Author: Martin Owens +# Licensed under GPL version 3 or any later version. + +import glob +import os +import sys + +from collections import defaultdict + +PREFIX = '/org/inkscape/' + +SCRIPT = os.path.abspath(os.path.dirname(__file__)) +PATH = os.path.abspath(os.path.join(SCRIPT, '..', 'share')) + +if len(sys.argv) == 2: + PATH = os.path.abspath(sys.argv[-1]) + +if not os.path.isdir(PATH): + sys.stderr.write(f"Couldn't find share path: '{PATH}'") + sys.exit(1) + +WHAT = [ + # Path to the resources, fnmatch, xml attributes + ('ui', "*.ui", {"preprocess": "xml-stripblanks", "compressed": "true"}), + ('ui', "*.glade", {"preprocess": "xml-stripblanks", "compressed": "true"}), + ('extensions', '*.inx', {"preprocess": "xml-stripblanks", "compressed": "true"}), +] + +if __name__ == '__main__': + output = "\n" + for path, pattern, attrs in WHAT: + fullpath = os.path.join(PATH, path) + if not os.path.isdir(fullpath): + sys.stderr.write(f"Can't find resource path: {path}\n") + sys.exit(1) + + att = "" + for key, val in attrs.items(): + att += f" {key}=\"{val}\"" + + for root, subdirs, files in os.walk(fullpath): + for file in files: + if glob.fnmatch.fnmatch(file, pattern): + internal_name = os.path.join(path, root.replace(fullpath, '').strip('/'), file) + output += f" {internal_name}\n" + + if not output: + sys.exit(2) + + print(f""" + + {output} +""") diff --git a/share/inkscape.gresources.xml b/share/inkscape.gresources.xml new file mode 100644 index 0000000000..19afcfca31 --- /dev/null +++ b/share/inkscape.gresources.xml @@ -0,0 +1,253 @@ + + + + ui/toolbar-marker.ui + ui/toolbar-calligraphy.ui + ui/toolbar-star.ui + ui/toolbar-select.ui + ui/toolbar-text.ui + ui/toolbar-spiral.ui + ui/toolbar-box3d.ui + ui/widget-new-from-template.ui + ui/toolbar-tweak.ui + ui/toolbar-measure.ui + ui/toolbar-snap.ui + ui/toolbar-booleans.ui + ui/toolbar-spray.ui + ui/toolbar-commands.ui + ui/toolbar-node.ui + ui/inkview-controls.ui + ui/toolbar-rect.ui + ui/toolbar-objectpicker.ui + ui/toolbar-mesh.ui + ui/toolbar-gradient.ui + ui/toolbar-arc.ui + ui/document-tab-preview.ui + ui/toolbar-dropper.ui + ui/statusbar.ui + ui/toolbar-connector.ui + ui/simple-tab.ui + ui/toolbar-paintbucket.ui + ui/toolbar-eraser.ui + ui/toolbar-tool-prefs.ui + ui/toolbar-pencil.ui + ui/toolbar-page.ui + ui/toolbar-lpe.ui + ui/dialog-spellcheck.ui + ui/dialog-measure-tool-settings.ui + ui/toolbar-tool.ui + ui/align-and-distribute.ui + ui/menus.ui + ui/document-tab.ui + ui/toolbar-zoom.ui + ui/dialog-objects.glade + ui/dialog-livepatheffect.glade + ui/dialog-filter-editor.glade + ui/attribute-edit-component.glade + ui/font-list.glade + ui/page-properties.glade + ui/completion-box.glade + ui/object-attributes.glade + ui/pattern-edit.glade + ui/dialog-livepatheffect-item.glade + ui/canvas-notice.glade + ui/dialog-trace.glade + ui/display-popup.glade + ui/inkscape-start.glade + ui/dialog-css.glade + ui/dialog-text-edit.glade + ui/dialog-xml.glade + ui/command-palette-main.glade + ui/color-page.glade + ui/color-palette.glade + ui/marker-popup.glade + ui/command-palette-operation.glade + ui/dialog-save-template.glade + ui/gradient-edit.glade + ui/dialog-export.glade + ui/dialog-paint-servers.glade + ui/dialog-crash.glade + ui/dialog-document-resources.glade + ui/dialog-symbols.glade + ui/image-properties.glade + ui/dialog-swatches.glade + ui/dialog-extensions.glade + ui/inkscape-about.glade + ui/extension-pdfinput.glade + ui/dialog-export-prefs.glade + ui/dialog-font-collections.glade + extensions/export_gimp_palette.inx + extensions/typst_formula.inx + extensions/straightseg.inx + extensions/convert2dashes.inx + extensions/voronoi_fill.inx + extensions/jessyink_install.inx + extensions/ps_input.inx + extensions/frame.inx + extensions/path_to_absolute.inx + extensions/interp_att_g.inx + extensions/render_barcode.inx + extensions/guides_creator.inx + extensions/color_hsl_adjust.inx + extensions/raster_output_tiff.inx + extensions/color_replace.inx + extensions/pixelsnap.inx + extensions/color_lesssaturation.inx + extensions/color_removeblue.inx + extensions/measure.inx + extensions/tar_layers.inx + extensions/template_seamless_pattern.inx + extensions/text_randomcase.inx + extensions/jessyink_effects.inx + extensions/layers2svgfont.inx + extensions/color_morelight.inx + extensions/text_sentencecase.inx + extensions/printing_marks.inx + extensions/fractalize.inx + extensions/lorem_ipsum.inx + extensions/web_set_att.inx + extensions/image_extract_selected.inx + extensions/param_curves.inx + extensions/guillotine.inx + extensions/scribus_export_pdf.inx + extensions/output_scour.inx + extensions/hershey.inx + extensions/template_business_card.inx + extensions/text_merge.inx + extensions/voronoi_diagram.inx + extensions/svg2fxg.inx + extensions/pdflatex.inx + extensions/media_zip.inx + extensions/web_interactive_mockup.inx + extensions/color_blackandwhite.inx + extensions/web_transmit_att.inx + extensions/foldablebox.inx + extensions/flatten.inx + extensions/perspective.inx + extensions/rtree.inx + extensions/template_dvd_cover.inx + extensions/gimp_xcf.inx + extensions/markers_strokepaint.inx + extensions/eps_input.inx + extensions/layer2png.inx + extensions/jessyink_transitions.inx + extensions/dpi96to90.inx + extensions/image_attributes.inx + extensions/spirograph.inx + extensions/text_split.inx + extensions/replace_font.inx + extensions/grid_polar.inx + extensions/previous_glyph_layer.inx + extensions/dxf_outlines.inx + extensions/handles.inx + extensions/next_glyph_layer.inx + extensions/long_shadow.inx + extensions/text_titlecase.inx + extensions/color_desaturate.inx + extensions/layout_nup.inx + extensions/dxf_input.inx + extensions/twirl.inx + extensions/path_number_nodes.inx + extensions/text_flipcase.inx + extensions/polyhedron_3d.inx + extensions/svgfont2layers.inx + extensions/image_embed_selected.inx + extensions/hpgl_input.inx + extensions/render_alphabetsoup.inx + extensions/jessyink_export.inx + extensions/text_lowercase.inx + extensions/render_barcode_datamatrix.inx + extensions/merge_styles.inx + extensions/render_gears.inx + extensions/jessyink_autotexts.inx + extensions/nicechart.inx + extensions/aisvg.inx + extensions/path_mesh_m2p.inx + extensions/webslicer_create_rect.inx + extensions/interp.inx + extensions/jessyink_master_slide.inx + extensions/new_glyph_layer.inx + extensions/construct_from_triangle.inx + extensions/image_embed.inx + extensions/image_extract.inx + extensions/render_barcode_qrcode.inx + extensions/ungroup_deep.inx + extensions/color_lesshue.inx + extensions/extrude.inx + extensions/dpi90to96.inx + extensions/color_lesslight.inx + extensions/jessyink_key_bindings.inx + extensions/ink2canvas.inx + extensions/color_randomize.inx + extensions/hpgl_output.inx + extensions/rubberstretch.inx + extensions/color_negative.inx + extensions/funcplot.inx + extensions/color_rgbbarrel.inx + extensions/dimension.inx + extensions/distribute_along_path.inx + extensions/jitternodes.inx + extensions/jessyink_summary.inx + extensions/text_uppercase.inx + extensions/restack.inx + extensions/color_removered.inx + extensions/path_envelope.inx + extensions/webslicer_export.inx + extensions/inset_shadow.inx + extensions/raster_output_jpg.inx + extensions/patternalongpath.inx + extensions/color_morehue.inx + extensions/webslicer_create_group.inx + extensions/print_win32_vector.inx + extensions/wireframe_sphere.inx + extensions/cgm_input.inx + extensions/setup_typography_canvas.inx + extensions/color_custom.inx + extensions/dhw_input.inx + extensions/perfectboundcover.inx + extensions/color_darker.inx + extensions/fig_input.inx + extensions/jessyink_video.inx + extensions/color_grayscale.inx + extensions/jessyink_view.inx + extensions/color_moresaturation.inx + extensions/doc_ai_convert.inx + extensions/raster_output_webp.inx + extensions/lindenmayer.inx + extensions/triangle.inx + extensions/grid_cartesian.inx + extensions/color_removegreen.inx + extensions/jessyink_mouse_handler.inx + extensions/color_brighter.inx + extensions/dxf12_outlines.inx + extensions/addnodes.inx + extensions/text_braille.inx + extensions/docinfo.inx + extensions/text_extract.inx + extensions/synfig_output.inx + extensions/inkscape_follow_link.inx + extensions/path_mesh_p2m.inx + extensions/color_list.inx + extensions/svgcalendar.inx + extensions/jessyink_uninstall.inx + extensions/grid_isometric.inx + extensions/plotter.inx + extensions/raster_output_png.inx + extensions/render_gear_rack.inx + extensions/other/templates/template_shape_prefab.inx + extensions/other/clipart/import_web_image.inx + extensions/other/gcodetools/gcodetools_prepare_path_for_plasma.inx + extensions/other/gcodetools/gcodetools_lathe.inx + extensions/other/gcodetools/gcodetools_dxf_points.inx + extensions/other/gcodetools/gcodetools_area.inx + extensions/other/gcodetools/gcodetools_about.inx + extensions/other/gcodetools/gcodetools_engraving.inx + extensions/other/gcodetools/gcodetools_orientation_points.inx + extensions/other/gcodetools/gcodetools_tools_library.inx + extensions/other/gcodetools/gcodetools_graffiti.inx + extensions/other/gcodetools/gcodetools_path_to_gcode.inx + extensions/other/extension-xaml/inkxaml/svg2xaml.inx + extensions/other/extension-xaml/inkxaml/xaml2svg.inx + extensions/other/inkman/manage_extensions.inx + + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6e620d538e..bbb644a9ec 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -288,6 +288,38 @@ list(APPEND inkscape_SRC ${CMAKE_BINARY_DIR}/src/inkscape-version.cpp ) +# ----------------------------------------------------------------------------- +# Generate resource file +# ----------------------------------------------------------------------------- + +add_custom_command( + OUTPUT ${CMAKE_BINARY_DIR}/include/inkscape-gresources.h + COMMAND glib-compile-resources + ${CMAKE_SOURCE_DIR}/share/inkscape.gresources.xml + --target=${CMAKE_BINARY_DIR}/include/inkscape-gresources.h + --internal + --generate + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/share/ + COMMENT "Generating inkscape-gresources.h") + +add_custom_command( + OUTPUT ${CMAKE_BINARY_DIR}/src/inkscape-gresources.c always-run-gr-source + COMMAND glib-compile-resources + ${CMAKE_SOURCE_DIR}/share/inkscape.gresources.xml + --target=${CMAKE_BINARY_DIR}/src/inkscape-gresources.c + --internal + --generate + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/share/ + COMMENT "Generating inkscape-gresources.c") + +list(APPEND inkscape_SRC + ${CMAKE_BINARY_DIR}/include/inkscape-gresources.h + ${CMAKE_BINARY_DIR}/src/inkscape-gresources.c +) + +add_custom_target(build-gresources + DEPENDS always-run-gr-source +) # ----------------------------------------------------------------------------- # Load in subdirectories diff --git a/src/extension/init.cpp b/src/extension/init.cpp index 9226ced6f4..22c9c252d7 100644 --- a/src/extension/init.cpp +++ b/src/extension/init.cpp @@ -247,10 +247,15 @@ init() load_user_extensions(); load_shared_extensions(); - for(auto &filename: get_filenames(SYSTEM, EXTENSIONS, {SP_MODULE_EXTENSION})) { - build_from_file(filename.c_str()); + // We need to tell it where the inx would have been so it can match py files + auto const resource_root = get_path_string(GRESOURCE, EXTENSIONS); + auto const system_root = get_path_string(SYSTEM, EXTENSIONS); + + for(auto &resource : get_resources(EXTENSIONS, {SP_MODULE_EXTENSION})) { + build_from_resource(resource_root + resource, system_root + resource); } + /* this is at the very end because it has several catch-alls * that are possibly over-ridden by other extensions (such as * svgz) diff --git a/src/extension/system.cpp b/src/extension/system.cpp index e09a46f6dd..025d8efede 100644 --- a/src/extension/system.cpp +++ b/src/extension/system.cpp @@ -459,6 +459,31 @@ build_from_file(gchar const *filename) Inkscape::GC::release(doc); } +/** + * \brief This function creates a module from a filename of an + * XML description. + * \param resource The file holding the XML description of the module. + * \param filename The location the inx *would have had* on the disk. + * + * This function calls build_from_reprdoc with using sp_repr_read_file to create the reprdoc. + */ +void +build_from_resource(std::string const &resource, std::string const &filename) +{ + auto doc = sp_repr_read_resource(resource, INKSCAPE_EXTENSION_URI); + if (!doc) { + g_critical("Inkscape::Extension::build_from_file() - XML description loaded from '%s' not valid.", resource.c_str()); + return; + } + + std::string dir = Glib::path_get_dirname(filename); + auto file_name = Glib::path_get_basename(filename); + if (!build_from_reprdoc(doc, {}, &dir, &file_name)) { + g_warning("Inkscape::Extension::build_from_file() - Could not parse extension from '%s'.", resource.c_str()); + } + Inkscape::GC::release(doc); +} + /** * \brief Create a module from a buffer holding an XML description. * \param buffer The buffer holding the XML description of the module. diff --git a/src/extension/system.h b/src/extension/system.h index 1ded839603..eaabfc0cf8 100644 --- a/src/extension/system.h +++ b/src/extension/system.h @@ -48,6 +48,7 @@ void save(Extension *key, SPDocument *doc, char const *filename, Inkscape::Extension::FileSaveMethod save_method); Print *get_print(char const *key); void build_from_file(char const *filename); +void build_from_resource(std::string const &resource, std::string const &filename); void build_from_mem(char const *buffer, std::unique_ptr in_imp); /** diff --git a/src/io/resource.cpp b/src/io/resource.cpp index 1241b88ac7..a8667abad8 100644 --- a/src/io/resource.cpp +++ b/src/io/resource.cpp @@ -24,6 +24,7 @@ #include +#include #include #include #include @@ -40,6 +41,7 @@ using Inkscape::IO::file_test; namespace Inkscape::IO::Resource { #define INKSCAPE_PROFILE_DIR "inkscape" +#define INKSCAPE_GRESOURCE_PREFIX "/org/inkscape/" /** * @returns Path. Value is in platform-native encoding (see Glib::filename_to_utf8). @@ -80,6 +82,7 @@ gchar *_get_path(Domain domain, Type type, char const *filename, char const *ext case SYSTEM: sysdir = "inkscape"; case SHARED: + case GRESOURCE: case USER: { switch (type) { case ATTRIBUTES: name = "attributes"; break; @@ -105,6 +108,11 @@ gchar *_get_path(Domain domain, Type type, char const *filename, char const *ext } } break; } + + if (domain == GRESOURCE) { + return g_build_path("/", INKSCAPE_GRESOURCE_PREFIX, name, filename, extra, nullptr); + } + // Look for an over-ride in the local environment if (envor && domain == USER) { std::string env_dir = Glib::getenv(envor); @@ -287,6 +295,41 @@ std::vector get_filenames(std::string path, std::vector get_resources(Type type, std::vector const &extensions) +{ + std::vector resources; + std::vector paths = {"/"}; + auto const root = get_path_string(GRESOURCE, type); + + // Recursive lookup + while(!paths.empty()) { + auto resource_path = paths.back(); + auto resource_root = root + resource_path; + paths.pop_back(); + for (auto &resource : Gio::Resource::enumerate_children_global(resource_root.c_str())) { + // If not extensions are specified, don't reject ANY files. + bool reject = !extensions.empty(); + + // Unreject any file which has one of the extensions. + for (auto &ext: extensions) { + reject ^= Glib::str_has_suffix(resource, ext); + } + if (resource.back() == '/') { + paths.emplace_back(resource_path + resource); + } else if(!reject) { + resources.emplace_back(resource_path + resource); + } + } + } + return resources; +} + /* * Gets all folders inside each type, for all domain types. * diff --git a/src/io/resource.h b/src/io/resource.h index 3cea902b15..fee24325dc 100644 --- a/src/io/resource.h +++ b/src/io/resource.h @@ -47,6 +47,7 @@ enum Domain { CREATE, CACHE, SHARED, + GRESOURCE, USER }; @@ -82,6 +83,10 @@ std::vector get_filenames(std::string path, std::vector const &extensions={}, std::vector const &exclusions={}); +[[nodiscard]] +std::vector get_resources(Type type, + std::vector const &extensions = {}); + [[nodiscard]] std::vector get_foldernames(Type type, std::vector const &exclusions = {}); diff --git a/src/ui/builder-utils.cpp b/src/ui/builder-utils.cpp index 21c24a19bd..3e8beb3d40 100644 --- a/src/ui/builder-utils.cpp +++ b/src/ui/builder-utils.cpp @@ -34,10 +34,17 @@ void throw_missing(const char* object_type, const char* id) } // namespace Detail Glib::RefPtr create_builder(const char* filename) { - auto glade = Inkscape::IO::Resource::get_filename(Inkscape::IO::Resource::UIS, filename); + auto glade = IO::Resource::get_path_string(IO::Resource::GRESOURCE, IO::Resource::UIS, filename); Glib::RefPtr builder; + + static bool loaded = false; + if (!loaded) { + g_resources_register(inkscape_get_resource()); + loaded = true; + } + try { - return Gtk::Builder::create_from_file(glade); + return Gtk::Builder::create_from_resource(glade); } catch (Glib::Error& ex) { g_error("Cannot load glade file: %s", ex.what()); diff --git a/src/ui/builder-utils.h b/src/ui/builder-utils.h index 1f6a90cd25..c4fc82a219 100644 --- a/src/ui/builder-utils.h +++ b/src/ui/builder-utils.h @@ -18,6 +18,10 @@ #include #include +extern "C" { +#include "inkscape-gresources.h" +} + namespace Inkscape { namespace UI { diff --git a/src/xml/repr-io.cpp b/src/xml/repr-io.cpp index 7422d6a54a..a81195a74e 100644 --- a/src/xml/repr-io.cpp +++ b/src/xml/repr-io.cpp @@ -37,6 +37,7 @@ #include "preferences.h" +#include #include using Inkscape::IO::Writer; @@ -318,6 +319,19 @@ Document *sp_repr_read_file (const gchar * filename, const gchar *default_ns, bo return rdoc; } +Document *sp_repr_read_resource(std::string const &resource, const gchar *default_ns) +{ + try { + if (auto bytes = Gio::Resource::lookup_data_global(resource)) { + auto size = bytes->get_size(); + return sp_repr_read_mem(reinterpret_cast(bytes->get_data(size)), size, default_ns); + } + } catch (Glib::Error& ex) { + g_warning("Cannot load resource file: %s", ex.what()); + } + return nullptr; +} + /** * Reads and parses XML from a buffer, returning it as an Document */ diff --git a/src/xml/repr.h b/src/xml/repr.h index d118349542..5ed09eca23 100644 --- a/src/xml/repr.h +++ b/src/xml/repr.h @@ -53,6 +53,7 @@ Inkscape::XML::Document *sp_repr_document_new(char const *rootname); /* IO */ Inkscape::XML::Document *sp_repr_read_file(char const *filename, char const *default_ns, bool xinclude = false); +Inkscape::XML::Document *sp_repr_read_resource(std::string const &resource, const gchar *default_ns); Inkscape::XML::Document *sp_repr_read_mem(char const *buffer, int length, char const *default_ns); void sp_repr_write_stream(Inkscape::XML::Node *repr, Inkscape::IO::Writer &out, int indent_level, bool add_whitespace, Glib::QueryQuark elide_prefix, -- GitLab From a54e4e92f688c1d38c03ac572cac5d1abc5b34e3 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Mon, 24 Mar 2025 15:22:55 -0400 Subject: [PATCH 2/2] Knock out all icon loading --- src/inkscape.cpp | 5 +++++ src/io/resource.cpp | 2 +- src/ui/cursor-utils.cpp | 3 --- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/inkscape.cpp b/src/inkscape.cpp index d55d303e0a..d4be2a8d70 100644 --- a/src/inkscape.cpp +++ b/src/inkscape.cpp @@ -240,13 +240,18 @@ Application::Application(bool use_gui) : auto display = Gdk::Display::get_default(); auto icon_theme = Gtk::IconTheme::get_for_display(display); auto search_paths = icon_theme->get_search_path(); + search_paths.clear(); // prepend search paths or else hicolor icons fallback will fail for (auto type : {USER, SHARED, SYSTEM}) { auto path = get_path_string(type, ICONS); if (!path.empty()) { + g_warning(" > '%s'", path.c_str()); search_paths.insert(search_paths.begin(), path); } } + for (auto &path : search_paths) { + g_warning(" < '%s'", path.c_str()); + } icon_theme->set_search_path(search_paths); themecontext = new Inkscape::UI::ThemeContext(); diff --git a/src/io/resource.cpp b/src/io/resource.cpp index a8667abad8..567f21c4d9 100644 --- a/src/io/resource.cpp +++ b/src/io/resource.cpp @@ -92,7 +92,7 @@ gchar *_get_path(Domain domain, Type type, char const *filename, char const *ext case FILTERS: name = "filters"; break; case FONTS: name = "fonts"; break; case FONTCOLLECTIONS: name = "fontcollections"; break; - case ICONS: name = "icons"; break; + case ICONS: name = "others"; break; case KEYS: name = "keys"; break; case MARKERS: name = "markers"; break; case PAINT: name = "paint"; break; diff --git a/src/ui/cursor-utils.cpp b/src/ui/cursor-utils.cpp index b3a8aa9008..f87ee4572a 100644 --- a/src/ui/cursor-utils.cpp +++ b/src/ui/cursor-utils.cpp @@ -40,9 +40,6 @@ #include "util/statics.h" #include "util/units.h" -using Inkscape::IO::Resource::SYSTEM; -using Inkscape::IO::Resource::ICONS; - namespace Inkscape { // SVG cursor unique ID/key -- GitLab