Expose Viewport functionality
This PR intends to expose most of the Viewport functionality of ImGui.
- Exposes the essential structs like PlatformIo, Viewport, Monitor, etc.
- Adds support for PlatformViewportBackend and RendererViewportBackend.
- imgui-winit-support mostly supports multiple Viewports, without breaking code changes to code that does not support Viewports.
The backend functions are implemented via two traits called PlatformViewportBackend and RendererViewportBackend.
I'm very open for suggestions for improvement, as I am not sure if everything I did uses the best approach.
Yes the renderers and platform integrations will need to be extended in order to support viewports.
I would have liked to add viewport support to the examples directly, but at least with glium it is currently impossible to create new windows at runtime, although it seems like this will be fixed soon :)
I also thought about reverting all the changes to the examples and add a single example with viewport support, as this might be easier to understand. Consider the changes to the examples as temporary testing code that i forgot to remove before opening the PR...
I will probably do some more work on this next week.
I was finally able to work on this a bit more :)
The examples should now be the same as before my PR again. The viewport example now implements a working viewport example using glow (since it still seems impossible to create glium windows in the event_loop).
I will add documentation to the example as soon as I have time.
Last time I checked (year or two ago), glium had troubles with sharing of textures between GL contexts. Dropped texture is cleaned up only from parent context, but left dangling in shared contexts (which messes up internal texture indices). Maybe there are some other bugs related to multiple windows (cause original glium author probably never tested such use case). wgpu worked fine with viewports, except that it leaked surface&swapchain on window destruction (pool of reusable windows could work as workaround).
Last time I checked (year or two ago), glium had troubles with sharing of textures between GL contexts. Dropped texture is cleaned up only from parent context, but left dangling in shared contexts (which messes up internal texture indices). Maybe there are some other bugs related to multiple windows. wgpu worked fine with viewports, except that it leaked surface&swapchain on window destruction (pool of reusable windows could work as workaround).
Those issues just add onto the problems with Glium i guess. It is just impossible to create windows at runtime as Glium relies on EventLoop rather than EventLoopWindowTarget, but this might be fixed soon on crates.io as in https://github.com/glium/glium/pull/1997.
The reusable window pool idea might work but that is a very dirty hack in my opinion :(
I will try to implement context sharing in the viewport example as soon as possible
Side note: I put this under the v0.10 milestone, but no pressure whatsoever if it's not done by then or if you stop working on the PR!
Plus we have a very lose schedule and are still working on 0.9, so who knows when 0.10 will even be a thing (I just put it in the milestone to keep track of it)
Hi there, BTW Can this PR achieve this goal? https://github.com/imgui-rs/imgui-rs/issues/299 also https://github.com/inkyblackness/imgui-go-examples/issues/1
Hi there, BTW Can this PR achieve this goal? https://github.com/imgui-rs/imgui-rs/issues/299 also https://github.com/inkyblackness/imgui-go-examples/issues/1
Not sure, the main focus of this feature are the extra viewports, the user is still responsible for the main window as far as i know
Side note: I put this under the v0.10 milestone, but no pressure whatsoever if it's not done by then or if you stop working on the PR!
Plus we have a very lose schedule and are still working on 0.9, so who knows when 0.10 will even be a thing (I just put it in the milestone to keep track of it)
We might need to do some more work before releasing this feature into the wild:
- The
platform_user_dataandrenderer_user_datafields of viewports are currently raw pointers, there might be a more rust-like approach - The imgui-winit-support crate currently assumes winit-26 when viewports are enabled
Hi there, BTW Can this PR achieve this goal? https://github.com/imgui-rs/imgui-rs/issues/299 also https://github.com/inkyblackness/imgui-go-examples/issues/1
I would assume the solution described in the imgui-go link should work here - basically make your "main imgui window" occupy the full (OS) window by doing something like
ui.window("Main")
.flags(flags)
.position([0.0, 0.0], imgui::Condition::Always)
.size(ui.io().display_size, imgui::Condition::Always)
.build(...)
Then hide the decoration on the OS-window via winit. Then make your other windows new viewports and it should do what you describe - just be a bunch of floating widnows
..at least, in theory!
The imgui-winit-support crate currently assumes winit-26 when viewports are enabled
I think this is fine - since the viewport handling would be a new thing, I think it's reasonable it would require a recent winit version. We could just make it error if you try adn use old winit + viewport feature, but.. maybe even simpler, I've made #627 to discuss if we need to support so many winit versions at all
Yay, That works pretty well. But I can only resize the window, not move it. How can I make the window move freely?
As I understand it, imgui's window is restricted to the main window, which now cannot be moved. after this PR merge, the window will be free to move, and then it will be awesome. Is this right?

Yay, That works pretty well. But I can only resize the window, not move it. How can I make the window move freely?
As I understand it, imgui's window is restricted to the main window, which now cannot be moved. after this PR merge, the window will be free to move, and then it will be awesome. Is this right?
You might be able to just set the winit window position to your imgui window position every frame. Not sure if this works very well though...
You might be able to just set the winit window position to your imgui window position every frame. Not sure if this works very well though...
// return window pos offset of "Hello world" window
let window_pos = run_ui(&mut run, ui);
if !run {
*control_flow = ControlFlow::Exit;
}
let gl_window = display.gl_window();
let mut target = display.draw();
target.clear_color_srgb(0.0, 0.0, 0.0, 0.0);
platform.prepare_render(&ui, gl_window.window());
println!("window_pos {:?}", window_pos);
let draw_data = imgui.render();
let gl_window_pos = gl_window.window().outer_position().unwrap();
println!("gl_window_pos {:?}", gl_window_pos);
// set winit window position
gl_window.window().set_outer_position(PhysicalPosition {
x: window_pos[0] + gl_window_pos.x as f32,
y: window_pos[1] + gl_window_pos.y as f32,
});
// code of run_ui
ui.window("Hello world")
.flags(WindowFlags::NO_COLLAPSE)
.position([0.0, 0.0], Condition::Once)
.build(|| {
// blablabla
pos = ui.window_pos();
});
pos
I have implemented the winit window movement according to your suggestion, but it keeps moving and I didn't find a way to reset the position of the imgui window after moving the winit window. 🌚
If I just execute ui.window("Hello world").position([0.0,0.0], Condition::Once) immediately after moving the winit window or after fetching the imgui's window position, it's display will get messed up.
When viewports are enabled, the imgui window position will be in desktop corrdinates, so you need to set the winit window position to the imgui window position as is, without adding winit position as offset :) But I don't think this will work perfectly as imgui doesnt really have support for a "now main window" mode...
It might be a good idea to have separate winit-support modules, one for non-viewport support and one with viewports enabled. Since the coordinate system is completely different depending on whether viewports are enabled, it might make the code more readable. Adding to that, Viewports require very tight interaction between platform and renderer backend, so it might be better to provide a combined platform-and-renderer-with-viewport support package.
Hi, any new updates?
I will try to work on a combined winit + glow viewports renderer that could serve as a complete example on how to use viewports :)
Combining the winit+glow into one crate for the viewport sounds like a good idea to me!
With the "combined" crate, I would suggest only supporting the latest version of winit. The imgui-winit-support supports a confusingly large range of versions, which I don't think is necessary for the viewport handling (it seems reasonable to require someone using new viewport feature to use a recent version of winit), and we may drop the handling of so many versions in a future release (https://github.com/imgui-rs/imgui-rs/issues/627#issuecomment-1073143077)
Thought so too, latest winit should be enough.
Hi, long time no see, any news?
Hey, I must admit I haven't done much on this lately, although I plan to continue working on this soon.
Don't worry, I know how hard it is to get something done when I don't need it.