2.8.0 SP3 // NotifierUI optimization, etc. Merge PR #161 from upd/2.8.0sp3

This commit is contained in:
ShikiSuen 2022-10-01 12:43:57 +08:00 committed by GitHub
commit 2af9cdebe2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 57 additions and 35 deletions

View File

@ -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).

View File

@ -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())

View File

@ -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
}
}

View File

@ -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"),
]
)
]

View File

@ -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 {

View File

@ -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

View File

@ -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>

View File

@ -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;