JohnCoates / Aerial

Apple TV Aerial Screensaver for Mac
MIT License
20.77k stars 1.05k forks source link

Screen Savers broken on 2+ monitor system in macOS Sonoma 14.0 #1305

Open xmddmx opened 1 year ago

xmddmx commented 1 year ago

This is a follow-up thread to https://github.com/JohnCoates/Aerial/issues/1286

Initial testing with macOS Sonoma (first beta, 23a5257q) suggests the problem has worsened again:

Conclusion: the first beta of Sonoma 14.0 is broken, and seems to be as broken as early betas of Ventura 13.3.

glouel commented 1 year ago

I'm still seeing the bug where the screens are launched out of order: screen[1] before screen[0], and the coordinates are wrong (both screens claim to be located at 0,0 )

I think the 0,0 is sadly the new normal, which may make it a huge issue to detect which screen is which, assuming you have two same sized screens. I have to ask, since you have 2 screens with different resolutions, I assume you get the correct window size for each (so no black zones/scaled out stuff ?).

We may need new solutions to detecting which screen we are on, I had a halfway working prototype for that but haven't been able to touch it in a week (may still not for a couple more days).

Out of order launch, same, might be the new normal and not something we can rely on.

Are you having any trouble having more than one copy of Aerial installed and finding the OS won't launch the correct one?

I'm troubled by your description of "more than one copy", you can only get one copy of your screen saver installed at a time, unless you install one as a user and one for everyone, but that's always been a utter mess.

Overall I think this may be because you need for force quit legacyScreenSaver when you install a new version. legacyScreenSaver will keep the old version in memory and keep running it until it gets killed/relaunch. I can see that failing if it needs to load stuff, and revert to a system one in that case. System settings, being its own thing, launch the screensaver separately and will immediately load the new build. ScreenSaverEngine (or whatever that is now) won't.

So make sure you kill legacyScreenSaver before installing a build.

xmddmx commented 1 year ago

I'm troubled by your description of "more than one copy", you can only get one copy of your screen saver installed at a time, unless you install one as a user and one for everyone, but that's always been a utter mess.

Well, in prior OSs I used to be able to make a screensaver, "Screensaver build 1000", and then make a new build in XCode, name it "Screensaver build 1001" and have both installed, and switch between them at will. I do this when debugging, as it makes it very easy to A/B test a new feature or bugfix.

This technique is no longer working in Sonoma: Screensaver 1000 will work in Preview and HotCorner mode, but Screensaver 1001 only works in Preview, but fails in HotCorner mode (the OS runs 'Ventura' saver instead). I believe I've also seen cases where I thought 1001 was running but 1000 was.

I am copying these screensavers from one mac to another, and I'm wondering if I've got some issue with code-signing or notarization?

I'll test your idea about force-quitting legacyscreensaver as well.

I think the OS used to get confused if two installed .savers had the same bundleID, so I'll play around with changing that as well...

glouel commented 1 year ago

Well you must force quit legacyScreenSaver for it to reload in Sonoma, this is what I have to do right now when I make a new build with the same bundle id. You could install 2 screensavers with the same bundle id and different filenames alongside each other, but System Settings didn't load the correct XIBs when you did that for your UI. So try that.

glouel commented 1 year ago

TLDR : Don't use spanned mode in Aerial in Sonoma

Extra beta 4 thoughts :

