blade icon indicating copy to clipboard operation
blade copied to clipboard

Redrawing on macOS will not work with future versions of Winit

Open madsmtm opened this issue 1 year ago • 2 comments

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).

madsmtm avatar Nov 25 '24 22:11 madsmtm

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)?

kvark avatar Nov 27 '24 02:11 kvark

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).

madsmtm avatar Nov 27 '24 03:11 madsmtm