rust-windowing / winit

Window handling library in pure Rust
https://docs.rs/winit/
Apache License 2.0
4.7k stars 885 forks source link

Exposing sub-APIs of the unix platforms #872

Open elinorbgr opened 5 years ago

elinorbgr commented 5 years ago

I'm in the process of marching towards 1.0 of calloop and wayland-rs, this opens a few possibilities that I'd like to discuss: exposing them as public dependencies of winit.

For wayland-rs, this would mean winit would expose its Display and WlSurface as rust type rather than raw pointers. This would allow much easier integration with third-party crates doing wayland stuff, as it'd not require any unsafe code. This kind of easy integration would remove some unsafe code from glutin, and allow clients to use winit under wayland without OpenGL easily (to do software rendering for example). It'd also ease integration of clipboard utilities (removing some more unsafe code).

For calloop, the potential gains are much larger. With the evl2 rewrite, both the x11 and wayland backend are now based on calloop, a simple event loop abstraction. Exposing it in the platform extension trait would allow winit users to register new sources of events to winit's event loop with callbacks, that would be seamlessly integrated to winit's main event loop run. This can be useful for apps that need to wait on network sockets for example, and would rather not spawn a new thread to handle them.

There could be a possibility to investigate if the other platforms could be united on using a calloop-powered event loop (calloop is built on mio which is rather multi-platform) to bring these functionalities to the other platforms.

None of this would occur before I've released versions 1.0 of calloop and wayland-rs of course, but I'd like to know what you'll think about it.

goddessfreya commented 5 years ago

Sounds like a cool idea, and if we could other platforms using it, I imagine it would help ease maintainability from unifying all those platforms.

elinorbgr commented 5 years ago

The "if we could get other platforms using it" is very not certain though. The easy thing on linux is that both Wayland and x11 take form of an unix socket connection, over which all is transmitted. It is thus pretty easy to monitor the associated file descriptor with mio/calloop and drive the event loop this way.

I really have no idea whether it's doable at all on other platforms...

aloucks commented 5 years ago

From my experience, crates that expose other crates as public dependencies in their API can cause some frustration. Ironically winit has caused me some grief when it's been a public dependency of other things.

I wouldn't say "no, never do that", but I would definitely weigh in some alternate options before deciding.

One trick might be to wrap the conversion functionality in a macro on the winit side. This would eliminate the hard dependency on the other crate(s), while still being ergonomic.

I do something like this here to avoid a hard dependency on winit: https://github.com/aloucks/vki/blob/master/src/macros.rs

elinorbgr commented 5 years ago

From my experience, crates that expose other crates as public dependencies in their API can cause some frustration.

That is specifically why I want to wait until wayland-client and calloop have reached 1.0 before doing anything like that though.

diwic commented 5 years ago

I really have no idea whether it's doable at all on other platforms...

The situation is worse on Windows: calloop is built on top of mio's event loop, which binds to IOCP, which is something primarily used to build highly scalable servers. A thread creating a window needs something that can process messages, mio cannot do that with its IOCP backend (AFAIK).

(Side note: I built https://crates.io/crates/thin_main_loop as an example of a main loop that binds to the APIs necessary for window creation a while ago, but it's alpha, and does not support anything else than Win32 and Glib platforms.)

elinorbgr commented 5 years ago

calloop is built on mio because on linux it is the smallest wrapper around epoll I could find. If other things should be used on other platforms, this can be changed. My initial use-case for calloop was for it to serve as an event loop for wayland compositors in smithay, hence why I ran for mio (for epoll), glib is a dependency I'd prefer to avoid. Similarly, I don't think we want winit to depend on glib (or Qt for that matter).

In general I see calloop and tiny_main_loop have pretty different design decision, but I don't think calloop would be hard to swap for thin_main_loop.

diwic commented 5 years ago

Sure. If thin_main_loop ever became the event loop used for winit, then it would need a non-glib backend for x11/wayland, possibly built on top of mio.

(If winit had a glib/GTK target and needed an event loop for that, then it would make sense to use the glib backend of thin_main_loop.)