diff --git a/.github/workflows/commit-ci.yml b/.github/workflows/commit-ci.yml index 6fa9b166f..8edb3c25d 100644 --- a/.github/workflows/commit-ci.yml +++ b/.github/workflows/commit-ci.yml @@ -14,31 +14,54 @@ on: pull_request: jobs: + lint: + runs-on: windows-2019 + steps: + - name: Checkout last commit + uses: actions/checkout@v4 + - name: Install llvm if necessary + shell: pwsh + run: | + $version = "" + if (Get-Command "clang-format" -ErrorAction SilentlyContinue){ + $version = clang-format --version + $pat = ".*\s+(\d+\.\d+\.\d+)" + if ($version -match $pat) { + $version = $matches[1] + } + } + if ($version -ne "") { + Write-Host "clang-format version:$version" + if ([version]$version -ge [version]"18.1.6") { + Write-Host "clang-format OK" + } else { + Write-Host "clang-format vesion does not meet" + choco install llvm --version=18.1.6 + } + } else { + Write-Host "clang-format not installed" + choco install llvm --version=18.1.6 + } + - name: Code style lint + shell: bash + run: ./clang-format.sh -i + build: + needs: lint runs-on: windows-2019 env: boost_version: 1.84.0 BOOST_ROOT: ${{ github.workspace }}\deps\boost_1_84_0 steps: + - name: Checkout last commit uses: actions/checkout@v4 with: - submodules: recursive - - - name: Cache llvm - id: cache-llvm - uses: actions/cache@v4 - with: - path: C:\\Program Files\\LLVM - key: ${{ runner.os }}-llvm-18.1.6 - - - name: Install llvm - if: steps.cache-llvm.outputs.cache-hit != 'true' - run: choco install llvm --version=18.1.6 + submodules: true + fetch-depth: 0 - - name: Code style lint - shell: bash - run: ./clang-format.sh -i + - name: Fetch all tags + run: git fetch --tags - name: Configure build environment shell: bash @@ -54,7 +77,6 @@ jobs: ${{ env.BOOST_ROOT }} key: ${{ runner.os }}-boost-${{ env.boost_version }} - # install boost if not cached - name: Install Boost if: steps.cache-boost.outputs.cache-hit != 'true' shell: bash @@ -62,11 +84,9 @@ jobs: ./install_boost.bat ./build.bat boost arm64 - # add msbuild to PATH - name: Add msbuild to PATH uses: microsoft/setup-msbuild@v2 - # use upper stream released librime files if stable release - name: Copy Rime files run: | .\github.install.bat @@ -93,3 +113,66 @@ jobs: path: | .\output\archives\weasel*.exe .\output\archives\debug_symbols.7z + + xbuild: + needs: lint + runs-on: windows-2019 + env: + boost_version: 1.84.0 + BOOST_ROOT: ${{ github.workspace }}\deps\boost_1_84_0 + steps: + + - name: Checkout last commit + uses: actions/checkout@v4 + with: + submodules: true + fetch-depth: 0 + + - name: Fetch all tags + run: git fetch --tags + + - name: Configure build environment + shell: bash + run: | + cp env.vs2019.bat env.bat + echo git_ref_name="$(git describe --always)" >> $GITHUB_ENV + + - name: Cache Boost + id: cache-boost + uses: actions/cache@v4 + with: + path: | + ${{ env.BOOST_ROOT }} + key: ${{ runner.os }}-boost-${{ env.boost_version }} + + - name: Install Boost + if: steps.cache-boost.outputs.cache-hit != 'true' + shell: bash + run: | + ./install_boost.bat + ./build.bat boost arm64 + + # xmake 2.9.4 or later + - uses: xmake-io/github-action-setup-xmake@v1 + with: + xmake-version: '2.9.4' + actions-cache-folder: '.xmake-cache' + + - uses: ilammy/msvc-dev-cmd@v1 + + - name: Copy Rime files + shell: pwsh + run: | + .\github.install.bat + + - name: Build data + run: | + $ErrorActionPreference = 'Stop' + .\build.bat data + + - name: Build Weasel + id: build_weasel + shell: cmd + run: | + .\xbuild.bat arm64 installer + diff --git a/.github/workflows/release-ci.yml b/.github/workflows/release-ci.yml index 81c7c3af0..b1d03e224 100644 --- a/.github/workflows/release-ci.yml +++ b/.github/workflows/release-ci.yml @@ -20,7 +20,12 @@ jobs: - name: Checkout last commit uses: actions/checkout@v4 with: - submodules: recursive + submodules: true + fetch-depth: 0 + + - name: Fetch all tags + if: github.ref == 'refs/heads/master' + run: git fetch --tags - name: Configure build environment shell: bash @@ -98,10 +103,15 @@ jobs: # create stable release - name: Release uses: softprops/action-gh-release@v2 - if: startsWith(github.ref, 'refs/tags/') + if: ${{ github.repository == 'rime/weasel' && startsWith(github.ref, 'refs/tags/') }} with: files: | ./output/archives/weasel*.exe ./output/archives/debug_symbols.7z body_path: ${{ github.workspace }}/RELEASE_CHANGELOG.md + - name: Update testing Appcast + if: ${{ github.repository == 'rime/weasel' }} + run: gh workflow run gh-pages.yml -R rime/home --ref master + env: + GH_TOKEN: ${{ secrets.ACTIONS_DEPLOY_KEY }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 6acb39add..35a7e6c7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,54 @@ + +## [0.16.3](https://github.com/rime/weasel/compare/0.16.2...0.16.3)(2024-10-04) + +#### Bug Fixes +* release channel feed_url not correct. ([fxliang](https://github.com/rime/weasel/commit/0c8bb0f01a929f46160482ae2f4492bed560b7b9)) +* invalid quick return ([Xuesong Peng](https://github.com/rime/weasel/commit/4da263727e16362f01054f6f0bb7522e83ae1e06)) + +#### Chores +* add update\bump-version.ps1 to bump version in powershell, when clog is not required ([fxliang](https://github.com/rime/weasel/commit/8770fb3ed1b4341b7875c1d60e98bfa5b42f8ac7)) +* update bump-version.sh, appcast.xml and testing-appcast.xml[skip ci] ([fxliang](https://github.com/rime/weasel/commit/91d5e4e224a0d73b8303a6ce10f03c71dace5cdd)) + +#### Continuous Integration +* release and update testing appcast only in rime/weasel ([fxliang](https://github.com/rime/weasel/commit/4af83b6e17f7c3cf78257dd300f4adadbffa1083)) + + +## [0.16.2](https://github.com/rime/weasel/compare/0.16.1...0.16.2) (2024-09-28) + +#### 安裝須知 + +**⚠️如您由0.16.0之前的版本升級,由於參數變化,安裝小狼毫前請保存好文件資料,於安裝後重啓或註銷 Windows,否則正在使用小狼毫的應用可能會崩潰。** + +**⚠如您由0.16.0之前的版本升級,請確認您的 `installation.yaml` 文件編碼爲 `UTF-8`, 否則如您在其中修改了非 ASCII 字符內容的路徑時,有可能會引起未明錯誤。** + +#### 主要更新 +* 新特性:支持自動檢查更新使用測試通道,使用`WeaselSetup.exe`參數可修改,`/testing`使用測試通道,`/release`使用發佈版本,默認後者; +* 新特性:`WeaselSetup.exe`參數設置界面語言,设置后覆盖区域设置的自动检测。`/lt`設置爲繁體中文界面,`/ls` 設置爲簡體中文界面,`/le`設置爲英文界面 +* 新特性:`WeaselSetup.exe`參數設置是否使用自動檢查更新,`/du`禁用自動檢查更新,`/eu`使用自動檢查更新 +* 新特性:安裝器彈窗提示設置是否自動檢查升級 +* 新特性:開關IME消息響應狀態可配置,`WeaselSetup.exe`參數`/toggleime`設置關閉鍵盤(原版本狀態),`/toggleascii`切換`ascii_mode`,安裝默認後者 #1364 +* 新特性:支持xmake 2.9.4以上版本構建,使用`xbuild.bat`開展,相關參數基本同`build.bat`, 使用`xbuild.bat commands`可生成`compile_commands.json`便於lsp使用,`xbuild.bat clean`可清空xmake構建 #1360 +* 新特性:支持`Caps_Lock` 按鍵binding(如選重),需将`key_binder`置于`ascii_composer`之前 +* 使能TSF dll中的WER +* nightly 構建後自動更新rime/home頁面更新測試通道appcast +* 升級lint檢查使用的llvm最低版本至18.1.6, 更新ci脚本检查更新llvm + +#### Bug 修復 + +* 修復安裝器在系統未滿足要求時未中斷的問題 +* 修復重新安裝時舊的安於路徑未保持的問題 +* 修復界面語言根據區域格式未正確設置的問題 +* 修復IPC通信時因新舊版本變更引起的異常崩潰的問題 +* 修正代碼編碼格式 +* 修復清空舊log文件 +* 修復控制面板卸載界面中的圖標顯示問題 +* 修復`style/hover_type`爲`"semi_hilite"`在首候選時的顯示異常問題 +* 修復新版librime產物未能直接替換使用問題 +* 禁用IPC通信的異步機制,修復一些因異步機制引發的應用異常 +* 修復構建腳本不能重生成正確的版本信息問題 +* 修復一些vs工程配置設置,處理一些deprecated API警告 + + ## [0.16.1](https://github.com/rime/weasel/compare/0.16.0...0.16.1) (2024-06-06) @@ -1015,3 +1066,4 @@ * 以Python開發的實驗版本 * 獨創「拼寫運算」技術 * 預裝標調拼音、註音、粵拼、吳語等多種輸入方案 + diff --git a/RimeWithWeasel/xmake.lua b/RimeWithWeasel/xmake.lua new file mode 100644 index 000000000..5bca92bd1 --- /dev/null +++ b/RimeWithWeasel/xmake.lua @@ -0,0 +1,5 @@ +target("RimeWithWeasel") + set_kind("static") + add_files("./*.cpp") + add_rules("use_weaselconstants") + diff --git a/WeaselDeployer/SwitcherSettingsDialog.cpp b/WeaselDeployer/SwitcherSettingsDialog.cpp index d9e648ce2..fe7f62765 100644 --- a/WeaselDeployer/SwitcherSettingsDialog.cpp +++ b/WeaselDeployer/SwitcherSettingsDialog.cpp @@ -182,8 +182,8 @@ LRESULT SwitcherSettingsDialog::OnOK(WORD, WORD code, HWND, BOOL&) { LRESULT SwitcherSettingsDialog::OnSchemaListItemChanged(int, LPNMHDR p, BOOL&) { LPNMLISTVIEW lv = reinterpret_cast(p); - if (!loaded_ || !lv || - lv->iItem < 0 && lv->iItem >= schema_list_.GetItemCount()) + if (!loaded_ || !lv || lv->iItem < 0 || + lv->iItem >= schema_list_.GetItemCount()) return 0; if ((lv->uNewState & LVIS_STATEIMAGEMASK) != (lv->uOldState & LVIS_STATEIMAGEMASK)) { diff --git a/WeaselDeployer/xmake.lua b/WeaselDeployer/xmake.lua new file mode 100644 index 000000000..61823d48d --- /dev/null +++ b/WeaselDeployer/xmake.lua @@ -0,0 +1,24 @@ +target("WeaselDeployer") + set_kind("binary") + add_files("./*.cpp") + add_rules("add_rcfiles", "use_weaselconstants", "subwin") + add_links("imm32", "kernel32", "rime") + add_deps("WeaselIPC", "RimeWithWeasel") + add_files("$(projectdir)/PerMonitorHighDPIAware.manifest") + add_ldflags("/DEBUG /OPT:ICF /LARGEADDRESSAWARE /ERRORREPORT:QUEUE") + before_build(function(target) + local target_dir = path.join(target:targetdir(), target:name()) + if not os.exists(target_dir) then + os.mkdir(target_dir) + end + target:set("targetdir", target_dir) + end) + after_build(function(target) + if is_arch("x86") then + os.cp(path.join(target:targetdir(), "WeaselDeployer.exe"), "$(projectdir)/output/Win32") + os.cp(path.join(target:targetdir(), "WeaselDeployer.pdb"), "$(projectdir)/output/Win32") + else + os.cp(path.join(target:targetdir(), "WeaselDeployer.exe"), "$(projectdir)/output") + os.cp(path.join(target:targetdir(), "WeaselDeployer.pdb"), "$(projectdir)/output") + end + end) diff --git a/WeaselIME/WeaselIME.vcxproj b/WeaselIME/WeaselIME.vcxproj index f7fe773a4..82bc33431 100644 --- a/WeaselIME/WeaselIME.vcxproj +++ b/WeaselIME/WeaselIME.vcxproj @@ -117,41 +117,49 @@ true weasel .ime + $(SolutionDir)output\ true weasel$(Platform) .ime + $(SolutionDir)output\ false weasel .ime + $(SolutionDir)output\ false weasel$(Platform) .ime + $(SolutionDir)output\ true weasel$(Platform) .ime + $(SolutionDir)output\ true weasel$(Platform) .ime + $(SolutionDir)output\ false weasel$(Platform) .ime + $(SolutionDir)output\ false weasel$(Platform) .ime + $(SolutionDir)output\ diff --git a/WeaselIME/xmake.lua b/WeaselIME/xmake.lua new file mode 100644 index 000000000..d24d4a353 --- /dev/null +++ b/WeaselIME/xmake.lua @@ -0,0 +1,30 @@ +target("WeaselIME") + set_kind("shared") + add_files("./*.cpp") + add_rules("add_rcfiles") + add_links("advapi32", "imm32", "user32", "gdi32") + add_deps("WeaselIPC", "WeaselUI") + local fname = '' + + before_build(function(target) + local target_dir = path.join(target:targetdir(), target:name()) + if not os.exists(target_dir) then + os.mkdir(target_dir) + end + target:set("targetdir", target_dir) + end) + + after_build(function(target) + os.cp(path.join(target:targetdir(), "*.ime"), "$(projectdir)/output") + end) + if is_arch("x86") then + fname = "weasel.ime" + elseif is_arch("x64") then + fname = "weaselx64.ime" + elseif is_arch("arm") then + fname = "weaselARM.ime" + elseif is_arch("arm64") then + fname = "weaselARM64.ime" + end + set_filename(fname) + diff --git a/WeaselIPC/WeaselClientImpl.cpp b/WeaselIPC/WeaselClientImpl.cpp index 2a5d90597..26122ad50 100644 --- a/WeaselIPC/WeaselClientImpl.cpp +++ b/WeaselIPC/WeaselClientImpl.cpp @@ -1,8 +1,6 @@ #include "stdafx.h" #include "WeaselClientImpl.h" #include -#include -#include using namespace weasel; @@ -197,18 +195,7 @@ LRESULT ClientImpl::_SendMessage(WEASEL_IPC_COMMAND Msg, DWORD lParam) { try { PipeMessage req{Msg, wParam, lParam}; - auto future = std::async(std::launch::async, - [this, &req]() { return channel.Transact(req); }); - - // wait Transact complete or overtime - if (future.wait_for(std::chrono::seconds(2)) == - std::future_status::timeout) { - // Transact overtime - return 0; - } else { - // Transact complete - return future.get(); - } + return channel.Transact(req); } catch (DWORD /* ex */) { return 0; } diff --git a/WeaselIPC/xmake.lua b/WeaselIPC/xmake.lua new file mode 100644 index 000000000..b55b10314 --- /dev/null +++ b/WeaselIPC/xmake.lua @@ -0,0 +1,4 @@ +target("WeaselIPC") + set_kind("static") + add_files("./*.cpp") + diff --git a/WeaselIPCServer/xmake.lua b/WeaselIPCServer/xmake.lua new file mode 100644 index 000000000..9ef67d0f9 --- /dev/null +++ b/WeaselIPCServer/xmake.lua @@ -0,0 +1,4 @@ +target("WeaselIPCServer") + set_kind("static") + add_files("./*.cpp") + diff --git a/WeaselServer/SystemTraySDK.cpp b/WeaselServer/SystemTraySDK.cpp index 4c5745c9e..19e8ca485 100644 --- a/WeaselServer/SystemTraySDK.cpp +++ b/WeaselServer/SystemTraySDK.cpp @@ -112,10 +112,16 @@ void CSystemTray::Initialise() { m_uCreationFlags = 0; #ifdef SYSTEMTRAY_USEW2K - OSVERSIONINFO os = {sizeof(os)}; - GetVersionEx(&os); - m_bWin2K = - (VER_PLATFORM_WIN32_NT == os.dwPlatformId && os.dwMajorVersion >= 5); + OSVERSIONINFOEX osInfo = {0}; + osInfo.dwOSVersionInfoSize = sizeof(osInfo); + osInfo.dwMajorVersion = 5; + osInfo.dwPlatformId = VER_PLATFORM_WIN32_NT; + DWORDLONG conditionMask = 0; + conditionMask = + VerSetConditionMask(conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL); + conditionMask = VerSetConditionMask(conditionMask, VER_PLATFORMID, VER_EQUAL); + m_bWin2K = VerifyVersionInfo(&osInfo, VER_MAJORVERSION | VER_PLATFORMID, + conditionMask); #else m_bWin2K = FALSE; #endif @@ -156,7 +162,13 @@ BOOL CSystemTray::Create(HINSTANCE hInst, m_bEnabled = TRUE; #else // this is only for Windows 95 (or higher) - m_bEnabled = (GetVersion() & 0xff) >= 4; + OSVERSIONINFOEXW osInfo = {0}; + osInfo.dwOSVersionInfoSize = sizeof(osInfo); + osInfo.dwMajorVersion = 4; + DWORDLONG conditionMask = 0; + conditionMask = + VerSetConditionMask(conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL); + m_bEnabled = VerifyVersionInfoW(&osInfo, VER_MAJORVERSION, conditionMask); if (!m_bEnabled) { ASSERT(FALSE); return FALSE; @@ -1058,4 +1070,4 @@ void CSystemTray::MaximiseFromTray(HWND hWnd) { SetActiveWindow(hWnd); SetForegroundWindow(hWnd); #endif -} \ No newline at end of file +} diff --git a/WeaselServer/WeaselServer.rc b/WeaselServer/WeaselServer.rc index bfc74ed91..53fcadd45 100644 Binary files a/WeaselServer/WeaselServer.rc and b/WeaselServer/WeaselServer.rc differ diff --git a/WeaselServer/WeaselServerApp.h b/WeaselServer/WeaselServerApp.h index 9fbc38302..d5e32e006 100644 --- a/WeaselServer/WeaselServerApp.h +++ b/WeaselServer/WeaselServerApp.h @@ -36,6 +36,12 @@ class WeaselServerApp { static bool check_update() { // when checked manually, show testing versions too std::string feed_url = GetCustomResource("ManualUpdateFeedURL", "APPCAST"); + std::wstring channel{}; + auto ret = RegGetStringValue(HKEY_CURRENT_USER, L"Software\\Rime\\Weasel", + L"UpdateChannel", channel); + if (!ret && channel == L"testing") { + feed_url = GetCustomResource("TestingManualUpdateFeedURL", "APPCAST"); + } if (!feed_url.empty()) { win_sparkle_set_appcast_url(feed_url.c_str()); } diff --git a/WeaselServer/xmake.lua b/WeaselServer/xmake.lua new file mode 100644 index 000000000..78b99b0d3 --- /dev/null +++ b/WeaselServer/xmake.lua @@ -0,0 +1,27 @@ +target("WeaselServer") + set_kind("binary") + add_files("./*.cpp") + add_rules("add_rcfiles", "subwin") + add_links("imm32", "kernel32", "rime") + add_deps("WeaselUI", "WeaselIPC", "RimeWithWeasel", "WeaselIPCServer") + + add_files("$(projectdir)/PerMonitorHighDPIAware.manifest") + add_ldflags("/DEBUG /OPT:REF /OPT:ICF /LARGEADDRESSAWARE /ERRORREPORT:QUEUE") + set_policy("windows.manifest.uac", "invoker") + before_build(function(target) + local target_dir = path.join(target:targetdir(), target:name()) + if not os.exists(target_dir) then + os.mkdir(target_dir) + end + target:set("targetdir", target_dir) + end) + after_build(function(target) + if is_arch("x86") then + os.cp(path.join(target:targetdir(), "WeaselServer.exe"), "$(projectdir)/output/Win32") + os.cp(path.join(target:targetdir(), "WeaselServer.pdb"), "$(projectdir)/output/Win32") + else + os.cp(path.join(target:targetdir(), "WeaselServer.exe"), "$(projectdir)/output") + os.cp(path.join(target:targetdir(), "WeaselServer.pdb"), "$(projectdir)/output") + end + end) + diff --git a/WeaselSetup/WeaselSetup.cpp b/WeaselSetup/WeaselSetup.cpp index d9fe9861d..259af11f7 100644 --- a/WeaselSetup/WeaselSetup.cpp +++ b/WeaselSetup/WeaselSetup.cpp @@ -161,6 +161,22 @@ static int Run(LPTSTR lpCmdLine) { L"CheckForUpdates", L"0", REG_SZ); } + if (!wcscmp(L"/toggleime", lpCmdLine)) { + return SetRegKeyValue(HKEY_CURRENT_USER, L"Software\\Rime\\weasel", + L"ToggleImeOnOpenClose", L"yes", REG_SZ); + } + if (!wcscmp(L"/toggleascii", lpCmdLine)) { + return SetRegKeyValue(HKEY_CURRENT_USER, L"Software\\Rime\\weasel", + L"ToggleImeOnOpenClose", L"no", REG_SZ); + } + if (!wcscmp(L"/testing", lpCmdLine)) { + return SetRegKeyValue(HKEY_CURRENT_USER, L"Software\\Rime\\weasel", + L"UpdateChannel", L"testing", REG_SZ); + } + if (!wcscmp(L"/release", lpCmdLine)) { + return SetRegKeyValue(HKEY_CURRENT_USER, L"Software\\Rime\\weasel", + L"UpdateChannel", L"release", REG_SZ); + } bool hans = !wcscmp(L"/s", lpCmdLine); if (hans) return install(false, silent, old_ime_support); diff --git a/WeaselSetup/xmake.lua b/WeaselSetup/xmake.lua new file mode 100644 index 000000000..49439e8bd --- /dev/null +++ b/WeaselSetup/xmake.lua @@ -0,0 +1,33 @@ +target("WeaselSetup") + set_kind("binary") + add_files("./*.cpp") + add_rules("add_rcfiles", "use_weaselconstants", "subwin") + add_links("imm32", "kernel32") + + set_policy("windows.manifest.uac", "admin") + add_files("$(projectdir)/PerMonitorHighDPIAware.manifest") + add_ldflags("/DEBUG /OPT:REF /OPT:ICF /LARGEADDRESSAWARE /ERRORREPORT:QUEUE") + + before_build(function(target) + local target_dir = path.join(target:targetdir(), target:name()) + if not os.exists(target_dir) then + os.mkdir(target_dir) + end + target:set("targetdir", target_dir) + local level = target:policy("windows.manifest.uac") + if level then + local level_maps = { + invoker = "asInvoker", + admin = "requireAdministrator", + highest = "highestAvailable" + } + assert(level_maps[level], "unknown uac level %s, please set invoker, admin or highest", level) + local ui = target:policy("windows.manifest.uac.ui") or false + target:add("ldflags", "/manifest:embed", {("/manifestuac:level='%s' uiAccess='%s'"):format(level_maps[level], ui)}, {force = true, expand = false}) + end + end) + + after_build(function(target) + os.cp(path.join(target:targetdir(), "WeaselSetup.exe"), "$(projectdir)/output") + os.cp(path.join(target:targetdir(), "WeaselSetup.pdb"), "$(projectdir)/output") + end) diff --git a/WeaselTSF/Compartment.cpp b/WeaselTSF/Compartment.cpp index a3b6a25a2..a45e0d1f9 100644 --- a/WeaselTSF/Compartment.cpp +++ b/WeaselTSF/Compartment.cpp @@ -5,6 +5,7 @@ #include #include "ResponseParser.h" #include "CandidateList.h" +#include "LanguageBar.h" STDAPI CCompartmentEventSink::QueryInterface(REFIID riid, _Outptr_ void** ppvObj) { @@ -242,13 +243,27 @@ void WeaselTSF::_UninitCompartment() { HRESULT WeaselTSF::_HandleCompartment(REFGUID guidCompartment) { if (IsEqualGUID(guidCompartment, GUID_COMPARTMENT_KEYBOARD_OPENCLOSE)) { - BOOL isOpen = _IsKeyboardOpen(); - // clear composition when close keyboard - if (!isOpen && _pEditSessionContext) { - m_client.ClearComposition(); - _EndComposition(_pEditSessionContext, true); + if (_isToOpenClose) { + BOOL isOpen = _IsKeyboardOpen(); + // clear composition when close keyboard + if (!isOpen && _pEditSessionContext) { + m_client.ClearComposition(); + _EndComposition(_pEditSessionContext, true); + } + _EnableLanguageBar(isOpen); + _UpdateLanguageBar(_status); + } else { + _status.ascii_mode = !_status.ascii_mode; + _SetKeyboardOpen(true); + if (_pLangBarButton && _pLangBarButton->IsLangBarDisabled()) + _EnableLanguageBar(true); + _HandleLangBarMenuSelect(_status.ascii_mode + ? ID_WEASELTRAY_ENABLE_ASCII + : ID_WEASELTRAY_DISABLE_ASCII); + if (_pEditSessionContext) + m_client.ClearComposition(); + _UpdateLanguageBar(_status); } - _EnableLanguageBar(isOpen); } else if (IsEqualGUID(guidCompartment, GUID_COMPARTMENT_KEYBOARD_INPUTMODE_CONVERSION)) { BOOL isOpen = _IsKeyboardOpen(); diff --git a/WeaselTSF/KeyEventSink.cpp b/WeaselTSF/KeyEventSink.cpp index 55dde4f98..e0d431410 100644 --- a/WeaselTSF/KeyEventSink.cpp +++ b/WeaselTSF/KeyEventSink.cpp @@ -9,7 +9,9 @@ static BOOL prevfEaten = FALSE; static int keyCountToSimulate = 0; void WeaselTSF::_ProcessKeyEvent(WPARAM wParam, LPARAM lParam, BOOL* pfEaten) { - if (!_IsKeyboardOpen() || _IsKeyboardDisabled()) { + // when _IsKeyboardDisabled don't eat the key, + // when keyboard closable and keyboard closed, don't eat the key + if ((_isToOpenClose && !_IsKeyboardOpen()) || _IsKeyboardDisabled()) { *pfEaten = FALSE; return; } diff --git a/WeaselTSF/LanguageBar.h b/WeaselTSF/LanguageBar.h index 667eab3fd..2c0513ab3 100644 --- a/WeaselTSF/LanguageBar.h +++ b/WeaselTSF/LanguageBar.h @@ -30,6 +30,7 @@ class CLangBarItemButton : public ITfLangBarItemButton, public ITfSource { /* ITfSource */ STDMETHODIMP AdviseSink(REFIID riid, IUnknown* punk, DWORD* pdwCookie); STDMETHODIMP UnadviseSink(DWORD dwCookie); + BOOL IsLangBarDisabled() { return (_status & TF_LBI_STATUS_DISABLED); } void UpdateWeaselStatus(weasel::Status stat); void SetLangbarStatus(DWORD dwStatus, BOOL fSet); diff --git a/WeaselTSF/WeaselTSF.cpp b/WeaselTSF/WeaselTSF.cpp index 0564ebdc1..236e3daf8 100644 --- a/WeaselTSF/WeaselTSF.cpp +++ b/WeaselTSF/WeaselTSF.cpp @@ -171,6 +171,10 @@ STDAPI WeaselTSF::ActivateEx(ITfThreadMgr* pThreadMgr, } STDMETHODIMP WeaselTSF::OnSetThreadFocus() { + std::wstring _ToggleImeOnOpenClose{}; + RegGetStringValue(HKEY_CURRENT_USER, L"Software\\Rime\\weasel", + L"ToggleImeOnOpenClose", _ToggleImeOnOpenClose); + _isToOpenClose = (_ToggleImeOnOpenClose == L"yes"); if (m_client.Echo()) { m_client.ProcessKeyEvent(0); weasel::ResponseParser parser(NULL, NULL, &_status, NULL, &_cand->style()); diff --git a/WeaselTSF/WeaselTSF.h b/WeaselTSF/WeaselTSF.h index 12ae30d17..696d3cce4 100644 --- a/WeaselTSF/WeaselTSF.h +++ b/WeaselTSF/WeaselTSF.h @@ -232,4 +232,5 @@ class WeaselTSF : public ITfTextInputProcessorEx, TfGuidAtom _gaDisplayAttributeInput; BOOL _async_edit = false; BOOL _committed = false; + BOOL _isToOpenClose = false; }; diff --git a/WeaselTSF/xmake.lua b/WeaselTSF/xmake.lua new file mode 100644 index 000000000..e13d9be86 --- /dev/null +++ b/WeaselTSF/xmake.lua @@ -0,0 +1,31 @@ +target("WeaselTSF") + set_kind("shared") + add_files("./*.cpp", "WeaselTSF.def") + add_rules("add_rcfiles", "use_weaselconstants") + add_deps("WeaselIPC", "WeaselUI") + local fname = '' + if is_arch("x86") then + fname = "weasel.dll" + elseif is_arch("x64") then + fname = "weaselx64.dll" + elseif is_arch("arm") then + fname = "weaselARM.dll" + elseif is_arch("arm64") then + fname = "weaselARM64.dll" + end + set_filename(fname) + + add_files("$(projectdir)/PerMonitorHighDPIAware.manifest") + add_shflags("/DEBUG /OPT:REF /OPT:ICF") + before_build(function(target) + local target_dir = path.join(target:targetdir(), target:name()) + if not os.exists(target_dir) then + os.mkdir(target_dir) + end + target:set("targetdir", target_dir) + end) + + after_build(function(target) + os.cp(path.join(target:targetdir(), "weasel*.dll"), "$(projectdir)/output") + os.cp(path.join(target:targetdir(), "weasel*.pdb"), "$(projectdir)/output") + end) diff --git a/WeaselUI/xmake.lua b/WeaselUI/xmake.lua new file mode 100644 index 000000000..420befc2a --- /dev/null +++ b/WeaselUI/xmake.lua @@ -0,0 +1,4 @@ +target("WeaselUI") + set_kind("static") + add_files("./*.cpp") + diff --git a/build.bat b/build.bat index 9766e9f72..152d0de85 100644 --- a/build.bat +++ b/build.bat @@ -10,22 +10,28 @@ if not defined WEASEL_ROOT set WEASEL_ROOT=%CD% if not defined VERSION_MAJOR set VERSION_MAJOR=0 if not defined VERSION_MINOR set VERSION_MINOR=16 -if not defined VERSION_PATCH set VERSION_PATCH=1 +if not defined VERSION_PATCH set VERSION_PATCH=3 if not defined WEASEL_VERSION set WEASEL_VERSION=%VERSION_MAJOR%.%VERSION_MINOR%.%VERSION_PATCH% if not defined WEASEL_BUILD set WEASEL_BUILD=0 -if not defined PRODUCT_VERSION ( - rem use numeric build version for release build - set PRODUCT_VERSION=%WEASEL_VERSION%.%WEASEL_BUILD% - rem for non-release build, try to use git commit hash as product build version - if not defined RELEASE_BUILD ( - rem check if git is installed and available, then get the short commit id of head - git --version >nul 2>&1 - if not errorlevel 1 ( - rem get short commmit id of head - for /F %%i in ('git rev-parse --short HEAD') do (set PRODUCT_VERSION=%WEASEL_VERSION%-%%i) +rem use numeric build version for release build +set PRODUCT_VERSION=%WEASEL_VERSION%.%WEASEL_BUILD% +rem for non-release build, try to use git commit hash as product build version +if not defined RELEASE_BUILD ( + rem check if git is installed and available, then get the short commit id of head + git --version >nul 2>&1 + if not errorlevel 1 ( + for /f "delims=" %%i in ('git tag --sort=-creatordate ^| findstr /r "%WEASEL_VERSION%"') do ( + set LAST_TAG=%%i + goto found_tag ) + :found_tag + for /f "delims=" %%i in ('git rev-list %LAST_TAG%..HEAD --count') do ( + set WEASEL_BUILD=%%i + ) + rem get short commmit id of head + for /F %%i in ('git rev-parse --short HEAD') do (set PRODUCT_VERSION=%WEASEL_VERSION%.%WEASEL_BUILD%.%%i) ) ) @@ -39,6 +45,11 @@ echo WEASEL_ROOT=%WEASEL_ROOT% echo WEASEL_BUNDLED_RECIPES=%WEASEL_BUNDLED_RECIPES% echo. +if defined GITHUB_ENV ( + setlocal enabledelayedexpansion + echo git_ref_name=%PRODUCT_VERSION%>>!GITHUB_ENV! +) + if defined BOOST_ROOT ( if exist "%BOOST_ROOT%\boost" goto boost_found ) @@ -214,10 +225,8 @@ if %build_installer% == 1 ( "%ProgramFiles(x86)%"\NSIS\Bin\makensis.exe ^ /DWEASEL_VERSION=%WEASEL_VERSION% ^ /DWEASEL_BUILD=%WEASEL_BUILD% ^ + /DPRODUCT_VERSION=%PRODUCT_VERSION% ^ output\install.nsi - if not defined RELEASE_BUILD ( - move output\archives\weasel-%WEASEL_VERSION%.%WEASEL_BUILD%-installer.exe output\archives\weasel-%PRODUCT_VERSION%-installer.exe - ) if errorlevel 1 goto error ) diff --git a/install-clang-format.bat b/install-clang-format.bat index 0fcc437fb..3e1cc78dc 100644 --- a/install-clang-format.bat +++ b/install-clang-format.bat @@ -2,17 +2,17 @@ if "%PROCESSOR_ARCHITECTURE%"=="AMD64" ( rem 64 bit system - rem powershell -Command "(New-Object Net.WebClient).DownloadFile('https://github.com/llvm/llvm-project/releases/download/llvmorg-17.0.6/LLVM-17.0.6-win64.exe', 'LLVM-17.0.6-win64.exe')" - rem LLVM-17.0.6-win64.exe /S + rem powershell -Command "(New-Object Net.WebClient).DownloadFile('https://github.com/llvm/llvm-project/releases/download/llvmorg-18.1.6/LLVM-18.1.6-win64.exe', 'LLVM-18.1.6-win64.exe')" + rem LLVM-18.1.6-win64.exe /S rem or maybe - rem output/7z.exe e LLVM-17.0.6-win64.exe bin/clang-format.exe -o. - rem rm LLVM-17.0.6-win64.exe + rem output/7z.exe e LLVM-18.1.6-win64.exe bin/clang-format.exe -o. + rem rm LLVM-18.1.6-win64.exe ) else ( rem 32 bit system - rem powershell -Command "(New-Object Net.WebClient).DownloadFile('https://github.com/llvm/llvm-project/releases/download/llvmorg-17.0.6/LLVM-17.0.6-win32.exe', 'LLVM-17.0.6-win32.exe')" - rem LLVM-17.0.6-win32.exe /S + rem powershell -Command "(New-Object Net.WebClient).DownloadFile('https://github.com/llvm/llvm-project/releases/download/llvmorg-18.1.6/LLVM-18.1.6-win32.exe', 'LLVM-18.1.6-win32.exe')" + rem LLVM-18.1.6-win32.exe /S rem or maybe - rem output/7z.exe e LLVM-17.0.6-win32.exe bin/clang-format.exe -o. - rem rm LLVM-17.0.6-win32.exe + rem output/7z.exe e LLVM-18.1.6-win32.exe bin/clang-format.exe -o. + rem rm LLVM-18.1.6-win32.exe ) pause diff --git a/librime b/librime index 5b09f35ba..76a0a16c5 160000 --- a/librime +++ b/librime @@ -1 +1 @@ -Subproject commit 5b09f35bab12683d8ed5e8663c18c940e971b954 +Subproject commit 76a0a16c5ca0c7efc80fa918c8e0c88754699fd7 diff --git a/output/install.nsi b/output/install.nsi index 8dd7450f2..b8254417a 100644 --- a/output/install.nsi +++ b/output/install.nsi @@ -25,7 +25,7 @@ Unicode true Name "小狼毫 ${WEASEL_VERSION}" ; The file to write -OutFile "archives\weasel-${WEASEL_VERSION}.${WEASEL_BUILD}-installer.exe" +OutFile "archives\weasel-${PRODUCT_VERSION}-installer.exe" VIProductVersion "${WEASEL_VERSION}.${WEASEL_BUILD}" VIAddVersionKey /LANG=2052 "ProductName" "小狼毫" diff --git a/test/TestResponseParser/xmake.lua b/test/TestResponseParser/xmake.lua new file mode 100644 index 000000000..906d03690 --- /dev/null +++ b/test/TestResponseParser/xmake.lua @@ -0,0 +1,12 @@ +target("TestResponseParser") + set_kind("binary") + add_files("./*.cpp") + add_deps("WeaselIPC", "WeaselIPCServer") + add_rules("subcmd") + before_build(function(target) + local target_dir = path.join(target:targetdir(), target:name()) + if not os.exists(target_dir) then + os.mkdir(target_dir) + end + target:set("targetdir", target_dir) + end) diff --git a/test/TestWeaselIPC/xmake.lua b/test/TestWeaselIPC/xmake.lua new file mode 100644 index 000000000..0219a5a71 --- /dev/null +++ b/test/TestWeaselIPC/xmake.lua @@ -0,0 +1,12 @@ +target("TestWeaselIPC") + set_kind("binary") + add_files("./*.cpp") + add_deps("WeaselIPC", "WeaselIPCServer") + add_rules("subcmd") + before_build(function(target) + local target_dir = path.join(target:targetdir(), target:name()) + if not os.exists(target_dir) then + os.mkdir(target_dir) + end + target:set("targetdir", target_dir) + end) diff --git a/update/appcast.xml b/update/appcast.xml index 212d542c4..380834301 100644 --- a/update/appcast.xml +++ b/update/appcast.xml @@ -1,17 +1,17 @@ - - - - 【小狼毫】輸入法更新頻道 - http://rime.github.io/release/weasel/appcast.xml - 小狼毫 Appcast 更新頻道 - zh - - 小狼毫 0.16.1 - http://rime.github.io/release/weasel/release-notes.html - Thu, 06 Jun 2024 19:29:28 +0800 - - - - + + + + 【小狼毫】輸入法更新頻道 + http://rime.github.io/release/weasel/appcast.xml + 小狼毫 Appcast 更新頻道 + zh + + 小狼毫 0.16.3 + http://rime.github.io/release/weasel/release-notes.html + Fri, 04 Oct 2024 21:08:10 +08:00 + + + + diff --git a/update/bump-version.ps1 b/update/bump-version.ps1 new file mode 100644 index 000000000..9e0a5093b --- /dev/null +++ b/update/bump-version.ps1 @@ -0,0 +1,161 @@ +param( [string]$tag, [switch]$updatelog) +# -tag [new_tag], new tag shall be in format ^\d+\.\d+\.\d+$ and greater than +# the current one +# -updatelog update CHANGELOG.md if this switch used + +# get old version info from file, esp from build.bat +function get_old_version{ + param ([string]$filePath) + $fileContent = Get-Content -Path $filePath; + $version = @{}; + foreach ($line in $fileContent) { + if ($version["major"] -eq $null -and $line -match 'VERSION_MAJOR=(\d+)') { + $version["major"] = $matches[1]; + } + if ($version["minor"] -eq $null -and $line -match 'VERSION_MINOR=(\d+)') { + $version["minor"] = $matches[1]; + } + if ($version["patch"] -eq $null -and $line -match 'VERSION_PATCH=(\d+)') { + $version["patch"] = $matches[1]; + } + if ($version["major"] -ne $null -and $version["minor"] -ne $null -and $version["patch"] -ne $null) { + break; + } + } + $version['str'] = $version["major"] + "." + $version["minor"] + "." + $version["patch"]; + return $version; +} + +# parse new version info +function parse_new_version { + param([string]$new_version) + $version = @{}; + if ($new_version -match "^(\d+)\.(\d+)\.(\d+)$") { + $version['major'] = $matches[1]; + $version['minor'] = $matches[2]; + $version['patch'] = $matches[3]; + } + return $version; +} + +# update bat file with param filePath, and tags +function update_bat_file{ + param( [string]$filePath, $old_version, $new_version) + $old_major, $old_minor, $old_patch = $old_version['major'], $old_version["minor"], $old_version["patch"]; + $new_major, $new_minor, $new_patch = $new_version['major'], $new_version["minor"], $new_version["patch"]; + $fileContent = Get-Content -Path $filePath; + $fileContent = $fileContent -replace "VERSION_MAJOR=$old_major", "VERSION_MAJOR=$new_major"; + $fileContent = $fileContent -replace "VERSION_MINOR=$old_minor", "VERSION_MINOR=$new_minor"; + $fileContent = $fileContent -replace "VERSION_PATCH=$old_patch", "VERSION_PATCH=$new_patch"; + Set-Content -Path $filePath -Value $fileContent -Encoding UTF8; +} + +# update change log, work like clog-cli +function update_changelog { + param( [string]$new_tag, [string]$old_tag) + # get the current the previous release tag and current release tag + $tags = git tag --sort=creatordate | Select-String -Pattern '^\d+\.\d+\.\d+$' | ForEach-Object { $_.ToString() }; + $latestTag = $tags[-1]; + $commits = git log "$latestTag..HEAD" --pretty=format:"%s ([%an](https://github.com/rime/weasel/commit/%H))"; + # group commit logs + $groupedCommits = @{ + build = @(); ci = @(); fix = @(); feat = @(); docs = @(); style = @(); + refactor = @(); test = @(); chore = @(); commit = @(); + }; + $groupedTitle = @{ + build = "Builds"; + ci = "Continuous Integration"; + fix = "Bug Fixes"; + feat = "Features"; + docs = "Documents"; + style = "Code Style"; + refactor = "Code Refactor"; + test = "Tests"; + chore = "Chores"; + commit = "Commits"; + }; + foreach ($commit in $commits) { + if ($commit -match "^(build|ci|fix|feat|docs|style|refactor|test|chore):") { + $prefix = $matches[1]; + $groupedCommits[$prefix] += $commit; + } else { + $groupedCommits["commit"] += $commit; + } + } + $changelog = ""; + foreach ($group in $groupedCommits.Keys) { + if ($groupedCommits[$group].Count -gt 0) { + $changelog += "`n#### " + $groupedTitle[$group] + "`n" + foreach ($commit in $groupedCommits[$group]) { + $msg = $commit -replace "^" + $group + ":", ''; + $changelog += "* $msg`n"; + } + } + } + $currentDateTime = Get-Date -Format "yyyy-MM-dd"; + $fileContent = Get-Content -Path "CHANGELOG.md" -Raw -Encoding UTF8; + $contentAdd = "`n" ; + $contentAdd += "## [$new_tag](https://github.com/rime/weasel/compare/$old_tag...$new_tag)($currentDateTime)`n" ; + $contentAdd += $changelog; + Write-Host "`n" + $contentAdd + "`n" + $fileContent = $contentAdd + "`n" + $fileContent; + $fileContent | Out-File -FilePath "CHANGELOG.md" -Encoding UTF8; +} + +# update appcast file, with regex patterns +function update_appcast_file { + param( [string]$filePath, [string]$pat_orig, [string]$pat_replace) + $fileContent = Get-Content -Path $filePath; + $fileContent = $fileContent -replace $pat_orig, $pat_replace; + Set-Content -Path $filePath -Value $fileContent; +} +############################################################################### +# program now started +# tag name not match rule, exit +if (-not ($tag -match '^\d+\.\d+\.\d+$')) { + Write-Host "tag name not match rule '^\d+\.\d+\.\d+$'"; + Write-Host "please recheck it"; + exit; +} +# get old version +$old_version = get_old_version -filePath "build.bat"; +$old_major, $old_minor, $old_patch = $old_version['major'], $old_version["minor"], $old_version["patch"]; +# get new version +$new_version = parse_new_version -new_version $tag +# check new version is greater than the current one +if ($tag -eq $old_version["str"]) { + Write-Host "the new tag: $tag is the same with the old one:" $old_version["str"]; + exit; +} elseif ($tag -lt $old_version["str"]) { + Write-Host "$tag is older version than " $old_version['str']", please recheck your target version."; + exit; +} +Write-Host "bump version to $tag ... " +#get date-time string in english date-time format +$CurrentCulture = [System.Globalization.CultureInfo]::InvariantCulture +$currentDateTime = (Get-Date).ToString("ddd, dd MMM yyyy HH:mm:ss K", $CurrentCulture) + +#update appcast files +update_appcast_file -filePath "update/appcast.xml" -pat_orig "$old_major\.$old_minor\.$old_patch" -pat_replace $tag +update_appcast_file -filePath "update/appcast.xml" -pat_orig ".*?" -pat_replace "$currentDateTime" +Write-Host "update/appcast.xml updated" +update_appcast_file -filePath "update/testing-appcast.xml" -pat_orig "$old_major\.$old_minor\.$old_patch" -pat_replace $tag +update_appcast_file -filePath "update/testing-appcast.xml" -pat_orig ".*?" -pat_replace "$currentDateTime" +Write-Host "update/testing-appcast.xml updated" +#update bat files +update_bat_file -filePath "build.bat" -old_version $old_version -new_version $new_version +Write-Host "build.bat updated" +update_bat_file -filePath "xbuild.bat" -old_version $old_version -new_version $new_version +Write-Host "xbuild.bat updated" +#update CHANGELOG.md +if ($updatelog) { + update_changelog -new_tag $tag -old_tag "$old_major.$old_minor.$old_patch" + & git add CHANGELOG.md + Write-Host "CHANGELOG.md updated" +} +#commit changes and make a new tag +$release_message = "chore(release): $tag :tada:" +$release_tag = $tag +& git add update/*.xml build.bat xbuild.bat +& git commit --message $release_message +& git tag --annotate $release_tag --message $release_message diff --git a/update/bump-version.sh b/update/bump-version.sh index 2fca3fdda..52e0557db 100755 --- a/update/bump-version.sh +++ b/update/bump-version.sh @@ -72,6 +72,9 @@ update_version_number() { update_version_number build.bat VERSION_MAJOR $old_major $new_major update_version_number build.bat VERSION_MINOR $old_minor $new_minor update_version_number build.bat VERSION_PATCH $old_patch $new_patch +update_version_number xbuild.bat VERSION_MAJOR $old_major $new_major +update_version_number xbuild.bat VERSION_MINOR $old_minor $new_minor +update_version_number xbuild.bat VERSION_PATCH $old_patch $new_patch if [[ $OSTYPE =~ darwin ]]; then L_BOUND='[[:<:]]' @@ -114,13 +117,14 @@ update_version_string update/appcast.xml update_pub_date update/testing-appcast.xml update_pub_date update/appcast.xml -update_changelog "${new_version}" -${VISUAL:-${EDITOR:-nano}} CHANGELOG.md -match_line "## ${new_version} " CHANGELOG.md || ( - echo >&2 "CHANGELOG.md has no changes for version ${new_version}." - exit 1 -) -bash update/write-release-notes.sh +# changelog manually, so disable this +#update_changelog "${new_version}" +#${VISUAL:-${EDITOR:-nano}} CHANGELOG.md +#match_line "## ${new_version} " CHANGELOG.md || ( +# echo >&2 "CHANGELOG.md has no changes for version ${new_version}." +# exit 1 +#) +#bash update/write-release-notes.sh release_message="chore(release): ${new_version} :tada:" release_tag="${new_version}" diff --git a/update/testing-appcast.xml b/update/testing-appcast.xml index 2f93d3fac..546ef60b4 100644 --- a/update/testing-appcast.xml +++ b/update/testing-appcast.xml @@ -1,17 +1,17 @@ - - - - 【小狼毫】輸入法測試頻道 - http://rime.github.io/testing/weasel/appcast.xml - 小狼毫測試版 Appcast 更新頻道 - zh - - 小狼毫 0.16.1 - http://rime.github.io/testing/weasel/release-notes.html - Thu, 06 Jun 2024 19:29:28 +0800 - - - - + + + + 【小狼毫】輸入法測試頻道 + http://rime.github.io/testing/weasel/appcast.xml + 小狼毫測試版 Appcast 更新頻道 + zh + + 小狼毫 0.16.3 + http://rime.github.io/testing/weasel/release-notes.html + Fri, 04 Oct 2024 21:08:10 +08:00 + + + + diff --git a/xbuild.bat b/xbuild.bat new file mode 100644 index 000000000..943399c64 --- /dev/null +++ b/xbuild.bat @@ -0,0 +1,221 @@ +@echo off +setlocal enabledelayedexpansion +if not defined include ( + echo You should run this inside Developer Command Promt! + exit /b +) +for %%a in ("%include:;=" "%") do ( + echo %%a| findstr /r "ATLMFC\\include" > nul + if not errorlevel 1 ( + set "atl_lib_dir=%%a" + set dpi_manifest=!atl_lib_dir:ATLMFC\include=Include\Manifest\PerMonitorHighDPIAware.manifest! + if not exist ".\PerMonitorHighDPIAware.manifest" ( + copy ""!dpi_manifest!"" .\ + ) + ) +) +rem --------------------------------------------------------------------------- +if not exist env.bat copy env.bat.template env.bat +if exist env.bat call env.bat +set PRODUCT_VERSION= +if not defined WEASEL_ROOT set WEASEL_ROOT=%CD% +if not defined VERSION_MAJOR set VERSION_MAJOR=0 +if not defined VERSION_MINOR set VERSION_MINOR=16 +if not defined VERSION_PATCH set VERSION_PATCH=3 + +if not defined WEASEL_VERSION set WEASEL_VERSION=%VERSION_MAJOR%.%VERSION_MINOR%.%VERSION_PATCH% +if not defined WEASEL_BUILD set WEASEL_BUILD=0 + +rem use numeric build version for release build +set PRODUCT_VERSION=%WEASEL_VERSION%.%WEASEL_BUILD% +rem for non-release build, try to use git commit hash as product build version +if not defined RELEASE_BUILD ( + rem check if git is installed and available, then get the short commit id of head + git --version >nul 2>&1 + if not errorlevel 1 ( + for /f "delims=" %%i in ('git tag --sort=-creatordate ^| findstr /r "%WEASEL_VERSION%"') do ( + set LAST_TAG=%%i + goto found_tag + ) + :found_tag + for /f "delims=" %%i in ('git rev-list %LAST_TAG%..HEAD --count') do ( + set WEASEL_BUILD=%%i + ) + rem get short commmit id of head + for /F %%i in ('git rev-parse --short HEAD') do (set PRODUCT_VERSION=%WEASEL_VERSION%.%WEASEL_BUILD%.%%i) + ) +) + +rem FILE_VERSION is always 4 numbers; same as PRODUCT_VERSION in release build +if not defined FILE_VERSION set FILE_VERSION=%WEASEL_VERSION%.%WEASEL_BUILD% +echo PRODUCT_VERSION=%PRODUCT_VERSION% +echo WEASEL_VERSION=%WEASEL_VERSION% +echo WEASEL_BUILD=%WEASEL_BUILD% +echo WEASEL_ROOT=%WEASEL_ROOT% +echo WEASEL_BUNDLED_RECIPES=%WEASEL_BUNDLED_RECIPES% +echo BOOST_ROOT=%BOOST_ROOT% + +if defined GITHUB_ENV ( + setlocal enabledelayedexpansion + echo git_ref_name=%PRODUCT_VERSION%>>!GITHUB_ENV! +) + +rem --------------------------------------------------------------------------- +rem parse the command line options +set build_config=release +set build_rebuild=0 +set build_boost=0 +set boost_build_variant=release +set build_data=0 +set build_opencc=0 +set build_rime=0 +set rime_build_variant=release +set build_weasel=0 +set build_installer=0 +set build_arm64=0 +set build_clean=0 +set build_commands=0 +:parse_cmdline_options + if "%1" == "" goto end_parsing_cmdline_options + if "%1" == "debug" ( + set build_config=debug + set boost_build_variant=debug + set rime_build_variant=debug + ) + if "%1" == "release" ( + set build_config=release + set boost_build_variant=release + set rime_build_variant=release + ) + if "%1" == "rebuild" set build_rebuild=1 + if "%1" == "boost" set build_boost=1 + if "%1" == "data" set build_data=1 + if "%1" == "opencc" set build_opencc=1 + if "%1" == "rime" set build_rime=1 + if "%1" == "librime" set build_rime=1 + if "%1" == "weasel" set build_weasel=1 + if "%1" == "installer" set build_installer=1 + if "%1" == "arm64" set build_arm64=1 + if "%1" == "clean" set build_clean=1 + if "%1" == "commands" set build_commands=1 + if "%1" == "all" ( + set build_boost=1 + set build_data=1 + set build_opencc=1 + set build_rime=1 + set build_weasel=1 + set build_installer=1 + set build_arm64=1 + set build_commands=1 + ) + shift + goto parse_cmdline_options +:end_parsing_cmdline_options + +if %build_weasel% == 0 ( +if %build_boost% == 0 ( +if %build_data% == 0 ( +if %build_opencc% == 0 ( +if %build_rime% == 0 ( +if %build_commands% == 0 ( + set build_weasel=1 +)))))) +rem +rem quit WeaselServer.exe before building +cd /d %WEASEL_ROOT% +if exist output\weaselserver.exe ( + output\weaselserver.exe /q +) + +rem build booost +if %build_boost% == 1 ( + if %build_arm64% == 1 ( + call build.bat boost arm64 + ) else ( + call build.bat boost + ) + if errorlevel 1 exit /b 1 + cd /d %WEASEL_ROOT% +) +if %build_rime% == 1 ( + call build.bat rime + if errorlevel 1 exit /b 1 + cd /d %WEASEL_ROOT% +) +if %build_data% == 1 ( + call build.bat data + if errorlevel 1 exit /b 1 + cd /d %WEASEL_ROOT% +) +if %build_opencc% == 1 ( + call build.bat opencc + if errorlevel 1 exit /b 1 + cd /d %WEASEL_ROOT% +) + +if %build_commands% == 1 ( + echo Generating compile_commands.json + xmake project -k compile_commands -m %build_config% +) + +rem if to clean +if %build_clean% == 1 ( goto clean ) +if %build_weasel% == 0 ( goto end ) + +if %build_arm64% == 1 ( + xmake f -a arm64 -m %build_config% + if %build_rebuild% == 1 ( xmake clean ) + xmake + if errorlevel 1 goto error + xmake f -a arm -m %build_config% + if %build_rebuild% == 1 ( xmake clean ) + xmake + if errorlevel 1 goto error +) +xmake f -a x64 -m %build_config% +if %build_rebuild% == 1 ( xmake clean ) +xmake +if errorlevel 1 goto error +xmake f -a x86 -m %build_config% +if %build_rebuild% == 1 ( xmake clean ) +xmake +if errorlevel 1 goto error + +if %build_arm64% == 1 ( + pushd arm64x_wrapper + call build.bat + if errorlevel 1 goto error + popd + + copy arm64x_wrapper\weaselARM64X.dll output + if errorlevel 1 goto error + copy arm64x_wrapper\weaselARM64X.ime output + if errorlevel 1 goto error +) +if %build_installer% == 1 ( + "%ProgramFiles(x86)%"\NSIS\Bin\makensis.exe ^ + /DWEASEL_VERSION=%WEASEL_VERSION% ^ + /DWEASEL_BUILD=%WEASEL_BUILD% ^ + /DPRODUCT_VERSION=%PRODUCT_VERSION% ^ + output\install.nsi + if errorlevel 1 goto error +) +goto end + +:clean + if exist build ( + rmdir /s /q build + if errorlevel 1 ( + echo error cleaning weasel build + goto error + ) + goto end + ) + +:error + echo error building weasel... + exit /b 1 + +:end + cd %WEASEL_ROOT% + diff --git a/xmake.lua b/xmake.lua new file mode 100644 index 000000000..3a61b7fe1 --- /dev/null +++ b/xmake.lua @@ -0,0 +1,107 @@ +-- 工作区的xmake.lua +set_project("weasel") + +-- 定义全局变量 +set_xmakever("2.9.4") +set_languages("c++17") +add_defines("UNICODE", "_UNICODE") +add_defines("WINDOWS") +add_defines("MSVC") + +add_includedirs("$(projectdir)/include") +-- 设置Boost库的全局路径 +boost_root = os.getenv("BOOST_ROOT") +boost_include_path = boost_root +boost_lib_path = boost_root .. "/stage/lib" +add_includedirs(boost_include_path) +add_linkdirs(boost_lib_path) +add_cxflags("/utf-8 /MP /O2 /Oi /Gm- /EHsc /MT /GS /Gy /fp:precise /Zc:wchar_t /Zc:forScope /Zc:inline /external:W3 /Gd /TP /FC") +add_ldflags("/TLBID:1 /DYNAMICBASE /NXCOMPAT") + +-- 全局ATL lib路径 +local atl_lib_dir = '' +dpi_manifest = '' +for include in string.gmatch(os.getenv("include"), "([^;]+)") do + if atl_lib_dir=='' and include:match(".*ATLMFC\\include\\?$") then + atl_lib_dir = include:replace("include$", "lib") + dpi_manifest = include:replace("ATLMFC\\include$", "Include\\Manifest\\PerMonitorHighDPIAware.manifest") + end + add_includedirs(include) +end + +add_includedirs("$(projectdir)/include/wtl") + +if is_arch("x64") then + add_linkdirs("$(projectdir)/lib64") + add_linkdirs(atl_lib_dir .. "/x64") +elseif is_arch("x86") then + add_linkdirs("$(projectdir)/lib") + add_linkdirs(atl_lib_dir .. "/x86") +elseif is_arch("arm") then + add_linkdirs(atl_lib_dir .. "/arm") +elseif is_arch("arm64") then + add_linkdirs(atl_lib_dir .. "/arm64") +end + +add_links("atls", "shell32", "advapi32", "gdi32", "user32", "uuid", "ole32") + +includes("WeaselIPC", "WeaselUI", "WeaselTSF", "WeaselIME") + +if is_arch("x64") or is_arch("x86") then + includes("RimeWithWeasel", "WeaselIPCServer", "WeaselServer", "WeaselDeployer") +end + +if is_arch("x86") then + includes("WeaselSetup") +end + +if is_mode("debug") then + includes("test/TestWeaselIPC") + includes("test/TestResponseParser") +else + add_cxflags("/GL") + add_ldflags("/LTCG /INCREMENTAL:NO", {force = true}) +end + +rule("subcmd") + on_load(function(target) + target:add("ldflags", "/SUBSYSTEM:CONSOLE") + end) +rule("subwin") + on_load(function(target) + target:add("ldflags", "/SUBSYSTEM:WINDOWS") + end) + +rule("add_rcfiles") + on_load(function(target) + target:add("files", path.join(target:scriptdir(), "*.rc"), + {defines = {"VERSION_MAJOR=" .. os.getenv("VERSION_MAJOR"), + "VERSION_MINOR=" .. os.getenv("VERSION_MINOR"), + "VERSION_PATCH=" .. os.getenv("VERSION_PATCH"), + "FILE_VERSION=" .. os.getenv("FILE_VERSION"), + "PRODUCT_VERSION=" .. os.getenv("PRODUCT_VERSION") + }}) + end) +rule("use_weaselconstants") + on_load(function(target) + function check_include_weasel_constants_in_dir(dir) + local files = os.files(path.join(dir, "**.h")) + table.join2(files, os.files(path.join(dir, "**.cpp"))) + for _, file in ipairs(files) do + local content = io.readfile(file) + if content:find('#include%s+"WeaselConstants%.h"') or content:find('#include%s+') then + return true + end + end + return false + end + if check_include_weasel_constants_in_dir(target:scriptdir()) then + target:add("defines", { + "VERSION_MAJOR=" .. os.getenv("VERSION_MAJOR"), + "VERSION_MINOR=" .. os.getenv("VERSION_MINOR"), + "VERSION_PATCH=" .. os.getenv("VERSION_PATCH"), + "FILE_VERSION=" .. os.getenv("FILE_VERSION"), + "PRODUCT_VERSION=" .. os.getenv("PRODUCT_VERSION") + }) + end + end)