2023-07-26 18:27:26.533 : ๐Ÿ–ผ๏ธ <AerialView: 0x14a332ff0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.534 : ๐Ÿ–ผ๏ธ <AerialView: 0x14a2ca0a0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.534 : ๐Ÿ–ผ๏ธ <AerialView: 0x14cf0b1c0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.535 : ๐Ÿ–ผ๏ธ <AerialView: 0x14a3ee570> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.535 : ๐Ÿ–ผ๏ธ <AerialView: 0x148e1cea0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.535 : ๐Ÿ–ผ๏ธ <AerialView: 0x14a071a00> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.535 : ๐Ÿ–ผ๏ธ <AerialView: 0x14a4394c0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.535 : ๐Ÿ–ผ๏ธ <AerialView: 0x14a444fc0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.536 : ๐Ÿ–ผ๏ธ <AerialView: 0x14a3c89d0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.536 : ๐Ÿ–ผ๏ธ <AerialView: 0x14a3e5d90> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.536 : ๐Ÿ–ผ๏ธ <AerialView: 0x14ca22930> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.536 : ๐Ÿ–ผ๏ธ <AerialView: 0x13a345be0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.537 : ๐Ÿ–ผ๏ธ <AerialView: 0x13a345f40> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.537 : ๐Ÿ–ผ๏ธ <AerialView: 0x14a272b50> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.537 : ๐Ÿ–ผ๏ธ <AerialView: 0x14a4281f0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.537 : ๐Ÿ–ผ๏ธ <AerialView: 0x14a2a5e30> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.538 : ๐Ÿ–ผ๏ธ <AerialView: 0x13a306b10> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.538 : ๐Ÿ–ผ๏ธ <AerialView: 0x14a2fcf30> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.538 : ๐Ÿ–ผ๏ธ <AerialView: 0x14a2a9890> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.538 : ๐Ÿ–ผ๏ธ <AerialView: 0x13a376d50> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.538 : ๐Ÿ–ผ๏ธ <AerialView: 0x148f3bed0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.539 : ๐Ÿ–ผ๏ธ <AerialView: 0x13a370cb0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.539 : ๐Ÿ–ผ๏ธ <AerialView: 0x14ca36200> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.539 : ๐Ÿ–ผ๏ธ <AerialView: 0x14a083ea0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.539 : ๐Ÿ–ผ๏ธ <AerialView: 0x14a431520> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.540 : ๐Ÿ–ผ๏ธ <AerialView: 0x13a376750> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.540 : ๐Ÿ–ผ๏ธ <AerialView: 0x14a0c73c0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.540 : ๐Ÿ–ผ๏ธ <AerialView: 0x12882fa50> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.540 : ๐Ÿ–ผ๏ธ <AerialView: 0x14c93d2e0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.540 : ๐Ÿ–ผ๏ธ <AerialView: 0x128a62fd0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.541 : ๐Ÿ–ผ๏ธ <AerialView: 0x14cf7ce80> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.541 : ๐Ÿ–ผ๏ธ <AerialView: 0x13a3a3930> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.541 : ๐Ÿ–ผ๏ธ <AerialView: 0x14cf38ab0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.541 : ๐Ÿ–ผ๏ธ <AerialView: 0x14a0ec970> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.541 : ๐Ÿ–ผ๏ธ <AerialView: 0x128a9cf00> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.542 : ๐Ÿ–ผ๏ธ <AerialView: 0x14cf3a850> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.542 : ๐Ÿ–ผ๏ธ <AerialView: 0x14ca3eff0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.542 : ๐Ÿ–ผ๏ธ <AerialView: 0x12c60dc40> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.542 : ๐Ÿ–ผ๏ธ <AerialView: 0x12884be60> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.542 : ๐Ÿ–ผ๏ธ <AerialView: 0x14cf2cdd0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.542 : ๐Ÿ–ผ๏ธ <AerialView: 0x14cf95130> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.543 : ๐Ÿ–ผ๏ธ <AerialView: 0x14cfe1090> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.543 : ๐Ÿ–ผ๏ธ <AerialView: 0x14cf5d090> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.543 : ๐Ÿ–ผ๏ธ <AerialView: 0x128afe410> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.543 : ๐Ÿ–ผ๏ธ <AerialView: 0x14cfb3270> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.543 : ๐Ÿ–ผ๏ธ <AerialView: 0x14cfcf9a0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.543 : ๐Ÿ–ผ๏ธ <AerialView: 0x14cfc7f10> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.544 : ๐Ÿ–ผ๏ธ <AerialView: 0x14a2b1310> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.544 : ๐Ÿ–ผ๏ธ <AerialView: 0x1323d3090> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.544 : ๐Ÿ–ผ๏ธ <AerialView: 0x12ede9e70> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.544 : ๐Ÿ–ผ๏ธ <AerialView: 0x13080fd30> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.544 : ๐Ÿ–ผ๏ธ <AerialView: 0x12c6e43f0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.545 : ๐Ÿ–ผ๏ธ <AerialView: 0x11f253a70> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.545 : ๐Ÿ–ผ๏ธ <AerialView: 0x11f253470> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.545 : ๐Ÿ–ผ๏ธ <AerialView: 0x12c6f63b0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.545 : ๐Ÿ–ผ๏ธ <AerialView: 0x148f7baa0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.553 : ๐Ÿ–ผ๏ธ <AerialView: 0x14a332ff0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.553 : ๐Ÿ–ผ๏ธ <AerialView: 0x14a2ca0a0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.554 : ๐Ÿ–ผ๏ธ <AerialView: 0x14cf0b1c0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.554 : ๐Ÿ–ผ๏ธ <AerialView: 0x14a3ee570> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.554 : ๐Ÿ–ผ๏ธ <AerialView: 0x148e1cea0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.554 : ๐Ÿ–ผ๏ธ <AerialView: 0x14a071a00> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.554 : ๐Ÿ–ผ๏ธ <AerialView: 0x14a4394c0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.554 : ๐Ÿ–ผ๏ธ <AerialView: 0x14a444fc0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.555 : ๐Ÿ–ผ๏ธ <AerialView: 0x14a3c89d0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.555 : ๐Ÿ–ผ๏ธ <AerialView: 0x14a3e5d90> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.555 : ๐Ÿ–ผ๏ธ <AerialView: 0x14ca22930> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.555 : ๐Ÿ–ผ๏ธ <AerialView: 0x13a345be0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.555 : ๐Ÿ–ผ๏ธ <AerialView: 0x13a345f40> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.555 : ๐Ÿ–ผ๏ธ <AerialView: 0x14a272b50> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.556 : ๐Ÿ–ผ๏ธ <AerialView: 0x14a4281f0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.556 : ๐Ÿ–ผ๏ธ <AerialView: 0x14a2a5e30> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.556 : ๐Ÿ–ผ๏ธ <AerialView: 0x13a306b10> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.556 : ๐Ÿ–ผ๏ธ <AerialView: 0x14a2fcf30> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.556 : ๐Ÿ–ผ๏ธ <AerialView: 0x14a2a9890> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.556 : ๐Ÿ–ผ๏ธ <AerialView: 0x13a376d50> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.557 : ๐Ÿ–ผ๏ธ <AerialView: 0x148f3bed0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.557 : ๐Ÿ–ผ๏ธ <AerialView: 0x13a370cb0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.557 : ๐Ÿ–ผ๏ธ <AerialView: 0x14ca36200> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.557 : ๐Ÿ–ผ๏ธ <AerialView: 0x14a083ea0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.557 : ๐Ÿ–ผ๏ธ <AerialView: 0x14a431520> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.557 : ๐Ÿ–ผ๏ธ <AerialView: 0x13a376750> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.558 : ๐Ÿ–ผ๏ธ <AerialView: 0x14a0c73c0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.558 : ๐Ÿ–ผ๏ธ <AerialView: 0x12882fa50> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.558 : ๐Ÿ–ผ๏ธ <AerialView: 0x14c93d2e0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.558 : ๐Ÿ–ผ๏ธ <AerialView: 0x128a62fd0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.558 : ๐Ÿ–ผ๏ธ <AerialView: 0x14cf7ce80> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.558 : ๐Ÿ–ผ๏ธ <AerialView: 0x13a3a3930> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.559 : ๐Ÿ–ผ๏ธ <AerialView: 0x14cf38ab0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.559 : ๐Ÿ–ผ๏ธ <AerialView: 0x14a0ec970> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.559 : ๐Ÿ–ผ๏ธ <AerialView: 0x128a9cf00> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.559 : ๐Ÿ–ผ๏ธ <AerialView: 0x14cf3a850> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.559 : ๐Ÿ–ผ๏ธ <AerialView: 0x14ca3eff0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.559 : ๐Ÿ–ผ๏ธ <AerialView: 0x12c60dc40> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.560 : ๐Ÿ–ผ๏ธ <AerialView: 0x12884be60> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.560 : ๐Ÿ–ผ๏ธ <AerialView: 0x14cf2cdd0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.560 : ๐Ÿ–ผ๏ธ <AerialView: 0x14cf95130> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.560 : ๐Ÿ–ผ๏ธ <AerialView: 0x14cfe1090> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.560 : ๐Ÿ–ผ๏ธ <AerialView: 0x14cf5d090> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.560 : ๐Ÿ–ผ๏ธ <AerialView: 0x128afe410> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.561 : ๐Ÿ–ผ๏ธ <AerialView: 0x14cfb3270> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.561 : ๐Ÿ–ผ๏ธ <AerialView: 0x14cfcf9a0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.561 : ๐Ÿ–ผ๏ธ <AerialView: 0x14cfc7f10> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.561 : ๐Ÿ–ผ๏ธ <AerialView: 0x14a2b1310> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.561 : ๐Ÿ–ผ๏ธ <AerialView: 0x1323d3090> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.561 : ๐Ÿ–ผ๏ธ <AerialView: 0x12ede9e70> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.562 : ๐Ÿ–ผ๏ธ <AerialView: 0x13080fd30> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.562 : ๐Ÿ–ผ๏ธ <AerialView: 0x12c6e43f0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.562 : ๐Ÿ–ผ๏ธ <AerialView: 0x11f253a70> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.562 : ๐Ÿ–ผ๏ธ <AerialView: 0x11f253470> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.562 : ๐Ÿ–ผ๏ธ <AerialView: 0x12c6f63b0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)
2023-07-26 18:27:26.562 : ๐Ÿ–ผ๏ธ <AerialView: 0x148f7baa0> startAnimation frame (0.0, 0.0, 2560.0, 1440.0) bounds (0.0, 0.0, 2560.0, 1440.0)

