-
Notifications
You must be signed in to change notification settings - Fork 894
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
Handle error cases in MonitorHandle
#2646
base: master
Are you sure you want to change the base?
Conversation
44d5ca8
to
ff6594f
Compare
That's not an option. Would suggest to return a |
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 we could add a MonitorDescription
or something like that and access it within the callback?
Then on the monitor handle itself we could have 2 methods.
fn is_alive(&self) -> bool;
fn with_description<T, F: Fn(MonitorDescription) -> T>(&self) -> Result<T>;
Then on that data you can access the things you need, that way it'll be less result
unwraps and such.
There is no callback you could write in which If we do that though, then I think I'd rather just rename
I actually think the
Vs. returning a
Of course, for the things that are fundamentally not possible to support, then we should do change the API. In any case, we should consider making video modes match monitors: So either we have |
Unfortunately this clashes with #2658.
This sounds like unnecessary complexity for the sake of consistency. That said, returning a The one part of |
I did a small error in the API. We need a fn is_alive(&self) -> bool;
fn with_description<T, F: Fn(&MonitorDescription) -> T>(&self) -> Result<T>;
No, the point is that you have a handle which might be long dead (
No, that will drive people to whine and complain, not to implement. Maybe that's my experience, but for example, over the years in alacritty no-one bothers to fix bugs on macOS even though they are relatively simple, the same will be about other bugs. Having potential crashes like that isn't a good idea for a library that is around for a long time. |
How to deal with the situation that the handle value is reused, which will cause consistency problems, how about using |
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.
Small nits, otherwise LGTM!
@@ -346,7 +346,7 @@ impl<T> EventLoopWindowTarget<T> { | |||
} | |||
|
|||
pub fn primary_monitor(&self) -> Option<MonitorHandle> { | |||
Some(MonitorHandle) | |||
None |
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.
Great change!
The documentation on EventLoopWindowTarget::primary_monitor()
has to be updated though.
pub fn scale_factor(&self) -> f64 { | ||
1.0 | ||
pub fn scale_factor(&self) -> Result<f64, MonitorGone> { | ||
unimplemented!() |
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 believe in this case it should actually be unreachable!()
, though unimplemented!()
is nice, in this case it should be literally unreachable.
pub struct MonitorGone { | ||
_inner: (), | ||
} |
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.
pub struct MonitorGone { | |
_inner: (), | |
} | |
pub struct MonitorGone(()); |
I don't have a preference here, but I think we should stick with something, I've seen this in tuple-form more often in our code base then in struct-form.
Alternatively (not advocating for it):
pub struct MonitorGone { | |
_inner: (), | |
} | |
#[non_exhaustive] | |
pub struct MonitorGone; |
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 like the approach because the problem is that lifetime should be attached to the event loop, where we don't do that. This problem is solved on winit-next where monitor handle has its own ID and you retrieve it from the event loop, thus none of that can happen on all the platforms.
Adding results to every method doesn't sound appealing to me.
We talked a bit about this in Friday's meeting, the API should stay mostly the same, but instead each backend should cache the required data about the monitor, such that the data can always be retrieved. I don't think I communicated this properly then, but I think it'd be fine for the backend to keep a reference to the monitor data alive, if that's enough that it can be fetched. Internally, it would be something like: // Backend 1
struct MonitorHandle {
// Not retrievable from the handle if the monitor is disconnected, so cached here
cached_data: {
name: String,
refresh_rate: u32,
...
},
// Used when entering fullscreen on the monitor
handle: *mut MyHandle,
}
// Backend 2
struct MonitorHandle {
// Used when entering fullscreen on the monitor, and to retrieve data about the monitor
handle: Arc<MyHandle>,
} |
I think we should keep it consistent and not do fetching on some backends and on others we cache. Because we will have to add a big note saying "this data is cached and reflects the state when it was retrieved". Adding backend specific exceptions makes this even more unintuitive. I would still be fine to leaving things as proposed here, with returning a |
In the current state of thins it shouldn't cache, since there's no way to propagate that the cache got invalidated or the data got updated. |
What changed your mind? Because that is what we agreed on the last time. |
All backends right now don't cache and kind of live update or query the data. I guess I misunderstood it, since I thought that we shouldn't cache in the future. Right now to remove reload/cache of data in handles it'll require to likely rewrite all of them all together, so this PR will be way bigger than report errors. |
Or what do you mean by caching in particular, like remember last asked value or use only POD and update when the user queries the monitor? |
The idea was to use POD only, no updating. If you want updated values you have to query the monitor from the event loop again. It might be sensible to add an |
Yeah, it's just will have to rewrite all the monitor handles code, since everything is doing the opposite. I'm not against that though, just way more work for this patch and it does completely different compared to this patch. |
Part of #971.
Makes all
MonitorHandle
methods fallible. The same is not done forVideoMode
, since they are just static blobs of data (rather than something queried dynamically) (but that might change in the future?).CHANGELOG.md
if knowledge of this change could be valuable to usersUnresolved
I'm unsure what we should do in the case where some functionality isn't implemented yet? Is the correct thing to return a dummy value? Perhaps it would actually be better if we just panic with an
unimplemented!()
?Though in any case I think this PR is an improvement over the status quo.