-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
can change window settings at runtime #644
Conversation
Yeah events seem like a reasonable approach. I see three options for "backend agnostic window property setters":
I think my preference is (2) or (3) |
I gave a try at (2) by adding setters. not sure about getters though? I don't really like having getters that just give the value of the field, but I guess they are needed if I make all the fields private... wdyt? |
Yeah the purpose of getters in this case is to allow us to make the fields private, which prevents users from setting them directly. This protects them from setting fields directly and nothing happening / state getting out of sync. I think we need to do this to protect users from shooting themselves in the foot. |
added the getters I left the field also the |
Im fine with leaving the canvas field as-is for now |
thank you for your review, I applied most of it |
Thanks for looking into this! While trying the branch on Windows 10 with Is anyone else able to reproduce this behavior on Windows? Looking at the logs (after adding pretty_env_logger to the example), once
|
seems like it's not possible on Windows to change the title of a window from another thread... I added a workaround just for Windows and title. |
Changing resizable, decorations, title, resolution, and |
I wonder if it would be reasonable to forward all window change events, not only title changes, to be handled the main thread. Then we would remove the special casing too. I've heard MacOS has some requirements about the main thread too, though I'm unable to test this. |
The simplest way to force everything onto the main thread would be changing the diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs
index 5b3d08fc..69d383f4 100644
--- a/crates/bevy_winit/src/lib.rs
+++ b/crates/bevy_winit/src/lib.rs
@@ -9,7 +9,7 @@ pub use winit_config::*;
pub use winit_windows::*;
use bevy_app::{prelude::*, AppExit};
-use bevy_ecs::{IntoQuerySystem, Res, ResMut, Resources};
+use bevy_ecs::{IntoThreadLocalSystem, Resources, World};
use bevy_math::Vec2;
use bevy_window::{
CreateWindow, CursorMoved, Window, WindowCloseRequested, WindowCreated, WindowResized, Windows,
@@ -30,18 +30,13 @@ impl Plugin for WinitPlugin {
// .add_event::<winit::event::WindowEvent>()
.init_resource::<WinitWindows>()
.set_runner(winit_runner)
- .add_system(change_window.system());
-
- #[cfg(target_os = "windows")]
- app.add_event::<WindowRename>();
+ .add_system(change_window.thread_local_system());
}
}
-fn change_window(
- winit_windows: Res<WinitWindows>,
- mut windows: ResMut<Windows>,
- #[cfg(target_os = "windows")] mut rename_events: ResMut<Events<WindowRename>>,
-) {
+fn change_window(_: &mut World, resources: &mut Resources) {
+ let winit_windows = resources.get::<WinitWindows>().unwrap();
+ let mut windows = resources.get_mut::<Windows>().unwrap();
for bevy_window in windows.iter_mut() {
let id = bevy_window.id();
for command in bevy_window.drain_commands() {
@@ -69,13 +64,8 @@ fn change_window(
}
}
bevy_window::WindowCommand::SetTitle { title } => {
- #[cfg(not(target_os = "windows"))]
- {
- let window = winit_windows.get_window(id).unwrap();
- window.set_title(&title);
- }
- #[cfg(target_os = "windows")]
- rename_events.send(WindowRename { id, title });
+ let window = winit_windows.get_window(id).unwrap();
+ window.set_title(&title);
}
bevy_window::WindowCommand::SetResolution { width, height } => {
let window = winit_windows.get_window(id).unwrap();
@@ -95,12 +85,6 @@ fn change_window(
}
}
-#[cfg(target_os = "windows")]
-struct WindowRename {
- id: bevy_window::WindowId,
- title: String,
-}
-
fn run<F>(event_loop: EventLoop<()>, event_handler: F) -> !
where
F: 'static + FnMut(Event<'_, ()>, &EventLoopWindowTarget<()>, &mut ControlFlow),
@@ -149,8 +133,6 @@ pub fn winit_runner(mut app: App) {
let mut create_window_event_reader = EventReader::<CreateWindow>::default();
let mut app_exit_event_reader = EventReader::<AppExit>::default();
- #[cfg(target_os = "windows")]
- let mut window_rename_event_reader = EventReader::<WindowRename>::default();
handle_create_window_events(
&mut app.resources,
@@ -180,15 +162,6 @@ pub fn winit_runner(mut app: App) {
}
}
- #[cfg(target_os = "windows")]
- if let Some(window_rename_events) = app.resources.get_mut::<Events<WindowRename>>() {
- if let Some(event) = window_rename_event_reader.latest(&window_rename_events) {
- let winit_windows = app.resources.get_mut::<WinitWindows>().unwrap();
- let window = winit_windows.get_window(event.id).unwrap();
- window.set_title(&event.title);
- }
- }
-
match event {
event::Event::WindowEvent {
event: WindowEvent::Resized(size), |
I think thats a good call. Better to bias toward safety here. |
also works on my Mac with a |
can change window settings at runtime
Added events to change a few settings for the window. This will keep the windows descriptor and the window from winit in sync.
It could be implemented as an external plugin but it would mean reimplementing some of the code from bevy_winit, like for fullscreen videomode