(that's a whole lot) Good news is, at least for Aerial, those instances are "marked as dead" so I don't start anything when receiving those events. So be mindful of that one as this is a significant change from b3.

2023-07-26 18:27:26.760 : ๐Ÿ–ผ๏ธ Using : Optional([id=9, width=2560, height=1440, bottomLeftFrame=(0.0, 0.0, 2560.0, 1440.0), topRightCorner=(2560.0, 1440.0), isMain=true, backingScaleFactor=2.0])
2023-07-26 18:27:26.780 : ๐Ÿ–ผ๏ธ Using : Optional([id=9, width=2560, height=1440, bottomLeftFrame=(0.0, 0.0, 2560.0, 1440.0), topRightCorner=(2560.0, 1440.0), isMain=true, backingScaleFactor=2.0])

Again, this is annoying ๐Ÿ˜ฉ I need to test my workarounds for this. Because right now you can set a different screensaver PER space (not just per screen), I want to do screen + space detection but again, this is still WIP.

glouel commented 1 year ago

@xmddmx

I've tried a few things to get the screen we're at but so far I have nothing. Do you currently have a working detection system ? I've seen you talk about screen initialization order and I'm wondering if you have any matching working.

The way I did it previously was to match the view's frame origin (which is now bugged to (0,0)).

I tried playing with self.window.screen but that just returns nil under legacyScreenSaver, independent of when its called. It does work however under System Settings, but that's not particularly helpful.

xmddmx commented 1 year ago

I also had the idea of using self.window.screen, but found that it was nil inside the intializer. I was hoping that later on (inside .Draw or AnimateOneFrame) it would be non-nil, but hadn't done those tests yet.

Sounds like you have and my idea won't work?

Have you filed a feedback case for this specific bug? Sometimes the really focused cases, such as "frame.origin is 0,0" seem to be more likely to get fixed.

glouel commented 1 year ago

I also had the idea of using self.window.screen, but found that it was nil inside the intializer. I was hoping that later on (inside .Draw or AnimateOneFrame) it would be non-nil, but hadn't done those tests yet.

Can confirm, I did try to check at a later time (after 30+ seconds) and still nil. Init was nil for when running in System Settings but showed results a tiny bit afterwards. But yeah, useless in the end.

Have you filed a feedback case for this specific bug? Sometimes the really focused cases, such as "frame.origin is 0,0" seem to be more likely to get fixed.

Not yet but will do tomorrow ! At this point I'm out of ideas, I did look at private APIs but didn't find anything that would help. So let's try and get that one fixed.

glouel commented 1 year ago

@xmddmx took me a while as I got busy but finally made a very detailed report of the frame origin issue as FB12831305

xmddmx commented 1 year ago

Initial testing of Sonoma beta 5:

I have added some code to try to work around the screen coordinates issue: basically, it ignores the X,Y coordiante and matches on Width,Height instead. This is working OK on my test system (which has 2 different-sized monitors) but would fail on a system with 2 identical monitors.

So far in testing, it does seem like screen[1] is always initialized before screen[0] in Sonoma. If this is reliable, then it may be possible to come up with an algorithm to figure out which screen is which based on this reverse order, combined with the width x height values?

glouel commented 1 year ago

I only spent 10 minutes on b5 but broadly agree.

Regarding the last chance matching thing, I think there's a backing scale factor property that can be used too to differentiate (it's the retina factor, not 100% sure how it's called, it's 2 for retina, 1 for regular screens), I think that may be an extra layer (I personally use 2 2560 monitors, one from Studio Display with retina and one old Asus thing without so that would work).

