rust-windowing / rust-windowing/winit
Support for creating child windows
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 6.2k
- Forks
- 1.3k
- Avg merge
- 2d 19h
- Merged PRs (30d)
- 9
Description
It would be very useful to have support for creating child windows with a given parent handle.
I implemented support for child windows on Windows in my glutin fork like half a year ago:
https://github.com/Boscop/glutin/blob/master/src/window.rs#L205
https://github.com/Boscop/glutin/blob/master/src/api/win32/init.rs#L76-L84
https://github.com/Boscop/glutin/blob/master/src/api/win32/callback.rs#L23
https://github.com/Boscop/glutin/blob/master/src/api/win32/mod.rs#L471-L473
(Child windows have to run in the same thread as the parent window, so I'm using a HashMap with HWND as key for event dispatching of all the windows in the same thread.)
It would also be useful to have support for timers on the window.
Either via callback:
https://github.com/Boscop/glutin/blob/master/src/window.rs#L508-L516
Or events:
https://github.com/Boscop/glutin/blob/master/src/events.rs#L61
https://github.com/Boscop/glutin/blob/master/src/api/win32/callback.rs#L342-L346
I implemented this because it's necessary to create a child window for writing GUIs for VST plugins. The plugin host creates a window and passes it to the plugin, which has to create a child window on that for it's GUI and register a timer on the HWND so that it refreshes it's GUI every few milliseconds.
This is what I do in the plugin:
impl<'a> Editor for MyPlugin<'a> {
fn open(&mut self, parent: *mut c_void) {
let mut display = WindowBuilder::new().with_dimensions(WINDOW_WIDTH, WINDOW_HEIGHT).with_parent(WindowID::new(parent)).build_glium().unwrap();
{
let window = display.get_window().unwrap();
unsafe { user32::SetWindowLongA(window.platform_window() as winapi::HWND, winapi::winuser::GWLP_USERDATA, self as *mut _ as winapi::LONG); }
window.set_timer(WIN_GUI_FRAME_TIMER, 25 /* ms */, Some(handle_timer)).unwrap();
}
// ...
const WIN_GUI_FRAME_TIMER: winapi::UINT_PTR = 4242;
unsafe extern "system" fn handle_timer(hwnd: winapi::HWND, _: winapi::UINT, timer_id: winapi::UINT_PTR, elapsed_ms: winapi::DWORD) {
if timer_id != WIN_GUI_FRAME_TIMER {
return;
}
let plugin = &mut *(user32::GetWindowLongA(hwnd, winapi::winuser::GWLP_USERDATA) as *mut MyPlugin);
plugin.do_ui();
}
Unfortunately I only know how to do this on windows. .
It would be very useful to have this in winit, maybe even in a cross-platform way.
So that winit with conrod can be used to write GUIs for VST plugins, completely in Rust :)
Btw, at the time, conrod didn't have a winit (or glium) backend, so I also forked piston so I could pass the parent all the way down from my plugin to PistonWindow in conrod down to glutin.
Btw, here is a screenshot of an old version of one of my plugins: https://i.imgur.com/4BQ1tCQ.gifv
In the future I would like to use conrod with winit/glium backend for this.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing the referenced glutin files: src/window.rs, src/api/win32/init.rs, src/api/win32/callback.rs, src/api/win32/mod.rs, and src/events.rs. Compare the child-window and timer approaches with winit's current window APIs, then clarify the intended platforms and API shape. Done should include an agreed scope and tests covering the supported behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- desktop
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 20/100