summaryrefslogtreecommitdiffstats
path: root/snap/local
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:24:48 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:24:48 +0000
commitcca66b9ec4e494c1d919bff0f71a820d8afab1fa (patch)
tree146f39ded1c938019e1ed42d30923c2ac9e86789 /snap/local
parentInitial commit. (diff)
downloadinkscape-upstream/1.2.2.tar.xz
inkscape-upstream/1.2.2.zip
Adding upstream version 1.2.2.upstream/1.2.2upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'snap/local')
-rw-r--r--snap/local/filedialog-native.patch385
-rw-r--r--snap/local/glib-spawn-no-close.patch16
-rw-r--r--snap/local/print-inkscape-version.cpp42
-rwxr-xr-xsnap/local/scripts/inkscape-variables30
-rwxr-xr-xsnap/local/scripts/private-fontcache42
5 files changed, 515 insertions, 0 deletions
diff --git a/snap/local/filedialog-native.patch b/snap/local/filedialog-native.patch
new file mode 100644
index 0000000..ce82d92
--- /dev/null
+++ b/snap/local/filedialog-native.patch
@@ -0,0 +1,385 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Taken from: https://gitlab.com/inkscape/inkscape/-/merge_requests/4237
+# And used only for the snap currently.
+diff --git a/src/ui/dialog/filedialogimpl-gtkmm.cpp b/src/ui/dialog/filedialogimpl-gtkmm.cpp
+index c3aba062dd963e72ec775bd9a2e3a753bf08ee0f..19203350bb3bae36e9157e538a0889b4c1de5a78 100644
+--- a/src/ui/dialog/filedialogimpl-gtkmm.cpp
++++ b/src/ui/dialog/filedialogimpl-gtkmm.cpp
+@@ -78,41 +78,26 @@ void fileDialogExtensionToPattern(Glib::ustring &pattern, Glib::ustring &extensi
+ }
+ }
+
++/*#########################################################################
++### F I L E D I A L O G B A S E C L A S S
++#########################################################################*/
+
+-void findEntryWidgets(Gtk::Container *parent, std::vector<Gtk::Entry *> &result)
++// Small function so the translatable strings stay out of the header
++const char * FileDialogBaseGtk::accept_label(Gtk::FileChooserAction dialogType)
+ {
+- if (!parent) {
+- return;
+- }
+- std::vector<Gtk::Widget *> children = parent->get_children();
+- for (auto child : children) {
+- GtkWidget *wid = child->gobj();
+- if (GTK_IS_ENTRY(wid))
+- result.push_back(dynamic_cast<Gtk::Entry *>(child));
+- else if (GTK_IS_CONTAINER(wid))
+- findEntryWidgets(dynamic_cast<Gtk::Container *>(child), result);
++ if (dialogType == Gtk::FILE_CHOOSER_ACTION_OPEN) {
++ return _("_Open");
++ } else {
++ return _("_Save");
+ }
+ }
+
+-void findExpanderWidgets(Gtk::Container *parent, std::vector<Gtk::Expander *> &result)
++// Small function so the translatable strings stay out of the header
++const char * FileDialogBaseGtk::cancel_label()
+ {
+- if (!parent)
+- return;
+- std::vector<Gtk::Widget *> children = parent->get_children();
+- for (auto child : children) {
+- GtkWidget *wid = child->gobj();
+- if (GTK_IS_EXPANDER(wid))
+- result.push_back(dynamic_cast<Gtk::Expander *>(child));
+- else if (GTK_IS_CONTAINER(wid))
+- findExpanderWidgets(dynamic_cast<Gtk::Container *>(child), result);
+- }
++ return _("_Cancel");
+ }
+
+-
+-/*#########################################################################
+-### F I L E D I A L O G B A S E C L A S S
+-#########################################################################*/
+-
+ void FileDialogBaseGtk::internalSetup()
+ {
+ // Open executable file dialogs don't need the preview panel
+@@ -126,11 +111,15 @@ void FileDialogBaseGtk::internalSetup()
+
+ previewCheckbox.signal_toggled().connect(sigc::mem_fun(*this, &FileDialogBaseGtk::_updatePreviewCallback));
+
++ previewCheckbox.show();
++
+ svgexportCheckbox.set_label(Glib::ustring(_("Export as SVG 1.1 per settings in Preferences dialog")));
+ svgexportCheckbox.set_active(enableSVGExport);
+
+ svgexportCheckbox.signal_toggled().connect(sigc::mem_fun(*this, &FileDialogBaseGtk::_svgexportEnabledCB));
+
++ svgexportCheckbox.show();
++
+ // Catch selection-changed events, so we can adjust the text widget
+ signal_update_preview().connect(sigc::mem_fun(*this, &FileDialogBaseGtk::_updatePreviewCallback));
+
+@@ -220,7 +209,7 @@ FileOpenDialogImplGtk::FileOpenDialogImplGtk(Gtk::Window &parentWindow, const Gl
+
+
+ /* Set the pwd and/or the filename */
+- if (dir.size() > 0) {
++ if (dir.size() > 0 && Glib::getenv("GTK_USE_PORTAL").empty()) {
+ Glib::ustring udir(dir);
+ Glib::ustring::size_type len = udir.length();
+ // leaving a trailing backslash on the directory name leads to the infamous
+@@ -241,9 +230,6 @@ FileOpenDialogImplGtk::FileOpenDialogImplGtk(Gtk::Window &parentWindow, const Gl
+ //###### Add the file types menu
+ createFilterMenu();
+
+- add_button(_("_Cancel"), Gtk::RESPONSE_CANCEL);
+- set_default(*add_button(_("_Open"), Gtk::RESPONSE_OK));
+-
+ //###### Allow easy access to our examples folder
+
+ using namespace Inkscape::IO::Resource;
+@@ -372,12 +358,11 @@ void FileOpenDialogImplGtk::createFilterMenu()
+ bool FileOpenDialogImplGtk::show()
+ {
+ set_modal(TRUE); // Window
+- sp_transientize(GTK_WIDGET(gobj())); // Make transient
+ gint b = run(); // Dialog
+ svgPreview.showNoPreview();
+ hide();
+
+- if (b == Gtk::RESPONSE_OK) {
++ if (b == Gtk::RESPONSE_ACCEPT) {
+ // This is a hack, to avoid the warning messages that
+ // Gtk::FileChooser::get_filter() returns
+ // should be: Gtk::FileFilter *filter = get_filter();
+@@ -511,37 +496,18 @@ FileSaveDialogImplGtk::FileSaveDialogImplGtk(Gtk::Window &parentWindow, const Gl
+
+ childBox.pack_start(checksBox);
+ childBox.pack_end(fileTypeComboBox);
++ childBox.show();
++
+ checksBox.pack_start(fileTypeCheckbox);
+ checksBox.pack_start(previewCheckbox);
+ checksBox.pack_start(svgexportCheckbox);
++ checksBox.show();
+
+ set_extra_widget(childBox);
+
+- // Let's do some customization
+- fileNameEntry = nullptr;
+- Gtk::Container *cont = get_toplevel();
+- std::vector<Gtk::Entry *> entries;
+- findEntryWidgets(cont, entries);
+- // g_message("Found %d entry widgets\n", entries.size());
+- if (!entries.empty()) {
+- // Catch when user hits [return] on the text field
+- fileNameEntry = entries[0];
+- fileNameEntry->signal_activate().connect(
+- sigc::mem_fun(*this, &FileSaveDialogImplGtk::fileNameEntryChangedCallback));
+- }
+ signal_selection_changed().connect(
+ sigc::mem_fun(*this, &FileSaveDialogImplGtk::fileNameChanged));
+
+- // Let's do more customization
+- std::vector<Gtk::Expander *> expanders;
+- findExpanderWidgets(cont, expanders);
+- // g_message("Found %d expander widgets\n", expanders.size());
+- if (!expanders.empty()) {
+- // Always show the file list
+- Gtk::Expander *expander = expanders[0];
+- expander->set_expanded(true);
+- }
+-
+ // allow easy access to the user's own templates folder
+ using namespace Inkscape::IO::Resource;
+ char const *templates = Inkscape::IO::Resource::get_path(USER, TEMPLATES);
+@@ -549,14 +515,6 @@ FileSaveDialogImplGtk::FileSaveDialogImplGtk(Gtk::Window &parentWindow, const Gl
+ Inkscape::IO::file_test(templates, G_FILE_TEST_IS_DIR) && g_path_is_absolute(templates)) {
+ add_shortcut_folder(templates);
+ }
+-
+- // if (extension == NULL)
+- // checkbox.set_sensitive(FALSE);
+-
+- add_button(_("_Cancel"), Gtk::RESPONSE_CANCEL);
+- set_default(*add_button(_("_Save"), Gtk::RESPONSE_OK));
+-
+- show_all_children();
+ }
+
+ /**
+@@ -566,44 +524,7 @@ FileSaveDialogImplGtk::~FileSaveDialogImplGtk()
+ = default;
+
+ /**
+- * Callback for fileNameEntry widget
+- */
+-void FileSaveDialogImplGtk::fileNameEntryChangedCallback()
+-{
+- if (!fileNameEntry)
+- return;
+-
+- Glib::ustring fileName = fileNameEntry->get_text();
+- if (!Glib::get_charset()) // If we are not utf8
+- fileName = Glib::filename_to_utf8(fileName);
+-
+- // g_message("User hit return. Text is '%s'\n", fileName.c_str());
+-
+- if (!Glib::path_is_absolute(fileName)) {
+- // try appending to the current path
+- // not this way: fileName = get_current_folder() + "/" + fileName;
+- std::vector<Glib::ustring> pathSegments;
+- pathSegments.emplace_back(get_current_folder());
+- pathSegments.push_back(fileName);
+- fileName = Glib::build_filename(pathSegments);
+- }
+-
+- // g_message("path:'%s'\n", fileName.c_str());
+-
+- if (Glib::file_test(fileName, Glib::FILE_TEST_IS_DIR)) {
+- set_current_folder(fileName);
+- } else if (/*Glib::file_test(fileName, Glib::FILE_TEST_IS_REGULAR)*/ true) {
+- // dialog with either (1) select a regular file or (2) cd to dir
+- // simulate an 'OK'
+- set_filename(fileName);
+- response(Gtk::RESPONSE_OK);
+- }
+-}
+-
+-
+-
+-/**
+- * Callback for fileNameEntry widget
++ * Callback for fileType widget changing
+ */
+ void FileSaveDialogImplGtk::fileTypeChangedCallback()
+ {
+@@ -649,6 +570,10 @@ void FileSaveDialogImplGtk::addFileType(Glib::ustring name, Glib::ustring patter
+ fileTypeComboBox.append(guessType.name);
+ fileTypes.push_back(guessType);
+
++ auto filter = Gtk::FileFilter::create();
++ filter->set_name(guessType.name);
++ filter->add_pattern(guessType.pattern);
++ add_filter(filter);
+
+ fileTypeComboBox.set_active(0);
+ fileTypeChangedCallback(); // call at least once to set the filter
+@@ -656,8 +581,13 @@ void FileSaveDialogImplGtk::addFileType(Glib::ustring name, Glib::ustring patter
+
+ void FileSaveDialogImplGtk::createFilterMenu()
+ {
++ if (_dialogType == CUSTOM_TYPE) {
++ return;
++ }
++
+ Inkscape::Extension::DB::OutputList extension_list;
+ Inkscape::Extension::db.get_output_list(extension_list);
++
+ knownExtensions.clear();
+
+ bool is_raster = _dialogType == RASTER_TYPES;
+@@ -680,6 +610,11 @@ void FileSaveDialogImplGtk::createFilterMenu()
+ type.extension = omod;
+ fileTypeComboBox.append(type.name);
+ fileTypes.push_back(type);
++
++ auto filter = Gtk::FileFilter::create();
++ filter->set_name(type.name);
++ filter->add_pattern(type.pattern);
++ add_filter(filter);
+ }
+
+ //#Let user choose
+@@ -690,6 +625,10 @@ void FileSaveDialogImplGtk::createFilterMenu()
+ fileTypeComboBox.append(guessType.name);
+ fileTypes.push_back(guessType);
+
++ auto filter = Gtk::FileFilter::create();
++ filter->set_name(guessType.name);
++ filter->add_pattern(guessType.pattern);
++ add_filter(filter);
+
+ fileTypeComboBox.set_active(0);
+ fileTypeChangedCallback(); // call at least once to set the filter
+@@ -704,13 +643,12 @@ bool FileSaveDialogImplGtk::show()
+ {
+ change_path(myFilename);
+ set_modal(TRUE); // Window
+- sp_transientize(GTK_WIDGET(gobj())); // Make transient
+ gint b = run(); // Dialog
+ svgPreview.showNoPreview();
+ set_preview_widget_active(false);
+ hide();
+
+- if (b == Gtk::RESPONSE_OK) {
++ if (b == Gtk::RESPONSE_ACCEPT) {
+ updateNameAndExtension();
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+
+@@ -799,6 +737,11 @@ FileSaveDialogImplGtk::change_title(const Glib::ustring& title)
+ */
+ void FileSaveDialogImplGtk::change_path(const Glib::ustring &path)
+ {
++ if (!Glib::getenv("GTK_USE_PORTAL").empty()) {
++ // If we're using the portal we can't control the path
++ return;
++ }
++
+ myFilename = path;
+
+ if (Glib::file_test(myFilename, Glib::FILE_TEST_IS_DIR)) {
+@@ -842,6 +785,27 @@ void FileSaveDialogImplGtk::updateNameAndExtension()
+ myFilename = tmp;
+ }
+
++ if (!Glib::getenv("GTK_USE_PORTAL").empty()) {
++ // If we're using the portal we can't change the filename
++ // and we need to use the filter to find the extension
++ GtkFileChooser *gtkFileChooser = Gtk::FileChooser::gobj();
++ GtkFileFilter *filter = gtk_file_chooser_get_filter(gtkFileChooser);
++
++ extension = nullptr;
++ if (filter) {
++ auto name = gtk_file_filter_get_name(filter);
++
++ for (auto type : fileTypes) {
++ if (type.name == name) {
++ extension = type.extension;
++ break;
++ }
++ }
++ }
++
++ return;
++ }
++
+ Inkscape::Extension::Output *newOut = extension ? dynamic_cast<Inkscape::Extension::Output *>(extension) : nullptr;
+ if (fileTypeCheckbox.get_active() && newOut) {
+ // Append the file extension if it's not already present and display it in the file name entry field
+diff --git a/src/ui/dialog/filedialogimpl-gtkmm.h b/src/ui/dialog/filedialogimpl-gtkmm.h
+index b16d36285c300d1c423e1e75f3260baaf8276b2b..8fde5824ab79f04115441bded47550aebab2ebea 100644
+--- a/src/ui/dialog/filedialogimpl-gtkmm.h
++++ b/src/ui/dialog/filedialogimpl-gtkmm.h
+@@ -49,14 +49,6 @@ void
+ fileDialogExtensionToPattern(Glib::ustring &pattern,
+ Glib::ustring &extension);
+
+-void
+-findEntryWidgets(Gtk::Container *parent,
+- std::vector<Gtk::Entry *> &result);
+-
+-void
+-findExpanderWidgets(Gtk::Container *parent,
+- std::vector<Gtk::Expander *> &result);
+-
+ class FileType
+ {
+ public:
+@@ -75,7 +67,7 @@ class FileType
+ * This class is the base implementation for the others. This
+ * reduces redundancies and bugs.
+ */
+-class FileDialogBaseGtk : public Gtk::FileChooserDialog
++class FileDialogBaseGtk : public Gtk::FileChooserNative
+ {
+ public:
+
+@@ -84,19 +76,7 @@ public:
+ */
+ FileDialogBaseGtk(Gtk::Window& parentWindow, const Glib::ustring &title,
+ Gtk::FileChooserAction dialogType, FileDialogType type, gchar const* preferenceBase) :
+- Gtk::FileChooserDialog(parentWindow, title, dialogType),
+- preferenceBase(preferenceBase ? preferenceBase : "unknown"),
+- _dialogType(type)
+- {
+- internalSetup();
+- }
+-
+- /**
+- *
+- */
+- FileDialogBaseGtk(Gtk::Window& parentWindow, const char *title,
+- Gtk::FileChooserAction dialogType, FileDialogType type, gchar const* preferenceBase) :
+- Gtk::FileChooserDialog(parentWindow, title, dialogType),
++ Gtk::FileChooserNative(title, parentWindow, dialogType, accept_label(dialogType), cancel_label()),
+ preferenceBase(preferenceBase ? preferenceBase : "unknown"),
+ _dialogType(type)
+ {
+@@ -130,6 +110,9 @@ protected:
+ Gtk::CheckButton svgexportCheckbox;
+
+ private:
++ const char * accept_label(Gtk::FileChooserAction dialogType);
++ const char * cancel_label();
++
+ void internalSetup();
+
+ /**
+@@ -281,9 +264,8 @@ private:
+ Inkscape::Extension::Extension *extension;
+
+ /**
+- * Callback for user input into fileNameEntry
++ * Callback for file name changed
+ */
+- void fileNameEntryChangedCallback();
+ void fileNameChanged();
+ bool fromCB;
+ };
diff --git a/snap/local/glib-spawn-no-close.patch b/snap/local/glib-spawn-no-close.patch
new file mode 100644
index 0000000..c17900e
--- /dev/null
+++ b/snap/local/glib-spawn-no-close.patch
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Disable closing file descriptors because the snap confinement has some
+# that it doesn't want us to close
+diff --git a/src/extension/implementation/script.cpp b/src/extension/implementation/script.cpp
+index 0d0a07e4b4..d94774868e 100644
+--- a/src/extension/implementation/script.cpp
++++ b/src/extension/implementation/script.cpp
+@@ -904,7 +904,7 @@ int Script::execute (const std::list<std::string> &in_command,
+ try {
+ Glib::spawn_async_with_pipes(working_directory, // working directory
+ argv, // arg v
+- static_cast<Glib::SpawnFlags>(0), // no flags
++ Glib::SPAWN_LEAVE_DESCRIPTORS_OPEN,
+ sigc::slot<void>(),
+ &_pid, // Pid
+ nullptr, // STDIN
diff --git a/snap/local/print-inkscape-version.cpp b/snap/local/print-inkscape-version.cpp
new file mode 100644
index 0000000..17d0c17
--- /dev/null
+++ b/snap/local/print-inkscape-version.cpp
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+// Use the Inkscape compiled version identifier and print it out with
+// the Snap restrictions on versions. Only a few characters allowed
+// and a limit of 32 characters.
+#include "inkscape-version.h"
+
+#include <iostream>
+#include <cctype>
+
+int main (int argc, char ** argv) {
+ std::string outstr;
+
+ for (const auto& c : std::string{Inkscape::version_string}) {
+ if (outstr.length() == 32) {
+ break;
+ }
+
+ if (std::isalpha(c) || std::isdigit(c)) {
+ outstr.append(1, c);
+ continue;
+ }
+
+ if (c == '(' || c == ')' || c == ',') {
+ continue;
+ }
+
+ if (c == '.' || c == '-') {
+ outstr.append(1, c);
+ continue;
+ }
+
+ outstr.append(1, '-');
+ }
+
+ while (outstr.length() > 0 && !std::isalpha(outstr.back()) && !std::isdigit(outstr.back())) {
+ outstr.pop_back();
+ }
+
+ std::cout << outstr << std::endl;
+
+ return 0;
+}
diff --git a/snap/local/scripts/inkscape-variables b/snap/local/scripts/inkscape-variables
new file mode 100755
index 0000000..1c8d456
--- /dev/null
+++ b/snap/local/scripts/inkscape-variables
@@ -0,0 +1,30 @@
+#!/bin/bash
+# Set all the Inkscape specific environment variables
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+# If we're on an older snapd that doesn't have SNAP_REAL_HOME try
+# to fake it
+if [ -z $SNAP_REAL_HOME ]; then
+SNAP_REAL_HOME=`getent passwd $UID | cut -d ':' -f 6`
+# fallback to pre-1.2 behaviour in case getent doesn't work due to apparmor
+# could suggest to install unscd to proxy requests to blocked nss module
+SNAP_REAL_HOME=${SNAP_REAL_HOME:-${SNAP_USER_DATA}/../../..}
+fi
+
+export INKSCAPE_PROFILE_DIR=${SNAP_REAL_HOME}/.config/inkscape
+export INKSCAPE_LOCALEDIR=${SNAP}/share/locale
+export INKSCAPE_DATADIR=${SNAP}/share
+export INKSCAPE_EXTENSIONS_DIR=${SNAP_USER_COMMON}/extensions/
+
+export GTK_USE_PORTAL=1
+
+export GS_LIB=${SNAP}/usr/share/ghostscript/9.55.0/Resource/Init/
+if [ ! -x ${GS_LIB} ]; then
+ echo "WARN: Ghostscript library not executable: $GS_LIB"
+fi
+
+export PYTHONPATH=/usr/lib/python3.10:/usr/lib/python3.10/lib-dynload:${SNAP}/lib/python3.10/site-packages:${SNAP}/usr/lib/python3/dist-packages
+
+cd $SNAP_REAL_HOME
+
+exec "$@"
diff --git a/snap/local/scripts/private-fontcache b/snap/local/scripts/private-fontcache
new file mode 100755
index 0000000..e85623d
--- /dev/null
+++ b/snap/local/scripts/private-fontcache
@@ -0,0 +1,42 @@
+#!/bin/bash
+# Ensure that we prioritize using the private font cache
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+# ensure_dir_exists calls `mkdir -p` if the given path is not a directory.
+# This speeds up execution time by avoiding unnecessary calls to mkdir.
+#
+# Usage: ensure_dir_exists <path> [<mkdir-options>]...
+function ensure_dir_exists() {
+ [ -d "$1" ] || mkdir -p "$@"
+}
+
+# Set $REALHOME to the users real home directory
+REALHOME=$(getent passwd $UID | cut -d ':' -f 6)
+# fallback to pre-1.2 behaviour in case getent doesn't work due to apparmor
+# could suggest to install unscd to proxy requests to blocked nss module
+REALHOME=${REALHOME:-${SNAP_USER_DATA}/../../..}
+
+# Set config folder to local path
+export XDG_CONFIG_HOME="$SNAP_USER_DATA/.config"
+ensure_dir_exists "$XDG_CONFIG_HOME"
+chmod 700 "$XDG_CONFIG_HOME"
+
+function make_user_fontconfig {
+ echo "<fontconfig>"
+ echo " <dir>$REALHOME/.local/share/fonts</dir>"
+ echo " <dir>$REALHOME/.fonts</dir>"
+ echo " <cachedir prefix=\"xdg\">fontconfig</cachedir>"
+ echo " <cachedir>$SNAP_DATA/fontconfig</cachedir>"
+ echo " <include ignore_missing=\"yes\">/etc/fonts/fonts.conf</include>"
+ if [ ! -z $SNAP_DESKTOP_RUNTIME ]; then
+ echo " <include ignore_missing=\"yes\">${SNAP_DESKTOP_RUNTIME}/etc/fonts/fonts.conf</include>"
+ fi
+ echo "</fontconfig>"
+}
+
+ensure_dir_exists "$XDG_CONFIG_HOME/fontconfig"
+make_user_fontconfig > "$XDG_CONFIG_HOME/fontconfig/fonts.conf"
+
+export FONTCONFIG_FILE=${XDG_CONFIG_HOME}/fontconfig/fonts.conf
+
+exec "$@"