7676import java .util .Objects ;
7777import java .util .function .Supplier ;
7878
79+ import static sun .awt .wl .WLGraphicsConfig .SCALE120 ;
80+
7981public class WLComponentPeer implements ComponentPeer {
8082 private static final PlatformLogger log = PlatformLogger .getLogger ("sun.awt.wl.WLComponentPeer" );
8183 private static final PlatformLogger focusLog = PlatformLogger .getLogger ("sun.awt.wl.focus.WLComponentPeer" );
@@ -119,9 +121,12 @@ public class WLComponentPeer implements ComponentPeer {
119121 boolean visible = false ;
120122
121123 private final Object dataLock = new Object ();
122- int width ; // in native pixels, protected by dataLock
123- int height ; // in native pixels, protected by dataLock
124- int wlBufferScale ; // protected by dataLock
124+ int javaWidth ; // in java coordinates, protected by dataLock
125+ int javaHeight ; // in java coordinates, protected by dataLock
126+ int surfaceWidth ; // in surface coordinates, protected by dataLock
127+ int surfaceHeight ; // in surface coordinates, protected by dataLock
128+ long scale120 ; // protected by dataLock
129+ Long preferredScale120 = null ; // protected by dataLock
125130 double effectiveScale ; // protected by dataLock
126131
127132 static {
@@ -135,31 +140,33 @@ public class WLComponentPeer implements ComponentPeer {
135140 this .target = target ;
136141 this .background = target .getBackground ();
137142 Dimension size = constrainSize (target .getBounds ().getSize ());
138- width = size .width ;
139- height = size .height ;
143+ javaWidth = size .width ;
144+ javaHeight = size .height ;
140145 final WLGraphicsConfig config = (WLGraphicsConfig )target .getGraphicsConfiguration ();
141- wlBufferScale = config .getWlScale ();
146+ scale120 = config .getWlScale120 ();
142147 effectiveScale = config .getEffectiveScale ();
143148 surfaceData = config .createSurfaceData (this );
144149 nativePtr = nativeCreateFrame ();
145150 paintArea = new WLRepaintArea ();
151+ surfaceWidth = Math .max (javaUnitsToSurfaceUnits (javaWidth ), 1 );
152+ surfaceHeight = Math .max (javaUnitsToSurfaceUnits (javaHeight ), 1 );
146153
147154 if (log .isLoggable (Level .FINE )) {
148- log .fine ("WLComponentPeer: target=" + target + " with size=" + width + "x" + height );
155+ log .fine ("WLComponentPeer: target=" + target + " with size=" + javaWidth + "x" + javaHeight );
149156 }
150157 // TODO
151158 // setup parent window for target
152159 }
153160
154- public int getWidth () {
161+ public int getJavaWidth () {
155162 synchronized (dataLock ) {
156- return width ;
163+ return javaWidth ;
157164 }
158165 }
159166
160- public int getHeight () {
167+ public int getJavaHeight () {
161168 synchronized (dataLock ) {
162- return height ;
169+ return javaHeight ;
163170 }
164171 }
165172
@@ -181,7 +188,7 @@ public void postPaintEvent(int x, int y, int w, int h) {
181188
182189 void postPaintEvent () {
183190 if (isVisible ()) {
184- postPaintEvent (0 , 0 , getWidth (), getHeight ());
191+ postPaintEvent (0 , 0 , getJavaWidth (), getJavaHeight ());
185192 }
186193 }
187194
@@ -268,8 +275,11 @@ protected void wlSetVisible(boolean v) {
268275 if (v ) {
269276 String title = getTitle ();
270277 boolean isWlPopup = targetIsWlPopup ();
271- int thisWidth = javaUnitsToSurfaceUnits (getWidth ());
272- int thisHeight = javaUnitsToSurfaceUnits (getHeight ());
278+ int thisWidth , thisHeight ;
279+ synchronized (dataLock ) {
280+ thisWidth = surfaceWidth ;
281+ thisHeight = surfaceHeight ;
282+ }
273283 boolean isModal = targetIsModal ();
274284
275285 int state = (target instanceof Frame frame )
@@ -354,14 +364,15 @@ private boolean targetIsModal() {
354364 }
355365
356366 void updateSurfaceData () {
367+ // The scale parameter is ignored.
357368 SurfaceData .convertTo (WLSurfaceDataExt .class , surfaceData ).revalidate (
358- getBufferWidth (), getBufferHeight (), getBufferScale () );
369+ getBufferWidth (), getBufferHeight (), 1 );
359370 updateWindowGeometry ();
360371 }
361372
362373 void configureWLSurface () {
363374 if (log .isLoggable (PlatformLogger .Level .FINE )) {
364- log .fine (String .format ("%s is configured to %dx%d with %dx scale" , this , getBufferWidth (), getBufferHeight (), getBufferScale ()));
375+ log .fine (String .format ("%s is configured to %dx%d with %fx scale" , this , getBufferWidth (), getBufferHeight (), getWlScale ()));
365376 }
366377 updateSurfaceData ();
367378 }
@@ -471,8 +482,8 @@ public void setBounds(int newX, int newY, int newWidth, int newHeight, int op) {
471482 if (sizeChanged ) {
472483 setSizeTo (newSize .width , newSize .height );
473484 if (log .isLoggable (PlatformLogger .Level .FINE )) {
474- log .fine (String .format ("%s is resizing its buffer to %dx%d with %dx scale" ,
475- this , getBufferWidth (), getBufferHeight (), getBufferScale ()));
485+ log .fine (String .format ("%s is resizing its buffer to %dx%d with %fx scale" ,
486+ this , getBufferWidth (), getBufferHeight (), getWlScale ()));
476487 }
477488 updateSurfaceData ();
478489 layout ();
@@ -485,18 +496,25 @@ public void setBounds(int newX, int newY, int newWidth, int newHeight, int op) {
485496
486497 private void setSizeTo (int newWidth , int newHeight ) {
487498 Dimension newSize = constrainSize (newWidth , newHeight );
499+ final int surfaceWidth = Math .max (javaUnitsToSurfaceUnits (newSize .width ), 1 );
500+ final int surfaceHeight = Math .max (javaUnitsToSurfaceUnits (newSize .height ), 1 );
488501 performLocked (() -> {
489- nativeSetSurfaceSize (nativePtr , javaUnitsToSurfaceUnits ( newSize . width ), javaUnitsToSurfaceUnits ( newSize . height ) );
502+ nativeSetSurfaceSize (nativePtr , surfaceWidth , surfaceHeight );
490503 });
491504 synchronized (dataLock ) {
492- this .width = newSize .width ;
493- this .height = newSize .height ;
505+ this .javaWidth = newSize .width ;
506+ this .javaHeight = newSize .height ;
507+ this .surfaceWidth = surfaceWidth ;
508+ this .surfaceHeight = surfaceHeight ;
494509 }
495510 }
496511
497512 private void repositionWlPopup (int newX , int newY ) {
498- final int thisWidth = getWidth ();
499- final int thisHeight = getHeight ();
513+ final int thisWidth , thisHeight ;
514+ synchronized (dataLock ) {
515+ thisWidth = surfaceWidth ;
516+ thisHeight = surfaceHeight ;
517+ }
500518 performLocked (() -> {
501519 Window popup = (Window ) target ;
502520 final Component popupParent = AWTAccessor .getWindowAccessor ().getPopupParent (popup );
@@ -523,32 +541,28 @@ private void repositionWlPopup(int newX, int newY) {
523541
524542 public Rectangle getVisibleBounds () {
525543 synchronized (dataLock ) {
526- return new Rectangle (0 , 0 , width , height );
544+ return new Rectangle (0 , 0 , javaWidth , javaHeight );
527545 }
528546 }
529547
530- /**
531- * Represents the scale ratio of Wayland's backing buffer in pixel units
532- * to surface units. Wayland events are generated in surface units, while
533- * painting should be performed in pixel units.
534- * The ratio is enforced with nativeSetSize().
535- */
536- int getBufferScale () {
548+ private double getWlScale () {
537549 synchronized (dataLock ) {
538- return wlBufferScale ;
550+ return ( double ) scale120 / SCALE120 ;
539551 }
540552 }
541553
542- public int getBufferWidth ( ) {
554+ private int getBufferSize ( int size ) {
543555 synchronized (dataLock ) {
544- return (int )(width * effectiveScale );
556+ return (int )(( size * scale120 + SCALE120 / 2 ) / SCALE120 );
545557 }
546558 }
547559
560+ public int getBufferWidth () {
561+ return getBufferSize (surfaceWidth );
562+ }
563+
548564 public int getBufferHeight () {
549- synchronized (dataLock ) {
550- return (int )(height * effectiveScale );
551- }
565+ return getBufferSize (surfaceHeight );
552566 }
553567
554568 public Rectangle getBufferBounds () {
@@ -566,8 +580,8 @@ private void updateWindowGeometry() {
566580 Rectangle nativeVisibleBounds = getVisibleBounds ();
567581 nativeVisibleBounds .x = javaUnitsToSurfaceUnits (nativeVisibleBounds .x );
568582 nativeVisibleBounds .y = javaUnitsToSurfaceUnits (nativeVisibleBounds .y );
569- nativeVisibleBounds .width = javaUnitsToSurfaceUnits (nativeVisibleBounds .width );
570- nativeVisibleBounds .height = javaUnitsToSurfaceUnits (nativeVisibleBounds .height );
583+ nativeVisibleBounds .width = Math . max ( javaUnitsToSurfaceUnits (nativeVisibleBounds .width ), 1 );
584+ nativeVisibleBounds .height = Math . max ( javaUnitsToSurfaceUnits (nativeVisibleBounds .height ), 1 );
571585 performLocked (() -> nativeSetWindowGeometry (nativePtr ,
572586 nativeVisibleBounds .x , nativeVisibleBounds .y ,
573587 nativeVisibleBounds .width , nativeVisibleBounds .height ));
@@ -831,7 +845,7 @@ private void updateCursorImmediately(WLInputState inputState) {
831845 WLComponentPeer peer = inputState .getPeer ();
832846 if (peer == null ) return ;
833847 Cursor cursor = peer .getCursor (inputState .getPointerX (), inputState .getPointerY ());
834- setCursor (cursor , getGraphicsDevice () != null ? getGraphicsDevice (). getWlScale () : 1 );
848+ setCursor (cursor , ( int )(( scale120 + SCALE120 - 1 ) / SCALE120 ) );
835849 }
836850
837851 Cursor getCursor (int x , int y ) {
@@ -942,16 +956,16 @@ public void applyShape(Region shape) {
942956
943957 @ Override
944958 public boolean updateGraphicsData (GraphicsConfiguration gc ) {
945- final int newWlScale = ((WLGraphicsConfig )gc ).getWlScale ();
959+ final long newScale120 = ((WLGraphicsConfig )gc ).getWlScale120 ();
946960
947961 WLGraphicsDevice gd = ((WLGraphicsConfig ) gc ).getDevice ();
948962 gd .addWindow (this );
949963 synchronized (dataLock ) {
950- if (newWlScale != wlBufferScale ) {
951- wlBufferScale = newWlScale ;
964+ if (newScale120 != scale120 ) {
965+ scale120 = newScale120 ;
952966 effectiveScale = ((WLGraphicsConfig )gc ).getEffectiveScale ();
953967 if (log .isLoggable (PlatformLogger .Level .FINE )) {
954- log .fine (String .format ("%s is updating buffer to %dx%d with %dx scale" , this , getBufferWidth (), getBufferHeight (), wlBufferScale ));
968+ log .fine (String .format ("%s is updating buffer to %dx%d with %fx scale" , this , getBufferWidth (), getBufferHeight (), getWlScale () ));
955969 }
956970 updateSurfaceData ();
957971 postPaintEvent ();
@@ -1185,7 +1199,7 @@ int surfaceUnitsToJavaUnits(int value) {
11851199 return value ;
11861200 } else {
11871201 synchronized (dataLock ) {
1188- return (int )(value * wlBufferScale / effectiveScale );
1202+ return (int )(value * scale120 / ( effectiveScale * SCALE120 ) );
11891203 }
11901204 }
11911205 }
@@ -1199,7 +1213,7 @@ int javaUnitsToSurfaceUnits(int value) {
11991213 return value ;
12001214 } else {
12011215 synchronized (dataLock ) {
1202- return (int )(value * effectiveScale / wlBufferScale );
1216+ return (int )(value * effectiveScale * SCALE120 / scale120 );
12031217 }
12041218 }
12051219 }
@@ -1285,8 +1299,17 @@ void notifyPopupDone() {
12851299 WLToolkit .postEvent (new WindowEvent ((Window ) target , WindowEvent .WINDOW_CLOSING ));
12861300 }
12871301
1302+ void notifyPreferredScale (long scale120 ) {
1303+ synchronized (dataLock ) {
1304+ if (preferredScale120 == null || preferredScale120 != scale120 ) {
1305+ preferredScale120 = scale120 ;
1306+ checkIfOnNewScreen ();
1307+ }
1308+ }
1309+ }
1310+
12881311 private WLGraphicsDevice getGraphicsDevice () {
1289- int scale = 0 ;
1312+ long scale120 = 0 ;
12901313 WLGraphicsDevice theDevice = null ;
12911314 // AFAIK there's no way of knowing which WLGraphicsDevice is displaying
12921315 // the largest portion of this component, so choose the first in the ordered list
@@ -1295,8 +1318,8 @@ private WLGraphicsDevice getGraphicsDevice() {
12951318 // Wayland's output and are removed as soon as we have left.
12961319 synchronized (devices ) {
12971320 for (WLGraphicsDevice gd : devices ) {
1298- if (gd .getWlScale () > scale ) {
1299- scale = gd .getWlScale ();
1321+ if (gd .getWlScale120 () > scale120 ) {
1322+ scale120 = gd .getWlScale120 ();
13001323 theDevice = gd ;
13011324 }
13021325 }
@@ -1308,7 +1331,7 @@ private WLGraphicsDevice getGraphicsDevice() {
13081331 private void checkIfOnNewScreen () {
13091332 final WLGraphicsDevice newDevice = getGraphicsDevice ();
13101333 if (newDevice != null ) { // could be null when screens are being reconfigured
1311- final GraphicsConfiguration gc = newDevice .getDefaultConfiguration ();
1334+ final WLGraphicsConfig gc = ( WLGraphicsConfig ) newDevice .getDefaultConfiguration ();
13121335 if (log .isLoggable (Level .FINE )) {
13131336 log .fine (this + " is on (possibly) new device " + newDevice );
13141337 }
@@ -1318,8 +1341,12 @@ private void checkIfOnNewScreen() {
13181341 newDevice .addWindow (this );
13191342 }
13201343 performUnlocked (() -> {
1344+ WLGraphicsConfig gcEffective = gc ;
1345+ if (preferredScale120 != null ) {
1346+ gcEffective = gc .withScale120 (preferredScale120 );
1347+ }
13211348 var acc = AWTAccessor .getComponentAccessor ();
1322- acc .setGraphicsConfiguration (target , gc );
1349+ acc .setGraphicsConfiguration (target , gcEffective );
13231350 });
13241351 }
13251352 }
0 commit comments