If you want to hide the application’s icon from the actual dock (which you can place on either side of the screen and hide), add the LSUIElement
key to your Info.plist
.
Created
May 26, 2021 15:33
-
-
Save larsaugustin/80df680285d21b086c38257469f5461e to your computer and use it in GitHub Desktop.
A macOS dock replacement with a modernized version of the design used before Yosemite
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import SwiftUI | |
// MARK: - Constants | |
// Items in the dock: Add any application you’d like to see in here | |
let items = | |
[ | |
"file:///Applications/Xcode.app", | |
"file:///Applications/Safari.app", | |
"file:///System/Applications/Messages.app", | |
"file:///System/Applications/Music.app" | |
] | |
// MARK: - View | |
struct ContentView: View { | |
// Used to refresh the view periodically | |
@State var refresh = false | |
var body: some View { | |
VStack { | |
Spacer() | |
// Front | |
ZStack(alignment: .bottom) { | |
RoundedRectangle(cornerRadius: 5) | |
.fill( | |
Color(red: 216/255, green: 216/255, blue: 216/255).opacity(0.9)) | |
.mask( | |
VStack { | |
Spacer() | |
Rectangle() | |
.fill(Color.blue) | |
.frame(height: 6).padding(.horizontal, 1.5) | |
} | |
) | |
// Shelf | |
RoundedRectangle(cornerRadius: 5) | |
.fill( | |
LinearGradient( | |
gradient: Gradient( | |
colors: [Color(red: 155/255, green: 155/255, blue: 155/255).opacity(0.5), Color.white.opacity(0.85)]), | |
startPoint: .top, endPoint: .bottom) | |
) | |
.frame(height: 85) | |
.rotation3DEffect( | |
Angle(degrees: 50), | |
axis: (x: 1, y: 0, z: 0), anchor: .bottom | |
) | |
.offset(x: 0, y: -4) | |
.shadow(color: .white, radius: 0, x: 0, y: 1) | |
// Icons | |
HStack { | |
ForEach(items, id: \.self) { item in | |
Button { | |
guard let url = URL(string: item) else { return } | |
NSWorkspace.shared.open(url) | |
} label: { | |
SystemIcon(forURL: item)?.resizable().aspectRatio(contentMode: .fit) | |
}.buttonStyle(PlainButtonStyle()) | |
} | |
}.frame(height: 75).offset(y: -15) | |
// Reflections | |
HStack { | |
ForEach(items, id: \.self) { item in | |
SystemIcon(forURL: item)?.resizable().aspectRatio(contentMode: .fit) | |
} | |
}.frame(height: 75) | |
.rotation3DEffect( | |
Angle(degrees: 180), | |
axis: (x: 1, y: 0, z: 0.0) | |
) | |
.offset(y: 57) | |
.mask( | |
Rectangle() | |
.offset(y: -2) | |
) | |
.blur(radius: 4) | |
.opacity(0.3) | |
// Running indicators | |
HStack(alignment: .bottom, spacing: 70) { | |
ForEach(items, id: \.self) { item in | |
if NSWorkspace.shared | |
.runningApplications | |
.first(where: { $0.bundleURL?.absoluteString.contains(item) ?? false }) != nil { | |
Rectangle() | |
.fill(Color.white) | |
.frame(width: 13, height: 8) | |
.offset(y: 5) | |
.shadow(color: Color(red: 168/255, green: 238/255, blue: 1), radius: 7, x: 0, y: 0) | |
} else { | |
Spacer().frame(width: 13) | |
} | |
}.opacity(refresh ? 1 : 1) | |
} | |
} | |
}.onAppear { | |
_ = Timer.scheduledTimer(withTimeInterval: 1, repeats: true, block: { _ in | |
refresh.toggle() | |
}) | |
} | |
} | |
} | |
// MARK: - Supporting Functions | |
func SystemIcon(forURL url: String) -> Image? { | |
guard let icon = | |
NSWorkspace.shared.icon(forFile: url.replacingOccurrences(of: "file://", with: "")) | |
.representations | |
.first(where: { $0.size.width > 150 })? | |
.cgImage(forProposedRect: nil, context: nil, hints: nil) | |
else { return nil } | |
let nsImage = NSImage(cgImage: icon, size: CGSize(width: icon.width, height: icon.height)) | |
return Image(nsImage: nsImage) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Cocoa | |
import SwiftUI | |
@main | |
class AppDelegate: NSObject, NSApplicationDelegate { | |
var window: NSWindow! | |
func applicationDidFinishLaunching(_ aNotification: Notification) { | |
let contentView = ContentView() | |
let width = CGFloat(items.count) * 83 + 80 | |
window = NSWindow( | |
contentRect: NSRect(x: (NSScreen.main!.frame.width - width) / 2, y: 0, width: width, height: 130), | |
styleMask: [.fullSizeContentView], | |
backing: .buffered, defer: false) | |
window.hasShadow = false | |
window.backgroundColor = .clear | |
window.level = NSWindow.Level(1000) | |
window.collectionBehavior = .canJoinAllSpaces | |
window.contentView = NSHostingView(rootView: contentView) | |
window.makeKeyAndOrderFront(nil) | |
} | |
func applicationWillTerminate(_ aNotification: Notification) { } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment