-
Notifications
You must be signed in to change notification settings - Fork 946
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
monitor: refactor MonitorHandle
to store dyn object
#3927
base: master
Are you sure you want to change the base?
Conversation
42cbaa6
to
c6e43dc
Compare
f2b84f4
to
84c9ae6
Compare
I've removed |
9486937
to
4c94b55
Compare
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.
Procedurally, I would prefer if we did the "refactor VideoModeHandle
to VideoMode
with plain data" in a separate PR first, that would make this PR easier to thoroughly review - I just cannot deal with 49 changed files at once, sorry ;). (For my own part I've been dreading reviewing this for that reason, I suspect the other maintainers feel the same).
Also, I feel it's undesirable to remove the no-op monitors, at least at this point / in this PR? I think that would allow you to keep the docsrs
stuff in platform
?
If you're burned out on it, I can try to do it in a few days? I.e. splitting this PR into effectively three parts:
VideoModeHandle
->VideoMode
MonitorHandle
-> trait- Remove no-op monitor handles
pub struct MonitorHandle { | ||
pub(crate) inner: platform_impl::MonitorHandle, | ||
#[derive(Debug, Clone)] | ||
pub struct MonitorHandle(pub(crate) Arc<dyn MonitorHandleProvider>); |
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.
Hmm, what if we instead exposed Arc<dyn MonitorHandle>
to the user, and had MonitorHandle: PartialEq + Eq + Hash
?
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.
Ah, right, because PartialEq
and Hash
can't be dyn
.
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.
Maybe there are ways around that?
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'm not sure how it's useful, I decided to remove it for now. We can always bring those back.
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.
So I found a way to make it possible, see this playground link.
In terms of usefulness, I think it's nicer to have the ability to just compare monitor handles vs. having to compare ids (this goes for other handles too IMO).
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 implement this Eq
based on Id
you store internally though? Like without a trait the way we're doing it for 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.
You can, though that only works if monitor equality is implementable on a u64
, which I don't think it is on macOS?
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.
At the very least it needs to be u128
because it's a UUID (I think)
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, though that only works if monitor equality is implementable on a u64, which I don't think it is on macOS?
You tell me :- ). In general, an ID is something assigned to you by the display server for that exact reason to compare them. You could have a more verbose monitor IDs.
In general, Though, I don't mind PartialEq
that way given that you say that it works. Though, can send it separately, since you'll be touching other stuff along the lines.
You need to look only into the top-level and the ones for your backend, and given that both are in the same file, you'll have 2 PRs with the 49 files changed, just twice or more. If you feel like splitting then go ahead, I won't block on that, it's just way more work and by the time you've done it you'll review the PR. Probably not that bad in this context. |
That's true, I guess, the issue is that certain types don't really exist sometimes and we still try to build, so I've removed since we generally want to remove platform, so point in keeping it doesn't bring any benefit in my opinion and just creates more work, which is not great. Like once the split is done, you won't have |
I've extracted video mode from it here #4060 |
1436e3e
to
2644af5
Compare
Separated docsrs and monitor handle parts. |
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've opened #4138 to ensure that we don't forget to do something about the docs.rs situation before v0.31.
Thanks again for doing this, and sorry for the long delay in reviewing it. Have approved, the only real concern here is the u64
(native) vs. u128
(unique) ID comparisons, but that can also be fixed in a follow-up.
} | ||
|
||
fn system_theme(&self) -> Option<Theme> { | ||
None | ||
} | ||
|
||
fn primary_monitor(&self) -> Option<crate::monitor::MonitorHandle> { | ||
Some(crate::monitor::MonitorHandle { inner: 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.
Nit: I'd prefer to keep functional changes like these out of refactoring PRs in the future, but it's fine for now.
Though maybe add a changelog entry for 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.
It's not really functional iirc, since monitors are not supported.
@@ -499,22 +500,16 @@ impl EventLoopBuilderExtMacOS for EventLoopBuilder { | |||
|
|||
/// Additional methods on [`MonitorHandle`] that are specific to MacOS. | |||
pub trait MonitorHandleExtMacOS { | |||
/// Returns the identifier of the monitor for Cocoa. | |||
fn native_id(&self) -> u32; |
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.
Hmm, I believe there is value in keeping this (and hmonitor
on Windows too).
The reason is that the native_id
that is returned here is directly usable in FFI calls, since and will be two different values on macOS, UUID for comparisons and CGDirectDisplayID
as the native ID.
Maybe rename MonitorHandleProvider::native_id
to MonitorHandleProvider::unique_id
? Or maybe just MonitorHandleProvider::id
?
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 thing is that we use it in ffi
of some sort right now as well. Not sure how to go about it though.
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 should keep all the native_id
/hmonitor
/..., and provide a new MonitorHandleProvider::id
, which is a u128
whose representation isn't guaranteed.
/// Provider of the [`MonitorHandle`]. | ||
pub trait MonitorHandleProvider: AsAny + fmt::Debug + Send + Sync { | ||
/// Native platform identifier of this monitor. | ||
fn native_id(&self) -> u64; |
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.
Researched a bit more, monitors are equatable on macOS, but the ID is a UUID (i.e. 128 bits), and comparing the naive ID (CGDirectDisplayID
) is wrong (see
winit/src/platform_impl/apple/appkit/monitor.rs
Lines 116 to 118 in 3a39a6d
// `CGDirectDisplayID` changes on video mode change, so we cannot rely on that | |
// for comparisons, but we can use `CGDisplayCreateUUIDFromDisplayID` to get an | |
// unique identifier that persists even across system reboots |
fn native_id(&self) -> u64; | |
fn native_id(&self) -> u128; |
99e13e8
to
c8f517d
Compare
This also alters `VideoMode` to be a regular object and not reference the `MonitorHandle`, since it's a static data. Given that `VideoMode` set may change during runtime keeping the reference as a some sort of validity may not be idea and propagating errors when changing video mode could be more reliable.
Due to casts and use of platform specific crates in those modules it's not really feasible to build docs for them. After separating crates, thus should become way easier to navigate, since backends information would be publicly available.
c8f517d
to
551f496
Compare
This also alters
VideoMode
to be a regular object and not reference theMonitorHandle
, since it's a static data.Given that
VideoMode
set may change during runtime keeping the reference as a some sort of validity may not be idea and propagating errors when changing video mode could be more reliable.--
I'm not sure that I like how the monitor stuff looks, but I don't have a better idea. Ideally we want to have some sort of
MonitorId
which is more reliable in representing and split theMonitorHandle
intoId
and a way to get the data for the monitor, but I think I'd rather leave it for the future.The
native_id
thing I've moved is already present on all the platforms, so I'd really see why not and usually platforms have some way to address the monitors and backends may build such addressing themselves.It could make sense to change
native_id() -> u64
toMonitorId(u64)
.