# Native window access and inset handling in Processing JAVA2D and P2D

**URL:** <https://discourse.processing.org/t/native-window-access-and-inset-handling-in-processing-java2d-and-p2d/48437>\
**Category:** Gallery\
**Created:** [April 14, 2026, 7:21pm UTC](https://discourse.processing.org/t/native-window-access-and-inset-handling-in-processing-java2d-and-p2d/48437 "2026-04-14T19:21:49Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [April 14, 2026, 7:21pm UTC](https://discourse.processing.org/t/native-window-access-and-inset-handling-in-processing-java2d-and-p2d/48437/1 "2026-04-14T19:21:49Z")

</div>

Hello folks!

This is an exploration of native window access in P2D/P3D and JAVA2D.  
In my Windows 10 environment, I was seeing offsets, and I was compelled to understand why.

And now I do!

This is an advanced topic and Chat GPT was used to support this research.

> **P2D Code**
>
> ```processing
> // Author: GLV
> // Date: 2026-04-14
> // ChatGPT supported.
> 
> // Description: 
> // This is an exploration of native window access in P2D/P3D, 
> // where the underlying GLWindow lets us read the window insets.
> 
> // This is displayed in console:
> // The sketch has been resized from 1920x1200 to 1920x1181 by the operating system.
> // This happened outside Processing, and may be a limitation of the OS or window manager.
> 
> import com.jogamp.newt.opengl.GLWindow;
> 
> void settings()
> {
> int w = displayWidth; 
> int h = displayHeight;
>     
> size(w, h, P2D); // or P3D
> }
> 
> void setup()
> {
> GLWindow glw = (GLWindow) surface.getNative();
>   
> int left = glw.getInsets().getLeftWidth();
> int right = glw.getInsets().getRightWidth();
> int top = glw.getInsets().getTopHeight();
> int bottom = glw.getInsets().getBottomHeight();
> println("Insets L/T/R/B = " + left + " / " + top + " / " + right + " / " + bottom);  
>   
> // Give these a try:
> //surface.setVisible(true); // Show (true) or hide (false) the window
> //surface.setLocation(0, 0); // Set desired window position (0, 0); frame insets will shift the sketch area.
> //surface.setLocation(-in.left, 0); // Offsets the left frame border so the sketch area starts at the desired position.
> //surface.setResizable(true); // Lets the window be resized or maximized
> }
> 
> void draw()
> {
> fill(random(64, 128+64));  
> circle(random(width), random(height), 20);    
> }
> 
> ```

> **JAVA2D Code**
>
> ```processing
> 
> // Author: GLV
> // Date: 2026-04-14
> // ChatGPT support
> 
> // Description: 
> // This is an exploration of native window access in JAVA2D, 
> // where the underlying AWT Frame lets us read the window insets.
> 
> import processing.awt.PSurfaceAWT;
> import java.awt.Insets;
> 
> void settings()
> {
> int w = displayWidth; 
> int h = displayHeight;
> println(w, h);
>     
> size(w, h, JAVA2D);
> }
> 
> void setup()
> {
> PSurfaceAWT.SmoothCanvas canvas = (PSurfaceAWT.SmoothCanvas) surface.getNative();
> Insets in = canvas.getFrame().getInsets();
>   
> println("Insets L/T/R/B = " + in.left + " / " + in.top + " / " + in.right + " / " + in.bottom);  
> 
> // Give these a try:
> //surface.setVisible(true); // Show (true) or hide (false) the window
> //surface.setLocation(0, 0); // Set desired window position (0, 0); frame insets will shift the sketch area.
> //surface.setLocation(-in.left, 0); // Offsets the left frame border so the sketch area starts at the desired position.
> //surface.setResizable(true); // Lets the window be resized or maximized
> }
> 
> void draw()
> {
> fill(random(64, 128+64));  
> circle(random(width), random(height), 20);    
> }
> 
> ```

Insets:

`Insets L/T/R/B = 8 / 31 / 8 / 8`

There is more going on here than just Java calling `getInsets()`. On my Windows system, the returned inset values also line up exactly with the Win32 metrics documented here:

> **[GetSystemMetrics function (winuser.h) - Win32 apps](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getsystemmetrics)**
>
> Retrieves the specified system metric or system configuration setting.

A lot of details sit between those layers.  
This was certainly an adventure.

I will post an update later… and now is later and I added to post below.

That was fun!

ChatGPT research:

> **Summary**
>
> For transparency:  
> ChatGPT supported my research, analysis, wording, and drafting of this test, while the direction, review, and interpretation were guided by me.  
> It is subject to scrutiny and I have not included the 800+ word research which includes references.  
> This was not a simple task and took a lot of iterations to get to this point.
> 
> > This test compares `Frame.getInsets()` in `setup()` and again in the first `draw()`, then compares both results to the corresponding Win32 metrics returned by `GetSystemMetrics()`. The goal is to check whether the inset values remain stable across both phases and whether they line up with the Windows frame, caption, and padded-border metrics. The output shows the actual Java/AWT inset values, the raw Windows metric values, the derived inset math, and whether the results match. It does not determine which internal AWT path produced the values, only whether the final values agree.
> 
> ```processing
> import processing.awt.PSurfaceAWT;
> import java.awt.Insets;
> import java.awt.Frame;
> import com.sun.jna.platform.win32.User32;
> 
> Insets inSetup;
> boolean reportedInDraw = false;
> 
> void settings()
> {
> size(600, 400, JAVA2D);
> }
> 
> void setup()
> {
> Frame frame = getFrameRef();
> inSetup = frame.getInsets();
> 
> printInsetReport("setup()", inSetup);
> }
> 
> void draw()
> {
> background(240);
> 
> if(reportedInDraw) return;
> 
> Frame frame = getFrameRef();
> Insets inDraw = frame.getInsets();
> 
> printInsetReport("first draw()", inDraw);
> 
> println();
> println("setup() vs first draw() match = " +
> (inSetup.left == inDraw.left &&
> inSetup.top == inDraw.top &&
> inSetup.right == inDraw.right &&
> inSetup.bottom == inDraw.bottom));
> 
> reportedInDraw = true;
> noLoop();
> }
> 
> Frame getFrameRef()
> {
> PSurfaceAWT.SmoothCanvas canvas = (PSurfaceAWT.SmoothCanvas) surface.getNative();
> return canvas.getFrame();
> }
> 
> void printInsetReport(String label, Insets in)
> {
> int cxFrame = User32.INSTANCE.GetSystemMetrics(32); // SM_CXFRAME
> int cyFrame = User32.INSTANCE.GetSystemMetrics(33); // SM_CYFRAME
> int cyCaption = User32.INSTANCE.GetSystemMetrics(4); // SM_CYCAPTION
> int cxPadded = User32.INSTANCE.GetSystemMetrics(92); // SM_CXPADDEDBORDER
> 
> int leftFromMetrics = cxFrame + cxPadded;
> int topFromMetrics = cyFrame + cxPadded + cyCaption;
> int rightFromMetrics = cxFrame + cxPadded;
> int bottomFromMetrics = cyFrame + cxPadded;
> 
> println();
> println("=== " + label + " ===");
> println("Actual Insets L/T/R/B = " + in.left + " / " + in.top + " / " + in.right + " / " + in.bottom);
> println();
> 
> println("Raw Windows metrics:");
> println("SM_CXFRAME = " + cxFrame);
> println("SM_CYFRAME = " + cyFrame);
> println("SM_CYCAPTION = " + cyCaption);
> println("SM_CXPADDEDBORDER = " + cxPadded);
> println();
> 
> println("Derived inset math:");
> println("left = SM_CXFRAME + SM_CXPADDEDBORDER = " + cxFrame + " + " + cxPadded + " = " + leftFromMetrics);
> println("top = SM_CYFRAME + SM_CXPADDEDBORDER + SM_CYCAPTION = " + cyFrame + " + " + cxPadded + " + " + cyCaption + " = " + topFromMetrics);
> println("right = SM_CXFRAME + SM_CXPADDEDBORDER = " + cxFrame + " + " + cxPadded + " = " + rightFromMetrics);
> println("bottom = SM_CYFRAME + SM_CXPADDEDBORDER = " + cyFrame + " + " + cxPadded + " = " + bottomFromMetrics);
> println();
> 
> println("Derived Insets L/T/R/B = " + leftFromMetrics + " / " + topFromMetrics + " / " + rightFromMetrics + " / " + bottomFromMetrics);
> 
> println("Metric match = " +
> (in.left == leftFromMetrics &&
> in.top == topFromMetrics &&
> in.right == rightFromMetrics &&
> in.bottom == bottomFromMetrics));
> }
> 
> ```
> 
> Console output on y W10 PC:
> 
> > 0 launchVirtualMachine()  
> > Free port allocated: 52159  
> > freePort: 52159  
> > Sketch runner port: 52159
> > 
> > === setup() ===  
> > Actual Insets L/T/R/B = 8 / 31 / 8 / 8
> > 
> > Raw Windows metrics:  
> > SM\_CXFRAME = 4  
> > SM\_CYFRAME = 4  
> > SM\_CYCAPTION = 23  
> > SM\_CXPADDEDBORDER = 4
> > 
> > Derived inset math:  
> > left = SM\_CXFRAME + SM\_CXPADDEDBORDER = 4 + 4 = 8  
> > top = SM\_CYFRAME + SM\_CXPADDEDBORDER + SM\_CYCAPTION = 4 + 4 + 23 = 31  
> > right = SM\_CXFRAME + SM\_CXPADDEDBORDER = 4 + 4 = 8  
> > bottom = SM\_CYFRAME + SM\_CXPADDEDBORDER = 4 + 4 = 8
> > 
> > Derived Insets L/T/R/B = 8 / 31 / 8 / 8  
> > Metric match = true
> > 
> > === first draw() ===  
> > Actual Insets L/T/R/B = 8 / 31 / 8 / 8
> > 
> > Raw Windows metrics:  
> > SM\_CXFRAME = 4  
> > SM\_CYFRAME = 4  
> > SM\_CYCAPTION = 23  
> > SM\_CXPADDEDBORDER = 4
> > 
> > Derived inset math:  
> > left = SM\_CXFRAME + SM\_CXPADDEDBORDER = 4 + 4 = 8  
> > top = SM\_CYFRAME + SM\_CXPADDEDBORDER + SM\_CYCAPTION = 4 + 4 + 23 = 31  
> > right = SM\_CXFRAME + SM\_CXPADDEDBORDER = 4 + 4 = 8  
> > bottom = SM\_CYFRAME + SM\_CXPADDEDBORDER = 4 + 4 = 8
> > 
> > Derived Insets L/T/R/B = 8 / 31 / 8 / 8  
> > Metric match = true
> > 
> > setup() vs first draw() match = true
> 
> The first part was a modified Processing to assign a free port.

`:)`
