blade
blade copied to clipboard
Redrawing on macOS will not work with future versions of Winit
Winit currently implements redrawing in a weird ad-hoc fashion on macOS. This causes a bunch of issues, see https://github.com/rust-windowing/winit/issues/2640 for some of it, which I intend to fix by emitting RedrawRequested in the built-in scheduled draw events (-[NSView drawRect:] / -[NSView updateLayer]) instead.
However, this won't work when the "consumer" of the raw-window-handle that Winit provides (i.e. blade) is overriding the layer on NSView, as is currently done, since that makes the view "layer-hosting", see -[NSView wantsLayer].
The code in question is around here: https://github.com/kvark/blade/blob/5da73b1807079c5289613b652901e29169b6ffc7/blade-graphics/src/metal/surface.rs#L21-L63
To fix this, blade should be using -[CALayer addSublayer:] like on iOS instead of -[CALayer setLayer:]. The logic to get resizing to work automatically after this though is a bit cumbersome (you'll need to use observers), so I've extracted it into a crate: raw-window-metal.
I can submit a PR for it if you want, though note that raw-window-metal depends on objc2. If you don't want to use that, you could try to use a similar approach as wgpu currently does, though beware that that still has issues, observers are really the best way to do this (that I've found at least).
Interesting, thank you for bringing this up! So you are saying we shouldn't be replacing the layer, and we can add a sub-layer. If there is already a layer though, would it be fine to just use it directly (instead of a sublayer)?
Interesting, thank you for bringing this up! So you are saying we shouldn't be replacing the layer, and we can add a sub-layer. If there is already a layer though, would it be fine to just use it directly (instead of a sublayer)?
Yeah, if the view is already configured with a CAMetalLayer, you either have MTKView, and then resizing is going to work in a different way anyhow, or the user has overwritten -[UIView layerClass] on iOS / called setLayer: on macOS, in which case they're responsible for the view now being layer-hosting (so they're also responsible for letting blade know when to resize and redraw).