Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding Demo to facilitate debug #1001

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions Demo/AppDelegate.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//
// AppDelegate.swift
// Demo
//
// Created by mi on 2024/12/1.
//

import Cocoa
import InputController

@main
class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ aNotification: Notification) {
// Insert code here to initialize your application

if GlobalContext.shared.problematicLaunchDetected() {
print("Problematic launch detected!")
let args = ["Problematic launch detected! Squirrel may be suffering a crash due to improper configuration. Revert previous modifications to see if the problem recurs."]
let task = Process()
task.executableURL = "/usr/bin/say".withCString { dir in
URL(fileURLWithFileSystemRepresentation: dir, isDirectory: false, relativeTo: nil)
}
task.arguments = args
try? task.run()
} else {
GlobalContext.shared.setupRime()
GlobalContext.shared.startRime(fullCheck: false)
GlobalContext.shared.loadSettings()
print("Squirrel reporting!")
}
}

func applicationWillTerminate(_ aNotification: Notification) {
// Insert code here to tear down your application
}

func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
return true
}


}

11 changes: 11 additions & 0 deletions Demo/Assets.xcassets/AccentColor.colorset/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
58 changes: 58 additions & 0 deletions Demo/Assets.xcassets/AppIcon.appiconset/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"images" : [
{
"idiom" : "mac",
"scale" : "1x",
"size" : "16x16"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "16x16"
},
{
"idiom" : "mac",
"scale" : "1x",
"size" : "32x32"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "32x32"
},
{
"idiom" : "mac",
"scale" : "1x",
"size" : "128x128"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "128x128"
},
{
"idiom" : "mac",
"scale" : "1x",
"size" : "256x256"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "256x256"
},
{
"idiom" : "mac",
"scale" : "1x",
"size" : "512x512"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "512x512"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
6 changes: 6 additions & 0 deletions Demo/Assets.xcassets/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
754 changes: 754 additions & 0 deletions Demo/Base.lproj/Main.storyboard

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions Demo/Demo.entitlements
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict/>
</plist>
67 changes: 67 additions & 0 deletions Demo/TextView+Unused.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
//
// Unused.swift
// Jyutping
//
// Created by mi on 2024/11/3.
//

import Cocoa
import InputMethodKit

extension Client {
func validAttributesForMarkedText() -> [Any]! {
fatalError()
}

func selectedRange() -> NSRange {
fatalError()
}

func markedRange() -> NSRange {
fatalError()
}

func attributedSubstring(from range: NSRange) -> NSAttributedString! {
fatalError()
}

func length() -> Int {
fatalError()
}

func characterIndex(for point: NSPoint, tracking mappingMode: IMKLocationToOffsetMappingMode, inMarkedRange: UnsafeMutablePointer<ObjCBool>!) -> Int {
fatalError()
}

func overrideKeyboard(withKeyboardNamed keyboardUniqueName: String!) {
fatalError()
}

func selectMode(_ modeIdentifier: String!) {
fatalError()
}

func supportsUnicode() -> Bool {
fatalError()
}

func supportsProperty(_ property: TSMDocumentPropertyTag) -> Bool {
fatalError()
}

func string(from range: NSRange, actualRange: NSRangePointer!) -> String! {
fatalError()
}

func firstRect(forCharacterRange aRange: NSRange, actualRange: NSRangePointer!) -> NSRect {
fatalError()
}

func windowLevel() -> CGWindowLevel {
fatalError()
}

func uniqueClientIdentifierString() -> String! {
fatalError()
}
}
97 changes: 97 additions & 0 deletions Demo/TextView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
//
// TextView.swift
// Demo
//
// Created by mi on 2024/11/3.
//

import Cocoa
import InputMethodKit

extension NSTextView {
func currentCursorRect() -> NSRect? {
guard let selectedRange = self.selectedRanges.first as? NSRange else {
return nil
}

var rect = NSRect.zero
self.layoutManager?.enumerateEnclosingRects(
forGlyphRange: selectedRange,
withinSelectedGlyphRange: selectedRange,
in: self.textContainer!,
using: { glyphRect, _ in
rect = glyphRect
}
)

return self.window?.convertToScreen(self.convert(rect, to: nil))
}
}

class Client: NSObject, IMKTextInput {
weak var textView: NSTextView?
init(textView: NSTextView?) {
self.textView = textView
}

func bundleIdentifier() -> String! {
Bundle.main.bundleIdentifier
}

func attributes(forCharacterIndex index: Int, lineHeightRectangle lineRect: UnsafeMutablePointer<NSRect>!) -> [AnyHashable : Any]! {
if let rect = textView?.currentCursorRect() {
lineRect.pointee = rect
}
return nil
}
var replacementRange: NSRange?
func setMarkedText(_ string: Any!, selectionRange: NSRange, replacementRange: NSRange) {
guard let textView else {
return
}
if let length = (string as? NSAttributedString)?.length, length == 0 {
if let replacementRange = self.replacementRange, replacementRange.length == 1 {
textView.insertText("", replacementRange: replacementRange)
}
self.replacementRange = nil
return
}

guard let firstRange = textView.selectedRanges.first?.rangeValue else {
return
}
if self.replacementRange == nil {
self.replacementRange = firstRange
}
guard let replacementRange = self.replacementRange else {
return
}

textView.setMarkedText(string as Any, selectedRange: selectionRange, replacementRange: replacementRange)
if let string = string as? String {
self.replacementRange?.length = string.count
} else if let string = string as? NSAttributedString {
self.replacementRange?.length = string.length
}
}

func insertText(_ string: Any!, replacementRange: NSRange) {
guard let string = string as? String, let textView = textView, let replacementRange = self.replacementRange else {
return
}
textView.insertText(string, replacementRange: replacementRange)
self.replacementRange = nil
}
}

class TextView: NSTextView {
lazy var client = Client(textView: self)
lazy var inputController = (NSClassFromString("SquirrelInputController") as! IMKInputController.Type).init(server: nil, delegate: nil, client: client)!

override func keyDown(with event: NSEvent) {
if inputController.handle(event, client: client) {
return
}
super.keyDown(with: event)
}
}
13 changes: 13 additions & 0 deletions Demo/ViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// ViewController.swift
// Demo
//
// Created by mi on 2024/11/10.
//

import Cocoa

class ViewController: NSViewController {
@IBOutlet var textView: TextView!

}
19 changes: 19 additions & 0 deletions InputController/InputController.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// InputController.h
// InputController
//
// Created by mi on 2024/12/1.
//

#import <Foundation/Foundation.h>

//! Project version number for InputController.
FOUNDATION_EXPORT double InputControllerVersionNumber;

//! Project version string for InputController.
FOUNDATION_EXPORT const unsigned char InputControllerVersionString[];

// In this header, you should import all the public headers of your framework using statements like #import <InputController/PublicHeader.h>

#import <rime_api_stdbool.h>
#import <rime/key_table.h>
Loading