diff --git a/mac/Config/Config.xcodeproj/project.pbxproj b/mac/Config/Config.xcodeproj/project.pbxproj index 1eb4f548bf..9522140b14 100644 --- a/mac/Config/Config.xcodeproj/project.pbxproj +++ b/mac/Config/Config.xcodeproj/project.pbxproj @@ -47,6 +47,11 @@ /* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ /* Begin PBXFileSystemSynchronizedRootGroup section */ + 3A589DC630539F2B00E2DD63 /* Resources */ = { + isa = PBXFileSystemSynchronizedRootGroup; + path = Resources; + sourceTree = ""; + }; D87D6F492FAF95400083A95E /* Installation */ = { isa = PBXFileSystemSynchronizedRootGroup; path = Installation; @@ -97,6 +102,7 @@ D88F03BD2F50ED5000C02A31 = { isa = PBXGroup; children = ( + 3A589DC630539F2B00E2DD63 /* Resources */, D8F10B613048F12A00C1E597 /* Localizable.xcstrings */, D87D6F492FAF95400083A95E /* Installation */, D88F03C82F50ED5000C02A31 /* Config */, @@ -139,6 +145,7 @@ dependencies = ( ); fileSystemSynchronizedGroups = ( + 3A589DC630539F2B00E2DD63 /* Resources */, D87D6F492FAF95400083A95E /* Installation */, D88F03C82F50ED5000C02A31 /* Config */, ); diff --git a/mac/Config/Config/About/AboutPanelView.swift b/mac/Config/Config/About/AboutPanelView.swift new file mode 100644 index 0000000000..fa28d0dac6 --- /dev/null +++ b/mac/Config/Config/About/AboutPanelView.swift @@ -0,0 +1,56 @@ +/* + * Keyman is copyright (C) SIL Global. MIT License. + * + * Created by Eli Schantz on 2026-07-23 + * + * View shown when About Keyman Configuration is selected from the menu. + */ + +import SwiftUI +import KeymanSettings + +struct AboutPanelView: View { + + var body: some View { + VStack(spacing: 20) { + HStack(alignment: .top, spacing: 28) { + Image(nsImage: NSApp.applicationIconImage) + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: 104, height: 104) + + VStack(alignment: .leading, spacing: 6) { + Text("Keyman Configuration") + .font(.system(size: 32, weight: .semibold)) + Text("Version \(ConfigAppUtil.configAppVersion())") + .font(.system(size: 13)) + .foregroundStyle(.secondary) + + Spacer(minLength: 14) + + Text("Copyright © SIL Global") + .font(.system(size: 11)) + .foregroundStyle(.secondary) + } + + Spacer(minLength: 0) + } + + HStack { + Spacer() + Button("License Agreement") { + if let url = Bundle.main.url(forResource: "keyman-for-mac-os-license", withExtension: "html") { + NSWorkspace.shared.open(url) + } + } + } + } + .padding(.top, 32) + .padding(.horizontal, 42) + .padding(.bottom, 20) + .frame(width: 570, height: 200) + } +} +#Preview { + AboutPanelView() +} diff --git a/mac/Config/Config/ConfigApp.swift b/mac/Config/Config/ConfigApp.swift index c462b15f60..1e902c9a0c 100644 --- a/mac/Config/Config/ConfigApp.swift +++ b/mac/Config/Config/ConfigApp.swift @@ -7,6 +7,7 @@ */ import SwiftUI +import AppKit import KeymanSettings import OSLog import Sentry @@ -61,6 +62,15 @@ struct ConfigApp: App { } .windowResizability(.contentSize) .defaultSize(width: 600, height: 500) + .commands { + CommandGroup(replacing: .appInfo) { + Button { + AboutPanelPresenter.showAboutPanel() + } label: { + Label("About Keyman Configuration", systemImage: "info.circle") + } + } + } // for testing purposes // Window("Install Test", id: "install-debug") { @@ -69,3 +79,35 @@ struct ConfigApp: App { // } } } + +@MainActor +private enum AboutPanelPresenter { + private static var aboutWindow: NSWindow? + + static func showAboutPanel() { + let contentView = AboutPanelView() + + let window = aboutWindow ?? makeAboutWindow() + window.contentView = NSHostingView(rootView: contentView) + window.center() + window.makeKeyAndOrderFront(nil) + aboutWindow = window + + NSApp.activate(ignoringOtherApps: true) + } + + private static func makeAboutWindow() -> NSWindow { + let window = NSWindow( + contentRect: NSRect(x: 0, y: 0, width: 570, height: 200), + styleMask: [.titled, .closable], + backing: .buffered, + defer: false + ) + + window.titleVisibility = .hidden + window.titlebarAppearsTransparent = true + window.isReleasedWhenClosed = false + window.backgroundColor = .windowBackgroundColor + return window + } +} diff --git a/mac/Config/Localizable.xcstrings b/mac/Config/Localizable.xcstrings index e2a2bea6b2..2c2735ae2e 100644 --- a/mac/Config/Localizable.xcstrings +++ b/mac/Config/Localizable.xcstrings @@ -1,6 +1,10 @@ { "sourceLanguage" : "en", "strings" : { + "About Keyman Configuration" : { + "comment" : "A label for the about panel.", + "isCommentAutoGenerated" : true + }, "Access has not been granted." : { }, @@ -30,6 +34,10 @@ }, "Copy link" : { + }, + "Copyright © SIL Global" : { + "comment" : "A copyright notice.", + "isCommentAutoGenerated" : true }, "Copyright:" : { @@ -78,6 +86,14 @@ }, "Keyboards" : { + }, + "Keyman Configuration" : { + "comment" : "The name of the app.", + "isCommentAutoGenerated" : true + }, + "License Agreement" : { + "comment" : "A button that opens a web page with the license agreement for Keyman for macOS.", + "isCommentAutoGenerated" : true }, "Missing Keyman Components" : { @@ -129,6 +145,10 @@ }, "To use Keyman, enable the Keyman input method in System Settings." : { + }, + "Version %@" : { + "comment" : "A description of the app, including its version and copyright.", + "isCommentAutoGenerated" : true }, "Website:" : { diff --git a/mac/Config/Resources/keyman-for-mac-os-license.html b/mac/Config/Resources/keyman-for-mac-os-license.html new file mode 100644 index 0000000000..feb7e7ac7e --- /dev/null +++ b/mac/Config/Resources/keyman-for-mac-os-license.html @@ -0,0 +1,123 @@ + + + + + + + + + + + + +
+ +

Keyman­® for macOS +End User Licence and Services Agreement

+ +

The MIT License

+

Copyright (c) 2017 SIL International

+

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

+

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

+ +

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ + + +
+ +

 

+ +
+ +
+ + + +