Fix problem with keyPressed variable being shadowed by keyPressed function, if present.
Bring sketch window to front on OS X.
MODIFY
Base - Launch Mode in Eclipse.launch
Base - Launch Mode in Eclipse.launch
</mapAttribute>
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER&quot; javaProject=&quot;processing-app&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#13;&#10;&lt;memento exportedEntriesOnly=&quot;false&quot; project=&quot;processing-app&quot;/&gt;&#13;&#10;&lt;/runtimeClasspathEntry&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/processing.py/buildtime/lib/jython/jython.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry path=&quot;3&quot; projectName=&quot;processing.py&quot; type=&quot;1&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/processing.py/buildtime/lib/java/guava-17.0.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry path=&quot;3&quot; projectName=&quot;processing-core&quot; type=&quot;1&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry path=&quot;3&quot; projectName=&quot;processing-java&quot; type=&quot;1&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry path=&quot;3&quot; projectName=&quot;processing-app&quot; type=&quot;1&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/processing-app/lib/ant.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/processing-app/lib/ant-launcher.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry path=&quot;3&quot; projectName=&quot;processing-video&quot; type=&quot;1&quot;/&gt;&#13;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER&quot; javaProject=&quot;processing-app&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#10;&lt;memento exportedEntriesOnly=&quot;false&quot; project=&quot;processing-app&quot;/&gt;&#10;&lt;/runtimeClasspathEntry&gt;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/processing.py/buildtime/lib/jython/jython.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry path=&quot;3&quot; projectName=&quot;processing.py&quot; type=&quot;1&quot;/&gt;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/processing.py/buildtime/lib/java/guava-17.0.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry path=&quot;3&quot; projectName=&quot;processing-core&quot; type=&quot;1&quot;/&gt;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry path=&quot;3&quot; projectName=&quot;processing-java&quot; type=&quot;1&quot;/&gt;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry path=&quot;3&quot; projectName=&quot;processing-app&quot; type=&quot;1&quot;/&gt;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/processing-app/lib/ant.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/processing-app/lib/ant-launcher.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry path=&quot;3&quot; projectName=&quot;processing-video&quot; type=&quot;1&quot;/&gt;&#10;"/>
</listAttribute>
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="processing.app.Base"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="processing-app"/>
-<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea -Dusemode=&quot;jycessing.mode.PythonMode:${resource_loc:/processing.py/mode}&quot;"/>
+<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea -Dusemode=&quot;jycessing.mode.PythonMode:${resource_loc:/processing.py/mode}&quot; -Djava.library.path=${resource_loc:/processing.py/native}"/>
</launchConfiguration>

MODIFY
build.xml
build.xml
<fileset dir="mode/" />
</copy>
+ <copy todir="${bundle}/mode">
+ <fileset dir="native/" />
+ </copy>
+
<copy todir="${bundle}/theme" file="libraries/runtime/splash.png"/>
<zip destfile="${bundle}/src.zip" basedir="."
</sequential>
</macrodef>
+ <target name="jni-OSX" depends="build">
+ <javah destdir="runtime/src/jycessing/jni"
+ force="yes"
+ class="jycessing.jni.OSX"
+ classpath="./bin"/>
+ </target>
+
<macrodef name="for-all-platforms">
<attribute name="target"/>
<sequential>

ADD
native/libjniosx.dylib
native/libjniosx.dylib
Binary files /dev/null and b/native/libjniosx.dylib differ

MODIFY
runtime/src/jycessing/PAppletJythonDriver.java
runtime/src/jycessing/PAppletJythonDriver.java
@@ -65,6 +65,7 @@ import com.google.common.io.Files;
import com.jogamp.newt.opengl.GLWindow;
import jycessing.IOUtil.ResourceReader;
+import jycessing.jni.OSX;
import jycessing.mode.run.WrappedPrintStream;
import jycessing.mode.run.WrappedPrintStream.PushedOut;
import processing.awt.PSurfaceAWT;
@@ -206,6 +207,9 @@ public class PAppletJythonDriver extends PApplet {
rawMidi3Meth,
midiMessage3Meth;
+ // Implement processing_websockets callbacks.
+ private PyObject webSocketEventMeth, webSocketServerEventMeth;
+
private SketchPositionListener sketchPositionListener;
private void processSketch(final String scriptSource) throws PythonSketchError {
@@ -583,8 +587,9 @@ public class PAppletJythonDriver extends PApplet {
}
};
+ // keyPressed is renamed to __keyPressed__ by the preprocessor.
keyPressedFunc =
- new EventFunction<KeyEvent>("keyPressed") {
+ new EventFunction<KeyEvent>("__keyPressed__") {
@Override
protected void callSuper(final KeyEvent event) {
PAppletJythonDriver.super.keyPressed(event);
@@ -708,6 +713,10 @@ public class PAppletJythonDriver extends PApplet {
midiMessage3Meth = meth;
}
}
+
+ // processing_websockets callbacks.
+ webSocketEventMeth = interp.get("webSocketEvent");
+ webSocketServerEventMeth = interp.get("webSocketServerEvent");
}
/*
@@ -815,7 +824,15 @@ public class PAppletJythonDriver extends PApplet {
super.start();
}
+ private void bringToFront() {
+ if (PApplet.platform == PConstants.MACOSX) {
+ OSX.bringToFront();
+ }
+ }
+
public void runAndBlock(final String[] args) throws PythonSketchError {
+ bringToFront();
+
PApplet.runSketch(args, this);
try {
finishedLatch.await();
@@ -1612,6 +1629,19 @@ public class PAppletJythonDriver extends PApplet {
}
}
+ // processing_websockets callbacks.
+ public void webSocketEvent(final String msg) {
+ if (webSocketEventMeth != null) {
+ webSocketEventMeth.__call__(Py.java2py(msg));
+ }
+ }
+
+ public void webSocketServerEvent(final String msg) {
+ if (webSocketServerEventMeth != null) {
+ webSocketServerEventMeth.__call__(Py.java2py(msg));
+ }
+ }
+
public void setSketchPositionListener(final SketchPositionListener sketchPositionListener) {
this.sketchPositionListener = sketchPositionListener;
}

ADD
runtime/src/jycessing/jni/OSX.java
+package jycessing.jni;
+
+import processing.core.PApplet;
+import processing.core.PConstants;
+
+public class OSX {
+ public static void bringToFront() {
+ if (PApplet.platform == PConstants.MACOSX) {
+ try {
+ System.loadLibrary("jniosx");
+ activateIgnoringOtherApps();
+ } catch (final UnsatisfiedLinkError err) {
+ System.err.println("Hmm. Can't load native code to bring window to front.");
+ }
+ }
+ }
+
+ private static native void activateIgnoringOtherApps();
+}

ADD
runtime/src/jycessing/jni/jniosx/jniosx/jniosx.m
+#include "jycessing_jni_OSX.h"
+
+#import "AppKit/AppKit.h"
+
+JNIEXPORT void JNICALL Java_jycessing_jni_OSX_activateIgnoringOtherApps
+(JNIEnv *env, jclass klass) {
+ [NSApp activateIgnoringOtherApps:true];
+}

ADD
runtime/src/jycessing/jni/jycessing_jni_OSX.h
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class jycessing_jni_OSX */
+
+#ifndef _Included_jycessing_jni_OSX
+#define _Included_jycessing_jni_OSX
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: jycessing_jni_OSX
+ * Method: activateIgnoringOtherApps
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_jycessing_jni_OSX_activateIgnoringOtherApps
+ (JNIEnv *, jclass);
+
+#ifdef __cplusplus
+}
+#endif
+#endif

MODIFY
runtime/src/jycessing/mode/run/SketchServiceProcess.java
runtime/src/jycessing/mode/run/SketchServiceProcess.java
@@ -130,7 +130,11 @@ public class SketchServiceProcess {
command.add("-Dverbose=true");
}
- command.add("-Djava.library.path=" + System.getProperty("java.library.path"));
+ command.add(
+ "-Djava.library.path="
+ + System.getProperty("java.library.path")
+ + File.pathSeparator
+ + mode.getContentFile("mode").getAbsolutePath());
final List<String> cp = new ArrayList<>();
cp.addAll(

MODIFY
runtime/src/jycessing/pyde_preprocessor.py
runtime/src/jycessing/pyde_preprocessor.py
# <statements>
# def draw():
# <statements>
+#
+# This also renames a "keyPressed" function to "__keyPressed__", to avoid hiding
+# the boolean variable with the same name.
import ast
@@ -41,6 +44,10 @@ def pyde_preprocessor(module):
# Walk throught the abstract syntax tree for the original sketch.
for node in module.body:
if isinstance(node, ast.FunctionDef):
+ if (node.name == 'keyPressed'):
+ # rename keyPressed to not clash with the builtin boolean variable
+ node.name = '__keyPressed__'
+ continue
if (node.name == 'setup'):
toremove = []
# The user has defined a setup() function. Look through setup() for calls

Fix problem with keyPressed variable being shadowed by keyPressed function, if present.

Bring sketch window to front on OS X.