2.8.0 SP3 // NotifierUI optimization, etc. Merge PR #161 from upd/2.8.0sp3
This commit is contained in:
commit
2af9cdebe2
|
@ -6,13 +6,10 @@
|
|||
|
||||
TDK 選字窗以純 SwiftUI 構築,用以取代此前自上游繼承來的 Voltaire 選字窗。
|
||||
|
||||
然而,TDK 選字窗目前有下述侷限:
|
||||
TDK 選字窗同時支援橫排矩陣佈局與縱排矩陣佈局。然而,目前有下述侷限:
|
||||
|
||||
- 因 SwiftUI 自身特性所導致的嚴重的效能問題。基本上來講,如果您經常使用全字庫模式的話,請在偏好設定內啟用效能更高的 IMK 選字窗。
|
||||
- 同樣出於上述原因,為了讓田所選字窗至少處於可在生產力環境下正常使用的狀態,就犧牲了捲動檢視的功能。也就是說,每次只顯示三行,但顯示內容則隨著使用者的游標操作而更新。
|
||||
- TDK 選字窗目前僅完成了橫版矩陣陳列模式的實作,且尚未引入對縱排選字窗陳列佈局的支援。
|
||||
|
||||
因為這些問題恐怕需要很久才能全部解決,所以威注音會在這段時間內推薦使用者們優先使用 IMK 選字窗。
|
||||
- 因 SwiftUI 自身特性所導致的嚴重的效能問題(可能只會在幾年前的老電腦上出現)。基本上來講,如果您經常使用全字庫模式的話,請在偏好設定內啟用效能更高的 IMK 選字窗。
|
||||
- 同樣出於上述原因,為了讓田所選字窗至少處於可在生產力環境下正常使用的狀態,就犧牲了捲動檢視的功能。也就是說,每次只顯示三行/三列,但顯示內容則隨著使用者的游標操作而更新。
|
||||
|
||||
```
|
||||
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
|
||||
|
|
|
@ -20,7 +20,7 @@ extension CandidateCellData {
|
|||
VStack(spacing: 0) {
|
||||
HStack(spacing: 4) {
|
||||
if UserDefaults.standard.bool(forKey: UserDef.kHandleDefaultCandidateFontsByLangIdentifier.rawValue) {
|
||||
Text(AttributedString(attributedStringHeader)).frame(width: CandidateCellData.unifiedSize / 2)
|
||||
Text(AttributedString(attributedStringHeader)).frame(width: CandidateCellData.unifiedSize * 2 / 3)
|
||||
Text(AttributedString(attributedString))
|
||||
} else {
|
||||
Text(key).font(.system(size: fontSizeKey).monospaced())
|
||||
|
|
|
@ -26,14 +26,14 @@ public class Notifier: NSWindowController {
|
|||
|
||||
// MARK: - Private Declarations
|
||||
|
||||
private static var instanceStack: [Notifier] = []
|
||||
private static var instanceSet: NSMutableOrderedSet = .init()
|
||||
private let blankValue = ""
|
||||
|
||||
@discardableResult private init(_ message: String) {
|
||||
currentMessage = message
|
||||
let rawMessage = message.replacingOccurrences(of: "\n", with: "")
|
||||
let isDuplicated: Bool = {
|
||||
if let firstInstanceExisted = Self.instanceStack.first {
|
||||
if let firstInstanceExisted = Self.instanceSet.firstNotifier {
|
||||
return message == firstInstanceExisted.currentMessage && firstInstanceExisted.isNew
|
||||
}
|
||||
return false
|
||||
|
@ -42,8 +42,16 @@ public class Notifier: NSWindowController {
|
|||
super.init(window: nil)
|
||||
return
|
||||
}
|
||||
// 剔除溢出的副本,讓 Swift 自動回收之。
|
||||
while Self.instanceSet.count > 3 {
|
||||
if let instanceToRemove = Self.instanceSet.lastNotifier {
|
||||
instanceToRemove.close()
|
||||
Self.instanceSet.remove(instanceToRemove)
|
||||
}
|
||||
}
|
||||
// 正式進入處理環節。
|
||||
defer { // 先讓新通知標記自此開始過 0.3 秒自動變為 false。
|
||||
defer {
|
||||
// 先讓新通知標記自此開始過 0.3 秒自動變為 false。
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
|
||||
self.isNew = false
|
||||
}
|
||||
|
@ -137,8 +145,8 @@ public class Notifier: NSWindowController {
|
|||
|
||||
extension Notifier {
|
||||
private func shiftExistingWindowPositions() {
|
||||
guard let window = window, !Self.instanceStack.isEmpty else { return }
|
||||
for theInstanceWindow in Self.instanceStack.compactMap(\.window) {
|
||||
guard let window = window else { return }
|
||||
Self.instanceSet.arrayOfWindows.forEach { theInstanceWindow in
|
||||
var theOrigin = theInstanceWindow.frame
|
||||
theOrigin.origin.y -= (10 + window.frame.height)
|
||||
theInstanceWindow.setFrame(theOrigin, display: true)
|
||||
|
@ -156,19 +164,30 @@ extension Notifier {
|
|||
}
|
||||
|
||||
private func display() {
|
||||
let existingInstanceArray = Self.instanceStack.compactMap(\.window)
|
||||
if !existingInstanceArray.isEmpty {
|
||||
existingInstanceArray.forEach {
|
||||
$0.alphaValue -= 0.1
|
||||
$0.contentView?.subviews.forEach { $0.alphaValue *= 0.5 }
|
||||
}
|
||||
Self.instanceSet.arrayOfWindows.forEach {
|
||||
$0.alphaValue -= 0.1
|
||||
$0.contentView?.subviews.forEach { $0.alphaValue *= 0.5 }
|
||||
}
|
||||
shiftExistingWindowPositions()
|
||||
fadeIn()
|
||||
Self.instanceStack.insert(self, at: 0)
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
|
||||
Self.instanceSet.insert(self, at: 0)
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1.3) {
|
||||
self.close()
|
||||
Self.instanceStack.removeAll(where: { $0.window == nil })
|
||||
Self.instanceSet.remove(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension NSMutableOrderedSet {
|
||||
fileprivate var arrayOfWindows: [NSWindow] { compactMap { ($0 as? Notifier)?.window } }
|
||||
|
||||
fileprivate var firstNotifier: Notifier? {
|
||||
for neta in self { if let result = neta as? Notifier { return result } }
|
||||
return nil
|
||||
}
|
||||
|
||||
fileprivate var lastNotifier: Notifier? {
|
||||
for neta in reversed { if let result = neta as? Notifier { return result } }
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,14 +14,14 @@ let package = Package(
|
|||
],
|
||||
dependencies: [
|
||||
.package(path: "../vChewing_CocoaExtension"),
|
||||
.package(path: "../vChewing_SwiftExtension")
|
||||
.package(path: "../vChewing_SwiftExtension"),
|
||||
],
|
||||
targets: [
|
||||
.target(
|
||||
name: "Shared",
|
||||
dependencies: [
|
||||
.product(name: "CocoaExtension", package: "vChewing_CocoaExtension"),
|
||||
.product(name: "SwiftExtension", package: "vChewing_SwiftExtension")
|
||||
.product(name: "SwiftExtension", package: "vChewing_SwiftExtension"),
|
||||
]
|
||||
)
|
||||
]
|
||||
|
|
|
@ -60,8 +60,14 @@ public class CandidateCellData: Hashable {
|
|||
let paraStyle = NSMutableParagraphStyle()
|
||||
paraStyle.setParagraphStyle(NSParagraphStyle.default)
|
||||
paraStyle.alignment = .natural
|
||||
let theFontForCandidateKey: NSFont = {
|
||||
if #available(macOS 10.15, *) {
|
||||
return NSFont.monospacedSystemFont(ofSize: size * 0.7, weight: .regular)
|
||||
}
|
||||
return NSFont.monospacedDigitSystemFont(ofSize: size * 0.7, weight: .regular)
|
||||
}()
|
||||
var attrKey: [NSAttributedString.Key: AnyObject] = [
|
||||
.font: NSFont.monospacedDigitSystemFont(ofSize: size * 0.7, weight: .regular),
|
||||
.font: theFontForCandidateKey,
|
||||
.paragraphStyle: paraStyleKey,
|
||||
]
|
||||
if isSelected {
|
||||
|
|
|
@ -43,8 +43,8 @@ extension SessionCtl {
|
|||
if PrefMgr.shared.showNotificationsWhenTogglingCapsLock {
|
||||
Notifier.notify(
|
||||
message: isCapsLockTurnedOn
|
||||
? "Caps Lock" + NSLocalizedString("Alphanumerical Input Mode", comment: "") + "\n" + status
|
||||
: NSLocalizedString("Chinese Input Mode", comment: "") + "\n" + status
|
||||
? "Caps Lock" + NSLocalizedString("Alphanumerical Input Mode", comment: "") + "\n" + status
|
||||
: NSLocalizedString("Chinese Input Mode", comment: "") + "\n" + status
|
||||
)
|
||||
}
|
||||
self.isASCIIMode = isCapsLockTurnedOn
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<key>CFBundleShortVersionString</key>
|
||||
<string>2.8.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>2802</string>
|
||||
<string>2803</string>
|
||||
<key>UpdateInfoEndpoint</key>
|
||||
<string>https://gitee.com/vchewing/vChewing-macOS/raw/main/Update-Info.plist</string>
|
||||
<key>UpdateInfoSite</key>
|
||||
|
|
|
@ -1262,7 +1262,7 @@
|
|||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 2802;
|
||||
CURRENT_PROJECT_VERSION = 2803;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
|
@ -1302,7 +1302,7 @@
|
|||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 2802;
|
||||
CURRENT_PROJECT_VERSION = 2803;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
|
@ -1341,7 +1341,7 @@
|
|||
CODE_SIGN_IDENTITY = "-";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 2802;
|
||||
CURRENT_PROJECT_VERSION = 2803;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
|
@ -1394,7 +1394,7 @@
|
|||
CODE_SIGN_IDENTITY = "-";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 2802;
|
||||
CURRENT_PROJECT_VERSION = 2803;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
|
@ -1529,7 +1529,7 @@
|
|||
CODE_SIGN_IDENTITY = "-";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 2802;
|
||||
CURRENT_PROJECT_VERSION = 2803;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_ASSET_PATHS = "";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
|
@ -1590,7 +1590,7 @@
|
|||
CODE_SIGN_IDENTITY = "-";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 2802;
|
||||
CURRENT_PROJECT_VERSION = 2803;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_ASSET_PATHS = "";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
|
@ -1638,7 +1638,7 @@
|
|||
CODE_SIGN_IDENTITY = "-";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 2802;
|
||||
CURRENT_PROJECT_VERSION = 2803;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
|
@ -1684,7 +1684,7 @@
|
|||
CODE_SIGN_IDENTITY = "-";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 2802;
|
||||
CURRENT_PROJECT_VERSION = 2803;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
|
|
Loading…
Reference in New Issue