Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 6 additions & 19 deletions .github/workflows/input-validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,24 +82,6 @@ jobs:
id: setup_hash
run: echo "hash=$(shasum -a 256 scripts/setup-workspace.sh | awk '{print $1}')" >> "$GITHUB_OUTPUT"

- name: Compute CN1 source hash
id: src_hash
run: |
set -euo pipefail
SRC_HASH=$(find CodenameOne/src Ports/iOSPort vm/JavaAPI vm/ByteCodeTranslator Themes native-themes \
maven/codenameone-maven-plugin/src/main \
-type f \( -name '*.java' -o -name '*.m' -o -name '*.h' -o -name '*.xml' -o -name '*.properties' -o -name '*.css' \) 2>/dev/null \
| sort | xargs shasum -a 256 | shasum -a 256 | awk '{print $1}')
POM_HASH=$(find . -name 'pom.xml' -not -path './scripts/*' 2>/dev/null \
| sort | xargs shasum -a 256 | shasum -a 256 | awk '{print $1}')
SCRIPT_HASH=$(shasum -a 256 \
scripts/setup-workspace.sh \
scripts/build-ios-port.sh \
scripts/build-native-themes.sh \
.github/workflows/_build-ios-port.yml \
| shasum -a 256 | awk '{print $1}')
echo "hash=${SRC_HASH:0:16}-${POM_HASH:0:16}-${SCRIPT_HASH:0:16}" >> "$GITHUB_OUTPUT"

- name: Set TMPDIR
run: echo "TMPDIR=${{ runner.temp }}" >> $GITHUB_ENV

Expand Down Expand Up @@ -128,13 +110,18 @@ jobs:
cn1-binaries-${{ runner.os }}-

- name: Restore built CN1 + iOS port artifacts
# Reuse the exact cache key the build-port job saved against. Locally
# recomputing the hash here has drifted out of sync with
# _build-ios-port.yml before (e.g. svg-transcoder/src/main added on
# one side only), causing a permanent cache miss for any PR that
# touches a file matching this workflow's paths filter.
uses: actions/cache/restore@v4
with:
path: |
~/.m2/repository/com/codenameone
Themes
Ports/iOSPort/nativeSources
key: cn1-built-${{ runner.os }}-${{ steps.src_hash.outputs.hash }}
key: ${{ needs.build-port.outputs.cn1_built_cache_key }}
fail-on-cache-miss: true

- name: Install XcodeGen
Expand Down
12 changes: 12 additions & 0 deletions CodenameOne/src/com/codename1/impl/CodenameOneImplementation.java
Original file line number Diff line number Diff line change
Expand Up @@ -1963,6 +1963,18 @@ public void popClip(Object graphics) {

}

/// Marks the start of a user-overrideable paint scope (e.g. `Component.paint`,
/// `Component.paintBackground`, `Painter.paint`, glass pane). Ports may use this
/// to snapshot graphics state and validate that the scope leaves it unchanged.
/// Default is a no-op so device ports pay zero cost.
public void beginPaintScope(Object graphics, Object owner) {
}

/// Marks the end of a paint scope opened by `#beginPaintScope`. Must be paired
/// with a `beginPaintScope` call on the same graphics with the same owner.
public void endPaintScope(Object graphics, Object owner) {
}

/// Draws a line between the 2 X/Y coordinates
///
/// #### Parameters
Expand Down
57 changes: 49 additions & 8 deletions CodenameOne/src/com/codename1/ui/Component.java
Original file line number Diff line number Diff line change
Expand Up @@ -3001,13 +3001,23 @@ void internalPaintImpl(Graphics g, boolean paintIntersects) {
int scrollX = getScrollX();
int scrollY = getScrollY();
g.translate(-scrollX, -scrollY);
paint(g);
Display.impl.beginPaintScope(g.getGraphics(), this);
try {
paint(g);
} finally {
Display.impl.endPaintScope(g.getGraphics(), this);
}
g.translate(scrollX, scrollY);
if (isScrollVisible) {
paintScrollbars(g);
}
} else {
paint(g);
Display.impl.beginPaintScope(g.getGraphics(), this);
try {
paint(g);
} finally {
Display.impl.endPaintScope(g.getGraphics(), this);
}
}
if (isBorderPainted()) {
paintBorder(g);
Expand Down Expand Up @@ -3395,9 +3405,19 @@ private void drawPaintersImpl(Graphics g, Component par, Component c,
rect.getSize().setWidth(par.getWidth());
rect.getSize().setHeight(par.getHeight());
}
p.paint(g, rect);
Display.impl.beginPaintScope(g.getGraphics(), p);
try {
p.paint(g, rect);
} finally {
Display.impl.endPaintScope(g.getGraphics(), p);
}
}
Display.impl.beginPaintScope(g.getGraphics(), par);
try {
par.paintBackground(g);
} finally {
Display.impl.endPaintScope(g.getGraphics(), par);
}
par.paintBackground(g);
((Container) par).paintIntersecting(g, c, x, y, w, h, false, 0);
g.translate(-transX, -transY);
}
Expand Down Expand Up @@ -3469,9 +3489,20 @@ private void paintBackgroundImpl(Graphics g) {
}
}
if (getStyle().getBgPainter() != null) {
getStyle().getBgPainter().paint(g, bounds);
Painter bp = getStyle().getBgPainter();
Display.impl.beginPaintScope(g.getGraphics(), bp);
try {
bp.paint(g, bounds);
} finally {
Display.impl.endPaintScope(g.getGraphics(), bp);
}
}
Display.impl.beginPaintScope(g.getGraphics(), this);
try {
paintBackground(g);
} finally {
Display.impl.endPaintScope(g.getGraphics(), this);
}
paintBackground(g);
paintRippleEffect(g);
}

Expand Down Expand Up @@ -5086,7 +5117,12 @@ protected Image getDragImage() {

g.translate(-getX(), -getY());
paintComponentBackground(g);
paint(g);
Display.impl.beginPaintScope(g.getGraphics(), this);
try {
paint(g);
} finally {
Display.impl.endPaintScope(g.getGraphics(), this);
}
if (isBorderPainted()) {
paintBorder(g);
}
Expand Down Expand Up @@ -5132,7 +5168,12 @@ public Image toImage() {

g.translate(-getX(), -getY());
paintComponentBackground(g);
paint(g);
Display.impl.beginPaintScope(g.getGraphics(), this);
try {
paint(g);
} finally {
Display.impl.endPaintScope(g.getGraphics(), this);
}
if (isBorderPainted()) {
paintBorder(g);
}
Expand Down
14 changes: 12 additions & 2 deletions CodenameOne/src/com/codename1/ui/Form.java
Original file line number Diff line number Diff line change
Expand Up @@ -1123,10 +1123,20 @@ void paintGlassImpl(Graphics g) {
int tx = g.getTranslateX();
int ty = g.getTranslateY();
g.translate(-tx, -ty);
glassPane.paint(g, getBounds());
Display.impl.beginPaintScope(g.getGraphics(), glassPane);
try {
glassPane.paint(g, getBounds());
} finally {
Display.impl.endPaintScope(g.getGraphics(), glassPane);
}
g.translate(tx, ty);
}
paintGlass(g);
Display.impl.beginPaintScope(g.getGraphics(), this);
try {
paintGlass(g);
} finally {
Display.impl.endPaintScope(g.getGraphics(), this);
}
if (dragged != null && dragged.isDragAndDropInitialized()) {
int[] c = g.getClip();
g.setClip(0, 0, getWidth(), getHeight());
Expand Down
Loading
Loading