Conversation
|
Whoa, this looks very promising - thanks for working on this ❤️ I tried running My biggest feedback so far is to add docstrings to the code. I'm trying to follow along in Second piece of feedback: wrap the naked Lastly: run |
|
Thank you for more motivation and feedback! ❤️
Today i will add |
|
This is the end of the day for me! I updated the viewports example and i added some documentation! Tomorrow i will make every Popup to use a |
|
This is the end of the day for me! I made I changed ViewportBuilder, everything in it to be optional. this will allow to create a viewport and run stuff in it without changing the window attributes, this will be used for And move code from eframe to egui-winit to be more generic. |
|
All coordinates in egui, including How do you plan on handling the coordinate system of multiple windows? |
If I want to try this out, is there any sort of feedback you'd be looking for in particular? Or should I simply tell you if I notice anything odd. |
|
@stefnotch |
|
Is it intentional that the windows apparently don't update unless they're being resized? I tried out the viewport demo, and this is what I got. I cannot press any of the buttons. Code_2023-08-23-0321.webmOperating system: Windows 10 |
That is not normal! |
|
@konkitoman Lovely, that does fix the issue. Operating system: Windows 10 Steps to reproduce: firefox_2023-08-23-0324.webm |
But you can resize the The spamming of
You are sure that is a bugged state or is crashing, look in the console, but that thing is not happening to me! |
|
This is how is working for me! OS: Arch Linux video.mp4The video is on speed up some times to 130% or 200%, because i was needed to be less than 10MB The starching is because of X11! When appear two viewports from nowhere, is because "Sync Viewport" and "Async Viewport" has the same state for showing the two other viewports! I unchecked every window/viewport from the main viewport at the end to show how the child viewport of the child viewport is closing! |
|
It might be a Windows specific bug. It only seems to happen if I repeatedly, and quickly, toggle "Force embedding". |
@stefnotch The main window is closing normally? Because in Wine resize and closing is not working! "Force embedding" is some thing that should be set at the start of the program, but should work and at runtime! |
|
@konkitoman I tested it on Windows 10.
|
|
Thanks @stefnotch
The problem with resizing is fixed in winit 0.29.1-beta
If you are referring to this Now i see that when you said:
The window is getting smaller and smaller, and the bugged state is happening when the window has width=1, at the beginning the blue bar i was thinking that was a encoder artifact!
|
|
I wanted to see the auto merge conflict and i pressed "Ready for review" by mistake! |
…wport_outer_pos, viewport_inner_size, viewport_outer_size are stored as inner_pos, outer_pos, inner_size, outer_pos and Now every (i32, i32) is stored as egui::Pos2 Addes some documentation
|
I see this as finished! The only problem that i see that, for every sync viewport the fps is cut in half, because if a sync viewport needs to be redraw his parent needs to, the only fixes that i see is to set vsync to off or shadow update the parent! |
|
I think this is ready to be merged (finally!) I've created an issue for follow-up work in #3556 |
|
Amazing! I was very confused why the examples in this Repo did not compile for me, despite being on the latest release of egui/eframe. Then I noticed that this was only merged (at the time of surprise) 4h ago! In case other people stumble here, you need to switch your eframe = { git = "https://github.com/emilk/egui/", rev = "83aa3109d31eb7ab09c40530ef4b7d5f3e370fd4" , features = ["persistence"]}
# other egui crates can be used like this too:
egui_plot = { git = "https://github.com/emilk/egui/", rev = "83aa3109d31eb7ab09c40530ef4b7d5f3e370fd4"}(or any commit after this one, so that the multiple windows code is included) |
Added by @konkitoman in #3172 I'm not sure what the hack is supposed to solve, but calling it every frame is a bad idea, as @ItsEthra reported in #3628 (comment) * Closes #3620 * Closes #3628
This was caused by a hack added by @konkitoman in #3172 The solution was reported by @ItsEthra in #3628 (comment) * Closes #3620 * Closes #3628
Addition for <#3847> In previous one i only fixed crash occurring with Wgpu backend. This fixes crash with Glow backend as well. I only tested this change with android so most things i changed are behind ```#[cfg(target_os = "android")]```. Both fixes are dirty thought. As <#3172> says that "The root viewport is the original viewport, and cannot be closed without closing the application.". So they break rules i guess? But i can't think about better solution for now. Closes <#3861>.



