Skip to content

Commit

Permalink
add mouse-highlight, improve status bar view, fix some crash
Browse files Browse the repository at this point in the history
  • Loading branch information
lihaoyun6 committed Apr 22, 2024
1 parent f74d43f commit 28f51c7
Show file tree
Hide file tree
Showing 19 changed files with 514 additions and 487 deletions.
12 changes: 8 additions & 4 deletions QuickRecorder.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

/* Begin PBXBuildFile section */
1862BF8D2BD5494E003ED522 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 1862BF8F2BD5494E003ED522 /* Credits.rtf */; };
187966FA2BD5639D003DB1B2 /* MousePointer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 187966F92BD5639D003DB1B2 /* MousePointer.swift */; };
18D3BDEB2BCE5DC1006CFFC0 /* QuickRecorderApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18D3BDEA2BCE5DC1006CFFC0 /* QuickRecorderApp.swift */; };
18D3BDED2BCE5DC1006CFFC0 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18D3BDEC2BCE5DC1006CFFC0 /* ContentView.swift */; };
18D3BDEF2BCE5DC2006CFFC0 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 18D3BDEE2BCE5DC2006CFFC0 /* Assets.xcassets */; };
Expand All @@ -26,6 +27,7 @@
/* Begin PBXFileReference section */
1862BF902BD5494F003ED522 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = "zh-Hans"; path = "zh-Hans.lproj/Credits.rtf"; sourceTree = "<group>"; };
1862BF912BD5495D003ED522 /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = Base; path = Base.lproj/Credits.rtf; sourceTree = "<group>"; };
187966F92BD5639D003DB1B2 /* MousePointer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MousePointer.swift; sourceTree = "<group>"; };
18D3BDE72BCE5DC1006CFFC0 /* QuickRecorder.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = QuickRecorder.app; sourceTree = BUILT_PRODUCTS_DIR; };
18D3BDEA2BCE5DC1006CFFC0 /* QuickRecorderApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickRecorderApp.swift; sourceTree = "<group>"; };
18D3BDEC2BCE5DC1006CFFC0 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -104,6 +106,7 @@
18FEBDAB2BD01E82003F09BC /* WinSelector.swift */,
18FEBDAD2BD10ED1003F09BC /* ScreenSelector.swift */,
18F1A0E12BD3E4C000DB102C /* AreaSelector.swift */,
187966F92BD5639D003DB1B2 /* MousePointer.swift */,
);
path = ViewModel;
sourceTree = "<group>";
Expand Down Expand Up @@ -183,6 +186,7 @@
files = (
18FEBDAE2BD10ED1003F09BC /* ScreenSelector.swift in Sources */,
18F1A0E22BD3E4C000DB102C /* AreaSelector.swift in Sources */,
187966FA2BD5639D003DB1B2 /* MousePointer.swift in Sources */,
18D3BDFF2BCE5E4B006CFFC0 /* StatusBar.swift in Sources */,
18D3BE042BCEC847006CFFC0 /* SCContext.swift in Sources */,
18D3BDED2BCE5DC1006CFFC0 /* ContentView.swift in Sources */,
Expand Down Expand Up @@ -343,7 +347,7 @@
CODE_SIGN_ENTITLEMENTS = QuickRecorder/QuickRecorder.entitlements;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 101;
CURRENT_PROJECT_VERSION = 102;
DEVELOPMENT_ASSET_PATHS = "\"QuickRecorder/Preview Content\"";
DEVELOPMENT_TEAM = "";
ENABLE_HARDENED_RUNTIME = YES;
Expand All @@ -357,7 +361,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = 1.0.1;
MARKETING_VERSION = 1.0.2;
PRODUCT_BUNDLE_IDENTIFIER = com.lihaoyun6.QuickRecorder;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
Expand All @@ -373,7 +377,7 @@
CODE_SIGN_ENTITLEMENTS = QuickRecorder/QuickRecorder.entitlements;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 101;
CURRENT_PROJECT_VERSION = 102;
DEVELOPMENT_ASSET_PATHS = "\"QuickRecorder/Preview Content\"";
DEVELOPMENT_TEAM = "";
ENABLE_HARDENED_RUNTIME = YES;
Expand All @@ -387,7 +391,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = 1.0.1;
MARKETING_VERSION = 1.0.2;
PRODUCT_BUNDLE_IDENTIFIER = com.lihaoyun6.QuickRecorder;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
Expand Down
Binary file modified QuickRecorder/Assets.xcassets/.DS_Store
Binary file not shown.
38 changes: 38 additions & 0 deletions QuickRecorder/Assets.xcassets/mypurple.colorset/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0xCF",
"green" : "0x56",
"red" : "0x57"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0xEA",
"green" : "0x61",
"red" : "0x62"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
25 changes: 25 additions & 0 deletions QuickRecorder/Assets.xcassets/unknowScreen.imageset/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"images" : [
{
"filename" : "unknow screen.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "unknow screen@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"template-rendering-intent" : "template"
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
82 changes: 49 additions & 33 deletions QuickRecorder/QuickRecorderApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ import AVFoundation
import ScreenCaptureKit
import UserNotifications

let ud = UserDefaults.standard
var statusMenu: NSMenu = NSMenu()
var statusBarItem: NSStatusItem!
var mouseMonitor: Any?
var hideMousePointer = false
let info = NSMenuItem(title: "Waiting on update…".local, action: nil, keyEquivalent: "")
class CustomWindow: NSWindow {
override var canBecomeKey: Bool {
return true
}
}
let mousePointer = NSWindow(contentRect: NSRect(x: -70, y: -70, width: 70, height: 70), styleMask: [.borderless], backing: .buffered, defer: false)
let updateTimer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()

@main
struct QuickRecorderApp: App {
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
Expand Down Expand Up @@ -57,14 +58,34 @@ struct QuickRecorderApp: App {
}

class AppDelegate: NSObject, NSApplicationDelegate, SCStreamDelegate, SCStreamOutput {

var audioSettings: [String : Any]!
var filter: SCContentFilter?
var updateTimer: Timer?
let ud = UserDefaults.standard

func mousePointerReLocation(event: NSEvent) {
if hideMousePointer { mousePointer.orderOut(nil); return }
let mouseLocation = event.locationInWindow
var windowFrame = mousePointer.frame
if SCContext.stream != nil && !hideMousePointer { mousePointer.orderFront(nil) } //mousePointer.orderOut(nil)
windowFrame.origin = NSPoint(x: mouseLocation.x - windowFrame.width / 2, y: mouseLocation.y - windowFrame.height / 2)
mousePointer.contentView = NSHostingView(rootView: MousePointerView(event: event))
mousePointer.setFrameOrigin(windowFrame.origin)
}

func registerGlobalMouseMonitor() {
// 注册全局鼠标监听器
mouseMonitor = NSEvent.addGlobalMonitorForEvents(matching: [.mouseMoved, .rightMouseUp, .rightMouseDown, .rightMouseDragged, .leftMouseUp, .leftMouseDown, .leftMouseDragged, .otherMouseUp, .otherMouseDown, .otherMouseDragged]) { event in
// 处理鼠标事件
self.mousePointerReLocation(event: event)
}
}

func stopGlobalMouseMonitor() {
// 停止全局鼠标监听器
mousePointer.orderOut(nil)
if let monitor = mouseMonitor { NSEvent.removeMonitor(monitor) }
}

func applicationWillTerminate(_ aNotification: Notification) {
if SCContext.stream != nil { stopRecording() }
if SCContext.stream != nil { SCContext.stopRecording() }
}

func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool {
Expand All @@ -74,10 +95,6 @@ class AppDelegate: NSObject, NSApplicationDelegate, SCStreamDelegate, SCStreamOu

func applicationDidFinishLaunching(_ aNotification: Notification) {
SCContext.updateAvailableContent{ print("available content has been updated") }
statusMenu.delegate = self
statusBarItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
statusBarItem.menu = statusMenu
updateIcon()
lazy var userDesktop = (NSSearchPathForDirectoriesInDomains(.desktopDirectory, .userDomainMask, true) as [String]).first!
let saveDirectory = (UserDefaults(suiteName: "com.apple.screencapture")?.string(forKey: "location") ?? userDesktop) as NSString

Expand All @@ -97,9 +114,20 @@ class AppDelegate: NSObject, NSApplicationDelegate, SCStreamDelegate, SCStreamOu
//"screenArea": [100, 100, 600, 450],
"showMouse": true,
"recordMic": false,
"recordWinSound": true
"recordWinSound": true,
"highlightMouse" : true
]
)

statusMenu.delegate = self
statusBarItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
statusBarItem.menu = statusMenu
mousePointer.title = "Mouse Pointer".local
mousePointer.level = .screenSaver
mousePointer.ignoresMouseEvents = true
mousePointer.isReleasedWhenClosed = false
mousePointer.backgroundColor = NSColor.clear

UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
if let error = error { print("Notification authorization denied: \(error.localizedDescription)") }
}
Expand All @@ -110,26 +138,14 @@ extension String {
var local: String { return NSLocalizedString(self, comment: "") }
}

enum AudioQuality: Int {
case normal = 128, good = 192, high = 256, extreme = 320
}
enum AudioQuality: Int { case normal = 128, good = 192, high = 256, extreme = 320 }

enum AudioFormat: String {
case aac, alac, flac, opus
}
enum AudioFormat: String { case aac, alac, flac, opus }

enum VideoFormat: String {
case mov, mp4
}
enum VideoFormat: String { case mov, mp4 }

enum Encoder: String {
case h264, h265
}
enum Encoder: String { case h264, h265 }

enum StreamType: Int {
case screen, window, application, screenarea, systemaudio
}
enum StreamType: Int { case screen, window, application, screenarea, systemaudio }

enum BackgroundType: String {
case wallpaper, black, white, red, green, yellow, orange, gray, blue, custom
}
enum BackgroundType: String { case wallpaper, black, white, red, green, yellow, orange, gray, blue, custom }
Loading

0 comments on commit 28f51c7

Please sign in to comment.