I think the order thing is also a last last layer of fallback, I'm wondering if it's main, secondary, secondary or left, middle, right, if you see what I mean ? (reversed in that case).

Worth investigating. I'll try to have another look tomorrow.

xmddmx commented 1 year ago

I've never had this much frustration testing screensavers in macOS, it seems like Sonoma is really trying to make our lives hard. For example, is there any way our processes can detect when they've been "converted" (?) into the (Wallpaper) process?

Would it be enough to get the ProcessInfo and look for "(Wallpaper)" and terminate if so? Or is that string translated into various languages...

glouel commented 1 year ago

I've never had this much frustration testing screensavers in macOS, it seems like Sonoma is really trying to make our lives hard.

I guess I'm getting numb to it at this point but yeah, they are trying hard to break our spirits ;)

For example, is there any way our processes can detect when they've been "converted" (?) into the (Wallpaper) process?

Well there's the willStop event now that works pretty well if you just want to detect that (I use that to "stop" my view).

Would it be enough to get the ProcessInfo and look for "(Wallpaper)" and terminate if so? Or is that string translated into various languages...

So I can be 100% wrong on this but I don't believe that we, the screensaver, can terminate ourselves, we are just plugins to some code and I don't think we can kill ourselves from the saver itself. I mean, I could be wrong, but basically it's :

ScreenSaverEngine.app -> legacyScreenSaver.appex -> us

And at some point we (legacyScreenSaver) get passed around, so even if we could kill ourselves, what would we kill ? ScreenSaverEngine, WallpaperAgent ? Who knows ? From an external app though ? 100% you could check for that but yeah, that string is 100% translated in other languages since beta 2 (I think). It says "Fond d'รฉcran" here for example.

An external app though could look for screensaver.willStop event, wait a bit, kill legacyScreenSaver*, and be done with it. It seems a lot of work for something they'll 100% have to address on their end before the end of the beta cycle though, as it makes intel macs 100% unusable with 1st party screen savers. But if you are frustrated enough by it, sure, that could be the way to go.

