-
Notifications
You must be signed in to change notification settings - Fork 921
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Winit Features and Scope #695
Changes from 8 commits
1605adc
1133995
4df37e4
cd6a6c8
479cf5d
81d7458
915eb6d
f99c8ea
fe70a66
8b5065e
8c64495
ed0a3a6
67b9176
bf2fb85
554cd23
26c41ba
60208e5
ad41504
54abf0a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,187 @@ | ||
# Winit Scope | ||
|
||
Winit aims to expose an interface that abstracts over window creation and input handling, and can | ||
be used to create both games and applications. It supports the main graphical platforms: | ||
- Desktop | ||
- Windows | ||
- macOS | ||
- Unix | ||
- via X11 | ||
- via Wayland | ||
- Mobile | ||
- iOS | ||
- Android | ||
- Web | ||
- via Emscripten | ||
- via WASM ***//DISCUSS: DO WE WANT TO SUPPORT THIS?*** | ||
|
||
Most platforms expose capabilities that cannot be meaningfully transposed onto others. Winit does not | ||
aim to support every single feature of every platform, but rather to abstract over the common features | ||
available everywhere. In this context, APIs exposed in winit can be split into different "support tiers": | ||
|
||
- **Core:** Features that are essential to providing a well-formed abstraction over each platform's | ||
windowing and input APIs. | ||
- **Platform:** Platform-specific features that can't be meaningfully exposed through a common API and | ||
cannot be implemented outside of Winit without exposing a significant amount of Winit's internals | ||
or interfering with Winit's abstractions. | ||
- **Usability:** Features that are not strictly essential to Winit's functionality, but provide meaningful | ||
usability improvements and cannot be reasonably implemented in an external crate. These are | ||
generally optional and exposed through Cargo features. | ||
|
||
Core features are taken care of by the core Winit maintainers. Platform features are not. | ||
When a platform feature is submitted, the submitter is considered the expert in the | ||
feature and may be asked to support the feature should it break in the future. | ||
|
||
Winit ***does not*** directly expose functionality for drawing inside windows or creating native | ||
menus, but ***does*** commit to providing APIs that higher-level crates can use to implement that | ||
functionality. | ||
|
||
## `1.0` and stability | ||
|
||
When all core features are implemented to the satisfaction of the Winit maintainers, Winit 1.0 will | ||
be released and the library will enter maintenance mode. For the most part, new core features will not | ||
be added past this point. New platform features may be accepted and exposed through point releases. | ||
***//DISCUSS: IS THIS ACCURATE?*** | ||
Osspial marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
### Tier upgrades | ||
Some platform features could in theory be exposed across multiple platforms, but have not gone | ||
through the implementation work necessary to function on all platforms. When one of these features | ||
gets implemented across all platforms, a PR can be opened to upgrade the feature to a core feature. | ||
If that gets accepted, the platform-specific functions gets deprecated and become permanently | ||
exposed through the core, cross-platform API. | ||
***//DISCUSS: DO WE WANT TO HAVE THIS BE AN OFFICIAL PROCESS, OR NO?*** | ||
Osspial marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
# Features | ||
|
||
## Core | ||
|
||
Osspial marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Tables detailing feature compatibility across platforms can be found in the wiki ***//TODO: MAKE LINK*** | ||
|
||
### Windowing | ||
- **Window initialization**: Winit allows the creation of a window | ||
- **Pointer to OpenGL**: Winit provides the necessary pointers to initialize a working opengl context | ||
- **Pointer to Vulkan**: Same as OpenGL but for Vulkan | ||
- **Window decorations**: The windows created by winit are properly decorated, and the decorations can | ||
be deactivated | ||
- **Window decorations toggle**: Decorations can be turned on or off after window creation | ||
- **Window resizing**: The windows created by winit can be resized and generate the appropriate events | ||
when they are. The application can precisely control its window size if wanted. | ||
- **Window transaprency**: Winit allows the creation of windows with a transparent background. | ||
Osspial marked this conversation as resolved.
Show resolved
Hide resolved
|
||
- **Window maximization**: The windows created by winit can be maximized upon creation. | ||
- **Window maximization toggle**: The windows created by winit can be maximized and unmaximized after | ||
creation. | ||
- **Fullscreen**: The windows created by winit support being fullscreen. | ||
- **Fullscreen toggle**: The windows created by winit can be switched to and from fullscreen after | ||
creation. | ||
- **Child windows**: Windows can be created relative to the client area of other windows, and parent | ||
windows can be disabled in favor of child windows. | ||
***//DISCUSS: SHOULD THIS BE SUPPORTED?*** | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe this can be in scope for winit. As you said (at least on wayland) creating child window require direct platform interaction in general, and can be difficult to expose without exposing a lot of winit's internals. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
What it really means for a window to be a child window is still slightly unclear to me, maybe a description of what a child window can offer that another regular window cannot would be worth adding? Reading the current entry, It seems to me that the relative positioning could be solved using the difference between I guess I just want to make sure we're not exposing something that could otherwise be done using application logic in order to reduce the winit surface area. I'm also a little concerned that the concept of a "child" window and what that means might be different per platform, though I haven't actually looked into this at all yet - it could very well have a very specific meaning across each platform. All that said, I have read some users mention that child windows are simply essential in some use cases. One example that comes to mind is the VST API, though I don't know much about it. |
||
|
||
|
||
### System Information | ||
- **Monitor list**: Retrieve the list of monitors and their metada, including which one is primary is applicable | ||
Osspial marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
### Input Handling | ||
- **Mouse events**: Generating mouse events associated with pointer motion, click, and scrolling events. | ||
- **Mouse set location**: Forcibly changing the location of the pointer. | ||
- **Cursor grab**: Locking the cursor so it cannot exit the client area of a window. | ||
- **Cursor icon**: Changing the cursor icon, or hiding the cursor. | ||
- **Touch events**: Single-touch events. | ||
- **Multitouch**: Multi-touch events, including cancellation of a gesture. | ||
- **Keyboard events**: Properly processing keyboard events using the user-specified keymap and | ||
translating keypresses into UTF-8 characters, handling dead keys and IMEs. | ||
- **Drag & Drop**: Dragging content into winit, detecting when content enters, drops, or if the drop is cancelled. | ||
***//DISCUSS: WINIT SUPPORTS FILE DROPS, BUT NOT TEXT OR IMAGE DROPS*** | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, this is a point I discussed in an earlier issue / PR. I don't know how this works for other platforms, but in wayland, drag'n'drop is unified for all kind of contents. The way it works is that the application starting the d'n'd and the application receiving it negociate a mime type for the data transfer. Dragging files from a file explorer is just a special case of this. Can this kind of general behavior be transposed to other platforms? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I assume? I know that it works on Windows, and I'm pretty sure I've done it before on macOS and X11 but I can't quite recall. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can confirm that it's similar on X11 and macOS, so I think we can reasonably provide this functionality. Also, what about knowing the hover position and being able to decide whether to accept or reject a drop (based on both position and type)? Anyone building GUIs on top of winit will demand this, and it's at least easy to implement on X11. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
That's also the natural way it works on wayland. With the added case that the sender application can actually provide a list of available mime types that the receiver can choose from. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From skimming the Windows code, that also seems to be how Windows does it. The one question I have is how do we implement communication from the callback back to the operating system to accept or reject the drop? The best way I can think of doing it would be to pass a mutable reference along with the event that the callback can modify (as otherwise we're getting into the realm of having different return types for different events), but that isn't possible on Windows before Event Loop 2.0 gets merged. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Another thing - Winit supports dragging content into windows. Should we support dragging content from windows? In principle I'm not opposed to it, but I don't know what the API would look like and it starts to turn Winit from windowing and user input to general cross-platform desktop interfacing which is a substantially bigger project. Perhaps we could publicly expose some of Winit's internals in a permanently unstable way (say, hide them behind a feature or make them all |
||
- **Clipboard**: Winit supports copy-pasting content to and from winit. | ||
***//DISCUSS: AN ISSUE SHOULD BE OPENED REGARDING HOW THIS API SHOULD WORK*** | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed. I believe this was already decided that this is in scope for winit. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've opened an issue to discuss how that should work at #704 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The more I think about it, the less comfortable I am declaring this as in-scope for Winit. Right now, Winit does a decent job of keeping the scope of its API small as exclusively a window creation library, and adding clipboard support starts to turn it into a grab-bag of assorted desktop interfacing tools. I don't want to be in a situation where Winit starts snowballing and gaining more and more features that aren't directly related to windowing/user input because it doesn't expose enough of its internals. @vberger If we exposed Winit's pointers to the Wayland environment through |
||
- **Raw Device Events**: Capturing input from input devices without any OS filtering. | ||
- **Gamepad/Joystick events**: Capturing input from gampads and joysticks. | ||
***//DISCUSS: SHOULD THIS BE SUPPORTED?*** | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While on X11 this can be done without winit, on wayland this requires at least some collaboration from winit to be possible. I don't know about other platforms. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is something I've gone back and forth on a lot in my head, though I've ultimately been leaning in favor of it. As @Osspial said, it's something people expect, and it's still largely an open problem in the Rust ecosystem. I'm pretty happy with the results I've had implementing Raw Input and XInput gamepad support on Windows. Since supporting Raw Input requires a window to receive events (which is why it was said to be out of scope for gilrs), and we already have a bunch of Raw Input abstractions in master, winit is really the simplest place this could be handled. While XInput is polling-based, XInput devices also send Raw Input events, so I was able to rely on that both to only poll when I know we won't have to wait, and to dynamically register which XInput devices are connected and disconnected (attempting to poll a nonexistent XInput device is very slow, and AFAIK there's no part of the XInput API for enumerating devices). I think all of this is a great boon, and it's something I don't think could be implemented as elegantly if done outside of winit. There's the issue of other platforms, though. On Linux, X11 and evdev are rather orthogonal, and different implementations will be required for BSD/etc. I haven't researched macOS at all, or the situation with the non-desktop platforms. Before pursuing a feature like this, I'd want us to have a clear view of how it would be integrated into the event loop on each platform. It's also worth noting that device-specific code is often needed to support force feedback, though Chromium is a good reference for that and it doesn't seem that extensive. I think that any gamepad support provided by winit should be "low level", which is to say, a stream of events that's been transformed only enough to have a consistent format across platforms. Something like SDL mappings would have to be applied downstream, though we'd still have to research what info we'd need to provide for that to be possible. |
||
- **Device movement events:**: Capturing input from the device gyroscope and accelerometer. | ||
***//DISCUSS: SHOULD THIS BE SUPPORTED?*** | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suppose this is mostly relevant for iOS/Android platforms? I'd say that if we decide Gamepad/Joystick is in scope for winit, then this should be as well. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, and it looks like it's supported on Emscripten as well. I don't know if it works on desktop platforms, though. I agree that it makes sense to talk about these in the same category as gamepad/joystick events. |
||
|
||
## Platform | ||
### Windows | ||
* Setting the taskbar icon (Maintainer: ***???***) | ||
* Setting the parent window (Maintainer: ***???***) | ||
***//DISCUSS: SHOULD THIS BE SUBSUMED INTO A CORE CHILD WINDOW FEATURE?*** | ||
* `WS_EX_NOREDIRECTIONBITMAP` support (Maintainer: ***???***) | ||
|
||
### macOS | ||
* Window activation policy (Maintainer: ***???***) | ||
* Window movable by background (Maintainer: ***???***) | ||
* Transparent titlebar (Maintainer: ***???***) | ||
* Hidden titlebar (Maintainer: ***???***) | ||
* Hidden titlebar buttons (Maintainer: ***???***) | ||
* Full-size content view (Maintainer: ***???***) | ||
* Resize increments (Maintainer: ***???***) ***//DISCUSS: SHOULD RESIZE INCREMENTS BE CORE?*** | ||
|
||
### Unix | ||
* Window urgency (Maintainer: ***???***) | ||
* X11 Window Class (Maintainer: ***???***) | ||
* X11 Override Redirect Flag (Maintainer: ***???***) | ||
* GTK Theme Variant (Maintainer: ***???***) | ||
* Resize increments (Maintainer: ***???***) ***//DISCUSS: SHOULD RESIZE INCREMENTS BE CORE?*** | ||
* Base window size (Maintainer: ***???***) | ||
|
||
## Usability | ||
* `icon_loading`: Enables loading window icons directly from files. (Maintainer: @francesca64) | ||
* `serde`: Enables serialization/deserialization of certain types with Serde. (Maintainer: @Osspial) | ||
|
||
# Compatibility Matrix - Move to wiki on merge | ||
|
||
Each section includes a collapsed description of the features it lists. | ||
|
||
Legend: | ||
|
||
- ✔️: Works as intended | ||
- ▢: Mostly works but some bugs are known | ||
- ❌: Missing feature or large bugs making it unusable | ||
- **N/A**: Not applicable for this platform | ||
- ❓: Unknown status | ||
|
||
## Windowing | ||
|Feature |Windows|MacOS |Linux x11|Linux Wayland|Android|iOS |Emscripten| | ||
|-------------------------------- | ----- | ---- | ------- | ----------- | ----- | ----- | -------- | | ||
|Window initialization |✔️ |✔️ |▢#5 |✔️ |▢#33 |▢#33 |❓ | | ||
|Providing pointer to init OpenGL |✔️ |✔️ |✔️ |✔️ |✔️ |✔️ |❓ | | ||
|Providing pointer to init Vulkan |✔️ |✔️ |✔️ |✔️ |✔️ |❓ |**N/A** | | ||
|Window decorations |✔️ |✔️ |✔️ |▢#306 |**N/A**|**N/A**|**N/A** | | ||
|Window decorations toggle |✔️ |✔️ |✔️ |✔️ |**N/A**|**N/A**|**N/A** | | ||
|Window resizing |✔️ |▢#219 |✔️ |▢#306 |**N/A**|**N/A**|❓ | | ||
|Window transparency |✔️ |✔️ |✔️ |✔️ |**N/A**|**N/A**|**N/A** | | ||
|Window maximization |✔️ |✔️ |✔️ |✔️ |**N/A**|**N/A**|**N/A** | | ||
|Window maximization toggle |✔️ |✔️ |✔️ |✔️ |**N/A**|**N/A**|**N/A** | | ||
|Fullscreen |✔️ |✔️ |✔️ |✔️ |**N/A**|**N/A**|❌ | | ||
|Fullscreen toggle |✔️ |✔️ |✔️ |✔️ |**N/A**|**N/A**|❌ | | ||
|HiDPI support #105 |✔️ |✔️ |✔️ |✔️ |▢ |✔️ |✔️ | | ||
|Child windows ***//DISCUSS*** |❌ |❌ |❌ |❌ |❌ |❌ |❌ | | ||
|
||
## System information | ||
|Feature |Windows|MacOS |Linux x11|Linux Wayland|Android|iOS |Emscripten| | ||
|------------ | ----- | ---- | ------- | ----------- | ----- | ----- | -------- | | ||
|Monitor list |✔️ |✔️ |✔️ |✔️ |**N/A**|**N/A**|**N/A** | | ||
|
||
## Input handling | ||
|Feature |Windows|MacOS |Linux x11|Linux Wayland|Android|iOS |Emscripten| | ||
|--------------------------------------- | ----- | ---- | ------- | ----------- | ----- | ----- | -------- | | ||
|Mouse events |✔️ |▢#63 |✔️ |✔️ |**N/A**|**N/A**|✔️ | | ||
|Mouse set location |✔️ |✔️ |✔️ |❓ |**N/A**|**N/A**|**N/A** | | ||
|Cursor grab |✔️ |▢#165 |▢#242 |❌#306 |**N/A**|**N/A**|✔️ | | ||
|Cursor icon |✔️ |✔️ |✔️ |❌#306 |**N/A**|**N/A**|❌ | | ||
|Touch events |✔️ |❌ |✔️ |✔️ |✔️ |✔️ |✔️ | | ||
|Multitouch |❓ |❌ |✔️ |✔️ |❓ |❌ |❌ | | ||
|Keyboard events |✔️ |✔️ |✔️ |✔️ |❓ |❌ |✔️ | | ||
|Drag & Drop |✔️ |✔️ |✔️ |❌#306 |❌ |❌ |❌ | | ||
|Clipboard #162 |❌ |❌ |❌ |❌ |❌ |❌ |❌ | | ||
|Raw Device Events |▢*#??*|▢*#??*|▢*#??* |❌ |❌ |❌ |❌ | | ||
|Gamepad/Joystick events ***//DISCUSS*** |❌ |❌ |❌ |❌ |❌ |❌ |❌ | | ||
|Device movement events ***//DISCUSS*** |❓ |❓ |❓ |❓ |❌ |❌ |❌ | | ||
|
||
## Pending API Reworks | ||
Changes in the API that have been agreed upon but aren't implemented across all platforms. | ||
|
||
|Feature |Windows|MacOS |Linux x11|Linux Wayland|Android|iOS |Emscripten| | ||
|------------------------------ | ----- | ---- | ------- | ----------- | ----- | ----- | -------- | | ||
|New API for HiDPI (#315 #319) |✔️ |✔️ |✔️ |✔️ |▢*#??* |✔️ |✔️ | | ||
|Event Loop 2.0 (#459) |❌#638|❌ |❌ |❌ |❌ |❌ |❌ | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Emscripten is tough to install, and furthermore there is a lot of attention on the wasm without emscripten ecosystem. I think that it certainly should be supported.