From e4db3b9ca3b884871cba2cb18584775aaa140d2e Mon Sep 17 00:00:00 2001 From: Stef Tervelde Date: Wed, 19 Nov 2025 15:13:50 +0100 Subject: [PATCH 1/6] Decoupling sketchbook --- app/build.gradle.kts | 2 +- .../main/resources}/languages/PDE.properties | 0 .../resources}/languages/PDE_ar.properties | 0 .../resources}/languages/PDE_ca.properties | 0 .../resources}/languages/PDE_de.properties | 0 .../resources}/languages/PDE_el.properties | 0 .../resources}/languages/PDE_en.properties | 0 .../resources}/languages/PDE_es.properties | 0 .../resources}/languages/PDE_fr.properties | 0 .../resources}/languages/PDE_it.properties | 0 .../resources}/languages/PDE_ja.properties | 0 .../resources}/languages/PDE_ko.properties | 0 .../resources}/languages/PDE_nl.properties | 0 .../resources}/languages/PDE_pt.properties | 0 .../resources}/languages/PDE_ru.properties | 0 .../resources}/languages/PDE_tr.properties | 0 .../resources}/languages/PDE_uk.properties | 0 .../resources}/languages/PDE_zh-CN.properties | 0 .../resources}/languages/PDE_zh-TW.properties | 0 app/src/processing/app/Base.java | 35 +- app/src/processing/app/Language.java | 69 ++-- app/src/processing/app/Platform.java | 23 +- app/src/processing/app/Preferences.java | 26 +- app/test/processing/app/SketchbookTest.kt | 23 ++ build/shared/lib/defaults.txt | 313 ------------------ 25 files changed, 115 insertions(+), 376 deletions(-) rename {build/shared/lib => app/src/main/resources}/languages/PDE.properties (100%) rename {build/shared/lib => app/src/main/resources}/languages/PDE_ar.properties (100%) rename {build/shared/lib => app/src/main/resources}/languages/PDE_ca.properties (100%) rename {build/shared/lib => app/src/main/resources}/languages/PDE_de.properties (100%) rename {build/shared/lib => app/src/main/resources}/languages/PDE_el.properties (100%) rename {build/shared/lib => app/src/main/resources}/languages/PDE_en.properties (100%) rename {build/shared/lib => app/src/main/resources}/languages/PDE_es.properties (100%) rename {build/shared/lib => app/src/main/resources}/languages/PDE_fr.properties (100%) rename {build/shared/lib => app/src/main/resources}/languages/PDE_it.properties (100%) rename {build/shared/lib => app/src/main/resources}/languages/PDE_ja.properties (100%) rename {build/shared/lib => app/src/main/resources}/languages/PDE_ko.properties (100%) rename {build/shared/lib => app/src/main/resources}/languages/PDE_nl.properties (100%) rename {build/shared/lib => app/src/main/resources}/languages/PDE_pt.properties (100%) rename {build/shared/lib => app/src/main/resources}/languages/PDE_ru.properties (100%) rename {build/shared/lib => app/src/main/resources}/languages/PDE_tr.properties (100%) rename {build/shared/lib => app/src/main/resources}/languages/PDE_uk.properties (100%) rename {build/shared/lib => app/src/main/resources}/languages/PDE_zh-CN.properties (100%) rename {build/shared/lib => app/src/main/resources}/languages/PDE_zh-TW.properties (100%) create mode 100644 app/test/processing/app/SketchbookTest.kt delete mode 100644 build/shared/lib/defaults.txt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 0d3fcbd12d..c3edf54b23 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -35,7 +35,7 @@ sourceSets{ srcDirs("src") } resources{ - srcDirs("resources", listOf("languages", "fonts", "theme").map { "../build/shared/lib/$it" }) + srcDirs("resources", listOf("fonts", "theme").map { "../build/shared/lib/$it" }) } } test{ diff --git a/build/shared/lib/languages/PDE.properties b/app/src/main/resources/languages/PDE.properties similarity index 100% rename from build/shared/lib/languages/PDE.properties rename to app/src/main/resources/languages/PDE.properties diff --git a/build/shared/lib/languages/PDE_ar.properties b/app/src/main/resources/languages/PDE_ar.properties similarity index 100% rename from build/shared/lib/languages/PDE_ar.properties rename to app/src/main/resources/languages/PDE_ar.properties diff --git a/build/shared/lib/languages/PDE_ca.properties b/app/src/main/resources/languages/PDE_ca.properties similarity index 100% rename from build/shared/lib/languages/PDE_ca.properties rename to app/src/main/resources/languages/PDE_ca.properties diff --git a/build/shared/lib/languages/PDE_de.properties b/app/src/main/resources/languages/PDE_de.properties similarity index 100% rename from build/shared/lib/languages/PDE_de.properties rename to app/src/main/resources/languages/PDE_de.properties diff --git a/build/shared/lib/languages/PDE_el.properties b/app/src/main/resources/languages/PDE_el.properties similarity index 100% rename from build/shared/lib/languages/PDE_el.properties rename to app/src/main/resources/languages/PDE_el.properties diff --git a/build/shared/lib/languages/PDE_en.properties b/app/src/main/resources/languages/PDE_en.properties similarity index 100% rename from build/shared/lib/languages/PDE_en.properties rename to app/src/main/resources/languages/PDE_en.properties diff --git a/build/shared/lib/languages/PDE_es.properties b/app/src/main/resources/languages/PDE_es.properties similarity index 100% rename from build/shared/lib/languages/PDE_es.properties rename to app/src/main/resources/languages/PDE_es.properties diff --git a/build/shared/lib/languages/PDE_fr.properties b/app/src/main/resources/languages/PDE_fr.properties similarity index 100% rename from build/shared/lib/languages/PDE_fr.properties rename to app/src/main/resources/languages/PDE_fr.properties diff --git a/build/shared/lib/languages/PDE_it.properties b/app/src/main/resources/languages/PDE_it.properties similarity index 100% rename from build/shared/lib/languages/PDE_it.properties rename to app/src/main/resources/languages/PDE_it.properties diff --git a/build/shared/lib/languages/PDE_ja.properties b/app/src/main/resources/languages/PDE_ja.properties similarity index 100% rename from build/shared/lib/languages/PDE_ja.properties rename to app/src/main/resources/languages/PDE_ja.properties diff --git a/build/shared/lib/languages/PDE_ko.properties b/app/src/main/resources/languages/PDE_ko.properties similarity index 100% rename from build/shared/lib/languages/PDE_ko.properties rename to app/src/main/resources/languages/PDE_ko.properties diff --git a/build/shared/lib/languages/PDE_nl.properties b/app/src/main/resources/languages/PDE_nl.properties similarity index 100% rename from build/shared/lib/languages/PDE_nl.properties rename to app/src/main/resources/languages/PDE_nl.properties diff --git a/build/shared/lib/languages/PDE_pt.properties b/app/src/main/resources/languages/PDE_pt.properties similarity index 100% rename from build/shared/lib/languages/PDE_pt.properties rename to app/src/main/resources/languages/PDE_pt.properties diff --git a/build/shared/lib/languages/PDE_ru.properties b/app/src/main/resources/languages/PDE_ru.properties similarity index 100% rename from build/shared/lib/languages/PDE_ru.properties rename to app/src/main/resources/languages/PDE_ru.properties diff --git a/build/shared/lib/languages/PDE_tr.properties b/app/src/main/resources/languages/PDE_tr.properties similarity index 100% rename from build/shared/lib/languages/PDE_tr.properties rename to app/src/main/resources/languages/PDE_tr.properties diff --git a/build/shared/lib/languages/PDE_uk.properties b/app/src/main/resources/languages/PDE_uk.properties similarity index 100% rename from build/shared/lib/languages/PDE_uk.properties rename to app/src/main/resources/languages/PDE_uk.properties diff --git a/build/shared/lib/languages/PDE_zh-CN.properties b/app/src/main/resources/languages/PDE_zh-CN.properties similarity index 100% rename from build/shared/lib/languages/PDE_zh-CN.properties rename to app/src/main/resources/languages/PDE_zh-CN.properties diff --git a/build/shared/lib/languages/PDE_zh-TW.properties b/app/src/main/resources/languages/PDE_zh-TW.properties similarity index 100% rename from build/shared/lib/languages/PDE_zh-TW.properties rename to app/src/main/resources/languages/PDE_zh-TW.properties diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 41370918ba..ec237d0efc 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -23,27 +23,30 @@ package processing.app; -import java.awt.*; -import java.awt.event.ActionListener; -import java.io.*; -import java.lang.reflect.InvocationTargetException; -import java.util.*; -import java.util.List; -import java.util.Map.Entry; - -import javax.swing.*; -import javax.swing.tree.DefaultMutableTreeNode; - import com.formdev.flatlaf.FlatDarkLaf; import com.formdev.flatlaf.FlatLaf; import com.formdev.flatlaf.FlatLightLaf; +import org.jetbrains.annotations.NotNull; import processing.app.contrib.*; import processing.app.tools.Tool; import processing.app.ui.*; import processing.app.ui.Toolkit; -import processing.core.*; +import processing.core.PApplet; import processing.data.StringList; +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import java.awt.*; +import java.awt.event.ActionListener; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; +import java.util.*; +import java.util.List; +import java.util.Map.Entry; + /** * The base class for the main processing application. * Primary role of this class is for platform identification and @@ -2263,6 +2266,10 @@ static public void locateSketchbookFolder() { // If a value is at least set, first check to see if the folder exists. // If it doesn't, warn the user that the sketchbook folder is being reset. String sketchbookPath = Preferences.getSketchbookPath(); + var sketchbookPathOverride = System.getProperty("processing.sketchbook.folder"); + if (sketchbookPathOverride != null && !sketchbookPathOverride.isEmpty()) { + sketchbookPath = sketchbookPathOverride; + } if (sketchbookPath != null) { sketchbookFolder = new File(sketchbookPath); if (!sketchbookFolder.exists()) { @@ -2325,6 +2332,9 @@ static protected void makeSketchbookSubfolders() { static public File getSketchbookFolder() { + if (sketchbookFolder == null) { + locateSketchbookFolder(); + } return sketchbookFolder; } @@ -2354,6 +2364,7 @@ static public File getSketchbookTemplatesFolder() { } + @NotNull static protected File getDefaultSketchbookFolder() { File sketchbookFolder = null; try { diff --git a/app/src/processing/app/Language.java b/app/src/processing/app/Language.java index d55c8b710c..fa893b0c72 100644 --- a/app/src/processing/app/Language.java +++ b/app/src/processing/app/Language.java @@ -21,12 +21,17 @@ package processing.app; -import java.io.*; -import java.util.*; - import processing.core.PApplet; import processing.data.StringList; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.MissingResourceException; + /** * Internationalization (I18N) and Localization (L10N) @@ -110,25 +115,17 @@ private Language() { static private String[] listSupported() { StringList supported = new StringList(); - try { - File baseFolder = Base.getLibFile("languages"); - String[] names = baseFolder.list(); - if (names != null) { - for (String filename : names) { - if (filename.startsWith("PDE_") && filename.endsWith(".properties")) { - int dotIndex = filename.lastIndexOf(".properties"); - String language = filename.substring(4, dotIndex); - supported.append(language); + var locales = Locale.getAvailableLocales(); + var loader = Language.class.getClassLoader(); + for (var locale : locales) { + var language = locale.toLanguageTag(); + var baseFilename = "languages/PDE_" + language + ".properties"; + var file = loader.getResource(baseFilename); + if (file == null) { + continue; } - } - } else { - throw new IOException("Could not read list of files inside " + baseFolder); + supported.append(language); } - } catch (IOException e) { - Messages.showError("Translation Trouble", - "There was a problem reading the language translations folder.\n" + - "You may need to reinstall, or report if the problem persists.", e); - } return supported.toArray(); } @@ -358,10 +355,12 @@ static class LanguageBundle { // language files in the download (i.e. still would not help // with adding new language codes.) - String baseFilename = "languages/PDE.properties"; - String langFilename = "languages/PDE_" + language + ".properties"; + var loader = Language.class.getClassLoader(); - File baseFile = Base.getLibFile(baseFilename); + String baseFilename = "languages/PDE.properties"; + String langFilename = "languages/PDE_" + language + ".properties"; + + var baseFile = loader.getResourceAsStream(baseFilename); /* // Also check to see if the user is working on localization, // and has their own .properties files in their sketchbook. @@ -372,7 +371,7 @@ static class LanguageBundle { } */ - File langFile = Base.getLibFile(langFilename); + var langFile = loader.getResourceAsStream(langFilename); /* File userLangFile = new File(Base.getSketchbookFolder(), langFilename); if (userLangFile.exists()) { @@ -384,11 +383,25 @@ static class LanguageBundle { read(langFile); } - void read(File additions) { - read(additions, false); - } + void read(File additions, boolean enforcePrefix) { + try { + InputStream in = PApplet.createInput(additions); + if (in != null) { + read(in, enforcePrefix); + in.close(); + } else { + System.err.println("Unable to read " + additions); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + void read(InputStream additions) { + read(additions, false); + } - void read(File additions, boolean enforcePrefix) { + void read(InputStream additions, boolean enforcePrefix) { String prefix = null; String[] lines = PApplet.loadStrings(additions); diff --git a/app/src/processing/app/Platform.java b/app/src/processing/app/Platform.java index 2c2ade5e12..ed76318b98 100644 --- a/app/src/processing/app/Platform.java +++ b/app/src/processing/app/Platform.java @@ -23,20 +23,22 @@ package processing.app; -import java.io.File; -import java.io.IOException; -import java.lang.management.ManagementFactory; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.*; - import com.sun.jna.platform.FileUtils; - import processing.app.platform.DefaultPlatform; import processing.core.PApplet; import processing.core.PConstants; import processing.data.StringDict; +import java.io.File; +import java.io.IOException; +import java.lang.management.ManagementFactory; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + public class Platform { static DefaultPlatform inst; @@ -83,8 +85,11 @@ static public boolean isAvailable() { return inst != null; } + static { + init(); + } - static public void init() { + static public void init() { try { // Start with DefaultPlatform, but try to upgrade to a known platform final String packageName = DefaultPlatform.class.getPackageName(); diff --git a/app/src/processing/app/Preferences.java b/app/src/processing/app/Preferences.java index 640c77eade..dc43f0826b 100644 --- a/app/src/processing/app/Preferences.java +++ b/app/src/processing/app/Preferences.java @@ -21,14 +21,14 @@ package processing.app; -import java.awt.Color; -import java.awt.Font; -import java.awt.SystemColor; -import java.io.*; -import java.util.*; - import processing.app.ui.Toolkit; -import processing.core.*; +import processing.core.PApplet; +import processing.core.PConstants; + +import java.awt.*; +import java.io.*; +import java.util.HashMap; +import java.util.Map; /** @@ -65,9 +65,11 @@ static public void init() { // start by loading the defaults, in case something // important was deleted from the user prefs try { - // Name changed for 2.1b2 to avoid problems with users modifying or - // replacing the file after doing a search for "preferences.txt". - load(Base.getLibStream(DEFAULTS_FILE)); + var defaultsStream = Preferences + .class + .getClassLoader() + .getResourceAsStream(DEFAULTS_FILE); + load(defaultsStream); } catch (Exception e) { Messages.showError(null, "Could not read default settings.\n" + "You'll need to reinstall Processing.", e); @@ -273,9 +275,7 @@ static public void save() { static public String get(String attribute /*, String defaultValue */) { if (!initialized) { - throw new RuntimeException( - "Tried reading preferences prior to initialization." - ); + init(); } return table.get(attribute); } diff --git a/app/test/processing/app/SketchbookTest.kt b/app/test/processing/app/SketchbookTest.kt new file mode 100644 index 0000000000..3d0c387cb0 --- /dev/null +++ b/app/test/processing/app/SketchbookTest.kt @@ -0,0 +1,23 @@ +package processing.app + +import kotlin.io.path.createTempDirectory +import kotlin.test.Test + +class SketchbookTest { + @Test + fun sketchbookTest() { + val result = Base.getSketchbookFolder() + assert(result != null) + } + + @Test + fun sketchbookIsOverridableTest() { + val directory = createTempDirectory("scaffolding") + val sketchbook = directory.resolve("sketchbook") + sketchbook.toFile().mkdirs() + System.setProperty("processing.sketchbook.folder", sketchbook.toAbsolutePath().toString()) + + val result = Base.getSketchbookFolder() + assert(result.absolutePath == sketchbook.toAbsolutePath().toString()) + } +} \ No newline at end of file diff --git a/build/shared/lib/defaults.txt b/build/shared/lib/defaults.txt deleted file mode 100644 index 1cfc190ca9..0000000000 --- a/build/shared/lib/defaults.txt +++ /dev/null @@ -1,313 +0,0 @@ -# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - -# DO NOT MAKE CHANGES TO THIS FILE!!! - -# These are the default preferences. If you want to modify -# them directly, use the per-user local version of the file: - -# Users -> [username] -> AppData -> Roaming -> -# Processing -> preferences.txt (on Windows 10) - -# ~/Library -> Processing -> preferences.txt (on macOS) - -# ~/.config/processing -> preferences.txt (on Linux) - -# The exact location of your preferences file can be found at -# the bottom of the Preferences window inside Processing. - -# Because AppData and Application Data may be considered -# hidden or system folders on Windows, you'll have to ensure -# that they're visible in order to get at preferences.txt - -# You'll have problems running Processing if you incorrectly -# modify lines in this file. It will probably not start at all. - -# AGAIN, DO NOT ALTER THIS FILE! I'M ONLY YELLING BECAUSE I LOVE YOU! - - -# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - -# If you don't want users to have their sketchbook default to -# "My Documents/Processing" on Windows and "Documents/Processing" on OS X, -# set this to another path that will be used by default. -# Note that this path must exist already otherwise it won't see -# the sketchbook folder, and will instead assume the sketchbook -# has gone missing, and that it should instead use the default. -# In 4.0, the location has changed. -#sketchbook.path.four= - -# Whether or not to show the Welcome screen for 4.0 -# (It's always available under Help → Welcome) -welcome.four.show = true -welcome.four.seen = false - -# Set 'true' for the default behavior before 4.0, where the -# main tab must have the same name as the sketch folder -editor.sync_folder_and_filename = true - -# By default, contributions are moved to backup folders when -# they are removed or replaced. The backups can be found at -# sketchbook/libraries/old, sketchbook/tools/old, and sketchbook/modes/old - -# true to backup contributions when "Remove" button is pressed -contribution.backup.on_remove = true -# true to backup contributions when installing a newer version -contribution.backup.on_install = true - -recent.count = 10 - -# Default to the native (AWT) file selector where possible -chooser.files.native = true -# We were shutting this off on macOS because it broke Copy/Paste: -# https://github.com/processing/processing/issues/1035 -# But removing again for 4.0 alpha 5, because the JFileChooser is awful, -# and worse on Big Sur, so a bigger problem than the Copy/Paste issue. -# https://github.com/processing/processing4/issues/77 -#chooser.files.native.macos = false - -# set to 'lab' to interpolate theme gradients using L*a*b* color space -theme.gradient.method = rgb - - -# by default, check the processing server for any updates -# (please avoid disabling, this also helps us know basic numbers -# on how many people are using Processing) -update.check = true - -# default value for beta_welcome -# -1 means no beta has been run -update.beta_welcome = -1 - -# on windows, automatically associate .pde files with processing.exe -platform.auto_file_type_associations = true - - -# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - -# default size for the main window -editor.window.width.default = 700 -editor.window.height.default = 600 - -editor.window.width.min = 400 -editor.window.height.min = 500 -# tested as approx 440 on OS X -editor.window.height.min.macos = 450 -# tested to be 515 on Windows XP, this leaves some room -editor.window.height.min.windows = 530 -# tested with Raspberry Pi display -editor.window.height.min.linux = 480 - -# scaling for the interface (to handle Windows and Linux HiDPI displays) -editor.zoom = 100% -# automatically set based on system dpi (only helps on Windows) -editor.zoom.auto = true - -# Use the default monospace font included in lib/fonts. -# (As of Processing 4 alpha 5, that's Source Code Pro) -editor.font.family = processing.mono -editor.font.size = 12 - -# To reset everyone's default, replaced editor.antialias with editor.smooth -# for 2.1. Fonts are unusably gross on OS X (and Linux) w/o smoothing and -# the Oracle JVM, and many longtime users have anti-aliasing turned off. -editor.smooth = true - -# blink the caret by default -editor.caret.blink = true -# change to true to use a block (instead of a bar) -editor.caret.block = false - -# enable ctrl-ins, shift-ins, shift-delete for cut/copy/paste -# on windows and linux, but disable on the mac -editor.keys.alternative_cut_copy_paste = true -editor.keys.alternative_cut_copy_paste.macos = false - -# true if shift-backspace sends the delete character, -# false if shift-backspace just means backspace -editor.keys.shift_backspace_is_delete = false - -# home and end keys should only travel to the start/end of the current line -editor.keys.home_and_end_travel_far = false -# home and end keys move to the first/last non-whitespace character, -# and move to the actual start/end when pressed a second time. -# Only works if editor.keys.home_and_end_travel_far is false. -editor.keys.home_and_end_travel_smart = true -# The OS X HI Guidelines say that home/end are relative to the document, -# but that drives some people nuts. This pref enables/disables it. -editor.keys.home_and_end_travel_far.macos = true - -# Enable/disable support for complex scripts. Used for Japanese and others, -# but disable when not needed, otherwise basic Western European chars break. -editor.input_method_support = false - -# convert tabs to spaces? how many spaces? -editor.tabs.expand = true -editor.tabs.size = 2 - -# Set to true to automatically close [ { ( " and ' -editor.completion.auto_close = false - -# automatically indent each line -editor.indent = true - -# Whether to check files to see if they've been modified externally -editor.watcher = true -# Set true to enable debugging, since this is quirky on others' machines -editor.watcher.debug = false -# The window of time (in milliseconds) in which a change won't be counted -editor.watcher.window = 1500 - -# Format and search engine to use for online queries -search.format = https://google.com/search?q=%s - -# font choice and size for the console -console.font.size = 12 - -# number of lines to show by default -console.lines = 4 - -# Number of blank lines to advance/clear console. -# Note that those lines are also printed in the terminal when -# Processing is executed there. -# Setting to 0 stops this behavior. -console.head_padding = 10 - -# Set to false to disable automatically clearing the console -# each time 'run' is hit -# If one sets it to false, one may also want to set 'console.head_padding' -# to a positive number to separate outputs from different runs. -console.auto_clear = true - -# number of days of history to keep around before cleaning -# setting to 0 will never clean files -console.temp.days = 7 - -# set the maximum number of lines remembered by the console -# the default is 500, lengthen at your own peril -console.scrollback.lines = 500 -console.scrollback.chars = 40000 - -# Any additional Java options when running. -# If you change this and can't run things, it's your own durn fault. -run.options = - -# settings for the -XmsNNNm and -XmxNNNm command line option -run.options.memory = false -run.options.memory.initial = 64 -run.options.memory.maximum = 512 - -# Index of the display to use for running sketches (starts at 1). -# Kept this 1-indexed because older vesions of Processing were setting -# the preference even before it was being used. -# -1 means the default display, 0 means all displays -run.display = -1 - -# set internally because it comes from the system -#run.window.bgcolor= - -# set to false to open a new untitled window when closing the last window -# (otherwise, the environment will quit) -# default to the relative norm for the different platforms, -# but the setting can be changed in the prefs dialog anyway -#sketchbook.closing_last_window_quits = true -#sketchbook.closing_last_window_quits.macos = false - -editor.untitled.prefix=sketch_ -# The old (pre-1.0, back for 2.0) style for default sketch name. -# If you change this, be careful that this will work with your language -# settings. For instance, MMMdd won't work on Korean-language systems -# because it'll insert non-ASCII characters and break the environment. -# https://github.com/processing/processing/issues/322 -editor.untitled.suffix=yyMMdd - -# replace underscores in .pde file names with spaces -sketch.name.replace_underscore = true - -# what to use for generating sketch names (change in the prefs window) -#sketch.name.approach = - -# number of days of build history and other temp files to keep around -# these are kept around for debugging purposes, and in case code is lost -temp.days = 7 - - -# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - -# whether or not to export as full screen (present) mode -export.application.fullscreen = false - -# whether to show the stop button when exporting to application -export.application.stop = true - -# embed Java by default for lower likelihood of problems -export.application.embed_java = true - -# set to false to no longer delete application folders before export -# (removed from the Preferences windows in 4.0 beta 9) -export.delete_target_folder = true - -# may be useful when attempting to debug the preprocessor -preproc.save_build_files=false - -# allows various preprocessor features to be toggled -# in case they are causing problems - -# preprocessor: pde.g -preproc.color_datatype = true -preproc.web_colors = true -preproc.enhanced_casting = true - -# preprocessor: PdeEmitter.java -preproc.substitute_floats = true - -# PdePreproc.java -# writes out the parse tree as parseTree.xml, which can be usefully -# viewed in (at least) Mozilla or IE. useful when debugging the preprocessor. -preproc.output_parse_tree = false - -# set to the program to be used for opening HTML files, folders, etc. -#launcher.linux = xdg-open - -# FULL SCREEN (PRESENT MODE) -run.present.bgcolor = #666666 -run.present.stop.color = #cccccc - -# PROXIES -# Set a proxy server for folks that require it. This will allow the update -# checker and the contrib manager to run properly in those environments. -# This changed from proxy.host and proxy.port to proxy.http.host and -# proxy.http.port in 3.0a8. In addition, https and socks were added. -proxy.http.host= -proxy.http.port= -proxy.https.host= -proxy.https.port= -proxy.socks.host= -proxy.socks.port= -# Example of usage (replace 'http' with 'https' or 'socks' as needed) -#proxy.http.host=proxy.example.com -#proxy.http.port=8080 -# Whether to use the system proxy by default -proxy.system=true - -# PDE X -pdex.errorCheckEnabled = true -pdex.warningsEnabled = true -pdex.writeErrorLogs = false - -pdex.autoSave.autoSaveEnabled = false -pdex.autoSaveInterval = 5 -pdex.autoSave.promptDisplay = true -pdex.autoSave.autoSaveByDefault = true - -# Enable auto-completion when hitting ctrl-space -pdex.completion = false -# Setting this true will show completions whenever available, not just after ctrl-space -pdex.completion.trigger = false -# Suggest libraries to import when a class is undefined/unavailable -pdex.suggest.imports = true -# Set to false to disable ctrl/cmd-click jump to definition -pdex.inspectMode.hotkey = true From 387aa8e9cfdd66841b4049c4808a5d33af48568e Mon Sep 17 00:00:00 2001 From: Stef Tervelde Date: Wed, 19 Nov 2025 15:44:22 +0100 Subject: [PATCH 2/6] Added settings override --- app/src/processing/app/Base.java | 5 ++++- app/test/processing/app/SketchbookTest.kt | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index ec237d0efc..396b784f93 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -2221,7 +2221,10 @@ static public File getSettingsFolder() { try { settingsFolder = Platform.getSettingsFolder(); - + var settingsOverride = System.getProperty("processing.settings.folder"); + if (settingsOverride != null && !settingsOverride.isEmpty()) { + settingsFolder = new File(settingsOverride); + } // create the folder if it doesn't exist already if (!settingsFolder.exists()) { if (!settingsFolder.mkdirs()) { diff --git a/app/test/processing/app/SketchbookTest.kt b/app/test/processing/app/SketchbookTest.kt index 3d0c387cb0..095dcacd2c 100644 --- a/app/test/processing/app/SketchbookTest.kt +++ b/app/test/processing/app/SketchbookTest.kt @@ -13,9 +13,13 @@ class SketchbookTest { @Test fun sketchbookIsOverridableTest() { val directory = createTempDirectory("scaffolding") + val preferences = directory.resolve("preferences") + preferences.toFile().mkdirs() val sketchbook = directory.resolve("sketchbook") sketchbook.toFile().mkdirs() + System.setProperty("processing.sketchbook.folder", sketchbook.toAbsolutePath().toString()) + System.setProperty("processing.settings.folder", preferences.toAbsolutePath().toString()) val result = Base.getSketchbookFolder() assert(result.absolutePath == sketchbook.toAbsolutePath().toString()) From 8660f0a5cd57d03f6ebdfd5567de64ef5d3b6669 Mon Sep 17 00:00:00 2001 From: Stef Tervelde Date: Wed, 19 Nov 2025 15:51:58 +0100 Subject: [PATCH 3/6] Revert "Added settings override" This reverts commit 387aa8e9cfdd66841b4049c4808a5d33af48568e. --- app/src/processing/app/Base.java | 5 +---- app/test/processing/app/SketchbookTest.kt | 4 ---- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 396b784f93..ec237d0efc 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -2221,10 +2221,7 @@ static public File getSettingsFolder() { try { settingsFolder = Platform.getSettingsFolder(); - var settingsOverride = System.getProperty("processing.settings.folder"); - if (settingsOverride != null && !settingsOverride.isEmpty()) { - settingsFolder = new File(settingsOverride); - } + // create the folder if it doesn't exist already if (!settingsFolder.exists()) { if (!settingsFolder.mkdirs()) { diff --git a/app/test/processing/app/SketchbookTest.kt b/app/test/processing/app/SketchbookTest.kt index 095dcacd2c..3d0c387cb0 100644 --- a/app/test/processing/app/SketchbookTest.kt +++ b/app/test/processing/app/SketchbookTest.kt @@ -13,13 +13,9 @@ class SketchbookTest { @Test fun sketchbookIsOverridableTest() { val directory = createTempDirectory("scaffolding") - val preferences = directory.resolve("preferences") - preferences.toFile().mkdirs() val sketchbook = directory.resolve("sketchbook") sketchbook.toFile().mkdirs() - System.setProperty("processing.sketchbook.folder", sketchbook.toAbsolutePath().toString()) - System.setProperty("processing.settings.folder", preferences.toAbsolutePath().toString()) val result = Base.getSketchbookFolder() assert(result.absolutePath == sketchbook.toAbsolutePath().toString()) From ce4ec3bf76558bf90f756855b65c7dfb917a4d81 Mon Sep 17 00:00:00 2001 From: Stef Tervelde Date: Wed, 19 Nov 2025 15:53:39 +0100 Subject: [PATCH 4/6] Moved sketchbook override --- app/src/processing/app/Base.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index ec237d0efc..b5ac774586 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -2263,13 +2263,14 @@ static public File getToolsFolder() { static public void locateSketchbookFolder() { - // If a value is at least set, first check to see if the folder exists. - // If it doesn't, warn the user that the sketchbook folder is being reset. - String sketchbookPath = Preferences.getSketchbookPath(); var sketchbookPathOverride = System.getProperty("processing.sketchbook.folder"); if (sketchbookPathOverride != null && !sketchbookPathOverride.isEmpty()) { - sketchbookPath = sketchbookPathOverride; + sketchbookFolder = new File(sketchbookPathOverride); + return; } + // If a value is at least set, first check to see if the folder exists. + // If it doesn't, warn the user that the sketchbook folder is being reset. + String sketchbookPath = Preferences.getSketchbookPath(); if (sketchbookPath != null) { sketchbookFolder = new File(sketchbookPath); if (!sketchbookFolder.exists()) { From dfd26bbbc341c0d6804a4c8fcabe37ca02c09039 Mon Sep 17 00:00:00 2001 From: Stef Tervelde Date: Wed, 19 Nov 2025 16:00:00 +0100 Subject: [PATCH 5/6] Using assertEquals --- app/test/processing/app/SketchbookTest.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/test/processing/app/SketchbookTest.kt b/app/test/processing/app/SketchbookTest.kt index 3d0c387cb0..8063435089 100644 --- a/app/test/processing/app/SketchbookTest.kt +++ b/app/test/processing/app/SketchbookTest.kt @@ -2,6 +2,7 @@ package processing.app import kotlin.io.path.createTempDirectory import kotlin.test.Test +import kotlin.test.assertEquals class SketchbookTest { @Test @@ -15,9 +16,10 @@ class SketchbookTest { val directory = createTempDirectory("scaffolding") val sketchbook = directory.resolve("sketchbook") sketchbook.toFile().mkdirs() - System.setProperty("processing.sketchbook.folder", sketchbook.toAbsolutePath().toString()) + val sketchbookAbs = sketchbook.toAbsolutePath().toString() + System.setProperty("processing.sketchbook.folder", sketchbookAbs) val result = Base.getSketchbookFolder() - assert(result.absolutePath == sketchbook.toAbsolutePath().toString()) + assertEquals(sketchbookAbs, result.absolutePath) } } \ No newline at end of file From 907238db146283e9ebcefaacf13828a2aca66fa5 Mon Sep 17 00:00:00 2001 From: Stef Tervelde Date: Wed, 19 Nov 2025 16:11:57 +0100 Subject: [PATCH 6/6] Stop using the private field internally --- app/src/processing/app/Base.java | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index b5ac774586..1ff90146fe 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -130,9 +130,6 @@ public class Base { // https://github.com/processing/processing/pull/2366 private JFileChooser openChooser; - static protected File sketchbookFolder; - - static public void main(final String[] args) { Messages.log("Starting Processing version" + VERSION_NAME + " revision "+ REVISION); EventQueue.invokeLater(() -> { @@ -1951,7 +1948,7 @@ public void populateSketchbookMenu(JMenu menu) { new Thread(() -> { boolean found = false; try { - found = addSketches(menu, sketchbookFolder); + found = addSketches(menu, getSketchbookFolder()); } catch (Exception e) { Messages.showWarning("Sketchbook Menu Error", "An error occurred while trying to list the sketchbook.", e); @@ -1990,7 +1987,7 @@ protected boolean addSketches(JMenu menu, File folder) { if (folder.getName().equals("sdk")) { // This could be Android's SDK folder. Let's double-check: File suspectSDKPath = new File(folder.getParent(), folder.getName()); - File expectedSDKPath = new File(sketchbookFolder, "android" + File.separator + "sdk"); + File expectedSDKPath = new File(getSketchbookFolder(), "android" + File.separator + "sdk"); if (expectedSDKPath.getAbsolutePath().equals(suspectSDKPath.getAbsolutePath())) { return false; // Most likely the SDK folder, skip it } @@ -2261,13 +2258,8 @@ static public File getToolsFolder() { return Platform.getContentFile("tools"); } - + static protected File sketchbookFolder; static public void locateSketchbookFolder() { - var sketchbookPathOverride = System.getProperty("processing.sketchbook.folder"); - if (sketchbookPathOverride != null && !sketchbookPathOverride.isEmpty()) { - sketchbookFolder = new File(sketchbookPathOverride); - return; - } // If a value is at least set, first check to see if the folder exists. // If it doesn't, warn the user that the sketchbook folder is being reset. String sketchbookPath = Preferences.getSketchbookPath(); @@ -2333,6 +2325,10 @@ static protected void makeSketchbookSubfolders() { static public File getSketchbookFolder() { + var sketchbookPathOverride = System.getProperty("processing.sketchbook.folder"); + if (sketchbookPathOverride != null && !sketchbookPathOverride.isEmpty()) { + return new File(sketchbookPathOverride); + } if (sketchbookFolder == null) { locateSketchbookFolder(); } @@ -2341,27 +2337,27 @@ static public File getSketchbookFolder() { static public File getSketchbookLibrariesFolder() { - return new File(sketchbookFolder, "libraries"); + return new File(getSketchbookFolder(), "libraries"); } static public File getSketchbookToolsFolder() { - return new File(sketchbookFolder, "tools"); + return new File(getSketchbookFolder(), "tools"); } static public File getSketchbookModesFolder() { - return new File(sketchbookFolder, "modes"); + return new File(getSketchbookFolder(), "modes"); } static public File getSketchbookExamplesFolder() { - return new File(sketchbookFolder, "examples"); + return new File(getSketchbookFolder(), "examples"); } static public File getSketchbookTemplatesFolder() { - return new File(sketchbookFolder, "templates"); + return new File(getSketchbookFolder(), "templates"); }