2.6.0 // Steam support, etc. Merge PR #131 from upd/2.6.0

This commit is contained in:
ShikiSuen 2022-09-11 19:35:18 +08:00 committed by GitHub
commit da9cccbb2a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
41 changed files with 811 additions and 206 deletions

View File

@ -17,7 +17,7 @@ $ Contributors and volunteers of the upstream repo, having no responsibility in
- Zonble Yang:
- McBopomofo for macOS 2.x architect.
- Voltaire candidate window MK2 (massively modified as MK3 in vChewing by Shiki Suen).
- Notifier window and Tooltip UI.
- Notifier window.
- App-style installer (only preserved for developer purposes).
- mgrPrefs (userdefaults manager).
- Mengjuei Hsieh:

View File

@ -101,6 +101,7 @@ class AppDelegate: NSWindowController, NSApplicationDelegate {
window.standardWindowButton(.closeButton)?.isHidden = true
window.standardWindowButton(.miniaturizeButton)?.isHidden = true
window.standardWindowButton(.zoomButton)?.isHidden = true
window.titlebarAppearsTransparent = true
if FileManager.default.fileExists(
atPath: kTargetPartialPath)

View File

@ -198,7 +198,7 @@ DQ
</textField>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="XLb-mv-73s">
<rect key="frame" x="89" y="387" width="431" height="15"/>
<textFieldCell key="cell" selectable="YES" title="Placeholder for detailed credits." id="VW8-s5-Wpn">
<textFieldCell key="cell" title="Placeholder for detailed credits." id="VW8-s5-Wpn">
<font key="font" size="12" name="Tahoma"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
@ -220,7 +220,7 @@ DQ
<constraints>
<constraint firstAttribute="width" constant="356" id="pu3-zr-hJy"/>
</constraints>
<textFieldCell key="cell" selectable="YES" id="Q9M-ni-kUM">
<textFieldCell key="cell" id="Q9M-ni-kUM">
<font key="font" size="12" name="Tahoma"/>
<string key="title">DISCLAIMER: The vChewing project, having no relationship of cooperation or affiliation with the OpenVanilla project, is not responsible for the phrase database shipped in the original McBopomofo project. Certain geopolitical and ideological contents, which are potentially harmful to the global spread of this software, are not included in vChewing official phrase database.</string>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>

View File

@ -65,9 +65,11 @@ public class NSAttributedTextView: NSView {
let isVertical: Bool = !(direction == .horizontal)
newAttributes[.verticalGlyphForm] = isVertical
let newStyle: NSMutableParagraphStyle = newAttributes[.paragraphStyle] as! NSMutableParagraphStyle
newStyle.lineSpacing = isVertical ? (fontSize / -2) : fontSize * 0.1
newStyle.maximumLineHeight = fontSize
newStyle.minimumLineHeight = fontSize
if #available(macOS 10.13, *) {
newStyle.lineSpacing = isVertical ? (fontSize / -2) : fontSize * 0.1
newStyle.maximumLineHeight = fontSize * 1.1
newStyle.minimumLineHeight = fontSize * 1.1
}
newAttributes[.paragraphStyle] = newStyle
var text: String = text ?? ""
if !(direction == .horizontal) {

@ -1 +1 @@
Subproject commit 6dba7237957681bfa4c623ab5689248cc02bc7e6
Subproject commit eeff2e3f7073873c07b4011717e32430db01227f

View File

@ -25,6 +25,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
// let vChewingKeyLayoutBundle = Bundle.init(path: URL(fileURLWithPath: Bundle.main.resourcePath ?? "").appendingPathComponent("vChewingKeyLayout.bundle").path)
@IBOutlet var window: NSWindow?
private var ctlClientListMgrInstance: ctlClientListMgr?
private var ctlPrefWindowInstance: ctlPrefWindow?
private var ctlAboutWindowInstance: ctlAboutWindow? // New About Window
public lazy var folderMonitor = FolderMonitor(
@ -80,6 +81,17 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
folderMonitor.startMonitoring()
}
func showClientListMgr() {
if ctlClientListMgrInstance == nil {
ctlClientListMgrInstance = ctlClientListMgr.init(windowNibName: "frmClientListMgr")
}
ctlClientListMgrInstance?.window?.center()
ctlClientListMgrInstance?.window?.orderFrontRegardless() //
ctlClientListMgrInstance?.window?.level = .statusBar
ctlClientListMgrInstance?.window?.titlebarAppearsTransparent = true
NSApp.setActivationPolicy(.accessory)
}
func showPreferences() {
if ctlPrefWindowInstance == nil {
ctlPrefWindowInstance = ctlPrefWindow.init(windowNibName: "frmPrefWindow")
@ -99,6 +111,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
ctlAboutWindowInstance?.window?.center()
ctlAboutWindowInstance?.window?.orderFrontRegardless() //
ctlAboutWindowInstance?.window?.level = .statusBar
ctlAboutWindowInstance?.window?.titlebarAppearsTransparent = true
NSApp.setActivationPolicy(.accessory)
}

View File

@ -113,6 +113,7 @@ extension IMEState {
// displayTextSegments
result.data.displayTextSegments = displayTextSegments
result.data.cursor = cursor
result.data.marker = cursor
return result
}

View File

@ -9,13 +9,16 @@
import Foundation
public struct StateData {
var displayedText: String = "" {
didSet {
let result = IME.kanjiConversionIfRequired(displayedText)
if result.utf16.count == displayedText.utf16.count, result.count == displayedText.count {
displayedText = result
}
var displayedText: String = ""
var displayedTextConverted: String {
///
var result = IME.kanjiConversionIfRequired(displayedText)
if result.utf16.count != displayedText.utf16.count
|| result.count != displayedText.count
{
result = displayedText
}
return result
}
// MARK: Cursor & Marker & Range for UTF8
@ -86,7 +89,7 @@ public struct StateData {
var attributedStringNormal: NSAttributedString {
///
/// JIS
let attributedString = NSMutableAttributedString(string: displayedText)
let attributedString = NSMutableAttributedString(string: displayedTextConverted)
var newBegin = 0
for (i, neta) in displayTextSegments.enumerated() {
attributedString.setAttributes(
@ -104,7 +107,7 @@ public struct StateData {
var attributedStringMarking: NSAttributedString {
///
/// JIS
let attributedString = NSMutableAttributedString(string: displayedText)
let attributedString = NSMutableAttributedString(string: displayedTextConverted)
let end = u16MarkedRange.upperBound
attributedString.setAttributes(
@ -130,7 +133,7 @@ public struct StateData {
],
range: NSRange(
location: end,
length: displayedText.utf16.count - end
length: displayedTextConverted.utf16.count - end
)
)
return attributedString

View File

@ -438,3 +438,52 @@ public class KeyHandler {
}
}
}
// MARK: - Components for Popup Composition Buffer (PCB) Window.
///
/// - Remark: IMKTextInput mgrPrefs
private let compositorWidthLimit = 20
extension KeyHandler {
///
///
///
///
/// 使
///
var commitOverflownComposition: String {
guard !compositor.walkedNodes.isEmpty,
compositor.width > compositorWidthLimit,
let identifier = delegate?.clientBundleIdentifier,
mgrPrefs.clientsIMKTextInputIncapable.contains(identifier)
else {
return ""
}
// Steam Client Identifier
var textToCommit = ""
while compositor.width > compositorWidthLimit {
var delta = compositor.width - compositorWidthLimit
let node = compositor.walkedNodes[0]
if node.isReadingMismatched {
delta = node.keyArray.count
textToCommit += node.currentPair.value
} else {
delta = min(delta, node.keyArray.count)
textToCommit += node.currentPair.value.charComponents[0..<delta].joined()
}
let newCursor = max(compositor.cursor - delta, 0)
compositor.cursor = 0
if !node.isReadingMismatched {
consolidateCursorContext(with: node.currentPair)
}
// Bigram
for _ in 0..<delta {
compositor.dropKey(direction: .front)
}
compositor.cursor = newCursor
walk()
}
return textToCommit
}
}

View File

@ -111,6 +111,9 @@ extension KeyHandler {
//
walk()
// App
let textToCommit = commitOverflownComposition
//
fetchSuggestionsFromUOM(apply: true)
@ -118,7 +121,8 @@ extension KeyHandler {
composer.clear()
// updateClientdisplayedText()
let inputting = buildInputtingState
var inputting = buildInputtingState
inputting.textToCommit = textToCommit
stateCallback(inputting)
///

View File

@ -22,15 +22,19 @@ extension NSEvent {
isARepeat: Bool? = nil,
keyCode: UInt16? = nil
) -> NSEvent? {
NSEvent.keyEvent(
let oldChars: String = {
if self.type == .flagsChanged { return "" }
return self.characters ?? ""
}()
return NSEvent.keyEvent(
with: type ?? self.type,
location: location ?? locationInWindow,
modifierFlags: modifierFlags ?? self.modifierFlags,
timestamp: timestamp ?? self.timestamp,
windowNumber: windowNumber ?? self.windowNumber,
context: nil,
characters: characters ?? self.characters ?? "",
charactersIgnoringModifiers: charactersIgnoringModifiers ?? self.characters ?? "",
characters: characters ?? oldChars,
charactersIgnoringModifiers: charactersIgnoringModifiers ?? characters ?? oldChars,
isARepeat: isARepeat ?? self.isARepeat,
keyCode: keyCode ?? self.keyCode
)
@ -81,6 +85,8 @@ extension NSEvent: InputSignalProtocol {
}
public var charCode: UInt16 {
guard type != .flagsChanged else { return 0 }
guard characters != nil else { return 0 }
// count > 0!isEmpty滿
guard !text.isEmpty else { return 0 }
let scalars = text.unicodeScalars

View File

@ -16,59 +16,9 @@ extension ctlInputMethod {
/// - Parameter event: IMK
/// - Returns: `true` IMK`false`
func commonEventHandler(_ event: NSEvent) -> Bool {
// Shift macOS 10.15 macOS
let shouldUseHandle: Bool = {
switch mgrPrefs.shiftKeyAccommodationBehavior {
case 0: return false
case 1: return IME.arrClientShiftHandlingExceptionList.contains(clientBundleIdentifier)
case 2: return true
default: return false
}
}()
if #available(macOS 10.15, *) {
if ShiftKeyUpChecker.check(event), !mgrPrefs.disableShiftTogglingAlphanumericalMode {
if !shouldUseHandle || (!rencentKeyHandledByKeyHandler && shouldUseHandle) {
NotifierController.notify(
message: NSLocalizedString("Alphanumerical Mode", comment: "") + "\n"
+ (toggleASCIIMode()
? NSLocalizedString("NotificationSwitchON", comment: "")
: NSLocalizedString("NotificationSwitchOFF", comment: ""))
)
}
if shouldUseHandle {
rencentKeyHandledByKeyHandler = false
}
return false
}
}
///
guard client() != nil else { return false }
var event = event
// 使 NSEvent Emacs NSEvent NSEvent
if event.isEmacsKey {
let verticalProcessing =
(state.isCandidateContainer)
? ctlInputMethod.isVerticalCandidateSituation : ctlInputMethod.isVerticalTypingSituation
event = event.convertFromEmacKeyEvent(isVerticalContext: verticalProcessing)
}
/// flags使 KeyHandler
/// flags
/// event.type == .flagsChanged return false
/// NSInternalInconsistencyException
if event.type == .flagsChanged { return false }
//
ctlInputMethod.areWeNerfing = event.modifierFlags.contains([.shift, .command])
//
// KeyHandler
if !event.charCode.isPrintable {
return false
}
if !event.charCode.isPrintable { return false }
/// 調
/// result bool IMK
@ -78,9 +28,43 @@ extension ctlInputMethod {
} errorCallback: {
clsSFX.beep()
}
if shouldUseHandle {
rencentKeyHandledByKeyHandler = result
}
return result
}
/// handle() IMK
/// handle()
/// - Parameter event: IMK
/// - Returns: `true` IMK`false`
func imkCandidatesEventHandler(event eventToDeal: NSEvent) -> Bool? {
// IMK IMK
// interpretKeyEvents()
// - super.interpretKeyEvents()
// - delegate ctlInputMethod KeyHandler
if let imkCandidates = ctlInputMethod.ctlCandidateCurrent as? ctlCandidateIMK, imkCandidates.visible {
let event: NSEvent = ctlCandidateIMK.replaceNumPadKeyCodes(target: eventToDeal) ?? eventToDeal
// Shift+Enter delegate keyHandler
// Shift Flags
if event.isShiftHold, event.isEnter {
guard let newEvent = event.reinitiate(modifierFlags: []) else {
NSSound.beep()
return true
}
imkCandidates.interpretKeyEvents([newEvent])
return true
}
//
if let newChar = ctlCandidateIMK.defaultIMKSelectionKey[event.keyCode],
event.isShiftHold, isAssociatedPhrasesState,
let newEvent = event.reinitiate(modifierFlags: [], characters: newChar)
{
imkCandidates.handleKeyboardEvent(newEvent)
}
imkCandidates.interpretKeyEvents([event])
return true
}
return nil
}
}

View File

@ -27,9 +27,12 @@ class ctlInputMethod: IMKInputController {
static var ctlCandidateCurrent: ctlCandidateProtocol =
mgrPrefs.useIMKCandidateWindow ? ctlCandidateIMK.init(.horizontal) : ctlCandidateUniversal.init(.horizontal)
///
///
static var tooltipInstance = ctlTooltip()
///
static var popupCompositionBuffer = ctlPopupCompositionBuffer()
// MARK: -
/// ctlInputMethod
@ -57,7 +60,7 @@ class ctlInputMethod: IMKInputController {
}
/// `handle(event:)` Shift
var rencentKeyHandledByKeyHandler = false
var rencentKeyHandledByKeyHandlerEtc = false
// MARK: -
@ -115,18 +118,7 @@ class ctlInputMethod: IMKInputController {
keyHandler.clear() // handle State.Empty()
keyHandler.ensureParser()
if isASCIIMode {
if mgrPrefs.disableShiftTogglingAlphanumericalMode {
isASCIIMode = false
} else {
NotifierController.notify(
message: NSLocalizedString("Alphanumerical Mode", comment: "") + "\n"
+ (isASCIIMode
? NSLocalizedString("NotificationSwitchON", comment: "")
: NSLocalizedString("NotificationSwitchOFF", comment: ""))
)
}
}
if isASCIIMode, mgrPrefs.disableShiftTogglingAlphanumericalMode { isASCIIMode = false }
///
/// macOS
@ -207,6 +199,8 @@ class ctlInputMethod: IMKInputController {
@objc(handleEvent:client:) override func handle(_ event: NSEvent!, client sender: Any!) -> Bool {
_ = sender //
// MARK:
//
ctlInputMethod.isASCIIModeSituation = isASCIIMode
ctlInputMethod.isVerticalTypingSituation = isVerticalTyping
@ -218,44 +212,72 @@ class ctlInputMethod: IMKInputController {
return false
}
// IMK IMK
// interpretKeyEvents()
// - super.interpretKeyEvents()
// - delegate ctlInputMethod KeyHandler
proc: if let ctlCandidateCurrent = ctlInputMethod.ctlCandidateCurrent as? ctlCandidateIMK {
guard ctlCandidateCurrent.visible else { break proc }
var event: NSEvent = ctlCandidateIMK.replaceNumPadKeyCodes(target: event) ?? event
// 使 NSEvent Emacs NSEvent NSEvent
if event.isEmacsKey {
event = event.convertFromEmacKeyEvent(isVerticalContext: ctlInputMethod.isVerticalCandidateSituation)
// Shift macOS 10.15 macOS
let shouldUseShiftToggleHandle: Bool = {
switch mgrPrefs.shiftKeyAccommodationBehavior {
case 0: return false
case 1: return IME.arrClientShiftHandlingExceptionList.contains(clientBundleIdentifier)
case 2: return true
default: return false
}
}()
// Shift+Enter delegate keyHandler
// Shift Flags
if event.isShiftHold, event.isEnter {
guard let newEvent = event.reinitiate(modifierFlags: []) else {
NSSound.beep()
return true
/// event event var Shift
if #available(macOS 10.15, *) {
if ShiftKeyUpChecker.check(event), !mgrPrefs.disableShiftTogglingAlphanumericalMode {
if !shouldUseShiftToggleHandle || (!rencentKeyHandledByKeyHandlerEtc && shouldUseShiftToggleHandle) {
NotifierController.notify(
message: NSLocalizedString("Alphanumerical Mode", comment: "") + "\n"
+ (toggleASCIIMode()
? NSLocalizedString("NotificationSwitchON", comment: "")
: NSLocalizedString("NotificationSwitchOFF", comment: ""))
)
}
ctlCandidateCurrent.interpretKeyEvents([newEvent])
return true
if shouldUseShiftToggleHandle {
rencentKeyHandledByKeyHandlerEtc = false
}
return false
}
//
if let newChar = ctlCandidateIMK.defaultIMKSelectionKey[event.keyCode], event.isShiftHold,
isAssociatedPhrasesState, let newEvent = event.reinitiate(modifierFlags: [], characters: newChar)
{
ctlCandidateCurrent.handleKeyboardEvent(newEvent)
}
ctlCandidateCurrent.interpretKeyEvents([event])
return true
}
/// commonEventHandler
// MARK:
/// flags使 KeyHandler
/// flags
/// event.type == .flagsChanged return false
/// NSInternalInconsistencyException
if event.type == .flagsChanged { return false }
///
guard client() != nil else { return false }
var eventToDeal = event
// 使 NSEvent Emacs NSEvent NSEvent
if eventToDeal.isEmacsKey {
let verticalProcessing =
(state.isCandidateContainer)
? ctlInputMethod.isVerticalCandidateSituation : ctlInputMethod.isVerticalTypingSituation
eventToDeal = eventToDeal.convertFromEmacKeyEvent(isVerticalContext: verticalProcessing)
}
//
ctlInputMethod.areWeNerfing = eventToDeal.modifierFlags.contains([.shift, .command])
// IMK IMK
if let result = imkCandidatesEventHandler(event: eventToDeal) {
if shouldUseShiftToggleHandle {
rencentKeyHandledByKeyHandlerEtc = result
}
return result
}
/// NSEvent commonEventHandler
/// IMK 便
/// event event var Shift
return commonEventHandler(event)
let result = commonEventHandler(eventToDeal)
if shouldUseShiftToggleHandle {
rencentKeyHandledByKeyHandlerEtc = result
}
return result
}
/// App Ctrl+Enter / Shift+Enter

View File

@ -16,7 +16,7 @@ extension ctlInputMethod: KeyHandlerDelegate {
///
public var isVerticalTyping: Bool {
guard let client = client() else { return false }
var textFrame = NSRect.zero
var textFrame = NSRect.seniorTheBeast
let attributes: [AnyHashable: Any]? = client.attributes(
forCharacterIndex: 0, lineHeightRectangle: &textFrame
)

View File

@ -13,19 +13,31 @@ import Cocoa
// MARK: - Tooltip Display and Candidate Display Methods
extension ctlInputMethod {
func show(tooltip: String, displayedText: String, u16Cursor: Int) {
guard let client = client() else { return }
var lineHeightRect = NSRect(x: 0.0, y: 0.0, width: 16.0, height: 16.0)
var cursor = u16Cursor
if cursor == displayedText.count, cursor != 0 {
cursor -= 1
func lineHeightRect(zeroCursor: Bool = false) -> NSRect {
var lineHeightRect = NSRect.seniorTheBeast
guard let client = client() else {
return lineHeightRect
}
while lineHeightRect.origin.x == 0, lineHeightRect.origin.y == 0, cursor >= 0 {
var u16Cursor: Int = {
// iMessage cursor == 0
if clientBundleIdentifier == "com.apple.MobileSMS" { return state.data.u16Cursor }
if state.data.marker >= state.data.cursor { return state.data.u16Cursor }
return state.data.u16Marker //
}()
u16Cursor = max(min(state.data.displayedTextConverted.utf16.count, u16Cursor), 0)
if zeroCursor { u16Cursor = 0 }
while lineHeightRect.origin.x == 0, lineHeightRect.origin.y == 0, u16Cursor >= 0 {
client.attributes(
forCharacterIndex: cursor, lineHeightRectangle: &lineHeightRect
forCharacterIndex: u16Cursor, lineHeightRectangle: &lineHeightRect
)
cursor -= 1
u16Cursor -= 1
}
return lineHeightRect
}
func show(tooltip: String) {
guard client() != nil else { return }
let lineHeightRect = lineHeightRect()
var finalOrigin: NSPoint = lineHeightRect.origin
let delta: CGFloat = lineHeightRect.size.height + 4.0 // bottomOutOfScreenAdjustmentHeight
if isVerticalTyping {
@ -120,34 +132,17 @@ extension ctlInputMethod {
ctlInputMethod.ctlCandidateCurrent.visible = true
var lineHeightRect = NSRect(x: 0.0, y: 0.0, width: 16.0, height: 16.0)
var cursor = 0
if [.ofCandidates, .ofSymbolTable].contains(state.type) {
cursor = state.data.cursor
if cursor == state.displayedText.count, cursor != 0 {
cursor -= 1
}
}
while lineHeightRect.origin.x == 0, lineHeightRect.origin.y == 0, cursor >= 0 {
client.attributes(
forCharacterIndex: cursor, lineHeightRectangle: &lineHeightRect
)
cursor -= 1
}
if isVerticalTyping {
ctlInputMethod.ctlCandidateCurrent.set(
windowTopLeftPoint: NSPoint(
x: lineHeightRect.origin.x + lineHeightRect.size.width + 4.0, y: lineHeightRect.origin.y - 4.0
x: lineHeightRect().origin.x + lineHeightRect().size.width + 4.0, y: lineHeightRect().origin.y - 4.0
),
bottomOutOfScreenAdjustmentHeight: lineHeightRect.size.height + 4.0
bottomOutOfScreenAdjustmentHeight: lineHeightRect().size.height + 4.0
)
} else {
ctlInputMethod.ctlCandidateCurrent.set(
windowTopLeftPoint: NSPoint(x: lineHeightRect.origin.x, y: lineHeightRect.origin.y - 4.0),
bottomOutOfScreenAdjustmentHeight: lineHeightRect.size.height + 4.0
windowTopLeftPoint: NSPoint(x: lineHeightRect().origin.x, y: lineHeightRect().origin.y - 4.0),
bottomOutOfScreenAdjustmentHeight: lineHeightRect().size.height + 4.0
)
}
}

View File

@ -65,10 +65,7 @@ extension ctlInputMethod {
if !textToCommit.isEmpty { commit(text: textToCommit) }
setInlineDisplayWithCursor()
if !state.tooltip.isEmpty {
show(
tooltip: state.tooltip, displayedText: state.displayedText,
u16Cursor: state.data.u16Cursor
)
show(tooltip: state.tooltip)
}
case .ofMarking:
ctlInputMethod.ctlCandidateCurrent.visible = false
@ -76,14 +73,7 @@ extension ctlInputMethod {
if state.tooltip.isEmpty {
ctlInputMethod.tooltipInstance.hide()
} else {
let cursorReference: Int = {
if state.data.marker >= state.data.cursor { return state.data.u16Cursor }
return state.data.u16Marker //
}()
show(
tooltip: state.tooltip, displayedText: state.displayedText,
u16Cursor: cursorReference
)
show(tooltip: state.tooltip)
}
case .ofCandidates, .ofAssociates, .ofSymbolTable:
ctlInputMethod.tooltipInstance.hide()
@ -91,6 +81,14 @@ extension ctlInputMethod {
show(candidateWindowWith: state)
default: break
}
//
if state.hasComposition, mgrPrefs.clientsIMKTextInputIncapable.contains(clientBundleIdentifier) {
ctlInputMethod.popupCompositionBuffer.show(
state: state, at: lineHeightRect(zeroCursor: true).origin
)
} else {
ctlInputMethod.popupCompositionBuffer.hide()
}
}
/// .NotEmpty()
@ -109,7 +107,7 @@ extension ctlInputMethod {
/// 0 replacementRangeNSNotFound
///
client.setMarkedText(
state.attributedString, selectionRange: NSRange(location: state.data.u16Cursor, length: 0),
state.attributedString, selectionRange: NSRange(state.data.u16MarkedRange),
replacementRange: NSRange(location: NSNotFound, length: NSNotFound)
)
return

View File

@ -156,6 +156,12 @@ extension ctlInputMethod {
withTitle: NSLocalizedString("vChewing Preferences…", comment: ""),
action: #selector(showPreferences(_:)), keyEquivalent: ""
)
}
menu.addItem(
withTitle: NSLocalizedString("Client Manager", comment: "") + "",
action: #selector(showClientListMgr(_:)), keyEquivalent: ""
)
if !optionKeyPressed {
menu.addItem(
withTitle: NSLocalizedString("Check for Updates…", comment: ""),
action: #selector(checkForUpdate(_:)), keyEquivalent: ""
@ -208,6 +214,11 @@ extension ctlInputMethod {
NSWorkspace.shared.openFile(url.path, withApplication: "Safari")
}
@objc func showClientListMgr(_: Any?) {
(NSApp.delegate as? AppDelegate)?.showClientListMgr()
NSApp.activate(ignoringOtherApps: true)
}
@objc func toggleSCPCTypingMode(_: Any? = nil) {
resetKeyHandler()
NotifierController.notify(

View File

@ -348,3 +348,11 @@ extension NSApplication {
return output
}
}
// MARK: NSRect Extension
extension NSRect {
public static var seniorTheBeast: NSRect {
NSRect(x: 0.0, y: 0.0, width: 0.114, height: 0.514)
}
}

View File

@ -152,7 +152,7 @@ class UpdateSputnik: NSObject, URLSessionDataDelegate {
let content = NSLocalizedString(message, comment: "")
alert.messageText = NSLocalizedString("Update Check Failed", comment: "")
alert.informativeText = content
alert.addButton(withTitle: NSLocalizedString("Dismiss", comment: ""))
alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
alert.runModal()
NSApp.setActivationPolicy(.accessory)
}

View File

@ -56,6 +56,7 @@ public enum UserDef: String, CaseIterable {
case kHardenVerticalPunctuations = "HardenVerticalPunctuations"
case kTrimUnfinishedReadingsOnCommit = "TrimUnfinishedReadingsOnCommit"
case kAlwaysShowTooltipTextsHorizontally = "AlwaysShowTooltipTextsHorizontally"
case kClientsIMKTextInputIncapable = "ClientsIMKTextInputIncapable"
case kUseIMKCandidateWindow = "UseIMKCandidateWindow"
case kHandleDefaultCandidateFontsByLangIdentifier = "HandleDefaultCandidateFontsByLangIdentifier"
@ -306,6 +307,9 @@ public enum mgrPrefs {
UserDefaults.standard.setDefault(
mgrPrefs.trimUnfinishedReadingsOnCommit, forKey: UserDef.kTrimUnfinishedReadingsOnCommit.rawValue
)
UserDefaults.standard.setDefault(
mgrPrefs.clientsIMKTextInputIncapable, forKey: UserDef.kClientsIMKTextInputIncapable.rawValue
)
// -----
@ -443,6 +447,9 @@ public enum mgrPrefs {
@UserDefault(key: UserDef.kAlwaysShowTooltipTextsHorizontally.rawValue, defaultValue: false)
static var alwaysShowTooltipTextsHorizontally: Bool
@UserDefault(key: UserDef.kClientsIMKTextInputIncapable.rawValue, defaultValue: ["com.valvesoftware.steam"])
static var clientsIMKTextInputIncapable: [String]
// MARK: - Settings (Tier 2)
@UserDefault(key: UserDef.kUseIMKCandidateWindow.rawValue, defaultValue: false)
@ -738,6 +745,8 @@ extension mgrPrefs {
mgrPrefs.disableShiftTogglingAlphanumericalMode = false
mgrPrefs.togglingAlphanumericalModeWithLShift = false
}
//
clientsIMKTextInputIncapable = Array(Set(clientsIMKTextInputIncapable)).sorted()
//
var isMandarinParserOptionValid = false
MandarinParser.allCases.forEach {

View File

@ -160,7 +160,7 @@ public class ctlCandidate: NSWindowController, ctlCandidateProtocol {
var adjustedPoint = windowTopLeftPoint
var delta = heightDelta
var screenFrame = NSScreen.main?.visibleFrame ?? NSRect.zero
var screenFrame = NSScreen.main?.visibleFrame ?? NSRect.seniorTheBeast
for frame in NSScreen.screens.map(\.visibleFrame).filter({ !$0.contains(windowTopLeftPoint) }) {
screenFrame = frame
break

View File

@ -167,7 +167,7 @@ public class ctlCandidateIMK: IMKCandidates, ctlCandidateProtocol {
var adjustedPoint = windowTopLeftPoint
var adjustedHeight = height
var screenFrame = NSScreen.main?.visibleFrame ?? NSRect.zero
var screenFrame = NSScreen.main?.visibleFrame ?? NSRect.seniorTheBeast
for screen in NSScreen.screens {
let frame = screen.visibleFrame
if windowTopLeftPoint.x >= frame.minX, windowTopLeftPoint.x <= frame.maxX,

View File

@ -346,7 +346,7 @@ public class ctlCandidateUniversal: ctlCandidate {
let panel = NSPanel(
contentRect: contentRect, styleMask: styleMask, backing: .buffered, defer: false
)
panel.level = NSWindow.Level(Int(kCGPopUpMenuWindowLevel) + 1)
panel.level = NSWindow.Level(Int(kCGPopUpMenuWindowLevel) + 2)
panel.hasShadow = true
panel.isOpaque = false
panel.backgroundColor = NSColor.clear
@ -600,7 +600,7 @@ extension ctlCandidateUniversal {
pageCounterLabel.isHidden = true
}
frameRect = window?.frame ?? NSRect.zero
frameRect = window?.frame ?? NSRect.seniorTheBeast
let topLeftPoint = NSPoint(x: frameRect.origin.x, y: frameRect.origin.y + frameRect.size.height)
frameRect.size = newSize

View File

@ -90,7 +90,7 @@ public class NotifierController: NSWindowController, NotifierWindowDelegate {
}
private init() {
let screenRect = NSScreen.main?.visibleFrame ?? NSRect.zero
let screenRect = NSScreen.main?.visibleFrame ?? NSRect.seniorTheBeast
let contentRect = NSRect(x: 0, y: 0, width: kWindowWidth, height: kWindowHeight)
var windowRect = contentRect
windowRect.origin.x = screenRect.maxX - windowRect.width - 10
@ -144,8 +144,8 @@ public class NotifierController: NSWindowController, NotifierWindowDelegate {
return
}
let lastLocation = NotifierController.lastLocation
let screenRect = NSScreen.main?.visibleFrame ?? NSRect.zero
var windowRect = window?.frame ?? NSRect.zero
let screenRect = NSScreen.main?.visibleFrame ?? NSRect.seniorTheBeast
var windowRect = window?.frame ?? NSRect.seniorTheBeast
windowRect.origin.x = lastLocation.x
windowRect.origin.y = lastLocation.y - 10 - windowRect.height
@ -157,7 +157,7 @@ public class NotifierController: NSWindowController, NotifierWindowDelegate {
}
func moveIn() {
let afterRect = window?.frame ?? NSRect.zero
let afterRect = window?.frame ?? NSRect.seniorTheBeast
NotifierController.lastLocation = afterRect.origin
var beforeRect = afterRect
beforeRect.origin.y += 10

View File

@ -0,0 +1,127 @@
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
// ====================
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
// ... with NTL restriction stating that:
// No trademark license is granted to use the trade names, trademarks, service
// marks, or product names of Contributor, except as required to fulfill notice
// requirements defined in MIT License.
import Cocoa
public class ctlPopupCompositionBuffer: NSWindowController {
private var messageTextField: NSTextField
private var textShown: NSAttributedString = .init(string: "") {
didSet {
messageTextField.attributedStringValue = textShown
adjustSize()
}
}
public init() {
let transparentVisualEffect = NSVisualEffectView()
transparentVisualEffect.blendingMode = .behindWindow
transparentVisualEffect.state = .active
let contentRect = NSRect(x: 128.0, y: 128.0, width: 300.0, height: 20.0)
let styleMask: NSWindow.StyleMask = [.borderless, .nonactivatingPanel]
let panel = NSPanel(
contentRect: contentRect, styleMask: styleMask, backing: .buffered, defer: false
)
panel.contentView = transparentVisualEffect
panel.level = NSWindow.Level(Int(kCGPopUpMenuWindowLevel) + 1)
panel.hasShadow = true
panel.backgroundColor = NSColor.clear
messageTextField = NSTextField()
messageTextField.isEditable = false
messageTextField.isSelectable = false
messageTextField.isBezeled = false
messageTextField.textColor = NSColor.textColor
messageTextField.drawsBackground = true
messageTextField.backgroundColor = NSColor.clear
messageTextField.font = .systemFont(ofSize: 18)
panel.contentView?.addSubview(messageTextField)
super.init(window: panel)
}
@available(*, unavailable)
public required init?(coder _: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public func show(state: IMEStateProtocol, at point: NSPoint) {
if !state.hasComposition {
hide()
return
}
//
let attrString: NSMutableAttributedString = .init(string: state.data.displayedTextConverted)
attrString.setAttributes(
[
.backgroundColor: NSColor.alternateSelectedControlColor,
.foregroundColor: NSColor.alternateSelectedControlTextColor,
.markedClauseSegment: 0,
],
range: NSRange(
location: state.data.u16MarkedRange.lowerBound,
length: state.data.u16MarkedRange.upperBound - state.data.u16MarkedRange.lowerBound
)
)
let attrCursor = NSMutableAttributedString(string: "_")
if #available(macOS 10.13, *) {
attrCursor.setAttributes(
[
.kern: -18,
.baselineOffset: -2,
.markedClauseSegment: 1,
],
range: NSRange(location: 0, length: attrCursor.string.utf16.count)
)
}
attrString.insert(attrCursor, at: state.data.u16Cursor)
textShown = attrString
messageTextField.maximumNumberOfLines = 1
if let editor = messageTextField.currentEditor() {
editor.selectedRange = NSRange(state.data.u16MarkedRange)
}
window?.orderFront(nil)
set(windowOrigin: point)
}
public func hide() {
window?.orderOut(nil)
}
private func set(windowOrigin: NSPoint) {
guard let window = window else { return }
let windowSize = window.frame.size
var adjustedPoint = windowOrigin
var screenFrame = NSScreen.main?.visibleFrame ?? NSRect.seniorTheBeast
for frame in NSScreen.screens.map(\.visibleFrame).filter({ !$0.contains(windowOrigin) }) {
screenFrame = frame
break
}
adjustedPoint.y = min(max(adjustedPoint.y, screenFrame.minY + windowSize.height), screenFrame.maxY)
adjustedPoint.x = min(max(adjustedPoint.x, screenFrame.minX), screenFrame.maxX - windowSize.width)
window.setFrameOrigin(adjustedPoint)
}
private func adjustSize() {
let attrString = messageTextField.attributedStringValue
var rect = attrString.boundingRect(
with: NSSize(width: 1600.0, height: 1600.0),
options: [.usesLineFragmentOrigin, .usesFontLeading]
)
rect.size.width = max(rect.size.width, 20 * CGFloat(attrString.string.count)) + 2
rect.size.height = 22
var bigRect = rect
bigRect.size.width += NSFont.systemFontSize
bigRect.size.height += NSFont.systemFontSize
rect.origin.x += NSFont.systemFontSize / 2
rect.origin.y += NSFont.systemFontSize / 2
messageTextField.frame = rect
window?.setFrame(bigRect, display: true)
}
}

View File

@ -40,7 +40,7 @@ public class ctlTooltip: NSWindowController {
let panel = NSPanel(
contentRect: contentRect, styleMask: styleMask, backing: .buffered, defer: false
)
panel.level = NSWindow.Level(Int(kCGPopUpMenuWindowLevel) + 1)
panel.level = NSWindow.Level(Int(kCGPopUpMenuWindowLevel) + 2)
panel.hasShadow = true
panel.backgroundColor = NSColor.controlBackgroundColor
messageText = NSAttributedTextView()
@ -129,7 +129,7 @@ public class ctlTooltip: NSWindowController {
var adjustedPoint = windowTopLeftPoint
var delta = heightDelta
var screenFrame = NSScreen.main?.visibleFrame ?? NSRect.zero
var screenFrame = NSScreen.main?.visibleFrame ?? NSRect.seniorTheBeast
for frame in NSScreen.screens.map(\.visibleFrame).filter({ !$0.contains(windowTopLeftPoint) }) {
screenFrame = frame
break

View File

@ -1,4 +1,15 @@
"vChewing" = "vChewing";
"Please enter the client app bundle identifier(s) you want to register." = "Please enter the client app bundle identifier(s) you want to register.";
"One record per line. Use Option+Enter to break lines.\nBlank lines will be dismissed." = "One record per line. Use Option+Enter to break lines.\nBlank lines will be dismissed.";
"Just Select" = "Just Select";
"Client Manager" = "Client Manager";
"Please manage the list of IMKTextInput-incompatible clients here. Clients listed here will trigger vChewing's built-in popup composition buffer window with maximum 20 reading counts holdable." = "Please manage the list of IMKTextInput-incompatible clients here. Clients listed here will trigger vChewing's built-in popup composition buffer window with maximum 20 reading counts holdable.";
"Add Client" = "Add Client";
"Remove Selected" = "Remove Selected";
"Choose the target application bundle." = "Choose the target application bundle.";
"The selected item is not a valid macOS application bundle." = "The selected item is not a valid macOS application bundle.";
"Please try again." = "Please try again.";
"The selected item's identifier is already in the list." = "The selected item's identifier is already in the list.";
"Update Check Completed" = "Update Check Completed";
"You are already using the latest version." = "You are already using the latest version.";
"Plist downloaded is nil." = "Plist downloaded is nil.";
@ -17,7 +28,7 @@
"Update Check Failed" = "Update Check Failed";
"There may be no internet connection or the server failed to respond.\n\nError message: %@" = "There may be no internet connection or the server failed to respond.\n\nError message: %@";
"OK" = "OK";
"Dismiss" = "Dismiss";
"Cancel" = "Cancel";
"New Version Available" = "New Version Available";
"Not Now" = "Not Now";
"Visit Website" = "Visit Website";

View File

@ -1,4 +1,15 @@
"vChewing" = "vChewing";
"Please enter the client app bundle identifier(s) you want to register." = "Please enter the client app bundle identifier(s) you want to register.";
"One record per line. Use Option+Enter to break lines.\nBlank lines will be dismissed." = "One record per line. Use Option+Enter to break lines.\nBlank lines will be dismissed.";
"Just Select" = "Just Select";
"Client Manager" = "Client Manager";
"Please manage the list of IMKTextInput-incompatible clients here. Clients listed here will trigger vChewing's built-in popup composition buffer window with maximum 20 reading counts holdable." = "Please manage the list of IMKTextInput-incompatible clients here. Clients listed here will trigger vChewing's built-in popup composition buffer window with maximum 20 reading counts holdable.";
"Add Client" = "Add Client";
"Remove Selected" = "Remove Selected";
"Choose the target application bundle." = "Choose the target application bundle.";
"The selected item is not a valid macOS application bundle." = "The selected item is not a valid macOS application bundle.";
"Please try again." = "Please try again.";
"The selected item's identifier is already in the list." = "The selected item's identifier is already in the list.";
"Update Check Completed" = "Update Check Completed";
"You are already using the latest version." = "You are already using the latest version.";
"Plist downloaded is nil." = "Plist downloaded is nil.";
@ -17,7 +28,7 @@
"Update Check Failed" = "Update Check Failed";
"There may be no internet connection or the server failed to respond.\n\nError message: %@" = "There may be no internet connection or the server failed to respond.\n\nError message: %@";
"OK" = "OK";
"Dismiss" = "Dismiss";
"Cancel" = "Cancel";
"New Version Available" = "New Version Available";
"Not Now" = "Not Now";
"Visit Website" = "Visit Website";

View File

@ -1,4 +1,15 @@
"vChewing" = "威注音入力アプリ";
"Please enter the client app bundle identifier(s) you want to register." = "登録したい客体アプリの唯一識別子Bundle Identifierをご入力ください。";
"One record per line. Use Option+Enter to break lines.\nBlank lines will be dismissed." = "毎行はつ記録とみなす。Option+Enter キーで改行。\n空白の記録値は無視される。";
"Just Select" = "直接に選ぶ";
"Client Manager" = "客体アプリの管理";
"Please manage the list of IMKTextInput-incompatible clients here. Clients listed here will trigger vChewing's built-in popup composition buffer window with maximum 20 reading counts holdable." = "IMKTextInput 議定規約に従っていない客体アプリはここでご登録ください。登録済みのアプリは客体アプリ(文字入力を受くアプリ)とされた時に、威注音入力アプリは「吹き出し入力緩衝列ウィンドウ」と「緩衝列容量制限」を起用し、その容量制限は最大限音読み20箇とする。";
"Add Client" = "入れる";
"Remove Selected" = "外す";
"Choose the target application bundle." = "登録したいアプリのバンドルのお選びを。";
"The selected item is not a valid macOS application bundle." = "今選んだんのは正しい macOS アプリバンドルではないと考えられる。";
"Please try again." = "お選び直しください。";
"The selected item's identifier is already in the list." = "今選んだバンドルの唯一識別子Bundle Identifierは既に登録済みである。";
"Update Check Completed" = "新バージョンチェック完了";
"You are already using the latest version." = "現在稼働中のは最新バージョンである。";
"Plist downloaded is nil." = "受けた新バージョンお知らせ情報データは Plist ではないため、失敗とみなす。";
@ -17,7 +28,7 @@
"Update Check Failed" = "更新通知受信失敗";
"There may be no internet connection or the server failed to respond.\n\nError message: %@" = "ネットの接続の有無の問題か、サーバー側の反応の問題か。\n\nいずれにせよ、エラーメッセージ「%@」";
"OK" = "うむ";
"Dismiss" = "却下";
"Cancel" = "取り消す";
"New Version Available" = "最新版利用可能";
"Not Now" = "後で";
"Visit Website" = "公式サイト";

View File

@ -1,4 +1,15 @@
"vChewing" = "威注音输入法";
"Please enter the client app bundle identifier(s) you want to register." = "请键入您要登记的客体应用的唯一标帜Bundle Identifier。";
"One record per line. Use Option+Enter to break lines.\nBlank lines will be dismissed." = "每行一笔记录,用 Option+Enter 换行。\n空白值会被无视。";
"Just Select" = "直接选取";
"Client Manager" = "管理客体应用";
"Please manage the list of IMKTextInput-incompatible clients here. Clients listed here will trigger vChewing's built-in popup composition buffer window with maximum 20 reading counts holdable." = "请在此管理那些不遵守 IMKTextInput 协定的客体应用。威注音输入法对于任何位列在此的客体应用均启用浮动组字窗、且对组字区内容设定容量上限(最多二十个读音)。";
"Add Client" = "登记新客体";
"Remove Selected" = "移除所选条目";
"Choose the target application bundle." = "请选择要登记的应用程式的封包。";
"The selected item is not a valid macOS application bundle." = "当前所选之物并非 macOS 应用程式封包。";
"Please try again." = "请重试。";
"The selected item's identifier is already in the list." = "当前所选之封包的唯一标帜Bundle Identifier已被登记。";
"Update Check Completed" = "更新检查完毕";
"You are already using the latest version." = "您正在使用目前最新的发行版。";
"Plist downloaded is nil." = "下载来的更新资讯并非 Plist 档案。";
@ -17,7 +28,7 @@
"Update Check Failed" = "无法检查新版";
"There may be no internet connection or the server failed to respond.\n\nError message: %@" = "网路连线失败,或是伺服器没有回应。\n\n错误说明%@";
"OK" = "确定";
"Dismiss" = "关闭本视窗";
"Cancel" = "取消";
"New Version Available" = "有新版可下载";
"Not Now" = "以后再说";
"Visit Website" = "前往网站";

View File

@ -1,4 +1,15 @@
"vChewing" = "威注音輸入法";
"Please enter the client app bundle identifier(s) you want to register." = "請鍵入您要登記的客體應用的唯一標幟Bundle Identifier。";
"One record per line. Use Option+Enter to break lines.\nBlank lines will be dismissed." = "每行一筆記錄,用 Option+Enter 換行。\n空白值會被無視。";
"Just Select" = "直接選取";
"Client Manager" = "管理客體應用";
"Please manage the list of IMKTextInput-incompatible clients here. Clients listed here will trigger vChewing's built-in popup composition buffer window with maximum 20 reading counts holdable." = "請在此管理那些不遵守 IMKTextInput 協定的客體應用。威注音輸入法對於任何位列在此的客體應用均啟用浮動組字窗、且對組字區內容設定容量上限(最多二十個讀音)。";
"Add Client" = "登記新客體";
"Remove Selected" = "移除所選條目";
"Choose the target application bundle." = "請選擇要登記的應用程式的封包。";
"The selected item is not a valid macOS application bundle." = "當前所選之物並非 macOS 應用程式封包。";
"Please try again." = "請重試。";
"The selected item's identifier is already in the list." = "當前所選之封包的唯一標幟Bundle Identifier已被登記。";
"Update Check Completed" = "更新檢查完畢";
"You are already using the latest version." = "您正在使用目前最新的發行版。";
"Plist downloaded is nil." = "下載來的更新資訊並非 Plist 檔案。";
@ -17,7 +28,7 @@
"Update Check Failed" = "無法檢查新版";
"There may be no internet connection or the server failed to respond.\n\nError message: %@" = "網路連線失敗,或是伺服器沒有回應。\n\n錯誤說明%@";
"OK" = "確定";
"Dismiss" = "關閉本視窗";
"Cancel" = "取消";
"New Version Available" = "有新版可下載";
"Not Now" = "以後再說";
"Visit Website" = "前往網站";

View File

@ -1,5 +1,3 @@
// (c) 2011 and onwards The OpenVanilla Project (MIT License).
// All possible vChewing-specific modifications are of:
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
// ====================
// This code is released under the MIT license (SPDX-License-Identifier: MIT)

View File

@ -0,0 +1,167 @@
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
// ====================
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
// ... with NTL restriction stating that:
// No trademark license is granted to use the trade names, trademarks, service
// marks, or product names of Contributor, except as required to fulfill notice
// requirements defined in MIT License.
import Cocoa
class ctlClientListMgr: NSWindowController, NSTableViewDelegate, NSTableViewDataSource {
@IBOutlet var tblClients: NSTableView!
@IBOutlet var btnRemoveClient: NSButton!
@IBOutlet var btnAddClient: NSButton!
@IBOutlet var lblClientMgrWindow: NSTextField!
override func windowDidLoad() {
super.windowDidLoad()
localize()
tblClients.delegate = self
tblClients.dataSource = self
tblClients.reloadData()
}
}
// MARK: - Implementations
extension ctlClientListMgr {
func numberOfRows(in _: NSTableView) -> Int {
mgrPrefs.clientsIMKTextInputIncapable.count
}
func callAlert(_ window: NSWindow, title: String, text: String? = nil) {
let alert = NSAlert()
alert.messageText = title
if let text = text {
alert.informativeText = text
}
alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
alert.beginSheetModal(for: window)
}
@IBAction func btnAddClientClicked(_: Any) {
guard let window = window else { return }
let alert = NSAlert()
alert.messageText = NSLocalizedString(
"Please enter the client app bundle identifier(s) you want to register.", comment: ""
)
alert.informativeText = NSLocalizedString(
"One record per line. Use Option+Enter to break lines.\nBlank lines will be dismissed.", comment: ""
)
alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
alert.addButton(withTitle: NSLocalizedString("Just Select", comment: "") + "")
alert.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
let maxFloat = CGFloat(Float.greatestFiniteMagnitude)
let scrollview = NSScrollView(frame: NSRect(x: 0, y: 0, width: 370, height: 380))
let contentSize = scrollview.contentSize
scrollview.borderType = .noBorder
scrollview.hasVerticalScroller = true
scrollview.hasHorizontalScroller = true
scrollview.horizontalScroller?.scrollerStyle = .legacy
scrollview.verticalScroller?.scrollerStyle = .legacy
scrollview.autoresizingMask = [.width, .height]
let theTextView = NSTextView(frame: NSRect(x: 0, y: 0, width: contentSize.width, height: contentSize.height))
theTextView.minSize = NSSize(width: 0.0, height: contentSize.height)
theTextView.maxSize = NSSize(width: maxFloat, height: maxFloat)
theTextView.isVerticallyResizable = true
theTextView.isHorizontallyResizable = false
theTextView.autoresizingMask = .width
theTextView.textContainer?.containerSize = NSSize(width: contentSize.width, height: maxFloat)
theTextView.textContainer?.widthTracksTextView = true
scrollview.documentView = theTextView
theTextView.enclosingScrollView?.hasHorizontalScroller = true
theTextView.isHorizontallyResizable = true
theTextView.autoresizingMask = [.width, .height]
theTextView.textContainer?.containerSize = NSSize(width: maxFloat, height: maxFloat)
theTextView.textContainer?.widthTracksTextView = false
alert.accessoryView = scrollview
alert.beginSheetModal(for: window) { result in
switch result {
case .alertFirstButtonReturn:
theTextView.textContainer?.textView?.string.components(separatedBy: "\n").filter { !$0.isEmpty }.forEach {
self.applyNewValue($0)
}
case .alertSecondButtonReturn:
IME.dlgOpenPath.title = NSLocalizedString(
"Choose the target application bundle.", comment: ""
)
IME.dlgOpenPath.showsResizeIndicator = true
IME.dlgOpenPath.showsHiddenFiles = true
IME.dlgOpenPath.canChooseFiles = true
IME.dlgOpenPath.canChooseDirectories = false
IME.dlgOpenPath.beginSheetModal(for: window) { result in
switch result {
case .OK:
guard let url = IME.dlgOpenPath.url else { return }
var title = NSLocalizedString("The selected item is not a valid macOS application bundle.", comment: "")
let text = NSLocalizedString("Please try again.", comment: "")
guard let bundle = Bundle(url: url) else {
self.callAlert(window, title: title, text: text)
return
}
guard let identifier = bundle.bundleIdentifier else {
self.callAlert(window, title: title, text: text)
return
}
if mgrPrefs.clientsIMKTextInputIncapable.contains(identifier) {
title = NSLocalizedString(
"The selected item's identifier is already in the list.", comment: ""
)
self.callAlert(window, title: title)
return
}
self.applyNewValue(identifier)
default: return
}
}
default: return
}
}
}
private func applyNewValue(_ newValue: String) {
guard !newValue.isEmpty else { return }
var arrResult = mgrPrefs.clientsIMKTextInputIncapable
arrResult.append(newValue)
mgrPrefs.clientsIMKTextInputIncapable = arrResult.sorted()
tblClients.reloadData()
btnRemoveClient.isEnabled = (0..<mgrPrefs.clientsIMKTextInputIncapable.count).contains(
tblClients.selectedRow)
}
@IBAction func btnRemoveClientClicked(_: Any) {
if tblClients.selectedRow >= mgrPrefs.clientsIMKTextInputIncapable.count { return }
if tblClients.selectedRow < 0 { return }
let isLastRow: Bool = {
if mgrPrefs.clientsIMKTextInputIncapable.count < 2 { return false }
return tblClients.selectedRow == mgrPrefs.clientsIMKTextInputIncapable.count - 1
}()
mgrPrefs.clientsIMKTextInputIncapable.remove(at: tblClients.selectedRow)
if isLastRow {
tblClients.selectRowIndexes(.init(arrayLiteral: tblClients.selectedRow - 1), byExtendingSelection: false)
}
tblClients.reloadData()
btnRemoveClient.isEnabled = (0..<mgrPrefs.clientsIMKTextInputIncapable.count).contains(tblClients.selectedRow)
}
func tableView(_: NSTableView, objectValueFor _: NSTableColumn?, row: Int) -> Any? {
defer {
self.btnRemoveClient.isEnabled = (0..<mgrPrefs.clientsIMKTextInputIncapable.count).contains(
self.tblClients.selectedRow)
}
return mgrPrefs.clientsIMKTextInputIncapable[row]
}
private func localize() {
guard let window = window else { return }
window.title = NSLocalizedString("Client Manager", comment: "")
lblClientMgrWindow.stringValue = NSLocalizedString(
"Please manage the list of IMKTextInput-incompatible clients here. Clients listed here will trigger vChewing's built-in popup composition buffer window with maximum 20 reading counts holdable.",
comment: ""
)
btnAddClient.title = NSLocalizedString("Add Client", comment: "")
btnRemoveClient.title = NSLocalizedString("Remove Selected", comment: "")
}
}

View File

@ -55,7 +55,7 @@
</textField>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8M8-3C-BZO">
<rect key="frame" x="89" y="387" width="431" height="15"/>
<textFieldCell key="cell" selectable="YES" title="Placeholder for detailed credits." id="lblCredits">
<textFieldCell key="cell" title="Placeholder for detailed credits." id="lblCredits">
<font key="font" size="12" name="Tahoma"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
@ -77,7 +77,7 @@
<constraints>
<constraint firstAttribute="width" constant="356" id="B0d-48-3we"/>
</constraints>
<textFieldCell key="cell" selectable="YES" id="lblDisclaimer">
<textFieldCell key="cell" id="lblDisclaimer">
<font key="font" size="12" name="Tahoma"/>
<string key="title">DISCLAIMER: The vChewing project, having no relationship of cooperation or affiliation with the OpenVanilla project, is not responsible for the phrase database shipped in the original McBopomofo project. Certain geopolitical and ideological contents, which are potentially harmful to the global spread of this software, are not included in vChewing official phrase database.</string>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>

View File

@ -0,0 +1,133 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21225" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21225"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="ctlClientListMgr" customModule="vChewing" customModuleProvider="target">
<connections>
<outlet property="btnAddClient" destination="JcI-Ff-tDM" id="XbA-OK-zl8"/>
<outlet property="btnRemoveClient" destination="UNR-wG-8n1" id="vkb-81-1hA"/>
<outlet property="lblClientMgrWindow" destination="3ev-ns-FKY" id="VqL-RC-OdY"/>
<outlet property="tblClients" destination="vIw-vc-WKJ" id="2lw-U5-JAh"/>
<outlet property="window" destination="F0z-JX-Cv5" id="gIp-Ho-8D9"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="Client Manager" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" titlebarAppearsTransparent="YES" id="F0z-JX-Cv5">
<windowStyleMask key="styleMask" titled="YES" closable="YES" fullSizeContentView="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="664" height="335"/>
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1055"/>
<view key="contentView" id="se5-gp-TjO" customClass="NSVisualEffectView" customModule="vChewing" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="664" height="335"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="3ev-ns-FKY" userLabel="lblClientMgrWindow">
<rect key="frame" x="18" y="20" width="494" height="46"/>
<constraints>
<constraint firstAttribute="height" constant="46" id="HDu-vv-Kcv"/>
<constraint firstAttribute="width" constant="490" id="LhL-fH-PVL"/>
</constraints>
<textFieldCell key="cell" title="Placeholder for description texts." id="hvd-Wx-n7n">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<scrollView autohidesScrollers="YES" horizontalLineScroll="24" horizontalPageScroll="10" verticalLineScroll="24" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="MUP-Im-g6c">
<rect key="frame" x="20" y="76" width="624" height="232"/>
<clipView key="contentView" id="wKQ-IV-k62">
<rect key="frame" x="1" y="1" width="622" height="230"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" tableStyle="inset" multipleSelection="NO" autosaveColumns="NO" rowHeight="24" id="vIw-vc-WKJ" userLabel="tblClients">
<rect key="frame" x="0.0" y="0.0" width="622" height="230"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<size key="intercellSpacing" width="17" height="0.0"/>
<color key="backgroundColor" name="_sourceListBackgroundColor" catalog="System" colorSpace="catalog"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
<tableColumn identifier="AutomaticTableColumnIdentifier.0" width="590" minWidth="40" maxWidth="1000" id="kWw-Lj-EFx">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border">
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Text Cell" id="evF-0c-DTr">
<font key="font" metaFont="system" size="20"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
</tableColumn>
</tableColumns>
</tableView>
</subviews>
<nil key="backgroundColor"/>
</clipView>
<scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="6Wq-mB-m8K">
<rect key="frame" x="1" y="215" width="622" height="16"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="rYb-HR-4th">
<rect key="frame" x="224" y="17" width="15" height="102"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
</scrollView>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="qCN-8Z-3x3">
<rect key="frame" x="518" y="20" width="126" height="46"/>
<subviews>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="JcI-Ff-tDM" userLabel="btnAddClient">
<rect key="frame" x="-7" y="19" width="140" height="32"/>
<buttonCell key="cell" type="push" title="Add" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="7rO-JZ-kgV">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="btnAddClientClicked:" target="-2" id="klb-NT-gqr"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="UNR-wG-8n1" userLabel="btnRemoveClient">
<rect key="frame" x="-7" y="-7" width="140" height="32"/>
<buttonCell key="cell" type="push" title="Remove" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="wNc-xy-U4i">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="btnRemoveClientClicked:" target="-2" id="VbY-dw-fRP"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstItem="JcI-Ff-tDM" firstAttribute="trailing" secondItem="UNR-wG-8n1" secondAttribute="trailing" id="3Fe-KL-u9x"/>
<constraint firstAttribute="bottom" secondItem="UNR-wG-8n1" secondAttribute="bottom" id="5MS-Xg-KDM"/>
<constraint firstItem="JcI-Ff-tDM" firstAttribute="top" secondItem="qCN-8Z-3x3" secondAttribute="top" id="DZc-Jc-kVr"/>
<constraint firstAttribute="trailing" secondItem="JcI-Ff-tDM" secondAttribute="trailing" id="foA-xu-NF8"/>
<constraint firstItem="JcI-Ff-tDM" firstAttribute="leading" secondItem="UNR-wG-8n1" secondAttribute="leading" id="hOp-FU-UKN"/>
<constraint firstItem="JcI-Ff-tDM" firstAttribute="leading" secondItem="qCN-8Z-3x3" secondAttribute="leading" id="r1x-vo-9qt"/>
</constraints>
</customView>
</subviews>
<constraints>
<constraint firstItem="3ev-ns-FKY" firstAttribute="top" secondItem="MUP-Im-g6c" secondAttribute="bottom" constant="10" id="2tx-uw-Zdh"/>
<constraint firstAttribute="bottom" secondItem="3ev-ns-FKY" secondAttribute="bottom" constant="20" symbolic="YES" id="9KE-bP-0Yi"/>
<constraint firstItem="MUP-Im-g6c" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" constant="27" id="BkF-ED-Uva"/>
<constraint firstAttribute="trailing" secondItem="MUP-Im-g6c" secondAttribute="trailing" constant="20" symbolic="YES" id="E0U-Vh-g3t"/>
<constraint firstItem="MUP-Im-g6c" firstAttribute="trailing" secondItem="qCN-8Z-3x3" secondAttribute="trailing" id="TqZ-q6-quu"/>
<constraint firstItem="MUP-Im-g6c" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="20" symbolic="YES" id="WXt-cJ-HaW"/>
<constraint firstItem="3ev-ns-FKY" firstAttribute="top" secondItem="qCN-8Z-3x3" secondAttribute="top" id="b4O-RW-K56"/>
<constraint firstItem="MUP-Im-g6c" firstAttribute="leading" secondItem="3ev-ns-FKY" secondAttribute="leading" id="g8i-I5-2Dw"/>
<constraint firstItem="3ev-ns-FKY" firstAttribute="bottom" secondItem="qCN-8Z-3x3" secondAttribute="bottom" id="ktC-2I-aWz"/>
<constraint firstItem="qCN-8Z-3x3" firstAttribute="leading" secondItem="3ev-ns-FKY" secondAttribute="trailing" constant="8" symbolic="YES" id="opE-OC-8Dh"/>
</constraints>
</view>
<connections>
<outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
</connections>
<point key="canvasLocation" x="231" y="176.5"/>
</window>
</objects>
</document>

View File

@ -3,9 +3,9 @@
<plist version="1.0">
<dict>
<key>CFBundleShortVersionString</key>
<string>2.5.0</string>
<string>2.6.0</string>
<key>CFBundleVersion</key>
<string>2500</string>
<string>2600</string>
<key>UpdateInfoEndpoint</key>
<string>https://gitee.com/vchewing/vChewing-macOS/raw/main/Update-Info.plist</string>
<key>UpdateInfoSite</key>

View File

@ -32,6 +32,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
ctlAboutWindowInstance?.window?.center()
ctlAboutWindowInstance?.window?.orderFrontRegardless() //
ctlAboutWindowInstance?.window?.level = .statusBar
ctlAboutWindowInstance?.window?.titlebarAppearsTransparent = true
}
// Call the New About Window

View File

@ -55,7 +55,7 @@
</textField>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8M8-3C-BZO">
<rect key="frame" x="89" y="372" width="431" height="30"/>
<textFieldCell key="cell" selectable="YES" id="lblCredits">
<textFieldCell key="cell" id="lblCredits">
<font key="font" size="12" name="Tahoma"/>
<string key="title">vChewing Phrase Editor developed by Shiki Suen.
vChewing Phrase Database Maintained by Shiki Suen.</string>
@ -79,7 +79,7 @@ vChewing Phrase Database Maintained by Shiki Suen.</string>
<constraints>
<constraint firstAttribute="width" constant="356" id="B0d-48-3we"/>
</constraints>
<textFieldCell key="cell" selectable="YES" id="lblDisclaimer">
<textFieldCell key="cell" id="lblDisclaimer">
<font key="font" size="12" name="Tahoma"/>
<string key="title">DISCLAIMER: The vChewing project, having no relationship of cooperation or affiliation with the OpenVanilla project, is not responsible for the phrase database shipped in the original McBopomofo project. Certain geopolitical and ideological contents, which are potentially harmful to the global spread of this software, are not included in vChewing official phrase database.</string>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>

View File

@ -1,5 +1,3 @@
// (c) 2011 and onwards The OpenVanilla Project (MIT License).
// All possible vChewing-specific modifications are of:
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
// ====================
// This code is released under the MIT license (SPDX-License-Identifier: MIT)

View File

@ -726,7 +726,7 @@
<key>USE_HFS+_COMPRESSION</key>
<false/>
<key>VERSION</key>
<string>2.5.0</string>
<string>2.6.0</string>
</dict>
<key>TYPE</key>
<integer>0</integer>

View File

@ -9,6 +9,8 @@
/* Begin PBXBuildFile section */
5B09307628B6FC3B0021F8C5 /* shortcuts.html in Resources */ = {isa = PBXBuildFile; fileRef = 5B09307828B6FC3B0021F8C5 /* shortcuts.html */; };
5B0AF8B527B2C8290096FE54 /* StringExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B0AF8B427B2C8290096FE54 /* StringExtension.swift */; };
5B0EF55D28CDBF7100F8F7CE /* frmClientListMgr.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5B0EF55C28CDBF7100F8F7CE /* frmClientListMgr.xib */; };
5B0EF55F28CDBF8E00F8F7CE /* ctlClientListMgr.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B0EF55E28CDBF8E00F8F7CE /* ctlClientListMgr.swift */; };
5B11328927B94CFB00E58451 /* AppleKeyboardConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B11328827B94CFB00E58451 /* AppleKeyboardConverter.swift */; };
5B16B84C28C9A89000ABA692 /* FolderMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B16B84B28C9A89000ABA692 /* FolderMonitor.swift */; };
5B175FFB28C5CDDC0078D1B4 /* IMKHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B175FFA28C5CDDC0078D1B4 /* IMKHelper.swift */; };
@ -39,6 +41,7 @@
5B62A33D27AE7CC100A19448 /* ctlAboutWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A33C27AE7CC100A19448 /* ctlAboutWindow.swift */; };
5B62A34727AE7CD900A19448 /* ctlCandidate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A34027AE7CD900A19448 /* ctlCandidate.swift */; };
5B62A34A27AE7CD900A19448 /* NotifierController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B62A34527AE7CD900A19448 /* NotifierController.swift */; };
5B630A3C28CC97020010D076 /* ctlPopupCompositionBuffer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B630A3B28CC97020010D076 /* ctlPopupCompositionBuffer.swift */; };
5B6C141228A9D4B30098ADF8 /* ctlInputMethod_Common.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6C141128A9D4B30098ADF8 /* ctlInputMethod_Common.swift */; };
5B73FB5E27B2BE1300E9BF49 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5B73FB6027B2BE1300E9BF49 /* InfoPlist.strings */; };
5B782EC4280C243C007276DE /* KeyHandler_HandleCandidate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B782EC3280C243C007276DE /* KeyHandler_HandleCandidate.swift */; };
@ -210,6 +213,8 @@
5B09307B28B6FC410021F8C5 /* ja */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; lineEnding = 0; name = ja; path = ja.lproj/shortcuts.html; sourceTree = "<group>"; };
5B0AF8B427B2C8290096FE54 /* StringExtension.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = StringExtension.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
5B0C5EDF27C7D9870078037C /* dataCompiler.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = dataCompiler.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
5B0EF55C28CDBF7100F8F7CE /* frmClientListMgr.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = frmClientListMgr.xib; sourceTree = "<group>"; };
5B0EF55E28CDBF8E00F8F7CE /* ctlClientListMgr.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ctlClientListMgr.swift; sourceTree = "<group>"; };
5B11328827B94CFB00E58451 /* AppleKeyboardConverter.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = AppleKeyboardConverter.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
5B16B84B28C9A89000ABA692 /* FolderMonitor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FolderMonitor.swift; sourceTree = "<group>"; };
5B175FFA28C5CDDC0078D1B4 /* IMKHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IMKHelper.swift; sourceTree = "<group>"; };
@ -253,6 +258,7 @@
5B62A33C27AE7CC100A19448 /* ctlAboutWindow.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = ctlAboutWindow.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
5B62A34027AE7CD900A19448 /* ctlCandidate.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = ctlCandidate.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
5B62A34527AE7CD900A19448 /* NotifierController.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = NotifierController.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
5B630A3B28CC97020010D076 /* ctlPopupCompositionBuffer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ctlPopupCompositionBuffer.swift; sourceTree = "<group>"; };
5B65B919284D0185007C558B /* README-CHT.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = "README-CHT.md"; sourceTree = "<group>"; };
5B6C141128A9D4B30098ADF8 /* ctlInputMethod_Common.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ctlInputMethod_Common.swift; sourceTree = "<group>"; };
5B73FB5427B2BD6900E9BF49 /* PhraseEditor-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "PhraseEditor-Info.plist"; path = "UserPhraseEditor/PhraseEditor-Info.plist"; sourceTree = SOURCE_ROOT; };
@ -581,6 +587,7 @@
children = (
5B62A33E27AE7CD900A19448 /* CandidateUI */,
5B62A34427AE7CD900A19448 /* NotifierUI */,
5B630A3A28CC96D80010D076 /* PopupCompositionBufferUI */,
5BA9FD0927FED9F3002DE248 /* PrefUI */,
5B62A34227AE7CD900A19448 /* TooltipUI */,
);
@ -591,6 +598,7 @@
isa = PBXGroup;
children = (
5B62A33C27AE7CC100A19448 /* ctlAboutWindow.swift */,
5B0EF55E28CDBF8E00F8F7CE /* ctlClientListMgr.swift */,
D47F7DCD278BFB57002F9DD7 /* ctlPrefWindow.swift */,
);
path = WindowControllers;
@ -599,6 +607,7 @@
5B62A33B27AE7C7F00A19448 /* WindowNIBs */ = {
isa = PBXGroup;
children = (
5B0EF55C28CDBF7100F8F7CE /* frmClientListMgr.xib */,
5BBBB76927AED5DB0023B93A /* frmAboutWindow.xib */,
5B7BC4AE27AFFBE800F66C24 /* frmPrefWindow.xib */,
6A187E2816004C5900466B2E /* MainMenu.xib */,
@ -645,6 +654,14 @@
name = Data;
sourceTree = "<group>";
};
5B630A3A28CC96D80010D076 /* PopupCompositionBufferUI */ = {
isa = PBXGroup;
children = (
5B630A3B28CC97020010D076 /* ctlPopupCompositionBuffer.swift */,
);
path = PopupCompositionBufferUI;
sourceTree = "<group>";
};
5B84579B2871AD2200C93B01 /* HotenkaChineseConverter */ = {
isa = PBXGroup;
children = (
@ -1068,6 +1085,7 @@
D4E33D8A27A838CF006DB1CF /* Localizable.strings in Resources */,
5BF9DA2828840E6200DBD48E /* template-exclusions.txt in Resources */,
5B7DA80328BF6BC600D7B2AD /* fixinstall.sh in Resources */,
5B0EF55D28CDBF7100F8F7CE /* frmClientListMgr.xib in Resources */,
5BDCBB2E27B4E67A00D0CC59 /* vChewingPhraseEditor.app in Resources */,
5BBBB76027AED54C0023B93A /* Fart.m4a in Resources */,
6A2E40F6253A69DA00D1AE1D /* Images.xcassets in Resources */,
@ -1214,6 +1232,7 @@
5B5F8AEE28C8826D007C11F1 /* ctlTooltip.swift in Sources */,
5BD0113B28180D6100609769 /* LMInstantiator.swift in Sources */,
5B2170E7289FACAD00BE7304 /* 1_Compositor.swift in Sources */,
5B0EF55F28CDBF8E00F8F7CE /* ctlClientListMgr.swift in Sources */,
5B21177028753B9D000443A9 /* ctlInputMethod_Delegates.swift in Sources */,
5B21176E28753B35000443A9 /* ctlInputMethod_HandleDisplay.swift in Sources */,
5B84579F2871AD2200C93B01 /* HotenkaChineseConverter.swift in Sources */,
@ -1268,6 +1287,7 @@
5BA9FD1327FEDB6B002DE248 /* suiPrefPaneDictionary.swift in Sources */,
5B2170E8289FACAD00BE7304 /* 5_Vertex.swift in Sources */,
5BBBB77A27AEDC690023B93A /* clsSFX.swift in Sources */,
5B630A3C28CC97020010D076 /* ctlPopupCompositionBuffer.swift in Sources */,
5BA9FD4727FEF3C9002DE248 /* PreferencesStyleController.swift in Sources */,
5B949BDB2816DDBC00D87B5D /* LMConsolidator.swift in Sources */,
5BFDF011289635C100417BBC /* ctlCandidateIMK.swift in Sources */,
@ -1463,7 +1483,7 @@
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2500;
CURRENT_PROJECT_VERSION = 2600;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_PREPROCESSOR_DEFINITIONS = (
@ -1473,7 +1493,7 @@
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 2.5.0;
MARKETING_VERSION = 2.6.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewingTests;
@ -1502,13 +1522,13 @@
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2500;
CURRENT_PROJECT_VERSION = 2600;
ENABLE_NS_ASSERTIONS = NO;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 2.5.0;
MARKETING_VERSION = 2.6.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewingTests;
@ -1540,7 +1560,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 2500;
CURRENT_PROJECT_VERSION = 2600;
DEAD_CODE_STRIPPING = YES;
ENABLE_HARDENED_RUNTIME = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
@ -1562,7 +1582,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 2.5.0;
MARKETING_VERSION = 2.6.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewing.vChewingPhraseEditor;
@ -1592,7 +1612,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 2500;
CURRENT_PROJECT_VERSION = 2600;
DEAD_CODE_STRIPPING = YES;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_NS_ASSERTIONS = NO;
@ -1610,7 +1630,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 2.5.0;
MARKETING_VERSION = 2.6.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewing.vChewingPhraseEditor;
@ -1726,7 +1746,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 2500;
CURRENT_PROJECT_VERSION = 2600;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = "";
@ -1755,7 +1775,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 2.5.0;
MARKETING_VERSION = 2.6.0;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.inputmethod.vChewing;
PRODUCT_NAME = "$(TARGET_NAME)";
@ -1785,7 +1805,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 2500;
CURRENT_PROJECT_VERSION = 2600;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = "";
@ -1808,7 +1828,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 2.5.0;
MARKETING_VERSION = 2.6.0;
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.inputmethod.vChewing;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -1832,7 +1852,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 2500;
CURRENT_PROJECT_VERSION = 2600;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = "";
ENABLE_HARDENED_RUNTIME = YES;
@ -1853,7 +1873,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 2.5.0;
MARKETING_VERSION = 2.6.0;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewing.vChewingInstaller;
PRODUCT_NAME = "$(TARGET_NAME)";
@ -1876,7 +1896,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 2500;
CURRENT_PROJECT_VERSION = 2600;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = "";
ENABLE_HARDENED_RUNTIME = YES;
@ -1891,7 +1911,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 2.5.0;
MARKETING_VERSION = 2.6.0;
PRODUCT_BUNDLE_IDENTIFIER = org.atelierInmu.vChewing.vChewingInstaller;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";