From e97c6bff218867e7075e1a2bb255470fb1c71f12 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sat, 6 Aug 2016 11:39:27 -0400 Subject: [PATCH] further refactoring --- .../processing/app/syntax/JEditTextArea.java | 9 +- .../app/syntax/TextAreaPainter.java | 6 + app/src/processing/app/ui/Editor.java | 20 +- core/todo.txt | 10 +- java/src/processing/mode/java/JavaEditor.java | 29 +- .../mode/java/pdex/JavaTextArea.java | 174 +---------- .../mode/java/pdex/JavaTextAreaPainter.java | 273 +++++++----------- todo.txt | 11 +- 8 files changed, 162 insertions(+), 370 deletions(-) diff --git a/app/src/processing/app/syntax/JEditTextArea.java b/app/src/processing/app/syntax/JEditTextArea.java index 97217e541..fd1355bf9 100644 --- a/app/src/processing/app/syntax/JEditTextArea.java +++ b/app/src/processing/app/syntax/JEditTextArea.java @@ -794,26 +794,27 @@ public class JEditTextArea extends JComponent } } + /** * Converts a point to an offset, from the start of the text. * @param x The x co-ordinate of the point * @param y The y co-ordinate of the point */ - public int xyToOffset(int x, int y) - { + public int xyToOffset(int x, int y) { int line = yToLine(y); int start = getLineStartOffset(line); return start + xToOffset(line,x); } + /** * Returns the document this text area is editing. */ - public final SyntaxDocument getDocument() - { + public final SyntaxDocument getDocument() { return document; } + /** * Sets the document this text area is editing. * @param document The document diff --git a/app/src/processing/app/syntax/TextAreaPainter.java b/app/src/processing/app/syntax/TextAreaPainter.java index 59c99a5a8..2dd0f7691 100644 --- a/app/src/processing/app/syntax/TextAreaPainter.java +++ b/app/src/processing/app/syntax/TextAreaPainter.java @@ -438,6 +438,12 @@ public class TextAreaPainter extends JComponent implements TabExpander { } + // fry [160806 for 3.2] + public int getLineHeight() { + return fm.getHeight() + fm.getDescent(); + } + + // /** // * Sets the font for this component. This is overridden to update the // * cached font metrics and to recalculate which lines are visible. diff --git a/app/src/processing/app/ui/Editor.java b/app/src/processing/app/ui/Editor.java index 0c713d181..58f5025fd 100644 --- a/app/src/processing/app/ui/Editor.java +++ b/app/src/processing/app/ui/Editor.java @@ -2358,6 +2358,14 @@ public abstract class Editor extends JFrame implements RunnerListener { // } + public boolean isDebuggerEnabled() { + return false; + } + + + public void toggleBreakpoint(int lineIndex) { } + + /** * Check if the sketch is modified and ask user to save changes. * @return false if canceling the close/quit operation @@ -2930,18 +2938,6 @@ public abstract class Editor extends JFrame implements RunnerListener { static Color bgColorError; - /* - public void toolTipError(JComponent comp, String message) { - setToolTip(comp, message, true); - } - - - public void toolTipWarning(JComponent comp, String message) { - setToolTip(comp, message, false); - } - */ - - public void statusToolTip(JComponent comp, String message, boolean error) { if (font == null) { font = Toolkit.getSansFont(9, Font.PLAIN); diff --git a/core/todo.txt b/core/todo.txt index 59916d171..203a3111c 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -1,4 +1,4 @@ -0252 (3.1.3?) +0252 (3.2) X some Table cleanup based on other CSV parsing work X use StandardCharsets.UTF_8 instead of getting encoding by name X PApplet.main(Blah.class) now works @@ -7,6 +7,14 @@ _ do the same for the other data classes _ note the difference between this and toJSONObject() or toJSONArray() _ or is that the better way to handle it? hm +jakub +X Fix resizing targets for async save +X https://github.com/processing/processing/pull/4607 +X https://github.com/processing/processing/issues/4578 + +_ disable OpenGL ES on Linux? +_ https://github.com/processing/processing/issues/4584 + _ Can't render PGraphics object using image() within a PDF _ https://github.com/processing/processing/issues/4473 diff --git a/java/src/processing/mode/java/JavaEditor.java b/java/src/processing/mode/java/JavaEditor.java index 82a949ccc..9272a0840 100644 --- a/java/src/processing/mode/java/JavaEditor.java +++ b/java/src/processing/mode/java/JavaEditor.java @@ -126,7 +126,8 @@ public class JavaEditor extends Editor { getJavaTextArea().setMode(jmode); - initPDEX(); + preprocessingService = new PreprocessingService(this); + pdex = new PDEX(this, preprocessingService); Toolkit.setMenuMnemonics(textarea.getRightClickPopup()); @@ -146,18 +147,12 @@ public class JavaEditor extends Editor { }); } - + public PdePreprocessor createPreprocessor(final String sketchName) { - return new PdePreprocessor(sketchName); + return new PdePreprocessor(sketchName); } - - protected void initPDEX() { - preprocessingService = new PreprocessingService(this); - pdex = new PDEX(this, preprocessingService); - } - - + protected JEditTextArea createTextArea() { return new JavaTextArea(new PdeTextAreaDefaults(mode), this); } @@ -1195,12 +1190,13 @@ public class JavaEditor extends Editor { } - /** Toggle a breakpoint on the current line. */ - public void toggleBreakpoint() { - debugger.toggleBreakpoint(getCurrentLineID().lineIdx()); - } +// /** Toggle a breakpoint on the current line. */ +// public void toggleBreakpoint() { +// toggleBreakpoint(getCurrentLineID().lineIdx()); +// } + @Override public void toggleBreakpoint(int lineIndex) { debugger.toggleBreakpoint(lineIndex); } @@ -1430,7 +1426,8 @@ public class JavaEditor extends Editor { item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Logger.getLogger(JavaEditor.class.getName()).log(Level.INFO, "Invoked 'Toggle Breakpoint' menu item"); - toggleBreakpoint(); + // TODO wouldn't getCaretLine() do the same thing with less effort? + toggleBreakpoint(getCurrentLineID().lineIdx()); } }); debugMenu.add(item); @@ -1522,8 +1519,8 @@ public class JavaEditor extends Editor { } + @Override public boolean isDebuggerEnabled() { - //return enableDebug.isSelected(); return debugEnabled; } diff --git a/java/src/processing/mode/java/pdex/JavaTextArea.java b/java/src/processing/mode/java/pdex/JavaTextArea.java index eb0881366..9eb57fb99 100644 --- a/java/src/processing/mode/java/pdex/JavaTextArea.java +++ b/java/src/processing/mode/java/pdex/JavaTextArea.java @@ -2,7 +2,7 @@ /* Part of the Processing project - http://processing.org -Copyright (c) 2012-15 The Processing Foundation +Copyright (c) 2012-16 The Processing Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 @@ -41,48 +41,19 @@ import processing.app.Messages; import processing.app.Mode; import processing.app.Platform; import processing.app.syntax.JEditTextArea; +import processing.app.syntax.PdeTextArea; import processing.app.syntax.TextAreaDefaults; import processing.app.ui.Editor; -// TODO The way listeners are added/removed here is fragile and -// likely to cause bugs that are very difficult to find. -// We shouldn't be re-inventing the wheel with how listeners are handled. -// TODO We're overriding more things in JEditTextArea than we should, which -// makes it trickier for other Modes (Python, etc) to subclass because -// they'll need to re-implement what's in here, but first wade through it. -// To fix, we need to clean this up and put the appropriate cross-Mode -// changes into JEditTextArea (or a subclass in processing.app) - -public class JavaTextArea extends JEditTextArea { - protected final JavaEditor editor; - - protected Image gutterGradient; - - /// the text marker for highlighting breakpoints in the gutter - static public final String BREAK_MARKER = "<>"; - /// the text marker for highlighting the current line in the gutter - static public final String STEP_MARKER = "->"; - - /// maps line index to gutter text - protected final Map gutterText = new HashMap<>(); +public class JavaTextArea extends PdeTextArea { + //protected final JavaEditor editor; private CompletionPanel suggestion; public JavaTextArea(TextAreaDefaults defaults, JavaEditor editor) { - super(defaults, new JavaInputHandler(editor)); - this.editor = editor; - - // change cursor to pointer in the gutter area - painter.addMouseMotionListener(gutterCursorMouseAdapter); - - //addCompletionPopupListner(); - add(CENTER, painter); - - // load settings from theme.txt - Mode mode = editor.getMode(); - gutterGradient = mode.makeGradient("editor", Editor.LEFT_GUTTER, 500); + super(defaults, new JavaInputHandler(editor), editor); // TweakMode code prevCompListeners = painter.getComponentListeners(); @@ -102,16 +73,11 @@ public class JavaTextArea extends JEditTextArea { } - protected JavaTextAreaPainter getCustomPainter() { + protected JavaTextAreaPainter getJavaPainter() { return (JavaTextAreaPainter) painter; } - public void setMode(JavaMode mode) { - getCustomPainter().setMode(mode); - } - - /** * Handles KeyEvents for TextArea (code completion begins from here). */ @@ -120,7 +86,7 @@ public class JavaTextArea extends JEditTextArea { if (evt.getKeyCode() == KeyEvent.VK_ESCAPE) { if (suggestion != null){ if (suggestion.isVisible()){ - Messages.log("esc key"); + Messages.log("ESC key"); hideSuggestion(); evt.consume(); return; @@ -544,114 +510,6 @@ public class JavaTextArea extends JEditTextArea { } - public Image getGutterGradient() { - return gutterGradient; - } - - - /** - * Set the gutter text of a specific line. - * - * @param lineIdx - * the line index (0-based) - * @param text - * the text - */ - public void setGutterText(int lineIdx, String text) { - gutterText.put(lineIdx, text); - painter.invalidateLine(lineIdx); - } - - - /** - * Clear the gutter text of a specific line. - * - * @param lineIdx - * the line index (0-based) - */ - public void clearGutterText(int lineIdx) { - gutterText.remove(lineIdx); - painter.invalidateLine(lineIdx); - } - - - /** - * Clear all gutter text. - */ - public void clearGutterText() { - for (int lineIdx : gutterText.keySet()) { - painter.invalidateLine(lineIdx); - } - gutterText.clear(); - } - - - /** - * Retrieve the gutter text of a specific line. - * - * @param lineIdx - * the line index (0-based) - * @return the gutter text - */ - public String getGutterText(int lineIdx) { - return gutterText.get(lineIdx); - } - - - /** - * Convert a character offset to a horizontal pixel position inside the text - * area. Overridden to take gutter width into account. - * - * @param line - * the 0-based line number - * @param offset - * the character offset (0 is the first character on a line) - * @return the horizontal position - */ - @Override - public int _offsetToX(int line, int offset) { - return super._offsetToX(line, offset) + Editor.LEFT_GUTTER; - } - - - /** - * Convert a horizontal pixel position to a character offset. Overridden to - * take gutter width into account. - * - * @param line - * the 0-based line number - * @param x - * the horizontal pixel position - * @return he character offset (0 is the first character on a line) - */ - @Override - public int xToOffset(int line, int x) { - return super.xToOffset(line, x - Editor.LEFT_GUTTER); - } - - - /** - * Sets default cursor (instead of text cursor) in the gutter area. - */ - protected final MouseMotionAdapter gutterCursorMouseAdapter = new MouseMotionAdapter() { - private int lastX; // previous horizontal position of the mouse cursor - - @Override - public void mouseMoved(MouseEvent me) { - if (me.getX() < Editor.LEFT_GUTTER) { - if (lastX >= Editor.LEFT_GUTTER) { - painter.setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); - } - } else { - if (lastX < Editor.LEFT_GUTTER) { - painter.setCursor(new Cursor(Cursor.TEXT_CURSOR)); - } - } - lastX = me.getX(); - } - }; - - // appears unused, removed when looking to change completion trigger [fry 140801] /* public void showSuggestionLater(final DefaultListModel defListModel, final String word) { @@ -667,10 +525,7 @@ public class JavaTextArea extends JEditTextArea { /** - * Calculates location of caret and displays the suggestion popup at the location. - * - * @param listModel - * @param subWord + * Calculates location of caret and displays the suggestion popup. */ protected void showSuggestion(DefaultListModel listModel, String subWord) { hideSuggestion(); @@ -682,10 +537,9 @@ public class JavaTextArea extends JEditTextArea { int position = getCaretPosition(); Point location = new Point(); try { - location.x = offsetToX(getCaretLine(), position - - getLineStartOffset(getCaretLine())); - location.y = lineToY(getCaretLine()) - + getPainter().getFontMetrics().getHeight() + getPainter().getFontMetrics().getDescent(); + location.x = offsetToX(getCaretLine(), + position - getLineStartOffset(getCaretLine())); + location.y = lineToY(getCaretLine()) + getPainter().getLineHeight(); //log("TA position: " + location); } catch (Exception e2) { e2.printStackTrace(); @@ -748,7 +602,7 @@ public class JavaTextArea extends JEditTextArea { // ignore if we are already in interactiveMode if (!tweakMode) { removeAllListeners(); - getCustomPainter().startTweakMode(); + getJavaPainter().startTweakMode(); this.editable = false; this.caretBlinks = false; this.setCaretVisible(false); @@ -762,7 +616,7 @@ public class JavaTextArea extends JEditTextArea { if (tweakMode) { removeAllListeners(); addPrevListeners(); - getCustomPainter().stopTweakMode(); + getJavaPainter().stopTweakMode(); editable = true; caretBlinks = true; setCaretVisible(true); @@ -790,6 +644,6 @@ public class JavaTextArea extends JEditTextArea { public void updateInterface(List> handles, List> colorBoxes) { - getCustomPainter().updateInterface(handles, colorBoxes); + getJavaPainter().updateInterface(handles, colorBoxes); } } diff --git a/java/src/processing/mode/java/pdex/JavaTextAreaPainter.java b/java/src/processing/mode/java/pdex/JavaTextAreaPainter.java index 1f9e311da..d9724e3b7 100644 --- a/java/src/processing/mode/java/pdex/JavaTextAreaPainter.java +++ b/java/src/processing/mode/java/pdex/JavaTextAreaPainter.java @@ -2,7 +2,7 @@ /* Part of the Processing project - http://processing.org -Copyright (c) 2012-15 The Processing Foundation +Copyright (c) 2012-16 The Processing Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 @@ -26,13 +26,11 @@ import processing.mode.java.tweak.*; import java.awt.Color; import java.awt.Cursor; import java.awt.Dimension; -import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.RenderingHints; import java.awt.Toolkit; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; @@ -48,59 +46,22 @@ import javax.swing.text.Utilities; import processing.app.Mode; import processing.app.SketchCode; +import processing.app.syntax.PdeTextAreaPainter; import processing.app.syntax.SyntaxDocument; import processing.app.syntax.TextAreaDefaults; -import processing.app.syntax.TextAreaPainter; import processing.app.syntax.TokenMarker; import processing.app.ui.Editor; -// TODO Most of this needs to be merged into the main TextAreaPainter, -// since it's not specific to Java. [fry 150821] - /** * Customized line painter. Adds support for background colors, * left hand gutter area with background color and text. */ -public class JavaTextAreaPainter extends TextAreaPainter - implements MouseListener, MouseMotionListener { - - public Color errorUnderlineColor; - public Color warningUnderlineColor; - - protected Font gutterTextFont; - protected Color gutterTextColor; - protected Color gutterPastColor; - protected Color gutterLineHighlightColor; - +public class JavaTextAreaPainter extends PdeTextAreaPainter { public JavaTextAreaPainter(final JavaTextArea textArea, TextAreaDefaults defaults) { super(textArea, defaults); - // Handle mouse clicks to toggle breakpoints - addMouseListener(new MouseAdapter() { - long lastTime; // OS X seems to be firing multiple mouse events - - public void mousePressed(MouseEvent event) { - JavaEditor javaEditor = getJavaEditor(); - // Don't toggle breakpoints when the debugger isn't enabled - // https://github.com/processing/processing/issues/3306 - if (javaEditor.isDebuggerEnabled()) { - long thisTime = event.getWhen(); - if (thisTime - lastTime > 100) { - if (event.getX() < Editor.LEFT_GUTTER) { - int offset = getJavaTextArea().xyToOffset(event.getX(), event.getY()); - if (offset >= 0) { - int lineIndex = getJavaTextArea().getLineOfOffset(offset); - javaEditor.toggleBreakpoint(lineIndex); - } - } - lastTime = thisTime; - } - } - } - }); - // TweakMode code tweakMode = false; cursorType = Cursor.DEFAULT_CURSOR; @@ -349,23 +310,6 @@ public class JavaTextAreaPainter extends TextAreaPainter } - /** - * Loads theme for TextAreaPainter(XQMode) - */ - public void setMode(Mode mode) { - errorUnderlineColor = mode.getColor("editor.error.underline.color"); - warningUnderlineColor = mode.getColor("editor.warning.underline.color"); - - gutterTextFont = mode.getFont("editor.gutter.text.font"); - gutterTextColor = mode.getColor("editor.gutter.text.color"); - gutterPastColor = new Color(gutterTextColor.getRed(), - gutterTextColor.getGreen(), - gutterTextColor.getBlue(), - 96); - gutterLineHighlightColor = mode.getColor("editor.gutter.linehighlight.color"); - } - - @Override public String getToolTipText(MouseEvent evt) { int line = evt.getY() / getFontMetrics().getHeight() + textArea.getFirstLine(); @@ -385,9 +329,7 @@ public class JavaTextAreaPainter extends TextAreaPainter if (x >= getJavaTextArea().offsetToX(line, startOffset) && x <= getJavaTextArea().offsetToX(line, stopOffset)) { - getJavaEditor().statusToolTip(JavaTextAreaPainter.this, - problem.getMessage(), - problem.isError()); + getEditor().statusToolTip(this, problem.getMessage(), problem.isError()); return super.getToolTipText(evt); } } @@ -455,8 +397,93 @@ public class JavaTextAreaPainter extends TextAreaPainter protected void startTweakMode() { - addMouseListener(this); - addMouseMotionListener(this); + addMouseListener(new MouseListener() { + + @Override + public void mouseReleased(MouseEvent e) { + if (mouseHandle != null) { + mouseHandle.resetProgress(); + mouseHandle = null; + + updateCursor(e.getX(), e.getY()); + repaint(); + } + } + + @Override + public void mousePressed(MouseEvent e) { + int currentTab = getCurrentCodeIndex(); + // check for clicks on number handles + for (Handle n : handles.get(currentTab)) { + if (n.pick(e.getX(), e.getY())) { + cursorType = -1; + JavaTextAreaPainter.this.setCursor(blankCursor); + mouseHandle = n; + mouseHandle.setCenterX(e.getX()); + repaint(); + return; + } + } + + // check for clicks on color boxes + for (ColorControlBox box : colorBoxes.get(currentTab)) { + if (box.pick(e.getX(), e.getY())) { + if (colorSelector != null) { + // we already show a color selector, close it + colorSelector.frame.dispatchEvent(new WindowEvent(colorSelector.frame, WindowEvent.WINDOW_CLOSING)); + } + + colorSelector = new ColorSelector(box); + colorSelector.frame.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + colorSelector.frame.setVisible(false); + colorSelector = null; + } + }); + colorSelector.show(getLocationOnScreen().x + e.getX() + 30, + getLocationOnScreen().y + e.getY() - 130); + } + } + } + + @Override + public void mouseExited(MouseEvent e) { } + + @Override + public void mouseEntered(MouseEvent e) { } + + @Override + public void mouseClicked(MouseEvent e) { } + }); + + addMouseMotionListener(new MouseMotionListener() { + + @Override + public void mouseMoved(MouseEvent e) { + updateCursor(e.getX(), e.getY()); + + if (!Settings.alwaysShowColorBoxes) { + showHideColorBoxes(e.getY()); + } + } + + @Override + public void mouseDragged(MouseEvent e) { + if (mouseHandle != null) { + // set the current drag amount of the arrows + mouseHandle.setCurrentX(e.getX()); + + // update code text with the new value + updateCodeText(); + + if (colorSelector != null) { + colorSelector.refreshColor(); + } + + repaint(); + } + } + }); tweakMode = true; setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); repaint(); @@ -613,126 +640,20 @@ public class JavaTextAreaPainter extends TextAreaPainter } - @Override - public void mouseDragged(MouseEvent e) { - if (mouseHandle != null) { - // set the current drag amount of the arrows - mouseHandle.setCurrentX(e.getX()); - - // update code text with the new value - updateCodeText(); - - if (colorSelector != null) { - colorSelector.refreshColor(); - } - - repaint(); - } - } - - - @Override - public void mouseExited(MouseEvent e) { - } - - - @Override - public void mousePressed(MouseEvent e) { - int currentTab = getCurrentCodeIndex(); - // check for clicks on number handles - for (Handle n : handles.get(currentTab)) { - if (n.pick(e.getX(), e.getY())) { - cursorType = -1; - this.setCursor(blankCursor); - mouseHandle = n; - mouseHandle.setCenterX(e.getX()); - repaint(); - return; - } - } - - // check for clicks on color boxes - for (ColorControlBox box : colorBoxes.get(currentTab)) { - if (box.pick(e.getX(), e.getY())) { - if (colorSelector != null) { - // we already show a color selector, close it - colorSelector.frame.dispatchEvent(new WindowEvent(colorSelector.frame, WindowEvent.WINDOW_CLOSING)); - } - - colorSelector = new ColorSelector(box); - colorSelector.frame.addWindowListener(new WindowAdapter() { - public void windowClosing(WindowEvent e) { - colorSelector.frame.setVisible(false); - colorSelector = null; - } - }); - colorSelector.show(getLocationOnScreen().x + e.getX() + 30, - getLocationOnScreen().y + e.getY() - 130); - } - } - } - - - @Override - public void mouseReleased(MouseEvent e) { - if (mouseHandle != null) { - mouseHandle.resetProgress(); - mouseHandle = null; - - updateCursor(e.getX(), e.getY()); - repaint(); - } - } - - - @Override - public void mouseMoved(MouseEvent e) { - updateCursor(e.getX(), e.getY()); - - if (!Settings.alwaysShowColorBoxes) { - showHideColorBoxes(e.getY()); - } - } - - - @Override - public void mouseClicked(MouseEvent e) { - // TODO Auto-generated method stub - } - - - @Override - public void mouseEntered(MouseEvent e) { - // TODO Auto-generated method stub - } - - // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - @Override - public int getScrollWidth() { - // https://github.com/processing/processing/issues/3591 - return super.getWidth() - Editor.LEFT_GUTTER; - } - - - public Editor getEditor() { - return ((JavaTextArea) textArea).editor; - } - - private JavaEditor getJavaEditor() { - return ((JavaTextArea) textArea).editor; + return (JavaEditor) getEditor(); } - private int getCurrentCodeIndex() { - return getEditor().getSketch().getCurrentCodeIndex(); - } - - private JavaTextArea getJavaTextArea() { return (JavaTextArea) textArea; } + + + private int getCurrentCodeIndex() { + return getEditor().getSketch().getCurrentCodeIndex(); + } } diff --git a/todo.txt b/todo.txt index ced871853..3aca8844e 100644 --- a/todo.txt +++ b/todo.txt @@ -1,4 +1,4 @@ -0252 (3.1.3?) +0252 (3.2) X change PdeInputHandler constructor _ check whether this breaks other Modes before releasing _ modify line number color when no lines extend that far? @@ -11,6 +11,9 @@ _ https://github.com/processing/processing/pull/4593 _ Processing .jar files in CLASSPATH can cause startup crash _ https://github.com/processing/processing/issues/4128 +_ Help Menu disabled on OS X +_ https://github.com/processing/processing/issues/43503#issuecomment-237715947 + contrib input method work @@ -45,6 +48,10 @@ _ https://github.com/processing/processing/issues/3948 _ possible infinite loop on modified externally _ https://github.com/processing/processing/issues/3965 +medium +_ Move general PDE code out of JavaMode and into general base classes +_ https://github.com/processing/processing/issues/4606 + lower _ make when opening new editor window, open on the same display as current _ https://github.com/processing/processing/issues/4526 @@ -110,6 +117,8 @@ _ mouse events (i.e. toggle breakpoint) seem to be firing twice run/debug _ Tweak Mode sometimes freezes while running, require a force quit _ https://github.com/processing/processing/issues/3928 +_ TweakMode listener mess in JavaTextArea +_ https://github.com/processing/processing/issues/4605 gui