Skip to content

Commit

Permalink
Merge pull request #108 from wakatime/main
Browse files Browse the repository at this point in the history
Release v2.1.0
  • Loading branch information
alanhamlett authored Jun 17, 2023
2 parents d56bce1 + f111899 commit 314d8f4
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 24 deletions.
7 changes: 5 additions & 2 deletions .github/workflows/on_push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,11 @@ jobs:
uses: fjogeleit/yaml-update-action@main
with:
valueFile: 'project.yml'
propertyPath: 'targets.WakaTime.settings.MARKETING_VERSION'
value: ${{ needs.version.outputs.semver }}
changes: |
{
"targets.WakaTime.settings.CURRENT_PROJECT_VERSION": "${{ needs.version.outputs.semver }}",
"targets.WakaTime.settings.MARKETING_VERSION": "${{ needs.version.outputs.semver }}"
}
commitChange: false
-
name: Install xcodegen via Homebrew for linting and building xcode project
Expand Down
9 changes: 9 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,13 @@ Please follow our guideline for branch names [here](https://github.com/wakatime/

## Troubleshooting

If you have trouble building off `main` branch, try:

* close Xcode
* `rm -rf ~/Library/Developer/Xcode/DerivedData/WakaTime*`
* `rm -rf ./WakaTime.xcodeproj`
* `xcodegen`
* Open the project in Xcode
* Under `Signing & Capabilities`, set your `Team`

Any question join us on [Slack](https://wakaslack.herokuapp.com/).
10 changes: 8 additions & 2 deletions WakaTime/WakaTime.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class WakaTime {
// they are declared atomic here
@Atomic var lastFile = ""
@Atomic var lastTime = 0
@Atomic var lastIsBuilding = false

// MARK: Constants

Expand Down Expand Up @@ -45,9 +46,10 @@ class WakaTime {

// MARK: Watcher Event Handling

private func shouldSendHeartbeat(file: URL, time: Int, isWrite: Bool) -> Bool {
private func shouldSendHeartbeat(file: URL, time: Int, isWrite: Bool, isBuilding: Bool) -> Bool {
guard
!isWrite,
isBuilding == lastIsBuilding,
file.formatted() == lastFile,
lastTime + 120 > time
else { return true }
Expand All @@ -57,10 +59,11 @@ class WakaTime {

public func handleEvent(app: NSRunningApplication, file: URL, isWrite: Bool, isBuilding: Bool) {
let time = Int(NSDate().timeIntervalSince1970)
guard shouldSendHeartbeat(file: file, time: time, isWrite: isWrite) else { return }
guard shouldSendHeartbeat(file: file, time: time, isWrite: isWrite, isBuilding: isBuilding) else { return }

lastFile = file.formatted()
lastTime = time
lastIsBuilding = isBuilding

guard
let id = app.bundleIdentifier,
Expand All @@ -86,6 +89,9 @@ class WakaTime {
args.append("--category")
args.append("building")
}

NSLog("Sending heartbeat with: \(args)")

process.arguments = args
process.standardOutput = FileHandle.nullDevice
process.standardError = FileHandle.nullDevice
Expand Down
53 changes: 35 additions & 18 deletions WakaTime/Watcher.swift
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//import EonilFSEvents
import Foundation
import AppKit

Expand Down Expand Up @@ -34,10 +35,25 @@ class Watcher: NSObject {
matching: [NSEvent.EventTypeMask.keyDown],
handler: handleKeyboardEvent
)

/*
do {
try EonilFSEvents.startWatching(
paths: ["/"],
for: ObjectIdentifier(self),
with: { event in
// print(event)
}
)
} catch {
NSLog("Failed to setup FSEvents: \(error.localizedDescription)")
}
*/
}

deinit {
NSWorkspace.shared.notificationCenter.removeObserver(self) // needed prior macOS 11 only
//EonilFSEvents.stopWatching(for: ObjectIdentifier(self))
}

@objc private func appChanged(_ notification: Notification) {
Expand All @@ -61,7 +77,7 @@ class Watcher: NSObject {
}

func handleKeyboardEvent(event: NSEvent!) {
print("keyDown")
// NSLog("keyDown")
// TODO: call eventHandler to send heartbeat
}

Expand Down Expand Up @@ -100,7 +116,7 @@ class Watcher: NSObject {
self.documentPath = currentPath
}
observeActivityText(activeWindow: activeWindow)
NSLog("Watching for file changes on \(app.localizedName ?? "nil")")
// NSLog("Watching for file changes on \(app.localizedName ?? "nil")")
} catch {
NSLog("Failed to setup AXObserver: \(error.localizedDescription)")
}
Expand All @@ -116,7 +132,7 @@ class Watcher: NSObject {
try? observer.remove(notification: kAXValueChangedNotification, element: observingElement)
self.observingElement = nil
self.observer = nil
NSLog("Stopped watching \(app.localizedName ?? "nil")")
// NSLog("Stopped watching \(app.localizedName ?? "nil")")
}
}

Expand All @@ -136,6 +152,9 @@ class Watcher: NSObject {
// Update the current isBuilding state when the observed "Activity Text" UI element changes
let value = element.getValue(for: kAXValueAttribute) as? String
self.isBuilding = checkIsBuilding(activityText: value)
if let path = self.documentPath {
self.handleNotificationEvent(path: path, isWrite: false)
}
} catch {
observingActivityTextElement = nil
}
Expand All @@ -154,21 +173,22 @@ class Watcher: NSObject {
if documentPath != oldValue {
guard let newPath = documentPath else { return }

NSLog("Document changed: \(newPath)")

handleNotificationEvent(path: newPath, isWrite: false)
fileMonitor = nil
fileMonitor = FileMonitor(filePath: newPath, queue: monitorQueue)
fileMonitor?.eventHandler = { [weak self] in
fileMonitor?.fileChangedEventHandler = { [weak self] in
self?.handleNotificationEvent(path: newPath, isWrite: true)
}
}
}
}

private func handleNotificationEvent(path: URL, isWrite: Bool) {
public func handleNotificationEvent(path: URL, isWrite: Bool) {
callbackQueue.async {
guard let app = self.activeApp else { return }

NSLog("Document changed: \(path.formatted()) isWrite: \(isWrite) isBuilding: \(self.isBuilding)")
self.eventHandler?(app, path, isWrite, self.isBuilding)
}
}
Expand All @@ -194,20 +214,19 @@ private func observerCallback(
!element.selectedText.isEmpty
else { return }
this.eventHandler?(app, currentPath, false, this.isBuilding)
// print("Selected text changed: \(element.selectedText)")
case .focusedUIElementChanged:
guard let currentPath = getCurrentPath(element: element, refcon: refcon) else { return }
this.documentPath = currentPath
print("Document path changed:", currentPath)
case .focusedWindowChanged:
this.observeActivityText(activeWindow: element)
print("Window changed")
case .valueChanged:
let id = element.getValue(for: kAXIdentifierAttribute) as? String
let value = element.getValue(for: kAXValueAttribute) as? String
if let id, id == "Activity Text" {
this.isBuilding = this.checkIsBuilding(activityText: value)
print("Activity Text value changed:", value ?? "<<nil>>")
if let path = this.documentPath {
this.handleNotificationEvent(path: path, isWrite: false)
}
}
default:
break
Expand Down Expand Up @@ -252,7 +271,7 @@ extension AXObserver {
throw AXObserverError.addNotificationFailed(error)
}

NSLog("Added notification \(notification) to observer \(self)")
// NSLog("Added notification \(notification) to observer \(self)")
}

func remove(notification: String, element: AXUIElement) throws {
Expand All @@ -262,17 +281,17 @@ extension AXObserver {
throw AXObserverError.removeNotificationFailed(error)
}

NSLog("Removed notification \(notification) from observer \(self)")
// NSLog("Removed notification \(notification) from observer \(self)")
}

func addToRunLoop(mode: CFRunLoopMode = .defaultMode) {
CFRunLoopAddSource(RunLoop.current.getCFRunLoop(), AXObserverGetRunLoopSource(self), mode)
NSLog("Added observer \(self) to run loop")
// NSLog("Added observer \(self) to run loop")
}

func removeFromRunLoop(mode: CFRunLoopMode = .defaultMode) {
CFRunLoopRemoveSource(RunLoop.current.getCFRunLoop(), AXObserverGetRunLoopSource(self), mode)
NSLog("Removed observer \(self) from run loop")
// NSLog("Removed observer \(self) from run loop")
}
}

Expand Down Expand Up @@ -320,7 +339,7 @@ class FileMonitor {
private let fileURL: URL
private var dispatchObject: DispatchSourceFileSystemObject?

public var eventHandler: (() -> Void)?
public var fileChangedEventHandler: (() -> Void)?

init?(filePath: URL, queue: DispatchQueue) {
self.fileURL = filePath
Expand All @@ -329,18 +348,16 @@ class FileMonitor {
guard descriptor >= -1 else { NSLog("open failed: \(descriptor)"); return nil }
dispatchObject = DispatchSource.makeFileSystemObjectSource(fileDescriptor: descriptor, eventMask: .write, queue: queue)
dispatchObject?.setEventHandler { [weak self] in
self?.eventHandler?()
self?.fileChangedEventHandler?()
}
dispatchObject?.setCancelHandler {
close(descriptor)
}
dispatchObject?.activate()
NSLog("Created FileMonitor for \(fileURL.formatted())")
}

deinit {
dispatchObject?.cancel()
NSLog("Deleted FileMonitor for \(fileURL.formatted())")
}
}

Expand Down
4 changes: 2 additions & 2 deletions project.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ targets:
deploymentTarget: 10.15
sources: [WakaTime]
settings:
CURRENT_PROJECT_VERSION: 2
CURRENT_PROJECT_VERSION: 0.0.1
MARKETING_VERSION: 0.0.1
INFOPLIST_FILE: WakaTime/WakaTime-Info.plist
GENERATE_INFOPLIST_FILE: YES
Expand Down Expand Up @@ -44,7 +44,7 @@ targets:
deploymentTarget: 10.15
sources: [WakaTime Helper]
settings:
CURRENT_PROJECT_VERSION: 1
CURRENT_PROJECT_VERSION: 0.0.1
MARKETING_VERSION: 0.0.1
INFOPLIST_FILE: WakaTime Helper/WakaTime Helper-Info.plist
GENERATE_INFOPLIST_FILE: YES
Expand Down

0 comments on commit 314d8f4

Please sign in to comment.