Skip to content

Commit

Permalink
Merge pull request #250 from wakatime/feature/canva
Browse files Browse the repository at this point in the history
Support tracking Canva
  • Loading branch information
alanhamlett authored Mar 27, 2024
2 parents 7e7879d + 0f1cef6 commit 3ec4aa2
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 6 deletions.
37 changes: 37 additions & 0 deletions WakaTime/Extensions/AXUIElementExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,43 @@ extension AXUIElement {
}
}

func elementAtPosition(x: Float, y: Float) -> AXUIElement? {
var element: AXUIElement?
AXUIElementCopyElementAtPosition(self, x, y, &element)
return element
}

func elementAtPositionRelativeToWindow(x: CGFloat, y: CGFloat) -> AXUIElement? {
// swiftlint:disable force_unwrapping
let windowPositionData = getValue(for: kAXPositionAttribute)!
let windowSizeData = getValue(for: kAXSizeAttribute)!
// swiftlint:enable force_unwrapping

var windowPosition = CGPoint()
var windowSize = CGSize()

// swiftlint:disable force_cast
if !AXValueGetValue(windowPositionData as! AXValue, .cgPoint, &windowPosition) ||
!AXValueGetValue(windowSizeData as! AXValue, .cgSize, &windowSize) {
return nil
}
// swiftlint:enable force_cast

let globalX = windowPosition.x + x
let globalY = windowPosition.y + y

if globalX < windowPosition.x || globalX > windowPosition.x + windowSize.width ||
globalY < windowPosition.y || globalY > windowPosition.y + windowSize.height {
// Point is outside the window bounds
return nil
}

var element: AXUIElement?
let systemWideElement = AXUIElementCreateSystemWide()
AXUIElementCopyElementAtPosition(systemWideElement, Float(globalX), Float(globalY), &element)
return element
}

func debugPrintSubtree(element: AXUIElement? = nil, depth: Int = 0, highlight indexPath: [Int] = [], currentPath: [Int] = []) {
let element = element ?? self
if let children = element.children {
Expand Down
16 changes: 10 additions & 6 deletions WakaTime/Watchers/MonitoredApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -235,12 +235,16 @@ enum MonitoredApp: String, CaseIterable {
case .brave:
fatalError("\(self.rawValue) should never use window title as entity")
case .canva:
guard
let title = element.extractPrefix(element.rawTitle, separator: " - ", minCount: 2),
title != "Canva",
title != "Home"
else { return nil }
return title
// Canva obviously implements tabs in a different way than the tab content UI.
// Due to this circumstance, it's possible to just sample an element from the
// Canva window which is positioned underneath the tab bar and trace to the
// web area root which appears to be properly titled. All the UI zoom settings
// in Canva only change the tab content or sub content of the tab content, hence
// this should be relatively safe. In cases where this fails, nil should be
// returned as a consequence of the web area not being found.
let someElem = element.elementAtPositionRelativeToWindow(x: 10, y: 60)
let webArea = someElem?.firstAncestorWhere { $0.role == "AXWebArea" }
return webArea?.rawTitle
case .chrome:
fatalError("\(self.rawValue) should never use window title as entity")
case .figma:
Expand Down

0 comments on commit 3ec4aa2

Please sign in to comment.