bevyengine / bevy

A refreshingly simple data-driven game engine built in Rust
https://bevyengine.org
Apache License 2.0
35.27k stars 3.48k forks source link

How to create multiple windows in multiple monitors? #7600

Open lewiszlw opened 1 year ago

lewiszlw commented 1 year ago

Bevy version

main branch (lastest commit is cd447fb4e68716fb908158ab9ca64d13746a6b97).

[Optional] Relevant system information

AdapterInfo { name: "Apple M1", vendor: 0, device: 0, device_type: IntegratedGpu, driver: "", driver_info: "", backend: Metal }

SystemInfo { os: "MacOS 13.0 ", kernel: "22.1.0", cpu: "Apple M1", core_count: "8", memory: "16.0 GiB" }

[DisplayInfo { id: 1, x: 0, y: 0, width: 1440, height: 900, rotation: 0.0, scale_factor: 2.0, is_primary: true }, DisplayInfo { id: 2, x: -264, y: -1080, width: 1920, height: 1080, rotation: 0.0, scale_factor: 1.0, is_primary: false }]

What you did

I'm trying to run offical example multiple_windows and want second window putted on second monitor. I tried

    let second_window = commands
        .spawn(Window {
            title: "Second window".to_owned(),
            position: WindowPosition::At(IVec2::new(-264, -1080)),
            resolution: WindowResolution::new(1920., 1080.),
            ..default()
        })
        .id();

and

    let second_window = commands
        .spawn(Window {
            title: "Second window".to_owned(),
            position: WindowPosition::Centered(MonitorSelection::Index(1)),   // I tried 0,1,2,3 here
            resolution: WindowResolution::new(1920., 1080.),
            ..default()
        })
        .id();

What went wrong

The second window is always on my primary monitor.

lewiszlw commented 1 year ago

Hi, @aceeri , could you give a look at this? I can put second window on second monitor when using bevy 0.9.1. I'm not sure if windows as entities pr breaks this or something I missed.

Aceeri commented 1 year ago

I'll double check that this works, never really tested it specifically myself just took existing code.

Aceeri commented 1 year ago

Hmm, it seems to work fine on Windows. I do have a M1 laptop to try and test this on, but I'll try doing that tomorrow.

Aceeri commented 1 year ago

@lewiszlw Would you mind posting the logs from running the code with

position: WindowPosition::Centered(MonitorSelection::Index(1)),

?

Just wondering if there is maybe a WARN about it not finding the second monitor.

lewiszlw commented 1 year ago
2023-02-16T08:38:20.479995Z  INFO bevy_render::renderer: AdapterInfo { name: "Apple M1", vendor: 0, device: 0, device_type: IntegratedGpu, driver: "", driver_info: "", backend: Metal }
2023-02-16T08:38:20.905247Z  INFO bevy_winit::system: Creating new window "Bevy App" (0v0)
2023-02-16T08:38:21.086569Z  INFO bevy_diagnostic::system_information_diagnostics_plugin::internal: SystemInfo { os: "MacOS 13.0 ", kernel: "22.1.0", cpu: "Apple M1", core_count: "8", memory: "16.0 GiB" }
2023-02-16T08:38:21.212242Z  INFO bevy_winit::system: Creating new window "Second window" (4v0)
2023-02-16T08:38:27.260902Z  INFO bevy_winit::system: Closing window 0v0
2023-02-16T08:38:27.316784Z  WARN bevy_winit: Window 0v0 is missing `Window` component, skipping event Destroyed
2023-02-16T08:38:28.674905Z  INFO bevy_window::system: No windows are open, exiting
2023-02-16T08:38:28.677308Z  INFO bevy_winit::system: Closing window 4v0
SpecificProtagonist commented 1 year ago

Works for me on Linux (X11) too.

Aceeri commented 1 year ago

@lewiszlw Would you be open to debugging this further on your end? Can ask me any questions about the windowing code in general.

Could also do it live somewhere if you think that'd be helpful.

lewiszlw commented 1 year ago

Sure, I'll try a deep dive.

lewiszlw commented 1 year ago

I have some findings @Aceeri

  1. When I put primary window on primary monitor, if I set a negative number (ex. -200) to Y of position of the second window, the second window will be created on bottom of my primary monitor rather than second monitor (seems the second monitor wasn't detected).
  2. When I put primary window on second monitor, if I set a negative number to Y of position of the second window, the second window will be created on second monitor as expected.

Seems the process behind creating primary window on second monitor will init somthing for the second monitor.

This is my monitors arrangement.

image
Aceeri commented 1 year ago

Hmm, this makes me think we either are or aren't flipping the coordinate space for position in the y direction.

Either way our vertical coordinate space is differing from winits I think.

lewiszlw commented 1 year ago

I tried winit multiwindow example, everything works fine.

lewiszlw commented 1 year ago

There are some talk in https://github.com/bevyengine/bevy/pull/6526, maybe helpful.

Aceeri commented 1 year ago

Can't seem to repro this still, tried moving my monitors around to be in a similar set up but it seems to work fine hmm

honungsburk commented 10 months ago

I've run into the same problem on bevy 0.12.0

SystemInfo { os: "MacOS 14.1.1 ", kernel: "23.1.0", cpu: "Apple M1 Pro", core_count: "8", memory: "16.0 GiB" }

AdapterInfo { name: "Apple M1 Pro", vendor: 0, device: 0, device_type: IntegratedGpu, driver: "", driver_info: "", backend: Metal }

DrewRidley commented 7 months ago

@lewiszlw, how were you able to get the primary window to be constructed on a secondary monitor?

        .add_plugins(DefaultPlugins.set(WindowPlugin {
            primary_window: Some(Window {
                position: WindowPosition::Centered(MonitorSelection::Index(1)),
                ..Default::default()
            }),
            ..Default::default()
        }))

always results in the window being on the primary display, no matter which index is used. This only happens on macOS.

lewiszlw commented 7 months ago

I think the method is like you pasted, setting position field.

TarekAS commented 1 month ago

@DrewRidley Did you manage to get the window to show up on the second monitor?

This configuration is still not working on M1 Mac:

.set(WindowPlugin {
    primary_window: Some(Window {
        mode: bevy::window::WindowMode::Fullscreen,
        resizable: false,
        position: WindowPosition::Centered(MonitorSelection::Index(1)),
        ..default()
    }),
    ..default()
}),

No matter what the value of the index, the window only shows up on the primary display.