Last active
November 22, 2018 16:02
-
-
Save bellbind/b69f6ef133f0ad5266ff40be2001aecc to your computer and use it in GitHub Desktop.
[macos][swift4] DisplayMode switcher on StatusBar
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
#!/usr/bin/env swift | |
// DisplayMode switcher on StatrusBar (for swift4) | |
// $ swiftc DisplayModeSwitcher.swift | |
import Cocoa | |
let monoText = NSFont.monospacedDigitSystemFont(ofSize: NSFont.systemFontSize, weight: .regular) | |
let attrsT: [NSAttributedString.Key: Any] = [.font: monoText] | |
let attrsS: [NSAttributedString.Key: Any] = [.font: monoText, .expansion: 0.8] | |
func resolution(_ id: String, _ w: String, _ h: String, _ mark: String) -> NSAttributedString { | |
let parts = [(String(repeating: " ", count: 3 - id.count), attrsS), ("\(id): ", attrsT), | |
(String(repeating: " ", count: 5 - w.count), attrsS), ("\(w) x \(h)", attrsT), | |
(String(repeating: " ", count: 5 - h.count), attrsS), (mark, attrsT)] | |
let title = NSMutableAttributedString() | |
for (text, attrs) in parts {title.append(NSAttributedString(string: text, attributes: attrs))} | |
return title | |
} | |
class Main: NSObject, NSMenuDelegate { | |
func menuWillOpen(_ menu: NSMenu) { | |
menu.removeAllItems() | |
let display = CGMainDisplayID() | |
let modes = CGDisplayCopyAllDisplayModes(display, nil) | |
guard let dmodes = modes as? [CGDisplayMode] else {return} | |
if let current = CGDisplayCopyDisplayMode(display) { | |
let now = NSMenuItem() | |
now.attributedTitle = resolution("Now", "\(current.width)", "\(current.height)", "") | |
menu.addItem(now) | |
menu.addItem(NSMenuItem.separator()) | |
let items = dmodes.enumerated().map {(i, dmode) -> NSMenuItem in | |
let mi = NSMenuItem() | |
let mark = dmode.ioDisplayModeID == current.ioDisplayModeID ? "\u{2713}" : "" | |
mi.attributedTitle = resolution("\(i)", "\(dmode.width)", "\(dmode.height)", mark) | |
mi.action = #selector(self.switchMode) | |
mi.target = self | |
mi.tag = i | |
return mi | |
} | |
for item in items {menu.addItem(item)} | |
} | |
menu.addItem(NSMenuItem.separator()) | |
let terminate = #selector(NSApplication.shared.terminate) | |
menu.addItem(withTitle: "Quit", action: terminate, keyEquivalent: "") | |
} | |
@objc func switchMode(_ sender: NSMenuItem) { | |
let display = CGMainDisplayID() | |
let modes = CGDisplayCopyAllDisplayModes(display, nil) | |
guard let dmodes = modes as? [CGDisplayMode] else {return} | |
let config = UnsafeMutablePointer<CGDisplayConfigRef?>.allocate(capacity: 1) | |
defer {config.deallocate()} | |
CGBeginDisplayConfiguration(config) | |
CGConfigureDisplayWithDisplayMode(config.pointee, display, dmodes[sender.tag], nil) | |
CGCompleteDisplayConfiguration(config.pointee, CGConfigureOption.permanently) | |
} | |
} | |
let main = Main() | |
NSApplication.loadApplication() | |
let menu = NSMenu() | |
menu.delegate = main | |
let statusItem = NSStatusBar.system.statusItem(withLength: -1) | |
//statusItem.button?.title = "\u{1F5A5}" | |
statusItem.button?.title = "\u{1F4BB}" | |
statusItem.menu = menu | |
NSApplication.shared.run() |
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
<svg xmlns="http://www.w3.org/2000/svg" viewVox="0 0 300 300"> | |
<text x="50%" y="60%" text-anchor="middle" dominant-baseline="central" font-size="300">💻</text> | |
</svg> |
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
<?xml version="1.0" encoding="UTF-8"?> | |
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |
<plist version="1.0"> | |
<dict> | |
<key>CFBundleInfoDictionaryVersion</key> | |
<string>6.0</string> | |
<key>CFBundlePackageType</key> | |
<string>APPL</string> | |
<key>CFBundleDevelopmentRegion</key> | |
<string>en</string> | |
<key>CFBundleExecutable</key> | |
<string>%name%</string> | |
<key>CFBundleIdentifier</key> | |
<string>%id%</string> | |
<key>CFBundleIconFile</key> | |
<string>%name%.icns</string> | |
<key>CFBundleName</key> | |
<string>%name%</string> | |
<key>CFBundleShortVersionString</key> | |
<string>1.0</string> | |
<key>CFBundleVersion</key> | |
<string>1</string> | |
<key>LSUIElement</key> | |
<true/> | |
</dict> | |
</plist> |
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
#!/bin/bash | |
if [ "$(which convert)" == "" ] ; then | |
echo "[Abort] Please install imagemagick" | |
exit 1 | |
fi | |
namespace=bellbind | |
name=DisplayModeSwitcher | |
svg=icon.svg | |
id="$namespace.$name" | |
#NOTE: Prepare your certificate in "Keychain Access" | |
#cert=bellbind | |
# build bin | |
cd $(dirname $0) | |
swiftopts="" | |
swiftc $swiftopts "$name.swift" | |
# build icns from svg | |
iconset="$name.iconset" | |
png="$svg.png" | |
opts="-fuzz 15% -transparent white" | |
mkdir -p "$iconset" | |
qlmanage -t -s 1024 -o . "$svg" | |
convert "$png" $opts -resize 16x16 "$iconset/icon_16x16.png" | |
convert "$png" $opts -resize 32x32 "$iconset/icon_16x16@2x.png" | |
convert "$png" $opts -resize 32x32 "$iconset/icon_32x32.png" | |
convert "$png" $opts -resize 64x64 "$iconset/icon_32x32@2x.png" | |
convert "$png" $opts -resize 128x128 "$iconset/icon_128x128.png" | |
convert "$png" $opts -resize 256x256 "$iconset/icon_128x128@2x.png" | |
convert "$png" $opts -resize 256x256 "$iconset/icon_256x256.png" | |
convert "$png" $opts -resize 512x512 "$iconset/icon_256x256@2x.png" | |
convert "$png" $opts -resize 512x512 "$iconset/icon_512x512.png" | |
convert "$png" $opts -resize 1024x1024 "$iconset/icon_512x512@2x.png" | |
iconutil -c icns "$iconset" | |
# build app bundle | |
app="$name.app" | |
mkdir -p "$app/Contents/MacOS" | |
mkdir -p "$app/Contents/Resources" | |
sed -e "s/%name%/$name/g;s/%id%/$id/g" Info.plist.xml > "$app/Contents/Info.plist" | |
cp "$name" "$app/Contents/MacOS" | |
cp "$name.icns" "$app/Contents/Resources" | |
# cleanup | |
rm -r "$name.iconset" | |
rm "$name" "$name.icns" "$png" | |
# codesign | |
if [ "$cert" ] ; then | |
codesign -s "$cert" "$app" | |
fi | |
# make dmg | |
mkdir -p dmg/ | |
cp -a "$app" dmg/ | |
( cd dmg ; ln -s /Applications/ ) | |
hdiutil create -srcfolder dmg -volname "$name" "$name.dmg" | |
rm -rf dmg/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
CLI command version: https://gist.github.com/bellbind/27220148ea752335259dfce63f43bd5d
Hidden CoreGraphics API version: https://gist.github.com/bellbind/0cbd295130e4e1dc4459925e81048cf1