From f67964573ded23b1eb798acf5a28ee05b1c3af16 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Thu, 5 Mar 2026 20:03:42 +0200 Subject: [PATCH 1/2] Coalesce queued size change events on EDT --- CodenameOne/src/com/codename1/ui/Display.java | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/CodenameOne/src/com/codename1/ui/Display.java b/CodenameOne/src/com/codename1/ui/Display.java index 0db43b6555..be554957ec 100644 --- a/CodenameOne/src/com/codename1/ui/Display.java +++ b/CodenameOne/src/com/codename1/ui/Display.java @@ -309,6 +309,7 @@ public final class Display extends CN1Constants { private int previousKeyPressed; private int lastKeyPressed; private int lastDragOffset; + private int lastSizeChangeOffset = -1; // huge false positive from PMD... @SuppressWarnings("PMD.SingularField") @@ -1139,6 +1140,7 @@ void edtLoopImpl() { inputEventStackPointerTmp = inputEventStackPointer; inputEventStackPointer = 0; lastDragOffset = -1; + lastSizeChangeOffset = -1; int[] qt = inputEventStackTmp; inputEventStackTmp = inputEventStack; @@ -2118,12 +2120,23 @@ public void pointerReleased(final int[] x, final int[] y) { private void addSizeChangeEvent(int type, int w, int h) { synchronized (lock) { - inputEventStack[inputEventStackPointer] = type; - inputEventStackPointer++; - inputEventStack[inputEventStackPointer] = w; - inputEventStackPointer++; - inputEventStack[inputEventStackPointer] = h; - inputEventStackPointer++; + try { + if (lastSizeChangeOffset > -1) { + inputEventStack[lastSizeChangeOffset] = w; + inputEventStack[lastSizeChangeOffset + 1] = h; + } else { + inputEventStack[inputEventStackPointer] = type; + inputEventStackPointer++; + lastSizeChangeOffset = inputEventStackPointer; + inputEventStack[inputEventStackPointer] = w; + inputEventStackPointer++; + inputEventStack[inputEventStackPointer] = h; + inputEventStackPointer++; + } + } catch (ArrayIndexOutOfBoundsException err) { + Log.p("EDT performance is very slow triggering this exception!"); + Log.e(err); + } lock.notifyAll(); } } From 8996947a16d5b89554b3009781d92e305e8bf5ad Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Thu, 5 Mar 2026 21:03:50 +0200 Subject: [PATCH 2/2] Debounce JavaSE resize notifications without changing Display queue --- CodenameOne/src/com/codename1/ui/Display.java | 25 +--- .../com/codename1/impl/javase/JavaSEPort.java | 122 ++++++++++++------ 2 files changed, 86 insertions(+), 61 deletions(-) diff --git a/CodenameOne/src/com/codename1/ui/Display.java b/CodenameOne/src/com/codename1/ui/Display.java index be554957ec..0db43b6555 100644 --- a/CodenameOne/src/com/codename1/ui/Display.java +++ b/CodenameOne/src/com/codename1/ui/Display.java @@ -309,7 +309,6 @@ public final class Display extends CN1Constants { private int previousKeyPressed; private int lastKeyPressed; private int lastDragOffset; - private int lastSizeChangeOffset = -1; // huge false positive from PMD... @SuppressWarnings("PMD.SingularField") @@ -1140,7 +1139,6 @@ void edtLoopImpl() { inputEventStackPointerTmp = inputEventStackPointer; inputEventStackPointer = 0; lastDragOffset = -1; - lastSizeChangeOffset = -1; int[] qt = inputEventStackTmp; inputEventStackTmp = inputEventStack; @@ -2120,23 +2118,12 @@ public void pointerReleased(final int[] x, final int[] y) { private void addSizeChangeEvent(int type, int w, int h) { synchronized (lock) { - try { - if (lastSizeChangeOffset > -1) { - inputEventStack[lastSizeChangeOffset] = w; - inputEventStack[lastSizeChangeOffset + 1] = h; - } else { - inputEventStack[inputEventStackPointer] = type; - inputEventStackPointer++; - lastSizeChangeOffset = inputEventStackPointer; - inputEventStack[inputEventStackPointer] = w; - inputEventStackPointer++; - inputEventStack[inputEventStackPointer] = h; - inputEventStackPointer++; - } - } catch (ArrayIndexOutOfBoundsException err) { - Log.p("EDT performance is very slow triggering this exception!"); - Log.e(err); - } + inputEventStack[inputEventStackPointer] = type; + inputEventStackPointer++; + inputEventStack[inputEventStackPointer] = w; + inputEventStackPointer++; + inputEventStack[inputEventStackPointer] = h; + inputEventStackPointer++; lock.notifyAll(); } } diff --git a/Ports/JavaSE/src/com/codename1/impl/javase/JavaSEPort.java b/Ports/JavaSE/src/com/codename1/impl/javase/JavaSEPort.java index 5400f1198f..99ab29c517 100644 --- a/Ports/JavaSE/src/com/codename1/impl/javase/JavaSEPort.java +++ b/Ports/JavaSE/src/com/codename1/impl/javase/JavaSEPort.java @@ -2075,6 +2075,83 @@ private boolean isPinchZoom(MouseEvent e) { private Cursor defaultCursor = Cursor.getDefaultCursor(); private int currentCursor = 0; private java.util.Timer reSize; + private final Object pendingSizeChangeLock = new Object(); + private int pendingSizeChangeWidth = -1; + private int pendingSizeChangeHeight = -1; + private boolean pendingSizeChangeQueued; + private boolean pendingRevalidateAfterSizeChange; + private boolean pendingForceRevalidateAfterSizeChange; + private boolean pendingResetGraphicsAfterSizeChange; + private boolean pendingDelayedWindowRepaint; + + private void queueSizeChangeEvent(int w, int h, boolean revalidate, boolean forceRevalidate, boolean resetGraphics, boolean delayedWindowRepaint) { + synchronized (pendingSizeChangeLock) { + pendingSizeChangeWidth = w; + pendingSizeChangeHeight = h; + pendingRevalidateAfterSizeChange |= revalidate; + pendingForceRevalidateAfterSizeChange |= forceRevalidate; + pendingResetGraphicsAfterSizeChange |= resetGraphics; + pendingDelayedWindowRepaint |= delayedWindowRepaint; + if (pendingSizeChangeQueued) { + return; + } + pendingSizeChangeQueued = true; + } + Display.getInstance().callSerially(new Runnable() { + public void run() { + int queuedW; + int queuedH; + boolean doRevalidate; + boolean doForceRevalidate; + boolean doResetGraphics; + boolean doDelayedWindowRepaint; + synchronized (pendingSizeChangeLock) { + queuedW = pendingSizeChangeWidth; + queuedH = pendingSizeChangeHeight; + doRevalidate = pendingRevalidateAfterSizeChange; + doForceRevalidate = pendingForceRevalidateAfterSizeChange; + doResetGraphics = pendingResetGraphicsAfterSizeChange; + doDelayedWindowRepaint = pendingDelayedWindowRepaint; + pendingRevalidateAfterSizeChange = false; + pendingForceRevalidateAfterSizeChange = false; + pendingResetGraphicsAfterSizeChange = false; + pendingDelayedWindowRepaint = false; + pendingSizeChangeQueued = false; + } + + JavaSEPort.this.sizeChanged(queuedW, queuedH); + + if (doResetGraphics) { + g2dInstance = null; + } + + Form f = Display.getInstance().getCurrent(); + if (f != null) { + if (doForceRevalidate) { + f.forceRevalidate(); + } else if (doRevalidate) { + f.revalidate(); + } + } + + if (doDelayedWindowRepaint) { + new Thread(new Runnable() { + @Override + public void run() { + try { + Thread.sleep(1500); + } catch (Exception e) { + } + if (window != null) { + window.repaint(); + } + } + }).start(); + reSize = null; + } + } + }); + } public void mouseMoved(MouseEvent e) { e.consume(); @@ -2138,11 +2215,7 @@ public void setBounds(int x, int y, int w, int h) { Preferences pref = Preferences.userNodeForPackage(JavaSEPort.class); boolean desktopSkin = pref.getBoolean("desktopSkin", false); if (getSkin() == null && !desktopSkin) { - Display.getInstance().callSerially(new Runnable() { - public void run() { - JavaSEPort.this.sizeChanged((int)(getWidth() * retinaScale), (int)(getHeight() * retinaScale)); - } - }); + queueSizeChangeEvent((int)(getWidth() * retinaScale), (int)(getHeight() * retinaScale), false, false, false, false); } } @@ -2186,17 +2259,7 @@ public void run() { setSize((int)topSize.getWidth(), (int)topSize.getHeight()); canvas.setForcedSize(new Dimension(getWidth(), getHeight())); - Display.getInstance().callSerially(new Runnable() { - public void run() { - - JavaSEPort.this.sizeChanged((int)(getWidth() * retinaScale), (int)(getHeight() * retinaScale)); - - Form f = Display.getInstance().getCurrent(); - if (f != null) { - f.revalidate(); - } - } - }); + queueSizeChangeEvent((int)(getWidth() * retinaScale), (int)(getHeight() * retinaScale), true, false, false, false); return; } @@ -2214,32 +2277,7 @@ public void run() { // System.out.println("Resize with media container"); // JavaSEPort.this.sizeChanged((int)(mediaContainer.getWidth() * retinaScale), (int)(mediaContainer.getHeight() * retinaScale)); //}else{ - Display.getInstance().callSerially(new Runnable() { - public void run() { - JavaSEPort.this.sizeChanged((int)(getWidth() * retinaScale), (int)(getHeight() * retinaScale)); - g2dInstance = null; - Form f = Display.getInstance().getCurrent(); - if (f != null) { - f.forceRevalidate(); - } - - // probably not necessary - new Thread(new Runnable() { - @Override - public void run() { - try { - Thread.sleep(1500); - } catch (Exception e) { - } - if (window != null) { - window.repaint(); - } - } - }).start(); - - reSize = null; - } - }); + queueSizeChangeEvent((int)(getWidth() * retinaScale), (int)(getHeight() * retinaScale), false, true, true, true); //}