On Windows it is not restricted AFAIK, moving a screen anywhere is allowed, and one can also drag windows beyond those limits. When a monitor is added/removed Windows may however decide to reshuffle all your Windows (or randomly if a monitor is slow to respond when waking from sleep) to ensure they're all visible.
I think Windows just treats the screen space as infinite with the monitors being views into it; overlaps and gaps are allowed, although you need some tricks to get your screens setup that way. Not sure what you find odd about the Windows behaviour? --John On 09/04/2025 13:57, Thiago Milczarek Sayão wrote: > Thanks John! > > I did not calculate the center, I just wanted to know the behaviour of > setX() outside bounds and within > bounds of the last screen. > > The GNOME window manager on Linux restricts programmatic movement of > windows to prevent them > from being moved outside screen boundaries. However, it allows users > to drag windows beyond these limits. > I find it odd that the maximum movement is restricted to the bounds of > the first screen, while it would be more > intuitive for it to be based on the last screen. > > The Windows behaviour also seems odd. > > -- Thiago > > Em qua., 9 de abr. de 2025 às 08:28, John Hendrikx > <john.hendr...@gmail.com> escreveu: > > Small addition; the 3520 button moved the top left of the Window > to the middle of the right screen, but the window as a whole was > not centered. > > --John > > On 09/04/2025 13:22, John Hendrikx wrote: >> >> Hi Thiago, >> >> I ran this on Windows. My monitor setup is: >> >> Left: 3840x2160 (150%) -- top left coordinate (-2560, 0) (-2560 >> because of scaling) >> Middle: 3840x2160 (150%) -- this one has a top left coordinate of >> (0, 0) >> Right: 1920x1200 (100%) -- this one has a top left coordinate of >> (2560, 0) >> >> When started, the program appeared perfectly centered on the >> middle screen. >> >> Your program showed buttons: 4480 and 3520 >> >> The 4480 button moved the Window far too the right, off screen >> and I had to stop the program >> >> The 3520 button moved the Window to the Right monitor, but it was >> not centered nicely. >> >> I added a `peek(System.out::println)` on the screens stream. >> These are my screens: >> >> Rectangle2D [minX=0.0, minY=0.0, maxX=2560.0, maxY=1440.0, >> width=2560.0, height=1440.0] >> >> Rectangle2D [minX=2560.0, minY=-194.0, maxX=4480.0, maxY=1006.0, >> width=1920.0, height=1200.0] >> >> Rectangle2D [minX=-2560.0, minY=6.0, maxX=0.0, maxY=1446.0, >> width=2560.0, height=1440.0] >> >> --John >> >> On 09/04/2025 12:55, Thiago Milczarek Sayão wrote: >>> Hi, >>> >>> Could anyone with a multi-screen setup on Mac and/or Windows >>> please share the results of the two buttons on this sample app? >>> Your feedback would be greatly appreciated! >>> >>> On Ubuntu 24.04 the first button moves the Stage to the end of >>> the first screen (bit weird). >>> The second work as expected, it gets moved to the start of the >>> center of the last screen. >>> >>> Thanks! >>> >>> import javafx.application.Application; >>> import javafx.geometry.Pos; >>> import javafx.geometry.Rectangle2D; >>> import javafx.scene.control.Button; >>> import javafx.scene.layout.VBox; >>> import javafx.stage.Screen; >>> import javafx.stage.StageStyle; >>> import javafx.application.Platform; >>> import javafx.scene.Scene; >>> import javafx.scene.layout.StackPane; >>> import javafx.scene.paint.Color; >>> import javafx.stage.Stage; >>> >>> import java.util.Comparator; >>> >>> public class TestScreenBounds extends Application { >>> >>> @Override >>> public void start(Stage stage) { >>> stage.setTitle("Move Outside Bounds"); >>> Rectangle2D bounds = Screen.getScreens().stream() >>> .map(Screen::getBounds) >>> >>> .sorted(Comparator.comparingDouble(Rectangle2D::getMaxX).reversed()) >>> .findFirst() >>> .orElseThrow(); >>> >>> Button btn = new Button("Move To " + bounds.getMaxX()); >>> btn.setOnAction(event -> stage.setX(bounds.getMaxX())); >>> >>> double middleLastScreen = bounds.getMinX() + bounds.getWidth() >>> / 2; >>> >>> Button btn2 = new Button("Move To " + middleLastScreen); >>> btn2.setOnAction(event -> stage.setX(middleLastScreen)); >>> >>> VBox root = new VBox(btn, btn2); >>> root.setFillWidth(true); >>> root.setAlignment(Pos.CENTER); >>> Scene scene = new Scene(root, 300, 300); >>> stage.setScene(scene); >>> stage.show(); >>> } >>> >>> public static void main(String[] args) { >>> launch(TestScreenBounds.class, args); >>> } >>> } >>>