mirror of
https://github.com/neon443/DockPhobia.git
synced 2026-03-11 06:49:12 +00:00
Compare commits
3 Commits
3e7a7c2ac2
...
c099d4bec3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c099d4bec3 | ||
|
|
5718e42f41 | ||
|
|
936f18d714 |
@@ -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 */,
|
||||||
);
|
);
|
||||||
|
|||||||
BIN
DockPhobia/.DS_Store
vendored
BIN
DockPhobia/.DS_Store
vendored
Binary file not shown.
@@ -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(
|
||||||
@@ -73,7 +95,6 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
|||||||
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,17 +112,18 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
|||||||
mouseTracker.start()
|
mouseTracker.start()
|
||||||
changeMenuIcon(running: true)
|
changeMenuIcon(running: true)
|
||||||
}
|
}
|
||||||
setupMenus()
|
refreshMenus()
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func quit() {
|
@objc func quit() {
|
||||||
NSApplication.shared.terminate(self)
|
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"
|
||||||
@@ -111,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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
40
DockPhobia/DPSettings.swift
Normal file
40
DockPhobia/DPSettings.swift
Normal 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")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
|
|||||||
BIN
DockPhobiaPy/.DS_Store
vendored
BIN
DockPhobiaPy/.DS_Store
vendored
Binary file not shown.
Reference in New Issue
Block a user