From d69d7c456eb4549e2a258099ae3fe9ee74419ea0 Mon Sep 17 00:00:00 2001 From: Max Gaukler Date: Mon, 9 Dec 2024 12:29:45 +0100 Subject: [PATCH] Fix Linux snap package build (1.4.x) Make the snap build work again for 1.4.x. Rework the patches for the file-open dialog and for launching extensions. Put these into the main code. Add a CMake option to enable/disable the snap-specific patches. (Having a special compile flag for the snap package is quite ugly, however, it is only a temporary workaround for 1.4. The upcoming code for 1.5 doesn't need the special flag anymore.) --- CMakeLists.txt | 1 + CMakeScripts/DefineDependsandFlags.cmake | 4 + snap/hooks/configure | 3 +- snap/local/filedialog-native.patch | 385 ----------------------- snap/local/glib-spawn-no-close.patch | 16 - snap/snapcraft.yaml | 14 +- src/extension/implementation/script.cpp | 10 +- src/ui/dialog/filedialogimpl-gtkmm.cpp | 56 +++- src/ui/dialog/filedialogimpl-gtkmm.h | 18 +- 9 files changed, 92 insertions(+), 415 deletions(-) delete mode 100644 snap/local/filedialog-native.patch delete mode 100644 snap/local/glib-spawn-no-close.patch diff --git a/CMakeLists.txt b/CMakeLists.txt index add81c8145..4badcde1e2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -138,6 +138,7 @@ mark_as_advanced(WITH_MANPAGE_COMPRESSION) option(ENABLE_BINRELOC "Enable relocatable binaries" OFF) +option(LINUX_SNAP_PACKAGE "Compile for use in Linux snap package format" OFF) include(CMakeScripts/DefineDependsandFlags.cmake) # Includes, Compiler Flags, and Link Libraries include(CMakeScripts/HelperMacros.cmake) # Misc Utility Macros diff --git a/CMakeScripts/DefineDependsandFlags.cmake b/CMakeScripts/DefineDependsandFlags.cmake index bad6787576..09f2311d88 100644 --- a/CMakeScripts/DefineDependsandFlags.cmake +++ b/CMakeScripts/DefineDependsandFlags.cmake @@ -250,6 +250,10 @@ else() add_definitions(-UWITH_MESH -UWITH_CSSBLEND -UWITH_SVG2) endif() +if(LINUX_SNAP_PACKAGE) + add_definitions(-DLINUX_SNAP_PACKAGE) +endif() + # ---------------------------------------------------------------------------- # CMake's builtin # ---------------------------------------------------------------------------- diff --git a/snap/hooks/configure b/snap/hooks/configure index c9bdc2651d..ab8d0a9397 100755 --- a/snap/hooks/configure +++ b/snap/hooks/configure @@ -11,4 +11,5 @@ echo "" >> ${SNAP_DATA}/fontconfig/fonts.conf export FONTCONFIG_FILE=${SNAP_DATA}/fontconfig/fonts.conf -exec ${SNAP}/snap/command-chain/snapcraft-runner ${SNAP}/usr/bin/fc-cache --force --system-only --verbose +# disabled because 'snapcraft-runner' does not exist anymore +# exec ${SNAP}/snap/command-chain/snapcraft-runner ${SNAP}/usr/bin/fc-cache --force --system-only --verbose diff --git a/snap/local/filedialog-native.patch b/snap/local/filedialog-native.patch deleted file mode 100644 index ce82d92e07..0000000000 --- a/snap/local/filedialog-native.patch +++ /dev/null @@ -1,385 +0,0 @@ -# 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 &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 children = parent->get_children(); -- for (auto child : children) { -- GtkWidget *wid = child->gobj(); -- if (GTK_IS_ENTRY(wid)) -- result.push_back(dynamic_cast(child)); -- else if (GTK_IS_CONTAINER(wid)) -- findEntryWidgets(dynamic_cast(child), result); -+ if (dialogType == Gtk::FILE_CHOOSER_ACTION_OPEN) { -+ return _("_Open"); -+ } else { -+ return _("_Save"); - } - } - --void findExpanderWidgets(Gtk::Container *parent, std::vector &result) -+// Small function so the translatable strings stay out of the header -+const char * FileDialogBaseGtk::cancel_label() - { -- if (!parent) -- return; -- std::vector children = parent->get_children(); -- for (auto child : children) { -- GtkWidget *wid = child->gobj(); -- if (GTK_IS_EXPANDER(wid)) -- result.push_back(dynamic_cast(child)); -- else if (GTK_IS_CONTAINER(wid)) -- findExpanderWidgets(dynamic_cast(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 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 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 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(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 &result); -- --void --findExpanderWidgets(Gtk::Container *parent, -- std::vector &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 deleted file mode 100644 index c17900e098..0000000000 --- a/snap/local/glib-spawn-no-close.patch +++ /dev/null @@ -1,16 +0,0 @@ -# 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 &in_command, - try { - Glib::spawn_async_with_pipes(working_directory, // working directory - argv, // arg v -- static_cast(0), // no flags -+ Glib::SPAWN_LEAVE_DESCRIPTORS_OPEN, - sigc::slot(), - &_pid, // Pid - nullptr, // STDIN diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 4ce8226f8d..cafbc0b022 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -25,14 +25,17 @@ slots: bus: session name: org.inkscape.Inkscape -assumes: [ command-chain ] +# commented out to work around https://github.com/canonical/snapcraft/issues/4931 +# assumes: [ command-chain ] parts: inkscape: plugin: cmake source: . + source-type: local cmake-parameters: - '-DCMAKE_INSTALL_PREFIX=' + - '-DLINUX_SNAP_PACKAGE=1' build-packages: - build-essential - cmake @@ -108,8 +111,6 @@ parts: - -*canberra*so* # We don't have sound permissions anyway - -usr/lib/*/gtk-2.0 override-build: | - patch -p1 --batch --directory=$SNAPCRAFT_PART_SRC --input=$SNAPCRAFT_PART_SRC/snap/local/filedialog-native.patch - patch -p1 --batch --directory=$SNAPCRAFT_PART_SRC --input=$SNAPCRAFT_PART_SRC/snap/local/glib-spawn-no-close.patch sed -i.bak -e 's|Icon=${INKSCAPE_ICONPATH}|Icon=${SNAP}/share/inkscape/branding/inkscape.svg|g' $SNAPCRAFT_PART_SRC/org.inkscape.Inkscape.desktop.template snapcraftctl build INKSCAPE_VERSION=`g++ -I${SNAPCRAFT_PART_SRC}/src ${SNAPCRAFT_PART_BUILD}/src/inkscape-version.cpp ${SNAPCRAFT_PROJECT_DIR}/snap/local/print-inkscape-version.cpp -o print-inkscape-version && ./print-inkscape-version` @@ -136,6 +137,12 @@ parts: - packaging - scour - virtualenv + - tinycss2 + - lxml + - numpy + - packaging + - pyparsing + - cssselect stage-packages: - optipng - pstoedit @@ -145,6 +152,7 @@ parts: source: snap/local/scripts desktop-helpers: source: https://github.com/ubuntu/snapcraft-desktop-helpers.git + source-type: git source-subdir: gtk plugin: make make-parameters: ["FLAVOR=gtk3"] diff --git a/src/extension/implementation/script.cpp b/src/extension/implementation/script.cpp index c34c766609..8ca6be88e9 100644 --- a/src/extension/implementation/script.cpp +++ b/src/extension/implementation/script.cpp @@ -759,11 +759,17 @@ int Script::execute (const std::list &in_command, //for(int i=0;i(0), // no flags + spawn_flags, // spawn flags sigc::slot(), &_pid, // Pid nullptr, // STDIN diff --git a/src/ui/dialog/filedialogimpl-gtkmm.cpp b/src/ui/dialog/filedialogimpl-gtkmm.cpp index 29af08b49f..1327b7b8d2 100644 --- a/src/ui/dialog/filedialogimpl-gtkmm.cpp +++ b/src/ui/dialog/filedialogimpl-gtkmm.cpp @@ -47,7 +47,12 @@ FileDialogBaseGtk::FileDialogBaseGtk(Gtk::Window &parentWindow, Glib::ustring co Gtk::FileChooserAction const dialogType, FileDialogType const type, char const * const preferenceBase) +#ifdef LINUX_SNAP_PACKAGE + // the snap package uses the native file dialog (which is then redirected via XDG desktop portal) + : Gtk::FileChooserNative(title, parentWindow, dialogType, accept_label(dialogType), cancel_label()) +#else : Gtk::FileChooserDialog{parentWindow, title, dialogType} +#endif , _preferenceBase{preferenceBase ? preferenceBase : "unknown"} , _dialogType(type) { @@ -89,6 +94,24 @@ Glib::ustring FileDialogBaseGtk::extToPattern(const Glib::ustring &extension) co return pattern; } +#ifdef LINUX_SNAP_PACKAGE +// Small function so the translatable strings stay out of the header +const char * FileDialogBaseGtk::accept_label(Gtk::FileChooserAction dialogType) + { + if (dialogType == Gtk::FILE_CHOOSER_ACTION_OPEN) { + return _("_Open"); + } else { + return _("_Save"); + } +} + +// Small function so the translatable strings stay out of the header +const char * FileDialogBaseGtk::cancel_label() +{ + return _("_Cancel"); +} +#endif + /*######################################################################### ### F I L E O P E N #########################################################################*/ @@ -114,7 +137,7 @@ FileOpenDialogImplGtk::FileOpenDialogImplGtk(Gtk::Window &parentWindow, const st _dialogType = fileTypes; /* Set the pwd and/or the filename */ - if (dir.size() > 0) { + if (dir.size() > 0 && Glib::getenv("GTK_USE_PORTAL").empty()) { std::string udir(dir); std::string::size_type len = udir.length(); // leaving a trailing backslash on the directory name leads to the infamous @@ -136,10 +159,11 @@ FileOpenDialogImplGtk::FileOpenDialogImplGtk(Gtk::Window &parentWindow, const st // Add the file types menu. createFilterMenu(); +#ifndef LINUX_SNAP_PACKAGE add_button(_("_Cancel"), Gtk::RESPONSE_CANCEL); add_button(_("_Open"), Gtk::RESPONSE_OK); set_default_response(Gtk::RESPONSE_OK); - +#endif // Allow easy access to our examples folder. using namespace Inkscape::IO::Resource; auto examplesdir = get_path_string(SYSTEM, EXAMPLES); @@ -258,10 +282,17 @@ void FileOpenDialogImplGtk::createFilterMenu() bool FileOpenDialogImplGtk::show() { set_modal(true); // Window + +#ifdef LINUX_SNAP_PACKAGE + int response = run(); // Dialog + const int response_ok = Gtk::RESPONSE_ACCEPT; +#else sp_transientize(GTK_WIDGET(gobj())); // Make transient int response = dialog_run(*this); // Dialog + const int response_ok = Gtk::RESPONSE_OK; +#endif - if (response == Gtk::RESPONSE_OK) { + if (response == response_ok) { setExtension(filterExtensionMap[get_filter()]); return true; } @@ -332,16 +363,19 @@ FileSaveDialogImplGtk::FileSaveDialogImplGtk(Gtk::Window &parentWindow, const st add_shortcut_folder(templates); } - // ===== Buttons ===== + // ===== Buttons ===== +#ifndef LINUX_SNAP_PACKAGE add_button(_("_Cancel"), Gtk::RESPONSE_CANCEL); add_button(_("_Save"), Gtk::RESPONSE_OK); set_default_response(Gtk::RESPONSE_OK); +#endif + // ===== Initial Value ===== // Set the directory or filename. Do this last, after dialog is completely set up. - if (dir.size() > 0) { + if (dir.size() > 0 && Glib::getenv("GTK_USE_PORTAL").empty()) { std::string udir(dir); std::string::size_type len = udir.length(); // Leaving a trailing backslash on the directory name leads to the infamous @@ -370,7 +404,9 @@ FileSaveDialogImplGtk::FileSaveDialogImplGtk(Gtk::Window &parentWindow, const st std::cerr << "FileDialogImplGtk: Unknown file type: " << (int)type << std::endl; } } +#ifndef LINUX_SNAP_PACKAGE show_all_children(); +#endif property_filter().signal_changed().connect([this]() { filefilterChanged(); }); signal_selection_changed().connect([this]() { filenameChanged(); }); @@ -382,11 +418,17 @@ FileSaveDialogImplGtk::FileSaveDialogImplGtk(Gtk::Window &parentWindow, const st bool FileSaveDialogImplGtk::show() { set_modal(true); // Window - sp_transientize(GTK_WIDGET(gobj())); // Make transient + #ifdef LINUX_SNAP_PACKAGE + int response = run(); + const int response_ok = Gtk::RESPONSE_ACCEPT; + #else + sp_transientize(GTK_WIDGET(gobj())); // Make transient int response = dialog_run(*this); // Dialog + const int response_ok = Gtk::RESPONSE_OK; + #endif - if (response == Gtk::RESPONSE_OK) { + if (response == response_ok) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); diff --git a/src/ui/dialog/filedialogimpl-gtkmm.h b/src/ui/dialog/filedialogimpl-gtkmm.h index 713fd31f2d..72ae481847 100644 --- a/src/ui/dialog/filedialogimpl-gtkmm.h +++ b/src/ui/dialog/filedialogimpl-gtkmm.h @@ -22,7 +22,13 @@ #include #include #include + +#ifdef LINUX_SNAP_PACKAGE +// the snap package uses the native file dialog (which is then redirected via XDG desktop portal) +#include +#else #include +#endif #include "filedialog.h" #include "ui/dialog/svg-preview.h" @@ -53,7 +59,12 @@ namespace Dialog { * This class is the base implementation for the others. This * reduces redundancies and bugs. */ -class FileDialogBaseGtk : public Gtk::FileChooserDialog +class FileDialogBaseGtk : +#ifdef LINUX_SNAP_PACKAGE + public Gtk::FileChooserNative +#else + public Gtk::FileChooserDialog +#endif { public: FileDialogBaseGtk(Gtk::Window &parentWindow, Glib::ustring const &title, @@ -69,6 +80,11 @@ public: Glib::ustring extToPattern(const Glib::ustring &extension) const; +private: +#ifdef LINUX_SNAP_PACKAGE + const char * accept_label(Gtk::FileChooserAction dialogType); + const char * cancel_label(); +#endif protected: Glib::ustring const _preferenceBase; -- GitLab