-
Notifications
You must be signed in to change notification settings - Fork 910
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
feat: Add a safe method for cross-crate interop to winit #2744
Conversation
cc @Lokathor |
I think that the new crate should also have the Zlib license as a license option the same as the raw-window-handle crate does, but otherwise it seems like an entirely appropriate "one level up" abstraction |
Sounds good to me, done in notgull/window-handle@64e1dfa! |
I wonder whether raw-window-handle itself should provide such abstraction in addition, simply because it's also a no_std single rwhd dep crate? So we'll have the same crate for such handles which we could stabilize and use? Managing 2 separate crates for handles could be not that easy, because you'd need to update both at the same time if raw-window-handle break something(like we want to add |
I would support this, I can file a PR if you want @Lokathor |
I'd be entirely fine with adding this right into the existing crate. |
Updated for rust-windowing/raw-window-handle#110 |
CI failures are due to having two versions of |
i can do a 0.5.1 later tonight |
That'd be great. That being said, I'd like to make sure that we aren't too hasty to commit to any design decisions, and give some time to let people respond to rust-windowing/raw-window-handle#111 |
Alright, good point. Since it's just one CI pass out of many, and since this is just a draft, we'll wait for more feedback. |
Ported to rust-windowing/raw-window-handle#116 |
Implements HasDisplayHandle so the handle can be used easily
|
Apple CI is failing because of madsmtm/objc2#432, and the other CI is failing because of |
/// querying the display's resolution or DPI, without having to create a window. It | ||
/// implements `HasDisplayHandle`. | ||
#[derive(Clone)] | ||
pub struct OwnedDisplayHandle { |
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.
I don't really understand the purpose of this type. The EventLoop
itself is what should have the HasDisplayHandle
impl, and its lifetime is what should be used. The fact that you're not using this type in examples at all suggests me that there's no clear case when it should be used(at least you should use it inside the examples).
The EventLoopWindowTarget
must have the same lifetime as the EventLoop
itself, because it's simply a field on EventLoop
in all the backends.
The Clone
is also sort of questionable, because it simply will discard the lifetime attached to it, given that there's only a way to get &OwnedDisplayHandle
not the owned type on its own?
if that's intent on lifetime
casting, different method should be used with unsafe
bit on it(because it's simply mem::tranmsute
like thingy of donig 'static
lifetime).
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.
The reason why this type exists is for the glutin
case. The scenario is that you need an object that has a display handle before a window is created, since you need to query the display. You can't use EventLoop
, &EventLoop
or a DisplayHandle<'_>
taken from an EventLoop
because the EventLoop
is owned/borrowed mutably for event handling. You can't use the EventLoopWindowTarget
that is provided in the event handler, since it disappears between events, which means it can't be used persistently. Normally I'd use a Window
, but for glutin
(outside of Win32) you haven't created a Window
yet.
Therefore I created this type to fill that hole. Something that implements HasDisplayHandle
that can be used according to Rust's borrowing system. This way, it can be used in the display position without any unsafe hacks.
If the actually, it might be necessary for the borrowing rules to check out in this case.Clone
is a deal breaker I can get rid of it.
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.
actually, it might be necessary for the borrowing rules to check out in this case.
I just think that it's unsafe
, so you might have different method like to_static
, which casts away lifetime.
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.
I have added documentation clarifying the purpose of OwnedWindowHandle
and why it is safe.
src/event_loop.rs
Outdated
/// This type allows one to take advantage of the display's capabilities, such as | ||
/// querying the display's resolution or DPI, without having to create a window. It | ||
/// implements [`HasDisplayHandle`]. | ||
/// |
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.
I think you can't query anything from it.
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.
I removed the part about querying. "Capabilities" should be enough to describe what it can be used for.
@@ -99,6 +100,11 @@ impl<T> PeekableReceiver<T> { | |||
} | |||
} | |||
|
|||
#[derive(Clone)] | |||
pub struct OwnedDisplayHandle { | |||
xconn: Arc<XConnection>, |
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.
you can use Rc
for it given that it's neither send nor sync.
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.
The object that's being passed around uses an Arc
because it's being stored in a static variable.
winit/src/platform_impl/linux/mod.rs
Lines 118 to 120 in fbea75d
#[cfg(x11_platform)] | |
pub(crate) static X11_BACKEND: Lazy<Mutex<Result<Arc<XConnection>, XNotSupported>>> = | |
Lazy::new(|| Mutex::new(XConnection::new(Some(x_error_callback)).map(Arc::new))); |
If we want to transition away from this model, it'd probably need to take place outside of this PR.
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.
Hm, that's fair.
Hey, sorry to be late catching up with these changes but I was away for a week and missed the RFC poke on rust-windowing/raw-window-handle#111 I'm a little worried that we may have made quite a significant design change that perhaps wasn't required for Android, while I don't currently know that there was a safety/soundness issue. Following the bread crumbs I wrote some initial thoughts here: rust-windowing/raw-window-handle#111 (comment) a quick comment on rust-windowing/raw-window-handle#110 (comment) and a comment on rust-windowing/raw-window-handle#116 Maybe there are multiple reasons for the changes, and i'm just looking at this from the pov of the Android backend, but still figured I should follow up |
No worries! We're still in the early days of this feature. I responded to your posts. The overarching theme is that the docs seem to indicate that you cannot access the native window handle after it's been dropped.
|
Superseded by #2943 |
CHANGELOG.md
if knowledge of this change could be valuable to usersOne of the main complaints with the current Rust GUI ecosystem is that interoperability requires unsafe code. As of now, the
raw-window-handle
crate is used for interoperability; however, it has two disadvantages:raw-window-handle
probably isn't at the appropriate level of abstraction to be fixing this anyways. However, this has led to some friction in crates that depend on it (gfx-rs/wgpu#1463 and rust-windowing/softbuffer#80 off the top of my head). I created awindow-handle
crate in an attempt to solve this. The new features are:Active
struct is used to access the window handles.Active
can only exist when the application isn't suspended.This PR adds the current implementation of
window-handle
to this crate and implements its traits. This PR also serves as a request for comments on thewindow-handle
crate. I'm not familiar with all of the platforms, so it's likely that there's some invariant that I've missed.