Skip to content

Commit

Permalink
add alternative dots-icon
Browse files Browse the repository at this point in the history
  • Loading branch information
relikd committed Oct 21, 2021
1 parent 86e33a8 commit 0371e31
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 27 deletions.
52 changes: 29 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,34 @@

Memmon remembers what your Mac forgets – A simple deamon that restores your window positions on external monitors.


## Install

1. You will need macOS 10.10 or newer.
2. Grant Memmon the Accessibility privilege. Go to "System Preference" > "Security & Privacy" > "Accessibility" and add Memmon to that list. Otherwise, you can't move other application windows around and the app has no purpose.
3. Thats it. The app runs in your status bar.


### Status Icon

You can hide the status icon either via `defaults` or the same-titled menu entry. If you do so, the only way to quit the app is by killing the process (with Activity.app or `killall Memmon`).

Memmon has exactly one app-setting, the status icon. You can manipulate the display of the icon, or hide the icon completely:

```sh
# disable status icon completely
defaults write de.relikd.Memmon icon -int 0
# Use window-dots-icon
defaults write de.relikd.Memmon icon -int 1
# Use monitor-with-windows icon (default)
defaults write de.relikd.Memmon icon -int 2
# re-enable status icon and use default icon
defaults delete de.relikd.Memmon icon
```

![status icons](img/status_icons.png)


## FAQ

### Why‽
Expand All @@ -23,33 +51,11 @@ Yes, for example [Mjolnir](https://github.com/mjolnirapp/mjolnir) or [Hammerspoo

### What is it good for?

First off, Memmon is just 130 lines of code – no dependencies. You can audit it in 5 minutes. Or just build it from scratch if you like (just run `make`).
First off, Memmon is just 140 lines of code – no dependencies. You can audit it in 5 minutes and build it from scratch just run `make`.

Secondly, it does one thing and one thing only: Save and restore window positions whenever your monitor setup changes.


## Install

1. You will need macOS 10.10 or newer.
2. Grant Memmon the Accessibility privilege. Go to "System Preference" > "Security & Privacy" > "Accessibility" and add Memmon to that list. Otherwise, you can't move other application windows around and the app has no purpose.
3. Thats it. The app runs in your status bar.

### Develop

You can either run the `main.swift` file directly with `swift main.swift`, via Terminal `./main.swift` (`chmod 755 main.swift`), or create a new Xcode project. Select the Command-Line template and after creation replace the existing `main.swift` with the bundled one.

To build the app run `make`.


### Hide Status Icon

You can hide the status icon either via the same-titled menu entry. If you do so, the only way to quit the app is by killing the process (with Activity.app or `killall Memmon`).

If you like to hide the icon directly on launch, use this app-setting:

```sh
# disable status icon completely
defaults write de.relikd.Memmon invisible -bool True
# re-enable status icon
defaults delete de.relikd.Memmon invisible
```
Binary file added img/status_icons.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 26 additions & 4 deletions src/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,16 @@ class AppDelegate: NSObject, NSApplicationDelegate {
private var state: [Int: WinConf] = [:] // [screencount: [pid: [windows]]]

func applicationDidFinishLaunching(_ aNotification: Notification) {
if UserDefaults.standard.bool(forKey: "invisible") == true {
return
}
UserDefaults.standard.register(defaults: ["icon": 2])
let icon = UserDefaults.standard.integer(forKey: "icon")
if icon == 0 { return }
self.statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
if let button = self.statusItem.button {
button.image = NSImage.statusIconMonitor
switch icon {
case 1: button.image = NSImage.statusIconDots
case 2: button.image = NSImage.statusIconMonitor
default: button.image = NSImage.statusIconMonitor
}
}
self.statusItem.menu = NSMenu(title: "")
self.statusItem.menu!.addItem(withTitle: "Memmon (v1.1)", action: nil, keyEquivalent: "")
Expand Down Expand Up @@ -134,6 +138,24 @@ class AppDelegate: NSObject, NSApplicationDelegate {
}

extension NSImage {
static var statusIconDots: NSImage {
let img = NSImage.init(size: .init(width: 20, height: 20), flipped: true) {
let ctx = NSGraphicsContext.current!.cgContext
let w = $0.width
let h = $0.height
let sw = 0.025 * w // stroke width
ctx.stroke(CGRect(x: 0.0 * w, y: 0.15 * h, width: 1.0 * w, height: 0.7 * h).insetBy(dx: sw / 2, dy: sw / 2), width: sw)
ctx.fill(CGRect(x: 0, y: 0.55 * h, width: w, height: sw))
let circle = CGRect(x: 0, y: 0.25 * h, width: 0.2 * w, height: 0.2 * w)
ctx.fillEllipse(in: circle.offsetBy(dx: 0.12 * w, dy: 0))
ctx.fillEllipse(in: circle.offsetBy(dx: 0.4 * w, dy: 0))
ctx.fillEllipse(in: circle.offsetBy(dx: 0.68 * w, dy: 0))
return true
}
img.isTemplate = true
return img
}

static var statusIconMonitor: NSImage {
let img = NSImage.init(size: .init(width: 21, height: 14), flipped: true) {
let ctx = NSGraphicsContext.current!.cgContext
Expand Down

0 comments on commit 0371e31

Please sign in to comment.