Repo // Ensure [weak self] wherever necessary.
This commit is contained in:
parent
f4e4c37e60
commit
09e5546e9b
|
@ -38,14 +38,15 @@ public class FolderMonitor {
|
||||||
)
|
)
|
||||||
// Define the block to call when a file change is detected.
|
// Define the block to call when a file change is detected.
|
||||||
folderMonitorSource?.setEventHandler { [weak self] in
|
folderMonitorSource?.setEventHandler { [weak self] in
|
||||||
self?.folderDidChange?()
|
guard let self = self else { return }
|
||||||
|
folderDidChange?()
|
||||||
}
|
}
|
||||||
// Define a cancel handler to ensure the directory is closed when the source is cancelled.
|
// Define a cancel handler to ensure the directory is closed when the source is cancelled.
|
||||||
folderMonitorSource?.setCancelHandler { [weak self] in
|
folderMonitorSource?.setCancelHandler { [weak self] in
|
||||||
guard let strongSelf = self else { return }
|
guard let self = self else { return }
|
||||||
close(strongSelf.monitoredFolderFileDescriptor)
|
close(monitoredFolderFileDescriptor)
|
||||||
strongSelf.monitoredFolderFileDescriptor = -1
|
monitoredFolderFileDescriptor = -1
|
||||||
strongSelf.folderMonitorSource = nil
|
folderMonitorSource = nil
|
||||||
}
|
}
|
||||||
// Start monitoring the directory via the source.
|
// Start monitoring the directory via the source.
|
||||||
folderMonitorSource?.resume()
|
folderMonitorSource?.resume()
|
||||||
|
|
|
@ -54,8 +54,9 @@ extension Backport where Wrapped: View {
|
||||||
super.init()
|
super.init()
|
||||||
self.handler = { [weak self] in
|
self.handler = { [weak self] in
|
||||||
Task { [weak self] in
|
Task { [weak self] in
|
||||||
|
guard let self = self else { return }
|
||||||
await handler()
|
await handler()
|
||||||
self?.endRefreshing()
|
endRefreshing()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -146,7 +146,8 @@ final class SettingsTabViewController: NSViewController, SettingsStyleController
|
||||||
from: fromViewController,
|
from: fromViewController,
|
||||||
to: toViewController,
|
to: toViewController,
|
||||||
options: options
|
options: options
|
||||||
) { [self] in
|
) { [weak self] in
|
||||||
|
guard let self = self else { return }
|
||||||
activeChildViewConstraints = toViewController.view.constrainToSuperviewBounds()
|
activeChildViewConstraints = toViewController.view.constrainToSuperviewBounds()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,8 @@ open class CtlCandidate: NSWindowController, CtlCandidateProtocol {
|
||||||
open var visible = false {
|
open var visible = false {
|
||||||
didSet {
|
didSet {
|
||||||
NSObject.cancelPreviousPerformRequests(withTarget: self)
|
NSObject.cancelPreviousPerformRequests(withTarget: self)
|
||||||
DispatchQueue.main.async { [self] in
|
DispatchQueue.main.async { [weak self] in
|
||||||
|
guard let self = self else { return }
|
||||||
_ = visible ? window?.orderFront(self) : window?.orderOut(self)
|
_ = visible ? window?.orderFront(self) : window?.orderOut(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,7 +114,8 @@ public class CtlCandidateTDK: CtlCandidate, NSWindowDelegate {
|
||||||
Self.thePool.tooltip = delegate?.candidateToolTip(shortened: !Self.thePool.isMatrix) ?? ""
|
Self.thePool.tooltip = delegate?.candidateToolTip(shortened: !Self.thePool.isMatrix) ?? ""
|
||||||
}
|
}
|
||||||
delegate?.candidatePairHighlightChanged(at: highlightedIndex)
|
delegate?.candidatePairHighlightChanged(at: highlightedIndex)
|
||||||
DispatchQueue.main.async { [self] in
|
DispatchQueue.main.async { [weak self] in
|
||||||
|
guard let self = self else { return }
|
||||||
updateNSWindowModern(window)
|
updateNSWindowModern(window)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,7 +85,8 @@ public extension AppDelegate {
|
||||||
LMMgr.loadCassetteData()
|
LMMgr.loadCassetteData()
|
||||||
LMMgr.initUserLangModels()
|
LMMgr.initUserLangModels()
|
||||||
folderMonitor.folderDidChange = { [weak self] in
|
folderMonitor.folderDidChange = { [weak self] in
|
||||||
self?.reloadOnFolderChangeHappens()
|
guard let self = self else { return }
|
||||||
|
reloadOnFolderChangeHappens()
|
||||||
}
|
}
|
||||||
if LMMgr.userDataFolderExists { folderMonitor.startMonitoring() }
|
if LMMgr.userDataFolderExists { folderMonitor.startMonitoring() }
|
||||||
|
|
||||||
|
@ -101,7 +102,8 @@ public extension AppDelegate {
|
||||||
url: URL(fileURLWithPath: LMMgr.dataFolderPath(isDefaultFolder: false))
|
url: URL(fileURLWithPath: LMMgr.dataFolderPath(isDefaultFolder: false))
|
||||||
)
|
)
|
||||||
folderMonitor.folderDidChange = { [weak self] in
|
folderMonitor.folderDidChange = { [weak self] in
|
||||||
self?.reloadOnFolderChangeHappens()
|
guard let self = self else { return }
|
||||||
|
reloadOnFolderChangeHappens()
|
||||||
}
|
}
|
||||||
if LMMgr.userDataFolderExists { // 沒有資料夾的話,FolderMonitor 會崩潰。
|
if LMMgr.userDataFolderExists { // 沒有資料夾的話,FolderMonitor 會崩潰。
|
||||||
folderMonitor.startMonitoring()
|
folderMonitor.startMonitoring()
|
||||||
|
|
|
@ -217,7 +217,8 @@ public class SessionCtl: IMKInputController {
|
||||||
|
|
||||||
/// 所有建構子都會執行的共用部分,在 super.init() 之後執行。
|
/// 所有建構子都會執行的共用部分,在 super.init() 之後執行。
|
||||||
private func construct(client theClient: (IMKTextInput & NSObjectProtocol)? = nil) {
|
private func construct(client theClient: (IMKTextInput & NSObjectProtocol)? = nil) {
|
||||||
DispatchQueue.main.async { [self] in
|
DispatchQueue.main.async { [weak self] in
|
||||||
|
guard let self = self else { return }
|
||||||
inputHandler = InputHandler(
|
inputHandler = InputHandler(
|
||||||
lm: LMMgr.currentLM, uom: LMMgr.currentUOM, pref: PrefMgr.shared
|
lm: LMMgr.currentLM, uom: LMMgr.currentUOM, pref: PrefMgr.shared
|
||||||
)
|
)
|
||||||
|
@ -239,7 +240,8 @@ public extension SessionCtl {
|
||||||
func setKeyLayout() {
|
func setKeyLayout() {
|
||||||
guard let client = client(), !isServingIMEItself else { return }
|
guard let client = client(), !isServingIMEItself else { return }
|
||||||
|
|
||||||
DispatchQueue.main.async { [self] in
|
DispatchQueue.main.async { [weak self] in
|
||||||
|
guard let self = self else { return }
|
||||||
if isASCIIMode, IMKHelper.isDynamicBasicKeyboardLayoutEnabled {
|
if isASCIIMode, IMKHelper.isDynamicBasicKeyboardLayoutEnabled {
|
||||||
client.overrideKeyboard(withKeyboardNamed: PrefMgr.shared.alphanumericalKeyboardLayout)
|
client.overrideKeyboard(withKeyboardNamed: PrefMgr.shared.alphanumericalKeyboardLayout)
|
||||||
return
|
return
|
||||||
|
@ -272,7 +274,8 @@ public extension SessionCtl {
|
||||||
override func activateServer(_ sender: Any!) {
|
override func activateServer(_ sender: Any!) {
|
||||||
super.activateServer(sender)
|
super.activateServer(sender)
|
||||||
isBootingUp = true
|
isBootingUp = true
|
||||||
DispatchQueue.main.async { [self] in
|
DispatchQueue.main.async { [weak self] in
|
||||||
|
guard let self = self else { return }
|
||||||
if let senderBundleID: String = (sender as? IMKTextInput)?.bundleIdentifier() {
|
if let senderBundleID: String = (sender as? IMKTextInput)?.bundleIdentifier() {
|
||||||
vCLog("activateServer(\(senderBundleID))")
|
vCLog("activateServer(\(senderBundleID))")
|
||||||
isServingIMEItself = Bundle.main.bundleIdentifier == senderBundleID
|
isServingIMEItself = Bundle.main.bundleIdentifier == senderBundleID
|
||||||
|
@ -285,7 +288,8 @@ public extension SessionCtl {
|
||||||
PrefMgr.shared.shouldNotFartInLieuOfBeep = true
|
PrefMgr.shared.shouldNotFartInLieuOfBeep = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DispatchQueue.main.async { [self] in
|
DispatchQueue.main.async { [weak self] in
|
||||||
|
guard let self = self else { return }
|
||||||
if inputMode != IMEApp.currentInputMode {
|
if inputMode != IMEApp.currentInputMode {
|
||||||
inputMode = IMEApp.currentInputMode
|
inputMode = IMEApp.currentInputMode
|
||||||
}
|
}
|
||||||
|
@ -300,7 +304,8 @@ public extension SessionCtl {
|
||||||
CtlCandidateTDK.currentWindow?.orderOut(nil)
|
CtlCandidateTDK.currentWindow?.orderOut(nil)
|
||||||
CtlCandidateTDK.currentWindow = nil
|
CtlCandidateTDK.currentWindow = nil
|
||||||
}
|
}
|
||||||
DispatchQueue.main.async { [self] in
|
DispatchQueue.main.async { [weak self] in
|
||||||
|
guard let self = self else { return }
|
||||||
if isActivated { return }
|
if isActivated { return }
|
||||||
|
|
||||||
// 這裡不需要 setValue(),因為 IMK 會在自動呼叫 activateServer() 之後自動執行 setValue()。
|
// 這裡不需要 setValue(),因為 IMK 會在自動呼叫 activateServer() 之後自動執行 setValue()。
|
||||||
|
@ -331,7 +336,8 @@ public extension SessionCtl {
|
||||||
/// 停用輸入法時,會觸發該函式。
|
/// 停用輸入法時,會觸發該函式。
|
||||||
/// - Parameter sender: 呼叫了該函式的客體(無須使用)。
|
/// - Parameter sender: 呼叫了該函式的客體(無須使用)。
|
||||||
override func deactivateServer(_ sender: Any!) {
|
override func deactivateServer(_ sender: Any!) {
|
||||||
DispatchQueue.main.async { [self] in
|
DispatchQueue.main.async { [weak self] in
|
||||||
|
guard let self = self else { return }
|
||||||
isActivated = false
|
isActivated = false
|
||||||
resetInputHandler() // 這條會自動搞定 Empty 狀態。
|
resetInputHandler() // 這條會自動搞定 Empty 狀態。
|
||||||
switchState(IMEState.ofDeactivated())
|
switchState(IMEState.ofDeactivated())
|
||||||
|
@ -352,7 +358,8 @@ public extension SessionCtl {
|
||||||
/// - tag: 標記(無須使用)。
|
/// - tag: 標記(無須使用)。
|
||||||
/// - sender: 呼叫了該函式的客體(無須使用)。
|
/// - sender: 呼叫了該函式的客體(無須使用)。
|
||||||
override func setValue(_ value: Any!, forTag tag: Int, client sender: Any!) {
|
override func setValue(_ value: Any!, forTag tag: Int, client sender: Any!) {
|
||||||
DispatchQueue.main.async { [self] in
|
DispatchQueue.main.async { [weak self] in
|
||||||
|
guard let self = self else { return }
|
||||||
let newMode: Shared.InputMode = .init(rawValue: value as? String ?? PrefMgr.shared.mostRecentInputMode) ?? .imeModeNULL
|
let newMode: Shared.InputMode = .init(rawValue: value as? String ?? PrefMgr.shared.mostRecentInputMode) ?? .imeModeNULL
|
||||||
if inputMode != newMode { inputMode = newMode }
|
if inputMode != newMode { inputMode = newMode }
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,8 @@ extension CtlPrefWindow: NSTextViewDelegate, NSTextFieldDelegate {
|
||||||
clearAllFields()
|
clearAllFields()
|
||||||
isLoading = true
|
isLoading = true
|
||||||
tfdPETextEditor.string = NSLocalizedString("Loading…", comment: "")
|
tfdPETextEditor.string = NSLocalizedString("Loading…", comment: "")
|
||||||
DispatchQueue.main.async { [self] in
|
DispatchQueue.main.async { [weak self] in
|
||||||
|
guard let self = self else { return }
|
||||||
tfdPETextEditor.string = LMMgr.retrieveData(mode: selInputMode, type: selUserDataType)
|
tfdPETextEditor.string = LMMgr.retrieveData(mode: selInputMode, type: selUserDataType)
|
||||||
tfdPETextEditor.toolTip = PETerms.TooltipTexts.sampleDictionaryContent(for: selUserDataType)
|
tfdPETextEditor.toolTip = PETerms.TooltipTexts.sampleDictionaryContent(for: selUserDataType)
|
||||||
isLoading = false
|
isLoading = false
|
||||||
|
@ -173,7 +174,8 @@ extension CtlPrefWindow: NSTextViewDelegate, NSTextFieldDelegate {
|
||||||
@IBAction func reloadPEButtonClicked(_: NSButton) { updatePhraseEditor() }
|
@IBAction func reloadPEButtonClicked(_: NSButton) { updatePhraseEditor() }
|
||||||
|
|
||||||
@IBAction func consolidatePEButtonClicked(_: NSButton) {
|
@IBAction func consolidatePEButtonClicked(_: NSButton) {
|
||||||
DispatchQueue.main.async { [self] in
|
DispatchQueue.main.async { [weak self] in
|
||||||
|
guard let self = self else { return }
|
||||||
isLoading = true
|
isLoading = true
|
||||||
vChewingLM.LMConsolidator.consolidate(text: &tfdPETextEditor.string, pragma: false)
|
vChewingLM.LMConsolidator.consolidate(text: &tfdPETextEditor.string, pragma: false)
|
||||||
if selUserDataType == .thePhrases {
|
if selUserDataType == .thePhrases {
|
||||||
|
@ -193,20 +195,22 @@ extension CtlPrefWindow: NSTextViewDelegate, NSTextFieldDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func openExternallyPEButtonClicked(_: NSButton) {
|
@IBAction func openExternallyPEButtonClicked(_: NSButton) {
|
||||||
DispatchQueue.main.async { [self] in
|
DispatchQueue.main.async { [weak self] in
|
||||||
|
guard let self = self else { return }
|
||||||
let app: String = NSEvent.keyModifierFlags.contains(.option) ? "TextEdit" : "Finder"
|
let app: String = NSEvent.keyModifierFlags.contains(.option) ? "TextEdit" : "Finder"
|
||||||
LMMgr.shared.openPhraseFile(mode: selInputMode, type: selUserDataType, app: app)
|
LMMgr.shared.openPhraseFile(mode: selInputMode, type: selUserDataType, app: app)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func addPEButtonClicked(_: NSButton) {
|
@IBAction func addPEButtonClicked(_: NSButton) {
|
||||||
DispatchQueue.main.async { [self] in
|
DispatchQueue.main.async { [weak self] in
|
||||||
|
guard let self = self else { return }
|
||||||
txtPEField1.stringValue.removeAll { " \t\n\r".contains($0) }
|
txtPEField1.stringValue.removeAll { " \t\n\r".contains($0) }
|
||||||
if selUserDataType != .theAssociates {
|
if selUserDataType != .theAssociates {
|
||||||
txtPEField2.stringValue.regReplace(pattern: #"( +| +| +|\t+)+"#, replaceWith: "-")
|
txtPEField2.stringValue.regReplace(pattern: #"( +| +| +|\t+)+"#, replaceWith: "-")
|
||||||
}
|
}
|
||||||
txtPEField2.stringValue.removeAll {
|
txtPEField2.stringValue.removeAll {
|
||||||
selUserDataType == .theAssociates ? "\n\r".contains($0) : " \t\n\r".contains($0)
|
self.selUserDataType == .theAssociates ? "\n\r".contains($0) : " \t\n\r".contains($0)
|
||||||
}
|
}
|
||||||
txtPEField3.stringValue.removeAll { !"0123456789.-".contains($0) }
|
txtPEField3.stringValue.removeAll { !"0123456789.-".contains($0) }
|
||||||
txtPECommentField.stringValue.removeAll { "\n\r".contains($0) }
|
txtPECommentField.stringValue.removeAll { "\n\r".contains($0) }
|
||||||
|
|
|
@ -156,8 +156,9 @@ class FrmRevLookupWindow: NSWindow {
|
||||||
@objc func keyboardConfirmed(_: Any?) {
|
@objc func keyboardConfirmed(_: Any?) {
|
||||||
if inputField.stringValue.isEmpty { return }
|
if inputField.stringValue.isEmpty { return }
|
||||||
resultView.string = "\n" + "Loading…".localized
|
resultView.string = "\n" + "Loading…".localized
|
||||||
DispatchQueue.main.async { [self] in
|
DispatchQueue.main.async { [weak self] in
|
||||||
self.updateResult(with: self.inputField.stringValue)
|
guard let self = self else { return }
|
||||||
|
updateResult(with: self.inputField.stringValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue