Muraloom is a macOS app that automatically changes your desktop wallpaper using photos from a OneDrive album.
- Automatic Wallpaper Changes: Set a frequency for how often your wallpaper changes (e.g., hourly, daily).
- Customizable Photo Selection: Choose between random or sequential photo picking.
- Image Filtering: Filter photos by minimum width and orientation (horizontal only).
- Wallpaper Fill Mode: Control how the image fills your desktop (fill, fit, stretch, center).
- OneDrive Album Picker: Sign in and pick a OneDrive album (advanced: manual album ID).
- RAW Photos (optional): ARW/DNG/etc are supported when LibRaw is enabled (see
docs/LIBRAW.md).
- macOS 12.0 or later
- Xcode 13.0 or later
- A Microsoft Entra ID (Azure) app registration for Microsoft Graph (personal Microsoft accounts).
You’ll need to:
- Create an app registration in the Azure portal: https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationsListBlade
- Set supported account types to include personal Microsoft accounts.
- Add an iOS/macOS redirect URI that matches
OneDriveRedirectUriinMuraloom/Info.plist.- Azure will generate the redirect URI in the format
msauth.<bundle_id>://auth.
- Azure will generate the redirect URI in the format
- Add delegated Microsoft Graph permissions:
User.ReadFiles.Read
- Provide your Application (client) ID to the app (don’t commit secrets):
- Copy
Muraloom/Secrets.xcconfig.exampletoMuraloom/Secrets.xcconfig(gitignored). - Set
ONEDRIVE_CLIENT_ID = ...inMuraloom/Secrets.xcconfig.
- Copy
If clicking “Sign In” shows “OneDrive auth is not configured”, it means the app is still using placeholder values.
- Ensure
Muraloom/Secrets.xcconfigexists and containsONEDRIVE_CLIENT_ID = ...(this is used byMuraloom/Info.plistvia$(ONEDRIVE_CLIENT_ID)). - Verify
OneDriveRedirectUrimatches the redirect URI shown in the Azure portal for the iOS/macOS platform (usuallymsauth.<bundle_id>://auth). - Verify
OneDriveScopesis a space-separated list (e.g.User.Read Files.Read).- Note:
openid,profile, andoffline_accessare reserved OIDC scopes. MSAL handles these automatically, so don’t include them here.
- Note:
If clicking “Sign In” shows “OneDrive auth setup failed …”, MSAL failed to initialize using the values from Info.plist.
- Verify
OneDriveRedirectUrimatches the redirect URI shown in the Azure portal for the iOS/macOS platform (usuallymsauth.<bundle_id>://auth). - Verify your app bundle identifier (Xcode target → Signing & Capabilities → Bundle Identifier) matches the
<bundle_id>you entered in the Azure portal. - If you changed bundle ID / redirect settings recently, try Product → Clean Build Folder in Xcode and run again.
- If the underlying error is OSStatus -34018, it usually means the app is missing a required Keychain entitlement. Ensure the
Muraloomtarget’s entitlements include MSAL’s default macOS cache group ($(AppIdentifierPrefix)com.microsoft.identity.universalstorage) and that the app is run as a signed build from Xcode.
If you downloaded Muraloom.app and macOS refuses to open it, remove the quarantine attribute and try again:
xattr -dr com.apple.quarantine /path/to/Muraloom.app
open /path/to/Muraloom.app- Clone this repository:
git clone https://github.com/andrewmy/muraloom.git cd muraloom - Open the
Muraloom.xcodeprojfile in Xcode. - In Xcode, select the
Muraloomtarget in the project navigator. - Go to the "Signing & Capabilities" tab.
- Change the "Team" to your development team.
- Change the "Bundle Identifier" to a unique identifier (e.g.,
com.yourcompany.Muraloom). - Ensure the URL scheme in
Muraloom/Info.plistmatches the scheme used by your redirect URI (default scheme:msauth.<bundle_id>).
- In Xcode, select your Mac as the target device.
- Click the "Run" button (or
Cmd + R).
The application should now build and run on your macOS device.
Build (Debug):
xcodebuild -scheme Muraloom -destination 'platform=macOS' -derivedDataPath /tmp/muraloom_deriveddata buildIf you only need a compile sanity check (and want to avoid signing/keychain issues):
xcodebuild -scheme Muraloom -destination 'platform=macOS' -derivedDataPath /tmp/muraloom_deriveddata CODE_SIGNING_ALLOWED=NO buildRun the built app (requires a signed build; CODE_SIGNING_ALLOWED=NO won’t produce a runnable app):
open /tmp/muraloom_deriveddata/Build/Products/Debug/Muraloom.appRun tests from CLI:
xcodebuild -scheme Muraloom -destination 'platform=macOS' -derivedDataPath /tmp/muraloom_deriveddata testRun only unit tests:
xcodebuild -scheme Muraloom -destination 'platform=macOS' -derivedDataPath /tmp/muraloom_deriveddata_test test -only-testing:MuraloomTestsRun unit tests with code coverage (and produce an .xcresult bundle you can inspect in Xcode):
xcodebuild -scheme Muraloom -destination 'platform=macOS' -derivedDataPath /tmp/muraloom_deriveddata_test -resultBundlePath /tmp/muraloom_tests.xcresult -enableCodeCoverage YES test -only-testing:MuraloomTests
bash bin/coverage-gate.sh /tmp/muraloom_tests.xcresult 50 MuraloomCI enforces this as a gate (unit tests only): Muraloom.app line coverage must be at least 50%.
To run the same gate locally, use just coverage (or just coverage-report for a report without enforcing a minimum).
Run only UI tests (hermetic; no network/auth required):
xcodebuild -scheme Muraloom -destination 'platform=macOS' -derivedDataPath /tmp/muraloom_deriveddata_ui_test -resultBundlePath /tmp/muraloom_ui_tests.xcresult CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY="-" CODE_SIGN_ENTITLEMENTS="" test -only-testing:MuraloomUITestsConvenience just recipes:
just test # unit tests
just coverage # unit tests + coverage gate
just ui-test # UI tests
just test-all # unit + UI testsUI tests (Debug builds) launch the app with -ui-testing to use local fixture services (no interactive sign-in, no Graph calls). In UI testing mode, Advanced also shows a small “Menu Bar (UI testing)” harness so menu actions can be tested without relying on the system status bar UI.
On macOS, Xcode UI tests may also prompt to close other running apps (“Remove Other Apps”) to improve reliability.
RAW decoding is optional and off by default. To enable it, follow docs/LIBRAW.md. CI installs LibRaw via Homebrew automatically (see .github/workflows/ci.yml).
- Configure the wallpaper change frequency and selection settings in the app.
- Sign in to OneDrive.
- Load albums and select an album.
- To create/manage albums, use OneDrive Photos (https://photos.onedrive.com) and then reload albums in the app.
- If you can’t load albums for some reason, use Advanced to paste an album ID manually.
- Click "Change Wallpaper Now" to update immediately.
- Roadmap / implementation notes:
docs/PROJECT_PLAN.md - Repo guidance (contributors/Codex):
AGENTS.md