toying with automatic restart

This commit is contained in:
Ben Fry
2023-01-22 13:24:03 -05:00
parent ecb0fcd9d8
commit 4c8fa46200
4 changed files with 180 additions and 22 deletions

View File

@@ -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 &rarr; Quit.
* Handler for File &rarr; 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.");
}
}
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

View File

@@ -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);
}
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

View File

@@ -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");

View File

@@ -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)