mirror of
https://github.com/neon443/DockPhobia.git
synced 2026-03-11 06:49:12 +00:00
190 lines
3.5 KiB
Swift
190 lines
3.5 KiB
Swift
//
|
|
// MouseTracker.swift
|
|
// DockPhobia
|
|
//
|
|
// Created by neon443 on 23/05/2025.
|
|
//
|
|
|
|
import Foundation
|
|
import AppKit
|
|
|
|
struct Screen {
|
|
var width: 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 {
|
|
var screen: Screen
|
|
|
|
var monitor: Any?
|
|
|
|
var running: Bool = false
|
|
|
|
var currentDockSide: DockSide
|
|
|
|
var dockHeight: CGFloat = 0
|
|
|
|
init() {
|
|
print(DockSide())
|
|
if let screen = NSScreen.main {
|
|
let rect = screen.frame
|
|
self.screen = Screen(
|
|
width: rect.width,
|
|
height: rect.height
|
|
)
|
|
print(self.screen)
|
|
} else {
|
|
fatalError("no screen wtf???")
|
|
}
|
|
self.currentDockSide = .left
|
|
moveDock(.bottom)
|
|
getDockSize()
|
|
}
|
|
|
|
func checkMouse(_ event: NSEvent) {
|
|
var location = event.locationInWindow
|
|
location.y = screen.height - location.y
|
|
#if DEBUG
|
|
print(location)
|
|
#endif
|
|
switch currentDockSide {
|
|
case .left:
|
|
guard location.x < dockHeight else { return }
|
|
if location.y < screen.height/2 {
|
|
moveDock(.bottom)
|
|
return
|
|
} else {
|
|
moveDock(.right)
|
|
return
|
|
}
|
|
case .bottom:
|
|
guard location.y > screen.height - dockHeight else { return }
|
|
if location.x < screen.width/2 {
|
|
moveDock(.right)
|
|
return
|
|
} else {
|
|
moveDock(.left)
|
|
return
|
|
}
|
|
case .right:
|
|
guard location.x > screen.width - dockHeight else { return }
|
|
if location.y < screen.height/2 {
|
|
moveDock(.bottom)
|
|
return
|
|
} else {
|
|
moveDock(.left)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
func start() {
|
|
self.monitor = NSEvent.addGlobalMonitorForEvents(matching: .mouseMoved, handler: checkMouse)
|
|
self.running = true
|
|
print("started tracking")
|
|
}
|
|
|
|
func stop() {
|
|
if let monitor = monitor {
|
|
NSEvent.removeMonitor(monitor)
|
|
self.running = false
|
|
}
|
|
|
|
print("stop tracking")
|
|
}
|
|
|
|
func moveDock(_ toSide: DockSide) {
|
|
guard currentDockSide != toSide else { return }
|
|
// let scriptHide = """
|
|
// tell application "System Events"
|
|
// tell dock preferences
|
|
// set autohide to true
|
|
// end tell
|
|
// end tell
|
|
// """
|
|
//
|
|
// let scriptShow = scriptHide.replacingOccurrences(of: "true", with: "false")
|
|
|
|
let scriptMove = """
|
|
tell application "System Events"
|
|
tell dock preferences
|
|
set screen edge to \(toSide)
|
|
end tell
|
|
end tell
|
|
"""
|
|
// applescript(scriptHide)
|
|
applescript(scriptMove)
|
|
// applescript(scriptShow)
|
|
currentDockSide = toSide
|
|
}
|
|
|
|
func getDockSize() {
|
|
guard let screen = NSScreen.main?.frame else { fatalError() }
|
|
guard let screenVisible = NSScreen.main?.visibleFrame else { fatalError() }
|
|
self.dockHeight = screen.height - screenVisible.height
|
|
}
|
|
|
|
@discardableResult
|
|
func applescript(_ script: String) -> String? {
|
|
var error: NSDictionary?
|
|
if let scriptObject = NSAppleScript(source: script) {
|
|
scriptObject.executeAndReturnError(&error)
|
|
if (error != nil) {
|
|
print(error as Any)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
}
|