Remember though that a user can set different screen saver per screen, and if you set one of the new Apple ones and yours on different screens, legacyScreenSaver does kinda have a purpose in that case. So wait like 10/30s before killing maybe is safe (from my understanding of how they do things, it's fine to kill at that point).

Still, too much work for something they'll fix IMO. I wouldn't be so confident on the screen coord issue though.

glouel commented 1 year ago

@xmddmx very quick update I spent the afternoon trying to make a workaround for the coordinates thing, some notes :

At this point I still don't see a way to make a 100% coverage fix but I'll take the better than nothing one.

The other hot issue for me is setting the screen saver as default. Because you can now set a different screen saver per screen/space, the old way to set a screen saver by editing a plist doesn't work anymore. I tracked the new plist, I don't remember if I talked about it here, but the relevant configuration keys are a binary blob which is not helpful. You can check if you are set as default still, but not set yourself default (the old plist is still written by System Settings, but ignored in the end). Annoying.

Bugs are filled, finger are crossed, and other stuff was done. We'll see if it bears fruit.

xmddmx commented 1 year ago

but the relevant configuration keys are a binary blob which is not helpful

That sucks, but I do love me a reverse-engineering binary blob puzzle! But I'm guessing the blob is not writeable by us mortals...

glouel commented 1 year ago

but the relevant configuration keys are a binary blob which is not helpful

That sucks, but I do love me a reverse-engineering binary blob puzzle! But I'm guessing the blob is not writeable by us mortals...

I believe it should be, it's in the user directory, but in such a weird place :

~/Library/Application Support/com.apple.wallpaper/Store/Index_v2.plist

From my understanding each screen is represented twice, there's a key provider that either says wallpaper or screen saver basically. If you use spaces, you'll have 2 entries per screen/space. Looks roughly like this :

Content = {
    Choices = (
        {
            Configuration = {length = 130, bytes = 0x62706c69 73743030 d1010256 6d6f6475 ... 00000000 0000005d };
            Files = ();
            Provider = "com.apple.wallpaper.choice.screen-saver";
        }
    );
    Shuffle = "$null";
};

They may change the whole thing but if you want to have a go, go ahead ;) It may be a simple encoding, I admit I didn't even try the basic things.

xmddmx commented 1 year ago

So I can be 100% wrong on this but I don't believe that we, the screensaver, can terminate ourselves, we are just plugins to some code and I don't think we can kill ourselves from the saver itself. I mean, I could be wrong, but basically it's :

ScreenSaverEngine.app -> legacyScreenSaver.appex -> us

And at some point we (legacyScreenSaver) get passed around, so even if we could kill ourselves, what would we kill ?

For fun, I tried adding a call to

exit(0) within the com.apple.screensaver.willstop notification handler, and it actually seems to work to terminate the LegacyScreensaver process.

Is this a bad thing to do? Not sure, but it seems like it will sure make testing easier for the time being.

glouel commented 1 year ago

@xmddmx I had no idea this would actually work... this is completely awesome !

Because of the passing thing, is it good, is it bad ? is there a better time (screenIsUnlocked could either be better or too late) ? I don't know, and I want to say who cares ! I'm completely amazed that it works, thanks for giving it a go ๐Ÿ˜…

I'll give it a shot locally too and let you know if I see bad things happening, but yeah this will make : 1) dev/testing much simpler 2) possibly fix many many many issues

Kudos ! I'll add it locally later today and report back if I see weird stuff. I mean maybe some stuff will complain in console, but it's not like it's not complaining already anyway !

glouel commented 1 year ago

It works, it looks pretty clean, I tried doing it a bit later, but it looks like we may not be able to exit if we are already passed to the wallpaper thing, so I think you have it right here. I'll report if there's an issue.

xmddmx commented 1 year ago

This is interesting, I added some debug info to look at the NSView's.Window property:

iScreensaver    [0] ########## .frame = (10000.0, 10000.0, 1440.0, 900.0)
iScreensaver    [0] ########## .windowNumber = 814
iScreensaver    [1] ########## .frame = (10000.0, 10000.0, 1680.0, 1050.0)
iScreensaver    [1] ########## .windowNumber = 815

Unfortunately, it seems that .windowNumber is set in the order of creation, and I'm finding that sometimes screen[1] initliazes before screen[0] so we can't use windowNumber to figure out which screen is which.

I also noticed this:

NSWindow.deviceDescription:

screen[0] ########## .deviceDescription = [__C.NSDeviceDescriptionKey(_rawValue: NSDeviceBitsPerSample): 8, __C.NSDeviceDescriptionKey(_rawValue: NSDeviceResolution): NSSize: {144, 144}, __C.NSDeviceDescriptionKey(_rawValue: NSDeviceIsScreen): YES, __C.NSDeviceDescriptionKey(_rawValue: NSDeviceSize): NSSize: {1440, 900}, __C.NSDeviceDescriptionKey(_rawValue: NSDeviceColorSpaceName): NSCalibratedRGBColorSpace]

screen[1] ########## .deviceDescription = [__C.NSDeviceDescriptionKey(_rawValue: NSDeviceResolution): NSSize: {144, 144}, __C.NSDeviceDescriptionKey(_rawValue: NSDeviceColorSpaceName): NSCalibratedRGBColorSpace, __C.NSDeviceDescriptionKey(_rawValue: NSDeviceSize): NSSize: {1680, 1050}, __C.NSDeviceDescriptionKey(_rawValue: NSDeviceIsScreen): YES, __C.NSDeviceDescriptionKey(_rawValue: NSDeviceBitsPerSample): 8]

Interesting, but doesn't seem to be anything that would help determine which screen is which.

glouel commented 1 year ago

@xmddmx how soon are you getting this ? I can't seem to read ScreenSaverView.window during my init process. Interesting nonetheless, maybe they park those windows out of view before putting them in place, legacyScreenSaver.appex seems like a huge pile of hack it's so crazy...

xmddmx commented 1 year ago

I'm checking a few seconds later.

