mirror of
https://github.com/processing/processing4.git
synced 2026-02-02 21:29:17 +01:00
toying with automatic restart
This commit is contained in:
@@ -600,6 +600,10 @@ public class Base {
|
||||
item.addActionListener(e -> thinkDifferentExamples());
|
||||
defaultFileMenu.add(item);
|
||||
|
||||
item = new JMenuItem("Restart");
|
||||
item.addActionListener(e -> handleRestart());
|
||||
defaultFileMenu.add(item);
|
||||
|
||||
return defaultFileMenu;
|
||||
}
|
||||
|
||||
@@ -858,16 +862,15 @@ public class Base {
|
||||
if (internalTools == null) {
|
||||
internalTools = new ArrayList<>();
|
||||
|
||||
initInternalTool("processing.app.tools.Archiver");
|
||||
initInternalTool("processing.app.tools.ColorSelector");
|
||||
initInternalTool("processing.app.tools.CreateFont");
|
||||
initInternalTool(processing.app.tools.Archiver.class);
|
||||
initInternalTool(processing.app.tools.ColorSelector.class);
|
||||
initInternalTool(processing.app.tools.CreateFont.class);
|
||||
|
||||
if (Platform.isMacOS()) {
|
||||
initInternalTool("processing.app.tools.InstallCommander");
|
||||
initInternalTool(processing.app.tools.InstallCommander.class);
|
||||
}
|
||||
|
||||
initInternalTool("processing.app.tools.ThemeSelector");
|
||||
//initInternalTool("processing.app.tools.UpdateTheme");
|
||||
initInternalTool(processing.app.tools.ThemeSelector.class);
|
||||
}
|
||||
|
||||
// Only init() these the first time they're loaded
|
||||
@@ -913,9 +916,8 @@ public class Base {
|
||||
}
|
||||
|
||||
|
||||
protected void initInternalTool(String className) {
|
||||
protected void initInternalTool(Class<?> toolClass) {
|
||||
try {
|
||||
Class<?> toolClass = Class.forName(className);
|
||||
final Tool tool = (Tool)
|
||||
toolClass.getDeclaredConstructor().newInstance();
|
||||
|
||||
@@ -1681,18 +1683,6 @@ public class Base {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// wow, this is wrong (should only be called after the last window)
|
||||
// but also outdated, because it's instance_server.* not server.*
|
||||
// and Preferences.save() is also about restoring sketches.
|
||||
|
||||
Preferences.unset("server.port"); //$NON-NLS-1$
|
||||
Preferences.unset("server.key"); //$NON-NLS-1$
|
||||
|
||||
// Save out the current prefs state
|
||||
Preferences.save();
|
||||
*/
|
||||
|
||||
if (defaultFileMenu == null) {
|
||||
if (preventQuit) {
|
||||
// need to close this editor, ever so temporarily
|
||||
@@ -1724,7 +1714,10 @@ public class Base {
|
||||
|
||||
|
||||
/**
|
||||
* Handler for File → Quit.
|
||||
* Handler for File → Quit. Note that this is *only* for the
|
||||
* File menu. On macOS, it will not call System.exit() because the
|
||||
* application will handle that. If calling this from elsewhere,
|
||||
* you'll need a System.exit() call on macOS.
|
||||
* @return false if canceled, true otherwise.
|
||||
*/
|
||||
public boolean handleQuit() {
|
||||
@@ -1777,6 +1770,46 @@ public class Base {
|
||||
}
|
||||
|
||||
|
||||
public void handleRestart() {
|
||||
File app = Platform.getProcessingApp();
|
||||
System.out.println(app);
|
||||
if (app.exists()) {
|
||||
if (handleQuitEach()) { // only if everything saved
|
||||
SingleInstance.clearRunning();
|
||||
|
||||
// Launch on quit
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||
try {
|
||||
//Runtime.getRuntime().exec(app.getAbsolutePath());
|
||||
System.out.println("launching");
|
||||
Process p;
|
||||
if (Platform.isMacOS()) {
|
||||
p = Runtime.getRuntime().exec(new String[]{
|
||||
"open", "-n", "-a", app.getAbsolutePath()
|
||||
});
|
||||
} else {
|
||||
p = PApplet.launch(app.getAbsolutePath());
|
||||
}
|
||||
System.out.println("launched with result " + p.waitFor());
|
||||
System.out.flush();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}));
|
||||
handleQuit();
|
||||
// handleQuit() does not call System.exit() on macOS
|
||||
if (Platform.isMacOS()) {
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Messages.showWarning("Cannot Restart",
|
||||
"Cannot automatically restart because the Processing\n" +
|
||||
"application has been renamed. Please quit and then restart manually.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2012-20 The Processing Foundation
|
||||
Copyright (c) 2012-23 The Processing Foundation
|
||||
Copyright (c) 2008-12 Ben Fry and Casey Reas
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
@@ -25,9 +25,12 @@ 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.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sun.jna.platform.FileUtils;
|
||||
@@ -404,6 +407,114 @@ public class Platform {
|
||||
}
|
||||
|
||||
|
||||
static protected File getProcessingApp() {
|
||||
File appFile;
|
||||
if (Platform.isMacOS()) {
|
||||
// walks up from Processing.app/Contents/Java to Processing.app
|
||||
// (or whatever the user has renamed it to)
|
||||
appFile = getContentFile("../..");
|
||||
} else if (Platform.isWindows()) {
|
||||
appFile = getContentFile("processing.exe");
|
||||
} else {
|
||||
appFile = getContentFile("processing");
|
||||
}
|
||||
try {
|
||||
return appFile.getCanonicalFile();
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// Not great, shows the crusty Duke icon in the dock.
|
||||
// Better to just re-launch the .exe instead.
|
||||
// Hacked up from <a href="https://lewisleo.blogspot.com/2012/08/programmatically-restart-java.html">this code</a>.
|
||||
static private void restartJavaApplication() {
|
||||
// System.out.println("java path: " + javaPath);
|
||||
// String java = System.getProperty("java.home") + "/bin/java";
|
||||
// Tested and working with JDK 17 [fry 230122]
|
||||
// System.out.println("sun java command: " + System.getProperty("sun.java.command"));
|
||||
// System.out.println("class path: " + System.getProperty("java.class.path"));
|
||||
List<String> cmd = new ArrayList<>();
|
||||
|
||||
// Add the path to the current java binary
|
||||
cmd.add(getJavaPath());
|
||||
|
||||
// Get all the VM arguments that are currently in use
|
||||
List<String> vmArguments =
|
||||
ManagementFactory.getRuntimeMXBean().getInputArguments();
|
||||
|
||||
// Add all the arguments we're using now, except for -agentlib
|
||||
for (String arg : vmArguments) {
|
||||
if (!arg.contains("-agentlib")) {
|
||||
cmd.add(arg);
|
||||
}
|
||||
}
|
||||
|
||||
// Does not work for .jar files, should this be used in a more general way
|
||||
cmd.add("-cp");
|
||||
cmd.add(System.getProperty("java.class.path"));
|
||||
|
||||
// Finally, add the class that was used to launch the app
|
||||
// (in our case, this is the Processing splash screen)
|
||||
String javaCommand = System.getProperty("sun.java.command");
|
||||
String[] splitCommand = PApplet.split(javaCommand, ' ');
|
||||
// if (splitCommand.length > 1) {
|
||||
// try {
|
||||
// Util.saveFile(javaCommand, PApplet.desktopFile("arrrrrghs.txt"));
|
||||
// } catch (IOException e) {
|
||||
// throw new RuntimeException(e);
|
||||
// }
|
||||
// }
|
||||
cmd.add(splitCommand[0]); // should be the main class name
|
||||
|
||||
ProcessBuilder builder = new ProcessBuilder(cmd);
|
||||
|
||||
/*
|
||||
StringBuffer vmArgsOneLine = new StringBuffer();
|
||||
for (String arg : vmArguments) {
|
||||
// if it's the agent argument : we ignore it otherwise the
|
||||
// address of the old application and the new one will be in conflict
|
||||
if (!arg.contains("-agentlib")) {
|
||||
vmArgsOneLine.append(arg);
|
||||
vmArgsOneLine.append(" ");
|
||||
}
|
||||
}
|
||||
// init the command to execute, add the vm args
|
||||
final StringBuffer cmd = new StringBuffer("\"" + java + "\" " + vmArgsOneLine);
|
||||
// program main and program arguments (be careful a sun property. might not be supported by all JVM)
|
||||
String[] mainCommand = System.getProperty("sun.java.command").split(" ");
|
||||
// program main is a jar
|
||||
if (mainCommand[0].endsWith(".jar")) {
|
||||
// if it's a jar, add -jar mainJar
|
||||
cmd.append("-jar " + new File(mainCommand[0]).getPath());
|
||||
} else {
|
||||
// else it's a .class, add the classpath and mainClass
|
||||
cmd.append("-cp \"" + System.getProperty("java.class.path") + "\" " + mainCommand[0]);
|
||||
}
|
||||
// finally add program arguments
|
||||
for (int i = 1; i < mainCommand.length; i++) {
|
||||
cmd.append(" ");
|
||||
cmd.append(mainCommand[i]);
|
||||
}
|
||||
*/
|
||||
// execute the command in a shutdown hook, to be sure that all the
|
||||
// resources have been disposed before restarting the application
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||
try {
|
||||
// System.out.println(new StringList(cmd).join(" "));
|
||||
// Runtime.getRuntime().exec(cmd.toArray(new String[0]));
|
||||
builder.start();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}));
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
|
||||
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
||||
|
||||
|
||||
|
||||
@@ -54,6 +54,15 @@ public class SingleInstance {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Disable briefly for Processing to restart itself.
|
||||
*/
|
||||
static public void clearRunning() {
|
||||
Preferences.unset(SERVER_PORT);
|
||||
Preferences.save();
|
||||
}
|
||||
|
||||
|
||||
static void startServer(final Base base) {
|
||||
try {
|
||||
Messages.log("Opening SingleInstance socket");
|
||||
|
||||
5
todo.txt
5
todo.txt
@@ -29,6 +29,11 @@ _ update console.scrollbar.thumb.rollover.color and console.scrollbar.thumb.pres
|
||||
_ currently just using .enabled.color because they weren't in ColorSet
|
||||
|
||||
|
||||
_ remove temporary 'restart' menu before release
|
||||
|
||||
_ implement automatic updates?
|
||||
_ especially with fixes to updates on startup...
|
||||
|
||||
_ export to IntelliJ? how tricky?
|
||||
_ just copy jars to /lib?
|
||||
_ point to binaries in /Applications/Processing.app? (no)
|
||||
|
||||
Reference in New Issue
Block a user