{"id":13649105,"url":"https://github.com/yingDev/QingDict","last_synced_at":"2025-04-22T12:33:23.925Z","repository":{"id":77683525,"uuid":"48326377","full_name":"yingDev/QingDict","owner":"yingDev","description":"Lightweight \u0026 pragmatic dictionary program for OS X. (Swift)","archived":false,"fork":false,"pushed_at":"2016-05-24T10:18:19.000Z","size":749,"stargazers_count":210,"open_issues_count":8,"forks_count":28,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-08-03T01:39:30.109Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://www.yingdev.com/projects/qingdict","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yingDev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2015-12-20T15:29:38.000Z","updated_at":"2024-07-09T09:44:43.000Z","dependencies_parsed_at":"2023-03-02T10:30:18.698Z","dependency_job_id":null,"html_url":"https://github.com/yingDev/QingDict","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yingDev%2FQingDict","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yingDev%2FQingDict/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yingDev%2FQingDict/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yingDev%2FQingDict/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yingDev","download_url":"https://codeload.github.com/yingDev/QingDict/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223896472,"owners_count":17221441,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-02T01:04:46.977Z","updated_at":"2024-11-09T23:30:55.343Z","avatar_url":"https://github.com/yingDev.png","language":"Swift","funding_links":[],"categories":["Swift"],"sub_categories":[],"readme":"# QingDict\n轻量级、实用主义的词典程序 for OS X\n\n![QingDict Icon](https://raw.githubusercontent.com/yingDev/QingDict/master/.readmeImages/qingdict.png) \n\n开发QingDict是基于以下一些想法：\n  - 词典是为了帮助用户记住单词，而不是让用户反复查询同一个单词\n  - 工具程序不应该分散用户的注意力\n  - 以“实用”为目标，不拘泥于形式\n\n# 获得代码\n```bash\n  git clone https://github.com/yingDev/QingDict.git\n  cd QingDict\n  git submodule init \u0026\u0026 git submodule update\n```\n\n# 截图\n\n![QingDict Demo](https://raw.githubusercontent.com/yingDev/QingDict/master/.readmeImages/1.gif) \n![QingDict Demo](https://raw.githubusercontent.com/yingDev/QingDict/master/.readmeImages/2.gif) \n\n![QingDict Demo](https://raw.githubusercontent.com/yingDev/QingDict/master/.readmeImages/6.gif) \n![QingDict Demo](https://raw.githubusercontent.com/yingDev/QingDict/master/.readmeImages/4.gif) \n\n\n# 结构\n包含三个Target: \n  - `QingDict`：主程序，处理鼠标取词事件、显示状态栏图标、生词表、偏好设置\n  - `QingDict-Result`： 显示执行查词、显示查词结果、与主程序通信；出于减少内存占用的目的，这是一个可独立运行的app，每次执行失去焦点会自动退出\n  - `Launch-Helper`(objc)： ServiceManagement实现启动项所需\n\n\n# 有趣的关注点\n\n* 取词\u003cbr/\u003e\n  虽然有Accessibility API，但是OSX中许多程序是不支持此API取词的。本项目中采取了3中手段结合取词：AX、Cmd+C、模拟DragDrop，基本能应对大多数情形。这部分实现在`UserTextSelectionExtractor.swfit`中。\n\n* 进程间通信\u003cbr/\u003e\n  主程序与结果显示程序间用到了两种简单的IPC机制：命令行参数 和 `NSDistributedNotification`。前者用于传递查询的单词和选项等；后者主要作为“添加到生词表”的API。\n\n* 可滑动删除条目的NSTableRowView\u003cbr/\u003e\n  ```Swift\n  //这个类通过派生NSTableRowView, 处理一些鼠标事件、绘制逻辑，从而可以实现生词表“滑动删除条目”功能\n  class WordbookRowView : NSTableRowView ...\n  ```\n\n* NSStatusItem Hacking\u003cbr/\u003e\n  有很多OSX程序拥有菜单栏图标(NSStatusItem)，其中一些有通过自定义窗口来实现的“弹出菜单”，这类实现往往有个问题，那就是Status Item的高亮状态，与系统不匹配。\n  ```Swift\n  //在 AppDelegate 的 createStatusItem() 方法中，通过这个方法拦截鼠标左键事件，阻止StatusItem被单击而引发系统默认行为，然后手动设置其高亮状态\n  NSEvent.addLocalMonitorForEventsMatchingMask(NSEventMask.LeftMouseDownMask) ...\n  ```\n\n\n* Swift dylibs\u003cbr/\u003e\n  `QingDict-Result.app`是放在`QingDict.app/Contents/Resources`中的。由于当前Swift运行时没有内置于OS X中，Xcode会拷贝所有swift的dylib到每个app中。这就导致`QingDict-Result.app`和`QingDict.app`都包含独立的一堆dylib，浪费了7MB左右的空间。项目中采取的解决办法是，在Build Phase中把`QingDict-Result.app`中的dylib替换为指向`QingDict.app`中dylib的symlink。\n  ```bash\n  # 与QingDict.app用到的dylib重复的，替换为symlink\ntheDir=\"${TARGET_BUILD_DIR}/${TARGETNAME}.app/Contents/Frameworks\"\nsourceDir=\"../../../../Frameworks\"\ndylibs=\"libswiftAppKit libswiftCore libswiftCoreData libswiftCoreGraphics libswiftCoreImage libswiftDarwin libswiftDispatch libswiftFoundation libswiftObjectiveC\"\n\nfor lib in $dylibs\ndo\n    theDylib=\"$theDir/$lib.dylib\"\n    rm -f $theDylib\n    ln -s $sourceDir/$lib.dylib $theDylib\ndone\n  ```\n  \n# License\n`GPL-V3`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FyingDev%2FQingDict","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FyingDev%2FQingDict","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FyingDev%2FQingDict/lists"}