mirror of
https://github.com/neon443/DockPhobia.git
synced 2026-03-11 23:06:17 +00:00
Compare commits
13 Commits
1.0
...
853fc2a2db
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
853fc2a2db | ||
|
|
6a68713ad5 | ||
|
|
b15116b292 | ||
|
|
e4c41c4a58 | ||
|
|
c099d4bec3 | ||
|
|
5718e42f41 | ||
|
|
936f18d714 | ||
|
|
3e7a7c2ac2 | ||
|
|
43863d3827 | ||
|
|
f18874deb3 | ||
|
|
7ba2e84cb1 | ||
|
|
bc2bc9bb6d | ||
|
|
d954730117 |
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,9 @@
|
|||||||
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 */; };
|
||||||
|
A9C9AF812DE7776A0039D7A5 /* DockSide.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9C9AF802DE777530039D7A5 /* DockSide.swift */; };
|
||||||
|
A9C9AF832DE77CB70039D7A5 /* SkyHigh.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9C9AF822DE77CB70039D7A5 /* SkyHigh.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
@@ -21,6 +24,9 @@
|
|||||||
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>"; };
|
||||||
|
A9C9AF802DE777530039D7A5 /* DockSide.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DockSide.swift; sourceTree = "<group>"; };
|
||||||
|
A9C9AF822DE77CB70039D7A5 /* SkyHigh.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkyHigh.swift; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
@@ -72,6 +78,9 @@
|
|||||||
children = (
|
children = (
|
||||||
A966B4EE2DE0842400C721A5 /* AppDelegate.swift */,
|
A966B4EE2DE0842400C721A5 /* AppDelegate.swift */,
|
||||||
A966B4F72DE0852900C721A5 /* MouseTracker.swift */,
|
A966B4F72DE0852900C721A5 /* MouseTracker.swift */,
|
||||||
|
A9C9AF822DE77CB70039D7A5 /* SkyHigh.swift */,
|
||||||
|
A98C20C52DE614180008D61C /* DPSettings.swift */,
|
||||||
|
A9C9AF802DE777530039D7A5 /* DockSide.swift */,
|
||||||
A94BEC102DE23ECE00D4811D /* Views */,
|
A94BEC102DE23ECE00D4811D /* Views */,
|
||||||
A94BEC0A2DE21F8100D4811D /* Resources */,
|
A94BEC0A2DE21F8100D4811D /* Resources */,
|
||||||
A966B4F02DE0842400C721A5 /* DockPhobia.entitlements */,
|
A966B4F02DE0842400C721A5 /* DockPhobia.entitlements */,
|
||||||
@@ -152,8 +161,11 @@
|
|||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
A98C20C62DE614180008D61C /* DPSettings.swift in Sources */,
|
||||||
|
A9C9AF832DE77CB70039D7A5 /* SkyHigh.swift in Sources */,
|
||||||
A966B4F82DE0852900C721A5 /* MouseTracker.swift in Sources */,
|
A966B4F82DE0852900C721A5 /* MouseTracker.swift in Sources */,
|
||||||
A966B4F42DE0842500C721A5 /* AppDelegate.swift in Sources */,
|
A966B4F42DE0842500C721A5 /* AppDelegate.swift in Sources */,
|
||||||
|
A9C9AF812DE7776A0039D7A5 /* DockSide.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@@ -294,6 +306,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 +341,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
BIN
DockPhobia/.DS_Store
vendored
Binary file not shown.
@@ -7,30 +7,36 @@
|
|||||||
|
|
||||||
import AppKit
|
import AppKit
|
||||||
|
|
||||||
@main
|
@NSApplicationMain
|
||||||
class AppDelegate: NSObject, NSApplicationDelegate {
|
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,37 +49,51 @@ 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())
|
menu.addItem(NSMenuItem.separator())
|
||||||
|
|
||||||
menu.addItem(
|
let moveMouseButton = NSMenuItem(
|
||||||
NSMenuItem(
|
title: "Move cursor instead",
|
||||||
|
action: #selector(moveMouseToggle),
|
||||||
|
keyEquivalent: ""
|
||||||
|
)
|
||||||
|
moveMouseButton.state = NSControl.StateValue(rawValue: settings.settings.moveMouseInstead ? 1 : 0)
|
||||||
|
menu.addItem(moveMouseButton)
|
||||||
|
|
||||||
|
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(
|
||||||
title: "Move Dock to left",
|
title: "Move Dock to left",
|
||||||
action: #selector(moveDockObjcLeft),
|
action: #selector(moveDockObjcLeft),
|
||||||
keyEquivalent: ""
|
keyEquivalent: ""))
|
||||||
)
|
menu.addItem(NSMenuItem(
|
||||||
)
|
|
||||||
menu.addItem(
|
|
||||||
NSMenuItem(
|
|
||||||
title: "Move Dock to bottom",
|
title: "Move Dock to bottom",
|
||||||
action: #selector(moveDockObjcBottom),
|
action: #selector(moveDockObjcBottom),
|
||||||
keyEquivalent: ""
|
keyEquivalent: ""))
|
||||||
)
|
menu.addItem(NSMenuItem(
|
||||||
)
|
|
||||||
menu.addItem(
|
|
||||||
NSMenuItem(
|
|
||||||
title: "Move Dock to right",
|
title: "Move Dock to right",
|
||||||
action: #selector(moveDockObjcRight),
|
action: #selector(moveDockObjcRight),
|
||||||
keyEquivalent: ""
|
keyEquivalent: ""))
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
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 +103,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 +111,22 @@ 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()
|
||||||
|
}
|
||||||
|
@objc func moveMouseToggle() {
|
||||||
|
settings.settings.moveMouseInstead.toggle()
|
||||||
|
refreshMenus()
|
||||||
|
}
|
||||||
func describeStartButton() -> String {
|
func describeStartButton() -> String {
|
||||||
if mouseTracker.running {
|
if mouseTracker.running {
|
||||||
return "Stop tracking"
|
return "Stop tracking"
|
||||||
@@ -107,3 +135,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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
41
DockPhobia/DPSettings.swift
Normal file
41
DockPhobia/DPSettings.swift
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
//
|
||||||
|
// 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
|
||||||
|
var moveMouseInstead: 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")
|
||||||
|
}
|
||||||
|
}
|
||||||
59
DockPhobia/DockSide.swift
Normal file
59
DockPhobia/DockSide.swift
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
//
|
||||||
|
// DockSide.swift
|
||||||
|
// DockPhobia
|
||||||
|
//
|
||||||
|
// Created by neon443 on 28/05/2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
enum DockSide: Int, RawRepresentable {
|
||||||
|
case left
|
||||||
|
case bottom
|
||||||
|
case right
|
||||||
|
|
||||||
|
public typealias RawValue = String
|
||||||
|
|
||||||
|
public var rawValue: RawValue {
|
||||||
|
switch self {
|
||||||
|
case .left:
|
||||||
|
return "left"
|
||||||
|
case .right:
|
||||||
|
return "right"
|
||||||
|
case .bottom:
|
||||||
|
return "bottom"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Random Dock Side
|
||||||
|
/// - will return a random Dock Side when calling DockSide()
|
||||||
|
public init() {
|
||||||
|
self = DockSide(rawValue: Int.random(in: 1...3))!
|
||||||
|
}
|
||||||
|
|
||||||
|
public init?(rawValue: String) {
|
||||||
|
switch rawValue {
|
||||||
|
case "left":
|
||||||
|
self = .left
|
||||||
|
case "right":
|
||||||
|
self = .right
|
||||||
|
case "bottom":
|
||||||
|
self = .bottom
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public init?(rawValue: Int) {
|
||||||
|
switch rawValue {
|
||||||
|
case 1:
|
||||||
|
self = .left
|
||||||
|
case 2:
|
||||||
|
self = .bottom
|
||||||
|
case 3:
|
||||||
|
self = .right
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,75 +7,25 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import AppKit
|
import AppKit
|
||||||
|
import Cocoa
|
||||||
|
import ApplicationServices
|
||||||
|
|
||||||
struct Screen {
|
struct Screen {
|
||||||
var width: CGFloat
|
var width: CGFloat
|
||||||
var height: CGFloat
|
var height: CGFloat
|
||||||
}
|
}
|
||||||
|
|
||||||
enum DockSide: Int, RawRepresentable {
|
|
||||||
case left
|
|
||||||
case bottom
|
|
||||||
case right
|
|
||||||
|
|
||||||
public typealias RawValue = String
|
|
||||||
|
|
||||||
public var rawValue: RawValue {
|
|
||||||
switch self {
|
|
||||||
case .left:
|
|
||||||
return "left"
|
|
||||||
case .right:
|
|
||||||
return "right"
|
|
||||||
case .bottom:
|
|
||||||
return "bottom"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Random Dock Side
|
|
||||||
/// - will return a random Dock Side when calling DockSide()
|
|
||||||
public init() {
|
|
||||||
self = DockSide(rawValue: Int.random(in: 1...3))!
|
|
||||||
}
|
|
||||||
|
|
||||||
public init?(rawValue: String) {
|
|
||||||
switch rawValue {
|
|
||||||
case "left":
|
|
||||||
self = .left
|
|
||||||
case "right":
|
|
||||||
self = .right
|
|
||||||
case "bottom":
|
|
||||||
self = .bottom
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public init?(rawValue: Int) {
|
|
||||||
switch rawValue {
|
|
||||||
case 1:
|
|
||||||
self = .left
|
|
||||||
case 2:
|
|
||||||
self = .bottom
|
|
||||||
case 3:
|
|
||||||
self = .right
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class MouseTracker {
|
class MouseTracker {
|
||||||
var screen: Screen
|
var screen: Screen
|
||||||
|
|
||||||
var monitor: Any?
|
var monitor: Any?
|
||||||
|
|
||||||
var running: Bool = false
|
var running: Bool = false
|
||||||
|
|
||||||
var currentDockSide: DockSide
|
var currentDockSide: DockSide
|
||||||
|
|
||||||
var dockHeight: CGFloat = 0
|
var dockHeight: CGFloat = 0
|
||||||
|
|
||||||
init() {
|
var settings: DPSettingsModel
|
||||||
|
var skyHigh = SkyHigh()
|
||||||
|
|
||||||
|
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,52 +37,95 @@ 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 {
|
||||||
moveDock(.bottom)
|
moveDockOrMouse(.bottom)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
moveDock(.right)
|
moveDockOrMouse(.right)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
case .bottom:
|
case .bottom:
|
||||||
guard location.y > screen.height - dockHeight else { return }
|
guard location.y > screen.height - dockHeight else { return }
|
||||||
if location.x < screen.width/2 {
|
if location.x < screen.width/2 {
|
||||||
moveDock(.right)
|
moveDockOrMouse(.right)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
moveDock(.left)
|
moveDockOrMouse(.left)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
case .right:
|
case .right:
|
||||||
guard location.x > screen.width - dockHeight else { return }
|
guard location.x > screen.width - dockHeight else { return }
|
||||||
if location.y < screen.height/2 {
|
if location.y < screen.height/2 {
|
||||||
moveDock(.bottom)
|
moveDockOrMouse(.bottom)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
moveDock(.left)
|
moveDockOrMouse(.left)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func moveDockOrMouse(_ dockTo: DockSide) {
|
||||||
|
if settings.settings.moveMouseInstead {
|
||||||
|
moveMouse()
|
||||||
|
} else {
|
||||||
|
moveDock(dockTo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func start() {
|
func start() {
|
||||||
self.monitor = NSEvent.addGlobalMonitorForEvents(matching: .mouseMoved, handler: checkMouse)
|
self.monitor = NSEvent.addGlobalMonitorForEvents(matching: .mouseMoved, handler: checkMouse)
|
||||||
self.running = true
|
self.running = true
|
||||||
print("started tracking")
|
print("started tracking")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
skyHigh.move()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func stop() {
|
func stop() {
|
||||||
@@ -144,6 +137,14 @@ class MouseTracker {
|
|||||||
print("stop tracking")
|
print("stop tracking")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func moveMouse() {
|
||||||
|
let rangeW = screen.width*0.1...screen.width*0.9
|
||||||
|
let posX = CGFloat.random(in: rangeW)
|
||||||
|
let rangeH = screen.height*0.1...screen.height*0.9
|
||||||
|
let posY = CGFloat.random(in: rangeH)
|
||||||
|
CGDisplayMoveCursorToPoint(0, CGPoint(x: posX, y: posY))
|
||||||
|
}
|
||||||
|
|
||||||
func moveDock(_ toSide: DockSide) {
|
func moveDock(_ toSide: DockSide) {
|
||||||
guard currentDockSide != toSide else { return }
|
guard currentDockSide != toSide else { return }
|
||||||
// let scriptHide = """
|
// let scriptHide = """
|
||||||
@@ -167,6 +168,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 +190,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
|
||||||
|
}
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 560 KiB After Width: | Height: | Size: 560 KiB |
52
DockPhobia/SkyHigh.swift
Normal file
52
DockPhobia/SkyHigh.swift
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
//
|
||||||
|
// SkyHigh.swift
|
||||||
|
// DockPhobia
|
||||||
|
//
|
||||||
|
// Created by neon443 on 28/05/2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Cocoa
|
||||||
|
|
||||||
|
class SkyHigh {
|
||||||
|
private var window: NSWindow
|
||||||
|
private var x = 1
|
||||||
|
private var timer: Timer?
|
||||||
|
|
||||||
|
init() {
|
||||||
|
guard let screen = NSScreen.main?.frame else { fatalError() }
|
||||||
|
self.window = NSWindow(
|
||||||
|
contentRect: CGRect(
|
||||||
|
x: screen.width*0.05,
|
||||||
|
y: screen.height*0.1,
|
||||||
|
width: screen.width*0.9,
|
||||||
|
height: screen.height*0.8
|
||||||
|
),
|
||||||
|
styleMask: .borderless,
|
||||||
|
backing: .buffered,
|
||||||
|
defer: false
|
||||||
|
)
|
||||||
|
window.backgroundColor = .init(srgbRed: 1, green: 1, blue: 1, alpha: 0.1)
|
||||||
|
window.isOpaque = false
|
||||||
|
window.level = NSWindow.Level.statusBar + 1
|
||||||
|
window.ignoresMouseEvents = true
|
||||||
|
window.hasShadow = true
|
||||||
|
window.makeKeyAndOrderFront(nil)
|
||||||
|
window.setFrameOrigin(NSPoint(x: screen.width*0.05, y: screen.height*0.1))
|
||||||
|
}
|
||||||
|
|
||||||
|
func move() {
|
||||||
|
x = 1
|
||||||
|
timer?.invalidate()
|
||||||
|
timer = Timer(timeInterval: 0.01, repeats: true) { [weak self] _ in
|
||||||
|
guard let self = self else { return }
|
||||||
|
guard x < 1001 else {
|
||||||
|
timer?.invalidate()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.window.setFrameOrigin(NSPoint(x: 1000-self.x, y: 1000-self.x))
|
||||||
|
self.x += 1
|
||||||
|
}
|
||||||
|
RunLoop.current.add(timer!, forMode: .common)
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
DockPhobiaPy/.DS_Store
vendored
BIN
DockPhobiaPy/.DS_Store
vendored
Binary file not shown.
36
README.md
36
README.md
@@ -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)"
|
||||||
|
|||||||
Reference in New Issue
Block a user