Also, my setup is probably different than yours, in that I have a ScreenSaverView, which adds a NSView, which adds a WKWebView. I'm seeing a lot of weird bugs in the WKWebView with HTML/JavaScript/CSS video and animations not working properly, but I don't think Aerial uses any of that.

Maybe the presence of a WebView is changing things?

It might be worth for you to try adding a dummy NSView to your ScreenSaverView and see if perhaps that view will have a useable .window value?

glouel commented 1 year ago

Good tips, I'll have a look and let you know, thanks !

zeromhz commented 1 year ago

The exit() fix is broadly great. It appears the fix doesn't work in the following scenario:

  1. Let screen saver activate
  2. Let system fall asleep
  3. Wake system with touchID (such that you don't see the screen saver)

There may be another notification that we can hook onto that would catch this situation.

glouel commented 1 year ago

Yep, I think maybe this notification, willSleepNotification, can be used :

NSWorkspace.shared.notificationCenter.addObserver(
        self, selector: #selector(onSleepNote(note:)),
        name: NSWorkspace.willSleepNotification, object: nil)

Made a quick build we'll see tomorrow how it goes. There's an IORegister thing also mentionned where I found that notification (bottom of the page) but I'd rather not use that : https://stackoverflow.com/questions/9247710/what-event-is-fired-when-mac-is-back-from-sleep

glouel commented 1 year ago

@xmddmx so the trick seems to work for system going to sleep, patch is here : https://github.com/JohnCoates/Aerial/commit/0fe3461a3d5aa519f8ecc65504bc3cad8ac73a96

I insta-exit when I get the notification, I think it's safer this way (we want to act before the system is put to sleep). Also logging is useless here (unless your logging is atomic and that's probably bad, we want to go fast).

As pointed to me earlier by @zeromhz the bug that we saw since beta 4 on quick subsequent launches behaves slightly differently. We get a black screen in that case.

This is more or less what we got earlier but I had noticed that it actually showed back the old (unkilled) instance in those cases (I could still see my uncleared overlays from previous launch).

It still seems fine in any case and I'll roll with both those changes after a tiny bit of cleanup in next beta, it should provide a very good improvement as even on my Mac Studio each view still took half a percent cpu with me tearing down everything I could think of.

xmddmx commented 1 year ago

Beta 6 came and went - very brief testing showed no major changes. Beta 7 is out today. Downloading it now.

xmddmx commented 1 year ago

In Beta 7, I'm not seeing any functional changes to the big issues:

halfbrilliant commented 1 year ago

Yeah, I just tried a fresh reinstall of the latest beta after updating to Sonoma DP Beta 7 and just get the black screen and then need to killl LegacyScreenSaver.

I've bothered the developer(s) about this a few times and I know they're aware of the issue. I'm assuming that they're waiting for the Sonoma GM to drop so they don't waste dev energy and time on a potentially moving goalpost. I'm excited though, as I finally caved and got an OLED TV after decades of using small monitors only. But I know it will be worth the wait!

glouel commented 1 year ago
  • the Initialize call still has all screens at X,Y=0,0

@xmddmx Sooooo, I think there may be a workaround but I'm not 100% sure of how to get there. Someone pointed me to this https://www.jwz.org/blog/2023/08/xscreensaver-6-07-out-now/

In the release notes he talks about the 13.3 horror show and mentions a callback I wasn't looking at yet, viewDidMoveToWindow.

Here's the good news, if I override that thing on ScreenSaverView, from there I can read window.screen and it actually works correctly.

2023-09-03 19:00:02.060 : ๐Ÿฅฌ๐ŸŒพ window.screen Optional("Optional(<NSScreen: 0x135a14e70; name=\"Studio Display\"; backingScaleFactor=2.000000; frame={{0, 0}, {2560, 1440}}; visibleFrame={{47, 0}, {2513, 1415}}>)")

(this is self.window?.screen.debugDescription, self.window?.screen is correctly initialised here)

The bad news is, this seems to get triggered by "something" (maybe something just before startAnimation), and I'm loading the video way too early in Aerial, so, right now, I can't use that trick to use the correct video on the correct screen. But I'm 100% sure there's a path in there. We just need to asynchronously grab the screen from that call, and only make the decision on what to display after we got it. I tried delaying things with some thread sleep but that's rarely the way to go, and it didn't work.

I'm not sure any of that makes sense, but I thought I'd give you a heads up as you may not have the same constraints I do and grabbing the screen there may work for you.

glouel commented 1 year ago

@xmddmx I looked at his code to fix the Ventura bug and I feel extremely dumb now, we were so, so close...

The important bit I missed is that you can use NSApplication.shared.windows to list every window that belongs to legacyScreenSaver and that changes everything ๐Ÿ˜ญ

From then on you can just walk those, check if there's a view attached, if not attach an unattached one, then reorder if needed... ๐Ÿคฆ

I haven't checked yet when exactly he triggers this, I'll dig a bit more tomorrow. If you feel like it, I suggest you look at the code (get the linux distribution on his site, then look for VENTURA_KLUDGE in OSX).

Edit : Interestingly now those windows are of a weird type, that might be the new thing they introduced in legacyScreenSaver :

