mirror of
https://github.com/neon443/DockPhobia.git
synced 2026-03-11 14:56:16 +00:00
Compare commits
9 Commits
1.0.1
...
853fc2a2db
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
853fc2a2db | ||
|
|
6a68713ad5 | ||
|
|
b15116b292 | ||
|
|
e4c41c4a58 | ||
|
|
c099d4bec3 | ||
|
|
5718e42f41 | ||
|
|
936f18d714 | ||
|
|
3e7a7c2ac2 | ||
|
|
43863d3827 |
@@ -6,7 +6,7 @@
|
||||
//
|
||||
|
||||
VERSION = 1.0.1
|
||||
BUILD_ID = 1
|
||||
BUILD_ID = 2
|
||||
TEAM_ID = 8JGND254B7
|
||||
BUNDLE_ID = com.neon443.DockPhobia
|
||||
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
A966B4F42DE0842500C721A5 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A966B4EE2DE0842400C721A5 /* AppDelegate.swift */; };
|
||||
A966B4F52DE0842500C721A5 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A966B4EF2DE0842400C721A5 /* Assets.xcassets */; };
|
||||
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 */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
@@ -21,6 +24,9 @@
|
||||
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>"; };
|
||||
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 */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -72,6 +78,9 @@
|
||||
children = (
|
||||
A966B4EE2DE0842400C721A5 /* AppDelegate.swift */,
|
||||
A966B4F72DE0852900C721A5 /* MouseTracker.swift */,
|
||||
A9C9AF822DE77CB70039D7A5 /* SkyHigh.swift */,
|
||||
A98C20C52DE614180008D61C /* DPSettings.swift */,
|
||||
A9C9AF802DE777530039D7A5 /* DockSide.swift */,
|
||||
A94BEC102DE23ECE00D4811D /* Views */,
|
||||
A94BEC0A2DE21F8100D4811D /* Resources */,
|
||||
A966B4F02DE0842400C721A5 /* DockPhobia.entitlements */,
|
||||
@@ -152,8 +161,11 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
A98C20C62DE614180008D61C /* DPSettings.swift in Sources */,
|
||||
A9C9AF832DE77CB70039D7A5 /* SkyHigh.swift in Sources */,
|
||||
A966B4F82DE0852900C721A5 /* MouseTracker.swift in Sources */,
|
||||
A966B4F42DE0842500C721A5 /* AppDelegate.swift in Sources */,
|
||||
A9C9AF812DE7776A0039D7A5 /* DockSide.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -294,6 +306,7 @@
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = NO;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.entertainment";
|
||||
INFOPLIST_KEY_LSUIElement = YES;
|
||||
INFOPLIST_KEY_NSAppleEventsUsageDescription = _;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
@@ -328,6 +341,7 @@
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = NO;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.entertainment";
|
||||
INFOPLIST_KEY_LSUIElement = YES;
|
||||
INFOPLIST_KEY_NSAppleEventsUsageDescription = _;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
|
||||
BIN
DockPhobia/.DS_Store
vendored
BIN
DockPhobia/.DS_Store
vendored
Binary file not shown.
@@ -7,30 +7,36 @@
|
||||
|
||||
import AppKit
|
||||
|
||||
@main
|
||||
@NSApplicationMain
|
||||
class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
|
||||
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) {
|
||||
statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
|
||||
if let button = statusItem.button {
|
||||
button.image = NSImage(named: "cursor.slash")
|
||||
}
|
||||
setupMenus()
|
||||
refreshMenus()
|
||||
}
|
||||
|
||||
func applicationWillTerminate(_ aNotification: Notification) {
|
||||
// Insert code here to tear down your application
|
||||
settings.saveSettings()
|
||||
}
|
||||
|
||||
func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
//MARK: menu bar stuff
|
||||
func setupMenus() {
|
||||
let menu = NSMenu()
|
||||
let start = NSMenuItem(title: describeStartButton(), action: #selector(didTapStart), keyEquivalent: "")
|
||||
@@ -43,37 +49,51 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
)
|
||||
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(
|
||||
let moveMouseButton = 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",
|
||||
action: #selector(moveDockObjcLeft),
|
||||
keyEquivalent: ""
|
||||
)
|
||||
)
|
||||
menu.addItem(
|
||||
NSMenuItem(
|
||||
keyEquivalent: ""))
|
||||
menu.addItem(NSMenuItem(
|
||||
title: "Move Dock to bottom",
|
||||
action: #selector(moveDockObjcBottom),
|
||||
keyEquivalent: ""
|
||||
)
|
||||
)
|
||||
menu.addItem(
|
||||
NSMenuItem(
|
||||
title: "Move Dock to right",
|
||||
action: #selector(moveDockObjcRight),
|
||||
keyEquivalent: ""
|
||||
)
|
||||
)
|
||||
|
||||
keyEquivalent: ""))
|
||||
menu.addItem(NSMenuItem(
|
||||
title: "Move Dock to right",
|
||||
action: #selector(moveDockObjcRight),
|
||||
keyEquivalent: ""))
|
||||
menu.addItem(NSMenuItem.separator())
|
||||
|
||||
let quit = NSMenuItem(title: "Quit", action: #selector(quit), keyEquivalent: "q")
|
||||
menu.addItem(quit)
|
||||
statusItem.menu = menu
|
||||
}
|
||||
|
||||
func changeMenuIcon(running: Bool) {
|
||||
guard let button = statusItem.button else { return }
|
||||
switch running {
|
||||
@@ -83,7 +103,6 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
button.image = NSImage(named: "cursor.slash")
|
||||
}
|
||||
}
|
||||
|
||||
@objc func didTapStart() {
|
||||
if mouseTracker.running {
|
||||
mouseTracker.stop()
|
||||
@@ -92,17 +111,22 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
mouseTracker.start()
|
||||
changeMenuIcon(running: true)
|
||||
}
|
||||
setupMenus()
|
||||
refreshMenus()
|
||||
}
|
||||
|
||||
@objc func quit() {
|
||||
NSApplication.shared.terminate(self)
|
||||
}
|
||||
|
||||
@objc func moveDockObjcLeft() { mouseTracker.moveDock(.left) }
|
||||
@objc func moveDockObjcRight() { mouseTracker.moveDock(.right) }
|
||||
@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 {
|
||||
if mouseTracker.running {
|
||||
return "Stop tracking"
|
||||
@@ -111,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 AppKit
|
||||
import Cocoa
|
||||
import ApplicationServices
|
||||
|
||||
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() {
|
||||
var settings: DPSettingsModel
|
||||
var skyHigh = SkyHigh()
|
||||
|
||||
init(settings: DPSettingsModel) {
|
||||
print(DockSide())
|
||||
if let screen = NSScreen.main {
|
||||
let rect = screen.frame
|
||||
@@ -87,52 +37,95 @@ class MouseTracker {
|
||||
} else {
|
||||
fatalError("no screen wtf???")
|
||||
}
|
||||
|
||||
self.settings = settings
|
||||
|
||||
self.currentDockSide = .left
|
||||
moveDock(.bottom)
|
||||
getDockSize()
|
||||
}
|
||||
|
||||
func checkMouse(_ event: NSEvent) {
|
||||
var location = event.locationInWindow
|
||||
var location = NSEvent.mouseLocation
|
||||
location.y = screen.height - location.y
|
||||
#if DEBUG
|
||||
print(location)
|
||||
#endif
|
||||
switch currentDockSide {
|
||||
|
||||
guard settings.settings.checkFullscreen else {
|
||||
handleDockValue(dockIsAt: currentDockSide, location: location)
|
||||
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:
|
||||
guard location.x < dockHeight else { return }
|
||||
if location.y < screen.height/2 {
|
||||
moveDock(.bottom)
|
||||
moveDockOrMouse(.bottom)
|
||||
return
|
||||
} else {
|
||||
moveDock(.right)
|
||||
moveDockOrMouse(.right)
|
||||
return
|
||||
}
|
||||
case .bottom:
|
||||
guard location.y > screen.height - dockHeight else { return }
|
||||
if location.x < screen.width/2 {
|
||||
moveDock(.right)
|
||||
moveDockOrMouse(.right)
|
||||
return
|
||||
} else {
|
||||
moveDock(.left)
|
||||
moveDockOrMouse(.left)
|
||||
return
|
||||
}
|
||||
case .right:
|
||||
guard location.x > screen.width - dockHeight else { return }
|
||||
if location.y < screen.height/2 {
|
||||
moveDock(.bottom)
|
||||
moveDockOrMouse(.bottom)
|
||||
return
|
||||
} else {
|
||||
moveDock(.left)
|
||||
moveDockOrMouse(.left)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func moveDockOrMouse(_ dockTo: DockSide) {
|
||||
if settings.settings.moveMouseInstead {
|
||||
moveMouse()
|
||||
} else {
|
||||
moveDock(dockTo)
|
||||
}
|
||||
}
|
||||
|
||||
func start() {
|
||||
self.monitor = NSEvent.addGlobalMonitorForEvents(matching: .mouseMoved, handler: checkMouse)
|
||||
self.running = true
|
||||
print("started tracking")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
skyHigh.move()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
func stop() {
|
||||
@@ -144,6 +137,14 @@ class MouseTracker {
|
||||
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) {
|
||||
guard currentDockSide != toSide else { return }
|
||||
// let scriptHide = """
|
||||
@@ -167,6 +168,8 @@ class MouseTracker {
|
||||
applescript(scriptMove)
|
||||
// applescript(scriptShow)
|
||||
currentDockSide = toSide
|
||||
settings.settings.dockMoves += 1
|
||||
refreshMenus()
|
||||
}
|
||||
|
||||
func getDockSize() {
|
||||
@@ -187,3 +190,27 @@ class MouseTracker {
|
||||
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
|
||||
}
|
||||
|
||||
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.
Reference in New Issue
Block a user