(new PR description written by @emilk)
Overview
This PR introduces the concept of
Viewports, which on the native eframe backend corresponds to native OS windows.You can spawn a new viewport using
Context::show_viewportandCotext::show_viewport_immediate.These needs to be called every frame the viewport should be visible.
This is implemented by the native
eframebackend, but not the web one.Viewport classes
The viewports form a tree of parent-child relationships.
There are different classes of viewports.
Root vieport
The root viewport is the original viewport, and cannot be closed without closing the application.
Deferred viewports
These are created with
Context::show_viewport.Deferred viewports take a closure that is called by the integration at a later time, perhaps multiple times.
Deferred viewports are repainted independenantly of the parent viewport.
This means communication with them need to done via channels, or
Arc/Mutex.This is the most performant type of child viewport, though a bit more cumbersome to work with compared to immediate viewports.
Immediate viewports
These are created with
Context::show_viewport_immediate.Immediate viewports take a
FnOnceclosure, similar to other egui functions, and is called immediately. This makes communication with them much simpler than with deferred viewports, but this simplicity comes at a cost: whenever tha parent viewports needs to be repainted, so will the child viewport, and vice versa. This means that if you haveNviewports you are poentially doingNtimes as much CPU work. However, if all your viewports are showing animations, and thus are repainting constantly anyway, this doesn't matter.In short: immediate viewports are simpler to use, but can waste a lot of CPU time.
Embedded viewports
These are not real, independenant viewports, but is a fallback mode for when the integration does not support real viewports. In your callback is called with
ViewportClass::Embeddedit means you need to create anegui::Windowto wrap your ui in, which will then be embedded in the parent viewport, unable to escape it.Using the viewports
Only one viewport is active at any one time, identified wth
Context::viewport_id.You can send commands to other viewports using
Context::send_viewport_command_to.There is an example in https://github.com/emilk/egui/tree/master/examples/multiple_viewports/src/main.rs.
For integrations
There are several changes relevant to integrations.
crate::RawInput::viewport] with information about the current viewport.Context::set_request_repaint_callbacknow points to which viewport should be repainted.Context::runnow returns a list of viewports inFullOutputwhich should result in their own independant windowsContext::set_immediate_viewport_rendererfor setting up the immediate viewport integrationContext::set_embed_viewports(false), or all new viewports will be embedded (the default behavior).Future work
egui::Windowegui::WindowViewportBuilderineframe::NativeOptionsContextmethod for listing all existing viewportsFind more at #3556
Outdated PR description by @konkitoman
Inspiration
What is a Viewport
A Viewport is a egui isolated component!
Can be used by the egui integration to create native windows!
When you create a Viewport is possible that the backend do not supports that!
So you need to check if the Viewport was created or you are in the normal egui context!
This is how you can do that:
This PR do not support for drag and drop between Viewports!
After this PR is accepted i will begin work to intregrate the Viewport system in
egui::Window!The
egui::Windowi want to behave the same on desktop and webThe
egui::Windowwill be like Godot WindowChanges and new
These are only public structs and functions!
New
egui::ViewportIdegui::ViewportBuilderThis is like winit WindowBuilder
egui::ViewportCommandWith this you can set any winit property on a viewport, when is a native window!
egui::Context::newegui::Context::create_viewportegui::Context::create_viewport_syncegui::Context::viewport_idegui::Context::parent_viewport_idegui::Context::viewport_id_pairegui::Context::set_render_sync_callbackegui::Context::is_desktopegui::Context::force_embeddingegui::Context::set_force_embeddingegui::Context::viewport_commandegui::Context::send_viewport_command_toegui::Context::input_foregui::Context::input_mut_foregui::Context::frame_nr_foregui::Context::request_repaint_foregui::Context::request_repaint_after_foregui::Context::requested_repaint_last_frameegui::Context::requested_repaint_last_frame_foregui::Context::requested_repaintegui::Context::requested_repaint_foregui::Context::inner_rectegui::Context::outer_rectegui::InputState::inner_rectegui::InputState::outer_rectegui::WindowEventChanges
egui::Context::runNow needs the viewport that we want to render!
egui::Context::begin_frameNow needs the viewport that we want to render!
egui::Context::tessellateNow needs the viewport that we want to render!
egui::FullOutputegui::RawInputegui::Event+ WindowEventAsync Viewport
Async means that is independent from other viewports!
Is created by
egui::Context::create_viewportTo be used you will need to wrap your state in
Arc<RwLock<T>>Look at viewports example to understand how to use it!
Sync Viewport
Sync means that is dependent on his parent!
Is created by
egui::Context::create_viewport_syncThis will pause the parent then render itself the resumes his parent!
Common
You will need to do this when you render your content
What you need to know as egui user
If you are using eframe
You don't need to change anything!
If you have a manual implementation
Now
egui::runoregui::beginandegui::tessellatewill need the current viewport id!You cannot create a
ViewportIdonlyViewportId::MAINIf you make a single window app you will set the viewport id to be
egui::ViewportId::MAINor see theexamples/pure_glowIf you want to have multiples window support look at
crates/eframeglow or wgpu implementations!If you want to try this
This before was wanted to change
This will probably be in feature PR's
egui::Window
To create a native window when embedded was set to false
You can try that in viewports example before: 78a0ae8
egui popups, context_menu, tooltip
To be a native window