2023-09-03 19:37:40.562 : window : <NSServiceViewControllerWindow: 0x15530e780> 2023-09-03 19:37:40.562 : window : <NSServiceViewControllerWindow: 0x151a47480>

xmddmx commented 1 year ago

This is great - I found a pretty simple workaround:

private func delayedInitialize() {
  [...]
  let screenNumber = NSScreen.getScreenNumber(view:self)
  [...]
}

extension NSScreen {
    class func getScreenNumber(view:NSView) -> Int {
        let sa = NSScreen.screens
        for i in 0..<sa.count {
            let s = sa[i]
            let s2 = view.window?.screen
            if s == s2 {
                return i
            }
        }
       return -1    
    }
}

I believe this solves the Sonoma "which screen am I on" issue. It does not solve the Ventura 13.4 problems (where Views are on the wrong screen or not on a window at all) which is what the VENTURA_KLUDGE fix is all about in XSaver. Since that's mostly fixed in Ventura 13.5, I'm not sure if it's worth worrying about that extra complexity...

glouel commented 1 year ago

@xmddmx awesome !

I'll give it a shot tomorrow ! how long do you set your timer for, 1s ?

I did give it a quick shot earlier by trying to delay things but at a much later point, and it just gets stupid because there's so so so many legacy workaround for every single bug that we've been facting that I couldn't make anything proper. Delaying early is definitely a better idea ๐Ÿ’ช

xmddmx commented 1 year ago

I'm using .01 seconds and it seem fine.

glouel commented 1 year ago

I'm using .01 seconds and it seem fine.

Yeah looks like that's plenty, you were right !

2023-09-04 15:12:05.104 : ๐Ÿ–ผ๏ธ AVinit (.saver) (0.0, 0.0, 2560.0, 1440.0) p: false o: false
2023-09-04 15:12:05.105 : ๐Ÿ–ผ๏ธ <AerialView: 0x127914650> viewDidMoveToWindow frame: (0.0, 0.0, 2560.0, 1440.0) window: Optional(<NSServiceViewControllerWindow: 0x136f32d10>)

Btw, I completely messed up my attempt yesterday, using thread.sleep instead of dispatchqueue ๐ŸคฆI'll blame that on the shock that 13.3 was fixable, still haven't digested this one ๐Ÿ˜…

Still need to button up things but will have a new Aerial today with that fix.

Right now to recap the issues that we haven't workarounded :

There's probably other annoyances I missed but those are the big ones I think ?

xmddmx commented 1 year ago

In Ventura, I was never able to get keyboard events working, but I was able to find a way to capture mouse events (move, click) which allows us to keep a onscreen UI (HUD: heads-up-display) that could be used while the screensaver was running, though I could only get it to work on a single monitor.

Given that legacyScreensaver in Sonoma appears to be totally rewitten from scratch, I though "why not try again?"

Here's what I've found:

This technique doesn't work in Sonoma - the events are never received.

When I log these events, event.window == nil, however the windowNumber is not 0, and in fact the windowNumber is a different windowNumber than self.window.

I suspect what's going on here is that in Sonoma, our screensaver is being run in some weird offscreen NSServiceViewControllerWindow, which is somehow displaying its contents to a different window which is a real window.

Unfortuantely, this real window does not show up in NSApplication.shared.windows so there doesn't seem an easy way to hack into it.

So at the moment, it looks like getting mouseMove events is possible (which could be somewhat useful for an onscreen UI/HUD) but any sort of clicking always exits the screensaver.

I will keep investigating.

glouel commented 1 year ago

When I log these events, event.window == nil, however the windowNumber is not 0, and in fact the windowNumber is a different windowNumber than self.window.

This is definitely weird.

I suspect what's going on here is that in Sonoma, our screensaver is being run in some weird offscreen NSServiceViewControllerWindow, which is somehow displaying its contents to a different window which is a real window.

This seems quite probable and would explains a lot of the weird stuff we've seen.

Unfortuantely, this real window does not show up in NSApplication.shared.windows so there doesn't seem an easy way to hack into it.

I'm wondering why they tried to isolate all this but I would guess those ServiceViews are like super locked down for security reasons, could explain why you saw 10000 coordinates a while back.

So at the moment, it looks like getting mouseMove events is possible (which could be somewhat useful for an onscreen UI/HUD) but any sort of clicking always exits the screensaver.

Do you think we can get trackpad gestures ? Like swipe left/right ? They may be the closest thing we can get to an actual button press if we can't cancel events (which I think they absolutely don't want us to do and will fight us endlessly on).

I will keep investigating.

Keep me posted (I realise I got swamped last year when you emailed me about this, super sorry again).

xmddmx commented 1 year ago

Re: WKWebView issues - I've reported this to apple as FB13094564, and I also submitted a TSI ticket today. THere's another third party screensaver that suffers from this as well so I submitted an Issue with that project also: https://github.com/liquidx/webviewscreensaver/issues/75

