Skip to content

Instantly share code, notes, and snippets.

@unrevised6419
Created October 2, 2026 23:59
Show Gist options
  • Select an option

  • Save unrevised6419/8eb526fcecbc6821aa9d80d77dbc7970 to your computer and use it in GitHub Desktop.

Select an option

Save unrevised6419/8eb526fcecbc6821aa9d80d77dbc7970 to your computer and use it in GitHub Desktop.
Adds black rounded corners to a wallpaper so maximized macOS windows blend into the screen edge.
#!/usr/bin/env swift
// Adds black rounded corners to a wallpaper so maximized macOS windows blend into the screen edge.
//
// The default corner shape was measured from real maximized windows on macOS 27:
// a continuous ("squircle") corner of ~16.75pt.
//
// Usage: round-wallpaper.swift <image> [-o out.png] [--radius 16.75] [--top 0]
// [--size 2880x1800] [--color 000000] [--set]
import AppKit
import SwiftUI
func fail(_ message: String) -> Never {
FileHandle.standardError.write(Data("error: \(message)\n".utf8))
exit(1)
}
let usage = """
usage: round-wallpaper.swift <image> [options]
-o, --output PATH output PNG (default: <image>-rounded.png)
--radius PT corner radius in points (default: 16.75, macOS 27 window radius)
--top PT top inset in points, e.g. menu bar height if windows sit below it (default: 0)
--size WxH output size in pixels (default: main screen's native pixel size)
--color HEX corner color (default: 000000)
--set set the result as wallpaper on all screens
"""
var input: String?
var output: String?
var radius: CGFloat = 16.75
var topInset: CGFloat = 0
var size: CGSize?
var color = NSColor.black
var setWallpaper = false
var args = CommandLine.arguments.dropFirst().makeIterator()
func value(_ flag: String) -> String {
guard let v = args.next() else { fail("\(flag) needs a value") }
return v
}
func number(_ flag: String) -> CGFloat {
guard let n = Double(value(flag)) else { fail("\(flag) needs a number") }
return CGFloat(n)
}
while let arg = args.next() {
switch arg {
case "-o", "--output": output = value(arg)
case "--radius": radius = number(arg)
case "--top": topInset = number(arg)
case "--size":
let parts = value(arg).lowercased().split(separator: "x").compactMap { Double($0) }
guard parts.count == 2 else { fail("--size must look like 2880x1800") }
size = CGSize(width: parts[0], height: parts[1])
case "--color":
guard let hex = UInt32(value(arg).trimmingCharacters(in: ["#"]), radix: 16) else { fail("bad --color") }
color = NSColor(
srgbRed: CGFloat((hex >> 16) & 0xFF) / 255,
green: CGFloat((hex >> 8) & 0xFF) / 255,
blue: CGFloat(hex & 0xFF) / 255,
alpha: 1)
case "--set": setWallpaper = true
case "-h", "--help": print(usage); exit(0)
default:
if arg.hasPrefix("-") || input != nil { fail("unexpected argument \(arg)\n\(usage)") }
input = arg
}
}
guard let input else { print(usage); exit(1) }
let inputURL = URL(fileURLWithPath: (input as NSString).expandingTildeInPath)
guard let source = NSImage(contentsOf: inputURL),
let cgSource = source.cgImage(forProposedRect: nil, context: nil, hints: nil)
else { fail("cannot read image \(input)") }
let screen = NSScreen.main
let scale = screen?.backingScaleFactor ?? 2
let pixelSize = size ?? screen.map {
CGSize(width: $0.frame.width * scale, height: $0.frame.height * scale)
} ?? CGSize(width: cgSource.width, height: cgSource.height)
let width = Int(pixelSize.width), height = Int(pixelSize.height)
guard let ctx = CGContext(
data: nil, width: width, height: height, bitsPerComponent: 8, bytesPerRow: 0,
space: CGColorSpace(name: CGColorSpace.sRGB)!,
bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue)
else { fail("cannot create bitmap context") }
ctx.interpolationQuality = .high
// Fill the screen like macOS does: scale to cover, center, crop.
let fill = max(pixelSize.width / CGFloat(cgSource.width), pixelSize.height / CGFloat(cgSource.height))
let drawn = CGSize(width: CGFloat(cgSource.width) * fill, height: CGFloat(cgSource.height) * fill)
ctx.draw(cgSource, in: CGRect(
x: (pixelSize.width - drawn.width) / 2, y: (pixelSize.height - drawn.height) / 2,
width: drawn.width, height: drawn.height))
// Paint everything outside the window-shaped rounded rect (even-odd: full canvas minus the window).
let canvas = CGRect(origin: .zero, size: pixelSize)
let window = CGRect(x: 0, y: 0, width: pixelSize.width, height: pixelSize.height - topInset * scale)
let corners = CGMutablePath()
corners.addRect(canvas)
corners.addPath(RoundedRectangle(cornerRadius: radius * scale, style: .continuous).path(in: window).cgPath)
ctx.addPath(corners)
ctx.setFillColor(color.cgColor)
ctx.fillPath(using: .evenOdd)
guard let result = ctx.makeImage(),
let png = NSBitmapImageRep(cgImage: result).representation(using: .png, properties: [:])
else { fail("cannot encode PNG") }
let outputURL = output.map { URL(fileURLWithPath: ($0 as NSString).expandingTildeInPath) }
?? inputURL.deletingPathExtension().appendingPathExtension("rounded.png")
do { try png.write(to: outputURL) } catch { fail("cannot write \(outputURL.path): \(error.localizedDescription)") }
print("wrote \(outputURL.path) (\(width)x\(height), radius \(radius)pt @\(scale)x)")
if setWallpaper {
for screen in NSScreen.screens {
do {
try NSWorkspace.shared.setDesktopImageURL(
outputURL, for: screen,
options: [.imageScaling: NSImageScaling.scaleProportionallyUpOrDown.rawValue, .allowClipping: true])
} catch { fail("cannot set wallpaper: \(error.localizedDescription)") }
}
print("wallpaper set")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment