9 Commits

Author SHA1 Message Date
neon443
c099d4bec3 Merge remote-tracking branch 'refs/remotes/origin/main' 2025-05-28 15:53:28 +01:00
neon443
5718e42f41 added settings: saves dock moves, smaller deathzone in fullscreeen etc 2025-05-28 15:52:40 +01:00
neon443
936f18d714 add fullscreen support, fix dock moving to the right when hovering over menu bar icon 2025-05-27 16:34:01 +01:00
Nihaal Sharma
3e7a7c2ac2 README.md 2025-05-27 15:05:28 +01:00
neon443
43863d3827 _ 2025-05-26 19:22:05 +01:00
neon443
f18874deb3 version bump 2025-05-26 17:26:24 +01:00
neon443
7ba2e84cb1 fix quit button 2025-05-26 17:24:19 +01:00
Nihaal Sharma
bc2bc9bb6d Update README.md 2025-05-26 13:47:13 +01:00
neon443
d954730117 icon stuff 2025-05-26 13:43:42 +01:00
10 changed files with 175 additions and 26 deletions

View File

@@ -5,8 +5,8 @@
// Created by neon443 on 26/05/2025. // Created by neon443 on 26/05/2025.
// //
VERSION = 1.0 VERSION = 1.0.1
BUILD_ID = 4 BUILD_ID = 2
TEAM_ID = 8JGND254B7 TEAM_ID = 8JGND254B7
BUNDLE_ID = com.neon443.DockPhobia BUNDLE_ID = com.neon443.DockPhobia

View File

@@ -11,6 +11,7 @@
A966B4F42DE0842500C721A5 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A966B4EE2DE0842400C721A5 /* AppDelegate.swift */; }; A966B4F42DE0842500C721A5 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A966B4EE2DE0842400C721A5 /* AppDelegate.swift */; };
A966B4F52DE0842500C721A5 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A966B4EF2DE0842400C721A5 /* Assets.xcassets */; }; A966B4F52DE0842500C721A5 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A966B4EF2DE0842400C721A5 /* Assets.xcassets */; };
A966B4F82DE0852900C721A5 /* MouseTracker.swift in Sources */ = {isa = PBXBuildFile; fileRef = A966B4F72DE0852900C721A5 /* MouseTracker.swift */; }; A966B4F82DE0852900C721A5 /* MouseTracker.swift in Sources */ = {isa = PBXBuildFile; fileRef = A966B4F72DE0852900C721A5 /* MouseTracker.swift */; };
A98C20C62DE614180008D61C /* DPSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98C20C52DE614180008D61C /* DPSettings.swift */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
@@ -21,6 +22,7 @@
A966B4F02DE0842400C721A5 /* DockPhobia.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DockPhobia.entitlements; sourceTree = "<group>"; }; A966B4F02DE0842400C721A5 /* DockPhobia.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DockPhobia.entitlements; sourceTree = "<group>"; };
A966B4F72DE0852900C721A5 /* MouseTracker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MouseTracker.swift; sourceTree = "<group>"; }; A966B4F72DE0852900C721A5 /* MouseTracker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MouseTracker.swift; sourceTree = "<group>"; };
A97798072DE485F200B6CB13 /* Config.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Config.xcconfig; sourceTree = "<group>"; }; A97798072DE485F200B6CB13 /* Config.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Config.xcconfig; sourceTree = "<group>"; };
A98C20C52DE614180008D61C /* DPSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DPSettings.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@@ -72,6 +74,7 @@
children = ( children = (
A966B4EE2DE0842400C721A5 /* AppDelegate.swift */, A966B4EE2DE0842400C721A5 /* AppDelegate.swift */,
A966B4F72DE0852900C721A5 /* MouseTracker.swift */, A966B4F72DE0852900C721A5 /* MouseTracker.swift */,
A98C20C52DE614180008D61C /* DPSettings.swift */,
A94BEC102DE23ECE00D4811D /* Views */, A94BEC102DE23ECE00D4811D /* Views */,
A94BEC0A2DE21F8100D4811D /* Resources */, A94BEC0A2DE21F8100D4811D /* Resources */,
A966B4F02DE0842400C721A5 /* DockPhobia.entitlements */, A966B4F02DE0842400C721A5 /* DockPhobia.entitlements */,
@@ -152,6 +155,7 @@
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
A98C20C62DE614180008D61C /* DPSettings.swift in Sources */,
A966B4F82DE0852900C721A5 /* MouseTracker.swift in Sources */, A966B4F82DE0852900C721A5 /* MouseTracker.swift in Sources */,
A966B4F42DE0842500C721A5 /* AppDelegate.swift in Sources */, A966B4F42DE0842500C721A5 /* AppDelegate.swift in Sources */,
); );
@@ -294,6 +298,7 @@
ENABLE_HARDENED_RUNTIME = YES; ENABLE_HARDENED_RUNTIME = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO; ENABLE_USER_SCRIPT_SANDBOXING = NO;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.entertainment";
INFOPLIST_KEY_LSUIElement = YES; INFOPLIST_KEY_LSUIElement = YES;
INFOPLIST_KEY_NSAppleEventsUsageDescription = _; INFOPLIST_KEY_NSAppleEventsUsageDescription = _;
INFOPLIST_KEY_NSHumanReadableCopyright = ""; INFOPLIST_KEY_NSHumanReadableCopyright = "";
@@ -328,6 +333,7 @@
ENABLE_HARDENED_RUNTIME = YES; ENABLE_HARDENED_RUNTIME = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO; ENABLE_USER_SCRIPT_SANDBOXING = NO;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.entertainment";
INFOPLIST_KEY_LSUIElement = YES; INFOPLIST_KEY_LSUIElement = YES;
INFOPLIST_KEY_NSAppleEventsUsageDescription = _; INFOPLIST_KEY_NSAppleEventsUsageDescription = _;
INFOPLIST_KEY_NSHumanReadableCopyright = ""; INFOPLIST_KEY_NSHumanReadableCopyright = "";

BIN
DockPhobia/.DS_Store vendored
View File

Binary file not shown.

View File

@@ -12,25 +12,31 @@ class AppDelegate: NSObject, NSApplicationDelegate {
public var statusItem: NSStatusItem! public var statusItem: NSStatusItem!
var mouseTracker = MouseTracker() var settings = DPSettingsModel()
var mouseTracker: MouseTracker
override init() {
self.mouseTracker = MouseTracker(settings: settings)
super.init()
}
func applicationDidFinishLaunching(_ aNotification: Notification) { func applicationDidFinishLaunching(_ aNotification: Notification) {
statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength) statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
if let button = statusItem.button { if let button = statusItem.button {
button.image = NSImage(named: "cursor.slash") button.image = NSImage(named: "cursor.slash")
} }
setupMenus() refreshMenus()
} }
func applicationWillTerminate(_ aNotification: Notification) { func applicationWillTerminate(_ aNotification: Notification) {
// Insert code here to tear down your application settings.saveSettings()
} }
func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool { func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
return true return true
} }
//MARK: menu bar stuff
func setupMenus() { func setupMenus() {
let menu = NSMenu() let menu = NSMenu()
let start = NSMenuItem(title: describeStartButton(), action: #selector(didTapStart), keyEquivalent: "") let start = NSMenuItem(title: describeStartButton(), action: #selector(didTapStart), keyEquivalent: "")
@@ -43,6 +49,22 @@ class AppDelegate: NSObject, NSApplicationDelegate {
) )
menu.addItem(screen) menu.addItem(screen)
let dockMoves = NSMenuItem(
title: "Moved the Dock \(settings.settings.dockMoves) time\(settings.settings.dockMoves.plural)",
action: nil,
keyEquivalent: ""
)
menu.addItem(dockMoves)
menu.addItem(NSMenuItem.separator())
let checkfullscreenButton = NSMenuItem(
title: "Smaller deathzone in fullscreen",
action: #selector(checkFullscreenToggle),
keyEquivalent: ""
)
checkfullscreenButton.state = NSControl.StateValue(rawValue: settings.settings.checkFullscreen ? 1 : 0)
menu.addItem(checkfullscreenButton)
menu.addItem(NSMenuItem.separator()) menu.addItem(NSMenuItem.separator())
menu.addItem( menu.addItem(
@@ -69,11 +91,10 @@ class AppDelegate: NSObject, NSApplicationDelegate {
menu.addItem(NSMenuItem.separator()) menu.addItem(NSMenuItem.separator())
let quit = NSMenuItem(title: "Quit", action: #selector(didTapStart), keyEquivalent: "q") let quit = NSMenuItem(title: "Quit", action: #selector(quit), keyEquivalent: "q")
menu.addItem(quit) menu.addItem(quit)
statusItem.menu = menu statusItem.menu = menu
} }
func changeMenuIcon(running: Bool) { func changeMenuIcon(running: Bool) {
guard let button = statusItem.button else { return } guard let button = statusItem.button else { return }
switch running { switch running {
@@ -83,7 +104,6 @@ class AppDelegate: NSObject, NSApplicationDelegate {
button.image = NSImage(named: "cursor.slash") button.image = NSImage(named: "cursor.slash")
} }
} }
@objc func didTapStart() { @objc func didTapStart() {
if mouseTracker.running { if mouseTracker.running {
mouseTracker.stop() mouseTracker.stop()
@@ -92,13 +112,18 @@ class AppDelegate: NSObject, NSApplicationDelegate {
mouseTracker.start() mouseTracker.start()
changeMenuIcon(running: true) changeMenuIcon(running: true)
} }
setupMenus() refreshMenus()
}
@objc func quit() {
NSApplication.shared.terminate(self)
} }
@objc func moveDockObjcLeft() { mouseTracker.moveDock(.left) } @objc func moveDockObjcLeft() { mouseTracker.moveDock(.left) }
@objc func moveDockObjcRight() { mouseTracker.moveDock(.right) } @objc func moveDockObjcRight() { mouseTracker.moveDock(.right) }
@objc func moveDockObjcBottom() { mouseTracker.moveDock(.bottom) } @objc func moveDockObjcBottom() { mouseTracker.moveDock(.bottom) }
@objc func checkFullscreenToggle() {
settings.settings.checkFullscreen.toggle()
refreshMenus()
}
func describeStartButton() -> String { func describeStartButton() -> String {
if mouseTracker.running { if mouseTracker.running {
return "Stop tracking" return "Stop tracking"
@@ -107,3 +132,14 @@ class AppDelegate: NSObject, NSApplicationDelegate {
} }
} }
} }
func refreshMenus() {
guard let delegate = NSApp.delegate as? AppDelegate else { return }
delegate.setupMenus()
}
extension Numeric {
var plural: String {
return self == 1 ? "" : "s"
}
}

View File

@@ -0,0 +1,40 @@
//
// Persistence.swift
// DockPhobia
//
// Created by neon443 on 27/05/2025.
//
import Foundation
import AppKit
struct DPSettings: Codable {
var dockMoves: Int = 0
var checkFullscreen: Bool = false
}
class DPSettingsModel {
var settings = DPSettings()
let userDefaults = UserDefaults.standard
init() {
guard let data = userDefaults.data(forKey: "settings") else { return }
let decoder = JSONDecoder()
guard let decoded = try? decoder.decode(DPSettings.self, from: data) else {
return
}
self.settings = decoded
refreshMenus()
}
func saveSettings() {
let encoder = JSONEncoder()
guard let encoded = try? encoder.encode(settings) else {
return
}
userDefaults.set(encoded, forKey: "settings")
}
}

View File

@@ -7,6 +7,8 @@
import Foundation import Foundation
import AppKit import AppKit
import Cocoa
import ApplicationServices
struct Screen { struct Screen {
var width: CGFloat var width: CGFloat
@@ -75,7 +77,9 @@ class MouseTracker {
var dockHeight: CGFloat = 0 var dockHeight: CGFloat = 0
init() { var settings: DPSettingsModel
init(settings: DPSettingsModel) {
print(DockSide()) print(DockSide())
if let screen = NSScreen.main { if let screen = NSScreen.main {
let rect = screen.frame let rect = screen.frame
@@ -87,18 +91,35 @@ class MouseTracker {
} else { } else {
fatalError("no screen wtf???") fatalError("no screen wtf???")
} }
self.settings = settings
self.currentDockSide = .left self.currentDockSide = .left
moveDock(.bottom) moveDock(.bottom)
getDockSize() getDockSize()
} }
func checkMouse(_ event: NSEvent) { func checkMouse(_ event: NSEvent) {
var location = event.locationInWindow var location = NSEvent.mouseLocation
location.y = screen.height - location.y location.y = screen.height - location.y
#if DEBUG
print(location) guard settings.settings.checkFullscreen else {
#endif handleDockValue(dockIsAt: currentDockSide, location: location)
switch currentDockSide { return
}
guard isFrontmostFullscreen() else {
if location.x < 1 ||
location.x < screen.width-1 ||
location.y > screen.height-1 {
handleDockValue(dockIsAt: currentDockSide, location: location)
}
return
}
}
func handleDockValue(dockIsAt: DockSide, location: NSPoint) {
switch dockIsAt {
case .left: case .left:
guard location.x < dockHeight else { return } guard location.x < dockHeight else { return }
if location.y < screen.height/2 { if location.y < screen.height/2 {
@@ -167,6 +188,8 @@ class MouseTracker {
applescript(scriptMove) applescript(scriptMove)
// applescript(scriptShow) // applescript(scriptShow)
currentDockSide = toSide currentDockSide = toSide
settings.settings.dockMoves += 1
refreshMenus()
} }
func getDockSize() { func getDockSize() {
@@ -187,3 +210,27 @@ class MouseTracker {
return nil return nil
} }
} }
func isFrontmostFullscreen() -> Bool {
guard let frontmostApp = NSWorkspace.shared.frontmostApplication,
let appPID = frontmostApp.processIdentifier as pid_t? else {
return false
}
let appElement = AXUIElementCreateApplication(appPID)
var frontWindo: AnyObject?
let result = AXUIElementCopyAttributeValue(appElement, kAXFocusedWindowAttribute as CFString, &frontWindo)
guard result == .success, let windowElement = frontWindo else {
return false
}
var fullscreenValue: AnyObject?
let fullscreenAttr = AXUIElementCopyAttributeValue(windowElement as! AXUIElement, "AXFullScreen" as CFString, &fullscreenValue)
if fullscreenAttr == .success,
let isFullscreen = fullscreenValue as? Bool {
return isFullscreen
}
return false
}

View File

@@ -55,7 +55,7 @@
"size" : "512x512" "size" : "512x512"
}, },
{ {
"filename" : "DockPhobiaAppIcon1024.png", "filename" : "DockPhobiaAppIcon.png",
"idiom" : "mac", "idiom" : "mac",
"scale" : "2x", "scale" : "2x",
"size" : "512x512" "size" : "512x512"

View File

Before

Width:  |  Height:  |  Size: 560 KiB

After

Width:  |  Height:  |  Size: 560 KiB

BIN
DockPhobiaPy/.DS_Store vendored
View File

Binary file not shown.

View File

@@ -1,5 +1,25 @@
# DockPhobia # DockPhobia
<div align="center">
<br/>
<p>
<img src="https://github.com/neon443/DockPhobia/blob/main/DockPhobia/Resources/Assets.xcassets/AppIcon.appiconset/DockPhobiaAppIcon.png?raw=true" title="dockphobia" alt="dockphobia icon" width="200" />
</p>
<p>
make your Dock scared of the mouse
<br/>
<a href="https://neon443.github.io">
made by neon443
</a>
</p>
<p>
<a href="https://github.com/neon443/DockPhobia/releases/latest/download/DockPhobia.dmg">
download
</a>
</p>
<br/>
</div>
Have you ever wanted to use your Dock? Have you ever wanted to use your Dock?
well now you cant well now you cant
@@ -8,17 +28,17 @@ well now you cant
- calculates the size of your screen & Dock - calculates the size of your screen & Dock
- when your cursor is on the Dock (+ extra 5% of screen), the Dock moves to a different side of the screen - when your cursor is on the Dock (+ extra 5% of screen), the Dock moves to a different side of the screen
- it also figures out the furthest it can be, for example if your cursor is at the top left quarter of the screen and near the Dock on the left, the dock moves to the bottom as that is the furthest, etc - it also figures out the furthest it can be, for example if your cursor is at the top left quarter of the screen and near the Dock on the left, the dock moves to the bottom as that is the furthest, etc
- -
## Quick start Guide (Swift Mac App) ## Quick start Guide (Mac App)
(Currently not functional) - Go to [releases](https://github.com/neon443/DockPhobia/releases)
``` - Download the latest version
git clone https://github.com/neon443/DockPhobia - That's it!
cd DockPhobia
open DockPhobia.xcodeproj ## Contributing
``` PRs welcome, as long as you use tabs instead of spaces lol
## Quick start Guide (Python version) ## Quick start Guide (Python version)
Dont use this, still here purely for archival purposes, use the native Mac app instead.
``` ```
xcode-select --install xcode-select --install
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"