(Since Aerial doesn't use WebKit, I feel kind of bad mentioning those issues here, though it certainly is handy to have 'all the sonoma bugs' in one place. )

xmddmx commented 1 year ago

Also, in quick testing of today's Sonoma RC release, I don't see any changes to the bugs we've found in legacyScreenSaver: screens are still misreported as (0,0), the legacyScreenSaver processes get stuck (someimtes running at 100% CPU), etc.

xmddmx commented 1 year ago

Tested today's Sonoma RC2 release: no changes that I can see, still buggy as before.

xmddmx commented 12 months ago

Testing in 14.1 beta 1 and today's 14.1 beta 2: I don't see any changes to the bugs we've found in legacyScreenSaver: screens are still misreported as (0,0), the legacyScreenSaver processes get stuck (someimtes running at 100% CPU), etc.

glouel commented 12 months ago

Yeah at this point I have little expectations they'll fix those.

I did find (through users) a few extra things :

I'm starting to get slightly annoyed at this point ๐Ÿ˜…

xmddmx commented 12 months ago
  • You can no longer run command line stuff (this breaks my nightshift integration, and script running)

I'm not seeing this, in fact I just solved an issue using the command line. My screensaver uses a standalone helper app to run the 'Options" UI, and although the .saver could easily launch the app (by using Process.launch() ) a subsequent press of the 'Options' button was no longer able to activate the app window, because NSRunningApplication.runningApplications(withBundleIdentifier: was no longer finding the app.

The solution was to simply issue a shell command: open Helpers/Helper.app

which brings the app frontmost.

Note: my helper app lives inside the .saver bundle - pehaps this is important?

p.s. here's my "Shell" function which uses Process() also:

func shell(_ command:String ) -> String
{
    let task = Process()
    var arguments = ["-c"]
    arguments.append(command)
    task.launchPath = "/bin/bash"
    task.arguments = arguments

    let pipe = Pipe()
    task.standardOutput = pipe
    task.launch()

    let data = pipe.fileHandleForReading.readDataToEndOfFile()
    let output = String(data: data, encoding: String.Encoding.utf8)!
    if output.count > 0 {
        //remove newline character.
        let lastIndex = output.index(before: output.endIndex)
        return String(output[output.startIndex ..< lastIndex])
    }
    return output
}
glouel commented 12 months ago

Ha interesting, thanks for the info!

I'll double check how I'm doing it and see if I can find the root cause.

glouel commented 12 months ago

@xmddmx

Do you run terminal programs by any chance, or a shell script ? Here's what I used to do that no longer works :

Process.launch() with

1) directly launching a shell script (test.sh is chmod +x and a basic bash script)

task.launchPath = "/Users/Shared/test.sh"

This fails as "permission denied" (it didn't prior to 14.0, and works outside the screensaver sandbox)

2) calling a terminal utility

task.launchPath = "/usr/libexec/corebrightnessdiag"
task.arguments = ["nightshift-internal"]

Fails as permission denied too (again this worked fine before, and works outside the sandbox)

I looked a bit at using open instead, but this is mostly for launching apps, not command line stuff. I tried launching Terminal.app but it no longer appears to be in /Applications/Utilities/ (I guess it's aliased from somewhere else...)

I think open is probably the way to go, but it's apparently a mess to be able to pass parameters around and get the output if you go with open. I'll keep digging a bit, but thanks for the info.

Edit : Some extra stuff I tried

Where my test.sh has :

#!/bin/bash
ps -A -o %cpu | awk '{s+=$1} END {print s "%"}'

(it's a quick way to get cpu usage)

So I think it's more likely that any system command is locked down, is the exact issue.

Replacing the script with :

#!/bin/bash
echo "hello"

Works fine (but is pretty useless obviously).

xmddmx commented 12 months ago

See https://github.com/JohnCoates/Aerial/issues/1305#issuecomment-1750763532 for my actual code. The only command I'm using so far is "open /path/to/my/helper.app" which works fine - but maybe because the helper app is inside my .saver bundle, the sandbox allows it?

Also, I just tested this from within the .saver

# get display sleep time
/usr/bin/pmset -g | /usr/bin/grep displaysleep | /usr/bin/awk '{ print $2 }'

And I tested it, and it does work fine in Sonoma.

glouel commented 12 months ago

Ha, I didn't see your edit, thanks a whole lot I'll give it a shot !

glouel commented 12 months ago

Ok this is getting crazy, your script does work as is with my old code ๐Ÿ˜…

May I ask you try ps or /usr/libexec/corebrightnessdiag ? I have a hard time understanding how pmset is ok but not ps, makes 0 sense... I'll keep digging, thanks for your help.

xmddmx commented 12 months ago

in my .saver in 14.1 beta 2 on a M1 macbook air

using the shell() function above,

shell("/usr/libexec/corebrightnessdiag")

returns

corebrightnessdiag [nightshift] [sunschedule] [nightshift-internal] [status-info]

xmddmx commented 12 months ago

The command 'ps' however, returns nothing.

glouel commented 12 months ago

Ok I think your /bin/bash trick seems to work, I'm looking at passing arguments right now and I'm not there yet, but I think I'm close. Thanks a whole lot !

To be precise, in a terminal, this is what I need to run :

/usr/libexec/corebrightnessdiag nightshift-internal

I'm having issues passing the nightshift-internal right now but I'll keep digging.