]> git.r.bdr.sh - rbdr/captura/blobdiff - Captura/Presentation/Windows/RecordingWindow.swift
Add sparkle
[rbdr/captura] / Captura / Presentation / Windows / RecordingWindow.swift
index f5941dc82bdbde22970439157d5088a2572eef23..7a64576acd161a97cfafbda235c0466c6edd073f 100644 (file)
@@ -13,11 +13,7 @@ class RecordingWindow: NSWindow {
   
   init(_ configuration: CaptureSessionConfiguration, _ button: NSRect?) {
     
   
   init(_ configuration: CaptureSessionConfiguration, _ button: NSRect?) {
     
-    let screens = NSScreen.screens
-    var boundingBox = NSZeroRect
-    for screen in screens {
-        boundingBox = NSUnionRect(boundingBox, screen.frame)
-    }
+    let boundingBox = NSScreen.screenWithMouse?.frame ?? NSZeroRect
     
     super.init(
       contentRect: boundingBox,
     
     super.init(
       contentRect: boundingBox,
@@ -25,6 +21,7 @@ class RecordingWindow: NSWindow {
       backing: .buffered,
       defer: false)
 
       backing: .buffered,
       defer: false)
 
+
     self.isReleasedWhenClosed = false
     self.collectionBehavior = [.canJoinAllSpaces]
     self.isMovableByWindowBackground = false
     self.isReleasedWhenClosed = false
     self.collectionBehavior = [.canJoinAllSpaces]
     self.isMovableByWindowBackground = false
@@ -33,11 +30,12 @@ class RecordingWindow: NSWindow {
     self.titlebarAppearsTransparent = true
     self.setFrame(boundingBox, display: true)
     self.titleVisibility = .hidden
     self.titlebarAppearsTransparent = true
     self.setFrame(boundingBox, display: true)
     self.titleVisibility = .hidden
-    let recordingView = RecordingContentView(configuration, frame: boundingBox)
+    let recordingView = RecordingContentView(configuration, frame: boundingBox, button: button ?? NSZeroRect)
     recordingView.frame = boundingBox
     recordingView.frame = boundingBox
-    recordingView.button = button
     self.contentView = recordingView
     self.backgroundColor = NSColor(white: 1.0, alpha: 0.001)
     self.contentView = recordingView
     self.backgroundColor = NSColor(white: 1.0, alpha: 0.001)
+    // uncomment below to debug window placement visually
+    // self.backgroundColor = NSColor(red: 1.0, green: 0.0, blue: 1.0, alpha: 0.5)
     self.level = .screenSaver
     self.isOpaque = false
     self.hasShadow = false
     self.level = .screenSaver
     self.isOpaque = false
     self.hasShadow = false
@@ -80,12 +78,25 @@ enum RecordingWindowState {
 
 class RecordingContentView: NSView {
   
 
 class RecordingContentView: NSView {
   
-  init(_ configuration: CaptureSessionConfiguration, frame: NSRect) {
+  init(_ configuration: CaptureSessionConfiguration, frame: NSRect, button: NSRect) {
+    self.buttonSize = button.size
+    var buttonOffset = NSPoint()
+    for screen in NSScreen.screens {
+      if screen.frame.intersects(button) {
+        let relativeY = screen.frame.height - (button.minY - screen.frame.minY)
+        let relativeX = screen.frame.width - (button.minX - screen.frame.minX)
+        buttonOffset = NSPoint(x: relativeX, y: relativeY)
+      }
+    }
+    self.buttonOffset = buttonOffset
     super.init(frame: frame)
     preventResize = configuration.preventResize
     preventMove = configuration.preventMove
     autoStart = configuration.autoStart
     
     super.init(frame: frame)
     preventResize = configuration.preventResize
     preventMove = configuration.preventMove
     autoStart = configuration.autoStart
     
+    self.bounds = frame
+    self.button = NSRect(x: frame.maxX - buttonOffset.x, y: frame.maxY - buttonOffset.y, width: buttonSize.width, height: buttonSize.height)
+    
     if configuration.x != nil || configuration.y != nil || configuration.width != nil || configuration.height != nil {
       box = NSRect(
         x: configuration.x ?? Int(frame.width / 2.0),
     if configuration.x != nil || configuration.y != nil || configuration.width != nil || configuration.height != nil {
       box = NSRect(
         x: configuration.x ?? Int(frame.width / 2.0),
@@ -106,6 +117,8 @@ class RecordingContentView: NSView {
     fatalError("init(coder:) has not been implemented")
   }
   
     fatalError("init(coder:) has not been implemented")
   }
   
+  private let buttonSize: NSSize
+  private let buttonOffset: NSPoint
   public var button: NSRect? = nil
   @Published public var box: NSRect? = nil
   public var state: RecordingWindowState = .idle
   public var button: NSRect? = nil
   @Published public var box: NSRect? = nil
   public var state: RecordingWindowState = .idle
@@ -167,6 +180,12 @@ class RecordingContentView: NSView {
     self.addTrackingArea(trackingArea)
   }
   
     self.addTrackingArea(trackingArea)
   }
   
+  override func mouseExited(with event: NSEvent) {
+    if state == .idle && box == nil {
+      self.moveWindow()
+    }
+  }
+  
   override func mouseMoved(with event: NSEvent) {
     
     self.mouseLocation = self.convert(event.locationInWindow, from: nil)
   override func mouseMoved(with event: NSEvent) {
     
     self.mouseLocation = self.convert(event.locationInWindow, from: nil)
@@ -306,6 +325,18 @@ class RecordingContentView: NSView {
     let dashLength: CGFloat = 5.0
     let lineWidth = 0.5
 
     let dashLength: CGFloat = 5.0
     let lineWidth = 0.5
 
+// Uncomment below to debug button placement visually
+//    if let button {
+//      let buttonPath = NSBezierPath()
+//      buttonPath.move(to: NSPoint(x: button.minX, y: button.minY))
+//      buttonPath.line(to: NSPoint(x: button.maxX, y: button.minY))
+//      buttonPath.line(to: NSPoint(x: button.maxX, y: button.maxY))
+//      buttonPath.line(to: NSPoint(x: button.minX, y: button.maxY))
+//      buttonPath.line(to: NSPoint(x: button.minX, y: button.minY))
+//      NSColor(red: 1, green: 0, blue: 1, alpha: 1).setFill()
+//      buttonPath.fill()
+//    }
+
     if state == .idle && box == nil {
       let blackLine = NSBezierPath()
       blackLine.lineWidth = lineWidth
     if state == .idle && box == nil {
       let blackLine = NSBezierPath()
       blackLine.lineWidth = lineWidth
@@ -424,4 +455,24 @@ class RecordingContentView: NSView {
 
     text.draw(in: textRect, withAttributes: textAttributes)
   }
 
     text.draw(in: textRect, withAttributes: textAttributes)
   }
+  
+  private func moveWindow() {
+    let screen = NSScreen.screenWithMouse
+    if let currentScreen = self.window?.screen {
+      if currentScreen != screen {
+        let frame = screen?.frame ?? NSZeroRect
+        self.frame = CGRect(origin: NSZeroPoint, size: frame.size)
+        self.bounds = CGRect(origin: NSZeroPoint, size: frame.size)
+        self.updateTrackingAreas()
+        
+        if let window = self.window {
+          self.bounds = frame
+          self.button = NSRect(x: frame.maxX - buttonOffset.x, y: frame.maxY - buttonOffset.y, width: buttonSize.width, height: buttonSize.height)
+          window.setFrame(frame, display: true, animate: false)
+          window.makeKeyAndOrderFront(nil)
+          window.orderFrontRegardless()
+        }
+      }
+    }
+  }
 }
 }