-
Notifications
You must be signed in to change notification settings - Fork 91
VST2 Guis
The DAW handles the creation, opening, and managing of the actual GUI window. It merely passes a window handle to the plugin for the plugin to access it. The type of window that is created is platform-dependent, but in rust-vst
it is always encoded as a *mut std::os::raw::c_void
(a C-style void pointer), referred to as the "parent pointer".
Let's say you had parent: *mut std::os::raw::c_void
.
- In Windows, the parent pointer is really a
winapi::HWND__
. You can convert the parent pointer by doingparent as *mut winapi::HWND__
. - In Linux, it's just an ID number to the parent window. You can convert it by doing
parent as u32
. - TODO: Mac OS X
Your job, as a VST2 GUI developer, is to "connect" your GUI to this parent window, so that the DAW can manage the window (open, close, get events, etc). This is usually done by passing parent
as an argument during the window creation phase of your platform's "native" window creation API (winapi's user32::CreateWindowExW
, X11/XCB's xcb::create_window
, etc).
This method gets messy very quickly. It would have been much wiser to have the plugin control its own window, and there are possibly historical reasons for this choice, but it creates confusing problems quickly. MacOS has a very different windowing and eventing system to Windows and has different rules. Also DAWs have historically presented the window slightly differently.
- The size of the editor window that the DAW creates for you is determined based on your
Editor::size()
function. -
Editor::position()
is usually ignored; most plugins usually just return(0, 0)
.
VST2 (and all of the currently popular plugin standards) expects the DAW (host) to have complete control over the application, including its threads. Generally, a DAW will have a thread (or multiple) reserved for each running plugin and send calls over FFI when an event is ready to be dealt with (such as a window closing or an audio buffer ready to be processed), but it will expect that function to give back control to the host DAW.
This is incompatible with most of the GUI crates in the Rust ecosystem, since they assume that you want your own event loop and event processing thread -- the crate will usually create a processing thread for you, locked by your application, and never returned.
The current major Rust libraries (like conrod
, imgui
, winit
, etc.) all make this assumption, and are therefore not good choices for VST2 GUI development -- unless you want to majorly hack away some core assumptions of those crates and maintain the result yourself. The rust-dsp
group have even attempted to create a fork of winit
that supports some of these features, but the rapidly changing winit
library underneath alongside platform complexities warranted exploring our own unique solution.