├── Cartfile ├── Cartfile.resolved ├── Eikana ├── Assets.xcassets │ └── AppIcon.appiconset │ │ ├── icon_128x128.png │ │ ├── icon_256x256.png │ │ ├── icon_512x512.png │ │ ├── icon_128x128@2x.png │ │ ├── icon_256x256@2x.png │ │ ├── icon_512x512@2x.png │ │ └── Contents.json ├── toggleLaunchAtStartup.swift ├── PreferenceWindowController.swift ├── AppData.swift ├── MappingMenu.swift ├── KeyMapping.swift ├── Info.plist ├── ViewController.swift ├── MediaKeyEvent.swift ├── dsa_pub.pem ├── ExclusionAppsController.swift ├── KeyTextField.swift ├── ShortcutsController.swift ├── AppDelegate.swift ├── KeyboardShortcut.swift ├── KeyEvent.swift └── ja.lproj │ └── Main.strings ├── Eikana.xcodeproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── project.pbxproj ├── Eikana-helper ├── main.m ├── AppDelegate.h ├── Info.plist ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── AppDelegate.m └── Base.lproj │ └── MainMenu.xib ├── LICENSE ├── docs └── appcast.xml ├── README.md └── .gitignore /Cartfile: -------------------------------------------------------------------------------- 1 | github "sparkle-project/Sparkle" 2 | -------------------------------------------------------------------------------- /Cartfile.resolved: -------------------------------------------------------------------------------- 1 | github "sparkle-project/Sparkle" "1.17.0" 2 | -------------------------------------------------------------------------------- /Eikana/Assets.xcassets/AppIcon.appiconset/icon_128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Imagine/cmd-eikana/master/Eikana/Assets.xcassets/AppIcon.appiconset/icon_128x128.png -------------------------------------------------------------------------------- /Eikana/Assets.xcassets/AppIcon.appiconset/icon_256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Imagine/cmd-eikana/master/Eikana/Assets.xcassets/AppIcon.appiconset/icon_256x256.png -------------------------------------------------------------------------------- /Eikana/Assets.xcassets/AppIcon.appiconset/icon_512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Imagine/cmd-eikana/master/Eikana/Assets.xcassets/AppIcon.appiconset/icon_512x512.png -------------------------------------------------------------------------------- /Eikana/Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Imagine/cmd-eikana/master/Eikana/Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.png -------------------------------------------------------------------------------- /Eikana/Assets.xcassets/AppIcon.appiconset/icon_256x256@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Imagine/cmd-eikana/master/Eikana/Assets.xcassets/AppIcon.appiconset/icon_256x256@2x.png -------------------------------------------------------------------------------- /Eikana/Assets.xcassets/AppIcon.appiconset/icon_512x512@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Imagine/cmd-eikana/master/Eikana/Assets.xcassets/AppIcon.appiconset/icon_512x512@2x.png -------------------------------------------------------------------------------- /Eikana.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Eikana-helper/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // cmd-eikana-helper 4 | // 5 | // Created by 岩田将成 on 2016/10/01. 6 | // Copyright © 2016年 eikana. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, const char * argv[]) { 12 | return NSApplicationMain(argc, argv); 13 | } 14 | -------------------------------------------------------------------------------- /Eikana-helper/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // cmd-eikana-helper 4 | // 5 | // Created by 岩田将成 on 2016/10/01. 6 | // Copyright © 2016年 eikana. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : NSObject 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /Eikana/toggleLaunchAtStartup.swift: -------------------------------------------------------------------------------- 1 | // 2 | // toggleLaunchAtStartup.swift 3 | // ⌘英かな 4 | // 5 | // MIT License 6 | // Copyright (c) 2016 iMasanari 7 | // 8 | 9 | // ログイン項目に追加、またはそこから削除するための関数 10 | 11 | import Cocoa 12 | import ServiceManagement 13 | 14 | func setLaunchAtStartup(_ enabled: Bool) { 15 | let appBundleIdentifier = "io.github.imasanari.cmd-eikana-helper" 16 | 17 | if SMLoginItemSetEnabled(appBundleIdentifier as CFString, enabled) { 18 | if enabled { 19 | print("Successfully add login item.") 20 | } else { 21 | print("Successfully remove login item.") 22 | } 23 | } else { 24 | print("Failed to add login item.") 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Eikana/PreferenceWindowController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PreferenceWindowController.swift 3 | // ⌘英かな 4 | // 5 | // MIT License 6 | // Copyright (c) 2016 iMasanari 7 | // 8 | 9 | import Cocoa 10 | 11 | class PreferenceWindowController: NSWindowController, NSWindowDelegate { 12 | static func getInstance() -> PreferenceWindowController { 13 | let storyboard = NSStoryboard(name: "Main", bundle: nil) 14 | let controller = storyboard.instantiateController(withIdentifier: "Preference") as! PreferenceWindowController 15 | 16 | controller.window?.title = "Eikana" 17 | 18 | return controller 19 | } 20 | 21 | func showAndActivate(_ sender: AnyObject?) { 22 | self.showWindow(sender) 23 | self.window?.makeKeyAndOrderFront(sender) 24 | NSApp.activate(ignoringOtherApps: true) 25 | } 26 | override func mouseDown(with event: NSEvent) { 27 | activeKeyTextField?.blur() 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Eikana/AppData.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppData.swift 3 | // ⌘英かな 4 | // 5 | // MIT License 6 | // Copyright (c) 2016 iMasanari 7 | // 8 | 9 | import Cocoa 10 | 11 | class AppData : NSObject { 12 | var name: String 13 | var id: String 14 | 15 | init(name: String, id: String) { 16 | self.name = name 17 | self.id = id 18 | 19 | super.init() 20 | } 21 | 22 | override init() { 23 | self.name = "" 24 | self.id = "" 25 | 26 | super.init() 27 | } 28 | 29 | init?(dictionary : [AnyHashable: Any]) { 30 | if let name = dictionary["name"] as? String, let id = dictionary["id"] as? String { 31 | self.name = name 32 | self.id = id 33 | 34 | super.init() 35 | } 36 | else { 37 | return nil 38 | } 39 | } 40 | 41 | func toDictionary() -> [AnyHashable: Any] { 42 | return [ 43 | "name": self.name, 44 | "id": self.id 45 | ] 46 | } 47 | } 48 | 49 | 50 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 iMasanari 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Eikana-helper/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | LSUIElement 26 | 27 | NSHumanReadableCopyright 28 | Copyright © 2016年 eikana. All rights reserved. 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /docs/appcast.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Eikana Changelog 5 | https://imasanari.github.io/cmd-eikana/appcast.xml 6 | Eikana update Changelog. 7 | en 8 | 9 | Eikana v2.2.2 10 | 11 |
  • Use Sparkle for update.
  • 13 | ]]> 14 |
    15 | Sun Feb 26 2017 10:10:00 GMT+0900 (JST) 16 | 22 |
    23 |
    24 |
    25 | -------------------------------------------------------------------------------- /Eikana-helper/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /Eikana/MappingMenu.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MappingMenu.swift 3 | // ⌘英かな 4 | // 5 | // MIT License 6 | // Copyright (c) 2016 iMasanari 7 | // 8 | 9 | import Cocoa 10 | 11 | class MappingMenu: NSPopUpButton { 12 | var row: Int? = nil 13 | 14 | func up() { 15 | if let row = self.row, row - 1 != -1 { 16 | let keyMapping = keyMappingList[row] 17 | 18 | keyMappingList[row] = keyMappingList[row - 1] 19 | keyMappingList[row - 1] = keyMapping 20 | } 21 | } 22 | func move(_ at: Int) { 23 | var at = at 24 | if let row = self.row { 25 | let keyMapping = keyMappingList[row] 26 | 27 | if at < 0 { 28 | at = 0 29 | } 30 | else if at > keyMappingList.count - 1 { 31 | at = keyMappingList.count - 1 32 | } 33 | 34 | keyMappingList.remove(at: row) 35 | keyMappingList.insert(keyMapping, at: at) 36 | } 37 | } 38 | func down() { 39 | if let row = self.row, row + 1 != keyMappingList.count { 40 | let keyMapping = keyMappingList[row] 41 | 42 | keyMappingList[row] = keyMappingList[row + 1] 43 | keyMappingList[row + 1] = keyMapping 44 | } 45 | } 46 | func remove() { 47 | keyMappingList.remove(at: self.row!) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Eikana-helper/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // cmd-eikana-helper 4 | // 5 | // Created by 岩田将成 on 2016/10/01. 6 | // Copyright © 2016年 eikana. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @property (weak) IBOutlet NSWindow *window; 14 | @end 15 | 16 | @implementation AppDelegate 17 | 18 | - (void)applicationDidFinishLaunching:(NSNotification *)aNotification 19 | { 20 | // Check whether the main application is running and active 21 | BOOL running = NO; 22 | BOOL active = NO; 23 | 24 | NSArray *applications = [NSRunningApplication runningApplicationsWithBundleIdentifier: @"io.github.imasanari.cmd-eikana"]; 25 | if (applications.count > 0) { 26 | NSRunningApplication *application = [applications firstObject]; 27 | 28 | running = YES; 29 | active = [application isActive]; 30 | } 31 | 32 | if (!running && !active) { 33 | // Launch main application 34 | NSURL *applicationURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@://", @"io.github.imasanari.cmd-eikana"]]; 35 | [[NSWorkspace sharedWorkspace] openURL:applicationURL]; 36 | } 37 | 38 | // Quit 39 | [NSApp terminate:nil]; 40 | } 41 | 42 | 43 | - (void)applicationWillTerminate:(NSNotification *)aNotification { 44 | // Insert code here to tear down your application 45 | } 46 | 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /Eikana/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "size" : "128x128", 25 | "idiom" : "mac", 26 | "filename" : "icon_128x128.png", 27 | "scale" : "1x" 28 | }, 29 | { 30 | "size" : "128x128", 31 | "idiom" : "mac", 32 | "filename" : "icon_128x128@2x.png", 33 | "scale" : "2x" 34 | }, 35 | { 36 | "size" : "256x256", 37 | "idiom" : "mac", 38 | "filename" : "icon_256x256.png", 39 | "scale" : "1x" 40 | }, 41 | { 42 | "size" : "256x256", 43 | "idiom" : "mac", 44 | "filename" : "icon_256x256@2x.png", 45 | "scale" : "2x" 46 | }, 47 | { 48 | "size" : "512x512", 49 | "idiom" : "mac", 50 | "filename" : "icon_512x512.png", 51 | "scale" : "1x" 52 | }, 53 | { 54 | "size" : "512x512", 55 | "idiom" : "mac", 56 | "filename" : "icon_512x512@2x.png", 57 | "scale" : "2x" 58 | } 59 | ], 60 | "info" : { 61 | "version" : 1, 62 | "author" : "xcode" 63 | } 64 | } -------------------------------------------------------------------------------- /Eikana/KeyMapping.swift: -------------------------------------------------------------------------------- 1 | // 2 | // KeyMapping.swift 3 | // ⌘英かな 4 | // 5 | // MIT License 6 | // Copyright (c) 2016 iMasanari 7 | // 8 | 9 | import Cocoa 10 | 11 | class KeyMapping : NSObject { 12 | var input: KeyboardShortcut 13 | var output: KeyboardShortcut 14 | var enable: Bool 15 | 16 | init(input: KeyboardShortcut, output: KeyboardShortcut, enable: Bool = true) { 17 | self.input = input 18 | self.output = output 19 | self.enable = enable 20 | 21 | super.init() 22 | } 23 | 24 | override init() { 25 | input = KeyboardShortcut() 26 | output = KeyboardShortcut() 27 | self.enable = true 28 | super.init() 29 | } 30 | 31 | init?(dictionary : [AnyHashable: Any]) { 32 | if let inputKeyDic = dictionary["input"] as? [AnyHashable: Any], 33 | let inputKey = KeyboardShortcut(dictionary: inputKeyDic), 34 | let outputKeyDic = dictionary["output"] as? [AnyHashable: Any], 35 | let outputKey = KeyboardShortcut(dictionary: outputKeyDic), 36 | let enable = dictionary["enable"] as? Bool { 37 | 38 | self.input = inputKey 39 | self.output = outputKey 40 | self.enable = enable 41 | 42 | super.init() 43 | } 44 | 45 | else { 46 | return nil 47 | } 48 | } 49 | 50 | func toDictionary() -> [AnyHashable: Any] { 51 | return [ 52 | "input": input.toDictionary(), 53 | "output": output.toDictionary(), 54 | "enable": enable 55 | ] 56 | } 57 | } 58 | 59 | -------------------------------------------------------------------------------- /Eikana/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 2.2.2 21 | CFBundleSignature 22 | ???? 23 | CFBundleURLTypes 24 | 25 | 26 | CFBundleTypeRole 27 | Editor 28 | CFBundleURLName 29 | io.github.imasanari.cmd-eikana 30 | CFBundleURLSchemes 31 | 32 | io.github.imasanari.cmd-eikana 33 | 34 | 35 | 36 | CFBundleVersion 37 | 2.2.2 38 | LSMinimumSystemVersion 39 | $(MACOSX_DEPLOYMENT_TARGET) 40 | LSUIElement 41 | 42 | NSHumanReadableCopyright 43 | Copyright (c) 2016 iMasanari 44 | NSMainStoryboardFile 45 | Main 46 | NSPrincipalClass 47 | NSApplication 48 | SUFeedURL 49 | https://imasanari.github.io/cmd-eikana/appcast.xml 50 | SUPublicDSAKeyFile 51 | dsa_pub.pem 52 | 53 | 54 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Eikana (⌘英かな) 2 | This application switches alphanumeric / kana when pushing left and right command keys. 3 | It can also be used as a key remapping application that works even with macOS Sierra by fiddling with settings in the preferences window. 4 | 5 | ## Download 6 | Download latest release at https://ei-kana.appspot.com 7 | 8 | ## How to use (at first launch) 9 | ⌘ Open the .app. Since it is unsigned, please open it by right clicking and choosing "Open". 10 | The app will display a confirmation dialog for accessibility functions, click on "Open" System Preferences ". Please click on the key in the lower left to unlock and mark ⌘ (Eikana) app as checked. 11 | 12 | ## How to Quit 13 | Open the "⌘" icon in the status bar at the top right and select "Quit". 14 | 15 | ## How to uninstall 16 | 17 | ⌘ Drag app to the trash 18 | Also, the configuration file is located at ~ / Library / Preferences / io.github.imasanari.cmd - eikana.plist. If you want to erase cleanly please also put this in the garbage can. 19 | 20 | ## Tested for compatibilitywith 21 | - OS X El Capitan 10.11.5 22 | - Mac OS Sierra 10.12 23 | 24 | ## License 25 | MIT License 26 | 27 | 28 | # ⌘英かな 29 | 30 | 左右のコマンドキーを単体で押した時に英数/かなを切り替えるようにするアプリです。 31 | 設定をいじることでmacOS Sierraでも動くキーリマップアプリとしても利用できます。 32 | 33 | ## ダウンロード 34 | https://ei-kana.appspot.com/ 35 | ここからダウンロードしてください 36 | 37 | ## 使い方(初回起動時) 38 | 39 | ⌘英かな.appを起動させます。未署名ですので[右クリック操作](https://support.apple.com/ja-jp/HT202491)で開いてください。 40 | アクセシビリティ機能へのアクセスの確認ダイアログが表示されるので「"システム環境設定"を開く」をクリックします。 41 | 左下の鍵をクリックして解除し、⌘英かな.appにチェックを入れてください。 42 | 43 | ## 終了方法 44 | 45 | 右上のステータスバーにある「⌘」アイコンを開き、「Quit」を選びます。 46 | 47 | ## アンインストール方法 48 | 49 | ⌘英かな.appをゴミ箱に入れてください。 50 | また、設定ファイルが`~/Library/Preferences/io.github.imasanari.cmd-eikana.plist`にあります。 51 | 綺麗さっぱり消したいという場合はこちらもゴミ箱に入れてください。 52 | 53 | ## 動作確認 54 | 55 | - OS X El Capitan 10.11.5 56 | - mac OS Sierra 10.12 57 | 58 | ## ライセンス 59 | MIT License 60 | -------------------------------------------------------------------------------- /Eikana/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // ⌘英かな 4 | // 5 | // MIT License 6 | // Copyright (c) 2016 iMasanari 7 | // 8 | 9 | import Cocoa 10 | 11 | class ViewController: NSViewController, NSTableViewDataSource, NSTableViewDelegate { 12 | let userDefaults = UserDefaults.standard 13 | 14 | @IBOutlet weak var showIcon: NSButton! 15 | @IBOutlet weak var lunchAtStartup: NSButton! 16 | @IBOutlet weak var checkUpdateAtlaunch: NSButton! 17 | 18 | override func viewDidLoad() { 19 | super.viewDidLoad() 20 | // Do any additional setup after loading the view. 21 | 22 | let showIconState = userDefaults.object(forKey: "showIcon") 23 | showIcon.state = showIconState == nil ? 1 : showIconState as! Int 24 | 25 | if #available(OSX 10.12, *) { 26 | } else { 27 | showIcon.title += "(macOS Sierraのみ)" 28 | showIcon.isEnabled = false 29 | } 30 | 31 | lunchAtStartup.state = userDefaults.integer(forKey: "lunchAtStartup") 32 | checkUpdateAtlaunch.state = userDefaults.integer(forKey: "checkUpdateAtlaunch") 33 | } 34 | 35 | override var representedObject: Any? { 36 | didSet { 37 | // Update the view, if already loaded. 38 | } 39 | } 40 | 41 | @available(OSX 10.12, *) 42 | @IBAction func clickShowIcon(_ sender: AnyObject) { 43 | statusItem.isVisible = (showIcon.state == NSOnState) 44 | userDefaults.set(showIcon.state, forKey: "showIcon") 45 | } 46 | @IBAction func clickLunchAtStartup(_ sender: AnyObject) { 47 | setLaunchAtStartup(lunchAtStartup.state == NSOnState) 48 | userDefaults.set(lunchAtStartup.state, forKey: "lunchAtStartup") 49 | } 50 | @IBAction func clickCheckUpdateAtlaunch(_ sender: AnyObject) { 51 | userDefaults.set(checkUpdateAtlaunch.state, forKey: "checkUpdateAtlaunch") 52 | } 53 | } 54 | 55 | -------------------------------------------------------------------------------- /Eikana/MediaKeyEvent.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MediaKeyEvent.swift 3 | // ⌘英かな 4 | // 5 | // MIT License 6 | // Copyright (c) 2016 iMasanari 7 | // 8 | 9 | import Cocoa 10 | 11 | class MediaKeyEvent: NSObject { 12 | let event: CGEvent 13 | let nsEvent: NSEvent 14 | 15 | var keyCode: Int 16 | var flags: CGEventFlags 17 | var keyDown: Bool 18 | 19 | init?(_ event: CGEvent) { 20 | if event.type.rawValue != UInt32(NX_SYSDEFINED) { 21 | return nil 22 | } 23 | 24 | if let nsEvent = NSEvent(cgEvent: event), nsEvent.subtype.rawValue == 8 { 25 | self.nsEvent = nsEvent 26 | } 27 | else { 28 | return nil 29 | } 30 | 31 | self.event = event 32 | keyCode = (nsEvent.data1 & 0xffff0000) >> 16 33 | flags = event.flags 34 | keyDown = ((nsEvent.data1 & 0xff00) >> 8) == 0xa 35 | 36 | super.init() 37 | } 38 | } 39 | 40 | let mediaKeyDic = [ 41 | NX_KEYTYPE_SOUND_UP: "Sound_up", 42 | NX_KEYTYPE_SOUND_DOWN: "Sound_down", 43 | NX_KEYTYPE_BRIGHTNESS_UP: "Brightness_up", 44 | NX_KEYTYPE_BRIGHTNESS_DOWN: "Brightness_down", 45 | NX_KEYTYPE_CAPS_LOCK: "CapsLock", 46 | NX_KEYTYPE_HELP: "HELP", 47 | NX_POWER_KEY: "PowerKey", 48 | NX_KEYTYPE_MUTE: "mute", 49 | NX_KEYTYPE_NUM_LOCK: "NUM_LOCK", 50 | NX_KEYTYPE_CONTRAST_UP: "CONTRAST_UP", 51 | NX_KEYTYPE_CONTRAST_DOWN: "CONTRAST_DOWN", 52 | NX_KEYTYPE_LAUNCH_PANEL: "LAUNCH_PANEL", 53 | NX_KEYTYPE_EJECT: "EJECT", 54 | NX_KEYTYPE_VIDMIRROR: "VIDMIRROR", 55 | NX_KEYTYPE_PLAY: "Play", 56 | NX_KEYTYPE_NEXT: "NEXT", 57 | NX_KEYTYPE_PREVIOUS: "PREVIOUS", 58 | NX_KEYTYPE_FAST: "Fast", 59 | NX_KEYTYPE_REWIND: "Rewind", 60 | NX_KEYTYPE_ILLUMINATION_UP: "Illumination_up", 61 | NX_KEYTYPE_ILLUMINATION_DOWN: "Illumination_down", 62 | NX_KEYTYPE_ILLUMINATION_TOGGLE: "ILLUMINATION_TOGGLE" 63 | ] 64 | -------------------------------------------------------------------------------- /Eikana/dsa_pub.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIGOjCCBC0GByqGSM44BAEwggQgAoICAQDGmtouPRa3YlJmKmjTK/qSZORB3rIS 3 | o03NU/AIvheGP4nWPzQ9oaRHcTs+xw1EcBq4leGwSBe1uD7fCuzAaPqYCIEqUWxf 4 | RAlDUWCa2IwFcEqBf35hdw/QEbUYy4c9s/un8pLzzJgSKSWEZFaaTVtuhpTTocdh 5 | RzPcwmMzON/o9rS9ytP40xjgwb4qpCGOVhr4Wu4ffPUkxAWONUxr6ILXQA7GlW3w 6 | GRUgB5FvYi2Ng5mwLIhvPg6hOv1HAm2dieBcWBVu+vGSLH5ar1xqq7oTpcSigOnW 7 | 7Nf9KIoRAEXEq2QoZdbQ02JNpB4su+JLRBmbA1yyCoujON4bVaf+E43fAUAhzBua 8 | 16+k57c08HctgcSuPO2MKaSYUiY1W8VuZA0BfjDmJrkRqRgphO5Zz9OCyrRT1Yws 9 | ifKQOnS4uVqzfsU6tvwrXdqEbUw8pHltosoSpVLGujbzDl96n7B4JbmKozaRNLOT 10 | dPi1Xw6SQZbvp5fJ/bO3cUMyE74eoZwJGSoKXHBhILEDuVkeBJj+G6wOH5kQGXc8 11 | mgdT1yMSKB6wwL1i7D8Bhbhg0OfITSLlCEcS5lPOtH1WZ/3o/iYCRhghLgi1vBBR 12 | zE+J9I07ANhQGsVSYj06ey4gyC6iFF+kC22qt/HeoOOLOhRKFploMIflLwgLg6f8 13 | 2neM6kvFyCdCKwIVAMTqPCOgsCZrsSDhBA0aFlxO9+PrAoICADsclHLV0CNo6jYQ 14 | pAMXG71QTMd/4sEDVyxCYAyNMbD+PwdVAU+LHD+p+LOPF35xHh1Wat4SvARqKgov 15 | PpzN2GdXlTjGO8o6a3HWU6jcb0b1uP0Aspy9Q192yWF2Ux1UcPfFub1qL57eMZ4K 16 | SaerIrFNJv1zWoOPFWHypvfKjB2XCRKsyydJ5a85FSpfMPdTpCG4OrM9OpkZJ+6L 17 | bzhK3nNMO/oCadKppV4P5nub6WrdUYyNH4kO7ixyHqSeyYcGADF2uencKY/E4F9o 18 | n0rosLWY6bUzTd1EPFvA4KKuX4sAkkPW8eCtX8lj4zmg+ArFiLtvViX7pwFO+qQu 19 | ugTS8xhSUe34kRr9d2BiBit0hAMQZyTb5+2V76E5Nkl6B0ZdZBMwGC+du0R9LaCj 20 | rBtueO4LPnpr8j3r7wSCk62J/SsJ17j42+6nwL5Tx3w97Y/fwgA7EjAasdQZiD1n 21 | 3jDBMKoJhkPovFoXjZHXwYQdFrBZznoEf2bQIQDYzKffD5Xo6sUnwmOucoaVBqAn 22 | Rk07u5QGQW/WJboOj+AyTZEwe104FEje1z6v3Dp0Ndz/mA/Hfu/EUj9pW8Q2G2GN 23 | ryTUuhnvDtWQs3s5+bUkznCupW8SLKBCbLTCfQ8lqFNVtFN7U/oy68tniIekIG0+ 24 | g+59lVHFY/DuBficVRXOvf++4SNzA4ICBQACggIAFitkPeieNl0aHJjSfxk/9bsn 25 | 5smynoXFZVIEoyGIKhEf/wctQrQ0hcCztBks2Hr2sP8nYNSPU7BXEoThnq5SDdKu 26 | ddlcLyCoj2ZjFcsl6o8TExb8uh8rVxxzn+p+K/y7YpFpGjCfTHDb4eKuTk94GOsy 27 | dSHOQsOolQUJhEfCqULew2j+laIFt48fAkVE4ftA8vv+hMmhYu1t0GXm0vpH212t 28 | R87EDEu5q4Xjw8JuXxWjacuuLeDVYU4Q9/srpq7P3nWvdg+1PLPsArV+Pw5GhMrg 29 | XQxzwFHbcAKwio4C45urplR3/pgaMOEq8kU3l41ie5wIEZEfBvTvQbJ+UeznW9qd 30 | 84XNSLX74K9sWu7XjowbQSS34fRcOdpWQ1yme4RfaDQfvnsAsDVbAjpcmNl7x5y9 31 | gOPLt2VhvYyVqNY/mBnHqQA0310OC5fv87LR9/es8vPgElFqi3be0VJdlGskKcVX 32 | L6JIfmm9iVTonZwAZk3NlX11F3+UlduzLEZnQwbLWsusJEhNNpgiGQ3zn2taLtEX 33 | x+ehoYNuk14w/1VLwlwryhoRrdrd878nOfjT0uf7GUp5R5E6Nc4osP5mEHnCfgeD 34 | lOdL78lg0ioe7ssEdsUR6idofwUxkCOF6N37uO+uP/mP1oCIAxAkc6IziUJG1O3z 35 | pXp57aTJJ3k4pQsrAms= 36 | -----END PUBLIC KEY----- 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Carthage 2 | Carthage/ 3 | 4 | # Created by https://www.gitignore.io/api/macos,swift 5 | 6 | ### macOS ### 7 | *.DS_Store 8 | .AppleDouble 9 | .LSOverride 10 | 11 | # Icon must end with two \r 12 | Icon 13 | 14 | 15 | # Thumbnails 16 | ._* 17 | 18 | # Files that might appear in the root of a volume 19 | .DocumentRevisions-V100 20 | .fseventsd 21 | .Spotlight-V100 22 | .TemporaryItems 23 | .Trashes 24 | .VolumeIcon.icns 25 | .com.apple.timemachine.donotpresent 26 | 27 | # Directories potentially created on remote AFP share 28 | .AppleDB 29 | .AppleDesktop 30 | Network Trash Folder 31 | Temporary Items 32 | .apdisk 33 | 34 | 35 | ### Swift ### 36 | # Xcode 37 | # 38 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 39 | 40 | ## Build generated 41 | build/ 42 | DerivedData/ 43 | 44 | ## Various settings 45 | *.pbxuser 46 | !default.pbxuser 47 | *.mode1v3 48 | !default.mode1v3 49 | *.mode2v3 50 | !default.mode2v3 51 | *.perspectivev3 52 | !default.perspectivev3 53 | xcuserdata/ 54 | 55 | ## Other 56 | *.moved-aside 57 | *.xcuserstate 58 | 59 | ## Obj-C/Swift specific 60 | *.hmap 61 | *.ipa 62 | *.dSYM.zip 63 | *.dSYM 64 | 65 | ## Playgrounds 66 | timeline.xctimeline 67 | playground.xcworkspace 68 | 69 | # Swift Package Manager 70 | # 71 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 72 | # Packages/ 73 | .build/ 74 | 75 | # CocoaPods 76 | # 77 | # We recommend against adding the Pods directory to your .gitignore. However 78 | # you should judge for yourself, the pros and cons are mentioned at: 79 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 80 | # 81 | # Pods/ 82 | 83 | # Carthage 84 | # 85 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 86 | # Carthage/Checkouts 87 | 88 | Carthage/Build 89 | 90 | # fastlane 91 | # 92 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 93 | # screenshots whenever they are needed. 94 | # For more information about the recommended setup visit: 95 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 96 | 97 | fastlane/report.xml 98 | fastlane/Preview.html 99 | fastlane/screenshots 100 | fastlane/test_output -------------------------------------------------------------------------------- /Eikana/ExclusionAppsController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ExclusionAppsController.swift 3 | // ⌘英かな 4 | // 5 | // MIT License 6 | // Copyright (c) 2016 iMasanari 7 | // 8 | 9 | import Cocoa 10 | 11 | 12 | class ExclusionAppsController: NSViewController, NSTableViewDataSource, NSTableViewDelegate { 13 | @IBOutlet weak var tableView: NSTableView! 14 | 15 | override func viewDidLoad() { 16 | super.viewDidLoad() 17 | // Do any additional setup after loading the view. 18 | 19 | NotificationCenter.default.addObserver(self, 20 | selector: #selector(ExclusionAppsController.tableReload), 21 | name: NSNotification.Name.NSApplicationDidBecomeActive, 22 | object: nil) 23 | } 24 | 25 | func numberOfRows(in tableView: NSTableView) -> Int { 26 | return exclusionAppsList.count + activeAppsList.count 27 | } 28 | 29 | func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? { 30 | let id = tableColumn!.identifier 31 | 32 | let isExclusion = row < exclusionAppsList.count 33 | 34 | if id == "checkbox" { 35 | return isExclusion 36 | } 37 | 38 | let value = isExclusion ? exclusionAppsList[row] : activeAppsList[row - exclusionAppsList.count] 39 | 40 | if id == "appName" { 41 | return value.name 42 | } 43 | if id == "appId" { 44 | return value.id 45 | } 46 | 47 | return nil 48 | } 49 | func tableView(_ tableView: NSTableView, setObjectValue object: Any?, for tableColumn: NSTableColumn?, row: Int) { 50 | let id = tableColumn!.identifier 51 | let isExclusion = row < exclusionAppsList.count 52 | 53 | if id != "checkbox" { 54 | return 55 | } 56 | 57 | if isExclusion { 58 | let item = exclusionAppsList.remove(at: row) 59 | activeAppsList.insert(item, at: 0) 60 | } 61 | else { 62 | let item = activeAppsList.remove(at: row - exclusionAppsList.count) 63 | exclusionAppsList.append(item) 64 | } 65 | 66 | exclusionAppsDict = [:] 67 | 68 | for val in exclusionAppsList { 69 | exclusionAppsDict[val.id] = val.name 70 | } 71 | 72 | tableReload() 73 | saveExclusionApps() 74 | } 75 | 76 | func tableReload() { 77 | tableView.reloadData() 78 | } 79 | 80 | func saveExclusionApps() { 81 | UserDefaults.standard.set(exclusionAppsList.map {$0.toDictionary()} , forKey: "exclusionApps") 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /Eikana/KeyTextField.swift: -------------------------------------------------------------------------------- 1 | // 2 | // KeyTextField.swift 3 | // ⌘英かな 4 | // 5 | // MIT License 6 | // Copyright (c) 2016 iMasanari 7 | // 8 | 9 | import Cocoa 10 | 11 | var activeKeyTextField: KeyTextField? 12 | 13 | class KeyTextField: NSComboBox { 14 | /// Custom delegate with other methods than NSTextFieldDelegate. 15 | var shortcut: KeyboardShortcut? = nil 16 | var saveAddress: (row: Int, id: String)? = nil 17 | var isAllowModifierOnly = true 18 | 19 | override func becomeFirstResponder() -> Bool { 20 | let became = super.becomeFirstResponder(); 21 | if (became) { 22 | activeKeyTextField = self 23 | } 24 | return became; 25 | } 26 | // override func resignFirstResponder() -> Bool { 27 | // let resigned = super.resignFirstResponder(); 28 | // if (resigned) { 29 | // } 30 | // return resigned; 31 | // } 32 | 33 | override func textDidEndEditing(_ obj: Notification) { 34 | super.textDidEndEditing(obj) 35 | 36 | switch self.stringValue { 37 | case "英数": 38 | shortcut = KeyboardShortcut(keyCode: 102) 39 | break 40 | case "かな": 41 | shortcut = KeyboardShortcut(keyCode: 104) 42 | break 43 | case "⇧かな": 44 | shortcut = KeyboardShortcut(keyCode: 104, flags: CGEventFlags.maskShift) 45 | break 46 | case "前の入力ソースを選択", "select the previous input source": 47 | let symbolichotkeys = UserDefaults.init(suiteName: "com.apple.symbolichotkeys.plist")?.object(forKey: "AppleSymbolicHotKeys") as! NSDictionary 48 | let parameters = symbolichotkeys.value(forKeyPath: "60.value.parameters") as! [Int] 49 | 50 | shortcut = KeyboardShortcut(keyCode: CGKeyCode(parameters[1]), flags: CGEventFlags(rawValue: UInt64(parameters[2]))) 51 | break 52 | case "入力メニューの次のソースを選択", "select next source in input menu": 53 | let symbolichotkeys = UserDefaults.init(suiteName: "com.apple.symbolichotkeys.plist")?.object(forKey: "AppleSymbolicHotKeys") as! NSDictionary 54 | let parameters = symbolichotkeys.value(forKeyPath: "61.value.parameters") as! [Int] 55 | 56 | shortcut = KeyboardShortcut(keyCode: CGKeyCode(parameters[1]), flags: CGEventFlags(rawValue: UInt64(parameters[2]))) 57 | break 58 | case "Disable": 59 | shortcut = KeyboardShortcut(keyCode: CGKeyCode(999)) 60 | break 61 | default: 62 | break 63 | } 64 | 65 | if let shortcut = shortcut { 66 | self.stringValue = shortcut.toString() 67 | 68 | if let saveAddress = saveAddress { 69 | if saveAddress.id == "input" { 70 | keyMappingList[saveAddress.row].input = shortcut 71 | } 72 | else { 73 | keyMappingList[saveAddress.row].output = shortcut 74 | } 75 | keyMappingListToShortcutList() 76 | } 77 | } 78 | else { 79 | self.stringValue = "" 80 | } 81 | 82 | saveKeyMappings() 83 | 84 | if activeKeyTextField == self { 85 | activeKeyTextField = nil 86 | } 87 | } 88 | func blur() { 89 | self.window?.makeFirstResponder(nil) 90 | activeKeyTextField = nil 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /Eikana/ShortcutsController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ShortcutsController.swift 3 | // ⌘英かな 4 | // 5 | // MIT License 6 | // Copyright (c) 2016 iMasanari 7 | // 8 | 9 | import Cocoa 10 | 11 | 12 | var shortcutList: [CGKeyCode: [KeyMapping]] = [:] 13 | 14 | var keyMappingList: [KeyMapping] = [] 15 | 16 | func saveKeyMappings() { 17 | UserDefaults.standard.set(keyMappingList.map {$0.toDictionary()} , forKey: "mappings") 18 | } 19 | 20 | func keyMappingListToShortcutList() { 21 | shortcutList = [:] 22 | 23 | for val in keyMappingList { 24 | let key = val.input.keyCode 25 | 26 | if shortcutList[key] == nil { 27 | shortcutList[key] = [] 28 | } 29 | 30 | shortcutList[key]?.append(val) 31 | 32 | #if DEBUG 33 | print("\(key): \(val.input.toString()) => \(val.output.toString())") 34 | #endif 35 | } 36 | } 37 | 38 | class ShortcutsController: NSViewController, NSTableViewDataSource, NSTableViewDelegate { 39 | @IBOutlet weak var tableView: NSTableView! 40 | 41 | override func viewDidLoad() { 42 | super.viewDidLoad() 43 | // Do any additional setup after loading the view. 44 | } 45 | 46 | override func mouseDown(with event: NSEvent) { 47 | activeKeyTextField?.blur() 48 | } 49 | 50 | func numberOfRows(in tableView: NSTableView) -> Int { 51 | return keyMappingList.count 52 | } 53 | 54 | func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { 55 | let id = tableColumn!.identifier 56 | 57 | if let cell = tableView.make(withIdentifier: id, owner: nil) as? NSTableCellView { 58 | if id == "input" || id == "output" { 59 | let value = id == "input" ? keyMappingList[row].input : keyMappingList[row].output 60 | 61 | // let textField = cell.textField! 62 | let textField = cell.subviews[0] as! KeyTextField 63 | 64 | textField.stringValue = value.toString() 65 | textField.shortcut = value 66 | textField.saveAddress = (row: row, id: id) 67 | textField.isAllowModifierOnly = id == "input" 68 | } 69 | if id == "mapping-menu" { 70 | let button = cell.subviews[0] as! MappingMenu 71 | 72 | button.row = row 73 | 74 | button.target = self 75 | button.action = #selector(ShortcutsController.remove(_:)) 76 | } 77 | 78 | return cell 79 | } 80 | return nil 81 | } 82 | func remove(_ sender: MappingMenu) { 83 | activeKeyTextField?.blur() 84 | 85 | switch sender.selectedItem!.title { 86 | case "この項目を削除", "remove": 87 | sender.remove() 88 | break 89 | case "最上部に移動", "move to the top": 90 | sender.move(0) 91 | break 92 | case "1つ上に移動", "move one up": 93 | sender.move(sender.row! - 1) 94 | break 95 | case "1つ下に移動", "move one down": 96 | sender.move(sender.row! + 1) 97 | break 98 | case "最下部に移動", "move to bottom": 99 | sender.move(keyMappingList.count - 1) 100 | break 101 | default: 102 | break 103 | } 104 | 105 | tableRreload() 106 | } 107 | 108 | func tableRreload() { 109 | tableView.reloadData() 110 | keyMappingListToShortcutList() 111 | saveKeyMappings() 112 | } 113 | 114 | @IBAction func quit(_ sender: AnyObject) { 115 | NSApplication.shared().terminate(self) 116 | } 117 | 118 | @IBAction func addRow(_ sender: AnyObject) { 119 | keyMappingList.append(KeyMapping()) 120 | tableRreload() 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /Eikana/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // ⌘英かな 4 | // 5 | // MIT License 6 | // Copyright (c) 2016 iMasanari 7 | // 8 | 9 | import Cocoa 10 | import Sparkle 11 | 12 | var statusItem = NSStatusBar.system().statusItem(withLength: CGFloat(NSVariableStatusItemLength)) 13 | var loginItem = NSMenuItem() 14 | 15 | @NSApplicationMain 16 | class AppDelegate: NSObject, NSApplicationDelegate { 17 | 18 | var windowController : NSWindowController? 19 | var preferenceWindowController: PreferenceWindowController! 20 | 21 | func applicationDidFinishLaunching(_ aNotification: Notification) { 22 | // Insert code here to initialize your application 23 | 24 | // resetUserDefault() // デバッグ用 25 | 26 | //////////////////////////// 27 | // 保存データの読み込み 28 | //////////////////////////// 29 | 30 | let userDefaults = UserDefaults.standard 31 | 32 | // 「ログイン後にこのアプリを起動」 33 | if userDefaults.object(forKey: "lunchAtStartup") == nil { 34 | setLaunchAtStartup(true) 35 | userDefaults.set(1, forKey: "lunchAtStartup") 36 | } 37 | 38 | // 「起動時にアップデートを確認」 39 | let checkUpdateState = userDefaults.object(forKey: "checkUpdateAtlaunch") 40 | let updater = SUUpdater.shared()! 41 | 42 | updater.feedURL = URL(string: "https://imasanari.github.io/cmd-eikana/appcast.xml") 43 | 44 | if checkUpdateState == nil { 45 | userDefaults.set(1, forKey: "checkUpdateAtlaunch") 46 | updater.checkForUpdatesInBackground() 47 | } 48 | else if checkUpdateState as! Int == 1 { 49 | updater.checkForUpdatesInBackground() 50 | } 51 | 52 | // 除外アプリ設定 53 | if let exclusionAppsListData = userDefaults.object(forKey: "exclusionApps") as? [[AnyHashable: Any]] { 54 | for val in exclusionAppsListData { 55 | if let exclusionApps = AppData(dictionary: val) { 56 | exclusionAppsList.append(exclusionApps) 57 | } 58 | } 59 | 60 | for val in exclusionAppsList { 61 | exclusionAppsDict[val.id] = val.name 62 | } 63 | } 64 | 65 | // ショートカット設定 66 | if let keyMappingListData = userDefaults.object(forKey: "mappings") as? [[AnyHashable: Any]] { 67 | for val in keyMappingListData { 68 | if let mapping = KeyMapping(dictionary: val) { 69 | keyMappingList.append(mapping) 70 | } 71 | } 72 | 73 | keyMappingListToShortcutList() 74 | } 75 | else { 76 | if let oneShotModifiersData = userDefaults.object(forKey: "oneShotModifiers") as? [AnyObject] { 77 | // v2.0.xからの引き継ぎ 78 | for val in oneShotModifiersData { 79 | if let inputKeyCodeInt = val["input"] as? Int, 80 | let outputDic = val["output"] as? [AnyHashable: Any], 81 | let output = KeyboardShortcut(dictionary: outputDic) 82 | { 83 | keyMappingList.append(KeyMapping(input: KeyboardShortcut(keyCode: CGKeyCode(inputKeyCodeInt)), 84 | output: output)) 85 | } 86 | } 87 | 88 | userDefaults.removeObject(forKey: "oneShotModifiers") 89 | } 90 | else { 91 | // 初期設定(左右のコマンドキー単体で英数/かな) 92 | keyMappingList = [ 93 | KeyMapping(input: KeyboardShortcut(keyCode: 55), output: KeyboardShortcut(keyCode: 102)), 94 | KeyMapping(input: KeyboardShortcut(keyCode: 54), output: KeyboardShortcut(keyCode: 104)) 95 | ] 96 | } 97 | 98 | saveKeyMappings() 99 | keyMappingListToShortcutList() 100 | } 101 | 102 | //////////////////////////// 103 | // UIの初期化 104 | //////////////////////////// 105 | 106 | preferenceWindowController = PreferenceWindowController.getInstance() 107 | // preferenceWindowController.showAndActivate(self) 108 | 109 | let menu = NSMenu() 110 | statusItem.title = "⌘" 111 | statusItem.highlightMode = true 112 | statusItem.menu = menu 113 | 114 | // loginItem = menu.addItem(withTitle: "ログイン時に開く", action: #selector(AppDelegate.launch(_:)), keyEquivalent: "") 115 | // loginItem.state = applicationIsInStartUpItems() ? 1 : 0 116 | // 117 | // menu.addItem(NSMenuItem.separator()) 118 | 119 | let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as! String 120 | 121 | menu.addItem(withTitle: "About Eikana \(version)", action: #selector(AppDelegate.open(_:)), keyEquivalent: "") 122 | menu.addItem(withTitle: "Preferences...", action: #selector(AppDelegate.openPreferencesSerector(_:)), keyEquivalent: "") 123 | menu.addItem(NSMenuItem.separator()) 124 | menu.addItem(withTitle: "Restart", action: #selector(AppDelegate.restart(_:)), keyEquivalent: "") 125 | menu.addItem(withTitle: "Quit", action: #selector(AppDelegate.quit(_:)), keyEquivalent: "") 126 | 127 | _ = KeyEvent() 128 | } 129 | 130 | func applicationWillTerminate(_ aNotification: Notification) { 131 | // Insert code here to tear down your application 132 | } 133 | 134 | func applicationDidResignActive(_ notification: Notification) { 135 | activeKeyTextField?.blur() 136 | } 137 | func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool { 138 | preferenceWindowController.showAndActivate(self) 139 | return false 140 | } 141 | 142 | // 保存されたUserDefaultを全削除する。 143 | func resetUserDefault() { 144 | let appDomain:String = Bundle.main.bundleIdentifier! 145 | UserDefaults.standard.removePersistentDomain(forName: appDomain) 146 | } 147 | 148 | @IBAction func open(_ sender: NSButton) { 149 | if let checkURL = URL(string: "https://ei-kana.appspot.com") { 150 | if NSWorkspace.shared().open(checkURL) { 151 | print("url successfully opened") 152 | } 153 | } else { 154 | print("invalid url") 155 | } 156 | } 157 | @IBAction func openPreferencesSerector(_ sender: NSButton) { 158 | preferenceWindowController.showAndActivate(self) 159 | } 160 | 161 | @IBAction func launch(_ sender: NSButton) { 162 | if sender.state == 0 { 163 | sender.state = 1 164 | // addLaunchAtStartup() 165 | } 166 | else { 167 | sender.state = 0 168 | // removeLaunchAtStartup() 169 | } 170 | } 171 | 172 | @IBAction func restart(_ sender: NSButton) { 173 | let url = URL(fileURLWithPath: Bundle.main.resourcePath!) 174 | let path = url.deletingLastPathComponent().deletingLastPathComponent().absoluteString 175 | let task = Process() 176 | task.launchPath = "/usr/bin/open" 177 | task.arguments = [path] 178 | task.launch() 179 | NSApplication.shared().terminate(self) 180 | } 181 | 182 | @IBAction func quit(_ sender: NSButton) { 183 | NSApplication.shared().terminate(self) 184 | } 185 | } 186 | 187 | -------------------------------------------------------------------------------- /Eikana/KeyboardShortcut.swift: -------------------------------------------------------------------------------- 1 | // 2 | // KeyboardShortcut.swift 3 | // ⌘英かな 4 | // 5 | // MIT License 6 | // Copyright (c) 2016 iMasanari 7 | // 8 | 9 | import Cocoa 10 | 11 | class KeyboardShortcut: NSObject { 12 | var keyCode: CGKeyCode 13 | var flags: CGEventFlags 14 | 15 | init(_ event: CGEvent) { 16 | self.keyCode = CGKeyCode(event.getIntegerValueField(.keyboardEventKeycode)) 17 | self.flags = event.flags 18 | 19 | super.init() 20 | } 21 | override init() { 22 | self.keyCode = 0 23 | self.flags = CGEventFlags(rawValue: 0) 24 | 25 | super.init() 26 | } 27 | 28 | init(keyCode: CGKeyCode, flags: CGEventFlags = CGEventFlags()) { 29 | self.keyCode = keyCode 30 | self.flags = flags 31 | 32 | super.init() 33 | } 34 | init?(dictionary: [AnyHashable: Any]) { 35 | if let keyCodeInt = dictionary["keyCode"] as? Int, 36 | let eventFlagsInt = dictionary["flags"] as? Int { 37 | 38 | self.flags = CGEventFlags(rawValue: UInt64(eventFlagsInt)) 39 | self.keyCode = CGKeyCode(keyCodeInt) 40 | 41 | super.init() 42 | } else { 43 | self.keyCode = 0 44 | self.flags = CGEventFlags(rawValue: 0) 45 | 46 | super.init() 47 | return nil 48 | } 49 | } 50 | 51 | func toDictionary() -> [AnyHashable: Any] { 52 | return [ 53 | "keyCode": Int(keyCode), 54 | "flags": Int(flags.rawValue) 55 | ] 56 | } 57 | 58 | func toString() -> String { 59 | let key = keyCodeDictionary[keyCode] 60 | 61 | if key == nil { 62 | return "" 63 | } 64 | 65 | var flagString = "" 66 | 67 | if isSecondaryFnDown() { 68 | flagString += "(fn)" 69 | } 70 | 71 | if isCapslockDown() { 72 | flagString += "⇪" 73 | } 74 | 75 | if isCommandDown() { 76 | flagString += "⌘" 77 | } 78 | 79 | if isShiftDown() { 80 | flagString += "⇧" 81 | } 82 | 83 | if isControlDown() { 84 | flagString += "⌃" 85 | } 86 | 87 | if isAlternateDown() { 88 | flagString += "⌥" 89 | } 90 | 91 | return flagString + key! 92 | } 93 | 94 | func isCommandDown() -> Bool { 95 | return self.flags.rawValue & CGEventFlags.maskCommand.rawValue != 0 && keyCode != 54 && keyCode != 55 96 | } 97 | 98 | func isShiftDown() -> Bool { 99 | return self.flags.rawValue & CGEventFlags.maskShift.rawValue != 0 && keyCode != 56 && keyCode != 60 100 | } 101 | 102 | func isControlDown() -> Bool { 103 | return self.flags.rawValue & CGEventFlags.maskControl.rawValue != 0 && keyCode != 59 && keyCode != 62 104 | } 105 | 106 | func isAlternateDown() -> Bool { 107 | return self.flags.rawValue & CGEventFlags.maskAlternate.rawValue != 0 && keyCode != 58 && keyCode != 61 108 | } 109 | 110 | func isSecondaryFnDown() -> Bool { 111 | return self.flags.rawValue & CGEventFlags.maskSecondaryFn.rawValue != 0 && keyCode != 63 112 | } 113 | 114 | func isCapslockDown() -> Bool { 115 | return self.flags.rawValue & CGEventFlags.maskAlphaShift.rawValue != 0 && keyCode != 57 116 | } 117 | 118 | func postEvent() -> Void { 119 | let loc = CGEventTapLocation.cghidEventTap 120 | 121 | let keyDownEvent = CGEvent(keyboardEventSource: nil, virtualKey: keyCode, keyDown: true)! 122 | let keyUpEvent = CGEvent(keyboardEventSource: nil, virtualKey: keyCode, keyDown: false)! 123 | 124 | keyDownEvent.flags = flags 125 | keyUpEvent.flags = CGEventFlags() 126 | 127 | keyDownEvent.post(tap: loc) 128 | keyUpEvent.post(tap: loc) 129 | } 130 | 131 | func isCover(_ shortcut: KeyboardShortcut) -> Bool { 132 | if shortcut.isCommandDown() && !self.isCommandDown() || 133 | shortcut.isShiftDown() && !self.isShiftDown() || 134 | shortcut.isControlDown() && !self.isControlDown() || 135 | shortcut.isAlternateDown() && !self.isAlternateDown() || 136 | shortcut.isSecondaryFnDown() && !self.isSecondaryFnDown() || 137 | shortcut.isCapslockDown() && !self.isCapslockDown() 138 | { 139 | return false 140 | } 141 | 142 | return true 143 | } 144 | } 145 | 146 | let keyCodeDictionary: Dictionary = [ 147 | 0: "A", 148 | 1: "S", 149 | 2: "D", 150 | 3: "F", 151 | 4: "H", 152 | 5: "G", 153 | 6: "Z", 154 | 7: "X", 155 | 8: "C", 156 | 9: "V", 157 | 10: "DANISH_DOLLAR", 158 | 11: "B", 159 | 12: "Q", 160 | 13: "W", 161 | 14: "E", 162 | 15: "R", 163 | 16: "Y", 164 | 17: "T", 165 | 18: "1", 166 | 19: "2", 167 | 20: "3", 168 | 21: "4", 169 | 22: "6", 170 | 23: "5", 171 | 24: "=", 172 | 25: "9", 173 | 26: "7", 174 | 27: "-", 175 | 28: "8", 176 | 29: "0", 177 | 30: "]", 178 | 31: "O", 179 | 32: "U", 180 | 33: "[", 181 | 34: "I", 182 | 35: "P", 183 | 36: "⏎", 184 | 37: "L", 185 | 38: "J", 186 | 39: "'", 187 | 40: "K", 188 | 41: ";", 189 | 42: "\\", 190 | 43: ",", 191 | 44: "/", 192 | 45: "N", 193 | 46: "M", 194 | 47: ".", 195 | 48: "⇥", 196 | 49: "Space", 197 | 50: "`", 198 | 51: "⌫", 199 | 52: "Enter_POWERBOOK", 200 | 53: "⎋", 201 | 54: "Command_R", 202 | 55: "Command_L", 203 | 56: "Shift_L", 204 | 57: "CapsLock", 205 | 58: "Option_L", 206 | 59: "Control_L", 207 | 60: "Shift_R", 208 | 61: "Option_R", 209 | 62: "Control_R", 210 | 63: "Fn", 211 | 64: "F17", 212 | 65: "Keypad_Dot", 213 | 67: "Keypad_Multiply", 214 | 69: "Keypad_Plus", 215 | 71: "Keypad_Clear", 216 | 75: "Keypad_Slash", 217 | 76: "⌤", 218 | 78: "Keypad_Minus", 219 | 79: "F18", 220 | 80: "F19", 221 | 81: "Keypad_Equal", 222 | 82: "Keypad_0", 223 | 83: "Keypad_1", 224 | 84: "Keypad_2", 225 | 85: "Keypad_3", 226 | 86: "Keypad_4", 227 | 87: "Keypad_5", 228 | 88: "Keypad_6", 229 | 89: "Keypad_7", 230 | 90: "F20", 231 | 91: "Keypad_8", 232 | 92: "Keypad_9", 233 | 93: "¥", 234 | 94: "_", 235 | 95: "Keypad_Comma", 236 | 96: "F5", 237 | 97: "F6", 238 | 98: "F7", 239 | 99: "F3", 240 | 100: "F8", 241 | 101: "F9", 242 | 102: "英数", 243 | 103: "F11", 244 | 104: "かな", 245 | 105: "F13", 246 | 106: "F16", 247 | 107: "F14", 248 | 109: "F10", 249 | 110: "App", 250 | 111: "F12", 251 | 113: "F15", 252 | 114: "Help", 253 | 115: "Home", // "↖", 254 | 116: "PgUp", 255 | 117: "⌦", 256 | 118: "F4", 257 | 119: "End", // "↘", 258 | 120: "F2", 259 | 121: "PgDn", 260 | 122: "F1", 261 | 123: "←", 262 | 124: "→", 263 | 125: "↓", 264 | 126: "↑", 265 | 127: "PC_POWER", 266 | 128: "GERMAN_PC_LESS_THAN", 267 | 130: "DASHBOARD", 268 | 131: "Launchpad", 269 | 144: "BRIGHTNESS_UP", 270 | 145: "BRIGHTNESS_DOWN", 271 | 160: "Expose_All", 272 | 273 | // media key (bata) 274 | 999: "Disable", 275 | 1000 + UInt16(NX_KEYTYPE_SOUND_UP): "Sound_up", 276 | 1000 + UInt16(NX_KEYTYPE_SOUND_DOWN): "Sound_down", 277 | 1000 + UInt16(NX_KEYTYPE_BRIGHTNESS_UP): "Brightness_up", 278 | 1000 + UInt16(NX_KEYTYPE_BRIGHTNESS_DOWN): "Brightness_down", 279 | 1000 + UInt16(NX_KEYTYPE_CAPS_LOCK): "CapsLock", 280 | 1000 + UInt16(NX_KEYTYPE_HELP): "HELP", 281 | 1000 + UInt16(NX_POWER_KEY): "PowerKey", 282 | 1000 + UInt16(NX_KEYTYPE_MUTE): "mute", 283 | 1000 + UInt16(NX_KEYTYPE_NUM_LOCK): "NUM_LOCK", 284 | 1000 + UInt16(NX_KEYTYPE_CONTRAST_UP): "CONTRAST_UP", 285 | 1000 + UInt16(NX_KEYTYPE_CONTRAST_DOWN): "CONTRAST_DOWN", 286 | 1000 + UInt16(NX_KEYTYPE_LAUNCH_PANEL): "LAUNCH_PANEL", 287 | 1000 + UInt16(NX_KEYTYPE_EJECT): "EJECT", 288 | 1000 + UInt16(NX_KEYTYPE_VIDMIRROR): "VIDMIRROR", 289 | 1000 + UInt16(NX_KEYTYPE_PLAY): "Play", 290 | 1000 + UInt16(NX_KEYTYPE_NEXT): "NEXT", 291 | 1000 + UInt16(NX_KEYTYPE_PREVIOUS): "PREVIOUS", 292 | 1000 + UInt16(NX_KEYTYPE_FAST): "Fast", 293 | 1000 + UInt16(NX_KEYTYPE_REWIND): "Rewind", 294 | 1000 + UInt16(NX_KEYTYPE_ILLUMINATION_UP): "Illumination_up", 295 | 1000 + UInt16(NX_KEYTYPE_ILLUMINATION_DOWN): "Illumination_down", 296 | 1000 + UInt16(NX_KEYTYPE_ILLUMINATION_TOGGLE): "ILLUMINATION_TOGGLE" 297 | ] 298 | -------------------------------------------------------------------------------- /Eikana/KeyEvent.swift: -------------------------------------------------------------------------------- 1 | // 2 | // KeyEvent.swift 3 | // ⌘英かな 4 | // 5 | // MIT License 6 | // Copyright (c) 2016 iMasanari 7 | // 8 | 9 | import Cocoa 10 | 11 | var activeAppsList: [AppData] = [] 12 | var exclusionAppsList: [AppData] = [] 13 | 14 | var exclusionAppsDict: [String: String] = [:] 15 | 16 | class KeyEvent: NSObject { 17 | var keyCode: CGKeyCode? = nil 18 | var isExclusionApp = false 19 | let bundleId = Bundle.main.infoDictionary?["CFBundleIdentifier"] as! String 20 | var hasConvertedEventLog: KeyMapping? = nil 21 | 22 | override init() { 23 | super.init() 24 | 25 | NSWorkspace.shared().notificationCenter.addObserver(self, 26 | selector: #selector(KeyEvent.setActiveApp(_:)), 27 | name: NSNotification.Name.NSWorkspaceDidActivateApplication, 28 | object:nil) 29 | 30 | let checkOptionPrompt = kAXTrustedCheckOptionPrompt.takeRetainedValue() as NSString 31 | let options: CFDictionary = [checkOptionPrompt: true] as NSDictionary 32 | 33 | if !AXIsProcessTrustedWithOptions(options) { 34 | // アクセシビリティに設定されていない場合、設定されるまでループで待つ 35 | Timer.scheduledTimer(timeInterval: 1.0, 36 | target: self, 37 | selector: #selector(KeyEvent.watchAXIsProcess(_:)), 38 | userInfo: nil, 39 | repeats: true) 40 | } 41 | else { 42 | self.watch() 43 | } 44 | } 45 | 46 | func watchAXIsProcess(_ timer: Timer) { 47 | if AXIsProcessTrusted() { 48 | timer.invalidate() 49 | 50 | self.watch() 51 | } 52 | } 53 | 54 | func setActiveApp(_ notification: NSNotification) { 55 | let app = notification.userInfo!["NSWorkspaceApplicationKey"] as! NSRunningApplication 56 | 57 | if let name = app.localizedName, let id = app.bundleIdentifier { 58 | isExclusionApp = exclusionAppsDict[id] != nil 59 | 60 | if (id != bundleId && !isExclusionApp) { 61 | activeAppsList = activeAppsList.filter {$0.id != id} 62 | activeAppsList.insert(AppData(name: name, id: id), at: 0) 63 | 64 | if activeAppsList.count > 10 { 65 | activeAppsList.removeLast() 66 | } 67 | } 68 | } 69 | } 70 | 71 | func watch() { 72 | // マウスのドラッグバグ回避のため、NSEventとCGEventを併用 73 | // CGEventのみでやる方法を捜索中 74 | 75 | let nsEventMaskList = [ 76 | NSEventMask.leftMouseDown, 77 | NSEventMask.leftMouseUp, 78 | NSEventMask.rightMouseDown, 79 | NSEventMask.rightMouseUp, 80 | NSEventMask.otherMouseDown, 81 | NSEventMask.otherMouseUp, 82 | NSEventMask.scrollWheel 83 | ] 84 | 85 | let globalHandler = {(evevt: NSEvent!) -> Void in self.keyCode = nil } 86 | let localHandler = {(evevt: NSEvent!) -> NSEvent in globalHandler(evevt); return evevt } 87 | 88 | for mask in nsEventMaskList { 89 | NSEvent.addGlobalMonitorForEvents(matching: mask, handler: globalHandler) 90 | NSEvent.addLocalMonitorForEvents(matching: mask, handler: localHandler) 91 | } 92 | 93 | let eventMaskList = [ 94 | CGEventType.keyDown.rawValue, 95 | CGEventType.keyUp.rawValue, 96 | CGEventType.flagsChanged.rawValue, 97 | // CGEventType.leftMouseDown.rawValue, 98 | // CGEventType.leftMouseUp.rawValue, 99 | // CGEventType.rightMouseDown.rawValue, 100 | // CGEventType.rightMouseUp.rawValue, 101 | // CGEventType.otherMouseDown.rawValue, 102 | // CGEventType.otherMouseUp.rawValue, 103 | // CGEventType.scrollWheel.rawValue, 104 | UInt32(NX_SYSDEFINED) // Media key Event 105 | ] 106 | var eventMask: UInt32 = 0 107 | 108 | for mask in eventMaskList { 109 | eventMask |= (1 << mask) 110 | } 111 | 112 | let observer = UnsafeMutableRawPointer(Unmanaged.passRetained(self).toOpaque()) 113 | 114 | guard let eventTap = CGEvent.tapCreate( 115 | tap: .cgSessionEventTap, 116 | place: .headInsertEventTap, 117 | options: .defaultTap, 118 | eventsOfInterest: CGEventMask(eventMask), 119 | callback: { (proxy: CGEventTapProxy, type: CGEventType, event: CGEvent, refcon: UnsafeMutableRawPointer?) -> Unmanaged? in 120 | if let observer = refcon { 121 | let mySelf = Unmanaged.fromOpaque(observer).takeUnretainedValue() 122 | return mySelf.eventCallback(proxy: proxy, type: type, event: event) 123 | } 124 | return Unmanaged.passUnretained(event) 125 | }, 126 | userInfo: observer 127 | ) else { 128 | print("failed to create event tap") 129 | exit(1) 130 | } 131 | 132 | let runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0) 133 | 134 | CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, .commonModes) 135 | CGEvent.tapEnable(tap: eventTap, enable: true) 136 | CFRunLoopRun() 137 | } 138 | 139 | func eventCallback(proxy: CGEventTapProxy, type: CGEventType, event: CGEvent) -> Unmanaged? { 140 | if isExclusionApp { 141 | return Unmanaged.passUnretained(event) 142 | } 143 | 144 | if let mediaKeyEvent = MediaKeyEvent(event) { 145 | return mediaKeyEvent.keyDown ? mediaKeyDown(mediaKeyEvent) : mediaKeyUp(mediaKeyEvent) 146 | } 147 | 148 | switch type { 149 | case CGEventType.flagsChanged: 150 | let keyCode = CGKeyCode(event.getIntegerValueField(.keyboardEventKeycode)) 151 | 152 | if modifierMasks[keyCode] == nil { 153 | return Unmanaged.passUnretained(event) 154 | } 155 | return event.flags.rawValue & modifierMasks[keyCode]!.rawValue != 0 ? 156 | modifierKeyDown(event) : modifierKeyUp(event) 157 | 158 | case CGEventType.keyDown: 159 | return keyDown(event) 160 | 161 | case CGEventType.keyUp: 162 | return keyUp(event) 163 | 164 | default: 165 | self.keyCode = nil 166 | 167 | return Unmanaged.passUnretained(event) 168 | } 169 | } 170 | 171 | func keyDown(_ event: CGEvent) -> Unmanaged? { 172 | #if DEBUG 173 | // print("keyCode: \(KeyboardShortcut(event).keyCode)") 174 | print(KeyboardShortcut(event).toString()) 175 | #endif 176 | 177 | self.keyCode = nil 178 | 179 | if let keyTextField = activeKeyTextField { 180 | keyTextField.shortcut = KeyboardShortcut(event) 181 | keyTextField.stringValue = keyTextField.shortcut!.toString() 182 | 183 | return nil 184 | } 185 | 186 | if hasConvertedEvent(event) { 187 | if let event = getConvertedEvent(event) { 188 | return Unmanaged.passUnretained(event) 189 | } 190 | return nil 191 | } 192 | 193 | return Unmanaged.passUnretained(event) 194 | } 195 | 196 | func keyUp(_ event: CGEvent) -> Unmanaged? { 197 | self.keyCode = nil 198 | 199 | if hasConvertedEvent(event) { 200 | if let event = getConvertedEvent(event) { 201 | return Unmanaged.passUnretained(event) 202 | } 203 | return nil 204 | } 205 | 206 | return Unmanaged.passUnretained(event) 207 | } 208 | 209 | func modifierKeyDown(_ event: CGEvent) -> Unmanaged? { 210 | #if DEBUG 211 | print(KeyboardShortcut(event).toString()) 212 | #endif 213 | 214 | self.keyCode = CGKeyCode(event.getIntegerValueField(.keyboardEventKeycode)) 215 | 216 | if let keyTextField = activeKeyTextField, keyTextField.isAllowModifierOnly { 217 | let shortcut = KeyboardShortcut(event) 218 | 219 | keyTextField.shortcut = shortcut 220 | keyTextField.stringValue = shortcut.toString() 221 | } 222 | 223 | return Unmanaged.passUnretained(event) 224 | } 225 | 226 | func modifierKeyUp(_ event: CGEvent) -> Unmanaged? { 227 | if activeKeyTextField != nil { 228 | self.keyCode = nil 229 | } 230 | else if self.keyCode == CGKeyCode(event.getIntegerValueField(.keyboardEventKeycode)) { 231 | if let convertedEvent = getConvertedEvent(event) { 232 | KeyboardShortcut(convertedEvent).postEvent() 233 | } 234 | } 235 | 236 | self.keyCode = nil 237 | 238 | return Unmanaged.passUnretained(event) 239 | } 240 | 241 | func mediaKeyDown(_ mediaKeyEvent: MediaKeyEvent) -> Unmanaged? { 242 | #if DEBUG 243 | print(KeyboardShortcut(keyCode: CGKeyCode(1000 + mediaKeyEvent.keyCode), flags: mediaKeyEvent.flags).toString()) 244 | #endif 245 | 246 | self.keyCode = nil 247 | 248 | if let keyTextField = activeKeyTextField { 249 | if keyTextField.isAllowModifierOnly { 250 | keyTextField.shortcut = KeyboardShortcut(keyCode: CGKeyCode(1000 + mediaKeyEvent.keyCode), 251 | flags: mediaKeyEvent.flags) 252 | keyTextField.stringValue = keyTextField.shortcut!.toString() 253 | } 254 | 255 | return nil 256 | } 257 | 258 | if hasConvertedEvent(mediaKeyEvent.event, keyCode: CGKeyCode(1000 + mediaKeyEvent.keyCode)) { 259 | if let event = getConvertedEvent(mediaKeyEvent.event, keyCode: CGKeyCode(1000 + mediaKeyEvent.keyCode)) { 260 | print(KeyboardShortcut(event).toString()) 261 | 262 | print(event.type == CGEventType.keyDown) 263 | event.post(tap: CGEventTapLocation.cghidEventTap) 264 | } 265 | return nil 266 | } 267 | 268 | return Unmanaged.passUnretained(mediaKeyEvent.event) 269 | } 270 | func mediaKeyUp(_ mediaKeyEvent: MediaKeyEvent) -> Unmanaged? { 271 | // if hasConvertedEvent(mediaKeyEvent.event, keyCode: CGKeyCode(1000 + mediaKeyEvent.keyCode)) { 272 | // if let event = getConvertedEvent(mediaKeyEvent.event, keyCode: CGKeyCode(1000 + Int(mediaKeyEvent.keyCode))) { 273 | // event.post(tap: CGEventTapLocation.cghidEventTap) 274 | // } 275 | // return nil 276 | // } 277 | 278 | return Unmanaged.passUnretained(mediaKeyEvent.event) 279 | } 280 | 281 | func hasConvertedEvent(_ event: CGEvent, keyCode: CGKeyCode? = nil) -> Bool { 282 | let shortcht = event.type.rawValue == UInt32(NX_SYSDEFINED) ? 283 | KeyboardShortcut(keyCode: 0, flags: MediaKeyEvent(event)!.flags) : KeyboardShortcut(event) 284 | 285 | if let mappingList = shortcutList[keyCode ?? shortcht.keyCode] { 286 | for mappings in mappingList { 287 | if shortcht.isCover(mappings.input) { 288 | hasConvertedEventLog = mappings 289 | return true 290 | } 291 | } 292 | } 293 | hasConvertedEventLog = nil 294 | return false 295 | } 296 | func getConvertedEvent(_ event: CGEvent, keyCode: CGKeyCode? = nil) -> CGEvent? { 297 | var event = event 298 | 299 | if event.type.rawValue == UInt32(NX_SYSDEFINED) { 300 | let flags = MediaKeyEvent(event)!.flags 301 | event = CGEvent(keyboardEventSource: nil, virtualKey: 0, keyDown: true)! 302 | event.flags = flags 303 | } 304 | 305 | let shortcht = KeyboardShortcut(event) 306 | 307 | func getEvent(_ mappings: KeyMapping) -> CGEvent? { 308 | if mappings.output.keyCode == 999 { 309 | // 999 is Disable 310 | return nil 311 | } 312 | 313 | event.setIntegerValueField(.keyboardEventKeycode, value: Int64(mappings.output.keyCode)) 314 | event.flags = CGEventFlags( 315 | rawValue: (event.flags.rawValue & ~mappings.input.flags.rawValue) | mappings.output.flags.rawValue 316 | ) 317 | 318 | return event 319 | } 320 | 321 | if let mappingList = shortcutList[keyCode ?? shortcht.keyCode] { 322 | if let mappings = hasConvertedEventLog, 323 | shortcht.isCover(mappings.input) { 324 | 325 | return getEvent(mappings) 326 | } 327 | for mappings in mappingList { 328 | if shortcht.isCover(mappings.input) { 329 | return getEvent(mappings) 330 | } 331 | } 332 | } 333 | return nil 334 | } 335 | } 336 | 337 | let modifierMasks: [CGKeyCode: CGEventFlags] = [ 338 | 54: CGEventFlags.maskCommand, 339 | 55: CGEventFlags.maskCommand, 340 | 56: CGEventFlags.maskShift, 341 | 60: CGEventFlags.maskShift, 342 | 59: CGEventFlags.maskControl, 343 | 62: CGEventFlags.maskControl, 344 | 58: CGEventFlags.maskAlternate, 345 | 61: CGEventFlags.maskAlternate, 346 | 63: CGEventFlags.maskSecondaryFn, 347 | 57: CGEventFlags.maskAlphaShift 348 | ] 349 | -------------------------------------------------------------------------------- /Eikana/ja.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "NSViewController"; title = "Key Remap"; ObjectID = "14e-rg-kjk"; */ 3 | "14e-rg-kjk.title" = "キーリマップ"; 4 | 5 | /* Class = "NSMenuItem"; title = "Customize Toolbar…"; ObjectID = "1UK-8n-QPP"; */ 6 | "1UK-8n-QPP.title" = "Customize Toolbar…"; 7 | 8 | /* Class = "NSMenuItem"; title = "⌘英かな"; ObjectID = "1Xt-HY-uBw"; */ 9 | "1Xt-HY-uBw.title" = "⌘英かな"; 10 | 11 | /* Class = "NSMenu"; title = "Find"; ObjectID = "1b7-l0-nxx"; */ 12 | "1b7-l0-nxx.title" = "Find"; 13 | 14 | /* Class = "NSMenuItem"; title = "Lower"; ObjectID = "1tx-W0-xDw"; */ 15 | "1tx-W0-xDw.title" = "Lower"; 16 | 17 | /* Class = "NSMenuItem"; title = "Raise"; ObjectID = "2h7-ER-AoG"; */ 18 | "2h7-ER-AoG.title" = "Raise"; 19 | 20 | /* Class = "NSMenuItem"; title = "Transformations"; ObjectID = "2oI-Rn-ZJC"; */ 21 | "2oI-Rn-ZJC.title" = "Transformations"; 22 | 23 | /* Class = "NSMenu"; title = "Spelling"; ObjectID = "3IN-sU-3Bg"; */ 24 | "3IN-sU-3Bg.title" = "Spelling"; 25 | 26 | /* Class = "NSMenuItem"; title = "Use Default"; ObjectID = "3Om-Ey-2VK"; */ 27 | "3Om-Ey-2VK.title" = "Use Default"; 28 | 29 | /* Class = "NSMenu"; title = "Speech"; ObjectID = "3rS-ZA-NoH"; */ 30 | "3rS-ZA-NoH.title" = "Speech"; 31 | 32 | /* Class = "NSMenuItem"; title = "Tighten"; ObjectID = "46P-cB-AYj"; */ 33 | "46P-cB-AYj.title" = "Tighten"; 34 | 35 | /* Class = "NSButtonCell"; title = "check update"; ObjectID = "4Dh-kS-y64"; */ 36 | "4Dh-kS-y64.title" = "確認する"; 37 | 38 | /* Class = "NSMenuItem"; title = "Find"; ObjectID = "4EN-yA-p0u"; */ 39 | "4EN-yA-p0u.title" = "Find"; 40 | 41 | /* Class = "NSTableColumn"; headerCell.title = "input"; ObjectID = "4Lt-aZ-uP6"; */ 42 | "4Lt-aZ-uP6.headerCell.title" = "input"; 43 | 44 | /* Class = "NSMenuItem"; title = "Quit ⌘英かな"; ObjectID = "4sb-4s-VLi"; */ 45 | "4sb-4s-VLi.title" = "Quit ⌘英かな"; 46 | 47 | /* Class = "NSMenuItem"; title = "remove"; ObjectID = "502-f2-l6k"; */ 48 | "502-f2-l6k.title" = "この項目を削除"; 49 | 50 | /* Class = "NSViewController"; title = "Exclusion Apps"; ObjectID = "5BL-ga-t3Q"; */ 51 | "5BL-ga-t3Q.title" = "除外アプリ"; 52 | 53 | /* Class = "NSMenuItem"; title = "move one up"; ObjectID = "5K6-xN-Jic"; */ 54 | "5K6-xN-Jic.title" = "1つ上に移動"; 55 | 56 | /* Class = "NSMenuItem"; title = "Edit"; ObjectID = "5QF-Oa-p0T"; */ 57 | "5QF-Oa-p0T.title" = "Edit"; 58 | 59 | /* Class = "NSMenuItem"; title = "Copy Style"; ObjectID = "5Vv-lz-BsD"; */ 60 | "5Vv-lz-BsD.title" = "Copy Style"; 61 | 62 | /* Class = "NSMenuItem"; title = "About ⌘英かな"; ObjectID = "5kV-Vb-QxS"; */ 63 | "5kV-Vb-QxS.title" = "About ⌘英かな"; 64 | 65 | /* Class = "NSButtonCell"; title = "check for update when start"; ObjectID = "6Pk-W2-evg"; */ 66 | "6Pk-W2-evg.title" = "起動時にアップデートを確認"; 67 | 68 | /* Class = "NSMenuItem"; title = "Redo"; ObjectID = "6dh-zS-Vam"; */ 69 | "6dh-zS-Vam.title" = "Redo"; 70 | 71 | /* Class = "NSMenuItem"; title = "Correct Spelling Automatically"; ObjectID = "78Y-hA-62v"; */ 72 | "78Y-hA-62v.title" = "Correct Spelling Automatically"; 73 | 74 | /* Class = "NSMenu"; title = "Writing Direction"; ObjectID = "8mr-sm-Yjd"; */ 75 | "8mr-sm-Yjd.title" = "Writing Direction"; 76 | 77 | /* Class = "NSMenuItem"; title = "Substitutions"; ObjectID = "9ic-FL-obx"; */ 78 | "9ic-FL-obx.title" = "Substitutions"; 79 | 80 | /* Class = "NSTableColumn"; headerCell.title = "Recently active Apps"; ObjectID = "9mf-tw-vRT"; */ 81 | "9mf-tw-vRT.headerCell.title" = "Recently active Apps"; 82 | 83 | /* Class = "NSMenuItem"; title = "Smart Copy/Paste"; ObjectID = "9yt-4B-nSM"; */ 84 | "9yt-4B-nSM.title" = "Smart Copy/Paste"; 85 | 86 | /* Class = "NSMenu"; title = "Main Menu"; ObjectID = "AYu-sK-qS6"; */ 87 | "AYu-sK-qS6.title" = "Main Menu"; 88 | 89 | /* Class = "NSMenuItem"; title = "Preferences…"; ObjectID = "BOF-NM-1cW"; */ 90 | "BOF-NM-1cW.title" = "Preferences…"; 91 | 92 | /* Class = "NSMenuItem"; title = "\tLeft to Right"; ObjectID = "BgM-ve-c93"; */ 93 | "BgM-ve-c93.title" = "\tLeft to Right"; 94 | 95 | /* Class = "NSMenuItem"; title = "Save As…"; ObjectID = "Bw7-FT-i3A"; */ 96 | "Bw7-FT-i3A.title" = "Save As…"; 97 | 98 | /* Class = "NSMenuItem"; title = "Close"; ObjectID = "DVo-aG-piG"; */ 99 | "DVo-aG-piG.title" = "Close"; 100 | 101 | /* Class = "NSMenuItem"; title = "Spelling and Grammar"; ObjectID = "Dv1-io-Yv7"; */ 102 | "Dv1-io-Yv7.title" = "Spelling and Grammar"; 103 | 104 | /* Class = "NSMenuItem"; title = "move to bottom"; ObjectID = "EUh-qz-H2g"; */ 105 | "EUh-qz-H2g.title" = "最下部に移動"; 106 | 107 | /* Class = "NSMenu"; title = "Help"; ObjectID = "F2S-fz-NVQ"; */ 108 | "F2S-fz-NVQ.title" = "Help"; 109 | 110 | /* Class = "NSMenuItem"; title = "⌘英かな Help"; ObjectID = "FKE-Sm-Kum"; */ 111 | "FKE-Sm-Kum.title" = "⌘英かな Help"; 112 | 113 | /* Class = "NSMenuItem"; title = "Text"; ObjectID = "Fal-I4-PZk"; */ 114 | "Fal-I4-PZk.title" = "Text"; 115 | 116 | /* Class = "NSMenu"; title = "Substitutions"; ObjectID = "FeM-D8-WVr"; */ 117 | "FeM-D8-WVr.title" = "Substitutions"; 118 | 119 | /* Class = "NSMenuItem"; title = "Bold"; ObjectID = "GB9-OM-e27"; */ 120 | "GB9-OM-e27.title" = "Bold"; 121 | 122 | /* Class = "NSMenu"; title = "Format"; ObjectID = "GEO-Iw-cKr"; */ 123 | "GEO-Iw-cKr.title" = "Format"; 124 | 125 | /* Class = "NSMenuItem"; title = "Use Default"; ObjectID = "GUa-eO-cwY"; */ 126 | "GUa-eO-cwY.title" = "Use Default"; 127 | 128 | /* Class = "NSMenuItem"; title = "Font"; ObjectID = "Gi5-1S-RQB"; */ 129 | "Gi5-1S-RQB.title" = "Font"; 130 | 131 | /* Class = "NSMenuItem"; title = "Writing Direction"; ObjectID = "H1b-Si-o9J"; */ 132 | "H1b-Si-o9J.title" = "Writing Direction"; 133 | 134 | /* Class = "NSMenuItem"; title = "View"; ObjectID = "H8h-7b-M4v"; */ 135 | "H8h-7b-M4v.title" = "View"; 136 | 137 | /* Class = "NSMenuItem"; title = "Text Replacement"; ObjectID = "HFQ-gK-NFA"; */ 138 | "HFQ-gK-NFA.title" = "Text Replacement"; 139 | 140 | /* Class = "NSMenuItem"; title = "Show Spelling and Grammar"; ObjectID = "HFo-cy-zxI"; */ 141 | "HFo-cy-zxI.title" = "Show Spelling and Grammar"; 142 | 143 | /* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "HyT-az-VxL"; */ 144 | "HyT-az-VxL.title" = "Text Cell"; 145 | 146 | /* Class = "NSMenu"; title = "View"; ObjectID = "HyV-fh-RgO"; */ 147 | "HyV-fh-RgO.title" = "View"; 148 | 149 | /* Class = "NSMenuItem"; title = "Subscript"; ObjectID = "I0S-gh-46l"; */ 150 | "I0S-gh-46l.title" = "Subscript"; 151 | 152 | /* Class = "NSMenuItem"; title = "Open…"; ObjectID = "IAo-SY-fd9"; */ 153 | "IAo-SY-fd9.title" = "Open…"; 154 | 155 | /* Class = "NSWindow"; title = "Window"; ObjectID = "IQv-IB-iLA"; */ 156 | "IQv-IB-iLA.title" = "Window"; 157 | 158 | /* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "Il7-rb-WM6"; */ 159 | "Il7-rb-WM6.title" = "Text Cell"; 160 | 161 | /* Class = "NSMenuItem"; title = "Justify"; ObjectID = "J5U-5w-g23"; */ 162 | "J5U-5w-g23.title" = "Justify"; 163 | 164 | /* Class = "NSMenuItem"; title = "Use None"; ObjectID = "J7y-lM-qPV"; */ 165 | "J7y-lM-qPV.title" = "Use None"; 166 | 167 | /* Class = "NSMenuItem"; title = "Revert to Saved"; ObjectID = "KaW-ft-85H"; */ 168 | "KaW-ft-85H.title" = "Revert to Saved"; 169 | 170 | /* Class = "NSMenuItem"; title = "Show All"; ObjectID = "Kd2-mp-pUS"; */ 171 | "Kd2-mp-pUS.title" = "Show All"; 172 | 173 | /* Class = "NSMenuItem"; title = "Bring All to Front"; ObjectID = "LE2-aR-0XJ"; */ 174 | "LE2-aR-0XJ.title" = "Bring All to Front"; 175 | 176 | /* Class = "NSMenuItem"; title = "Paste Ruler"; ObjectID = "LVM-kO-fVI"; */ 177 | "LVM-kO-fVI.title" = "Paste Ruler"; 178 | 179 | /* Class = "NSMenuItem"; title = "\tLeft to Right"; ObjectID = "Lbh-J2-qVU"; */ 180 | "Lbh-J2-qVU.title" = "\tLeft to Right"; 181 | 182 | /* Class = "NSMenuItem"; title = "Copy Ruler"; ObjectID = "MkV-Pr-PK5"; */ 183 | "MkV-Pr-PK5.title" = "Copy Ruler"; 184 | 185 | /* Class = "NSMenuItem"; title = "Services"; ObjectID = "NMo-om-nkz"; */ 186 | "NMo-om-nkz.title" = "Services"; 187 | 188 | /* Class = "NSMenuItem"; title = "\tDefault"; ObjectID = "Nop-cj-93Q"; */ 189 | "Nop-cj-93Q.title" = "\tDefault"; 190 | 191 | /* Class = "NSMenuItem"; title = "Minimize"; ObjectID = "OY7-WF-poV"; */ 192 | "OY7-WF-poV.title" = "Minimize"; 193 | 194 | /* Class = "NSMenuItem"; title = "Baseline"; ObjectID = "OaQ-X3-Vso"; */ 195 | "OaQ-X3-Vso.title" = "Baseline"; 196 | 197 | /* Class = "NSMenuItem"; title = "Hide ⌘英かな"; ObjectID = "Olw-nP-bQN"; */ 198 | "Olw-nP-bQN.title" = "Hide ⌘英かな"; 199 | 200 | /* Class = "NSMenuItem"; title = "Find Previous"; ObjectID = "OwM-mh-QMV"; */ 201 | "OwM-mh-QMV.title" = "Find Previous"; 202 | 203 | /* Class = "NSMenuItem"; title = "Stop Speaking"; ObjectID = "Oyz-dy-DGm"; */ 204 | "Oyz-dy-DGm.title" = "Stop Speaking"; 205 | 206 | /* Class = "NSMenuItem"; title = "Bigger"; ObjectID = "Ptp-SP-VEL"; */ 207 | "Ptp-SP-VEL.title" = "Bigger"; 208 | 209 | /* Class = "NSMenuItem"; title = "Show Fonts"; ObjectID = "Q5e-8K-NDq"; */ 210 | "Q5e-8K-NDq.title" = "Show Fonts"; 211 | 212 | /* Class = "NSMenuItem"; title = "Zoom"; ObjectID = "R4o-n2-Eq4"; */ 213 | "R4o-n2-Eq4.title" = "Zoom"; 214 | 215 | /* Class = "NSMenuItem"; title = "\tRight to Left"; ObjectID = "RB4-Sm-HuC"; */ 216 | "RB4-Sm-HuC.title" = "\tRight to Left"; 217 | 218 | /* Class = "NSMenuItem"; title = "Superscript"; ObjectID = "Rqc-34-cIF"; */ 219 | "Rqc-34-cIF.title" = "Superscript"; 220 | 221 | /* Class = "NSMenuItem"; title = "Select All"; ObjectID = "Ruw-6m-B2m"; */ 222 | "Ruw-6m-B2m.title" = "Select All"; 223 | 224 | /* Class = "NSMenuItem"; title = "Jump to Selection"; ObjectID = "S0p-oC-mLd"; */ 225 | "S0p-oC-mLd.title" = "Jump to Selection"; 226 | 227 | /* Class = "NSMenuItem"; title = "move to the top"; ObjectID = "SPl-n7-KTj"; */ 228 | "SPl-n7-KTj.title" = "最上部に移動"; 229 | 230 | /* Class = "NSButtonCell"; title = "show icon on menu bar"; ObjectID = "Swa-9Q-bjA"; */ 231 | "Swa-9Q-bjA.title" = "メニューバーにアイコンを表示"; 232 | 233 | /* Class = "NSMenu"; title = "Window"; ObjectID = "Td7-aD-5lo"; */ 234 | "Td7-aD-5lo.title" = "Window"; 235 | 236 | /* Class = "NSMenuItem"; title = "Capitalize"; ObjectID = "UEZ-Bs-lqG"; */ 237 | "UEZ-Bs-lqG.title" = "Capitalize"; 238 | 239 | /* Class = "NSButtonCell"; title = "start with system login"; ObjectID = "UJa-91-PJq"; */ 240 | "UJa-91-PJq.title" = "ログイン後にこのアプリを起動"; 241 | 242 | /* Class = "NSMenuItem"; title = "Center"; ObjectID = "VIY-Ag-zcb"; */ 243 | "VIY-Ag-zcb.title" = "Center"; 244 | 245 | /* Class = "NSMenuItem"; title = "Hide Others"; ObjectID = "Vdr-fp-XzO"; */ 246 | "Vdr-fp-XzO.title" = "Hide Others"; 247 | 248 | /* Class = "NSMenuItem"; title = "Italic"; ObjectID = "Vjx-xi-njq"; */ 249 | "Vjx-xi-njq.title" = "Italic"; 250 | 251 | /* Class = "NSMenu"; title = "Edit"; ObjectID = "W48-6f-4Dl"; */ 252 | "W48-6f-4Dl.title" = "Edit"; 253 | 254 | /* Class = "NSMenuItem"; title = "Underline"; ObjectID = "WRG-CD-K1S"; */ 255 | "WRG-CD-K1S.title" = "Underline"; 256 | 257 | /* Class = "NSMenuItem"; title = "New"; ObjectID = "Was-JA-tGl"; */ 258 | "Was-JA-tGl.title" = "New"; 259 | 260 | /* Class = "NSMenuItem"; title = "Paste and Match Style"; ObjectID = "WeT-3V-zwk"; */ 261 | "WeT-3V-zwk.title" = "Paste and Match Style"; 262 | 263 | /* Class = "NSMenuItem"; title = "Find…"; ObjectID = "Xz5-n4-O0W"; */ 264 | "Xz5-n4-O0W.title" = "Find…"; 265 | 266 | /* Class = "NSTextFieldCell"; title = "remapping is disabled for checked applications"; ObjectID = "Y1I-k0-J1y"; */ 267 | "Y1I-k0-J1y.title" = "チェックがあるアプリではリマップが無効になります"; 268 | 269 | /* Class = "NSMenuItem"; title = "Find and Replace…"; ObjectID = "YEy-JH-Tfz"; */ 270 | "YEy-JH-Tfz.title" = "Find and Replace…"; 271 | 272 | /* Class = "NSMenuItem"; title = "\tDefault"; ObjectID = "YGs-j5-SAR"; */ 273 | "YGs-j5-SAR.title" = "\tDefault"; 274 | 275 | /* Class = "NSMenuItem"; title = "Start Speaking"; ObjectID = "Ynk-f8-cLZ"; */ 276 | "Ynk-f8-cLZ.title" = "Start Speaking"; 277 | 278 | /* Class = "NSMenuItem"; title = "Align Left"; ObjectID = "ZM1-6Q-yy1"; */ 279 | "ZM1-6Q-yy1.title" = "Align Left"; 280 | 281 | /* Class = "NSMenuItem"; title = "Paragraph"; ObjectID = "ZvO-Gk-QUH"; */ 282 | "ZvO-Gk-QUH.title" = "Paragraph"; 283 | 284 | /* Class = "NSMenuItem"; title = "Print…"; ObjectID = "aTl-1u-JFS"; */ 285 | "aTl-1u-JFS.title" = "Print…"; 286 | 287 | /* Class = "NSMenuItem"; title = "Window"; ObjectID = "aUF-d1-5bR"; */ 288 | "aUF-d1-5bR.title" = "Window"; 289 | 290 | /* Class = "NSMenu"; title = "Font"; ObjectID = "aXa-aM-Jaq"; */ 291 | "aXa-aM-Jaq.title" = "Font"; 292 | 293 | /* Class = "NSMenuItem"; title = "Use Default"; ObjectID = "agt-UL-0e3"; */ 294 | "agt-UL-0e3.title" = "Use Default"; 295 | 296 | /* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "bGK-Pv-Let"; */ 297 | "bGK-Pv-Let.title" = "Text Cell"; 298 | 299 | /* Class = "NSMenuItem"; title = "Show Colors"; ObjectID = "bgn-CT-cEk"; */ 300 | "bgn-CT-cEk.title" = "Show Colors"; 301 | 302 | /* Class = "NSMenu"; title = "File"; ObjectID = "bib-Uj-vzu"; */ 303 | "bib-Uj-vzu.title" = "File"; 304 | 305 | /* Class = "NSMenuItem"; title = "Use Selection for Find"; ObjectID = "buJ-ug-pKt"; */ 306 | "buJ-ug-pKt.title" = "Use Selection for Find"; 307 | 308 | /* Class = "NSMenu"; title = "Transformations"; ObjectID = "c8a-y6-VQd"; */ 309 | "c8a-y6-VQd.title" = "Transformations"; 310 | 311 | /* Class = "NSMenuItem"; title = "Use None"; ObjectID = "cDB-IK-hbR"; */ 312 | "cDB-IK-hbR.title" = "Use None"; 313 | 314 | /* Class = "NSMenuItem"; title = "Selection"; ObjectID = "cqv-fj-IhA"; */ 315 | "cqv-fj-IhA.title" = "Selection"; 316 | 317 | /* Class = "NSMenuItem"; title = "Smart Links"; ObjectID = "cwL-P1-jid"; */ 318 | "cwL-P1-jid.title" = "Smart Links"; 319 | 320 | /* Class = "NSMenuItem"; title = "Make Lower Case"; ObjectID = "d9M-CD-aMd"; */ 321 | "d9M-CD-aMd.title" = "Make Lower Case"; 322 | 323 | /* Class = "NSMenu"; title = "Text"; ObjectID = "d9c-me-L2H"; */ 324 | "d9c-me-L2H.title" = "Text"; 325 | 326 | /* Class = "NSMenuItem"; title = "File"; ObjectID = "dMs-cI-mzQ"; */ 327 | "dMs-cI-mzQ.title" = "File"; 328 | 329 | /* Class = "NSMenuItem"; title = "Undo"; ObjectID = "dRJ-4n-Yzg"; */ 330 | "dRJ-4n-Yzg.title" = "Undo"; 331 | 332 | /* Class = "NSTableColumn"; headerCell.title = "output"; ObjectID = "enk-hD-eRH"; */ 333 | "enk-hD-eRH.headerCell.title" = "output"; 334 | 335 | /* Class = "NSComboBoxCell"; title = "Eisuu"; ObjectID = "f2N-dm-xIa"; */ 336 | "f2N-dm-xIa.title" = "Eisuu"; 337 | 338 | /* Class = "NSComboBoxCell"; f2N-dm-xIa.ibShadowedObjectValues[0] = "英数"; ObjectID = "f2N-dm-xIa"; */ 339 | "f2N-dm-xIa.ibShadowedObjectValues[0]" = "英数"; 340 | 341 | /* Class = "NSComboBoxCell"; f2N-dm-xIa.ibShadowedObjectValues[1] = "かな"; ObjectID = "f2N-dm-xIa"; */ 342 | "f2N-dm-xIa.ibShadowedObjectValues[1]" = "かな"; 343 | 344 | /* Class = "NSComboBoxCell"; f2N-dm-xIa.ibShadowedObjectValues[2] = "⇧かな"; ObjectID = "f2N-dm-xIa"; */ 345 | "f2N-dm-xIa.ibShadowedObjectValues[2]" = "⇧かな"; 346 | 347 | /* Class = "NSComboBoxCell"; f2N-dm-xIa.ibShadowedObjectValues[3] = "select the previous input source"; ObjectID = "f2N-dm-xIa"; */ 348 | "f2N-dm-xIa.ibShadowedObjectValues[3]" = "前の入力ソースを選択"; 349 | 350 | /* Class = "NSComboBoxCell"; f2N-dm-xIa.ibShadowedObjectValues[4] = "select next source in input menu"; ObjectID = "f2N-dm-xIa"; */ 351 | "f2N-dm-xIa.ibShadowedObjectValues[4]" = "入力メニューの次のソースを選択"; 352 | 353 | /* Class = "NSComboBoxCell"; f2N-dm-xIa.ibShadowedObjectValues[5] = "Disable"; ObjectID = "f2N-dm-xIa"; */ 354 | "f2N-dm-xIa.ibShadowedObjectValues[5]" = "Disable"; 355 | 356 | /* Class = "NSMenuItem"; title = "move one down"; ObjectID = "fY1-dw-1o1"; */ 357 | "fY1-dw-1o1.title" = "1つ下に移動"; 358 | 359 | /* Class = "NSMenuItem"; title = "Paste"; ObjectID = "gVA-U4-sdL"; */ 360 | "gVA-U4-sdL.title" = "Paste"; 361 | 362 | /* Class = "NSMenuItem"; title = "menu"; ObjectID = "hM9-HT-fqx"; */ 363 | "hM9-HT-fqx.title" = "menu"; 364 | 365 | /* Class = "NSMenuItem"; title = "Smart Quotes"; ObjectID = "hQb-2v-fYv"; */ 366 | "hQb-2v-fYv.title" = "Smart Quotes"; 367 | 368 | /* Class = "NSButtonCell"; title = "Quit ⌘英かな"; ObjectID = "heb-5j-piH"; */ 369 | "heb-5j-piH.title" = "Quit ⌘英かな"; 370 | 371 | /* Class = "NSMenuItem"; title = "Check Document Now"; ObjectID = "hz2-CU-CR7"; */ 372 | "hz2-CU-CR7.title" = "Check Document Now"; 373 | 374 | /* Class = "NSMenu"; title = "Services"; ObjectID = "hz9-B4-Xy5"; */ 375 | "hz9-B4-Xy5.title" = "Services"; 376 | 377 | /* Class = "NSMenuItem"; title = "Smaller"; ObjectID = "i1d-Er-qST"; */ 378 | "i1d-Er-qST.title" = "Smaller"; 379 | 380 | /* Class = "NSMenu"; title = "Baseline"; ObjectID = "ijk-EB-dga"; */ 381 | "ijk-EB-dga.title" = "Baseline"; 382 | 383 | /* Class = "NSMenuItem"; title = "Kern"; ObjectID = "jBQ-r6-VK2"; */ 384 | "jBQ-r6-VK2.title" = "Kern"; 385 | 386 | /* Class = "NSMenuItem"; title = "\tRight to Left"; ObjectID = "jFq-tB-4Kx"; */ 387 | "jFq-tB-4Kx.title" = "\tRight to Left"; 388 | 389 | /* Class = "NSMenuItem"; title = "Format"; ObjectID = "jxT-CU-nIS"; */ 390 | "jxT-CU-nIS.title" = "Format"; 391 | 392 | /* Class = "NSMenuItem"; title = "Check Grammar With Spelling"; ObjectID = "mK6-2p-4JG"; */ 393 | "mK6-2p-4JG.title" = "Check Grammar With Spelling"; 394 | 395 | /* Class = "NSMenuItem"; title = "Ligatures"; ObjectID = "o6e-r0-MWq"; */ 396 | "o6e-r0-MWq.title" = "Ligatures"; 397 | 398 | /* Class = "NSMenu"; title = "Open Recent"; ObjectID = "oas-Oc-fiZ"; */ 399 | "oas-Oc-fiZ.title" = "Open Recent"; 400 | 401 | /* Class = "NSMenuItem"; title = "Loosen"; ObjectID = "ogc-rX-tC1"; */ 402 | "ogc-rX-tC1.title" = "Loosen"; 403 | 404 | /* Class = "NSMenuItem"; title = "Delete"; ObjectID = "pa3-QI-u2k"; */ 405 | "pa3-QI-u2k.title" = "Delete"; 406 | 407 | /* Class = "NSTableColumn"; headerCell.title = "Identifier"; ObjectID = "paP-xc-yLu"; */ 408 | "paP-xc-yLu.headerCell.title" = "Identifier"; 409 | 410 | /* Class = "NSMenuItem"; title = "Save…"; ObjectID = "pxx-59-PXV"; */ 411 | "pxx-59-PXV.title" = "Save…"; 412 | 413 | /* Class = "NSMenuItem"; title = "Find Next"; ObjectID = "q09-fT-Sye"; */ 414 | "q09-fT-Sye.title" = "Find Next"; 415 | 416 | /* Class = "NSComboBoxCell"; title = "Command_R"; ObjectID = "qIB-xs-Dfg"; */ 417 | "qIB-xs-Dfg.title" = "Command_R"; 418 | 419 | /* Class = "NSComboBoxCell"; qIB-xs-Dfg.ibShadowedObjectValues[0] = "英数"; ObjectID = "qIB-xs-Dfg"; */ 420 | "qIB-xs-Dfg.ibShadowedObjectValues[0]" = "英数"; 421 | 422 | /* Class = "NSComboBoxCell"; qIB-xs-Dfg.ibShadowedObjectValues[1] = "かな"; ObjectID = "qIB-xs-Dfg"; */ 423 | "qIB-xs-Dfg.ibShadowedObjectValues[1]" = "かな"; 424 | 425 | /* Class = "NSComboBoxCell"; qIB-xs-Dfg.ibShadowedObjectValues[2] = "⇧かな"; ObjectID = "qIB-xs-Dfg"; */ 426 | "qIB-xs-Dfg.ibShadowedObjectValues[2]" = "⇧かな"; 427 | 428 | /* Class = "NSMenuItem"; title = "Page Setup…"; ObjectID = "qIS-W8-SiK"; */ 429 | "qIS-W8-SiK.title" = "Page Setup…"; 430 | 431 | /* Class = "NSMenuItem"; title = "Check Spelling While Typing"; ObjectID = "rbD-Rh-wIN"; */ 432 | "rbD-Rh-wIN.title" = "Check Spelling While Typing"; 433 | 434 | /* Class = "NSMenuItem"; title = "Smart Dashes"; ObjectID = "rgM-f4-ycn"; */ 435 | "rgM-f4-ycn.title" = "Smart Dashes"; 436 | 437 | /* Class = "NSMenuItem"; title = "Show Toolbar"; ObjectID = "snW-S8-Cw5"; */ 438 | "snW-S8-Cw5.title" = "Show Toolbar"; 439 | 440 | /* Class = "NSMenuItem"; title = "Data Detectors"; ObjectID = "tRr-pd-1PS"; */ 441 | "tRr-pd-1PS.title" = "Data Detectors"; 442 | 443 | /* Class = "NSMenuItem"; title = "Open Recent"; ObjectID = "tXI-mr-wws"; */ 444 | "tXI-mr-wws.title" = "Open Recent"; 445 | 446 | /* Class = "NSMenu"; title = "Kern"; ObjectID = "tlD-Oa-oAM"; */ 447 | "tlD-Oa-oAM.title" = "Kern"; 448 | 449 | /* Class = "NSMenu"; title = "⌘英かな"; ObjectID = "uQy-DD-JDr"; */ 450 | "uQy-DD-JDr.title" = "⌘英かな"; 451 | 452 | /* Class = "NSMenuItem"; title = "Cut"; ObjectID = "uRl-iY-unG"; */ 453 | "uRl-iY-unG.title" = "Cut"; 454 | 455 | /* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "uTH-4i-rjb"; */ 456 | "uTH-4i-rjb.title" = "Text Cell"; 457 | 458 | /* Class = "NSViewController"; title = "Setting"; ObjectID = "uYA-LV-zsC"; */ 459 | "uYA-LV-zsC.title" = "設定"; 460 | 461 | /* Class = "NSTextFieldCell"; title = "Text"; ObjectID = "ugI-Ze-ysm"; */ 462 | "ugI-Ze-ysm.title" = "Text"; 463 | 464 | /* Class = "NSMenuItem"; title = "Paste Style"; ObjectID = "vKC-jM-MkH"; */ 465 | "vKC-jM-MkH.title" = "Paste Style"; 466 | 467 | /* Class = "NSMenuItem"; title = "Show Ruler"; ObjectID = "vLm-3I-IUL"; */ 468 | "vLm-3I-IUL.title" = "Show Ruler"; 469 | 470 | /* Class = "NSMenuItem"; title = "Clear Menu"; ObjectID = "vNY-rz-j42"; */ 471 | "vNY-rz-j42.title" = "Clear Menu"; 472 | 473 | /* Class = "NSMenuItem"; title = "Make Upper Case"; ObjectID = "vmV-6d-7jI"; */ 474 | "vmV-6d-7jI.title" = "Make Upper Case"; 475 | 476 | /* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "vq8-Nd-QTc"; */ 477 | "vq8-Nd-QTc.title" = "Text Cell"; 478 | 479 | /* Class = "NSMenu"; title = "Ligatures"; ObjectID = "w0m-vy-SC9"; */ 480 | "w0m-vy-SC9.title" = "Ligatures"; 481 | 482 | /* Class = "NSMenuItem"; title = "Align Right"; ObjectID = "wb2-vD-lq4"; */ 483 | "wb2-vD-lq4.title" = "Align Right"; 484 | 485 | /* Class = "NSMenuItem"; title = "Help"; ObjectID = "wpr-3q-Mcd"; */ 486 | "wpr-3q-Mcd.title" = "Help"; 487 | 488 | /* Class = "NSMenuItem"; title = "Copy"; ObjectID = "x3v-GG-iWU"; */ 489 | "x3v-GG-iWU.title" = "Copy"; 490 | 491 | /* Class = "NSMenuItem"; title = "Use All"; ObjectID = "xQD-1f-W4t"; */ 492 | "xQD-1f-W4t.title" = "Use All"; 493 | 494 | /* Class = "NSTabViewController"; title = "⌘英かな"; ObjectID = "xjl-OD-0Sx"; */ 495 | "xjl-OD-0Sx.title" = "⌘英かな"; 496 | 497 | /* Class = "NSMenuItem"; title = "Speech"; ObjectID = "xrE-MZ-jX0"; */ 498 | "xrE-MZ-jX0.title" = "Speech"; 499 | 500 | /* Class = "NSMenuItem"; title = "Show Substitutions"; ObjectID = "z6F-FW-3nz"; */ 501 | "z6F-FW-3nz.title" = "Show Substitutions"; 502 | -------------------------------------------------------------------------------- /Eikana.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 620E0B441D9F2F8F0067F88B /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 620E0B431D9F2F8F0067F88B /* AppDelegate.m */; }; 11 | 620E0B471D9F2F8F0067F88B /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 620E0B461D9F2F8F0067F88B /* main.m */; }; 12 | 620E0B491D9F2F8F0067F88B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 620E0B481D9F2F8F0067F88B /* Assets.xcassets */; }; 13 | 620E0B4C1D9F2F8F0067F88B /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 620E0B4A1D9F2F8F0067F88B /* MainMenu.xib */; }; 14 | 620E0B511D9F31E30067F88B /* Eikana-helper.app in CopyFiles */ = {isa = PBXBuildFile; fileRef = 620E0B401D9F2F8F0067F88B /* Eikana-helper.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 15 | 620E47771DB3C6E9004A2664 /* MappingMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 620E47761DB3C6E9004A2664 /* MappingMenu.swift */; }; 16 | 623E2E071DA60DA800AF163C /* PreferenceWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 623E2E061DA60DA800AF163C /* PreferenceWindowController.swift */; }; 17 | 6242D4BC1DA2455D00CA80DD /* KeyboardShortcut.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6242D4BB1DA2455D00CA80DD /* KeyboardShortcut.swift */; }; 18 | 6242D4BE1DA395AC00CA80DD /* KeyTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6242D4BD1DA395AC00CA80DD /* KeyTextField.swift */; }; 19 | 624BF4CA1DD182F500A70E2C /* MediaKeyEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 624BF4C91DD182F500A70E2C /* MediaKeyEvent.swift */; }; 20 | 6259C7041EA46E43001444A1 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6259C7031EA46E43001444A1 /* Sparkle.framework */; }; 21 | 6259C7081EA48433001444A1 /* appcast.xml in Resources */ = {isa = PBXBuildFile; fileRef = 6259C7071EA48433001444A1 /* appcast.xml */; }; 22 | 6259C70A1EA4861C001444A1 /* dsa_pub.pem in Resources */ = {isa = PBXBuildFile; fileRef = 6259C7091EA4861C001444A1 /* dsa_pub.pem */; }; 23 | 627265F61D3CC84000703F85 /* KeyEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 627265F51D3CC84000703F85 /* KeyEvent.swift */; }; 24 | 628908EE1DADB0B6008EF46A /* KeyMapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = 628908ED1DADB0B6008EF46A /* KeyMapping.swift */; }; 25 | 6294281B1D387503001BD4E9 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6294281A1D387503001BD4E9 /* AppDelegate.swift */; }; 26 | 6294281D1D387503001BD4E9 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6294281C1D387503001BD4E9 /* ViewController.swift */; }; 27 | 6294281F1D387503001BD4E9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6294281E1D387503001BD4E9 /* Assets.xcassets */; }; 28 | 629428221D387503001BD4E9 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 629428201D387503001BD4E9 /* Main.storyboard */; }; 29 | 62BEA2A41DA739B6004409AE /* ShortcutsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62BEA2A31DA739B6004409AE /* ShortcutsController.swift */; }; 30 | 62D162E71D3B350B009C95B0 /* toggleLaunchAtStartup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62D162E61D3B350B009C95B0 /* toggleLaunchAtStartup.swift */; }; 31 | 62FE51611DC70C5B0037B8D1 /* ExclusionAppsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62FE51601DC70C5B0037B8D1 /* ExclusionAppsController.swift */; }; 32 | 62FE51631DC75ECE0037B8D1 /* AppData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62FE51621DC75ECE0037B8D1 /* AppData.swift */; }; 33 | /* End PBXBuildFile section */ 34 | 35 | /* Begin PBXCopyFilesBuildPhase section */ 36 | 6289285F1D99021700313C05 /* CopyFiles */ = { 37 | isa = PBXCopyFilesBuildPhase; 38 | buildActionMask = 2147483647; 39 | dstPath = Contents/Library/LoginItems; 40 | dstSubfolderSpec = 1; 41 | files = ( 42 | 620E0B511D9F31E30067F88B /* Eikana-helper.app in CopyFiles */, 43 | ); 44 | runOnlyForDeploymentPostprocessing = 0; 45 | }; 46 | /* End PBXCopyFilesBuildPhase section */ 47 | 48 | /* Begin PBXFileReference section */ 49 | 620E0B401D9F2F8F0067F88B /* Eikana-helper.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Eikana-helper.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 50 | 620E0B421D9F2F8F0067F88B /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 51 | 620E0B431D9F2F8F0067F88B /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 52 | 620E0B461D9F2F8F0067F88B /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 53 | 620E0B481D9F2F8F0067F88B /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 54 | 620E0B4B1D9F2F8F0067F88B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; 55 | 620E0B4D1D9F2F8F0067F88B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 56 | 620E47761DB3C6E9004A2664 /* MappingMenu.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MappingMenu.swift; sourceTree = ""; }; 57 | 620F5D681EA45B3300942FCC /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Main.strings; sourceTree = ""; }; 58 | 623E2E061DA60DA800AF163C /* PreferenceWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PreferenceWindowController.swift; sourceTree = ""; }; 59 | 6242D4BB1DA2455D00CA80DD /* KeyboardShortcut.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyboardShortcut.swift; sourceTree = ""; }; 60 | 6242D4BD1DA395AC00CA80DD /* KeyTextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyTextField.swift; sourceTree = ""; }; 61 | 624BF4C91DD182F500A70E2C /* MediaKeyEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MediaKeyEvent.swift; sourceTree = ""; }; 62 | 6259C7031EA46E43001444A1 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sparkle.framework; path = Carthage/Build/Mac/Sparkle.framework; sourceTree = ""; }; 63 | 6259C7071EA48433001444A1 /* appcast.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = appcast.xml; path = docs/appcast.xml; sourceTree = SOURCE_ROOT; }; 64 | 6259C7091EA4861C001444A1 /* dsa_pub.pem */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = dsa_pub.pem; sourceTree = ""; }; 65 | 627265F51D3CC84000703F85 /* KeyEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyEvent.swift; sourceTree = ""; }; 66 | 628908ED1DADB0B6008EF46A /* KeyMapping.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyMapping.swift; sourceTree = ""; }; 67 | 629428171D387503001BD4E9 /* Eikana.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Eikana.app; sourceTree = BUILT_PRODUCTS_DIR; }; 68 | 6294281A1D387503001BD4E9 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 69 | 6294281C1D387503001BD4E9 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 70 | 6294281E1D387503001BD4E9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 71 | 629428211D387503001BD4E9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 72 | 629428231D387503001BD4E9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 73 | 62BEA2A31DA739B6004409AE /* ShortcutsController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShortcutsController.swift; sourceTree = ""; }; 74 | 62D162E61D3B350B009C95B0 /* toggleLaunchAtStartup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = toggleLaunchAtStartup.swift; sourceTree = ""; }; 75 | 62FE51601DC70C5B0037B8D1 /* ExclusionAppsController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExclusionAppsController.swift; sourceTree = ""; }; 76 | 62FE51621DC75ECE0037B8D1 /* AppData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppData.swift; sourceTree = ""; }; 77 | /* End PBXFileReference section */ 78 | 79 | /* Begin PBXFrameworksBuildPhase section */ 80 | 620E0B3D1D9F2F8F0067F88B /* Frameworks */ = { 81 | isa = PBXFrameworksBuildPhase; 82 | buildActionMask = 2147483647; 83 | files = ( 84 | ); 85 | runOnlyForDeploymentPostprocessing = 0; 86 | }; 87 | 629428141D387503001BD4E9 /* Frameworks */ = { 88 | isa = PBXFrameworksBuildPhase; 89 | buildActionMask = 2147483647; 90 | files = ( 91 | 6259C7041EA46E43001444A1 /* Sparkle.framework in Frameworks */, 92 | ); 93 | runOnlyForDeploymentPostprocessing = 0; 94 | }; 95 | /* End PBXFrameworksBuildPhase section */ 96 | 97 | /* Begin PBXGroup section */ 98 | 620E0B411D9F2F8F0067F88B /* Eikana-helper */ = { 99 | isa = PBXGroup; 100 | children = ( 101 | 620E0B421D9F2F8F0067F88B /* AppDelegate.h */, 102 | 620E0B431D9F2F8F0067F88B /* AppDelegate.m */, 103 | 620E0B481D9F2F8F0067F88B /* Assets.xcassets */, 104 | 620E0B4A1D9F2F8F0067F88B /* MainMenu.xib */, 105 | 620E0B4D1D9F2F8F0067F88B /* Info.plist */, 106 | 620E0B451D9F2F8F0067F88B /* Supporting Files */, 107 | ); 108 | path = "Eikana-helper"; 109 | sourceTree = ""; 110 | }; 111 | 620E0B451D9F2F8F0067F88B /* Supporting Files */ = { 112 | isa = PBXGroup; 113 | children = ( 114 | 620E0B461D9F2F8F0067F88B /* main.m */, 115 | ); 116 | name = "Supporting Files"; 117 | sourceTree = ""; 118 | }; 119 | 6259C7021EA46E43001444A1 /* Frameworks */ = { 120 | isa = PBXGroup; 121 | children = ( 122 | 6259C7031EA46E43001444A1 /* Sparkle.framework */, 123 | ); 124 | name = Frameworks; 125 | sourceTree = ""; 126 | }; 127 | 6259C7061EA483B7001444A1 /* docs */ = { 128 | isa = PBXGroup; 129 | children = ( 130 | 6259C7071EA48433001444A1 /* appcast.xml */, 131 | ); 132 | name = docs; 133 | path = Eikana; 134 | sourceTree = ""; 135 | }; 136 | 6294280E1D387503001BD4E9 = { 137 | isa = PBXGroup; 138 | children = ( 139 | 629428191D387503001BD4E9 /* Eikana */, 140 | 620E0B411D9F2F8F0067F88B /* Eikana-helper */, 141 | 6259C7061EA483B7001444A1 /* docs */, 142 | 629428181D387503001BD4E9 /* Products */, 143 | 6259C7021EA46E43001444A1 /* Frameworks */, 144 | ); 145 | sourceTree = ""; 146 | }; 147 | 629428181D387503001BD4E9 /* Products */ = { 148 | isa = PBXGroup; 149 | children = ( 150 | 629428171D387503001BD4E9 /* Eikana.app */, 151 | 620E0B401D9F2F8F0067F88B /* Eikana-helper.app */, 152 | ); 153 | name = Products; 154 | sourceTree = ""; 155 | }; 156 | 629428191D387503001BD4E9 /* Eikana */ = { 157 | isa = PBXGroup; 158 | children = ( 159 | 6294281A1D387503001BD4E9 /* AppDelegate.swift */, 160 | 62D162E61D3B350B009C95B0 /* toggleLaunchAtStartup.swift */, 161 | 627265F51D3CC84000703F85 /* KeyEvent.swift */, 162 | 6242D4BB1DA2455D00CA80DD /* KeyboardShortcut.swift */, 163 | 624BF4C91DD182F500A70E2C /* MediaKeyEvent.swift */, 164 | 62FE51621DC75ECE0037B8D1 /* AppData.swift */, 165 | 628908ED1DADB0B6008EF46A /* KeyMapping.swift */, 166 | 6294281E1D387503001BD4E9 /* Assets.xcassets */, 167 | 629428201D387503001BD4E9 /* Main.storyboard */, 168 | 623E2E061DA60DA800AF163C /* PreferenceWindowController.swift */, 169 | 62BEA2A31DA739B6004409AE /* ShortcutsController.swift */, 170 | 62FE51601DC70C5B0037B8D1 /* ExclusionAppsController.swift */, 171 | 6294281C1D387503001BD4E9 /* ViewController.swift */, 172 | 620E47761DB3C6E9004A2664 /* MappingMenu.swift */, 173 | 6242D4BD1DA395AC00CA80DD /* KeyTextField.swift */, 174 | 629428231D387503001BD4E9 /* Info.plist */, 175 | 6259C7091EA4861C001444A1 /* dsa_pub.pem */, 176 | ); 177 | path = Eikana; 178 | sourceTree = ""; 179 | }; 180 | /* End PBXGroup section */ 181 | 182 | /* Begin PBXNativeTarget section */ 183 | 620E0B3F1D9F2F8F0067F88B /* Eikana-helper */ = { 184 | isa = PBXNativeTarget; 185 | buildConfigurationList = 620E0B4E1D9F2F8F0067F88B /* Build configuration list for PBXNativeTarget "Eikana-helper" */; 186 | buildPhases = ( 187 | 620E0B3C1D9F2F8F0067F88B /* Sources */, 188 | 620E0B3D1D9F2F8F0067F88B /* Frameworks */, 189 | 620E0B3E1D9F2F8F0067F88B /* Resources */, 190 | ); 191 | buildRules = ( 192 | ); 193 | dependencies = ( 194 | ); 195 | name = "Eikana-helper"; 196 | productName = "cmd-eikana-helper"; 197 | productReference = 620E0B401D9F2F8F0067F88B /* Eikana-helper.app */; 198 | productType = "com.apple.product-type.application"; 199 | }; 200 | 629428161D387503001BD4E9 /* Eikana */ = { 201 | isa = PBXNativeTarget; 202 | buildConfigurationList = 629428311D387503001BD4E9 /* Build configuration list for PBXNativeTarget "Eikana" */; 203 | buildPhases = ( 204 | 629428131D387503001BD4E9 /* Sources */, 205 | 629428141D387503001BD4E9 /* Frameworks */, 206 | 629428151D387503001BD4E9 /* Resources */, 207 | 6289285F1D99021700313C05 /* CopyFiles */, 208 | 6259C7051EA46E5A001444A1 /* ShellScript */, 209 | ); 210 | buildRules = ( 211 | ); 212 | dependencies = ( 213 | ); 214 | name = Eikana; 215 | productName = StatusBarApp; 216 | productReference = 629428171D387503001BD4E9 /* Eikana.app */; 217 | productType = "com.apple.product-type.application"; 218 | }; 219 | /* End PBXNativeTarget section */ 220 | 221 | /* Begin PBXProject section */ 222 | 6294280F1D387503001BD4E9 /* Project object */ = { 223 | isa = PBXProject; 224 | attributes = { 225 | LastSwiftUpdateCheck = 0800; 226 | LastUpgradeCheck = 0800; 227 | ORGANIZATIONNAME = eikana; 228 | TargetAttributes = { 229 | 620E0B3F1D9F2F8F0067F88B = { 230 | CreatedOnToolsVersion = 8.0; 231 | ProvisioningStyle = Automatic; 232 | }; 233 | 629428161D387503001BD4E9 = { 234 | CreatedOnToolsVersion = 7.3; 235 | LastSwiftMigration = 0800; 236 | SystemCapabilities = { 237 | com.apple.Sandbox = { 238 | enabled = 0; 239 | }; 240 | }; 241 | }; 242 | }; 243 | }; 244 | buildConfigurationList = 629428121D387503001BD4E9 /* Build configuration list for PBXProject "Eikana" */; 245 | compatibilityVersion = "Xcode 3.2"; 246 | developmentRegion = English; 247 | hasScannedForEncodings = 0; 248 | knownRegions = ( 249 | en, 250 | Base, 251 | ); 252 | mainGroup = 6294280E1D387503001BD4E9; 253 | productRefGroup = 629428181D387503001BD4E9 /* Products */; 254 | projectDirPath = ""; 255 | projectRoot = ""; 256 | targets = ( 257 | 629428161D387503001BD4E9 /* Eikana */, 258 | 620E0B3F1D9F2F8F0067F88B /* Eikana-helper */, 259 | ); 260 | }; 261 | /* End PBXProject section */ 262 | 263 | /* Begin PBXResourcesBuildPhase section */ 264 | 620E0B3E1D9F2F8F0067F88B /* Resources */ = { 265 | isa = PBXResourcesBuildPhase; 266 | buildActionMask = 2147483647; 267 | files = ( 268 | 620E0B491D9F2F8F0067F88B /* Assets.xcassets in Resources */, 269 | 620E0B4C1D9F2F8F0067F88B /* MainMenu.xib in Resources */, 270 | ); 271 | runOnlyForDeploymentPostprocessing = 0; 272 | }; 273 | 629428151D387503001BD4E9 /* Resources */ = { 274 | isa = PBXResourcesBuildPhase; 275 | buildActionMask = 2147483647; 276 | files = ( 277 | 6294281F1D387503001BD4E9 /* Assets.xcassets in Resources */, 278 | 6259C70A1EA4861C001444A1 /* dsa_pub.pem in Resources */, 279 | 629428221D387503001BD4E9 /* Main.storyboard in Resources */, 280 | 6259C7081EA48433001444A1 /* appcast.xml in Resources */, 281 | ); 282 | runOnlyForDeploymentPostprocessing = 0; 283 | }; 284 | /* End PBXResourcesBuildPhase section */ 285 | 286 | /* Begin PBXShellScriptBuildPhase section */ 287 | 6259C7051EA46E5A001444A1 /* ShellScript */ = { 288 | isa = PBXShellScriptBuildPhase; 289 | buildActionMask = 2147483647; 290 | files = ( 291 | ); 292 | inputPaths = ( 293 | "$(SRCROOT)/Carthage/Build/Mac/Sparkle.framework", 294 | ); 295 | outputPaths = ( 296 | ); 297 | runOnlyForDeploymentPostprocessing = 0; 298 | shellPath = /bin/sh; 299 | shellScript = "/usr/local/bin/carthage copy-frameworks"; 300 | }; 301 | /* End PBXShellScriptBuildPhase section */ 302 | 303 | /* Begin PBXSourcesBuildPhase section */ 304 | 620E0B3C1D9F2F8F0067F88B /* Sources */ = { 305 | isa = PBXSourcesBuildPhase; 306 | buildActionMask = 2147483647; 307 | files = ( 308 | 620E0B471D9F2F8F0067F88B /* main.m in Sources */, 309 | 620E0B441D9F2F8F0067F88B /* AppDelegate.m in Sources */, 310 | ); 311 | runOnlyForDeploymentPostprocessing = 0; 312 | }; 313 | 629428131D387503001BD4E9 /* Sources */ = { 314 | isa = PBXSourcesBuildPhase; 315 | buildActionMask = 2147483647; 316 | files = ( 317 | 62FE51631DC75ECE0037B8D1 /* AppData.swift in Sources */, 318 | 62BEA2A41DA739B6004409AE /* ShortcutsController.swift in Sources */, 319 | 624BF4CA1DD182F500A70E2C /* MediaKeyEvent.swift in Sources */, 320 | 627265F61D3CC84000703F85 /* KeyEvent.swift in Sources */, 321 | 620E47771DB3C6E9004A2664 /* MappingMenu.swift in Sources */, 322 | 6294281D1D387503001BD4E9 /* ViewController.swift in Sources */, 323 | 62D162E71D3B350B009C95B0 /* toggleLaunchAtStartup.swift in Sources */, 324 | 62FE51611DC70C5B0037B8D1 /* ExclusionAppsController.swift in Sources */, 325 | 623E2E071DA60DA800AF163C /* PreferenceWindowController.swift in Sources */, 326 | 6242D4BE1DA395AC00CA80DD /* KeyTextField.swift in Sources */, 327 | 6242D4BC1DA2455D00CA80DD /* KeyboardShortcut.swift in Sources */, 328 | 628908EE1DADB0B6008EF46A /* KeyMapping.swift in Sources */, 329 | 6294281B1D387503001BD4E9 /* AppDelegate.swift in Sources */, 330 | ); 331 | runOnlyForDeploymentPostprocessing = 0; 332 | }; 333 | /* End PBXSourcesBuildPhase section */ 334 | 335 | /* Begin PBXVariantGroup section */ 336 | 620E0B4A1D9F2F8F0067F88B /* MainMenu.xib */ = { 337 | isa = PBXVariantGroup; 338 | children = ( 339 | 620E0B4B1D9F2F8F0067F88B /* Base */, 340 | ); 341 | name = MainMenu.xib; 342 | sourceTree = ""; 343 | }; 344 | 629428201D387503001BD4E9 /* Main.storyboard */ = { 345 | isa = PBXVariantGroup; 346 | children = ( 347 | 629428211D387503001BD4E9 /* Base */, 348 | 620F5D681EA45B3300942FCC /* ja */, 349 | ); 350 | name = Main.storyboard; 351 | sourceTree = ""; 352 | }; 353 | /* End PBXVariantGroup section */ 354 | 355 | /* Begin XCBuildConfiguration section */ 356 | 620E0B4F1D9F2F8F0067F88B /* Debug */ = { 357 | isa = XCBuildConfiguration; 358 | buildSettings = { 359 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 360 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 361 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 362 | COMBINE_HIDPI_IMAGES = YES; 363 | INFOPLIST_FILE = "$(SRCROOT)/Eikana-helper/Info.plist"; 364 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 365 | MACOSX_DEPLOYMENT_TARGET = 10.12; 366 | PRODUCT_BUNDLE_IDENTIFIER = "io.github.imasanari.cmd-eikana-helper"; 367 | PRODUCT_NAME = "$(TARGET_NAME)"; 368 | }; 369 | name = Debug; 370 | }; 371 | 620E0B501D9F2F8F0067F88B /* Release */ = { 372 | isa = XCBuildConfiguration; 373 | buildSettings = { 374 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 375 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 376 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 377 | COMBINE_HIDPI_IMAGES = YES; 378 | INFOPLIST_FILE = "$(SRCROOT)/Eikana-helper/Info.plist"; 379 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 380 | MACOSX_DEPLOYMENT_TARGET = 10.12; 381 | PRODUCT_BUNDLE_IDENTIFIER = "io.github.imasanari.cmd-eikana-helper"; 382 | PRODUCT_NAME = "$(TARGET_NAME)"; 383 | }; 384 | name = Release; 385 | }; 386 | 6294282F1D387503001BD4E9 /* Debug */ = { 387 | isa = XCBuildConfiguration; 388 | buildSettings = { 389 | ALWAYS_SEARCH_USER_PATHS = NO; 390 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 391 | CLANG_ANALYZER_NONNULL = YES; 392 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 393 | CLANG_CXX_LIBRARY = "libc++"; 394 | CLANG_ENABLE_MODULES = YES; 395 | CLANG_ENABLE_OBJC_ARC = YES; 396 | CLANG_WARN_BOOL_CONVERSION = YES; 397 | CLANG_WARN_CONSTANT_CONVERSION = YES; 398 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 399 | CLANG_WARN_EMPTY_BODY = YES; 400 | CLANG_WARN_ENUM_CONVERSION = YES; 401 | CLANG_WARN_INFINITE_RECURSION = YES; 402 | CLANG_WARN_INT_CONVERSION = YES; 403 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 404 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 405 | CLANG_WARN_UNREACHABLE_CODE = YES; 406 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 407 | CODE_SIGN_IDENTITY = "-"; 408 | COPY_PHASE_STRIP = NO; 409 | DEBUG_INFORMATION_FORMAT = dwarf; 410 | ENABLE_STRICT_OBJC_MSGSEND = YES; 411 | ENABLE_TESTABILITY = YES; 412 | GCC_C_LANGUAGE_STANDARD = gnu99; 413 | GCC_DYNAMIC_NO_PIC = NO; 414 | GCC_NO_COMMON_BLOCKS = YES; 415 | GCC_OPTIMIZATION_LEVEL = 0; 416 | GCC_PREPROCESSOR_DEFINITIONS = ( 417 | "DEBUG=1", 418 | "$(inherited)", 419 | ); 420 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 421 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 422 | GCC_WARN_UNDECLARED_SELECTOR = YES; 423 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 424 | GCC_WARN_UNUSED_FUNCTION = YES; 425 | GCC_WARN_UNUSED_VARIABLE = YES; 426 | MACOSX_DEPLOYMENT_TARGET = 10.11; 427 | MTL_ENABLE_DEBUG_INFO = YES; 428 | ONLY_ACTIVE_ARCH = YES; 429 | "OTHER_SWIFT_FLAGS[arch=*]" = "-D DEBUG"; 430 | SDKROOT = macosx; 431 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 432 | }; 433 | name = Debug; 434 | }; 435 | 629428301D387503001BD4E9 /* Release */ = { 436 | isa = XCBuildConfiguration; 437 | buildSettings = { 438 | ALWAYS_SEARCH_USER_PATHS = NO; 439 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 440 | CLANG_ANALYZER_NONNULL = YES; 441 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 442 | CLANG_CXX_LIBRARY = "libc++"; 443 | CLANG_ENABLE_MODULES = YES; 444 | CLANG_ENABLE_OBJC_ARC = YES; 445 | CLANG_WARN_BOOL_CONVERSION = YES; 446 | CLANG_WARN_CONSTANT_CONVERSION = YES; 447 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 448 | CLANG_WARN_EMPTY_BODY = YES; 449 | CLANG_WARN_ENUM_CONVERSION = YES; 450 | CLANG_WARN_INFINITE_RECURSION = YES; 451 | CLANG_WARN_INT_CONVERSION = YES; 452 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 453 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 454 | CLANG_WARN_UNREACHABLE_CODE = YES; 455 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 456 | CODE_SIGN_IDENTITY = "-"; 457 | COPY_PHASE_STRIP = NO; 458 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 459 | ENABLE_NS_ASSERTIONS = NO; 460 | ENABLE_STRICT_OBJC_MSGSEND = YES; 461 | GCC_C_LANGUAGE_STANDARD = gnu99; 462 | GCC_NO_COMMON_BLOCKS = YES; 463 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 464 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 465 | GCC_WARN_UNDECLARED_SELECTOR = YES; 466 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 467 | GCC_WARN_UNUSED_FUNCTION = YES; 468 | GCC_WARN_UNUSED_VARIABLE = YES; 469 | MACOSX_DEPLOYMENT_TARGET = 10.11; 470 | MTL_ENABLE_DEBUG_INFO = NO; 471 | SDKROOT = macosx; 472 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 473 | }; 474 | name = Release; 475 | }; 476 | 629428321D387503001BD4E9 /* Debug */ = { 477 | isa = XCBuildConfiguration; 478 | buildSettings = { 479 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 480 | COMBINE_HIDPI_IMAGES = YES; 481 | FRAMEWORK_SEARCH_PATHS = ( 482 | "$(inherited)", 483 | "$(PROJECT_DIR)/Carthage/Build/Mac", 484 | ); 485 | INFOPLIST_FILE = "$(SRCROOT)/Eikana/Info.plist"; 486 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 487 | MACOSX_DEPLOYMENT_TARGET = 10.11; 488 | PRODUCT_BUNDLE_IDENTIFIER = "io.github.imasanari.cmd-eikana"; 489 | PRODUCT_NAME = Eikana; 490 | SWIFT_VERSION = 3.0; 491 | }; 492 | name = Debug; 493 | }; 494 | 629428331D387503001BD4E9 /* Release */ = { 495 | isa = XCBuildConfiguration; 496 | buildSettings = { 497 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 498 | COMBINE_HIDPI_IMAGES = YES; 499 | FRAMEWORK_SEARCH_PATHS = ( 500 | "$(inherited)", 501 | "$(PROJECT_DIR)/Carthage/Build/Mac", 502 | ); 503 | INFOPLIST_FILE = "$(SRCROOT)/Eikana/Info.plist"; 504 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 505 | MACOSX_DEPLOYMENT_TARGET = 10.11; 506 | PRODUCT_BUNDLE_IDENTIFIER = "io.github.imasanari.cmd-eikana"; 507 | PRODUCT_NAME = Eikana; 508 | SWIFT_VERSION = 3.0; 509 | }; 510 | name = Release; 511 | }; 512 | /* End XCBuildConfiguration section */ 513 | 514 | /* Begin XCConfigurationList section */ 515 | 620E0B4E1D9F2F8F0067F88B /* Build configuration list for PBXNativeTarget "Eikana-helper" */ = { 516 | isa = XCConfigurationList; 517 | buildConfigurations = ( 518 | 620E0B4F1D9F2F8F0067F88B /* Debug */, 519 | 620E0B501D9F2F8F0067F88B /* Release */, 520 | ); 521 | defaultConfigurationIsVisible = 0; 522 | defaultConfigurationName = Release; 523 | }; 524 | 629428121D387503001BD4E9 /* Build configuration list for PBXProject "Eikana" */ = { 525 | isa = XCConfigurationList; 526 | buildConfigurations = ( 527 | 6294282F1D387503001BD4E9 /* Debug */, 528 | 629428301D387503001BD4E9 /* Release */, 529 | ); 530 | defaultConfigurationIsVisible = 0; 531 | defaultConfigurationName = Release; 532 | }; 533 | 629428311D387503001BD4E9 /* Build configuration list for PBXNativeTarget "Eikana" */ = { 534 | isa = XCConfigurationList; 535 | buildConfigurations = ( 536 | 629428321D387503001BD4E9 /* Debug */, 537 | 629428331D387503001BD4E9 /* Release */, 538 | ); 539 | defaultConfigurationIsVisible = 0; 540 | defaultConfigurationName = Release; 541 | }; 542 | /* End XCConfigurationList section */ 543 | }; 544 | rootObject = 6294280F1D387503001BD4E9 /* Project object */; 545 | } 546 | -------------------------------------------------------------------------------- /Eikana-helper/Base.lproj/MainMenu.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | Default 539 | 540 | 541 | 542 | 543 | 544 | 545 | Left to Right 546 | 547 | 548 | 549 | 550 | 551 | 552 | Right to Left 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | Default 564 | 565 | 566 | 567 | 568 | 569 | 570 | Left to Right 571 | 572 | 573 | 574 | 575 | 576 | 577 | Right to Left 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | --------------------------------------------------------------------------------