Skip to content

render wallpaper on every connected display#14

Open
max-frai wants to merge 1 commit into
museslabs:mainfrom
max-frai:macos-multi-screen
Open

render wallpaper on every connected display#14
max-frai wants to merge 1 commit into
museslabs:mainfrom
max-frai:macos-multi-screen

Conversation

@max-frai
Copy link
Copy Markdown

Previously the macOS backend only created a window on NSScreen.mainScreen, so users with multiple displays saw the wallpaper on a single screen.

  • Enumerate NSScreen.screens() and build one borderless window plus one AVPlayerLayer per display. A single AVPlayer is shared across every layer so all screens stay in sync and the decoder only runs once.
  • Use each screen's backingScaleFactor for its layer's contentsScale so mixed Retina / non-Retina setups render at native resolution.
  • ScreenObserver now holds Vecs of windows and layers and re-applies geometry on NSApplicationDidChangeScreenParametersNotification by asking each window for its current screen(), so windows track their display across rearrangements.
  • Extract per-screen window/layer construction into build_wallpaper_window so run() stays readable as orchestration.

Previously the macOS backend only created a window on NSScreen.mainScreen,
so users with multiple displays saw the wallpaper on a single screen.

- Enumerate NSScreen.screens() and build one borderless window plus one
  AVPlayerLayer per display. A single AVPlayer is shared across every
  layer so all screens stay in sync and the decoder only runs once.
- Use each screen's backingScaleFactor for its layer's contentsScale so
  mixed Retina / non-Retina setups render at native resolution.
- ScreenObserver now holds Vecs of windows and layers and re-applies
  geometry on NSApplicationDidChangeScreenParametersNotification by
  asking each window for its current screen(), so windows track their
  display across rearrangements.
- Extract per-screen window/layer construction into
  build_wallpaper_window so run() stays readable as orchestration.
@tharropoulos
Copy link
Copy Markdown
Member

Thank you for your contribution! I'd like to extend this to pick which displays each wallpaper would be rendered on. While I don't use a second monitor myself, I would imagine that users would benefit from being able to pick wallpapers or extend their wallpaper across monitors.

If @ploMP4 aggrees, we can merge this for the time being and extend this afterwards. I will most probably spend some time tomorrow on setting the API around it.

Copy link
Copy Markdown
Member

@ploMP4 ploMP4 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks good, @tharropoulos if you are ok with it and works you can go ahead and merge.

Copy link
Copy Markdown
Member

@tharropoulos tharropoulos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of small things noticed while reading through.

frame.size.height as u32,
backing_scale,
);
for (window, layer) in ivars.windows.iter().zip(ivars.layers.iter()) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This only repositions existing windows. If a new display is plugged in after launch, no window or layer gets created for it and that screen stays bare. Worth a follow up to rebuild the list when screen parameters change.

Comment thread src/backend/macos/mod.rs
// AVAsset resolves relative paths against the process cwd, which isn't
// what users expect from `phonto ./video.mp4`.
let abs = Path::new(&video_path)
.canonicalize()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original comment about why we canonicalize got dropped in this refactor. It explained that AVAsset resolves relative paths against the process cwd, which isn't what users expect from phonto ./video.mp4. Worth restoring.

Comment thread src/backend/macos/mod.rs
window.setOpaque(false);
window.setBackgroundColor(Some(&NSColor::clearColor()));
window.setHasShadow(false);
window.setSharingType(NSWindowSharingType::ReadOnly);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original comment about why we use ReadOnly rather than None got dropped. It noted that ReadOnly lets screen capture and screen sharing still read us, while None blocks them. Worth restoring.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants