diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 85801822..8cf65c70 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -3,60 +3,61 @@ name: CI on: push: branches: - - 'develop' - - 'releases/*' + - "develop" + - "releases/*" pull_request: branches: - - 'develop' + - "develop" env: CARGO_TERM_COLOR: always jobs: build: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 - - uses: cachix/install-nix-action@v18 - with: - github_access_token: ${{ secrets.GITHUB_TOKEN }} - - name: Caching cargo - uses: actions/cache@v2 - with: - path: | - ~/.cargo/registry - ~/.cargo/git - target - key: ${{ runner.os }}-nix-rustc-v1-1.55.0-${{ hashFiles('Cargo.lock') }} - restore-keys: | - ${{ runner.os }}-nix-rustc-v1-1.55.0- - - run: nix develop -c bash scripts/build.sh -ad - - run: nix develop -c cargo test + - uses: actions/checkout@v4 + - uses: cachix/install-nix-action@v18 + with: + github_access_token: ${{ secrets.GITHUB_TOKEN }} + - name: Caching cargo + uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + target + key: ${{ runner.os }}-nix-rustc-v1-1.55.0-${{ hashFiles('Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-nix-rustc-v1-1.55.0- + - run: nix develop -c meson setup build --buildtype=debug -Dcargo_profile=debug + - run: nix develop -c ninja -C build + - run: nix develop -c cargo test cargo-deny: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 strategy: matrix: checks: - bans licenses sources steps: - - uses: actions/checkout@v4 - - uses: EmbarkStudios/cargo-deny-action@v1 - with: - command: check ${{ matrix.checks }} + - uses: actions/checkout@v4 + - uses: EmbarkStudios/cargo-deny-action@v2 format: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 + - name: Install Rustfmt + run: rustup component add rustfmt - name: Check Rustfmt run: cargo fmt -- --check spell-check: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 - - uses: crate-ci/typos@master + - uses: actions/checkout@v4 + - uses: crate-ci/typos@master diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 4ea684c6..5be6b06c 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -5,323 +5,231 @@ on: tags: - "v*" -env: - DOCKER_BUILDKIT: 1 +permissions: + contents: write jobs: - create-release: - runs-on: ubuntu-20.04 - - outputs: - url: ${{ steps.create_release.outputs.upload_url }} - - steps: - - name: Create draft release - id: create_release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ github.ref }} - release_name: Release ${{ github.ref }} - draft: true - prerelease: false - - build-engine: - runs-on: ubuntu-20.04 - + build-archive: + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - - name: Build engine - run: | - sudo apt-get update - sudo apt-get install -y libclang-10-dev - cargo build --release -p kime-engine-capi - LD_LIBRARY_PATH=$PWD/target/release cargo build --release -p kime-check - strip -s ./target/release/libkime_engine.so - strip -s ./target/release/kime-check - - name: Upload cpp header - uses: actions/upload-artifact@v2 + - uses: cachix/install-nix-action@v18 with: - name: cpp-header - path: ./src/engine/cffi/kime_engine.hpp - - name: Upload engine - uses: actions/upload-artifact@v2 - with: - name: engine - path: ./target/release/libkime_engine.so - - name: Upload check - uses: actions/upload-artifact@v2 - with: - name: check - path: ./target/release/kime-check + github_access_token: ${{ secrets.GITHUB_TOKEN }} - build-other: - needs: - - build-engine - - create-release - - runs-on: ubuntu-20.04 + - name: Build + run: | + nix develop -c meson setup build \ + -Dgtk3=enabled -Dgtk4=enabled -Dqt5=disabled -Dqt6=disabled + nix develop -c ninja -C build - steps: - - uses: actions/checkout@v4 - - name: Install deps + - name: Strip run: | - sudo apt-get update - sudo apt-get install -y libclang-10-dev - sudo apt-get install -y libgtk-3-dev + for f in kime kime-check kime-indicator kime-candidate-window kime-xim kime-wayland; do + [ -f "target/release/$f" ] && strip -s "target/release/$f" + done + [ -f "target/release/libkime_engine.so" ] && strip -s target/release/libkime_engine.so + for f in build/src/frontends/*/lib*.so; do + [ -e "$f" ] && strip -s "$f" + done - - name: Download engine - uses: actions/download-artifact@v2 + - name: Upload engine artifacts + uses: actions/upload-artifact@v4 with: name: engine - path: . + path: | + target/release/libkime_engine.so + src/engine/capi/kime_engine.h + src/engine/capi/kime_engine.hpp - - name: Download check - uses: actions/download-artifact@v2 - with: - name: check - path: . - - - name: Build + - name: Create archive run: | - sudo mv ./libkime_engine.so /usr/lib - KIME_SKIP_ENGINE=1 scripts/build.sh -ar - cp /usr/lib/libkime_engine.so ./build/out - mv ./kime-check ./build/out - scripts/release-zst.sh . + # run inside nix develop so the cargo rebuild (build_always_stale) + # uses nix's rust, not the runner's rustup (which races on rust-src) + DESTDIR=$(pwd)/kime-install nix develop -c ninja -C build install + tar -C kime-install -caf kime-${{ github.ref_name }}.tar.zst . - - name: Upload artifact - uses: actions/upload-artifact@v2 + - name: Upload release + uses: softprops/action-gh-release@v2 with: - name: other - path: ./build/out/* - - - name: Upload zst - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ needs.create-release.outputs.url }} - asset_path: ./kime.tar.zst - asset_name: kime-${{ github.ref }}.tar.zst - asset_content_type: application/zstd + draft: true + files: kime-${{ github.ref_name }}.tar.zst build-qt5: - needs: - - build-engine - - create-release - - runs-on: ubuntu-20.04 - + needs: build-archive + runs-on: ubuntu-24.04 strategy: matrix: - # 5.15.3 doesn't have binary release - qt5: - - 5.9.5 - - 5.11.3 - - 5.12.8 - - 5.12.9 - - 5.14.2 - - 5.15.2 - + qt5: ['5.12.8', '5.15.2'] steps: + - uses: actions/checkout@v4 + - name: Download engine - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: engine - path: . - - - name: Download header - uses: actions/download-artifact@v2 - with: - name: cpp-header - path: . + path: ./engine-artifacts - name: Install engine run: | - sudo mv ./libkime_engine.so /usr/lib - sudo mv ./kime_engine.hpp /usr/include + sudo install -Dm755 engine-artifacts/target/release/libkime_engine.so -t /usr/lib + sudo install -Dm644 engine-artifacts/src/engine/capi/kime_engine.h -t /usr/include + sudo install -Dm644 engine-artifacts/src/engine/capi/kime_engine.hpp -t /usr/include + sudo ldconfig - - name: Install Qt-${{ matrix.qt5 }} + - name: Install Qt ${{ matrix.qt5 }} uses: jurplel/install-qt-action@v4 with: dir: /opt version: ${{ matrix.qt5 }} - - uses: actions/checkout@v4 + - name: Install meson + run: sudo apt-get update && sudo apt-get install -y meson - - name: Build Qt-${{ matrix.qt5 }} + - name: Build Qt5 plugin run: | - mkdir build - cd build - cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_QT5=ON ../src - make -j$(nproc --all) - strip -s ./lib/libkime-qt5.so - - - name: Upload Qt-${{ matrix.qt5 }} artifact - uses: actions/upload-artifact@v2 - with: - name: qt-${{matrix.qt5}} - path: build/lib/libkime-qt5.so + meson setup build -Dsystem_engine=true -Dqt5=enabled -Dqt6=disabled -Dgtk3=disabled -Dgtk4=disabled + ninja -C build + strip -s build/src/frontends/qt5/libkimeplatforminputcontextplugin.so + cp build/src/frontends/qt5/libkimeplatforminputcontextplugin.so libkime-qt-${{ matrix.qt5 }}.so - - name: Upload Qt-${{ matrix.qt5 }} file - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Upload release + uses: softprops/action-gh-release@v2 with: - upload_url: ${{ needs.create-release.outputs.url }} - asset_path: build/lib/libkime-qt5.so - asset_name: libkime-qt-${{ matrix.qt5 }}.so - asset_content_type: application/x-sharedlib + draft: true + files: libkime-qt-${{ matrix.qt5 }}.so build-qt6: - needs: - - build-engine - - create-release - - runs-on: ubuntu-20.04 - + needs: build-archive + runs-on: ubuntu-24.04 strategy: matrix: - qt6: - - 6.0.2 - + qt6: ['6.2.4', '6.5.3', '6.7.3', '6.8.2', '6.9.3', '6.10.3'] steps: + - uses: actions/checkout@v4 + - name: Download engine - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: engine - path: . - - - name: Download header - uses: actions/download-artifact@v2 - with: - name: cpp-header - path: . + path: ./engine-artifacts - name: Install engine run: | - sudo mv ./libkime_engine.so /usr/lib - sudo mv ./kime_engine.hpp /usr/include + sudo install -Dm755 engine-artifacts/target/release/libkime_engine.so -t /usr/lib + sudo install -Dm644 engine-artifacts/src/engine/capi/kime_engine.h -t /usr/include + sudo install -Dm644 engine-artifacts/src/engine/capi/kime_engine.hpp -t /usr/include + sudo ldconfig - - name: Install Qt-${{ matrix.qt6 }} + - name: Install Qt ${{ matrix.qt6 }} uses: jurplel/install-qt-action@v4 with: dir: /opt version: ${{ matrix.qt6 }} - - uses: actions/checkout@v4 + - name: Install meson + run: sudo apt-get update && sudo apt-get install -y meson - - name: Build Qt-${{ matrix.qt6 }} + - name: Build Qt6 plugin run: | - mkdir build - cd build - cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_QT6=ON ../src - make -j$(nproc --all) - strip -s ./lib/libkime-qt6.so + meson setup build -Dsystem_engine=true -Dqt6=enabled -Dqt5=disabled -Dgtk3=disabled -Dgtk4=disabled + ninja -C build + strip -s build/src/frontends/qt6/libkimeplatforminputcontextplugin.so + cp build/src/frontends/qt6/libkimeplatforminputcontextplugin.so libkime-qt-${{ matrix.qt6 }}.so - - name: Upload Qt-${{ matrix.qt6 }} artifact - uses: actions/upload-artifact@v2 + - name: Upload release + uses: softprops/action-gh-release@v2 with: - name: qt-${{matrix.qt6}} - path: build/lib/libkime-qt6.so - - - name: Upload Qt-${{ matrix.qt6 }} file - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ needs.create-release.outputs.url }} - asset_path: build/lib/libkime-qt6.so - asset_name: libkime-qt-${{ matrix.qt6 }}.so - asset_content_type: application/x-sharedlib - - package-archive: - needs: - - build-other - - build-qt5 - - build-qt6 - - create-release - - runs-on: ubuntu-20.04 + draft: true + files: libkime-qt-${{ matrix.qt6 }}.so + build-deb: + runs-on: ubuntu-24.04 + container: ${{ matrix.container }} strategy: - fail-fast: false matrix: include: - - qt5: 5.9.5 - pkg: deb - name: ubuntu-18.04 - - qt5: 5.12.8 - pkg: deb - name: ubuntu-20.04 - - qt5: 5.14.2 - pkg: deb - name: ubuntu-20.10 - - qt5: 5.15.2 - pkg: deb - name: ubuntu-22.04 - - qt5: 5.11.3 - pkg: deb - name: debian-buster - - qt5: 5.15.2 - qt6: 6.0.2 - pkg: zst - name: latest + - container: ubuntu:22.04 + gtk3: enabled + gtk4: enabled + qt5: enabled + qt6: enabled + suffix: ubuntu-22.04 + - container: ubuntu:24.04 + gtk3: enabled + gtk4: enabled + qt5: enabled + qt6: enabled + suffix: ubuntu-24.04 + - container: debian:bookworm + gtk3: enabled + gtk4: enabled + qt5: enabled + qt6: enabled + suffix: debian-bookworm + - container: debian:trixie + gtk3: enabled + gtk4: enabled + qt5: enabled + qt6: enabled + suffix: debian-trixie steps: - - uses: actions/checkout@v4 - - - name: Create out folder - run: mkdir -pv ./build/out - - - name: Download qt5 artifact - if: ${{ matrix.qt5 }} - uses: actions/download-artifact@v2 - with: - name: qt-${{ matrix.qt5 }} - path: ./build/out - - - name: Download qt6 artifact - if: ${{ matrix.qt6 }} - uses: actions/download-artifact@v2 - with: - name: qt-${{ matrix.qt6 }} - path: ./build/out - - - name: Download other artifact - uses: actions/download-artifact@v2 - with: - name: other - path: ./build/out + - name: Install dependencies + env: + DEBIAN_FRONTEND: noninteractive + run: | + apt-get update + # NOTE: meson is installed via pip below, not apt: ubuntu 22.04 ships + # meson 0.61 and debian bookworm 1.0.1, both older than the >=1.1 the + # project requires. ninja still comes from apt. + PKGS="build-essential curl git pkg-config libclang-dev ninja-build python3 python3-venv" + if [ "${{ matrix.gtk3 }}" = "enabled" ]; then PKGS="$PKGS libgtk-3-dev"; fi + if [ "${{ matrix.gtk4 }}" = "enabled" ]; then PKGS="$PKGS libgtk-4-dev"; fi + if [ "${{ matrix.qt5 }}" = "enabled" ]; then PKGS="$PKGS qtbase5-dev qtbase5-private-dev"; fi + if [ "${{ matrix.qt6 }}" = "enabled" ]; then PKGS="$PKGS qt6-base-dev qt6-base-private-dev"; fi + apt-get install -y $PKGS + # modern meson in an isolated venv (avoids PEP668 on bookworm/trixie/24.04) + python3 -m venv /opt/mesonenv + /opt/mesonenv/bin/pip install --quiet --upgrade pip meson + echo "/opt/mesonenv/bin" >> "$GITHUB_PATH" + + - name: Install Rust + run: | + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y + echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" + export PATH="$HOME/.cargo/bin:$PATH" + rustup default stable - - name: Create deb - if: ${{ matrix.pkg == 'deb' }} - run: scripts/release-deb.sh . + - uses: actions/checkout@v4 - - name: Upload deb - if: ${{ matrix.pkg == 'deb' }} - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ needs.create-release.outputs.url }} - asset_path: ./kime_amd64.deb - asset_name: kime_${{ matrix.name }}_${{ github.ref }}_amd64.deb - asset_content_type: application/x-xz + - name: Build + run: | + MULTIARCH=$(dpkg-architecture -qDEB_HOST_MULTIARCH) + meson setup build --prefix=/usr --libdir="lib/$MULTIARCH" \ + -Dgtk3=${{ matrix.gtk3 }} -Dgtk4=${{ matrix.gtk4 }} \ + -Dqt5=${{ matrix.qt5 }} -Dqt6=${{ matrix.qt6 }} + ninja -C build - - name: Create zst - if: ${{ matrix.pkg == 'zst' }} - run: scripts/release-zst.sh . + - name: Strip + run: | + for f in kime kime-check kime-indicator kime-candidate-window kime-xim kime-wayland; do + [ -f "target/release/$f" ] && strip -s "target/release/$f" + done + [ -f "target/release/libkime_engine.so" ] && strip -s target/release/libkime_engine.so + for f in build/src/frontends/*/lib*.so; do + [ -e "$f" ] && strip -s "$f" + done + + - name: Build .deb + run: | + mkdir -p output + bash packaging/build-deb.sh build output + ARCH=$(dpkg --print-architecture) + mv output/kime_*_${ARCH}.deb "output/kime-${{ github.ref_name }}_${ARCH}_${{ matrix.suffix }}.deb" - - name: Upload zst - if: ${{ matrix.pkg == 'zst' }} - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Upload release + uses: softprops/action-gh-release@v2 with: - upload_url: ${{ needs.create-release.outputs.url }} - asset_path: ./kime.tar.zst - asset_name: kime_${{ matrix.name }}_${{ github.ref }}.tar.zst - asset_content_type: application/zstd + draft: true + files: output/kime-*.deb diff --git a/.gitignore b/.gitignore index 9b4aeb32..d1b99f13 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ kime_engine.h kime_engine.hpp massif.out* flamegraph.svg +kime-crash.log result .DS_Store diff --git a/.vscode/launch.json b/.vscode/launch.json index 3e7b9a39..19e6f5cf 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,12 +4,6 @@ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ - { - "type": "lldb", - "request": "attach", - "name": "Attach", - "program": "java" - }, { "type": "lldb", "request": "attach", @@ -59,7 +53,9 @@ "LD_LIBRARY_PATH": "${workspaceFolder}/target/debug" }, "program": "${cargo:program}", - "args": ["--verbose"] + "args": [ + "--verbose" + ] }, { "type": "lldb", @@ -75,7 +71,9 @@ "LD_LIBRARY_PATH": "${workspaceFolder}/target/debug" }, "program": "${cargo:program}", - "args": ["--verbose"] + "args": [ + "--verbose" + ] }, { "type": "lldb", @@ -89,7 +87,14 @@ "G_MESSAGES_DEBUG": "kime", }, "program": "/usr/lib64/firefox/firefox", - "args": ["-g", "-new-instance", "-P", "kime-debug", "-new-window", "https://codepen.io/hpop/pen/drLiH"] + "args": [ + "-g", + "-new-instance", + "-P", + "kime-debug", + "-new-window", + "https://codepen.io/hpop/pen/drLiH" + ] }, { "type": "lldb", @@ -103,7 +108,9 @@ "G_MESSAGES_DEBUG": "kime" }, "program": "/usr/lib/libreoffice/program/soffice.bin", - "args": ["--calc"] + "args": [ + "--calc" + ] }, { "type": "lldb", diff --git a/Cargo.lock b/Cargo.lock index b9f8b2c7..5b95cc72 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,112 +1,87 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "ab_glyph" -version = "0.2.28" +version = "0.2.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79faae4620f45232f599d9bc7b290f88247a0834162c4495ab2f02d60004adfb" +checksum = "01c0457472c38ea5bd1c3b5ada5e368271cb550be7a4ca4a0b4634e9913f6cc2" dependencies = [ "ab_glyph_rasterizer", - "owned_ttf_parser 0.24.0", + "owned_ttf_parser", ] [[package]] name = "ab_glyph_rasterizer" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" - -[[package]] -name = "accesskit" -version = "0.8.1" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3083ac5a97521e35388ca80cf365b6be5210962cc59f11ee238cd92ac2fa9524" -dependencies = [ - "enumset", - "kurbo", -] +checksum = "366ffbaa4442f4684d91e2cd7c5ea7c4ed8add41959a31447066e279e432b618" [[package]] -name = "accesskit_consumer" -version = "0.12.1" +name = "adler2" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f47393f706a2d2f9d1ebd109351f886afd256a09d2308861a6dec0853a625e2" -dependencies = [ - "accesskit", - "parking_lot", -] +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] -name = "accesskit_macos" -version = "0.4.2" +name = "ahash" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fabafb94d8a4dd6b20fe4112f943756ff8dc9778e3d742fb5478bf7f000a3282" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ - "accesskit", - "accesskit_consumer", - "objc2 0.3.0-beta.3", + "cfg-if", + "const-random", + "getrandom 0.3.4", "once_cell", - "parking_lot", + "version_check", + "zerocopy", ] [[package]] -name = "accesskit_windows" -version = "0.10.4" +name = "aho-corasick" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "662496f45a2e2ddff05e28d0a9fc2b319cc4f886d3664e3469c3d30800598962" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ - "accesskit", - "accesskit_consumer", - "arrayvec 0.7.4", - "once_cell", - "parking_lot", - "paste", - "windows", + "memchr", ] [[package]] -name = "accesskit_winit" -version = "0.7.3" +name = "alloca" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f270416d033ab5b2a8fa72a976dfdad0db1ea194721f16cadbdb45ff219779f" +checksum = "e5a7d05ea6aea7e9e64d25b9156ba2fee3fdd659e34e41063cd2fc7cd020d7f4" dependencies = [ - "accesskit", - "accesskit_macos", - "accesskit_windows", - "parking_lot", - "winit", + "cc", ] [[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "ahash" -version = "0.8.11" +name = "android-activity" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046" dependencies = [ - "cfg-if", - "const-random", - "getrandom 0.2.15", - "once_cell", - "version_check", - "zerocopy 0.7.35", + "android-properties", + "bitflags 2.10.0", + "cc", + "cesu8", + "jni", + "jni-sys", + "libc", + "log", + "ndk", + "ndk-context", + "ndk-sys", + "num_enum", + "thiserror 1.0.69", ] [[package]] -name = "aho-corasick" -version = "1.1.3" +name = "android-properties" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] +checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" [[package]] name = "anes" @@ -115,19 +90,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] -name = "ansi_term" -version = "0.12.1" +name = "anstyle" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "approx" @@ -140,182 +112,232 @@ dependencies = [ [[package]] name = "arboard" -version = "3.4.0" +version = "3.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb4009533e8ff8f1450a5bcbc30f4242a1d34442221f72314bea1f5dc9c7f89" +checksum = "0348a1c054491f4bfe6ab86a7b6ab1e44e45d899005de92f58b3df180b36ddaf" dependencies = [ "clipboard-win", + "image", "log", - "objc2 0.5.2", - "objc2-app-kit", - "objc2-foundation", + "objc2 0.6.3", + "objc2-app-kit 0.3.2", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-foundation 0.3.2", "parking_lot", - "x11rb 0.13.1", + "percent-encoding", + "windows-sys 0.60.2", + "x11rb", ] [[package]] -name = "arrayref" -version = "0.3.8" +name = "arrayvec" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] -name = "arrayvec" -version = "0.5.2" +name = "as-raw-xcb-connection" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" +checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" [[package]] -name = "arrayvec" -version = "0.7.4" +name = "async-broadcast" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532" +dependencies = [ + "event-listener", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] [[package]] -name = "atomic_refcell" -version = "0.1.13" +name = "async-recursion" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41e67cd8309bbd06cd603a9e693a784ac2e5d1e955f11286e355089fcab3047c" +checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "atty" -version = "0.2.14" +name = "async-trait" +version = "0.1.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ - "hermit-abi", - "libc", - "winapi", + "proc-macro2", + "quote", + "syn", ] +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "autocfg" -version = "1.3.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "bindgen" -version = "0.69.4" +version = "0.72.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" +checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "cexpr", "clang-sys", - "itertools 0.12.1", - "lazy_static", - "lazycell", + "itertools 0.13.0", "proc-macro2", "quote", "regex", - "rustc-hash", + "rustc-hash 2.1.1", "shlex", - "syn 2.0.72", + "syn", ] [[package]] -name = "bit_field" -version = "0.10.2" +name = "bit-set" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +dependencies = [ + "bit-vec", +] [[package]] -name = "bitflags" -version = "1.3.2" +name = "bit-vec" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" [[package]] name = "bitflags" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" - -[[package]] -name = "block" -version = "0.1.6" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] -name = "block-sys" -version = "0.1.0-beta.1" +name = "bitflags" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa55741ee90902547802152aaf3f8e5248aab7e21468089560d4c8840561146" -dependencies = [ - "objc-sys 0.2.0-beta.2", -] +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" [[package]] name = "block2" -version = "0.2.0-alpha.6" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dd9e63c1744f755c2f60332b88de39d341e5e86239014ad839bd71c106dec42" +checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" dependencies = [ - "block-sys", - "objc2-encode 2.0.0-pre.2", + "objc2 0.5.2", ] [[package]] name = "block2" -version = "0.5.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" +checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" dependencies = [ - "objc2 0.5.2", + "objc2 0.6.3", ] [[package]] name = "bumpalo" -version = "3.16.0" +version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" [[package]] name = "bytemuck" -version = "1.16.1" +version = "1.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b236fc92302c97ed75b38da1f4917b5cdda4984745740f153a5d3059e48d725e" +checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" dependencies = [ "bytemuck_derive", ] [[package]] name = "bytemuck_derive" -version = "1.7.0" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ee891b04274a59bd38b412188e24b849617b2e45a0fd8d057deb63e7403761b" +checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn", ] [[package]] -name = "byteorder" -version = "1.5.0" +name = "byteorder-lite" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" [[package]] name = "bytes" -version = "1.6.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" +checksum = "8ae3f5d315924270530207e2a68396c3cc547f6dca3fbdca317cfb1a51edb593" [[package]] name = "calloop" -version = "0.10.6" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52e0d00eb1ea24371a97d2da6201c6747a633dc6dc1988ef503403b4c59504a8" +checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.10.0", "log", - "nix 0.25.1", - "slotmap", - "thiserror", - "vec_map", + "polling", + "rustix 0.38.44", + "slab", + "thiserror 1.0.69", +] + +[[package]] +name = "calloop" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb9f6e1368bd4621d2c86baa7e37de77a938adf5221e5dd3d6133340101b309e" +dependencies = [ + "bitflags 2.10.0", + "polling", + "rustix 1.1.3", + "slab", + "tracing", +] + +[[package]] +name = "calloop-wayland-source" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" +dependencies = [ + "calloop 0.13.0", + "rustix 0.38.44", + "wayland-backend", + "wayland-client", +] + +[[package]] +name = "calloop-wayland-source" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138efcf0940a02ebf0cc8d1eff41a1682a46b431630f4c52450d6265876021fa" +dependencies = [ + "calloop 0.14.3", + "rustix 1.1.3", + "wayland-backend", + "wayland-client", ] [[package]] @@ -326,27 +348,33 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cbindgen" -version = "0.26.0" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da6bc11b07529f16944307272d5bd9b22530bc7d05751717c9d416586cedab49" +checksum = "befbfd072a8e81c02f8c507aefce431fe5e7d051f83d48a23ffc9b9fe5a11799" dependencies = [ "heck", - "indexmap 1.9.3", + "indexmap", "log", "proc-macro2", "quote", "serde", "serde_json", - "syn 1.0.109", + "syn", "tempfile", "toml", ] [[package]] name = "cc" -version = "1.1.7" +version = "1.2.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc" +checksum = "cd4932aefd12402b36c60956a4fe0035421f544799057659ff86f923657aada3" +dependencies = [ + "find-msvc-tools", + "jobserver", + "libc", + "shlex", +] [[package]] name = "cesu8" @@ -365,15 +393,15 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cfg_aliases" -version = "0.1.1" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "cgl" @@ -423,110 +451,47 @@ dependencies = [ [[package]] name = "clap" -version = "2.34.0" +version = "4.5.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +checksum = "c6e6ff9dcd79cff5cd969a17a545d79e84ab086e444102a591e288a8aa3ce394" dependencies = [ - "ansi_term", - "atty", - "bitflags 1.3.2", - "strsim 0.8.0", - "textwrap 0.11.0", - "unicode-width", - "vec_map", + "clap_builder", ] [[package]] -name = "clap" -version = "3.2.25" +name = "clap_builder" +version = "4.5.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" +checksum = "fa42cf4d2b7a41bc8f663a7cab4031ebafa1bf3875705bfaf8466dc60ab52c00" dependencies = [ - "bitflags 1.3.2", + "anstyle", "clap_lex", - "indexmap 1.9.3", - "textwrap 0.16.1", ] [[package]] name = "clap_lex" -version = "0.2.4" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" -dependencies = [ - "os_str_bytes", -] +checksum = "c3e64b0cc0439b12df2fa678eae89a1c56a529fd067a9115f7827f1fffd22b32" [[package]] name = "clipboard-win" -version = "5.4.0" +version = "5.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15efe7a882b08f34e38556b14f2fb3daa98769d06c7f0c1b076dfd0d983bc892" +checksum = "bde03770d3df201d4fb868f2c9c59e66a3e4e2bd06692a0fe701e7103c7e84d4" dependencies = [ "error-code", ] [[package]] -name = "cmake" -version = "0.1.50" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130" -dependencies = [ - "cc", -] - -[[package]] -name = "cocoa" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f425db7937052c684daec3bd6375c8abe2d146dca4b8b143d6db777c39138f3a" -dependencies = [ - "bitflags 1.3.2", - "block", - "cocoa-foundation", - "core-foundation", - "core-graphics 0.22.3", - "foreign-types 0.3.2", - "libc", - "objc", -] - -[[package]] -name = "cocoa" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6140449f97a6e97f9511815c5632d84c8aacf8ac271ad77c559218161a1373c" -dependencies = [ - "bitflags 1.3.2", - "block", - "cocoa-foundation", - "core-foundation", - "core-graphics 0.23.2", - "foreign-types 0.5.0", - "libc", - "objc", -] - -[[package]] -name = "cocoa-foundation" -version = "0.1.2" +name = "codespan-reporting" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7" +checksum = "fe6d2e5af09e8c8ad56c969f2157a3d4238cebc7c55f0a517728c38f7b200f81" dependencies = [ - "bitflags 1.3.2", - "block", - "core-foundation", - "core-graphics-types", - "libc", - "objc", + "unicode-width", ] -[[package]] -name = "color_quant" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" - [[package]] name = "combine" version = "4.6.7" @@ -537,6 +502,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "const-random" version = "0.1.18" @@ -552,25 +526,26 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" dependencies = [ - "getrandom 0.2.15", + "getrandom 0.2.17", "once_cell", "tiny-keccak", ] [[package]] -name = "conv" -version = "0.3.3" +name = "core-foundation" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ff10625fd0ac447827aa30ea8b861fead473bb60aeb73af6c1c58caf0d1299" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ - "custom_derive", + "core-foundation-sys", + "libc", ] [[package]] name = "core-foundation" -version = "0.9.4" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" dependencies = [ "core-foundation-sys", "libc", @@ -578,22 +553,9 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" - -[[package]] -name = "core-graphics" -version = "0.22.3" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "core-graphics-types", - "foreign-types 0.3.2", - "libc", -] +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "core-graphics" @@ -602,9 +564,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" dependencies = [ "bitflags 1.3.2", - "core-foundation", + "core-foundation 0.9.4", "core-graphics-types", - "foreign-types 0.5.0", + "foreign-types", "libc", ] @@ -615,52 +577,48 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" dependencies = [ "bitflags 1.3.2", - "core-foundation", + "core-foundation 0.9.4", "libc", ] [[package]] -name = "core-text" -version = "20.1.0" +name = "core_maths" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9d2790b5c08465d49f8dc05c8bcae9fea467855947db39b0f8145c091aaced5" +checksum = "77745e017f5edba1a9c1d854f6f3a52dac8a12dd5af5d2f54aecf61e43d80d30" dependencies = [ - "core-foundation", - "core-graphics 0.23.2", - "foreign-types 0.5.0", - "libc", + "libm", ] [[package]] name = "crc32fast" -version = "1.4.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" dependencies = [ "cfg-if", ] [[package]] name = "criterion" -version = "0.4.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c76e09c1aae2bc52b3d2f29e13c6572553b30c4aa1b8a49fd70de6412654cb" +checksum = "4d883447757bb0ee46f233e9dc22eb84d93a9508c9b868687b274fc431d886bf" dependencies = [ + "alloca", "anes", - "atty", "cast", "ciborium", - "clap 3.2.25", + "clap", "criterion-plot", - "itertools 0.10.5", - "lazy_static", + "itertools 0.13.0", "num-traits", "oorandom", + "page_size", "plotters", "rayon", "regex", "serde", - "serde_derive", "serde_json", "tinytemplate", "walkdir", @@ -668,19 +626,19 @@ dependencies = [ [[package]] name = "criterion-plot" -version = "0.5.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" +checksum = "ed943f81ea2faa8dcecbbfa50164acf95d555afec96a27871663b300e387b2e4" dependencies = [ "cast", - "itertools 0.10.5", + "itertools 0.13.0", ] [[package]] name = "crossbeam-deque" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -697,198 +655,124 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" - -[[package]] -name = "crossfont" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eb5a3822b594afc99b503cc1859b94686d3c3efdd60507a28587dab80ee1071" -dependencies = [ - "cocoa 0.25.0", - "core-foundation", - "core-foundation-sys", - "core-graphics 0.23.2", - "core-text", - "dwrote", - "foreign-types 0.5.0", - "freetype-rs", - "libc", - "log", - "objc", - "once_cell", - "pkg-config", - "servo-fontconfig", - "winapi", -] +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crunchy" -version = "0.2.2" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "ctrlc" -version = "3.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "672465ae37dc1bc6380a6547a8883d5dd397b0f1faaad4f265726cc7042a5345" -dependencies = [ - "nix 0.28.0", - "windows-sys 0.52.0", -] - -[[package]] -name = "cty" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" - -[[package]] -name = "custom_derive" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef8ae57c4978a2acd8b869ce6b9ca1dfe817bff704c220209fdef2c0b75a01b9" - -[[package]] -name = "daemonize" -version = "0.5.0" +version = "3.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab8bfdaacb3c887a54d41bdf48d3af8873b3f5566469f8ba21b92057509f116e" +checksum = "73736a89c4aff73035ba2ed2e565061954da00d4970fc9ac25dcc85a2a20d790" dependencies = [ - "libc", + "dispatch2", + "nix", + "windows-sys 0.61.2", ] [[package]] -name = "darling" -version = "0.13.4" +name = "cursor-icon" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" -dependencies = [ - "darling_core 0.13.4", - "darling_macro 0.13.4", -] +checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f" [[package]] name = "darling" -version = "0.20.10" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" dependencies = [ - "darling_core 0.20.10", - "darling_macro 0.20.10", + "darling_core", + "darling_macro", ] [[package]] name = "darling_core" -version = "0.13.4" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" +checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "strsim 0.10.0", - "syn 1.0.109", + "syn", ] [[package]] -name = "darling_core" -version = "0.20.10" +name = "darling_macro" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ - "fnv", - "ident_case", - "proc-macro2", + "darling_core", "quote", - "syn 2.0.72", + "syn", ] [[package]] -name = "darling_macro" -version = "0.13.4" +name = "deranged" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" -dependencies = [ - "darling_core 0.13.4", - "quote", - "syn 1.0.109", -] +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" [[package]] -name = "darling_macro" -version = "0.20.10" +name = "diff" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" -dependencies = [ - "darling_core 0.20.10", - "quote", - "syn 2.0.72", -] +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" [[package]] -name = "dbus" -version = "0.9.7" +name = "dispatch" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bb21987b9fb1613058ba3843121dd18b163b254d8a6e797e144cbac14d96d1b" -dependencies = [ - "libc", - "libdbus-sys", - "winapi", -] +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" [[package]] -name = "dbus-codegen" -version = "0.9.1" +name = "dispatch2" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a49da9fdfbe872d4841d56605dc42efa5e6ca3291299b87f44e1cde91a28617c" +checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" dependencies = [ - "clap 2.34.0", - "dbus", - "xml-rs", + "bitflags 2.10.0", + "block2 0.6.2", + "libc", + "objc2 0.6.3", ] [[package]] -name = "dbus-tree" -version = "0.9.2" +name = "displaydoc" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f456e698ae8e54575e19ddb1f9b7bce2298568524f215496b248eb9498b4f508" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ - "dbus", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "deranged" -version = "0.3.11" +name = "dlib" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" dependencies = [ - "powerfmt", + "libloading", ] [[package]] -name = "diff" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" - -[[package]] -name = "dispatch" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" - -[[package]] -name = "dlib" -version = "0.5.2" +name = "document-features" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" +checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" dependencies = [ - "libloading 0.8.5", + "litrs", ] [[package]] @@ -898,118 +782,161 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] -name = "dwrote" -version = "0.11.0" +name = "dpi" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439a1c2ba5611ad3ed731280541d36d2e9c4ac5e7fb818a27b604bdc5a6aa65b" -dependencies = [ - "lazy_static", - "libc", - "serde", - "serde_derive", - "winapi", - "wio", -] +checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" [[package]] name = "ecolor" -version = "0.20.0" +version = "0.33.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b601108bca3af7650440ace4ca55b2daf52c36f2635be3587d77b16efd8d0691" +checksum = "71ddb8ac7643d1dba1bb02110e804406dd459a838efcb14011ced10556711a8e" dependencies = [ "bytemuck", + "emath", ] [[package]] name = "eframe" -version = "0.20.1" +version = "0.33.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea929ec5819fef373728bb0e55003ce921975039cfec3ca8305bb024e5b7b32" +checksum = "457481173e6db5ca9fa2be93a58df8f4c7be639587aeb4853b526c6cf87db4e6" dependencies = [ + "ahash", "bytemuck", + "document-features", "egui", + "egui-wgpu", "egui-winit", "egui_glow", "glow", "glutin", + "glutin-winit", + "image", "js-sys", + "log", + "objc2 0.5.2", + "objc2-app-kit 0.2.2", + "objc2-foundation 0.2.2", + "parking_lot", "percent-encoding", - "raw-window-handle 0.5.2", - "tracing", + "profiling", + "raw-window-handle", + "static_assertions", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", + "web-time", + "windows-sys 0.61.2", "winit", ] [[package]] name = "egui" -version = "0.20.1" +version = "0.33.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65a5e883a316e53866977450eecfbcac9c48109c2ab3394af29feb83fcde4ea9" +checksum = "6a9b567d356674e9a5121ed3fedfb0a7c31e059fe71f6972b691bcd0bfc284e3" dependencies = [ - "accesskit", "ahash", + "bitflags 2.10.0", + "emath", "epaint", + "log", "nohash-hasher", - "tracing", + "profiling", + "smallvec", + "unicode-segmentation", +] + +[[package]] +name = "egui-wgpu" +version = "0.33.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e4d209971c84b2352a06174abdba701af1e552ce56b144d96f2bd50a3c91236" +dependencies = [ + "ahash", + "bytemuck", + "document-features", + "egui", + "epaint", + "log", + "profiling", + "thiserror 2.0.17", + "type-map", + "web-time", + "wgpu", + "winit", ] [[package]] name = "egui-winit" -version = "0.20.1" +version = "0.33.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5696bdbe60898b81157f07ae34fe02dbfd522174bd6e620942c269cd7307901f" +checksum = "ec6687e5bb551702f4ad10ac428bab12acf9d53047ebb1082d4a0ed8c6251a29" dependencies = [ - "accesskit_winit", "arboard", + "bytemuck", "egui", - "instant", + "log", + "objc2 0.5.2", + "objc2-foundation 0.2.2", + "objc2-ui-kit", + "profiling", + "raw-window-handle", "smithay-clipboard", - "tracing", + "web-time", "webbrowser", "winit", ] [[package]] name = "egui_glow" -version = "0.20.1" +version = "0.33.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d4b5960cb1bae1c403a6c9027a745210a41913433b10c73b6e7d76a1017f8b4" +checksum = "6420863ea1d90e750f75075231a260030ad8a9f30a7cef82cdc966492dc4c4eb" dependencies = [ "bytemuck", "egui", "glow", - "memoffset 0.6.5", - "tracing", + "log", + "memoffset", + "profiling", "wasm-bindgen", "web-sys", + "winit", ] [[package]] name = "either" -version = "1.13.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "emath" -version = "0.20.0" +version = "0.33.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5277249c8c3430e7127e4f2c40a77485e7baf11ae132ce9b3253a8ed710df0a0" +checksum = "491bdf728bf25ddd9ad60d4cf1c48588fa82c013a2440b91aa7fc43e34a07c32" dependencies = [ "bytemuck", ] [[package]] name = "encoding_rs" -version = "0.8.34" +version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ "cfg-if", ] +[[package]] +name = "endi" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66b7e2430c6dff6a955451e2cfc438f09cea1965a9d6f87f7e3b90decc014099" + [[package]] name = "enum-map" version = "2.7.3" @@ -1027,14 +954,35 @@ checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn", +] + +[[package]] +name = "enumflags2" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef" +dependencies = [ + "enumflags2_derive", + "serde", +] + +[[package]] +name = "enumflags2_derive" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] name = "enumset" -version = "1.1.5" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07a4b049558765cef5f0c1a273c3fc57084d768b44d2f98127aef4cceb17293" +checksum = "25b07a8dfbbbfc0064c0a6bdf9edcf966de6b1c33ce344bdeca3b41615452634" dependencies = [ "enumset_derive", "serde", @@ -1042,112 +990,132 @@ dependencies = [ [[package]] name = "enumset_derive" -version = "0.10.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59c3b24c345d8c314966bdc1832f6c2635bfcce8e7cf363bd115987bba2ee242" +checksum = "f43e744e4ea338060faee68ed933e46e722fb7f3617e722a5772d7e856d8b3ce" dependencies = [ - "darling 0.20.10", + "darling", "proc-macro2", "quote", - "syn 2.0.72", + "syn", ] [[package]] name = "epaint" -version = "0.20.0" +version = "0.33.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de14b65fe5e423e0058f77a8beb2c863b056d0566d6c4ce0d097aa5814cb705a" +checksum = "009d0dd3c2163823a0abdb899451ecbc78798dec545ee91b43aff1fa790bab62" dependencies = [ "ab_glyph", "ahash", - "atomic_refcell", "bytemuck", "ecolor", "emath", + "epaint_default_fonts", + "log", "nohash-hasher", "parking_lot", + "profiling", ] +[[package]] +name = "epaint_default_fonts" +version = "0.33.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c4fbe202b6578d3d56428fa185cdf114a05e49da05f477b3c7f0fbb221f1862" + [[package]] name = "equivalent" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.9" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] name = "error-code" -version = "3.2.0" +version = "3.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0474425d51df81997e2f90a21591180b38eccf27292d755f3e30750225c175b" +checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59" [[package]] -name = "expat-sys" -version = "2.1.6" +name = "event-listener" +version = "5.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658f19728920138342f68408b7cf7644d90d4784353d8ebc32e7e8663dbe45fa" +checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" dependencies = [ - "cmake", - "pkg-config", + "concurrent-queue", + "parking", + "pin-project-lite", ] [[package]] -name = "exr" -version = "1.72.0" +name = "event-listener-strategy" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "887d93f60543e9a9362ef8a21beedd0a833c5d9610e18c67abe15a5963dcb1a4" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" dependencies = [ - "bit_field", - "flume", - "half", - "lebe", - "miniz_oxide", - "rayon-core", - "smallvec", - "zune-inflate", + "event-listener", + "pin-project-lite", ] [[package]] name = "fastrand" -version = "2.1.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] -name = "fdeflate" -version = "0.3.4" +name = "fax" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645" +checksum = "f05de7d48f37cd6730705cbca900770cab77a89f413d23e100ad7fad7795a0ab" dependencies = [ - "simd-adler32", + "fax_derive", ] [[package]] -name = "flate2" -version = "1.0.30" +name = "fax_derive" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" +checksum = "a0aca10fb742cb43f9e7bb8467c91aa9bcb8e3ffbc6a6f7389bb93ffc920577d" dependencies = [ - "crc32fast", - "miniz_oxide", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "flume" -version = "0.11.0" +name = "fdeflate" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f449e6c6c08c865631d4890cfacf252b3d396c9bcc83adb6623cdb02a8336c41" + +[[package]] +name = "flate2" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +checksum = "b375d6465b98090a5f25b1c7703f3859783755aa9a80433b36e0379a3ec2f369" dependencies = [ - "spin", + "crc32fast", + "miniz_oxide", ] [[package]] @@ -1156,34 +1124,33 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + [[package]] name = "fontconfig-parser" -version = "0.5.6" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a595cb550439a117696039dfc69830492058211b771a2a165379f2a1a53d84d" +checksum = "bbc773e24e02d4ddd8395fd30dc147524273a83e54e0f312d986ea30de5f5646" dependencies = [ "roxmltree", ] [[package]] name = "fontdb" -version = "0.11.2" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "652aa0009b1406e40114685c96ea2c01069e1c035ad6c340999fa08213fad4c5" +checksum = "457e789b3d1202543297a350643cf459f836cade38934e7a4cf6a39e7cde2905" dependencies = [ "fontconfig-parser", "log", - "memmap2 0.5.10", - "ttf-parser 0.18.1", -] - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared 0.1.1", + "memmap2", + "slotmap", + "tinyvec", + "ttf-parser", ] [[package]] @@ -1193,7 +1160,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" dependencies = [ "foreign-types-macros", - "foreign-types-shared 0.3.1", + "foreign-types-shared", ] [[package]] @@ -1204,15 +1171,9 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn", ] -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "foreign-types-shared" version = "0.3.1" @@ -1221,85 +1182,102 @@ checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" [[package]] name = "form_urlencoded" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" dependencies = [ "percent-encoding", ] [[package]] -name = "freetype-rs" -version = "0.26.0" +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-io" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74eadec9d0a5c28c54bb9882e54787275152a4e36ce206b45d7451384e5bf5fb" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-lite" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" dependencies = [ - "bitflags 1.3.2", - "freetype-sys", - "libc", + "fastrand", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", ] [[package]] -name = "freetype-sys" -version = "0.13.1" +name = "futures-macro" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a37d4011c0cc628dfa766fcc195454f4b068d7afdc2adfd28861191d866e731a" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ - "cmake", - "libc", - "pkg-config", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "gethostname" -version = "0.2.3" +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ebd34e35c46e00bb73e81363248d627782724609fe1b6396f553f68fe3862e" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ - "libc", - "winapi", + "futures-core", + "futures-macro", + "futures-task", + "pin-project-lite", + "pin-utils", + "slab", ] [[package]] name = "gethostname" -version = "0.4.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818" +checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8" dependencies = [ - "libc", - "windows-targets 0.48.5", + "rustix 1.1.3", + "windows-link", ] [[package]] name = "getrandom" -version = "0.1.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", "libc", - "wasi 0.9.0+wasi-snapshot-preview1", + "wasi", ] [[package]] name = "getrandom" -version = "0.2.15" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", + "js-sys", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", -] - -[[package]] -name = "gif" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2" -dependencies = [ - "color_quant", - "weezl", + "r-efi", + "wasip2", + "wasm-bindgen", ] [[package]] @@ -1314,125 +1292,309 @@ dependencies = [ ] [[package]] -name = "glob" -version = "0.3.1" +name = "glam" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +checksum = "333928d5eb103c5d4050533cec0384302db6be8ef7d3cebd30ec6a35350353da" [[package]] -name = "glow" -version = "0.11.2" +name = "glam" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8bd5877156a19b8ac83a29b2306fe20537429d318f3ff0a1a2119f8d9c61919" -dependencies = [ - "js-sys", - "slotmap", - "wasm-bindgen", - "web-sys", -] +checksum = "3abb554f8ee44336b72d522e0a7fe86a29e09f839a36022fa869a7dfe941a54b" [[package]] -name = "glutin" -version = "0.30.10" +name = "glam" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc93b03242719b8ad39fb26ed2b01737144ce7bd4bfc7adadcef806596760fe" -dependencies = [ - "bitflags 1.3.2", - "cfg_aliases", - "cgl", - "core-foundation", - "dispatch", - "glutin_egl_sys", - "glutin_glx_sys", - "glutin_wgl_sys", - "libloading 0.7.4", - "objc2 0.3.0-beta.3", - "once_cell", - "raw-window-handle 0.5.2", - "wayland-sys 0.30.1", - "windows-sys 0.45.0", - "x11-dl", -] +checksum = "4126c0479ccf7e8664c36a2d719f5f2c140fbb4f9090008098d2c291fa5b3f16" [[package]] -name = "glutin_egl_sys" -version = "0.5.1" +name = "glam" +version = "0.17.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af784eb26c5a68ec85391268e074f0aa618c096eadb5d6330b0911cf34fe57c5" -dependencies = [ - "gl_generator", - "windows-sys 0.45.0", -] +checksum = "e01732b97afd8508eee3333a541b9f7610f454bb818669e66e90f5f57c93a776" [[package]] -name = "glutin_glx_sys" -version = "0.4.0" +name = "glam" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b53cb5fe568964aa066a3ba91eac5ecbac869fb0842cd0dc9e412434f1a1494" -dependencies = [ - "gl_generator", - "x11-dl", -] +checksum = "525a3e490ba77b8e326fb67d4b44b4bd2f920f44d4cc73ccec50adc68e3bee34" [[package]] -name = "glutin_wgl_sys" -version = "0.4.0" +name = "glam" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef89398e90033fc6bc65e9bd42fd29bbbfd483bda5b56dc5562f455550618165" -dependencies = [ - "gl_generator", -] +checksum = "2b8509e6791516e81c1a630d0bd7fbac36d2fa8712a9da8662e716b52d5051ca" [[package]] -name = "half" -version = "2.4.1" +name = "glam" +version = "0.20.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" -dependencies = [ - "cfg-if", - "crunchy", -] +checksum = "f43e957e744be03f5801a55472f593d43fabdebf25a4585db250f04d86b1675f" [[package]] -name = "hashbrown" -version = "0.12.3" +name = "glam" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +checksum = "518faa5064866338b013ff9b2350dc318e14cc4fcd6cb8206d7e7c9886c98815" [[package]] -name = "hashbrown" -version = "0.13.2" +name = "glam" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +checksum = "12f597d56c1bd55a811a1be189459e8fad2bbc272616375602443bdfb37fa774" [[package]] -name = "hashbrown" -version = "0.14.5" +name = "glam" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +checksum = "8e4afd9ad95555081e109fe1d21f2a30c691b5f0919c67dfa690a2e1eb6bd51c" + +[[package]] +name = "glam" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5418c17512bdf42730f9032c74e1ae39afc408745ebb2acf72fbc4691c17945" + +[[package]] +name = "glam" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151665d9be52f9bb40fc7966565d39666f2d1e69233571b71b87791c7e0528b3" + +[[package]] +name = "glam" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e05e7e6723e3455f4818c7b26e855439f7546cf617ef669d1adedb8669e5cb9" + +[[package]] +name = "glam" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "779ae4bf7e8421cf91c0b3b64e7e8b40b862fba4d393f59150042de7c4965a94" + +[[package]] +name = "glam" +version = "0.29.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8babf46d4c1c9d92deac9f7be466f76dfc4482b6452fc5024b5e8daf6ffeb3ee" + +[[package]] +name = "glam" +version = "0.30.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19fc433e8437a212d1b6f1e68c7824af3aed907da60afa994e7f542d18d12aa9" + +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + +[[package]] +name = "glow" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5e5ea60d70410161c8bf5da3fdfeaa1c72ed2c15f8bbb9d19fe3a4fad085f08" +dependencies = [ + "js-sys", + "slotmap", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "glutin" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12124de845cacfebedff80e877bb37b5b75c34c5a4c89e47e1cdd67fb6041325" +dependencies = [ + "bitflags 2.10.0", + "cfg_aliases", + "cgl", + "dispatch2", + "glutin_egl_sys", + "glutin_glx_sys", + "glutin_wgl_sys", + "libloading", + "objc2 0.6.3", + "objc2-app-kit 0.3.2", + "objc2-core-foundation", + "objc2-foundation 0.3.2", + "once_cell", + "raw-window-handle", + "wayland-sys", + "windows-sys 0.52.0", + "x11-dl", +] + +[[package]] +name = "glutin-winit" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85edca7075f8fc728f28cb8fbb111a96c3b89e930574369e3e9c27eb75d3788f" +dependencies = [ + "cfg_aliases", + "glutin", + "raw-window-handle", + "winit", +] + +[[package]] +name = "glutin_egl_sys" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c4680ba6195f424febdc3ba46e7a42a0e58743f2edb115297b86d7f8ecc02d2" +dependencies = [ + "gl_generator", + "windows-sys 0.52.0", +] + +[[package]] +name = "glutin_glx_sys" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7bb2938045a88b612499fbcba375a77198e01306f52272e692f8c1f3751185" +dependencies = [ + "gl_generator", + "x11-dl", +] + +[[package]] +name = "glutin_wgl_sys" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c4ee00b289aba7a9e5306d57c2d05499b2e5dc427f84ac708bd2c090212cf3e" +dependencies = [ + "gl_generator", +] + +[[package]] +name = "half" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" +dependencies = [ + "cfg-if", + "crunchy", + "num-traits", + "zerocopy", +] + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "foldhash", +] [[package]] name = "heck" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.1.19" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hexf-parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" + +[[package]] +name = "icu_collections" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" dependencies = [ - "libc", + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", ] [[package]] -name = "home" -version = "0.5.9" +name = "icu_locale_core" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" dependencies = [ - "windows-sys 0.52.0", + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" + +[[package]] +name = "icu_properties" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +dependencies = [ + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" + +[[package]] +name = "icu_provider" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", ] [[package]] @@ -1443,114 +1605,89 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.5.0" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "icu_normalizer", + "icu_properties", ] [[package]] name = "image" -version = "0.24.9" +version = "0.25.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d" +checksum = "e6506c6c10786659413faa717ceebcb8f70731c0a60cbae39795fdf114519c1a" dependencies = [ "bytemuck", - "byteorder", - "color_quant", - "exr", - "gif", - "jpeg-decoder", + "byteorder-lite", + "moxcms", "num-traits", "png", - "qoi", "tiff", ] [[package]] name = "imageproc" -version = "0.23.0" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aee993351d466301a29655d628bfc6f5a35a0d062b6160ca0808f425805fd7" +checksum = "645329c490783f3ea465d2b6c7c08286fece97f15e714fd533b6c70a3ead2252" dependencies = [ + "ab_glyph", "approx", - "conv", + "getrandom 0.3.4", "image", - "itertools 0.10.5", + "itertools 0.14.0", "nalgebra", "num", "rand", "rand_distr", - "rayon", - "rusttype", -] - -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", ] [[package]] name = "indexmap" -version = "2.2.6" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" dependencies = [ "equivalent", - "hashbrown 0.14.5", -] - -[[package]] -name = "instant" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", + "hashbrown", ] [[package]] name = "itertools" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" dependencies = [ "either", ] [[package]] name = "itertools" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" dependencies = [ "either", ] [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" [[package]] name = "jni" @@ -1563,7 +1700,7 @@ dependencies = [ "combine", "jni-sys", "log", - "thiserror", + "thiserror 1.0.69", "walkdir", "windows-sys 0.45.0", ] @@ -1575,20 +1712,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] -name = "jpeg-decoder" -version = "0.3.1" +name = "jobserver" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ - "rayon", + "getrandom 0.3.4", + "libc", ] [[package]] name = "js-sys" -version = "0.3.69" +version = "0.3.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -1603,11 +1742,11 @@ name = "kime" version = "0.1.0" dependencies = [ "ctrlc", - "daemonize", - "kime-engine-cffi", + "kime-engine-core", "kime-run-dir", "kime-version", "log", + "nix", "pico-args", ] @@ -1617,16 +1756,15 @@ version = "0.1.0" dependencies = [ "eframe", "egui", - "kime-engine-cffi", + "kime-engine-core", ] [[package]] name = "kime-check" version = "0.1.0" dependencies = [ - "ansi_term", - "kime-engine-cffi", "kime-engine-core", + "owo-colors", "pad", "serde_yaml", "strum", @@ -1637,7 +1775,7 @@ dependencies = [ name = "kime-engine-backend" version = "0.1.0" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.10.0", "enum-map", "enumset", "serde", @@ -1680,6 +1818,7 @@ name = "kime-engine-backend-latin" version = "0.1.0" dependencies = [ "kime-engine-backend", + "log", "serde", "serde_yaml", ] @@ -1698,24 +1837,16 @@ name = "kime-engine-candidate" version = "0.1.0" dependencies = [ "kime-engine-dict", - "nix 0.26.4", + "nix", ] [[package]] name = "kime-engine-capi" version = "0.5.0" -dependencies = [ - "kime-engine-core", -] - -[[package]] -name = "kime-engine-cffi" -version = "0.8.1" dependencies = [ "bindgen", "cbindgen", - "kime-engine-capi", - "kime-engine-config", + "kime-engine-core", ] [[package]] @@ -1756,11 +1887,11 @@ dependencies = [ name = "kime-engine-dict" version = "0.1.0" dependencies = [ - "itertools 0.13.0", - "quick-xml", + "itertools 0.14.0", + "quick-xml 0.39.0", "serde", "serde_json", - "unic", + "unicode-properties", ] [[package]] @@ -1768,12 +1899,13 @@ name = "kime-indicator" version = "0.1.0" dependencies = [ "anyhow", - "kime-engine-cffi", + "kime-engine-core", "kime-run-dir", "kime-version", "ksni", "log", "pico-args", + "tokio", ] [[package]] @@ -1791,7 +1923,7 @@ version = "0.1.0" name = "kime-version" version = "0.1.0" dependencies = [ - "kime-engine-cffi", + "kime-engine-core", "kime-log", ] @@ -1799,141 +1931,121 @@ dependencies = [ name = "kime-wayland" version = "0.1.0" dependencies = [ - "kime-engine-cffi", + "kime-engine-core", "kime-version", "libc", "log", - "mio 0.7.14", - "mio-timerfd", + "mio", "pico-args", + "timerfd-mio", "wayland-client", "wayland-protocols", + "wayland-protocols-misc", "xkbcommon", - "zwp-virtual-keyboard", ] [[package]] name = "kime-xim" version = "0.3.0" dependencies = [ + "ab_glyph", "ahash", "image", "imageproc", - "kime-engine-cffi", + "kime-engine-core", "kime-version", "log", "pico-args", - "rusttype", - "x11rb 0.11.1", + "x11rb", "xim", ] [[package]] name = "ksni" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4934310bdd016e55725482b8d35ac0c16fd058c1b955d8959aa2d953b918c85b" -dependencies = [ - "dbus", - "dbus-codegen", - "dbus-tree", - "thiserror", -] - -[[package]] -name = "kurbo" -version = "0.8.3" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a53776d271cfb873b17c618af0298445c88afc52837f3e948fa3fafd131f449" +checksum = "b5b29c089f14ce24c5b25d9bdcb265413b5e0c3df0871823e0d96bd83bc52a24" dependencies = [ - "arrayvec 0.7.4", + "futures-util", + "pastey", + "serde", + "tokio", + "zbus", ] [[package]] -name = "lazy_static" -version = "1.5.0" +name = "libc" +version = "0.2.180" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" [[package]] -name = "lazycell" -version = "1.3.0" +name = "libloading" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" +dependencies = [ + "cfg-if", + "windows-link", +] [[package]] -name = "lebe" -version = "0.5.2" +name = "libm" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] -name = "libc" -version = "0.2.155" +name = "libredox" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" +dependencies = [ + "bitflags 2.10.0", + "libc", + "redox_syscall 0.7.0", +] [[package]] -name = "libdbus-sys" -version = "0.2.5" +name = "linux-raw-sys" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06085512b750d640299b79be4bad3d2fa90a9c00b1fd9e1b46364f66f0485c72" -dependencies = [ - "pkg-config", -] +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] -name = "libloading" -version = "0.7.4" +name = "linux-raw-sys" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" -dependencies = [ - "cfg-if", - "winapi", -] +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] -name = "libloading" -version = "0.8.5" +name = "litemap" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" -dependencies = [ - "cfg-if", - "windows-targets 0.52.6", -] +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" [[package]] -name = "linux-raw-sys" -version = "0.4.14" +name = "litrs" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" [[package]] name = "lock_api" -version = "0.4.12" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ - "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" -dependencies = [ - "serde", -] - -[[package]] -name = "malloc_buf" -version = "0.0.6" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" dependencies = [ - "libc", + "serde_core", ] [[package]] @@ -1943,16 +2055,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" [[package]] -name = "matches" -version = "0.1.10" +name = "matrixmultiply" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" - -[[package]] -name = "matrixmultiply" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9380b911e3e96d10c1f415da0876389aaf1b56759054eeb0de7df940c456ba1a" +checksum = "a06de3016e9fae57a36fd14dba131fccf49f74b40b7fbdb472f96e361ec71a08" dependencies = [ "autocfg", "rawpointer", @@ -1960,42 +2066,24 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "memmap2" -version = "0.5.10" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" -dependencies = [ - "libc", -] +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "memmap2" -version = "0.8.0" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a5a03cefb0d953ec0be133036f14e109412fa594edc2f77227249db66cc3ed" +checksum = "744133e4a0e0a658e1374cf3bf8e415c4052a15a111acd372764c55b4177d490" dependencies = [ "libc", ] [[package]] name = "memoffset" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" -dependencies = [ - "autocfg", -] - -[[package]] -name = "memoffset" -version = "0.7.1" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" dependencies = [ "autocfg", ] @@ -2008,65 +2096,84 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.4" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ - "adler", + "adler2", "simd-adler32", ] [[package]] name = "mio" -version = "0.7.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc" -dependencies = [ - "libc", - "log", - "miow", - "ntapi", - "winapi", -] - -[[package]] -name = "mio" -version = "0.8.11" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" dependencies = [ "libc", "log", - "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.48.0", + "wasi", + "windows-sys 0.61.2", ] [[package]] -name = "mio-timerfd" -version = "0.2.0" +name = "moxcms" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61840339b339e86a6f728531091b7626d16da3256037152ac92c66b8801c365c" +checksum = "ac9557c559cd6fc9867e122e20d2cbefc9ca29d80d027a8e39310920ed2f0a97" dependencies = [ - "libc", - "mio 0.7.14", + "num-traits", + "pxfm", ] [[package]] -name = "miow" -version = "0.3.7" +name = "naga" +version = "27.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" +checksum = "066cf25f0e8b11ee0df221219010f213ad429855f57c494f995590c861a9a7d8" dependencies = [ - "winapi", + "arrayvec", + "bit-set", + "bitflags 2.10.0", + "cfg-if", + "cfg_aliases", + "codespan-reporting", + "half", + "hashbrown", + "hexf-parse", + "indexmap", + "libm", + "log", + "num-traits", + "once_cell", + "rustc-hash 1.1.0", + "thiserror 2.0.17", + "unicode-ident", ] [[package]] name = "nalgebra" -version = "0.30.1" +version = "0.34.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb2d0de08694bed883320212c18ee3008576bfe8c306f4c3c4a58b4876998be" +checksum = "c4d5b3eff5cd580f93da45e64715e8c20a3996342f1e466599cf7a267a0c2f5f" dependencies = [ "approx", + "glam 0.14.0", + "glam 0.15.2", + "glam 0.16.0", + "glam 0.17.3", + "glam 0.18.0", + "glam 0.19.0", + "glam 0.20.5", + "glam 0.21.3", + "glam 0.22.0", + "glam 0.23.0", + "glam 0.24.2", + "glam 0.25.0", + "glam 0.27.0", + "glam 0.28.0", + "glam 0.29.3", + "glam 0.30.10", "matrixmultiply", "num-complex", "num-rational", @@ -2077,16 +2184,17 @@ dependencies = [ [[package]] name = "ndk" -version = "0.7.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "451422b7e4718271c8b5b3aadf5adedba43dc76312454b387e98fae0fc951aa0" +checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.10.0", "jni-sys", + "log", "ndk-sys", "num_enum", - "raw-window-handle 0.5.2", - "thiserror", + "raw-window-handle", + "thiserror 1.0.69", ] [[package]] @@ -2095,89 +2203,22 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" -[[package]] -name = "ndk-glue" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0434fabdd2c15e0aab768ca31d5b7b333717f03cf02037d5a0a3ff3c278ed67f" -dependencies = [ - "libc", - "log", - "ndk", - "ndk-context", - "ndk-macro", - "ndk-sys", - "once_cell", - "parking_lot", -] - -[[package]] -name = "ndk-macro" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0df7ac00c4672f9d5aece54ee3347520b7e20f158656c7db2e6de01902eb7a6c" -dependencies = [ - "darling 0.13.4", - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "ndk-sys" -version = "0.4.1+23.1.7779620" +version = "0.6.0+11769913" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cf2aae958bd232cac5069850591667ad422d263686d75b52a065f9badeee5a3" +checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" dependencies = [ "jni-sys", ] [[package]] name = "nix" -version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" -dependencies = [ - "bitflags 1.3.2", - "cfg-if", - "libc", - "memoffset 0.6.5", -] - -[[package]] -name = "nix" -version = "0.25.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4" -dependencies = [ - "autocfg", - "bitflags 1.3.2", - "cfg-if", - "libc", - "memoffset 0.6.5", -] - -[[package]] -name = "nix" -version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" -dependencies = [ - "bitflags 1.3.2", - "cfg-if", - "libc", - "memoffset 0.7.1", - "pin-utils", -] - -[[package]] -name = "nix" -version = "0.28.0" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" +checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "cfg-if", "cfg_aliases", "libc", @@ -2199,22 +2240,12 @@ dependencies = [ "minimal-lexical", ] -[[package]] -name = "ntapi" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f" -dependencies = [ - "winapi", -] - [[package]] name = "num" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" dependencies = [ - "num-bigint", "num-complex", "num-integer", "num-iter", @@ -2243,19 +2274,19 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.1.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" [[package]] name = "num-derive" -version = "0.3.3" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] @@ -2296,27 +2327,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", + "libm", ] [[package]] name = "num_enum" -version = "0.5.11" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c" dependencies = [ "num_enum_derive", + "rustversion", ] [[package]] name = "num_enum_derive" -version = "0.5.11" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] @@ -2328,21 +2361,6 @@ dependencies = [ "libc", ] -[[package]] -name = "objc" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" -dependencies = [ - "malloc_buf", -] - -[[package]] -name = "objc-sys" -version = "0.2.0-beta.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b9834c1e95694a05a828b59f55fa2afec6288359cda67146126b3f90a55d7" - [[package]] name = "objc-sys" version = "0.3.5" @@ -2351,23 +2369,21 @@ checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" [[package]] name = "objc2" -version = "0.3.0-beta.3" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe31e5425d3d0b89a15982c024392815da40689aceb34bad364d58732bcfd649" +checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" dependencies = [ - "block2 0.2.0-alpha.6", - "objc-sys 0.2.0-beta.2", - "objc2-encode 2.0.0-pre.2", + "objc-sys", + "objc2-encode", ] [[package]] name = "objc2" -version = "0.5.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" +checksum = "b7c2599ce0ec54857b29ce62166b0ed9b4f6f1a70ccc9a71165b6154caca8c05" dependencies = [ - "objc-sys 0.3.5", - "objc2-encode 4.0.3", + "objc2-encode", ] [[package]] @@ -2376,26 +2392,87 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "block2 0.5.1", "libc", "objc2 0.5.2", "objc2-core-data", "objc2-core-image", - "objc2-foundation", + "objc2-foundation 0.2.2", "objc2-quartz-core", ] +[[package]] +name = "objc2-app-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" +dependencies = [ + "bitflags 2.10.0", + "objc2 0.6.3", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-foundation 0.3.2", +] + +[[package]] +name = "objc2-cloud-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" +dependencies = [ + "bitflags 2.10.0", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-core-location", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-contacts" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + [[package]] name = "objc2-core-data" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "block2 0.5.1", "objc2 0.5.2", - "objc2-foundation", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-core-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" +dependencies = [ + "bitflags 2.10.0", + "dispatch2", + "objc2 0.6.3", +] + +[[package]] +name = "objc2-core-graphics" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" +dependencies = [ + "bitflags 2.10.0", + "dispatch2", + "objc2 0.6.3", + "objc2-core-foundation", + "objc2-io-surface", ] [[package]] @@ -2406,24 +2483,27 @@ checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" dependencies = [ "block2 0.5.1", "objc2 0.5.2", - "objc2-foundation", + "objc2-foundation 0.2.2", "objc2-metal", ] [[package]] -name = "objc2-encode" -version = "2.0.0-pre.2" +name = "objc2-core-location" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abfcac41015b00a120608fdaa6938c44cb983fee294351cc4bac7638b4e50512" +checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" dependencies = [ - "objc-sys 0.2.0-beta.2", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-contacts", + "objc2-foundation 0.2.2", ] [[package]] name = "objc2-encode" -version = "4.0.3" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7891e71393cd1f227313c9379a26a584ff3d7e6e7159e988851f0934c993f0f8" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" [[package]] name = "objc2-foundation" @@ -2431,22 +2511,57 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "block2 0.5.1", + "dispatch", "libc", "objc2 0.5.2", ] +[[package]] +name = "objc2-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" +dependencies = [ + "bitflags 2.10.0", + "objc2 0.6.3", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-io-surface" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d" +dependencies = [ + "bitflags 2.10.0", + "objc2 0.6.3", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-link-presentation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.2", + "objc2-app-kit 0.2.2", + "objc2-foundation 0.2.2", +] + [[package]] name = "objc2-metal" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "block2 0.5.1", "objc2 0.5.2", - "objc2-foundation", + "objc2-foundation 0.2.2", ] [[package]] @@ -2455,49 +2570,115 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "block2 0.5.1", "objc2 0.5.2", - "objc2-foundation", + "objc2-foundation 0.2.2", "objc2-metal", ] +[[package]] +name = "objc2-symbols" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" +dependencies = [ + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-ui-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" +dependencies = [ + "bitflags 2.10.0", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-cloud-kit", + "objc2-core-data", + "objc2-core-image", + "objc2-core-location", + "objc2-foundation 0.2.2", + "objc2-link-presentation", + "objc2-quartz-core", + "objc2-symbols", + "objc2-uniform-type-identifiers", + "objc2-user-notifications", +] + +[[package]] +name = "objc2-uniform-type-identifiers" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-user-notifications" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" +dependencies = [ + "bitflags 2.10.0", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-core-location", + "objc2-foundation 0.2.2", +] + [[package]] name = "once_cell" -version = "1.19.0" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "oorandom" -version = "11.1.4" +version = "11.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" +checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" [[package]] -name = "os_str_bytes" -version = "6.6.1" +name = "orbclient" +version = "0.3.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" +checksum = "52ad2c6bae700b7aa5d1cc30c59bdd3a1c180b09dbaea51e2ae2b8e1cf211fdd" +dependencies = [ + "libc", + "libredox", +] [[package]] -name = "owned_ttf_parser" -version = "0.15.2" +name = "ordered-stream" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05e6affeb1632d6ff6a23d2cd40ffed138e82f1532571a26f527c8a284bb2fbb" +checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50" dependencies = [ - "ttf-parser 0.15.2", + "futures-core", + "pin-project-lite", ] [[package]] name = "owned_ttf_parser" -version = "0.24.0" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "490d3a563d3122bf7c911a59b0add9389e5ec0f5f0c3ac6b91ff235a0e6a7f90" +checksum = "36820e9051aca1014ddc75770aab4d68bc1e9e632f0f5627c4086bc216fb583b" dependencies = [ - "ttf-parser 0.24.0", + "ttf-parser", ] +[[package]] +name = "owo-colors" +version = "4.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c6901729fa79e91a0913333229e9ca5dc725089d1c363b2f4b4760709dc4a52" + [[package]] name = "pad" version = "0.1.6" @@ -2507,11 +2688,27 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "page_size" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d5b2194ed13191c1999ae0704b7839fb18384fa22e49b57eeaa97d79ce40da" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + [[package]] name = "parking_lot" -version = "0.12.3" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", "parking_lot_core", @@ -2519,15 +2716,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.10" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.5.18", "smallvec", - "windows-targets 0.52.6", + "windows-link", ] [[package]] @@ -2536,11 +2733,17 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +[[package]] +name = "pastey" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b867cad97c0791bbd3aaa6472142568c6c9e8f71937e98379f584cfb0cf35bec" + [[package]] name = "percent-encoding" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pico-args" @@ -2549,10 +2752,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" [[package]] -name = "pin-project-lite" -version = "0.2.14" +name = "pin-project" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] name = "pin-utils" @@ -2562,15 +2785,15 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "plotters" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15b6eccb8484002195a3e44fe65a4ce8e93a625797a063735536fd59cb01cf3" +checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" dependencies = [ "num-traits", "plotters-backend", @@ -2581,32 +2804,70 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "414cec62c6634ae900ea1c56128dfe87cf63e7caece0852ec76aba307cebadb7" +checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" [[package]] name = "plotters-svg" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81b30686a7d9c3e010b84284bdd26a29f2138574f52f5eb6f794fc0ad924e705" +checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" dependencies = [ "plotters-backend", ] [[package]] name = "png" -version = "0.17.13" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1" +checksum = "97baced388464909d42d89643fe4361939af9b7ce7a31ee32a168f832a70f2a0" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.10.0", "crc32fast", "fdeflate", "flate2", "miniz_oxide", ] +[[package]] +name = "polling" +version = "3.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi", + "pin-project-lite", + "rustix 1.1.3", + "windows-sys 0.61.2", +] + +[[package]] +name = "portable-atomic" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f89776e4d69bb58bc6993e99ffa1d11f228b839984854c7daeb5d37f87cbe950" + +[[package]] +name = "portable-atomic-util" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "potential_utf" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +dependencies = [ + "zerovec", +] + [[package]] name = "powerfmt" version = "0.2.0" @@ -2615,18 +2876,18 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.18" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee4364d9f3b902ef14fab8a1ddffb783a1cb6b4bba3bfc1fa3922732c7de97f" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ - "zerocopy 0.6.6", + "zerocopy", ] [[package]] name = "pretty_assertions" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" +checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d" dependencies = [ "diff", "yansi", @@ -2634,23 +2895,28 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "1.3.1" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" dependencies = [ - "once_cell", "toml_edit", ] [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "535d180e0ecab6268a3e718bb9fd44db66bbbc256257165fc699dadf70d16fe7" dependencies = [ "unicode-ident", ] +[[package]] +name = "profiling" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773" + [[package]] name = "properties_writer" version = "0.1.0" @@ -2660,19 +2926,34 @@ dependencies = [ ] [[package]] -name = "qoi" -version = "0.4.1" +name = "pxfm" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" +checksum = "7186d3822593aa4393561d186d1393b3923e9d6163d3fbfd6e825e3e6cf3e6a8" dependencies = [ - "bytemuck", + "num-traits", +] + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + +[[package]] +name = "quick-xml" +version = "0.38.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b66c2058c55a409d601666cffe35f04333cf1013010882cec174a7467cd4e21c" +dependencies = [ + "memchr", ] [[package]] name = "quick-xml" -version = "0.27.1" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffc053f057dd768a56f62cd7e434c42c831d296968997e9ac1f76ea7c2d14c41" +checksum = "f2e3bf4aa9d243beeb01a7b3bc30b77cfe2c44e24ec02d751a7104a53c2c49a1" dependencies = [ "encoding_rs", "memchr", @@ -2680,31 +2961,34 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.36" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a" dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + [[package]] name = "rand" -version = "0.7.3" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ - "getrandom 0.1.16", - "libc", "rand_chacha", "rand_core", - "rand_hc", ] [[package]] name = "rand_chacha" -version = "0.2.2" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", "rand_core", @@ -2712,45 +2996,28 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.5.1" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" dependencies = [ - "getrandom 0.1.16", + "getrandom 0.3.4", ] [[package]] name = "rand_distr" -version = "0.2.2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96977acbdd3a6576fb1d27391900035bf3863d4a16422973a409b488cf29ffb2" +checksum = "6a8615d50dcf34fa31f7ab52692afec947c4dd0ab803cc87cb3b0b4570ff7463" dependencies = [ + "num-traits", "rand", ] -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core", -] - -[[package]] -name = "raw-window-handle" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b800beb9b6e7d2df1fe337c9e3d04e3af22a124460fb4c30fcc22c9117cefb41" -dependencies = [ - "cty", -] - [[package]] name = "raw-window-handle" -version = "0.5.2" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" +checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" [[package]] name = "rawpointer" @@ -2760,9 +3027,9 @@ checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" [[package]] name = "rayon" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" dependencies = [ "either", "rayon-core", @@ -2770,9 +3037,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.1" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -2780,18 +3047,36 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.3" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", +] + +[[package]] +name = "redox_syscall" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f3fe0889e69e2ae9e41f4d6c4c0181701d00e4697b356fb1f74173a5e0ee27" +dependencies = [ + "bitflags 2.10.0", ] [[package]] name = "regex" -version = "1.10.5" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" dependencies = [ "aho-corasick", "memchr", @@ -2801,9 +3086,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" dependencies = [ "aho-corasick", "memchr", @@ -2812,15 +3097,21 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" + +[[package]] +name = "renderdoc-sys" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" [[package]] name = "roxmltree" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cd14fd5e3b777a7422cca79358c57a8f6e3a703d9ac187448d0daf220c2407f" +checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97" [[package]] name = "rustc-hash" @@ -2828,55 +3119,55 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "errno", "libc", - "linux-raw-sys", - "windows-sys 0.52.0", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", ] [[package]] -name = "rusttype" -version = "0.9.3" +name = "rustix" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff8374aa04134254b7995b63ad3dc41c7f7236f69528b28553da7d72efaa967" +checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" dependencies = [ - "ab_glyph_rasterizer", - "owned_ttf_parser 0.15.2", + "bitflags 2.10.0", + "errno", + "libc", + "linux-raw-sys 0.11.0", + "windows-sys 0.61.2", ] [[package]] name = "rustversion" -version = "1.0.17" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "ryu" -version = "1.0.18" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" - -[[package]] -name = "safe_arch" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ff3d6d9696af502cc3110dacce942840fb06ff4514cad92236ecc455f2ce05" -dependencies = [ - "bytemuck", -] +checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984" [[package]] name = "safe_arch" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3460605018fdc9612bce72735cba0d27efbcd9904780d44c7e3a9948f96148a" +checksum = "96b02de82ddbe1b636e6170c21be622223aea188ef2e139be0a5b219ec215323" dependencies = [ "bytemuck", ] @@ -2903,81 +3194,79 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] -name = "sctk-adwaita" -version = "0.4.3" +name = "serde" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61270629cc6b4d77ec1907db1033d5c2e1a404c412743621981a871dc9c12339" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ - "crossfont", - "log", - "smithay-client-toolkit", - "tiny-skia", + "serde_core", + "serde_derive", ] [[package]] -name = "serde" -version = "1.0.204" +name = "serde_core" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.204" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn", ] [[package]] name = "serde_json" -version = "1.0.121" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ab380d7d9f22ef3f21ad3e6c1ebe8e4fc7a2000ccba2e4d71fc96f15b2cb609" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ "itoa", "memchr", - "ryu", "serde", + "serde_core", + "zmij", ] [[package]] -name = "serde_yaml" -version = "0.9.34+deprecated" +name = "serde_repr" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" +checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ - "indexmap 2.2.6", - "itoa", - "ryu", - "serde", - "unsafe-libyaml", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "servo-fontconfig" -version = "0.5.1" +name = "serde_spanned" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7e3e22fe5fd73d04ebf0daa049d3efe3eae55369ce38ab16d07ddd9ac5c217c" +checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776" dependencies = [ - "libc", - "servo-fontconfig-sys", + "serde_core", ] [[package]] -name = "servo-fontconfig-sys" -version = "5.1.0" +name = "serde_yaml" +version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36b879db9892dfa40f95da1c38a835d41634b825fbd8c4c418093d53c24b388" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "expat-sys", - "freetype-sys", - "pkg-config", + "indexmap", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", ] [[package]] @@ -2986,11 +3275,21 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "signal-hook-registry" +version = "1.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +dependencies = [ + "errno", + "libc", +] + [[package]] name = "simba" -version = "0.7.3" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f3fd720c48c53cace224ae62bef1bbff363a70c68c4802a78b5cc6159618176" +checksum = "c99284beb21666094ba2b75bbceda012e610f5479dfcc2d6e2426f53197ffd95" dependencies = [ "approx", "num-complex", @@ -3001,9 +3300,9 @@ dependencies = [ [[package]] name = "simd-adler32" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" [[package]] name = "simplelog" @@ -3016,98 +3315,147 @@ dependencies = [ "time", ] +[[package]] +name = "slab" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" + [[package]] name = "slotmap" -version = "1.0.7" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" +checksum = "bdd58c3c93c3d278ca835519292445cb4b0d4dc59ccfdf7ceadaab3f8aeb4038" dependencies = [ "version_check", ] [[package]] name = "smallvec" -version = "1.13.2" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "smithay-client-toolkit" -version = "0.16.1" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "870427e30b8f2cbe64bf43ec4b86e88fe39b0a84b3f15efd9c9c2d020bc86eb9" +checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" dependencies = [ - "bitflags 1.3.2", - "calloop", - "dlib", - "lazy_static", + "bitflags 2.10.0", + "calloop 0.13.0", + "calloop-wayland-source 0.3.0", + "cursor-icon", + "libc", "log", - "memmap2 0.5.10", - "nix 0.24.3", - "pkg-config", + "memmap2", + "rustix 0.38.44", + "thiserror 1.0.69", + "wayland-backend", "wayland-client", + "wayland-csd-frame", "wayland-cursor", "wayland-protocols", + "wayland-protocols-wlr", + "wayland-scanner", + "xkeysym", ] [[package]] -name = "smithay-clipboard" -version = "0.6.6" +name = "smithay-client-toolkit" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a345c870a1fae0b1b779085e81b51e614767c239e93503588e54c5b17f4b0e8" +checksum = "0512da38f5e2b31201a93524adb8d3136276fa4fe4aafab4e1f727a82b534cc0" dependencies = [ - "smithay-client-toolkit", + "bitflags 2.10.0", + "calloop 0.14.3", + "calloop-wayland-source 0.4.1", + "cursor-icon", + "libc", + "log", + "memmap2", + "rustix 1.1.3", + "thiserror 2.0.17", + "wayland-backend", "wayland-client", + "wayland-csd-frame", + "wayland-cursor", + "wayland-protocols", + "wayland-protocols-experimental", + "wayland-protocols-misc", + "wayland-protocols-wlr", + "wayland-scanner", + "xkeysym", ] [[package]] -name = "spin" -version = "0.9.8" +name = "smithay-clipboard" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +checksum = "71704c03f739f7745053bde45fa203a46c58d25bc5c4efba1d9a60e9dba81226" dependencies = [ - "lock_api", + "libc", + "smithay-client-toolkit 0.20.0", + "wayland-backend", ] [[package]] -name = "strsim" -version = "0.8.0" +name = "smol_str" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" +dependencies = [ + "serde", +] + +[[package]] +name = "socket2" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +dependencies = [ + "libc", + "windows-sys 0.60.2", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] -name = "strsim" -version = "0.10.0" +name = "static_assertions" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "strum" -version = "0.24.1" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" +checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" dependencies = [ "strum_macros", ] [[package]] name = "strum_macros" -version = "0.24.3" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" dependencies = [ "heck", "proc-macro2", "quote", - "rustversion", - "syn 1.0.109", + "syn", ] [[package]] name = "syn" -version = "1.0.109" +version = "2.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" dependencies = [ "proc-macro2", "quote", @@ -3115,26 +3463,27 @@ dependencies = [ ] [[package]] -name = "syn" -version = "2.0.72" +name = "synstructure" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "unicode-ident", + "syn", ] [[package]] name = "tempfile" -version = "3.10.1" +version = "3.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" dependencies = [ - "cfg-if", "fastrand", - "rustix", - "windows-sys 0.52.0", + "getrandom 0.3.4", + "once_cell", + "rustix 1.1.3", + "windows-sys 0.61.2", ] [[package]] @@ -3147,116 +3496,118 @@ dependencies = [ ] [[package]] -name = "textwrap" -version = "0.11.0" +name = "thiserror" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "unicode-width", + "thiserror-impl 1.0.69", ] [[package]] -name = "textwrap" -version = "0.16.1" +name = "thiserror" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" +dependencies = [ + "thiserror-impl 2.0.17", +] [[package]] -name = "thiserror" -version = "1.0.63" +name = "thiserror-impl" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ - "thiserror-impl", + "proc-macro2", + "quote", + "syn", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn", ] [[package]] name = "tiff" -version = "0.9.1" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" +checksum = "af9605de7fee8d9551863fd692cce7637f548dbd9db9180fcc07ccc6d26c336f" dependencies = [ + "fax", "flate2", - "jpeg-decoder", + "half", + "quick-error", "weezl", + "zune-jpeg", ] [[package]] name = "time" -version = "0.3.36" +version = "0.3.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +checksum = "85c17d80feb7334b40c484e45ed1a5273dfd8bfda537c3be2e74a06a6686f327" dependencies = [ "deranged", - "itoa", "libc", "num-conv", "num_threads", "powerfmt", - "serde", + "serde_core", "time-core", "time-macros", ] [[package]] name = "time-core" -version = "0.1.2" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" [[package]] name = "time-macros" -version = "0.2.18" +version = "0.2.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +checksum = "dcef1a61bdb119096e153208ec5cbec23944ce8bca13be5c7f60c634f7403935" dependencies = [ "num-conv", "time-core", ] [[package]] -name = "tiny-keccak" -version = "2.0.2" +name = "timerfd-mio" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +checksum = "e57340aeab6d741ff3f7be79ac04838af05918788b8c31af58e8996b67de1399" dependencies = [ - "crunchy", + "mio", + "rustix 1.1.3", ] [[package]] -name = "tiny-skia" -version = "0.7.0" +name = "tiny-keccak" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "642680569bb895b16e4b9d181c60be1ed136fa0c9c7f11d004daf053ba89bf82" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" dependencies = [ - "arrayref", - "arrayvec 0.5.2", - "bytemuck", - "cfg-if", - "png", - "safe_arch 0.5.2", - "tiny-skia-path", + "crunchy", ] [[package]] -name = "tiny-skia-path" -version = "0.7.0" +name = "tinystr" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c114d32f0c2ee43d585367cb013dfaba967ab9f62b90d9af0d696e955e70fa6c" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" dependencies = [ - "arrayref", - "bytemuck", + "displaydoc", + "zerovec", ] [[package]] @@ -3271,9 +3622,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" dependencies = [ "tinyvec_macros", ] @@ -3285,640 +3636,582 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] -name = "toml" -version = "0.5.11" +name = "tokio" +version = "1.49.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" dependencies = [ - "serde", + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "tracing", + "windows-sys 0.61.2", ] [[package]] -name = "toml_datetime" -version = "0.6.7" +name = "tokio-macros" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8fb9f64314842840f1d940ac544da178732128f1c78c21772e876579e0da1db" - +checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] -name = "toml_edit" -version = "0.19.15" +name = "toml" +version = "0.9.11+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +checksum = "f3afc9a848309fe1aaffaed6e1546a7a14de1f935dc9d89d32afd9a44bab7c46" dependencies = [ - "indexmap 2.2.6", + "indexmap", + "serde_core", + "serde_spanned", "toml_datetime", + "toml_parser", + "toml_writer", "winnow", ] [[package]] -name = "tracing" -version = "0.1.40" +name = "toml_datetime" +version = "0.7.5+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" dependencies = [ - "pin-project-lite", - "tracing-core", + "serde_core", ] [[package]] -name = "tracing-core" -version = "0.1.32" +name = "toml_edit" +version = "0.23.10+spec-1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" dependencies = [ - "once_cell", + "indexmap", + "toml_datetime", + "toml_parser", + "winnow", ] [[package]] -name = "ttf-parser" -version = "0.15.2" +name = "toml_parser" +version = "1.0.6+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b3e06c9b9d80ed6b745c7159c40b311ad2916abb34a49e9be2653b90db0d8dd" +checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" +dependencies = [ + "winnow", +] [[package]] -name = "ttf-parser" -version = "0.18.1" +name = "toml_writer" +version = "1.0.6+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0609f771ad9c6155384897e1df4d948e692667cc0588548b68eb44d052b27633" +checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607" [[package]] -name = "ttf-parser" -version = "0.24.0" +name = "tracing" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8686b91785aff82828ed725225925b33b4fde44c4bb15876e5f7c832724c420a" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] [[package]] -name = "typenum" -version = "1.17.0" +name = "tracing-attributes" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "unic" -version = "0.9.0" +name = "tracing-core" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e31748f3e294dc6a9243a44686e8155a162af9a11cd56e07c0ebbc530b2a8a87" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ - "unic-bidi", - "unic-char", - "unic-common", - "unic-emoji", - "unic-idna", - "unic-normal", - "unic-segment", - "unic-ucd", + "once_cell", ] [[package]] -name = "unic-bidi" -version = "0.9.0" +name = "ttf-parser" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1356b759fb6a82050666f11dce4b6fe3571781f1449f3ef78074e408d468ec09" +checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31" dependencies = [ - "matches", - "unic-ucd-bidi", + "core_maths", ] [[package]] -name = "unic-char" -version = "0.9.0" +name = "type-map" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af25df79bd134107f088ba725d9c470600f16263205d0be36c75e75b020bac0a" +checksum = "cb30dbbd9036155e74adad6812e9898d03ec374946234fbcebd5dfc7b9187b90" dependencies = [ - "unic-char-basics", - "unic-char-property", - "unic-char-range", + "rustc-hash 2.1.1", ] [[package]] -name = "unic-char-basics" -version = "0.9.0" +name = "typenum" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20e5d239bc6394309225a0c1b13e1d059565ff2cfef1a437aff4a5871fa06c4b" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] -name = "unic-char-property" -version = "0.9.0" +name = "uds_windows" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221" +checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" dependencies = [ - "unic-char-range", + "memoffset", + "tempfile", + "winapi", ] [[package]] -name = "unic-char-range" -version = "0.9.0" +name = "unicode-ident" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] -name = "unic-common" -version = "0.9.0" +name = "unicode-properties" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc" +checksum = "7df058c713841ad818f1dc5d3fd88063241cc61f49f5fbea4b951e8cf5a8d71d" [[package]] -name = "unic-emoji" -version = "0.9.0" +name = "unicode-segmentation" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74193f32f7966ad20b819e70e29c6f1ac8c386692a9d5e90078eef80ea008bfb" -dependencies = [ - "unic-emoji-char", -] +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] -name = "unic-emoji-char" -version = "0.9.0" +name = "unicode-width" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b07221e68897210270a38bde4babb655869637af0f69407f96053a34f76494d" -dependencies = [ - "unic-char-property", - "unic-char-range", - "unic-ucd-version", -] +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] -name = "unic-idna" -version = "0.9.0" +name = "unsafe-libyaml" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "621e9cf526f2094d2c2ced579766458a92f8f422d6bb934c503ba1a95823a62d" -dependencies = [ - "matches", - "unic-idna-mapping", - "unic-idna-punycode", - "unic-normal", - "unic-ucd-bidi", - "unic-ucd-normal", - "unic-ucd-version", -] +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" [[package]] -name = "unic-idna-mapping" -version = "0.9.0" +name = "url" +version = "2.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4de70fd4e5331537347a50a0dbc938efb1f127c9f6e5efec980fc90585aa1343" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" dependencies = [ - "unic-char-property", - "unic-char-range", - "unic-ucd-version", + "form_urlencoded", + "idna", + "percent-encoding", + "serde", ] [[package]] -name = "unic-idna-punycode" -version = "0.9.0" +name = "utf8_iter" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06feaedcbf9f1fc259144d833c0d630b8b15207b0486ab817d29258bc89f2f8a" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] -name = "unic-normal" -version = "0.9.0" +name = "uuid" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f09d64d33589a94628bc2aeb037f35c2e25f3f049c7348b5aa5580b48e6bba62" +checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" dependencies = [ - "unic-ucd-normal", + "js-sys", + "serde_core", + "wasm-bindgen", ] [[package]] -name = "unic-segment" -version = "0.9.0" +name = "version_check" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4ed5d26be57f84f176157270c112ef57b86debac9cd21daaabbe56db0f88f23" -dependencies = [ - "unic-ucd-segment", -] +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] -name = "unic-ucd" -version = "0.9.0" +name = "walkdir" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "625b18f7601e1127504a20ae731dc3c7826d0e86d5f7fe3434f8137669240efd" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ - "unic-ucd-age", - "unic-ucd-bidi", - "unic-ucd-block", - "unic-ucd-case", - "unic-ucd-category", - "unic-ucd-common", - "unic-ucd-hangul", - "unic-ucd-ident", - "unic-ucd-name", - "unic-ucd-name_aliases", - "unic-ucd-normal", - "unic-ucd-segment", - "unic-ucd-version", + "same-file", + "winapi-util", ] [[package]] -name = "unic-ucd-age" -version = "0.9.0" +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8cfdfe71af46b871dc6af2c24fcd360e2f3392ee4c5111877f2947f311671c" -dependencies = [ - "unic-char-property", - "unic-char-range", - "unic-ucd-version", -] +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] -name = "unic-ucd-bidi" -version = "0.9.0" +name = "wasip2" +version = "1.0.1+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1d568b51222484e1f8209ce48caa6b430bf352962b877d592c29ab31fb53d8c" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" dependencies = [ - "unic-char-property", - "unic-char-range", - "unic-ucd-version", + "wit-bindgen", ] [[package]] -name = "unic-ucd-block" -version = "0.9.0" +name = "wasm-bindgen" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b2a16f2d7ecd25325a1053ca5a66e7fa1b68911a65c5e97f8d2e1b236b6f1d7" +checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" dependencies = [ - "unic-char-property", - "unic-char-range", - "unic-ucd-version", + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", ] [[package]] -name = "unic-ucd-case" -version = "0.9.0" +name = "wasm-bindgen-futures" +version = "0.4.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d98d6246a79bac6cf66beee01422bda7c882e11d837fa4969bfaaba5fdea6d3" +checksum = "70a6e77fd0ae8029c9ea0063f87c46fde723e7d887703d74ad2616d792e51e6f" dependencies = [ - "unic-char-property", - "unic-char-range", - "unic-ucd-version", + "cfg-if", + "futures-util", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", ] [[package]] -name = "unic-ucd-category" -version = "0.9.0" +name = "wasm-bindgen-macro" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8d4591f5fcfe1bd4453baaf803c40e1b1e69ff8455c47620440b46efef91c0" +checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608" dependencies = [ - "matches", - "unic-char-property", - "unic-char-range", - "unic-ucd-version", + "quote", + "wasm-bindgen-macro-support", ] [[package]] -name = "unic-ucd-common" -version = "0.9.0" +name = "wasm-bindgen-macro-support" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9b78b910beafa1aae5c59bf00877c6cece1c5db28a1241ad801e86cecdff4ad" +checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55" dependencies = [ - "unic-char-property", - "unic-char-range", - "unic-ucd-version", + "bumpalo", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", ] [[package]] -name = "unic-ucd-hangul" -version = "0.9.0" +name = "wasm-bindgen-shared" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1dc690e19010e1523edb9713224cba5ef55b54894fe33424439ec9a40c0054" +checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12" dependencies = [ - "unic-ucd-version", + "unicode-ident", ] [[package]] -name = "unic-ucd-ident" -version = "0.9.0" +name = "wayland-backend" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e230a37c0381caa9219d67cf063aa3a375ffed5bf541a452db16e744bdab6987" +checksum = "fee64194ccd96bf648f42a65a7e589547096dfa702f7cadef84347b66ad164f9" dependencies = [ - "unic-char-property", - "unic-char-range", - "unic-ucd-version", + "cc", + "downcast-rs", + "rustix 1.1.3", + "scoped-tls", + "smallvec", + "wayland-sys", ] [[package]] -name = "unic-ucd-name" -version = "0.9.0" +name = "wayland-client" +version = "0.31.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8fc55a45b2531089dc1773bf60c1f104b38e434b774ffc37b9c29a9b0f492e" +checksum = "b8e6faa537fbb6c186cb9f1d41f2f811a4120d1b57ec61f50da451a0c5122bec" dependencies = [ - "unic-char-property", - "unic-ucd-hangul", - "unic-ucd-version", + "bitflags 2.10.0", + "rustix 1.1.3", + "wayland-backend", + "wayland-scanner", ] [[package]] -name = "unic-ucd-name_aliases" -version = "0.9.0" +name = "wayland-csd-frame" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b7674212643087699ba247a63dd05f1204c7e4880ec9342e545a7cffcc6a46f" +checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" dependencies = [ - "unic-char-property", - "unic-ucd-version", + "bitflags 2.10.0", + "cursor-icon", + "wayland-backend", ] [[package]] -name = "unic-ucd-normal" -version = "0.9.0" +name = "wayland-cursor" +version = "0.31.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86aed873b8202d22b13859dda5fe7c001d271412c31d411fd9b827e030569410" +checksum = "5864c4b5b6064b06b1e8b74ead4a98a6c45a285fe7a0e784d24735f011fdb078" dependencies = [ - "unic-char-property", - "unic-char-range", - "unic-ucd-category", - "unic-ucd-hangul", - "unic-ucd-version", + "rustix 1.1.3", + "wayland-client", + "xcursor", ] [[package]] -name = "unic-ucd-segment" -version = "0.9.0" +name = "wayland-protocols" +version = "0.32.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2079c122a62205b421f499da10f3ee0f7697f012f55b675e002483c73ea34700" +checksum = "baeda9ffbcfc8cd6ddaade385eaf2393bd2115a69523c735f12242353c3df4f3" dependencies = [ - "unic-char-property", - "unic-char-range", - "unic-ucd-version", + "bitflags 2.10.0", + "wayland-backend", + "wayland-client", + "wayland-scanner", ] [[package]] -name = "unic-ucd-version" -version = "0.9.0" +name = "wayland-protocols-experimental" +version = "20250721.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4" +checksum = "40a1f863128dcaaec790d7b4b396cc9b9a7a079e878e18c47e6c2d2c5a8dcbb1" dependencies = [ - "unic-common", + "bitflags 2.10.0", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", ] [[package]] -name = "unicode-bidi" -version = "0.3.15" +name = "wayland-protocols-misc" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "unicode-normalization" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +checksum = "791c58fdeec5406aa37169dd815327d1e47f334219b523444bc26d70ceb4c34e" dependencies = [ - "tinyvec", + "bitflags 2.10.0", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", ] [[package]] -name = "unicode-width" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" - -[[package]] -name = "unsafe-libyaml" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" - -[[package]] -name = "url" -version = "2.5.2" +name = "wayland-protocols-plasma" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +checksum = "aa98634619300a535a9a97f338aed9a5ff1e01a461943e8346ff4ae26007306b" dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", + "bitflags 2.10.0", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", ] [[package]] -name = "vec_map" -version = "0.8.2" +name = "wayland-protocols-wlr" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +checksum = "e9597cdf02cf0c34cd5823786dce6b5ae8598f05c2daf5621b6e178d4f7345f3" dependencies = [ - "same-file", - "winapi-util", + "bitflags 2.10.0", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", ] [[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.92" +name = "wayland-scanner" +version = "0.31.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "5423e94b6a63e68e439803a3e153a9252d5ead12fd853334e2ad33997e3889e3" dependencies = [ - "cfg-if", - "wasm-bindgen-macro", + "proc-macro2", + "quick-xml 0.38.4", + "quote", ] [[package]] -name = "wasm-bindgen-backend" -version = "0.2.92" +name = "wayland-sys" +version = "0.31.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +checksum = "1e6dbfc3ac5ef974c92a2235805cc0114033018ae1290a72e474aa8b28cbbdfd" dependencies = [ - "bumpalo", + "dlib", "log", "once_cell", - "proc-macro2", - "quote", - "syn 2.0.72", - "wasm-bindgen-shared", + "pkg-config", ] [[package]] -name = "wasm-bindgen-futures" -version = "0.4.42" +name = "web-sys" +version = "0.3.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +checksum = "312e32e551d92129218ea9a2452120f4aabc03529ef03e4d0d82fb2780608598" dependencies = [ - "cfg-if", "js-sys", "wasm-bindgen", - "web-sys", ] [[package]] -name = "wasm-bindgen-macro" -version = "0.2.92" +name = "web-time" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" dependencies = [ - "quote", - "wasm-bindgen-macro-support", + "js-sys", + "wasm-bindgen", ] [[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.92" +name = "webbrowser" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "00f1243ef785213e3a32fa0396093424a3a6ea566f9948497e5a2309261a4c97" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.72", - "wasm-bindgen-backend", - "wasm-bindgen-shared", + "core-foundation 0.10.1", + "jni", + "log", + "ndk-context", + "objc2 0.6.3", + "objc2-foundation 0.3.2", + "url", + "web-sys", ] [[package]] -name = "wasm-bindgen-shared" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" - -[[package]] -name = "wayland-client" -version = "0.29.5" +name = "weezl" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f3b068c05a039c9f755f881dc50f01732214f5685e379829759088967c46715" -dependencies = [ - "bitflags 1.3.2", - "downcast-rs", - "libc", - "nix 0.24.3", - "scoped-tls", - "wayland-commons", - "wayland-scanner", - "wayland-sys 0.29.5", -] +checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88" [[package]] -name = "wayland-commons" -version = "0.29.5" +name = "wgpu" +version = "27.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8691f134d584a33a6606d9d717b95c4fa20065605f798a3f350d78dced02a902" +checksum = "bfe68bac7cde125de7a731c3400723cadaaf1703795ad3f4805f187459cd7a77" dependencies = [ - "nix 0.24.3", - "once_cell", + "arrayvec", + "bitflags 2.10.0", + "cfg-if", + "cfg_aliases", + "document-features", + "hashbrown", + "log", + "portable-atomic", + "profiling", + "raw-window-handle", "smallvec", - "wayland-sys 0.29.5", + "static_assertions", + "wgpu-core", + "wgpu-hal", + "wgpu-types", ] [[package]] -name = "wayland-cursor" -version = "0.29.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6865c6b66f13d6257bef1cd40cbfe8ef2f150fb8ebbdb1e8e873455931377661" -dependencies = [ - "nix 0.24.3", - "wayland-client", - "xcursor", -] - -[[package]] -name = "wayland-protocols" -version = "0.29.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b950621f9354b322ee817a23474e479b34be96c2e909c14f7bc0100e9a970bc6" -dependencies = [ - "bitflags 1.3.2", - "wayland-client", - "wayland-commons", - "wayland-scanner", -] - -[[package]] -name = "wayland-scanner" -version = "0.29.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f4303d8fa22ab852f789e75a967f0a2cdc430a607751c0499bada3e451cbd53" -dependencies = [ - "proc-macro2", - "quote", - "xml-rs", -] - -[[package]] -name = "wayland-sys" -version = "0.29.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be12ce1a3c39ec7dba25594b97b42cb3195d54953ddb9d3d95a7c3902bc6e9d4" -dependencies = [ - "dlib", - "lazy_static", - "pkg-config", -] - -[[package]] -name = "wayland-sys" -version = "0.30.1" +name = "wgpu-core" +version = "27.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b2a02ac608e07132978689a6f9bf4214949c85998c247abadd4f4129b1aa06" +checksum = "27a75de515543b1897b26119f93731b385a19aea165a1ec5f0e3acecc229cae7" dependencies = [ - "dlib", - "lazy_static", + "arrayvec", + "bit-set", + "bit-vec", + "bitflags 2.10.0", + "bytemuck", + "cfg_aliases", + "document-features", + "hashbrown", + "indexmap", "log", - "pkg-config", + "naga", + "once_cell", + "parking_lot", + "portable-atomic", + "profiling", + "raw-window-handle", + "rustc-hash 1.1.0", + "smallvec", + "thiserror 2.0.17", + "wgpu-core-deps-windows-linux-android", + "wgpu-hal", + "wgpu-types", ] [[package]] -name = "web-sys" -version = "0.3.69" +name = "wgpu-core-deps-windows-linux-android" +version = "27.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +checksum = "71197027d61a71748e4120f05a9242b2ad142e3c01f8c1b47707945a879a03c3" dependencies = [ - "js-sys", - "wasm-bindgen", + "wgpu-hal", ] [[package]] -name = "webbrowser" -version = "0.8.15" +name = "wgpu-hal" +version = "27.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db67ae75a9405634f5882791678772c94ff5f16a66535aae186e26aa0841fc8b" +checksum = "5b21cb61c57ee198bc4aff71aeadff4cbb80b927beb912506af9c780d64313ce" dependencies = [ - "core-foundation", - "home", - "jni", + "bitflags 2.10.0", + "cfg-if", + "cfg_aliases", + "libloading", "log", - "ndk-context", - "objc", - "raw-window-handle 0.5.2", - "url", - "web-sys", + "naga", + "portable-atomic", + "portable-atomic-util", + "raw-window-handle", + "renderdoc-sys", + "thiserror 2.0.17", + "wgpu-types", ] [[package]] -name = "weezl" -version = "0.1.8" +name = "wgpu-types" +version = "27.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" +checksum = "afdcf84c395990db737f2dd91628706cb31e86d72e53482320d368e52b5da5eb" +dependencies = [ + "bitflags 2.10.0", + "bytemuck", + "js-sys", + "log", + "thiserror 2.0.17", + "web-sys", +] [[package]] name = "wide" -version = "0.7.26" +version = "0.7.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "901e8597c777fa042e9e245bd56c0dc4418c5db3f845b6ff94fbac732c6a0692" +checksum = "0ce5da8ecb62bcd8ec8b7ea19f69a51275e91299be594ea5cc6ef7819e16cd03" dependencies = [ "bytemuck", - "safe_arch 0.7.2", + "safe_arch", ] [[package]] @@ -3939,20 +4232,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.8" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "winapi-wsapoll" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1eafc5f679c576995526e81635d0cf9695841736712b4e892f87abbe6fed3f28" -dependencies = [ - "winapi", + "windows-sys 0.61.2", ] [[package]] @@ -3962,70 +4246,54 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "windows" -version = "0.42.0" +name = "windows-link" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0286ba339aa753e70765d521bb0242cc48e1194562bfa2a2ad7ac8a6de28f5d5" -dependencies = [ - "windows-implement", - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] -name = "windows-implement" -version = "0.42.0" +name = "windows-sys" +version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9539b6bd3eadbd9de66c9666b22d802b833da7e996bc06896142e09854a61767" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", + "windows-targets 0.42.2", ] [[package]] name = "windows-sys" -version = "0.36.1" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows_aarch64_msvc 0.36.1", - "windows_i686_gnu 0.36.1", - "windows_i686_msvc 0.36.1", - "windows_x86_64_gnu 0.36.1", - "windows_x86_64_msvc 0.36.1", + "windows-targets 0.52.6", ] [[package]] name = "windows-sys" -version = "0.45.0" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets 0.42.2", + "windows-targets 0.52.6", ] [[package]] name = "windows-sys" -version = "0.48.0" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets 0.48.5", + "windows-targets 0.53.5", ] [[package]] name = "windows-sys" -version = "0.52.0" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows-targets 0.52.6", + "windows-link", ] [[package]] @@ -4043,21 +4311,6 @@ dependencies = [ "windows_x86_64_msvc 0.42.2", ] -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - [[package]] name = "windows-targets" version = "0.52.6" @@ -4067,7 +4320,7 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm", + "windows_i686_gnullvm 0.52.6", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", @@ -4075,16 +4328,27 @@ dependencies = [ ] [[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" +name = "windows-targets" +version = "0.53.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", +] [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.5" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" [[package]] name = "windows_aarch64_gnullvm" @@ -4093,10 +4357,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] -name = "windows_aarch64_msvc" -version = "0.36.1" +name = "windows_aarch64_gnullvm" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" [[package]] name = "windows_aarch64_msvc" @@ -4104,12 +4368,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" @@ -4117,10 +4375,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] -name = "windows_i686_gnu" -version = "0.36.1" +name = "windows_aarch64_msvc" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" [[package]] name = "windows_i686_gnu" @@ -4130,15 +4388,15 @@ checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_gnu" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnu" -version = "0.52.6" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" [[package]] name = "windows_i686_gnullvm" @@ -4147,10 +4405,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] -name = "windows_i686_msvc" -version = "0.36.1" +name = "windows_i686_gnullvm" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" [[package]] name = "windows_i686_msvc" @@ -4158,12 +4416,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - [[package]] name = "windows_i686_msvc" version = "0.52.6" @@ -4171,10 +4423,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] -name = "windows_x86_64_gnu" -version = "0.36.1" +name = "windows_i686_msvc" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" [[package]] name = "windows_x86_64_gnu" @@ -4184,15 +4436,15 @@ checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnu" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnu" -version = "0.52.6" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" [[package]] name = "windows_x86_64_gnullvm" @@ -4200,12 +4452,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" @@ -4213,10 +4459,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] -name = "windows_x86_64_msvc" -version = "0.36.1" +name = "windows_x86_64_gnullvm" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" [[package]] name = "windows_x86_64_msvc" @@ -4226,66 +4472,87 @@ checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "windows_x86_64_msvc" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "windows_x86_64_msvc" -version = "0.52.6" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winit" -version = "0.27.5" +version = "0.30.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb796d6fbd86b2fd896c9471e6f04d39d750076ebe5680a3958f00f5ab97657c" +checksum = "c66d4b9ed69c4009f6321f762d6e61ad8a2389cd431b97cb1e146812e9e6c732" dependencies = [ - "bitflags 1.3.2", - "cocoa 0.24.1", - "core-foundation", - "core-graphics 0.22.3", - "dispatch", - "instant", + "ahash", + "android-activity", + "atomic-waker", + "bitflags 2.10.0", + "block2 0.5.1", + "bytemuck", + "calloop 0.13.0", + "cfg_aliases", + "concurrent-queue", + "core-foundation 0.9.4", + "core-graphics", + "cursor-icon", + "dpi", + "js-sys", "libc", - "log", - "mio 0.8.11", + "memmap2", "ndk", - "ndk-glue", - "objc", - "once_cell", - "parking_lot", + "objc2 0.5.2", + "objc2-app-kit 0.2.2", + "objc2-foundation 0.2.2", + "objc2-ui-kit", + "orbclient", "percent-encoding", - "raw-window-handle 0.4.3", - "raw-window-handle 0.5.2", - "sctk-adwaita", - "smithay-client-toolkit", + "pin-project", + "raw-window-handle", + "redox_syscall 0.4.1", + "rustix 0.38.44", + "smithay-client-toolkit 0.19.2", + "smol_str", + "tracing", + "unicode-segmentation", "wasm-bindgen", + "wasm-bindgen-futures", + "wayland-backend", "wayland-client", "wayland-protocols", + "wayland-protocols-plasma", "web-sys", - "windows-sys 0.36.1", + "web-time", + "windows-sys 0.52.0", "x11-dl", + "x11rb", + "xkbcommon-dl", ] [[package]] name = "winnow" -version = "0.5.40" +version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" dependencies = [ "memchr", ] [[package]] -name = "wio" -version = "0.2.2" +name = "wit-bindgen" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d129932f4644ac2396cb456385cbf9e63b5b30c6e8dc4820bdca4eb082037a5" -dependencies = [ - "winapi", -] +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" + +[[package]] +name = "writeable" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" [[package]] name = "x11-dl" @@ -4300,95 +4567,90 @@ dependencies = [ [[package]] name = "x11rb" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdf3c79412dd91bae7a7366b8ad1565a85e35dd049affc3a6a2c549e97419617" -dependencies = [ - "gethostname 0.2.3", - "nix 0.25.1", - "winapi", - "winapi-wsapoll", - "x11rb-protocol 0.11.1", -] - -[[package]] -name = "x11rb" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d91ffca73ee7f68ce055750bf9f6eca0780b8c85eff9bc046a3b0da41755e12" -dependencies = [ - "gethostname 0.4.3", - "rustix", - "x11rb-protocol 0.13.1", -] - -[[package]] -name = "x11rb-protocol" -version = "0.11.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0b1513b141123073ce54d5bb1d33f801f17508fbd61e02060b1214e96d39c56" +checksum = "9993aa5be5a26815fe2c3eacfc1fde061fc1a1f094bf1ad2a18bf9c495dd7414" dependencies = [ - "nix 0.25.1", + "as-raw-xcb-connection", + "gethostname", + "libc", + "libloading", + "once_cell", + "rustix 1.1.3", + "x11rb-protocol", ] [[package]] name = "x11rb-protocol" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec107c4503ea0b4a98ef47356329af139c0a4f7750e621cf2973cd3385ebcb3d" +checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd" [[package]] name = "xcursor" -version = "0.3.6" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d491ee231a51ae64a5b762114c3ac2104b967aadba1de45c86ca42cf051513b7" +checksum = "bec9e4a500ca8864c5b47b8b482a73d62e4237670e5b5f1d6b9e3cae50f28f2b" [[package]] name = "xdg" -version = "2.5.2" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546" +checksum = "2fb433233f2df9344722454bc7e96465c9d03bff9d77c248f9e7523fe79585b5" [[package]] name = "xim" -version = "0.2.3" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d33c4b134739b0462b484db0f0bad06b5f701203dd139ffdd3042ce88542b29d" +checksum = "bb59e6a1a1e0a88e15f870621fa98e8a840f736db8d852ff4e254d76dc75fe26" dependencies = [ "ahash", - "hashbrown 0.13.2", + "hashbrown", "log", - "x11rb 0.11.1", + "x11rb", "xim-ctext", "xim-parser", ] [[package]] name = "xim-ctext" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ac61a7062c40f3c37b6e82eeeef835d5cc7824b632a72784a89b3963c33284c" +checksum = "c5aa25609628bea64c97aa815f33b432e7ea40f047e4492a4f08be9331b10d32" dependencies = [ "encoding_rs", ] [[package]] name = "xim-parser" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b100b895758fefbf602129502acc0dd474bc08dd1e2036f17a7c118d6fd6fe53" +checksum = "5dcee45f89572d5a65180af3a84e7ddb24f5ea690a6d3aa9de231281544dd7b7" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.10.0", ] [[package]] name = "xkbcommon" -version = "0.7.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13867d259930edc7091a6c41b4ce6eee464328c6ff9659b7e4c668ca20d4c91e" +checksum = "a7a974f48060a14e95705c01f24ad9c3345022f4d97441b8a36beb7ed5c4a02d" dependencies = [ "libc", - "memmap2 0.8.0", + "memmap2", + "xkeysym", +] + +[[package]] +name = "xkbcommon-dl" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" +dependencies = [ + "bitflags 2.10.0", + "dlib", + "log", + "once_cell", "xkeysym", ] @@ -4400,73 +4662,226 @@ checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" [[package]] name = "xml-rs" -version = "0.8.20" +version = "0.8.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791978798f0597cfc70478424c2b4fdc2b7a8024aaff78497ef00f24ef674193" +checksum = "3ae8337f8a065cfc972643663ea4279e04e7256de865aa66fe25cec5fb912d3f" [[package]] name = "yansi" -version = "0.5.1" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" [[package]] -name = "zerocopy" -version = "0.6.6" +name = "yoke" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zbus" +version = "5.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfeff997a0aaa3eb20c4652baf788d2dfa6d2839a0ead0b3ff69ce2f9c4bdd1" +dependencies = [ + "async-broadcast", + "async-recursion", + "async-trait", + "enumflags2", + "event-listener", + "futures-core", + "futures-lite", + "hex", + "libc", + "ordered-stream", + "rustix 1.1.3", + "serde", + "serde_repr", + "tokio", + "tracing", + "uds_windows", + "uuid", + "windows-sys 0.61.2", + "winnow", + "zbus_macros", + "zbus_names", + "zvariant", +] + +[[package]] +name = "zbus_macros" +version = "5.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bbd5a90dbe8feee5b13def448427ae314ccd26a49cac47905cafefb9ff846f1" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", + "zbus_names", + "zvariant", + "zvariant_utils", +] + +[[package]] +name = "zbus_names" +version = "4.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854e949ac82d619ee9a14c66a1b674ac730422372ccb759ce0c39cabcf2bf8e6" +checksum = "ffd8af6d5b78619bab301ff3c560a5bd22426150253db278f164d6cf3b72c50f" dependencies = [ - "byteorder", - "zerocopy-derive 0.6.6", + "serde", + "winnow", + "zvariant", ] [[package]] name = "zerocopy" -version = "0.7.35" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +checksum = "668f5168d10b9ee831de31933dc111a459c97ec93225beb307aed970d1372dfd" dependencies = [ - "zerocopy-derive 0.7.35", + "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.6.6" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "125139de3f6b9d625c39e2efdd73d41bdac468ccd556556440e322be0e1bbd91" +checksum = "2c7962b26b0a8685668b671ee4b54d007a67d4eaf05fda79ac0ecf41e32270f1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn", ] [[package]] -name = "zerocopy-derive" -version = "0.7.35" +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn", + "synstructure", ] [[package]] -name = "zune-inflate" -version = "0.2.54" +name = "zerotrie" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" dependencies = [ - "simd-adler32", + "displaydoc", + "yoke", + "zerofrom", ] [[package]] -name = "zwp-virtual-keyboard" -version = "0.2.7" +name = "zerovec" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07b449405e5c49d10ab71187d3338366625340263d3fb061944ae3c94a639a9a" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" dependencies = [ - "wayland-client", - "wayland-commons", - "wayland-scanner", + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zmij" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd8f3f50b848df28f887acb68e41201b5aea6bc8a8dacc00fb40635ff9a72fea" + +[[package]] +name = "zune-core" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" + +[[package]] +name = "zune-jpeg" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29ce2c8a9384ad323cf564b67da86e21d3cfdff87908bc1223ed5c99bc792713" +dependencies = [ + "zune-core", +] + +[[package]] +name = "zvariant" +version = "5.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b64ef4f40c7951337ddc7023dd03528a57a3ce3408ee9da5e948bd29b232c4" +dependencies = [ + "endi", + "enumflags2", + "serde", + "winnow", + "zvariant_derive", + "zvariant_utils", +] + +[[package]] +name = "zvariant_derive" +version = "5.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "484d5d975eb7afb52cc6b929c13d3719a20ad650fea4120e6310de3fc55e415c" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", + "zvariant_utils", +] + +[[package]] +name = "zvariant_utils" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f75c23a64ef8f40f13a6989991e643554d9bef1d682a281160cf0c1bc389c5e9" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "syn", + "winnow", ] diff --git a/Cargo.toml b/Cargo.toml index 9a3565de..e71f42a8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,6 @@ members = [ "src/engine/candidate", "src/engine/core", "src/engine/config", - "src/engine/cffi", "src/engine/dict", "src/engine/backend", diff --git a/README.ko.md b/README.ko.md index cecbf764..7bf7fb76 100644 --- a/README.ko.md +++ b/README.ko.md @@ -51,8 +51,7 @@ i18n = { inputMethod = { enable = true; type = "kime"; - kime.config = { - indicator.icon_color = "White"; + kime.iconColor = "White"; }; }; }; @@ -66,6 +65,15 @@ i18n = { [releases](https://github.com/Riey/kime/releases) 탭에 있는 .deb 파일을 설치할 수 있습니다. +### 페도라 + +비공식 패키지가 [Fedora Copr](https://copr.fedorainfracloud.org/coprs/toroidalfox/kime/) 에서 운영되고 있습니다. + +```sh +dnf copr enable toroidalfox/kime +dnf install kime # 개발 버전은 `kime-git` +``` + ### 젠투 ```sh @@ -75,6 +83,12 @@ emaint sync -r riey emerge -av kime ``` +### 오픈수세 (텀블위드) + +``` +zypper in kime +``` + ### 소스에서 빌드하기 ### 도커 @@ -87,27 +101,25 @@ cd kime docker build --file build-docker/<배포판 경로>/Dockerfile --tag kime-build:git . docker run --name kime kime-build:git -docker cp kime:/opt/kime-out/kime.tar.xz . +docker cp kime:/opt/kime-out/kime.tar.zst . # deb 파일을 얻으시려면 대신 이 명령어를 실행하세요 # docker cp kime:/opt/kime-out/kime_amd64.deb . ``` ### 직접 빌드 -빌드하기 전에 **cargo** 및 아래 나열되어 있는 기타 종속성이 설치되어 있는지 확인하세요. +빌드하기 전에 **cargo**, **meson**, **ninja** 및 아래 나열되어 있는 기타 종속성이 설치되어 있는지 확인하세요. ```sh -git clone https://github.com/riey/kime +git clone https://github.com/Riey/kime cd kime -scripts/build.sh -ar +meson setup build +ninja -C build +sudo ninja -C build install ``` -이제 모든 파일은 build/out 경로에 있습니다. 만약 수동 설치를 원하시면 쓰시면 됩니다. - -`scripts/install.sh ` 스크립트를 쓸 수도 있습니다. 패키징할 때 유용합니다. - -`scripts/release-deb.sh ` 스크립트를 사용하시면 `deb` 파일을 생성합니다. +필요한 프론트엔드만 `-Dgtk3=true`, `-Dqt5=true` 등으로 선택 또는 해제 하세요. #### GTK @@ -122,12 +134,6 @@ sudo gtk-query-immodules-3.0 --update-cache sudo gio-querymodules /usr/lib/gtk-4.0/4.0.0/immodules ``` -## 개발 - -### C/C++ - -`./scripts/generate_properties.sh`을 실행해서 vscode에서 C/C++ 코드의 인텔리센스 기능을 사용할 수 있습니다. - ## 설정 ### 데비안 계열 @@ -154,8 +160,8 @@ kime은 kime 데몬을 위한 kime.desktop 파일을 /etc/xdg/autostart에 설 ### KDE Plasma Wayland -시스템 설정 > 하드웨어 > 입력 장치 > 가상 키보드에서 `kime 데몬`을 선택해야 합니다. -이후에 로그아웃을 하는 것을 권장합니다. +시스템 설정 > 입력과 출력 > 키보드 > 가상 키보드에서 `kime 데몬`을 선택해야 합니다. +이후에 로그아웃 후 재로그인을 하는 것을 권장합니다. ### Weston `~/.config/weston.ini`에 해당 내용이 있어야 합니다. @@ -189,7 +195,8 @@ path=/usr/bin/kime #### 필수 -* cmake +* meson +* ninja * cargo * libclang * pkg-config diff --git a/README.md b/README.md index 572b4aaf..6b06c9ef 100644 --- a/README.md +++ b/README.md @@ -51,8 +51,7 @@ i18n = { inputMethod = { enable = true; type = "kime"; - kime.config = { - indicator.icon_color = "White"; + kime.iconColor = "White"; }; }; }; @@ -68,6 +67,15 @@ Developing version is available on [`kime-git`](https://aur.archlinux.org/packag `.deb` package is available on github [releases](https://github.com/Riey/kime/releases) tab. +### Fedora + +The unofficial package is being maintained on [Fedora Copr](https://copr.fedorainfracloud.org/coprs/toroidalfox/kime/). + +```sh +dnf copr enable toroidalfox/kime +dnf install kime # `kime-git` for bleeding edge +``` + ### Gentoo ```sh @@ -77,6 +85,12 @@ emaint sync -r riey emerge -av kime ``` +### openSUSE (Tumbleweed) + +``` +zypper in kime +``` + ### Build from source #### Docker @@ -89,27 +103,25 @@ cd kime docker build --file build-docker//Dockerfile --tag kime-build:git . docker run --name kime kime-build:git -docker cp kime:/opt/kime-out/kime.tar.xz . +docker cp kime:/opt/kime-out/kime.tar.zst . # if you want to build deb package try this command instead # docker cp kime:/opt/kime-out/kime_amd64.deb . ``` #### Manual build -Make sure that **cargo** and other dependencies listed below are installed before build. +Make sure that **cargo**, **meson**, **ninja**, and other dependencies listed below are installed before build. ```sh git clone https://github.com/Riey/kime cd kime -scripts/build.sh -ar +meson setup build +ninja -C build +sudo ninja -C build install ``` -Every files needed for manual install is in `build/out` directory. - -`scripts/install.sh ` can be used for packaging. - -`scripts/release-deb.sh ` can be used for packaging `deb` package. +Enable/disable the frontends by toggling `-Dgtk3=true`, `-Dqt5=false`, etc. #### GTK @@ -122,12 +134,6 @@ sudo gtk-query-immodules-3.0 --update-cache sudo gio-querymodules /usr/lib/gtk-4.0/4.0.0/immodules ``` -## Development - -### C/C++ - -Run `./scripts/generate_properties.sh` for using intellisense C/C++ in vscode - ## Configuration ### environment variables setup @@ -154,8 +160,8 @@ kime.desktop file is installed in /etc/xdg/autostart when installing kime. ### KDE Plasma Wayland -It is required to select `kime daemon` under System Settings > Hardware > Input Devices > Virtual Keyboard. -A logout is recommended afterwards. +It is required to select `kime daemon` under System Settings > Input & Output > Keyboard > Virtual Keyboard. +A logout and re-login is recommended afterwards. ### Weston @@ -189,7 +195,8 @@ These dependencies are optional depending on your environments. For example, qt6 #### Required -* cmake +* meson +* ninja * cargo * libclang * pkg-config diff --git a/VERSION b/VERSION index 94ff29cc..944880fa 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.1.1 +3.2.0 diff --git a/build-docker/arch/Dockerfile b/build-docker/arch/Dockerfile index 89f45acd..9e751891 100644 --- a/build-docker/arch/Dockerfile +++ b/build-docker/arch/Dockerfile @@ -1,9 +1,11 @@ FROM archlinux:base-devel +ENV MESON_ARGS="-Dgtk3=enabled -Dgtk4=enabled -Dqt5=enabled -Dqt6=enabled" + WORKDIR /opt/kime RUN pacman -Syu --noconfirm -RUN pacman -S --noconfirm --needed rust cmake clang llvm libxcb cairo +RUN pacman -S --noconfirm --needed rustup meson ninja clang llvm libxcb cairo RUN pacman -S --noconfirm --needed gtk3 gtk4 RUN pacman -S --noconfirm --needed qt5-base qt6-base RUN pacman -S --noconfirm --needed git @@ -14,17 +16,22 @@ COPY .git ./.git COPY Cargo.toml . COPY Cargo.lock . +COPY rust-toolchain.toml . + +RUN rustup install RUN cargo fetch COPY res ./res COPY ci ./ci +COPY packaging ./packaging COPY docs ./docs -COPY scripts ./scripts +COPY meson.build . +COPY meson.options . COPY LICENSE . COPY NOTICE.md . COPY README.ko.md . COPY README.md . COPY VERSION . -ENTRYPOINT [ "ci/build_xz.sh" ] +ENTRYPOINT [ "ci/build_zst.sh" ] diff --git a/build-docker/debian-bookworm/Dockerfile b/build-docker/debian-bookworm/Dockerfile new file mode 100644 index 00000000..2fc3bc11 --- /dev/null +++ b/build-docker/debian-bookworm/Dockerfile @@ -0,0 +1,39 @@ +FROM rust:slim-bookworm + +ENV DEBIAN_FRONTEND=noninteractive +ENV MESON_ARGS="-Dgtk3=enabled -Dgtk4=enabled -Dqt5=enabled -Dqt6=enabled" + +WORKDIR /opt/kime + +RUN echo " \n\ +deb http://ftp.kr.debian.org/debian/ sid main contrib non-free\n\ +#deb http://ftp.kr.debian.org/debian/ sid-updates main contrib non-free\n\ +#deb http://security.debian.org/ sid/updates main\n\ +#deb http://ftp.debian.org/debian bookworm-backports main\n\ +" > /etc/apt/sources.list +RUN apt-get update +RUN apt-get install -y build-essential git gcc clang libclang-dev ninja-build pkg-config zstd meson +RUN apt-get install -y libpango1.0-dev libcairo2-dev libgtk-4-dev libgtk-3-dev libglib2.0-0t64 libxcb1 +RUN apt-get install -y qtbase5-dev qtbase5-private-dev libqt5gui5t64 qt6-base-dev qt6-base-private-dev libxcb-shape0-dev libxcb-xfixes0-dev +RUN mkdir -pv /opt/kime-out + +COPY src ./src + +COPY Cargo.toml . +COPY Cargo.lock . + +RUN cargo fetch + +COPY res ./res +COPY ci ./ci +COPY packaging ./packaging +COPY docs ./docs +COPY meson.build . +COPY meson.options . +COPY LICENSE . +COPY NOTICE.md . +COPY README.ko.md . +COPY README.md . +COPY VERSION . + +ENTRYPOINT [ "ci/build_deb.sh" ] diff --git a/build-docker/debian-buster/Dockerfile b/build-docker/debian-buster/Dockerfile deleted file mode 100644 index b8c6229c..00000000 --- a/build-docker/debian-buster/Dockerfile +++ /dev/null @@ -1,36 +0,0 @@ -FROM rust:slim-buster - -ENV DEBIAN_FRONTEND=noninteractive - -WORKDIR /opt/kime - -RUN echo " \n\ -deb http://ftp.kr.debian.org/debian/ stable main contrib non-free\n\ -deb http://ftp.kr.debian.org/debian/ stable-updates main contrib non-free\n\ -deb http://security.debian.org/ stable/updates main\n\ -deb http://ftp.debian.org/debian buster-backports main\n\ -" > /etc/apt/sources.list -RUN apt-get update -RUN apt-get install -y build-essential git gcc clang libclang-dev cmake extra-cmake-modules pkg-config zstd -RUN apt-get install -y libpango1.0-dev libcairo2-dev libgtk-3-dev libglib2.0 libxcb1 -RUN apt-get install -y qt5-default qtbase5-dev qtbase5-private-dev libqt5gui5 -RUN mkdir -pv /opt/kime-out - -COPY src ./src - -COPY Cargo.toml . -COPY Cargo.lock . - -RUN cargo fetch - -COPY res ./res -COPY ci ./ci -COPY docs ./docs -COPY scripts ./scripts -COPY LICENSE . -COPY NOTICE.md . -COPY README.ko.md . -COPY README.md . -COPY VERSION . - -ENTRYPOINT [ "ci/build_deb.sh" ] diff --git a/build-docker/debian-trixie/Dockerfile b/build-docker/debian-trixie/Dockerfile new file mode 100644 index 00000000..c607ab4b --- /dev/null +++ b/build-docker/debian-trixie/Dockerfile @@ -0,0 +1,33 @@ +FROM rust:slim-trixie + +ENV DEBIAN_FRONTEND=noninteractive +ENV MESON_ARGS="-Dgtk3=enabled -Dgtk4=enabled -Dqt5=enabled -Dqt6=enabled" + +WORKDIR /opt/kime + +RUN apt-get update +RUN apt-get install -y build-essential git gcc clang libclang-dev ninja-build pkg-config zstd meson +RUN apt-get install -y libpango1.0-dev libcairo2-dev libgtk-4-dev libgtk-3-dev libglib2.0-0t64 libxcb1 +RUN apt-get install -y qtbase5-dev qtbase5-private-dev libqt5gui5t64 qt6-base-dev qt6-base-private-dev libxcb-shape0-dev libxcb-xfixes0-dev +RUN mkdir -pv /opt/kime-out + +COPY src ./src + +COPY Cargo.toml . +COPY Cargo.lock . + +RUN cargo fetch + +COPY res ./res +COPY ci ./ci +COPY packaging ./packaging +COPY docs ./docs +COPY meson.build . +COPY meson.options . +COPY LICENSE . +COPY NOTICE.md . +COPY README.ko.md . +COPY README.md . +COPY VERSION . + +ENTRYPOINT [ "ci/build_deb.sh" ] diff --git a/build-docker/ubuntu-18.04/Dockerfile b/build-docker/ubuntu-18.04/Dockerfile deleted file mode 100644 index 8a6e2991..00000000 --- a/build-docker/ubuntu-18.04/Dockerfile +++ /dev/null @@ -1,33 +0,0 @@ -FROM ubuntu:18.04 - -ENV DEBIAN_FRONTEND=noninteractive - -WORKDIR /opt/kime - -RUN apt-get update -RUN apt-get install -y curl apt-utils -RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --no-modify-path --profile minimal -RUN curl --proto '=https' https://github.com/Kitware/CMake/releases/download/v3.19.5/cmake-3.19.5-Linux-$(uname -m).sh | sh -s -- --skip-license --prefix=/usr -RUN apt-get install -y build-essential git gcc libclang-10-dev pkg-config zstd -RUN apt-get install -y libpango1.0-dev libcairo2-dev libgtk-3-dev libglib2.0 libxcb1 -RUN apt-get install -y qt5-default qtbase5-dev qtbase5-private-dev libqt5gui5 -RUN mkdir -pv /opt/kime-out - -COPY src ./src - -COPY Cargo.toml . -COPY Cargo.lock . - -RUN cargo fetch - -COPY res ./res -COPY ci ./ci -COPY docs ./docs -COPY scripts ./scripts -COPY LICENSE . -COPY NOTICE.md . -COPY README.ko.md . -COPY README.md . -COPY VERSION . - -ENTRYPOINT [ "ci/build_deb.sh" ] diff --git a/build-docker/ubuntu-20.04/Dockerfile b/build-docker/ubuntu-20.04/Dockerfile deleted file mode 100644 index 59cccdbd..00000000 --- a/build-docker/ubuntu-20.04/Dockerfile +++ /dev/null @@ -1,35 +0,0 @@ -FROM ubuntu:20.04 - -ENV DEBIAN_FRONTEND=noninteractive \ - PATH=/root/.cargo/bin:$PATH - -WORKDIR /opt/kime - -RUN apt-get update -RUN apt-get install -y curl apt-utils -RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --no-modify-path --profile minimal -RUN rustc --version -RUN apt-get install -y build-essential git gcc libclang-10-dev cmake extra-cmake-modules pkg-config zstd -RUN apt-get install -y libpango1.0-dev libcairo2-dev libgtk-3-dev libglib2.0 libxcb1 -RUN apt-get install -y qtbase5-dev qtbase5-private-dev libqt5gui5 -RUN apt-get install -y libxcb-shape0-dev libxcb-xfixes0-dev -RUN mkdir -pv /opt/kime-out - -COPY src ./src - -COPY Cargo.toml . -COPY Cargo.lock . - -RUN cargo fetch - -COPY res ./res -COPY ci ./ci -COPY docs ./docs -COPY scripts ./scripts -COPY LICENSE . -COPY NOTICE.md . -COPY README.ko.md . -COPY README.md . -COPY VERSION . - -ENTRYPOINT [ "ci/build_deb.sh" ] diff --git a/build-docker/ubuntu-20.10/Dockerfile b/build-docker/ubuntu-20.10/Dockerfile deleted file mode 100644 index 7a472edf..00000000 --- a/build-docker/ubuntu-20.10/Dockerfile +++ /dev/null @@ -1,34 +0,0 @@ -FROM ubuntu:20.10 - -ENV DEBIAN_FRONTEND=noninteractive \ - PATH=/root/.cargo/bin:$PATH - -WORKDIR /opt/kime - -RUN apt-get update -RUN apt-get install -y curl apt-utils -RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --no-modify-path --profile minimal -RUN rustc --version -RUN apt-get install -y build-essential git gcc libclang-10-dev cmake extra-cmake-modules pkg-config zstd -RUN apt-get install -y libpango1.0-dev libcairo2-dev libgtk-3-dev libglib2.0 libxcb1 -RUN apt-get install -y qtbase5-dev qtbase5-private-dev libqt5gui5 -RUN mkdir -pv /opt/kime-out - -COPY src ./src - -COPY Cargo.toml . -COPY Cargo.lock . - -RUN cargo fetch - -COPY res ./res -COPY ci ./ci -COPY docs ./docs -COPY scripts ./scripts -COPY LICENSE . -COPY NOTICE.md . -COPY README.ko.md . -COPY README.md . -COPY VERSION . - -ENTRYPOINT [ "ci/build_deb.sh" ] diff --git a/build-docker/ubuntu-21.04/Dockerfile b/build-docker/ubuntu-21.04/Dockerfile deleted file mode 100644 index eb42c68d..00000000 --- a/build-docker/ubuntu-21.04/Dockerfile +++ /dev/null @@ -1,34 +0,0 @@ -FROM ubuntu:21.04 - -ENV DEBIAN_FRONTEND=noninteractive \ - PATH=/root/.cargo/bin:$PATH - -WORKDIR /opt/kime - -RUN apt-get update -RUN apt-get install -y curl apt-utils -RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --no-modify-path --profile minimal -RUN rustc --version -RUN apt-get install -y build-essential git gcc libclang-11-dev cmake extra-cmake-modules pkg-config zstd -RUN apt-get install -y libpango1.0-dev libcairo2-dev libgtk-3-dev libglib2.0 libxcb1 -RUN apt-get install -y qtbase5-dev qtbase5-private-dev libqt5gui5 libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev -RUN mkdir -pv /opt/kime-out - -COPY src ./src - -COPY Cargo.toml . -COPY Cargo.lock . - -RUN cargo fetch - -COPY res ./res -COPY ci ./ci -COPY docs ./docs -COPY scripts ./scripts -COPY LICENSE . -COPY NOTICE.md . -COPY README.ko.md . -COPY README.md . -COPY VERSION . - -ENTRYPOINT [ "ci/build_deb.sh" ] diff --git a/build-docker/ubuntu-21.10/Dockerfile b/build-docker/ubuntu-21.10/Dockerfile deleted file mode 100644 index e4c131fd..00000000 --- a/build-docker/ubuntu-21.10/Dockerfile +++ /dev/null @@ -1,36 +0,0 @@ -FROM ubuntu:21.10 - -ENV DEBIAN_FRONTEND=noninteractive \ - PATH=/root/.cargo/bin:$PATH - -WORKDIR /opt/kime - -# RUN sed -i -re 's/([a-z]{2}.)?archive.ubuntu.com|security.ubuntu.com/mirror.kakao.com/g' /etc/apt/sources.list -RUN apt-get update -RUN apt-get install -y curl apt-utils -RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --no-modify-path --profile minimal -RUN rustc --version -RUN apt-get install -y build-essential git gcc libclang-11-dev cmake extra-cmake-modules pkg-config zstd -RUN apt-get install -y libpango1.0-dev libcairo2-dev libgtk-3-dev libglib2.0 libxcb1 -RUN apt-get install -y qtbase5-dev qtbase5-private-dev libqt5gui5 -RUN apt-get install -y libxcb-shape0-dev libxcb-xfixes0-dev -RUN mkdir -pv /opt/kime-out - -COPY src ./src - -COPY Cargo.toml . -COPY Cargo.lock . - -RUN cargo fetch - -COPY res ./res -COPY ci ./ci -COPY docs ./docs -COPY scripts ./scripts -COPY LICENSE . -COPY NOTICE.md . -COPY README.ko.md . -COPY README.md . -COPY VERSION . - -ENTRYPOINT [ "ci/build_deb.sh" ] diff --git a/build-docker/ubuntu-22.04/Dockerfile b/build-docker/ubuntu-22.04/Dockerfile index 1d791a9a..40d75080 100644 --- a/build-docker/ubuntu-22.04/Dockerfile +++ b/build-docker/ubuntu-22.04/Dockerfile @@ -2,15 +2,15 @@ FROM ubuntu:22.04 ENV DEBIAN_FRONTEND=noninteractive \ PATH=/root/.cargo/bin:$PATH +ENV MESON_ARGS="-Dgtk3=enabled -Dgtk4=disabled -Dqt5=enabled -Dqt6=disabled" WORKDIR /opt/kime -RUN sed -i -re 's/([a-z]{2}.)?archive.ubuntu.com|security.ubuntu.com/mirror.kakao.com/g' /etc/apt/sources.list RUN apt-get update RUN apt-get install -y curl apt-utils RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --no-modify-path --profile minimal RUN rustc --version -RUN apt-get install -y build-essential git gcc libclang-11-dev cmake extra-cmake-modules pkg-config zstd +RUN apt-get install -y build-essential git gcc libclang-11-dev ninja-build pkg-config zstd meson RUN apt-get install -y libpango1.0-dev libcairo2-dev libgtk-3-dev libglib2.0 libxcb1 RUN apt-get install -y qtbase5-dev qtbase5-private-dev libqt5gui5 RUN apt-get install -y libxcb-shape0-dev libxcb-xfixes0-dev @@ -25,8 +25,10 @@ RUN cargo fetch COPY res ./res COPY ci ./ci +COPY packaging ./packaging COPY docs ./docs -COPY scripts ./scripts +COPY meson.build . +COPY meson.options . COPY LICENSE . COPY NOTICE.md . COPY README.ko.md . diff --git a/build-docker/ubuntu-22.10/Dockerfile b/build-docker/ubuntu-22.10/Dockerfile deleted file mode 100644 index 1f65611c..00000000 --- a/build-docker/ubuntu-22.10/Dockerfile +++ /dev/null @@ -1,37 +0,0 @@ -FROM ubuntu:22.10 - -ENV DEBIAN_FRONTEND=noninteractive \ - PATH=/root/.cargo/bin:$PATH - -WORKDIR /opt/kime - -RUN sed -i -re 's/([a-z]{2}.)?archive.ubuntu.com|security.ubuntu.com/mirror.kakao.com/g' /etc/apt/sources.list -RUN apt-get update -RUN apt-get install -y curl apt-utils \ - build-essential git gcc libclang-11-dev cmake extra-cmake-modules pkg-config zstd \ - libpango1.0-dev libcairo2-dev libgtk-4-dev libgtk-3-dev libglib2.0 libxcb1 \ - qtbase5-dev qtbase5-private-dev libqt5gui5 \ - qt6-base-dev qt6-base-private-dev \ - libxcb-shape0-dev libxcb-xfixes0-dev -RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --no-modify-path --profile minimal -RUN rustc --version -RUN mkdir -pv /opt/kime-out - -COPY src ./src - -COPY Cargo.toml . -COPY Cargo.lock . - -RUN cargo fetch - -COPY res ./res -COPY ci ./ci -COPY docs ./docs -COPY scripts ./scripts -COPY LICENSE . -COPY NOTICE.md . -COPY README.ko.md . -COPY README.md . -COPY VERSION . - -ENTRYPOINT [ "ci/build_deb.sh" ] diff --git a/build-docker/ubuntu-24.04/Dockerfile b/build-docker/ubuntu-24.04/Dockerfile new file mode 100644 index 00000000..b0636d99 --- /dev/null +++ b/build-docker/ubuntu-24.04/Dockerfile @@ -0,0 +1,40 @@ +FROM ubuntu:24.04 + +ENV DEBIAN_FRONTEND=noninteractive \ + PATH=/root/.cargo/bin:$PATH +ENV MESON_ARGS="-Dgtk3=enabled -Dgtk4=enabled -Dqt5=enabled -Dqt6=enabled" + +WORKDIR /opt/kime + +RUN apt-get update +RUN apt-get install -y curl apt-utils \ + build-essential git gcc libclang-dev ninja-build pkg-config zstd \ + libpango1.0-dev libcairo2-dev libgtk-4-dev libgtk-3-dev libglib2.0 libxcb1 \ + qtbase5-dev qtbase5-private-dev libqt5gui5 \ + qt6-base-dev qt6-base-private-dev \ + libxcb-shape0-dev libxcb-xfixes0-dev \ + meson +RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --no-modify-path --profile minimal +RUN rustc --version +RUN mkdir -pv /opt/kime-out + +COPY src /opt/kime/src + +COPY Cargo.toml /opt/kime +COPY Cargo.lock /opt/kime + +RUN cargo fetch + +COPY res /opt/kime/res +COPY ci /opt/kime/ci +COPY packaging /opt/kime/packaging +COPY docs /opt/kime/docs +COPY meson.build /opt/kime +COPY meson.options /opt/kime +COPY LICENSE /opt/kime +COPY NOTICE.md /opt/kime +COPY README.ko.md /opt/kime +COPY README.md /opt/kime +COPY VERSION /opt/kime + +ENTRYPOINT [ "ci/build_deb.sh" ] diff --git a/ci/build_deb.sh b/ci/build_deb.sh index 12b3f4a3..45a68086 100755 --- a/ci/build_deb.sh +++ b/ci/build_deb.sh @@ -1,4 +1,16 @@ #!/bin/bash +set -e -ci/build_zst.sh -scripts/release-deb.sh /opt/kime-out +MULTIARCH=$(dpkg-architecture -qDEB_HOST_MULTIARCH) +meson setup build --prefix=/usr --libdir="lib/$MULTIARCH" $MESON_ARGS +ninja -C build + +for f in kime kime-check kime-indicator kime-candidate-window kime-xim kime-wayland; do + [ -f "target/release/$f" ] && strip -s "target/release/$f" +done +strip -s target/release/libkime_engine.so +for f in build/src/frontends/*/lib*.so; do + [ -e "$f" ] && strip -s "$f" +done + +packaging/build-deb.sh build /opt/kime-out diff --git a/ci/build_zst.sh b/ci/build_zst.sh index d27ec0ad..1ec5721a 100755 --- a/ci/build_zst.sh +++ b/ci/build_zst.sh @@ -1,4 +1,14 @@ #!/bin/bash +set -e -scripts/build.sh -ar -scripts/release-zst.sh /opt/kime-out +meson setup build $MESON_ARGS +ninja -C build + +for f in kime kime-check kime-indicator kime-candidate-window kime-xim kime-wayland; do + [ -f "target/release/$f" ] && strip -s "target/release/$f" +done +strip -s target/release/libkime_engine.so +strip -s build/src/frontends/*/lib*.so + +DESTDIR=$(pwd)/kime-install ninja -C build install +tar -cvf - -C kime-install . | zstd -T0 -15 -o /opt/kime-out/kime.tar.zst diff --git a/default.nix b/default.nix index f901d9d0..957dda52 100644 --- a/default.nix +++ b/default.nix @@ -1,41 +1,56 @@ { - pkgs ? import { }, + pkgs ? import {}, + rustToolchain ? pkgs.rustc, debug ? false, + gtk3 ? true, + gtk4 ? true, + qt5 ? false, + qt6 ? true, }: let - deps = import ./nix/deps.nix { pkgs = pkgs; }; - kimeVersion = builtins.readFile ./VERSION; - testArgs = if debug then "" else "--release"; + src = pkgs.lib.cleanSourceWith { + src = ./.; + filter = path: type: + let baseName = baseNameOf path; + in pkgs.lib.cleanSourceFilter path type + && !(baseName == "build" && type == "directory") + && !(baseName == "target" && type == "directory"); + }; + deps = import ./nix/deps.nix { inherit pkgs gtk3 gtk4 qt5 qt6; }; + kimeVersion = pkgs.lib.fileContents ./VERSION; + cargoProfile = if debug then "debug" else "release"; + boolToFeature = b: if b then "enabled" else "disabled"; + inherit (pkgs) llvmPackages_18 rustPlatform; in -with pkgs; -llvmPackages_18.stdenv.mkDerivation rec { +llvmPackages_18.stdenv.mkDerivation { name = "kime"; - src = ./.; + inherit src; buildInputs = deps.kimeBuildInputs; - nativeBuildInputs = deps.kimeNativeBuildInputs ++ [ rustPlatform.cargoSetupHook ]; + nativeBuildInputs = deps.kimeNativeBuildInputs ++ [ rustToolchain pkgs.cargo rustPlatform.cargoSetupHook ]; version = kimeVersion; - cargoDeps = rustPlatform.fetchCargoTarball { + cargoDeps = rustPlatform.fetchCargoVendor { inherit src; - #sha256 = "0000000000000000000000000000000000000000000000000000"; - sha256 = "sha256-hlTxyaE/300CBGIJtFzIh6CT5PcmmqWt8CN428sr2U8="; + hash = "sha256-ZgWHzXixTZWg7+2nXbw2NjeWD/cskGoZ/VSrM7vCwFs="; }; - LIBCLANG_PATH = "${pkgs.llvmPackages_18.libclang.lib}/lib"; - dontUseCmakeConfigure = true; + LIBCLANG_PATH = "${llvmPackages_18.libclang.lib}/lib"; dontWrapQtApps = true; - buildPhase = if debug then "bash scripts/build.sh -ad" else "bash scripts/build.sh -ar"; + configurePhase = '' + meson setup build \ + --prefix=$out \ + -Dcargo_profile=${cargoProfile} \ + -Dgtk3=${boolToFeature gtk3} -Dgtk4=${boolToFeature gtk4} \ + -Dqt5=${boolToFeature qt5} -Dqt6=${boolToFeature qt6} \ + ${pkgs.lib.optionalString qt5 "-Dqt5_plugindir=$out/${pkgs.qt5.qtbase.qtPluginPrefix}"} \ + ${pkgs.lib.optionalString qt6 "-Dqt6_plugindir=$out/${pkgs.qt6.qtbase.qtPluginPrefix}"} + ''; + buildPhase = '' + ninja -C build + ''; installPhase = '' - KIME_BIN_DIR=bin \ - KIME_INSTALL_HEADER=1 \ - KIME_INCLUDE_DIR=include \ - KIME_ICON_DIR=share/icons \ - KIME_LIB_DIR=lib \ - KIME_DOC_DIR=share/doc/kime \ - KIME_QT5_DIR=lib/qt-${pkgs.qt5.qtbase.version} \ - bash scripts/install.sh "$out" + ninja -C build install ''; doCheck = true; checkPhase = '' - cargo test ${testArgs} + cargo test ${if debug then "" else "--release"} ''; } - diff --git a/deny.toml b/deny.toml index d2065bb1..167038c9 100644 --- a/deny.toml +++ b/deny.toml @@ -9,6 +9,11 @@ # The values provided in this template are the default values that will be used # when any section or field is not specified in your own configuration +# Root options + +# The graph table configures how the dependency graph is constructed and thus +# which crates the checks are performed against +[graph] # If 1 or more target triples (and optionally, target_features) are specified, # only the specified targets will be checked when running `cargo deny check`. # This means, if a particular package is only ever used as a target specific @@ -20,58 +25,71 @@ targets = [ # The triple can be any string, but only the target triples built in to # rustc (as of 1.40) can be checked against actual config expressions - #{ triple = "x86_64-unknown-linux-musl" }, + #"x86_64-unknown-linux-musl", # You can also specify which target_features you promise are enabled for a # particular target. target_features are currently not validated against # the actual valid features supported by the target architecture. #{ triple = "wasm32-unknown-unknown", features = ["atomics"] }, ] +# When creating the dependency graph used as the source of truth when checks are +# executed, this field can be used to prune crates from the graph, removing them +# from the view of cargo-deny. This is an extremely heavy hammer, as if a crate +# is pruned from the graph, all of its dependencies will also be pruned unless +# they are connected to another crate in the graph that hasn't been pruned, +# so it should be used with care. The identifiers are [Package ID Specifications] +# (https://doc.rust-lang.org/cargo/reference/pkgid-spec.html) +#exclude = [] +# If true, metadata will be collected with `--all-features`. Note that this can't +# be toggled off if true, if you want to conditionally enable `--all-features` it +# is recommended to pass `--all-features` on the cmd line instead +all-features = false +# If true, metadata will be collected with `--no-default-features`. The same +# caveat with `all-features` applies +no-default-features = false +# If set, these feature will be enabled when collecting metadata. If `--features` +# is specified on the cmd line they will take precedence over this option. +#features = [] + +# The output table provides options for how/if diagnostics are outputted +[output] +# When outputting inclusion graphs in diagnostics that include features, this +# option can be used to specify the depth at which feature edges will be added. +# This option is included since the graphs can be quite large and the addition +# of features from the crate(s) to all of the graph roots can be far too verbose. +# This option can be overridden via `--feature-depth` on the cmd line +feature-depth = 1 # This section is considered when running `cargo deny check advisories` # More documentation for the advisories section can be found here: # https://embarkstudios.github.io/cargo-deny/checks/advisories/cfg.html [advisories] -# The path where the advisory database is cloned/fetched into -db-path = "~/.cargo/advisory-db" +# The path where the advisory databases are cloned/fetched into +#db-path = "$CARGO_HOME/advisory-dbs" # The url(s) of the advisory databases to use -db-urls = ["https://github.com/rustsec/advisory-db"] -# The lint level for security vulnerabilities -vulnerability = "deny" -# The lint level for unmaintained crates -unmaintained = "deny" -# The lint level for crates that have been yanked from their source registry -yanked = "deny" -# The lint level for crates with security notices. Note that as of -# 2019-12-17 there are no security notice advisories in -# https://github.com/rustsec/advisory-db -notice = "warn" +#db-urls = ["https://github.com/rustsec/advisory-db"] # A list of advisory IDs to ignore. Note that ignored advisories will still # output a note when they are encountered. ignore = [ - # only for build deps - "RUSTSEC-2022-0048", - #"RUSTSEC-0000-0000", + "RUSTSEC-2024-0436", + #{ id = "RUSTSEC-0000-0000", reason = "you can specify a reason the advisory is ignored" }, + #"a-crate-that-is-yanked@0.1.1", # you can also ignore yanked crate versions if you wish + #{ crate = "a-crate-that-is-yanked@0.1.1", reason = "you can specify why you are ignoring the yanked crate" }, ] -# Threshold for security vulnerabilities, any vulnerability with a CVSS score -# lower than the range specified will be ignored. Note that ignored advisories -# will still output a note when they are encountered. -# * None - CVSS Score 0.0 -# * Low - CVSS Score 0.1 - 3.9 -# * Medium - CVSS Score 4.0 - 6.9 -# * High - CVSS Score 7.0 - 8.9 -# * Critical - CVSS Score 9.0 - 10.0 -#severity-threshold = +# If this is true, then cargo deny will use the git executable to fetch advisory database. +# If this is false, then it uses a built-in git library. +# Setting this to true can be helpful if you have special authentication requirements that cargo-deny does not support. +# See Git Authentication for more information about setting up git authentication. +#git-fetch-with-cli = true # This section is considered when running `cargo deny check licenses` # More documentation for the licenses section can be found here: # https://embarkstudios.github.io/cargo-deny/checks/licenses/cfg.html [licenses] -# The lint level for crates which do not have a detectable license -unlicensed = "deny" # List of explicitly allowed licenses # See https://spdx.org/licenses/ for list of possible licenses -# [possible values: any SPDX 3.7 short identifier (+ optional exception)]. +# [possible values: any SPDX 3.11 short identifier (+ optional exception)]. allow = [ + "GPL-3.0-or-later", "MIT", "Apache-2.0", "BSD-2-Clause", @@ -81,32 +99,11 @@ allow = [ "Zlib", "ISC", "BSL-1.0", - "GPL-3.0", - "Unicode-DFS-2016", + "MPL-2.0", + "Unicode-3.0", "OFL-1.1", - "LicenseRef-UFL-1.0", "Unlicense", ] -# List of explicitly disallowed licenses -# See https://spdx.org/licenses/ for list of possible licenses -# [possible values: any SPDX 3.7 short identifier (+ optional exception)]. -deny = [ - #"Nokia", -] -# Lint level for licenses considered copyleft -copyleft = "allow" -# Blanket approval or denial for OSI-approved or FSF Free/Libre licenses -# * both - The license will be approved if it is both OSI-approved *AND* FSF -# * either - The license will be approved if it is either OSI-approved *OR* FSF -# * osi-only - The license will be approved if is OSI-approved *AND NOT* FSF -# * fsf-only - The license will be approved if is FSF *AND NOT* OSI-approved -# * neither - This predicate is ignored and the default lint level is used -allow-osi-fsf-free = "neither" -# Lint level used when no other predicates are matched -# 1. License isn't in the allow or deny lists -# 2. License isn't copyleft -# 3. License isn't OSI/FSF, or allow-osi-fsf-free = "neither" -default = "deny" # The confidence threshold for detecting a license from license text. # The higher the value, the more closely the license text must be to the # canonical license text of a valid SPDX license file. @@ -117,32 +114,23 @@ confidence-threshold = 0.8 exceptions = [ # Each entry is the crate and version constraint, and its specific allow # list - #{ allow = ["Zlib"], name = "adler32", version = "*" }, + #{ allow = ["Zlib"], crate = "adler32" }, ] # Some crates don't have (easily) machine readable licensing information, # adding a clarification entry for it allows you to manually specify the # licensing information -#[[licenses.clarify]] -# The name of the crate the clarification applies to -#name = "ring" -# The optional version constraint for the crate -#version = "*" -# The SPDX expression for the license requirements of the crate -#expression = "MIT AND ISC AND OpenSSL" -# One or more files in the crate's source used as the "source of truth" for -# the license expression. If the contents match, the clarification will be used -# when running the license check, otherwise the clarification will be ignored -# and the crate will be checked normally, which may produce warnings or errors -# depending on the rest of your configuration -#license-files = [ - # Each entry is a crate relative path, and the (opaque) hash of its contents - #{ path = "LICENSE", hash = 0xbd0eed23 } -#] +[[licenses.clarify]] +name = "epaint_default_fonts" +version = "*" +expression = "(MIT OR Apache-2.0) AND OFL-1.1" +license-files = [] [licenses.private] # If true, ignores workspace crates that aren't published, or are only -# published to private registries +# published to private registries. +# To see how to mark a crate as unpublished (to the official registry), +# visit https://doc.rust-lang.org/cargo/reference/manifest.html#the-publish-field. ignore = false # One or more private registries that you might publish crates to, if a crate # is only published to private registries, and ignore is true, the crate will @@ -165,29 +153,67 @@ wildcards = "allow" # * simplest-path - The path to the version with the fewest edges is highlighted # * all - Both lowest-version and simplest-path are used highlight = "all" +# The default lint level for `default` features for crates that are members of +# the workspace that is being checked. This can be overridden by allowing/denying +# `default` on a crate-by-crate basis if desired. +workspace-default-features = "allow" +# The default lint level for `default` features for external crates that are not +# members of the workspace. This can be overridden by allowing/denying `default` +# on a crate-by-crate basis if desired. +external-default-features = "allow" # List of crates that are allowed. Use with care! allow = [ - #{ name = "ansi_term", version = "=0.11.0" }, + #"ansi_term@0.11.0", + #{ crate = "ansi_term@0.11.0", reason = "you can specify a reason it is allowed" }, ] +# If true, workspace members are automatically allowed even when using deny-by-default +# This is useful for organizations that want to deny all external dependencies by default +# but allow their own workspace crates without having to explicitly list them +allow-workspace = false # List of crates to deny deny = [ - # Each entry the name of a crate and a version range. If version is - # not specified, all versions will be matched. - #{ name = "ansi_term", version = "=0.11.0" }, - # + #"ansi_term@0.11.0", + #{ crate = "ansi_term@0.11.0", reason = "you can specify a reason it is banned" }, # Wrapper crates can optionally be specified to allow the crate when it # is a direct dependency of the otherwise banned crate - #{ name = "ansi_term", version = "=0.11.0", wrappers = [] }, + #{ crate = "ansi_term@0.11.0", wrappers = ["this-crate-directly-depends-on-ansi_term"] }, ] + +# List of features to allow/deny +# Each entry the name of a crate and a version range. If version is +# not specified, all versions will be matched. +#[[bans.features]] +#crate = "reqwest" +# Features to not allow +#deny = ["json"] +# Features to allow +#allow = [ +# "rustls", +# "__rustls", +# "__tls", +# "hyper-rustls", +# "rustls", +# "rustls-pemfile", +# "rustls-tls-webpki-roots", +# "tokio-rustls", +# "webpki-roots", +#] +# If true, the allowed features must exactly match the enabled feature set. If +# this is set there is no point setting `deny` +#exact = true + # Certain crates/versions that will be skipped when doing duplicate detection. skip = [ + #"ansi_term@0.11.0", + #{ crate = "ansi_term@0.11.0", reason = "you can specify a reason why it can't be updated/removed" }, ] -# Similarly to `skip` allows you to skip certain crates during duplicate -# detection. Unlike skip, it also includes the entire tree of transitive +# Similarly to `skip` allows you to skip certain crates during duplicate +# detection. Unlike skip, it also includes the entire tree of transitive # dependencies starting at the specified crate, up to a certain depth, which is -# by default infinite +# by default infinite. skip-tree = [ - { name = "criterion", version = "=0.3.5" } + #"ansi_term@0.11.0", # will be skipped along with _all_ of its direct and transitive dependencies + #{ crate = "ansi_term@0.11.0", depth = 20 }, ] # This section is considered when running `cargo deny check sources`. @@ -207,9 +233,9 @@ allow-registry = ["https://github.com/rust-lang/crates.io-index"] allow-git = [] [sources.allow-org] -# 1 or more github.com organizations to allow git sources for +# github.com organizations to allow git sources for github = [] -# 1 or more gitlab.com organizations to allow git sources for +# gitlab.com organizations to allow git sources for gitlab = [] -# 1 or more bitbucket.org organizations to allow git sources for +# bitbucket.org organizations to allow git sources for bitbucket = [] diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 2eba007d..0df45e7d 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -6,6 +6,62 @@ ### Improve +## 3.2.0 + +### Breaking + +### Improve + +* fix(hangul): revert [#719] — pass keys (layout symbol/number layers such as the sebeolsik shifted right-half) are committed in Hangul mode again instead of being bypassed to the application. Shortcut-modified keys (Ctrl/Alt/Super) have no layout entry and are already passed through by the caller, so the special-case bypass was unnecessary and regressed every Hangul layout. [#754](https://github.com/Riey/kime/issues/754) +* Replace cmake build system with meson + - cargo builds via `custom_target()`, GTK/Qt frontends as `shared_library()` + - Per-component build options (gtk3, gtk4, qt5, qt6, check, indicator, etc.), enabled by default + - `kime` and other binaries build by default when running `ninja` + - `system_engine` mode for building frontends against system-installed engine + - Qt plugin dir override options for nix compatibility +* Remove EOL distro Dockerfiles (ubuntu 18.04~22.10, debian buster) +* Add debian-trixie Dockerfile +* Update release workflow: Qt5/Qt6 multi-version matrix builds, softprops/action-gh-release@v2 +* nix: switch to fetchCargoVendor, parameterize frontend toggles +* Fix mismatched cargoDeps in nix and update attribute syntax **[@nakoo]** +* Updated NixOS configuration example to match updated attribute syntax. +* Remove `kime-engine-cffi` +* fix(wayland input_method_v2): not return unwarp **[@racakenon]** [#715](https://github.com/Riey/kime/715) +* feat(engine): Let default `Alt_R` hotkey accept `Alt` modifier [#719](https://github.com/Riey/kime/719) +* fix(hangul): Don't consume pass keys (numbers, symbols) so app shortcuts like `@`/`#` fire in Hangul mode [#719](https://github.com/Riey/kime/719) +* Add Opensuse Build Service repository and modify README +* fix(xim): handle None from from_hardware_code without panic [#721](https://github.com/Riey/kime/721) +* Update dependencies: + - wayland-client 0.29 → 0.31, wayland-protocols 0.29 → 0.32 + - wayland-protocols-misc 0.3 (신규), xdg 2.5 → 3.0, quick-xml 0.27 → 0.39 + - xkbcommon 0.7 → 0.9, ksni 0.2 → 0.3.3 + tokio + - bitflags 2.10, nix 0.30, strum 0.27 + - x11rb 0.13, xim 0.5, image 0.25, imageproc 0.26 + - mio 1.0 with timerfd-mio, egui/eframe 0.33, itertools 0.14 + - bindgen 0.72.1, cbindgen 0.29.2 + - Replace rusttype with ab_glyph + - Replace ansi_term with owo-colors + - Replace daemonize with nix daemon + - Replace unic with unicode-properties +* Remove unused dependencies: + - Remove zwp-virtual-keyboard (merged into wayland-protocols-misc) +* Fix kime-wayland crash on KDE Plasma 6.5.5 by handling KeyState::Repeated +* Fix indicator tray icon not showing/updating on KDE with tokio async I/O (ksni 0.3.3) +* Rewrite kime-wayland for wayland-rs 0.31 API (Dispatch trait pattern) +* fix(xim): degrade gracefully when the preedit font is missing instead of panicking [#706](https://github.com/Riey/kime/issues/706) +* feat(engine): add `SuperL`/`SuperR` keycodes so Right-Super can be bound as a hotkey [#640](https://github.com/Riey/kime/issues/640) +* fix(hangul): enable `ComposeJongseongSsang` by default for sebeolsik-3sin-p2 (ㄲ 받침) [#646](https://github.com/Riey/kime/issues/646) +* fix(latin): repair the malformed Dvorak layout so it parses and works [#626](https://github.com/Riey/kime/issues/626) +* fix(hangul): Sebeolsik composition bug when typing `v` instead of `/` [#679](https://github.com/Riey/kime/issues/679) +* Qt6 immodule: append `.5.1` suffix to the plugin IID so it builds without `qt5-base` installed (fixes Arch/AUR build) [#732](https://github.com/Riey/kime/issues/732) [#736](https://github.com/Riey/kime/pull/736) +* Add `qt5` dependency to fix the frontend build failure on Arch Linux [#724](https://github.com/Riey/kime/pull/724) +* Release: build Qt6 immodules per-version like Qt5 and add Qt 6.9 / 6.10 to the build matrix [#749](https://github.com/Riey/kime/pull/749) +* Packaging: include gtk4 and qt6 immodules in the `.deb` packages, including ubuntu-22.04 [#734](https://github.com/Riey/kime/issues/734) [#750](https://github.com/Riey/kime/pull/750) +* Build Dockerfiles for Ubuntu 24.04 and Debian Bookworm [#726](https://github.com/Riey/kime/pull/726) +* fix(wayland): prevent text selection deletion on Ctrl/modifier shortcuts [#714](https://github.com/Riey/kime/issues/714) [#718](https://github.com/Riey/kime/pull/718) +* fix(wayland): bypass key events when input is not activated [#745](https://github.com/Riey/kime/pull/745) + + ## 3.1.1 ### Improve @@ -369,7 +425,7 @@ sebeolsik-sin1995 -> sebeolsik-3sin-1995 * Workaround patch with xwayland input focus bug ([#137](https://github.com/Riey/kime/issues/137)) * Handle disabled key repeat properly by **[@simnalamburt]** ([#188](https://github.com/Riey/kime/issues/188)) * Fix unwanted key repeat bug on wayland by **[@simnalamburt]** ([#206](https://github.com/Riey/kime/issues/206)) -* Fix preedit string sended to wrong client by **[@simnalamburt]** ([#205](https://github.com/Riey/kime/issues/205)) +* Fix preedit string sent to wrong client by **[@simnalamburt]** ([#205](https://github.com/Riey/kime/issues/205)) * Fix the key repeat regression by **[@simnalamburt]** ([#215](https://github.com/Riey/kime/issues/215)) * Fix wrong behavior in neovide ([#179](https://github.com/Riey/kime/issues/179)) * Fix xim crash when typing fast ([#170](https://github.com/Riey/kime/issues/170)) @@ -480,3 +536,5 @@ sebeolsik-sin1995 -> sebeolsik-3sin-1995 [@xnuk]: https://github.com/xnuk [@Riey]: https://github.com/Riey [@kpqi5858]: https://github.com/kpqi5858 +[@racakenon]: https://github.com/racakenon +[@strictpvp]: https://github.com/strictpvp/ diff --git a/docs/CONFIGURATION.ko.md b/docs/CONFIGURATION.ko.md index 67bf4115..bea9d46c 100644 --- a/docs/CONFIGURATION.ko.md +++ b/docs/CONFIGURATION.ko.md @@ -210,6 +210,8 @@ all: - ComposeChoseongSsang dubeolsik: - TreatJongseongAsChoseong +sebeolsik-3sin-p2: + - ComposeJongseongSsang ``` #### Addons diff --git a/docs/CONFIGURATION.md b/docs/CONFIGURATION.md index 8f1957d9..24816a59 100644 --- a/docs/CONFIGURATION.md +++ b/docs/CONFIGURATION.md @@ -141,11 +141,25 @@ Set latin setting ### preferred_direct -Handling key event by external as possible +Pass latin key events through to the application directly instead of letting +kime remap them, so the OS/firmware keyboard layout is used as-is. + +| default |`true`| +|---------|------| + +**Note:** when `preferred_direct` is `true` the embedded [`layout`](#layout) +below is **ignored**, because keys are handed to the OS layout untouched. To use +an embedded latin layout such as `Dvorak` or `Colemak`, set +`preferred_direct: false`. (kime maps physical keycodes, so the hangul layout is +unaffected by this setting.) See [#626]. + +[#626]: https://github.com/Riey/kime/issues/626 ### layout -Set latin layout +Set latin layout. + +Only takes effect when [`preferred_direct`](#preferred_direct) is `false`. | default |`Qwerty`| |---------|--------| @@ -211,6 +225,8 @@ all: - ComposeChoseongSsang dubeolsik: - TreatJongseongAsChoseongg +sebeolsik-3sin-p2: + - ComposeJongseongSsang ``` #### Addons diff --git a/flake.lock b/flake.lock index 7d837c01..759ff5dc 100644 --- a/flake.lock +++ b/flake.lock @@ -5,11 +5,11 @@ "systems": "systems" }, "locked": { - "lastModified": 1710146030, - "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", "owner": "numtide", "repo": "flake-utils", - "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", "type": "github" }, "original": { @@ -20,11 +20,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1722335482, - "narHash": "sha256-ogz81JDwIyuX67JC2dZUr3tIPqJABgSKJF9tynZLksQ=", + "lastModified": 1769049916, + "narHash": "sha256-RcsY0BtjUhRuA1SRcqMrVpWC8cQkfCzhVcYdiBzDxNw=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "3563397b2f10ffa1891e1a6ce99d13d960d73acd", + "rev": "47f3deb4bc905ce0de12ba7bd6ad002c132acd02", "type": "github" }, "original": { @@ -33,10 +33,45 @@ "type": "github" } }, + "nixpkgs_2": { + "locked": { + "lastModified": 1744536153, + "narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "18dd725c29603f582cf1900e0d25f9f1063dbf11", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, "root": { "inputs": { "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs" + "nixpkgs": "nixpkgs", + "rust-overlay": "rust-overlay" + } + }, + "rust-overlay": { + "inputs": { + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1769050281, + "narHash": "sha256-1H8DN4UZgEUqPUA5ecHOufLZMscJ4IlcGaEftaPtpBY=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "6deef0585c52d9e70f96b6121207e1496d4b0c49", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" } }, "systems": { diff --git a/flake.nix b/flake.nix index ea6056bc..5f31c5d2 100644 --- a/flake.nix +++ b/flake.nix @@ -3,18 +3,23 @@ inputs = { nixpkgs.url = github:NixOS/nixpkgs; + rust-overlay.url = github:oxalica/rust-overlay; flake-utils.url = github:numtide/flake-utils; }; - outputs = { self, nixpkgs, flake-utils }: + outputs = { self, nixpkgs, rust-overlay, flake-utils }: flake-utils.lib.eachDefaultSystem (system: - let pkgs = import nixpkgs { - system = system; - }; in + let + overlays = [ (import rust-overlay) ]; + pkgs = import nixpkgs { + inherit system overlays; + }; + rustToolchain = pkgs.rust-bin.stable.latest.default; + in { - devShell = import ./shell.nix { inherit pkgs; }; - defaultPackage = import ./default.nix { inherit pkgs; }; + devShells.default = import ./shell.nix { inherit pkgs rustToolchain; }; + packages.default = import ./default.nix { inherit pkgs rustToolchain; }; } ); } diff --git a/meson.build b/meson.build new file mode 100644 index 00000000..a15dc7df --- /dev/null +++ b/meson.build @@ -0,0 +1,174 @@ +project('kime', 'c', 'cpp', + version: files('VERSION'), + meson_version: '>= 1.1', + default_options: [ + 'cpp_std=c++20', + 'buildtype=release', + 'b_ndebug=if-release', + 'c_args=-Wall -fvisibility=hidden', + 'cpp_args=-Wall -fvisibility=hidden', + ], +) + +cargo = find_program('cargo') +cargo_profile = get_option('cargo_profile') + +if cargo_profile == 'release' + cargo_args = ['--release'] + target_dir = meson.project_source_root() / 'target' / 'release' +else + cargo_args = [] + target_dir = meson.project_source_root() / 'target' / 'debug' +endif + +kime_engine_inc = include_directories('src/engine/capi') + +if get_option('system_engine') + message('system_engine mode: skipping cargo build, binary options (check, indicator, etc.) are ignored') + # Use system-installed kime engine + kime_engine_dep = declare_dependency( + include_directories: kime_engine_inc, + link_args: ['-lkime_engine'], + ) +else + # Build engine and binaries from source via cargo + cargo_packages = ['-p', 'kime-engine-capi'] + + if get_option('check').allowed() + cargo_packages += ['-p', 'kime-check'] + endif + if get_option('indicator').allowed() + cargo_packages += ['-p', 'kime-indicator'] + endif + if get_option('candidate_window').allowed() + cargo_packages += ['-p', 'kime-candidate-window'] + endif + if get_option('xim').allowed() + cargo_packages += ['-p', 'kime-xim'] + endif + if get_option('wayland').allowed() + cargo_packages += ['-p', 'kime-wayland'] + endif + # kime main binary is always built when not using system engine + cargo_packages += ['-p', 'kime'] + + cargo_build = custom_target('cargo-build', + command: ['sh', '-c', '"$@" && touch "@OUTPUT@"', '_', + cargo, 'build'] + cargo_args + cargo_packages, + output: 'cargo-build.stamp', + build_always_stale: true, + console: true, + build_by_default: true, + ) + + kime_engine_dep = declare_dependency( + include_directories: kime_engine_inc, + link_args: ['-L' + target_dir, '-lkime_engine'], + sources: cargo_build, + ) + + # Install cargo-built binaries + meson.add_install_script('sh', '-c', + 'install -Dm755 "$1" -t "${DESTDIR}${MESON_INSTALL_PREFIX}/bin"', + '_', target_dir / 'kime', + ) + + if get_option('check').allowed() + meson.add_install_script('sh', '-c', + 'install -Dm755 "$1" -t "${DESTDIR}${MESON_INSTALL_PREFIX}/bin"', + '_', target_dir / 'kime-check', + ) + endif + if get_option('indicator').allowed() + meson.add_install_script('sh', '-c', + 'install -Dm755 "$1" -t "${DESTDIR}${MESON_INSTALL_PREFIX}/bin"', + '_', target_dir / 'kime-indicator', + ) + endif + if get_option('candidate_window').allowed() + meson.add_install_script('sh', '-c', + 'install -Dm755 "$1" -t "${DESTDIR}${MESON_INSTALL_PREFIX}/bin"', + '_', target_dir / 'kime-candidate-window', + ) + endif + if get_option('xim').allowed() + meson.add_install_script('sh', '-c', + 'install -Dm755 "$1" -t "${DESTDIR}${MESON_INSTALL_PREFIX}/bin"', + '_', target_dir / 'kime-xim', + ) + endif + if get_option('wayland').allowed() + meson.add_install_script('sh', '-c', + 'install -Dm755 "$1" -t "${DESTDIR}${MESON_INSTALL_PREFIX}/bin"', + '_', target_dir / 'kime-wayland', + ) + endif + + # Install engine shared library + meson.add_install_script('sh', '-c', + 'install -Dm755 "$1" -t "${DESTDIR}${MESON_INSTALL_PREFIX}/@0@"'.format(get_option('libdir')), + '_', target_dir / 'libkime_engine.so', + ) +endif + +# Install headers +if get_option('install_headers') + meson.add_install_script('sh', '-c', + 'install -Dm644 "$1" -t "${DESTDIR}${MESON_INSTALL_PREFIX}/include"', + '_', meson.project_source_root() / 'src/engine/capi/kime_engine.hpp', + ) + meson.add_install_script('sh', '-c', + 'install -Dm644 "$1" -t "${DESTDIR}${MESON_INSTALL_PREFIX}/include"', + '_', meson.project_source_root() / 'src/engine/capi/kime_engine.h', + ) +endif + +# Install desktop file +install_data('res/kime.desktop', + install_dir: get_option('sysconfdir') / 'xdg' / 'autostart', +) +install_data('res/kime.desktop', + install_dir: get_option('datadir') / 'applications', +) + +# Install autostart helper script +meson.add_install_script('sh', '-c', + 'install -Dm755 "$1" -t "${DESTDIR}${MESON_INSTALL_PREFIX}/bin"', + '_', meson.project_source_root() / 'res' / 'kime-xdg-autostart', +) + +# Install icons +install_data( + 'res/icons/64x64/kime-hangul-black.png', + 'res/icons/64x64/kime-hangul-white.png', + 'res/icons/64x64/kime-latin-black.png', + 'res/icons/64x64/kime-latin-white.png', + install_dir: get_option('datadir') / 'icons' / 'hicolor' / '64x64' / 'apps', +) + +# Install docs +if get_option('install_docs') + install_data( + 'res/default_config.yaml', + 'docs/CHANGELOG.md', + 'LICENSE', + 'NOTICE.md', + 'README.md', + 'README.ko.md', + install_dir: get_option('datadir') / 'doc' / 'kime', + ) +endif + +# Conditional frontend builds +if get_option('gtk3').allowed() + subdir('src/frontends/gtk3') +endif +if get_option('gtk4').allowed() + subdir('src/frontends/gtk4') +endif +if get_option('qt5').allowed() + subdir('src/frontends/qt5') +endif +if get_option('qt6').allowed() + subdir('src/frontends/qt6') +endif diff --git a/meson.options b/meson.options new file mode 100644 index 00000000..f12c06fc --- /dev/null +++ b/meson.options @@ -0,0 +1,19 @@ +option('gtk3', type: 'feature', value: 'auto', description: 'Build GTK3 IM module') +option('gtk4', type: 'feature', value: 'auto', description: 'Build GTK4 IM module') +option('qt5', type: 'feature', value: 'auto', description: 'Build Qt5 IM module') +option('qt6', type: 'feature', value: 'auto', description: 'Build Qt6 IM module') +option('cargo_profile', type: 'combo', choices: ['release', 'debug'], value: 'release', description: 'Cargo build profile') + +option('check', type: 'feature', value: 'auto', description: 'Build kime-check') +option('indicator', type: 'feature', value: 'auto', description: 'Build kime-indicator') +option('candidate_window', type: 'feature', value: 'auto', description: 'Build kime-candidate-window') +option('xim', type: 'feature', value: 'auto', description: 'Build kime-xim') +option('wayland', type: 'feature', value: 'auto', description: 'Build kime-wayland') + +option('install_headers', type: 'boolean', value: true, description: 'Install C/C++ headers') +option('install_docs', type: 'boolean', value: true, description: 'Install documentation') + +option('system_engine', type: 'boolean', value: false, description: 'Use system-installed kime engine instead of building from source') + +option('qt5_plugindir', type: 'string', value: '', description: 'Override Qt5 plugin install directory') +option('qt6_plugindir', type: 'string', value: '', description: 'Override Qt6 plugin install directory') diff --git a/nix/deps.nix b/nix/deps.nix index 4e908238..3116b6a0 100644 --- a/nix/deps.nix +++ b/nix/deps.nix @@ -1,7 +1,6 @@ -{ pkgs }: -with pkgs; +{ pkgs, gtk3 ? true, gtk4 ? true, qt5 ? false, qt6 ? true }: { - kimeBuildInputs = [ + kimeBuildInputs = with pkgs; [ dbus libdbusmenu @@ -9,23 +8,20 @@ with pkgs; libGL wayland libxkbcommon + ] + ++ pkgs.lib.optional gtk3 pkgs.gtk3 + ++ pkgs.lib.optional gtk4 pkgs.gtk4 + ++ pkgs.lib.optional qt5 pkgs.qt5.qtbase + ++ pkgs.lib.optional qt6 pkgs.qt6.qtbase; - gtk3 - gtk4 - - qt5.qtbase - # qt6.qtbase - ]; - - kimeNativeBuildInputs = [ + kimeNativeBuildInputs = with pkgs; [ python3 # xcb 0.9.0 pkg-config llvmPackages_18.clang llvmPackages_18.libclang.lib llvmPackages_18.bintools - rustc cargo - cmake - extra-cmake-modules + meson + ninja ]; } diff --git a/packaging/build-deb.sh b/packaging/build-deb.sh new file mode 100755 index 00000000..2664fc53 --- /dev/null +++ b/packaging/build-deb.sh @@ -0,0 +1,20 @@ +#!/bin/bash +set -e +# Usage: build-deb.sh +BUILD_DIR=${1:?} +OUT_DIR=${2:?} +VER=$(cat VERSION) +ARCH=$(dpkg --print-architecture) +TMP=$(mktemp -d) +trap 'rm -rf "$TMP"' EXIT + +mkdir -p "$TMP/DEBIAN" +sed "s/%VER%/$VER/; s/%ARCH%/$ARCH/" packaging/control.in > "$TMP/DEBIAN/control" + +mkdir -p "$TMP/usr/share/im-config/data" +cp packaging/im_kime.conf "$TMP/usr/share/im-config/data/51_kime.conf" +cp packaging/im_kime.rc "$TMP/usr/share/im-config/data/51_kime.rc" + +DESTDIR="$TMP" meson install -C "$BUILD_DIR" --no-rebuild + +dpkg-deb --root-owner-group --build "$TMP" "$OUT_DIR/kime_${VER}_${ARCH}.deb" diff --git a/scripts/control.in b/packaging/control.in similarity index 100% rename from scripts/control.in rename to packaging/control.in diff --git a/scripts/im_kime.conf b/packaging/im_kime.conf similarity index 99% rename from scripts/im_kime.conf rename to packaging/im_kime.conf index c6a34696..15f4467d 100644 --- a/scripts/im_kime.conf +++ b/packaging/im_kime.conf @@ -8,4 +8,3 @@ package_auto () { package_menu () { package_status kime } - diff --git a/scripts/im_kime.rc b/packaging/im_kime.rc similarity index 81% rename from scripts/im_kime.rc rename to packaging/im_kime.rc index 8d8c3958..08035f4e 100644 --- a/scripts/im_kime.rc +++ b/packaging/im_kime.rc @@ -1,6 +1,5 @@ if [ "$IM_CONFIG_PHASE" = 2 ]; then # start kime daemon - # it failed when other daemon is already running kime || true fi diff --git a/res/default_config.yaml b/res/default_config.yaml index 95be2a25..990cf86d 100644 --- a/res/default_config.yaml +++ b/res/default_config.yaml @@ -36,6 +36,11 @@ engine: - Hangul - Latin result: Consume + M-AltR: + behavior: !Toggle + - Hangul + - Latin + result: Consume Hangul: behavior: !Toggle - Hangul @@ -90,3 +95,5 @@ engine: - ComposeChoseongSsang dubeolsik: - TreatJongseongAsChoseong + sebeolsik-3sin-p2: + - ComposeJongseongSsang diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 00000000..292fe499 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "stable" diff --git a/scripts/build.sh b/scripts/build.sh deleted file mode 100755 index d25a12d2..00000000 --- a/scripts/build.sh +++ /dev/null @@ -1,151 +0,0 @@ -#!/usr/bin/env bash - -source $(dirname $0)/tool.sh - -mkdir -pv $KIME_OUT - -if [ -z "$KIME_MAKE_ARGS" ]; then - KIME_MAKE_ARGS="-j4" -fi - -if [ -z "$KIME_SKIP_ENGINE" ]; then - KIME_SKIP_ENGINE=0 -fi - -if [ -z "$KIME_BUILD_CANDIDATE_WINDOW" ]; then - KIME_BUILD_CANDIDATE_WINDOW=0 -fi - -if [ -z "$KIME_BUILD_CHECK" ]; then - KIME_BUILD_CHECK=0 -fi - -if [ -z "$KIME_BUILD_XIM" ]; then - KIME_BUILD_XIM=0 -fi - -if [ -z "$KIME_BUILD_WAYLAND" ]; then - KIME_BUILD_WAYLAND=0 -fi - -if [ -z "$KIME_BUILD_INDICATOR" ]; then - KIME_BUILD_INDICATOR=0 -fi - -set_release() { - TARGET_DIR=./target/release - _KIME_CARGO_ARGS="--release" - _KIME_CMAKE_ARGS="-DCMAKE_BUILD_TYPE=Release" -} - -set_debug() { - TARGET_DIR=./target/debug - _KIME_CARGO_ARGS="" - _KIME_CMAKE_ARGS="-DCMAKE_BUILD_TYPE=Debug" -} - -cargo_build() { - cargo build $_KIME_CARGO_ARGS $KIME_CARGO_ARGS "$@" -} - -set_release - -while getopts hrda opt; do - case $opt in - h) - echo "build.sh" - echo "Please set KIME_BUILD_{CHECK,INDICATOR,XIM,WAYLAND}, KIME_CMAKE_ARGS or use -a" - echo "-h: help" - echo "-r: release mode(default)" - echo "-d: debug mode" - echo "-a: all modules" - exit 0 - ;; - r) - set_release - ;; - d) - set_debug - ;; - a) - KIME_BUILD_CHECK=1 - KIME_BUILD_CANDIDATE_WINDOW=1 - KIME_BUILD_INDICATOR=1 - KIME_BUILD_WAYLAND=1 - if (pkg-config --exists xcb && pkg-config --exists cairo); then - KIME_BUILD_XIM=1 - fi - KIME_BUILD_KIME=1 - KIME_CMAKE_ARGS="-DENABLE_GTK3=ON -DENABLE_GTK4=ON -DENABLE_QT5=ON -DENABLE_QT6=ON $KIME_CMAKE_ARGS" - ;; - esac -done - -echo Build rust pkgs - -KIME_RUST_PKGS=() - -if [ "$KIME_SKIP_ENGINE" -eq "1" ]; then - _KIME_CMAKE_ARGS="${_KIME_CMAKE_ARGS} -DUSE_SYSTEM_ENGINE=ON" - KIME_BUILD_CHECK=0 - echo Use system engine -else - LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${PWD}/${TARGET_DIR}" - KIME_RUST_PKGS+=("-pkime-engine-capi") -fi - -if [ "$KIME_BUILD_CHECK" -eq "1" ]; then - KIME_RUST_PKGS+=("-pkime-check") -fi - -if [ "$KIME_BUILD_INDICATOR" -eq "1" ]; then - KIME_RUST_PKGS+=("-pkime-indicator") -fi - -if [ "$KIME_BUILD_CANDIDATE_WINDOW" -eq "1" ]; then - KIME_RUST_PKGS+=("-pkime-candidate-window") -fi - -if [ "$KIME_BUILD_XIM" -eq "1" ]; then - KIME_RUST_PKGS+=("-pkime-xim") -fi - -if [ "$KIME_BUILD_WAYLAND" -eq "1" ]; then - KIME_RUST_PKGS+=("-pkime-wayland") -fi - -if [ "$KIME_BUILD_KIME" -eq "1" ]; then - KIME_RUST_PKGS+=("-pkime") -fi - -cargo_build "${KIME_RUST_PKGS[@]}" - -cp $TARGET_DIR/libkime_engine.so $KIME_OUT || true -cp $TARGET_DIR/kime-check $KIME_OUT || true -cp $TARGET_DIR/kime-candidate-window $KIME_OUT || true -cp $TARGET_DIR/kime-indicator $KIME_OUT || true -cp $TARGET_DIR/kime-xim $KIME_OUT || true -cp $TARGET_DIR/kime-wayland $KIME_OUT || true -cp $TARGET_DIR/kime $KIME_OUT || true - -cp src/engine/cffi/kime_engine.h $KIME_OUT -cp src/engine/cffi/kime_engine.hpp $KIME_OUT -cp docs/CHANGELOG.md $KIME_OUT -cp LICENSE $KIME_OUT -cp NOTICE.md $KIME_OUT -cp README.md $KIME_OUT -cp README.ko.md $KIME_OUT -cp -R res/* $KIME_OUT - -mkdir -pv build/cmake - -echo Build gtk qt immodules... - -cd build/cmake - -cmake ../../src $_KIME_CMAKE_ARGS $KIME_CMAKE_ARGS - -make $KIME_MAKE_ARGS - -cp lib/* $KIME_OUT || true - diff --git a/scripts/generate_properties.sh b/scripts/generate_properties.sh deleted file mode 100755 index fab8ae95..00000000 --- a/scripts/generate_properties.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -source $(dirname $0)/tool.sh - -cargo run -p properties_writer > .vscode/c_cpp_properties.json diff --git a/scripts/install.sh b/scripts/install.sh deleted file mode 100755 index ef68352d..00000000 --- a/scripts/install.sh +++ /dev/null @@ -1,110 +0,0 @@ -#!/usr/bin/env bash - -source $(dirname $0)/tool.sh - -if [ -z "$1" ]; then - echo "Usage: " - exit 1 -fi - -if [ -z "$KIME_INSTALL_HEADER" ]; then - KIME_INSTALL_HEADER=0 -fi - -if [ -z "$KIME_INSTALL_DOC" ]; then - KIME_INSTALL_DOC=1 -fi - -PREFIX=$1 - -if [ -z "$KIME_BIN_DIR" ]; then - KIME_BIN_DIR=usr/bin -fi - -if [ -z "$KIME_INCLUDE_DIR" ]; then - KIME_INCLUDE_DIR=usr/include -fi - -if [ -z "$KIME_DOC_DIR" ]; then - KIME_DOC_DIR=usr/share/doc/kime -fi - -if [ -z "$KIME_ICON_DIR" ]; then - KIME_ICON_DIR=usr/share/icons -fi - -if [ -z "$KIME_AUTOSTART_DIR" ]; then - KIME_AUTOSTART_DIR=etc/xdg/autostart -fi - -if [ -z "$KIME_DESKTOP_ENTRY_DIR" ]; then - KIME_DESKTOP_ENTRY_DIR=usr/share/applications -fi - -if [ -z "$KIME_LIB_DIR" ]; then - KIME_LIB_DIR=usr/lib -fi - -if [ -z "$KIME_GTK3_DIR" ]; then - KIME_GTK3_DIR="$KIME_LIB_DIR/gtk-3.0/3.0.0/immodules" -fi - -if [ -z "$KIME_GTK4_DIR" ]; then - KIME_GTK4_DIR="$KIME_LIB_DIR/gtk-4.0/4.0.0/immodules" -fi - -if [ -z "$KIME_QT5_DIR" ]; then - KIME_QT5_DIR="$KIME_LIB_DIR/qt" -fi - -if [ -z "$KIME_QT6_DIR" ]; then - KIME_QT6_DIR="$KIME_LIB_DIR/qt6" -fi - -install_if () { - if [ -f $KIME_OUT/$1 ]; then - install -Dm$2 $KIME_OUT/$1 $3 "$PREFIX/$4" - else - echo "SKIP $1" - fi -} - -install_bin () { - install_if $1 755 -t "$KIME_BIN_DIR" -} - -install_doc () { - install -Dm644 $KIME_OUT/$1 -t "$PREFIX/$KIME_DOC_DIR" -} - -install_bin kime-check -install_bin kime-indicator -install_bin kime-candidate-window -install_bin kime-xim -install_bin kime-wayland -install_bin kime - -if [ "${KIME_INSTALL_HEADER}" -eq "1" ]; then - install -Dm644 $KIME_OUT/kime_engine.h -t "$PREFIX/$KIME_INCLUDE_DIR" - install -Dm644 $KIME_OUT/kime_engine.hpp -t "$PREFIX/$KIME_INCLUDE_DIR" -fi - -if [ "${KIME_INSTALL_DOC}" -eq "1" ]; then - install_doc default_config.yaml - install_doc LICENSE - install_doc NOTICE.md - install_doc README.md - install_doc README.ko.md - install_doc CHANGELOG.md -fi - -install -Dm644 $KIME_OUT/*.desktop -t "$PREFIX/$KIME_AUTOSTART_DIR" -install -Dm644 $KIME_OUT/*.desktop -t "$PREFIX/$KIME_DESKTOP_ENTRY_DIR" -install -Dm755 $KIME_OUT/kime-xdg-autostart -t "$PREFIX/$KIME_BIN_DIR" -install -Dm644 $KIME_OUT/icons/64x64/*.png -t "$PREFIX/$KIME_ICON_DIR/hicolor/64x64/apps" -install -Dm755 $KIME_OUT/libkime_engine.so -t "$PREFIX/$KIME_LIB_DIR" - -install_if libkime-gtk3.so 755 -T "$KIME_GTK3_DIR/im-kime.so" -install_if libkime-gtk4.so 755 -t "$KIME_GTK4_DIR" -install_if libkime-qt5.so 755 -T "$KIME_QT5_DIR/plugins/platforminputcontexts/libkimeplatforminputcontextplugin.so" -install_if libkime-qt6.so 755 -T "$KIME_QT6_DIR/plugins/platforminputcontexts/libkimeplatforminputcontextplugin.so" diff --git a/scripts/release-deb.sh b/scripts/release-deb.sh deleted file mode 100755 index e68e7f6f..00000000 --- a/scripts/release-deb.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env bash - -KIME_PREFIX=51_kime - -source $(dirname $0)/tool.sh - -if [ -z "$1" ]; then - echo "Usage: " - exit 1 -fi - -TARGET_PATH=$1 -TMP_PATH=$(mktemp -d) -ARCH=$(dpkg --print-architecture) -VER=$(cat ./VERSION) - -mkdir -pv $TMP_PATH/DEBIAN -mkdir -pv $TMP_PATH/usr/share/im-config/data - -cat scripts/control.in | sed "s/%VER%/$VER/; s/%ARCH%/$ARCH/" > $TMP_PATH/DEBIAN/control -cp scripts/im_kime.rc $TMP_PATH/usr/share/im-config/data/$KIME_PREFIX.rc -cp scripts/im_kime.conf $TMP_PATH/usr/share/im-config/data/$KIME_PREFIX.conf - -KIME_INSTALL_HEADER=0 \ -KIME_LIB_DIR=usr/lib/x86_64-linux-gnu \ -KIME_QT5_DIR=usr/lib/x86_64-linux-gnu/qt5 \ -KIME_QT6_DIR=usr/lib/x86_64-linux-gnu/qt6 \ -scripts/install.sh $TMP_PATH - -dpkg-deb --root-owner-group --build $TMP_PATH "${TARGET_PATH}/kime_$ARCH.deb" diff --git a/scripts/release-zst.sh b/scripts/release-zst.sh deleted file mode 100755 index 91a9fd83..00000000 --- a/scripts/release-zst.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bash - -source $(dirname $0)/tool.sh - -if [ -z "$1" ]; then - echo "Usage: " - exit 1 -fi - -tar -cvf - -C $KIME_OUT . | zstd -T0 -15 -o "${1}/kime.tar.zst" diff --git a/scripts/tool.sh b/scripts/tool.sh deleted file mode 100755 index 7b50d44c..00000000 --- a/scripts/tool.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -set -e - -cd $(readlink -f $(dirname $0))/.. - -KIME_OUT=$PWD/build/out - diff --git a/shell.nix b/shell.nix index 167ed73a..30bb8bbc 100644 --- a/shell.nix +++ b/shell.nix @@ -1,22 +1,25 @@ { - pkgs ? import { }, + pkgs ? import {}, + rustToolchain ? pkgs.rustc, + gtk3 ? true, + gtk4 ? true, + qt5 ? false, + qt6 ? true, }: let - deps = import ./nix/deps.nix { pkgs = pkgs; }; + deps = import ./nix/deps.nix { inherit pkgs gtk3 gtk4 qt5 qt6; }; stdenv = pkgs.llvmPackages_18.stdenv; - mkShell = (pkgs.mkShell.override { stdenv = stdenv; }); + mkShell = (pkgs.mkShell.override { inherit stdenv; }); in mkShell { name = "kime-shell"; - dontUseCmakeConfigure = true; dontWrapQtApps = true; buildInputs = deps.kimeBuildInputs; - nativeBuildInputs = deps.kimeNativeBuildInputs ++ (with pkgs; [ - rustfmt + nativeBuildInputs = deps.kimeNativeBuildInputs ++ [ + rustToolchain pkgs.gedit - llvmPackages_18.lldb - ]); - CMAKE_EXPORT_COMPILE_COMMANDS = 1; + pkgs.llvmPackages_18.lldb + ]; LIBCLANG_PATH = "${pkgs.llvmPackages_18.libclang.lib}/lib"; LD_LIBRARY_PATH = "./target/debug:${pkgs.wayland}/lib:${pkgs.libGL}/lib:${pkgs.libxkbcommon}/lib"; G_MESSAGES_DEBUG = "kime"; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt deleted file mode 100644 index 317c6e27..00000000 --- a/src/CMakeLists.txt +++ /dev/null @@ -1,41 +0,0 @@ -cmake_minimum_required(VERSION 3.13.0) - -project(kime VERSION 2.0.0) - -option(USE_SYSTEM_ENGINE "Use system engine file" OFF) -option(ENABLE_GTK3 "Enable GTK3 immodule" OFF) -option(ENABLE_GTK4 "Enable GTK4 immodule" OFF) -option(ENABLE_QT5 "Enable Qt5 immodule" OFF) -option(ENABLE_QT6 "Enable Qt6 immodule" OFF) - -set(CMAKE_SKIP_RPATH TRUE) -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -fvisibility=hidden") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fvisibility=hidden") -set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DDEBUG") -set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG") -set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) -set(KIME_INCLUDE ${CMAKE_CURRENT_SOURCE_DIR}/engine/cffi) -if(${USE_SYSTEM_ENGINE}) - set(KIME_LIB_DIRS "") -else() - set(KIME_LIB_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../target/debug ${CMAKE_CURRENT_SOURCE_DIR}/../target/release) -endif() -set(KIME_ENGINE kime_engine) -set(OpenGL_GL_PREFERENCE GLVND) - -include(GNUInstallDirs) - -if(${ENABLE_GTK3}) - add_subdirectory(frontends/gtk3) -endif() -if(${ENABLE_GTK4}) - add_subdirectory(frontends/gtk4) -endif() - -if(${ENABLE_QT5}) - add_subdirectory(frontends/qt5) -endif() -if(${ENABLE_QT6}) - add_subdirectory(frontends/qt6) -endif() diff --git a/src/engine/backend/Cargo.toml b/src/engine/backend/Cargo.toml index c14f4e4e..3b9ba3f4 100644 --- a/src/engine/backend/Cargo.toml +++ b/src/engine/backend/Cargo.toml @@ -6,8 +6,8 @@ edition = "2021" license = "GPL-3.0-or-later" [dependencies] -bitflags = "1.2.1" +bitflags = "2.10" enum-map = "2" -enumset = { version = "1", features = ["serde"] } +enumset = { version = "1.1", features = ["serde"] } serde = { version = "1", features = ["derive"] } -strum = { version = "0.24", features = ["derive"] } +strum = { version = "0.27", features = ["derive"] } diff --git a/src/engine/backend/src/input_result.rs b/src/engine/backend/src/input_result.rs index ac0d3cb8..fa0b85ca 100644 --- a/src/engine/backend/src/input_result.rs +++ b/src/engine/backend/src/input_result.rs @@ -1,4 +1,5 @@ bitflags::bitflags! { + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] #[repr(transparent)] pub struct InputResult: u32 { const CONSUMED = 0b1; diff --git a/src/engine/backend/src/keycode.rs b/src/engine/backend/src/keycode.rs index f58788c6..96905c10 100644 --- a/src/engine/backend/src/keycode.rs +++ b/src/engine/backend/src/keycode.rs @@ -8,6 +8,7 @@ use serde::{ use strum::{Display, EnumString}; bitflags::bitflags! { + #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] pub struct ModifierState: u32 { const SHIFT = 0x1; @@ -123,6 +124,8 @@ pub enum KeyCode { Henkan, AltL, AltR, + SuperL, + SuperR, Hangul, HangulHanja, @@ -229,6 +232,8 @@ impl KeyCode { 102 => Some(Self::Muhenkan), 64 => Some(Self::AltL), 108 => Some(Self::AltR), + 133 => Some(Self::SuperL), + 134 => Some(Self::SuperR), 122 | 130 => Some(Self::Hangul), 121 | 123 | 131 => Some(Self::HangulHanja), @@ -379,3 +384,26 @@ fn key_parse() { assert_eq!("C-Space".parse::().unwrap(), Key::ctrl(KeyCode::Space)); assert_eq!("M-X".parse::().unwrap(), Key::alt(KeyCode::X)); } + +#[test] +fn super_keys() { + // X11 hardware keycodes for Super_L (133) / Super_R (134), + // e.g. Apple right-command, so they can be bound as a category toggle. + assert_eq!( + KeyCode::from_hardware_code(133, false), + Some(KeyCode::SuperL) + ); + assert_eq!( + KeyCode::from_hardware_code(134, false), + Some(KeyCode::SuperR) + ); + + // The variants must round-trip through their string form so they can be + // written in the config like the existing AltR toggle. + assert_eq!("SuperL".parse::().unwrap(), KeyCode::SuperL); + assert_eq!("SuperR".parse::().unwrap(), KeyCode::SuperR); + assert_eq!( + "SuperR".parse::().unwrap(), + Key::normal(KeyCode::SuperR) + ); +} diff --git a/src/engine/backends/hangul/Cargo.toml b/src/engine/backends/hangul/Cargo.toml index 9abe8a11..820ec0cf 100644 --- a/src/engine/backends/hangul/Cargo.toml +++ b/src/engine/backends/hangul/Cargo.toml @@ -7,11 +7,11 @@ license = "GPL-3.0-or-later" [dependencies] kime-engine-backend = { path = "../../backend" } -enumset = "1.0.6" -num-derive = "0.3.3" -num-traits = "0.2.14" -serde = { version = "1.0.124", features = ["derive"] } +enumset = "1.1" +num-derive = "0.4" +num-traits = "0.2" +serde = { version = "1.0", features = ["derive"] } serde_yaml = "0.9" [target.'cfg(unix)'.dependencies] -xdg = "2.2.0" +xdg = "3.0" diff --git a/src/engine/backends/hangul/data/sebeolsik-3-90.yaml b/src/engine/backends/hangul/data/sebeolsik-3-90.yaml index 87388c0c..3592ea50 100644 --- a/src/engine/backends/hangul/data/sebeolsik-3-90.yaml +++ b/src/engine/backends/hangul/data/sebeolsik-3-90.yaml @@ -35,8 +35,8 @@ D: $ㅣ F: $ㅏ G: ㅡ C: $ㅔ -V: $ㅗ -B: $ㅜ +V: ㅗ +B: ㅜ 0: ㅋ Y: ㄹ diff --git a/src/engine/backends/hangul/data/sebeolsik-3-91.yaml b/src/engine/backends/hangul/data/sebeolsik-3-91.yaml index daced086..8d4250b7 100644 --- a/src/engine/backends/hangul/data/sebeolsik-3-91.yaml +++ b/src/engine/backends/hangul/data/sebeolsik-3-91.yaml @@ -41,8 +41,8 @@ F: $ㅏ G: ㅡ S-G: $ㅒ C: $ㅔ -V: $ㅗ -B: $ㅜ +V: ㅗ +B: ㅜ 0: ㅋ Y: ㄹ diff --git a/src/engine/backends/hangul/src/lib.rs b/src/engine/backends/hangul/src/lib.rs index c4745f79..1555aece 100644 --- a/src/engine/backends/hangul/src/lib.rs +++ b/src/engine/backends/hangul/src/lib.rs @@ -65,6 +65,10 @@ impl Default for HangulConfig { addons: vec![ ("all".into(), Addon::ComposeChoseongSsang.into()), ("dubeolsik".into(), Addon::TreatJongseongAsChoseong.into()), + ( + "sebeolsik-3sin-p2".into(), + Addon::ComposeJongseongSsang.into(), + ), ] .into_iter() .collect(), diff --git a/src/engine/backends/hangul/src/state.rs b/src/engine/backends/hangul/src/state.rs index 93db1a5d..ed7c678c 100644 --- a/src/engine/backends/hangul/src/state.rs +++ b/src/engine/backends/hangul/src/state.rs @@ -73,6 +73,14 @@ impl HangulEngine { pub fn key(&mut self, kv: KeyValue, addons: EnumSet, commit_buf: &mut String) -> bool { let ret = match kv { KeyValue::Pass(pass) => { + // A pass key is a literal character defined by the layout (e.g. + // the sebeolsik number/symbol layer). Commit any pending + // composition, then emit the literal (issue #754). + // + // Keys carrying a shortcut modifier (Ctrl/Alt/Super) never reach + // here: the layout only has plain/Shift entries, so the lookup + // misses and the caller passes the key through to the + // application — which is where shortcut handling belongs. self.clear_preedit(commit_buf); commit_buf.push(pass); return true; @@ -534,6 +542,28 @@ mod tests { ); } + // issue #754: a pass key (layout literal) commits its character in Hangul mode. + #[test] + fn pass_key() { + let mut engine = HangulEngine::new(false, PreeditJohabLevel::Needed); + let mut commit = String::new(); + + // compose ㄱ + assert!(engine.key( + KeyValue::Choseong { + cho: Choseong::Giyeok + }, + EnumSet::empty(), + &mut commit + )); + assert!(engine.has_preedit()); + + // a pass key commits the pending preedit and then its own literal + assert!(engine.key(KeyValue::Pass('@'), EnumSet::empty(), &mut commit)); + assert_eq!(commit, "ㄱ@"); + assert!(!engine.has_preedit()); + } + #[test] fn filler() { let state = CharacterState { diff --git a/src/engine/backends/latin/Cargo.toml b/src/engine/backends/latin/Cargo.toml index e1e25039..0d0b40e0 100644 --- a/src/engine/backends/latin/Cargo.toml +++ b/src/engine/backends/latin/Cargo.toml @@ -9,3 +9,4 @@ license = "GPL-3.0-or-later" kime-engine-backend = { path = "../../backend" } serde = { version = "1.0.124", features = ["derive"] } serde_yaml = "0.9" +log = "0.4" diff --git a/src/engine/backends/latin/data/dvorak.yaml b/src/engine/backends/latin/data/dvorak.yaml index 4b9aed61..dbcfedc1 100644 --- a/src/engine/backends/latin/data/dvorak.yaml +++ b/src/engine/backends/latin/data/dvorak.yaml @@ -1,9 +1,9 @@ Q: "'" S-Q: '"' -W: \, -S-W: \< -E: \. -S-E: \> +W: ',' +S-W: '<' +E: '.' +S-E: '>' R: p S-R: P T: y @@ -37,7 +37,7 @@ S-K: T L: n S-L: N Z: ':' -S-Z: \; +S-Z: ';' X: q S-X: Q C: j diff --git a/src/engine/backends/latin/src/lib.rs b/src/engine/backends/latin/src/lib.rs index aea8bf73..d87aee4a 100644 --- a/src/engine/backends/latin/src/lib.rs +++ b/src/engine/backends/latin/src/lib.rs @@ -30,12 +30,33 @@ impl Default for LatinConfig { } } +impl LatinConfig { + /// Returns `true` when the configured `layout` has no effect. + /// + /// With `preferred_direct` enabled kime passes key events through to the + /// OS/firmware layout instead of applying the embedded latin layout, so a + /// non-`Qwerty` `layout` (e.g. `Dvorak`, `Colemak`) is silently ignored. + /// `Qwerty` is excluded because its mapping matches a plain pass-through. + /// See . + pub fn layout_ignored(&self) -> bool { + self.preferred_direct && !matches!(self.layout, LatinLayout::Qwerty) + } +} + pub struct LatinData { keymap: KeyMap, } impl LatinData { pub fn new(config: &LatinConfig) -> Self { + if config.layout_ignored() { + log::warn!( + "latin.layout is set to a non-Qwerty layout but latin.preferred_direct is true, \ + so the layout is ignored and key events are passed through to the OS layout. \ + Set latin.preferred_direct to false to use the embedded latin layout." + ); + } + Self { keymap: load_layout(config), } @@ -92,3 +113,104 @@ impl InputEngineBackend for LatinEngine { fn preedit_str(&self, _buf: &mut String) {} } + +#[cfg(test)] +mod tests { + use super::*; + use kime_engine_backend::KeyCode; + + #[test] + fn embedded_dvorak_layout_is_loaded() { + // The embedded Dvorak layout remaps the physical `Q` key to `'`. + let data = LatinData::new(&LatinConfig { + layout: LatinLayout::Dvorak, + preferred_direct: false, + }); + assert_eq!(data.lookup(Key::normal(KeyCode::Q)), Some('\'')); + // Regression guard: these keys used invalid YAML backslash escapes + // (`\,`, `\<`, `\.`, `\>`, `\;`) which made the whole layout fail to + // parse and silently fall back to an empty keymap (#626). + assert_eq!(data.lookup(Key::normal(KeyCode::W)), Some(',')); + assert_eq!(data.lookup(Key::shift(KeyCode::W)), Some('<')); + assert_eq!(data.lookup(Key::normal(KeyCode::E)), Some('.')); + assert_eq!(data.lookup(Key::shift(KeyCode::E)), Some('>')); + assert_eq!(data.lookup(Key::shift(KeyCode::Z)), Some(';')); + // And an ordinary letter mapping still works. + assert_eq!(data.lookup(Key::normal(KeyCode::K)), Some('t')); + } + + #[test] + fn embedded_layouts_parse_completely() { + // A malformed entry makes serde fall back to an empty map via + // `unwrap_or_default()`, so a full keymap proves the file parsed. + for layout in [ + LatinLayout::Qwerty, + LatinLayout::Dvorak, + LatinLayout::Colemak, + ] { + let data = LatinData::new(&LatinConfig { + layout, + preferred_direct: false, + }); + assert!( + data.lookup(Key::normal(KeyCode::A)).is_some() + && data.lookup(Key::normal(KeyCode::Backslash)).is_some(), + "embedded layout failed to parse and fell back to empty keymap", + ); + } + } + + #[test] + fn layout_ignored_detects_conflicting_config() { + // Non-Qwerty layout + preferred_direct => layout silently ignored (#626). + assert!(LatinConfig { + layout: LatinLayout::Dvorak, + preferred_direct: true, + } + .layout_ignored()); + assert!(LatinConfig { + layout: LatinLayout::Colemak, + preferred_direct: true, + } + .layout_ignored()); + + // Qwerty + preferred_direct is fine: pass-through yields the same chars. + assert!(!LatinConfig { + layout: LatinLayout::Qwerty, + preferred_direct: true, + } + .layout_ignored()); + + // Non-Qwerty without preferred_direct actually applies the layout. + assert!(!LatinConfig { + layout: LatinLayout::Dvorak, + preferred_direct: false, + } + .layout_ignored()); + + // The default config (Qwerty + preferred_direct) must never warn. + assert!(!LatinConfig::default().layout_ignored()); + } + + #[test] + fn preferred_direct_bypasses_dvorak_layout() { + // Reproduces #626: with preferred_direct the Dvorak mapping never applies; + // the key is not consumed and nothing is committed. + let data = LatinData::new(&LatinConfig { + layout: LatinLayout::Dvorak, + preferred_direct: true, + }); + let mut engine = LatinEngine::new(true); + let mut buf = String::new(); + let consumed = engine.press_key(&data, Key::normal(KeyCode::Q), &mut buf); + assert!(!consumed); + assert!(buf.is_empty()); + + // Without preferred_direct the same key commits the Dvorak char. + let mut engine = LatinEngine::new(false); + let mut buf = String::new(); + let consumed = engine.press_key(&data, Key::normal(KeyCode::Q), &mut buf); + assert!(consumed); + assert_eq!(buf, "'"); + } +} diff --git a/src/engine/candidate/Cargo.toml b/src/engine/candidate/Cargo.toml index 560f5424..1c8169b0 100644 --- a/src/engine/candidate/Cargo.toml +++ b/src/engine/candidate/Cargo.toml @@ -9,4 +9,4 @@ license = "GPL-3.0-or-later" kime-engine-dict = { path = "../dict" } [dependencies] -nix = "0.26.1" +nix = { version = "0.30", features = ["poll"] } diff --git a/src/engine/candidate/src/client.rs b/src/engine/candidate/src/client.rs index c72e931f..665221e6 100644 --- a/src/engine/candidate/src/client.rs +++ b/src/engine/candidate/src/client.rs @@ -1,14 +1,13 @@ -use nix::poll; +use nix::poll::{self, PollFd, PollFlags, PollTimeout}; use std::fmt; use std::io::{self, BufWriter, Write}; -use std::os::unix::io::{AsRawFd, RawFd}; +use std::os::unix::io::{AsFd, BorrowedFd}; use std::process::{Child, Stdio}; pub const CANDIDATE_PROCESS_NAME: &str = "kime-candidate-window"; pub struct Client { child: Child, - stdout_fd: RawFd, } impl Client { @@ -32,14 +31,13 @@ impl Client { drop(stdin); - let stdout_fd = child.stdout.as_ref().unwrap().as_raw_fd(); - - Ok(Self { stdout_fd, child }) + Ok(Self { child }) } pub fn is_ready(&self) -> bool { - let fds = &mut [poll::PollFd::new(self.stdout_fd, poll::PollFlags::POLLIN)]; - poll::poll(fds, 200) == Ok(1) + let stdout: BorrowedFd = self.child.stdout.as_ref().unwrap().as_fd(); + let fds = &mut [PollFd::new(stdout, PollFlags::POLLIN)]; + poll::poll(fds, PollTimeout::from(200u16)) == Ok(1) } pub fn close(mut self) -> io::Result> { diff --git a/src/engine/capi/Cargo.toml b/src/engine/capi/Cargo.toml index 9f625bec..ce0649c4 100644 --- a/src/engine/capi/Cargo.toml +++ b/src/engine/capi/Cargo.toml @@ -12,3 +12,7 @@ crate-type = ["cdylib"] [dependencies] kime-engine-core = { path = "../core" } + +[build-dependencies] +bindgen = { version = "0.72.1", default-features = false } +cbindgen = { version = "0.29.2", default-features = false } diff --git a/src/engine/cffi/build.rs b/src/engine/capi/build.rs similarity index 52% rename from src/engine/cffi/build.rs rename to src/engine/capi/build.rs index d34bdb79..9162b56c 100644 --- a/src/engine/cffi/build.rs +++ b/src/engine/capi/build.rs @@ -1,5 +1,3 @@ -use std::env; - fn main() { println!("cargo:rerun-if-changed=./kime_engine.h"); println!("cargo:rerun-if-changed=./kime_engine.hpp"); @@ -20,20 +18,4 @@ fn main() { .unwrap(); cpp_binding.write_to_file("kime_engine.hpp"); - - let rust_binding = bindgen::builder() - .layout_tests(false) - .header("./kime_engine.hpp") - .disable_name_namespacing() - .rustified_enum("kime::.+") - .allowlist_var("kime::.+") - .allowlist_type("kime::.+") - .allowlist_function("kime::.+") - .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) - .generate() - .unwrap(); - - rust_binding - .write_to_file(std::path::PathBuf::from(env::var("OUT_DIR").unwrap()).join("bindings.rs")) - .unwrap(); } diff --git a/src/engine/capi/src/lib.rs b/src/engine/capi/src/lib.rs index b528d103..81aec88b 100644 --- a/src/engine/capi/src/lib.rs +++ b/src/engine/capi/src/lib.rs @@ -1,9 +1,10 @@ #![allow(clippy::missing_safety_doc)] +use kime_engine_core::{load_engine_config_from_config_dir, load_raw_config_from_config_dir}; + pub use kime_engine_core::{ - load_engine_config_from_config_dir, load_other_configs_from_config_dir, Config, DaemonConfig, - DaemonModule, IconColor, IndicatorConfig, InputCategory, InputEngine, InputResult, LogConfig, - ModifierState, + Config, DaemonConfig, DaemonModule, IconColor, IndicatorConfig, InputCategory, InputEngine, + InputResult, LogConfig, ModifierState, }; pub const KIME_API_VERSION: usize = 7; @@ -204,10 +205,7 @@ pub extern "C" fn kime_config_xim_preedit_font(config: &Config) -> FontData { #[cfg(unix)] #[no_mangle] pub extern "C" fn kime_daemon_config_load() -> *mut DaemonConfig { - let config = load_other_configs_from_config_dir() - .map(|c| c.0) - .unwrap_or_default(); - Box::into_raw(Box::new(config)) + Box::into_raw(Box::new(load_raw_config_from_config_dir().daemon)) } /// Get daemon `modules` @@ -233,10 +231,7 @@ pub unsafe extern "C" fn kime_daemon_config_delete(config: *mut DaemonConfig) { #[cfg(unix)] #[no_mangle] pub extern "C" fn kime_indicator_config_load() -> *mut IndicatorConfig { - let config = load_other_configs_from_config_dir() - .map(|c| c.1) - .unwrap_or_default(); - Box::into_raw(Box::new(config)) + Box::into_raw(Box::new(load_raw_config_from_config_dir().indicator)) } /// Get default indicator config @@ -262,10 +257,7 @@ pub extern "C" fn kime_indicator_config_icon_color(config: &IndicatorConfig) -> #[cfg(unix)] #[no_mangle] pub extern "C" fn kime_log_config_load() -> *mut LogConfig { - let config = load_other_configs_from_config_dir() - .map(|c| c.2) - .unwrap_or_default(); - Box::into_raw(Box::new(config)) + Box::into_raw(Box::new(load_raw_config_from_config_dir().log)) } /// Get default log config diff --git a/src/engine/cffi/Cargo.toml b/src/engine/cffi/Cargo.toml deleted file mode 100644 index 825c71df..00000000 --- a/src/engine/cffi/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "kime-engine-cffi" -version = "0.8.1" -authors = ["Riey "] -edition = "2021" -license = "GPL-3.0-or-later" - -[dependencies] -kime-engine-capi = { path = "../capi" } -kime-engine-config = { path = "../config" } - -[build-dependencies] -bindgen = { version = "0.69.4", default-features = false } -cbindgen = { version = "0.26.0", default-features = false } diff --git a/src/engine/cffi/src/lib.rs b/src/engine/cffi/src/lib.rs deleted file mode 100644 index 233023ed..00000000 --- a/src/engine/cffi/src/lib.rs +++ /dev/null @@ -1,263 +0,0 @@ -#[allow(dead_code)] -#[allow(non_camel_case_types)] -#[allow(non_snake_case)] -#[allow(non_upper_case_globals)] -mod ffi { - include!(concat!(env!("OUT_DIR"), "/bindings.rs")); -} - -#[link(name = "kime_engine", kind = "dylib")] -extern "C" {} - -pub use kime_engine_config::{DaemonModule, EnumSet}; - -pub use ffi::{ - IconColor, InputCategory, InputResult, InputResult_CONSUMED, InputResult_HAS_COMMIT, - InputResult_HAS_PREEDIT, InputResult_LANGUAGE_CHANGED, InputResult_NOT_READY, ModifierState, - ModifierState_ALT, ModifierState_CONTROL, ModifierState_SHIFT, ModifierState_SUPER, - KIME_API_VERSION, -}; - -pub fn check_api_version() -> bool { - unsafe { ffi::kime_api_version() == ffi::KIME_API_VERSION } -} - -pub struct InputEngine { - engine: *mut ffi::InputEngine, -} - -impl InputEngine { - pub fn new(config: &Config) -> Self { - Self { - engine: unsafe { ffi::kime_engine_new(config.config) }, - } - } - - pub fn update_layout_state(&self) { - unsafe { ffi::kime_engine_update_layout_state(self.engine) } - } - - pub fn end_ready(&mut self) -> InputResult { - unsafe { ffi::kime_engine_end_ready(self.engine) } - } - - pub fn check_ready(&self) -> bool { - unsafe { ffi::kime_engine_check_ready(self.engine) } - } - - pub fn set_input_category(&mut self, category: InputCategory) { - unsafe { ffi::kime_engine_set_input_category(self.engine, category) }; - } - - pub fn press_key( - &mut self, - config: &Config, - hardware_code: u16, - numlock: bool, - state: ModifierState, - ) -> InputResult { - unsafe { - ffi::kime_engine_press_key(self.engine, config.config, hardware_code, numlock, state) - } - } - - pub fn preedit_str(&mut self) -> &str { - unsafe { - let s = ffi::kime_engine_preedit_str(self.engine); - core::str::from_utf8_unchecked(core::slice::from_raw_parts(s.ptr, s.len)) - } - } - - pub fn commit_str(&self) -> &str { - unsafe { - let s = ffi::kime_engine_commit_str(self.engine); - core::str::from_utf8_unchecked(core::slice::from_raw_parts(s.ptr, s.len)) - } - } - - pub fn clear_commit(&mut self) { - unsafe { - ffi::kime_engine_clear_commit(self.engine); - } - } - - pub fn clear_preedit(&mut self) { - unsafe { - ffi::kime_engine_clear_preedit(self.engine); - } - } - - pub fn remove_preedit(&mut self) { - unsafe { - ffi::kime_engine_remove_preedit(self.engine); - } - } - - pub fn reset(&mut self) { - unsafe { - ffi::kime_engine_reset(self.engine); - } - } -} - -impl Drop for InputEngine { - fn drop(&mut self) { - unsafe { - ffi::kime_engine_delete(self.engine); - } - } -} - -pub struct Config { - config: *mut ffi::Config, -} - -impl Default for Config { - fn default() -> Self { - Self { - config: unsafe { ffi::kime_config_default() }, - } - } -} - -impl Config { - #[cfg(unix)] - pub fn load() -> Self { - Self { - config: unsafe { ffi::kime_config_load() }, - } - } - - pub fn candidate_font(&self) -> (&[u8], u32) { - unsafe { - let font = ffi::kime_config_candidate_font(self.config); - - ( - core::slice::from_raw_parts(font.font_data.ptr, font.font_data.len), - font.index, - ) - } - } - - pub fn xim_font(&self) -> (&[u8], u32, f32) { - unsafe { - let font = ffi::kime_config_xim_preedit_font(self.config); - - ( - core::slice::from_raw_parts(font.font_data.ptr, font.font_data.len), - font.index, - font.size, - ) - } - } -} - -impl Drop for Config { - fn drop(&mut self) { - unsafe { - ffi::kime_config_delete(self.config); - } - } -} - -pub struct DaemonConfig { - config: *mut ffi::DaemonConfig, -} - -impl DaemonConfig { - #[cfg(unix)] - pub fn load() -> Self { - Self { - config: unsafe { ffi::kime_daemon_config_load() }, - } - } - - pub fn modules(&self) -> EnumSet { - EnumSet::from_u32(unsafe { ffi::kime_daemon_config_modules(self.config) }) - } -} - -impl Default for DaemonConfig { - fn default() -> Self { - Self { - config: unsafe { ffi::kime_daemon_config_default() }, - } - } -} - -impl Drop for DaemonConfig { - fn drop(&mut self) { - unsafe { - ffi::kime_daemon_config_delete(self.config); - } - } -} - -pub struct IndicatorConfig { - config: *mut ffi::IndicatorConfig, -} - -impl IndicatorConfig { - #[cfg(unix)] - pub fn load() -> Self { - Self { - config: unsafe { ffi::kime_indicator_config_load() }, - } - } - - pub fn icon_color(&self) -> IconColor { - unsafe { ffi::kime_indicator_config_icon_color(self.config) } - } -} - -impl Default for IndicatorConfig { - fn default() -> Self { - Self { - config: unsafe { ffi::kime_indicator_config_default() }, - } - } -} - -impl Drop for IndicatorConfig { - fn drop(&mut self) { - unsafe { - ffi::kime_indicator_config_delete(self.config); - } - } -} - -pub struct LogConfig { - config: *mut ffi::LogConfig, -} - -impl LogConfig { - #[cfg(unix)] - pub fn load() -> Self { - Self { - config: unsafe { ffi::kime_log_config_load() }, - } - } - - pub fn global_level(&self) -> &'static str { - unsafe { - let s = ffi::kime_log_config_global_level(self.config); - core::str::from_utf8_unchecked(core::slice::from_raw_parts(s.ptr, s.len)) - } - } -} - -impl Default for LogConfig { - fn default() -> Self { - Self { - config: unsafe { ffi::kime_log_config_default() }, - } - } -} - -impl Drop for LogConfig { - fn drop(&mut self) { - unsafe { - ffi::kime_log_config_delete(self.config); - } - } -} diff --git a/src/engine/config/Cargo.toml b/src/engine/config/Cargo.toml index 67146cb3..7dc74a3c 100644 --- a/src/engine/config/Cargo.toml +++ b/src/engine/config/Cargo.toml @@ -12,8 +12,8 @@ config-serde = ["serde", "enumset/serde", "log/serde"] kime-engine-backend = { path = "../backend" } kime-engine-backend-hangul = { path = "../backends/hangul" } kime-engine-backend-latin = { path = "../backends/latin" } -log = "0.4.14" -serde = { version = "1.0.124", features = ["derive"], optional = true } -enumset = "1.0.6" +log = "0.4" +serde = { version = "1.0", features = ["derive"], optional = true } +enumset = "1.1" enum-map = "2" -maplit = "1.0.2" +maplit = "1.0" diff --git a/src/engine/config/src/lib.rs b/src/engine/config/src/lib.rs index 0da942ae..635eb961 100644 --- a/src/engine/config/src/lib.rs +++ b/src/engine/config/src/lib.rs @@ -161,6 +161,8 @@ impl Default for EngineConfig { global_hotkeys: btreemap! { Key::normal(KeyCode::Esc) => Hotkey::new(HotkeyBehavior::Switch(InputCategory::Latin), HotkeyResult::Bypass), Key::normal(KeyCode::AltR) => Hotkey::new(HotkeyBehavior::toggle_hangul_latin(), HotkeyResult::Consume), + // Sometimes Alt_R contains Alt modifier state + Key::alt(KeyCode::AltR) => Hotkey::new(HotkeyBehavior::toggle_hangul_latin(), HotkeyResult::Consume), Key::normal(KeyCode::Hangul) => Hotkey::new(HotkeyBehavior::toggle_hangul_latin(), HotkeyResult::Consume), Key::super_(KeyCode::Space) => Hotkey::new(HotkeyBehavior::toggle_hangul_latin(), HotkeyResult::Consume), Key::normal(KeyCode::Muhenkan) => Hotkey::new(HotkeyBehavior::toggle_hangul_latin(), HotkeyResult::Consume), diff --git a/src/engine/core/Cargo.toml b/src/engine/core/Cargo.toml index 06bd2fc0..76eb2eaf 100644 --- a/src/engine/core/Cargo.toml +++ b/src/engine/core/Cargo.toml @@ -15,15 +15,15 @@ kime-engine-backend-math = { path = "../backends/math", optional = true } kime-engine-backend-emoji = { path = "../backends/emoji", optional = true } serde_yaml = "0.9" parking_lot = "0.12" -fontdb = { version = "0.11.2", features = ["fontconfig"] } +fontdb = { version = "0.23", features = ["fontconfig"] } [target.'cfg(unix)'.dependencies] -xdg = "2.2.0" +xdg = "3.0" kime-run-dir = { path = "../../tools/run_dir" } [dev-dependencies] -criterion = "0.4" -pretty_assertions = "1.0.0" +criterion = "0.8" +pretty_assertions = "1.4" [[bench]] name = "call_key" diff --git a/src/engine/core/src/config.rs b/src/engine/core/src/config.rs index 45f5f94f..5d927efe 100644 --- a/src/engine/core/src/config.rs +++ b/src/engine/core/src/config.rs @@ -40,11 +40,7 @@ impl Config { #[cfg(unix)] let translation_layer: Option> = engine .translation_layer - .and_then(|f| { - xdg::BaseDirectories::with_prefix("kime") - .ok() - .and_then(|d| d.find_config_file(f)) - }) + .and_then(|f| xdg::BaseDirectories::with_prefix("kime").find_config_file(f)) .as_ref() .and_then(|f| fs::read_to_string(f.as_path()).ok()) .as_ref() @@ -111,23 +107,21 @@ impl Config { } #[cfg(unix)] -pub fn load_engine_config_from_config_dir() -> Option { - let dir = xdg::BaseDirectories::with_prefix("kime").ok()?; - let config: RawConfig = dir - .find_config_file("config.yaml") - .and_then(|config| serde_yaml::from_reader(std::fs::File::open(config).ok()?).ok()) - .unwrap_or_default(); +pub fn load_raw_config_from_config_dir() -> RawConfig { + let dir = xdg::BaseDirectories::with_prefix("kime"); - Some(Config::from_engine_config_with_dir(config.engine, &dir)) + dir.find_config_file("config.yaml") + .and_then(|config| serde_yaml::from_reader(std::fs::File::open(config).ok()?).ok()) + .unwrap_or_default() } #[cfg(unix)] -pub fn load_other_configs_from_config_dir() -> Option<(DaemonConfig, IndicatorConfig, LogConfig)> { - let dir = xdg::BaseDirectories::with_prefix("kime").ok()?; +pub fn load_engine_config_from_config_dir() -> Option { + let dir = xdg::BaseDirectories::with_prefix("kime"); let config: RawConfig = dir .find_config_file("config.yaml") .and_then(|config| serde_yaml::from_reader(std::fs::File::open(config).ok()?).ok()) .unwrap_or_default(); - Some((config.daemon, config.indicator, config.log)) + Some(Config::from_engine_config_with_dir(config.engine, &dir)) } diff --git a/src/engine/core/src/lib.rs b/src/engine/core/src/lib.rs index 3f45e436..8db27a10 100644 --- a/src/engine/core/src/lib.rs +++ b/src/engine/core/src/lib.rs @@ -2,7 +2,7 @@ mod config; mod os; #[cfg(unix)] -pub use config::{load_engine_config_from_config_dir, load_other_configs_from_config_dir}; +pub use config::{load_engine_config_from_config_dir, load_raw_config_from_config_dir}; pub use config::{ Config, DaemonConfig, DaemonModule, EngineConfig, EnumSet, Hotkey, IconColor, IndicatorConfig, InputCategory, InputMode, LevelFilter, LogConfig, RawConfig, @@ -145,9 +145,23 @@ impl InputEngine { ret |= InputResult::CONSUMED; } else if key.code == KeyCode::Shift { // ignore shift key + } else if matches!( + key.code, + KeyCode::ControlL + | KeyCode::ControlR + | KeyCode::AltL + | KeyCode::AltR + | KeyCode::SuperL + | KeyCode::SuperR + | KeyCode::Shift + ) { + ret |= self.current_result(); + return ret; } else { // clear preedit when get unhandled key - self.clear_preedit(); + if self.engine_impl.has_preedit() { + self.clear_preedit(); + } } ret |= self.current_result(); diff --git a/src/engine/core/src/os.rs b/src/engine/core/src/os.rs index 78801de0..3ee74893 100644 --- a/src/engine/core/src/os.rs +++ b/src/engine/core/src/os.rs @@ -60,6 +60,7 @@ mod unix { } } +#[cfg(not(unix))] mod fallback { use crate::InputCategory; use std::io; diff --git a/src/engine/core/tests/dubeolsik.rs b/src/engine/core/tests/dubeolsik.rs index 762ade16..f2daf015 100644 --- a/src/engine/core/tests/dubeolsik.rs +++ b/src/engine/core/tests/dubeolsik.rs @@ -146,15 +146,36 @@ fn number() { (Key::normal(S), "안", ""), (Key::normal(G), "않", ""), (Key::normal(E), "ㄷ", "않"), + // a pass key commits the pending preedit, then commits its own literal (Key::normal(One), "", "ㄷ1"), ]); } #[test] fn exclamation_mark() { + // '!' commits the pending preedit, then commits itself test_input(&[(Key::shift(R), "ㄲ", ""), (Key::shift(One), "", "ㄲ!")]); } +// issue #754: plain special-character (pass) keys must be typed in Hangul mode, +// not bypassed to the application. +#[test] +fn special_char_commit() { + // with a pending composition, '@' commits it and then commits '@' + test_input(&[(Key::normal(R), "ㄱ", ""), (Key::shift(Two), "", "ㄱ@")]); + // with no pending composition, '@' is committed + test_input(&[(Key::shift(Two), "", "@")]); +} + +// issue #754/#719: a shortcut-modified key (Ctrl+...) has no layout entry, so it +// is bypassed to the application by the caller — shortcut handling lives there, +// not in the pass-key path. +#[test] +fn ctrl_shortcut_bypass() { + use kime_engine_core::ModifierState; + test_input(&[(Key::new(Two, ModifierState::CONTROL), "", "PASS")]); +} + #[test] fn backspace() { test_input(&[ diff --git a/src/engine/core/tests/latin.rs b/src/engine/core/tests/latin.rs index a9ebd5b3..d502775b 100644 --- a/src/engine/core/tests/latin.rs +++ b/src/engine/core/tests/latin.rs @@ -11,3 +11,45 @@ fn qwerty() { (Key::shift(SemiColon), "", "PASS"), ]); } + +fn dvorak_config(preferred_direct: bool) -> EngineConfig { + let mut config = EngineConfig::default(); + config.latin.layout = LatinLayout::Dvorak; + config.latin.preferred_direct = preferred_direct; + config +} + +/// With `preferred_direct: false` the embedded Dvorak layout is applied: +/// physical QWERTY positions are remapped to their Dvorak characters. +/// (`W` -> `,` used to be impossible because dvorak.yaml failed to parse, #626.) +#[test] +fn dvorak_applies_when_not_preferred_direct() { + test_input_impl( + dvorak_config(false), + InputCategory::Latin, + &[ + (Key::normal(Q), "", "'"), + (Key::normal(W), "", ","), + (Key::shift(W), "", "<"), + (Key::normal(E), "", "."), + (Key::normal(K), "", "t"), + (Key::shift(Z), "", ";"), + ], + ); +} + +/// Reproduces the exact #626 configuration (Dvorak + `preferred_direct: true`, +/// which is the default): keys are passed through to the OS layout untouched, +/// so the embedded Dvorak layout has no effect. +#[test] +fn dvorak_ignored_when_preferred_direct() { + test_input_impl( + dvorak_config(true), + InputCategory::Latin, + &[ + (Key::normal(Q), "", "PASS"), + (Key::normal(W), "", "PASS"), + (Key::normal(K), "", "PASS"), + ], + ); +} diff --git a/src/engine/core/tests/sebeolsik_3_90.rs b/src/engine/core/tests/sebeolsik_3_90.rs index 7df7f54f..d86e1e3e 100644 --- a/src/engine/core/tests/sebeolsik_3_90.rs +++ b/src/engine/core/tests/sebeolsik_3_90.rs @@ -59,15 +59,15 @@ fn dont_change_jongseong() { } #[test] -fn flexible_compose_not_composable_jungseong() { +fn flexible_compose_composable_jungseong1() { test_input_with_addon( - &[(Key::normal(F), "ㅏ", ""), (Key::normal(V), "ㅗ", "ㅏ")], + &[(Key::normal(F), "ㅏ", ""), (Key::normal(V), "ㅘ", "")], Addon::FlexibleComposeOrder, ); } #[test] -fn flexible_compose_composable_jungseong() { +fn flexible_compose_composable_jungseong2() { test_input_with_addon( &[(Key::normal(F), "ㅏ", ""), (Key::normal(Slash), "ㅘ", "")], Addon::FlexibleComposeOrder, @@ -117,3 +117,18 @@ fn s_number() { fn colon() { test_input(&[(Key::shift(SemiColon), "", ":")]); } + +// issue #754: sebeolsik-390 puts a number/symbol layer on the shifted right-half +// keys via pass characters. These must be committed, not bypassed to the app +// (which would type the raw QWERTY letter instead). +#[test] +fn s754_number_layer() { + test_input(&[(Key::shift(U), "", "7")]); + test_input(&[(Key::shift(I), "", "8")]); + test_input(&[(Key::shift(O), "", "9")]); + test_input(&[(Key::shift(J), "", "4")]); + test_input(&[(Key::shift(K), "", "5")]); + test_input(&[(Key::shift(L), "", "6")]); + test_input(&[(Key::shift(Y), "", "<")]); + test_input(&[(Key::shift(P), "", ">")]); +} diff --git a/src/engine/core/tests/sebeolsik_3_91.rs b/src/engine/core/tests/sebeolsik_3_91.rs index bf140c24..7c891bcd 100644 --- a/src/engine/core/tests/sebeolsik_3_91.rs +++ b/src/engine/core/tests/sebeolsik_3_91.rs @@ -46,6 +46,7 @@ fn issue_521() { ]); } +// issue #754: a pass key (here ':') is committed in Hangul mode, not bypassed. #[test] fn colon() { test_input(&[(Key::normal(Backslash), "", ":")]); diff --git a/src/engine/core/tests/sebeolsik_3sin_p2.rs b/src/engine/core/tests/sebeolsik_3sin_p2.rs index 19357ca2..2335b0a7 100644 --- a/src/engine/core/tests/sebeolsik_3sin_p2.rs +++ b/src/engine/core/tests/sebeolsik_3sin_p2.rs @@ -18,6 +18,17 @@ fn double_jongseong() { test_input(&[(Key::normal(T), "ㅋ", ""), (Key::normal(T), "ㅋ", "ㅋ")]); } +#[test] +fn compose_jongseong_ssang_giyeok() { + // 신세벌식 P2: 쌍기역 받침은 ㄱ 받침(C 키)을 두 번 눌러 입력한다. + test_input(&[ + (Key::normal(J), "ㅇ", ""), + (Key::normal(F), "아", ""), + (Key::normal(C), "악", ""), + (Key::normal(C), "앆", ""), + ]); +} + #[test] fn hello() { test_input(&[ diff --git a/src/engine/core/tests/super_key.rs b/src/engine/core/tests/super_key.rs new file mode 100644 index 00000000..cbd51339 --- /dev/null +++ b/src/engine/core/tests/super_key.rs @@ -0,0 +1,52 @@ +use kime_engine_config::{HotkeyBehavior, HotkeyResult}; +use kime_engine_core::{ + Config, EngineConfig, Hotkey, InputCategory, InputEngine, InputResult, Key, KeyCode, + ModifierState, +}; +use pretty_assertions::assert_eq; + +// X11 hardware keycodes (evdev + 8) for the Super keys. +const SUPER_R: u16 = 134; +// R key, which is `ㄱ` in dubeolsik (the default hangul layout). +const KEY_R: u16 = 27; + +/// Right-Super (Apple right-command) can be bound as a category toggle, the +/// exact use case requested in issue #640. This drives the full hardware-code +/// path so it also proves `from_hardware_code(134)` resolves to `SuperR`. +#[test] +fn super_r_can_toggle_category() { + let mut engine_config = EngineConfig::default(); + engine_config.global_hotkeys = std::iter::once(( + Key::normal(KeyCode::SuperR), + Hotkey::new(HotkeyBehavior::toggle_hangul_latin(), HotkeyResult::Consume), + )) + .collect(); + + let config = Config::new(engine_config); + let mut engine = InputEngine::new(&config); + engine.set_input_category(InputCategory::Hangul); + assert_eq!(engine.category(), InputCategory::Hangul); + + let ret = engine.press_key_code(SUPER_R, ModifierState::empty(), false, &config); + assert!(ret.contains(InputResult::CONSUMED)); + assert_eq!(engine.category(), InputCategory::Latin); + + engine.press_key_code(SUPER_R, ModifierState::empty(), false, &config); + assert_eq!(engine.category(), InputCategory::Hangul); +} + +/// An unbound Super key press must behave like the other modifier keys +/// (Alt/Control) and leave an in-progress preedit untouched instead of +/// clearing it. +#[test] +fn unbound_super_keeps_preedit() { + let config = Config::new(EngineConfig::default()); + let mut engine = InputEngine::new(&config); + engine.set_input_category(InputCategory::Hangul); + + engine.press_key_code(KEY_R, ModifierState::empty(), false, &config); + assert_eq!(engine.preedit_str(), "ㄱ"); + + engine.press_key_code(SUPER_R, ModifierState::empty(), false, &config); + assert_eq!(engine.preedit_str(), "ㄱ"); +} diff --git a/src/engine/dict/Cargo.toml b/src/engine/dict/Cargo.toml index 2cf93fff..bf185ebc 100644 --- a/src/engine/dict/Cargo.toml +++ b/src/engine/dict/Cargo.toml @@ -8,6 +8,6 @@ license = "GPL-3.0-or-later" [build-dependencies] serde = {version = "1.0.118", features = ["derive"]} serde_json = "1.0" -itertools = "0.13.0" -quick-xml = { version = "0.27.1", features = ["encoding"] } -unic = "0.9.0" +itertools = "0.14.0" +quick-xml = { version = "0.39.0", features = ["encoding"] } +unicode-properties = { version = "0.1", features = ["emoji"] } diff --git a/src/engine/dict/build.rs b/src/engine/dict/build.rs index 13c86cc6..79d56045 100644 --- a/src/engine/dict/build.rs +++ b/src/engine/dict/build.rs @@ -11,7 +11,7 @@ use std::{ mem, path::PathBuf, }; -use unic::emoji::char::is_emoji; +use unicode_properties::UnicodeEmoji; #[derive(Default, Debug, Clone, Copy)] struct HanjaEntry { @@ -133,7 +133,7 @@ fn load_unicode_annotations() -> quick_xml::Result> { Event::Start(start) if start.name().0 == b"annotation" => { let cp = start.attributes().next().unwrap()?; debug_assert_eq!(cp.key.0, b"cp"); - let cp = cp.decode_and_unescape_value(&reader)?; + let cp = cp.decode_and_unescape_value(reader.decoder())?; if current_entry.cp != cp { if !current_entry.cp.is_empty() { out.push(mem::take(&mut current_entry)); @@ -204,7 +204,7 @@ fn main() { ) .unwrap(); for entry in load_unicode_annotations().unwrap() { - if !entry.cp.chars().any(|c| is_emoji(c)) { + if !entry.cp.chars().any(|c| c.is_emoji_char()) { continue; } diff --git a/src/frontends/gtk3/CMakeLists.txt b/src/frontends/gtk3/CMakeLists.txt deleted file mode 100644 index cbbb63ad..00000000 --- a/src/frontends/gtk3/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -find_package(PkgConfig REQUIRED) -pkg_check_modules(GTK3 gtk+-3.0) - -if(GTK3_FOUND) - add_library(kime-gtk3 SHARED ./src/gtk.c ./src/immodule.c ./src/str_buf.c) - - target_include_directories(kime-gtk3 PRIVATE ${GTK3_INCLUDE_DIRS} ${KIME_INCLUDE}) - target_link_directories(kime-gtk3 PRIVATE ${GTK3_LIBRARY_DIRS} ${KIME_LIB_DIRS}) - target_link_libraries(kime-gtk3 ${GTK3_LIBRARIES} ${KIME_ENGINE}) -endif() diff --git a/src/frontends/gtk3/meson.build b/src/frontends/gtk3/meson.build new file mode 100644 index 00000000..108f1cc2 --- /dev/null +++ b/src/frontends/gtk3/meson.build @@ -0,0 +1,12 @@ +gtk3_dep = dependency('gtk+-3.0', required: get_option('gtk3')) + +if gtk3_dep.found() + shared_library('im-kime', + 'src/gtk.c', + 'src/immodule.c', + 'src/str_buf.c', + dependencies: [gtk3_dep, kime_engine_dep], + install: true, + install_dir: get_option('libdir') / 'gtk-3.0' / '3.0.0' / 'immodules', + ) +endif diff --git a/src/frontends/gtk4/CMakeLists.txt b/src/frontends/gtk4/CMakeLists.txt deleted file mode 100644 index 2f3e3943..00000000 --- a/src/frontends/gtk4/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -find_package(PkgConfig REQUIRED) -pkg_check_modules(GTK4 QUIET gtk4) - -if(GTK4_FOUND) - add_library(kime-gtk4 SHARED src/gtk4.c ../gtk3/src/immodule.c ../gtk3/src/str_buf.c) - - target_include_directories(kime-gtk4 PRIVATE ${GTK4_INCLUDE_DIRS} ${KIME_INCLUDE}) - target_link_directories(kime-gtk4 PRIVATE ${GTK4_LIBRARY_DIRS} ${KIME_LIB_DIRS}) - target_link_libraries(kime-gtk4 PRIVATE ${GTK4_LIBRARIES} ${KIME_ENGINE}) -endif() diff --git a/src/frontends/gtk4/meson.build b/src/frontends/gtk4/meson.build new file mode 100644 index 00000000..7711ac73 --- /dev/null +++ b/src/frontends/gtk4/meson.build @@ -0,0 +1,12 @@ +gtk4_dep = dependency('gtk4', required: get_option('gtk4')) + +if gtk4_dep.found() + shared_library('kime-gtk4', + 'src/gtk4.c', + '../gtk3/src/immodule.c', + '../gtk3/src/str_buf.c', + dependencies: [gtk4_dep, kime_engine_dep], + install: true, + install_dir: get_option('libdir') / 'gtk-4.0' / '4.0.0' / 'immodules', + ) +endif diff --git a/src/frontends/qt5/CMakeLists.txt b/src/frontends/qt5/CMakeLists.txt deleted file mode 100644 index 3b8b9021..00000000 --- a/src/frontends/qt5/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -set(CMAKE_CXX_STANDARD 20) - -set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTORCC ON) -set(CMAKE_AUTOUIC ON) - -find_package(Qt5 5.1.0 QUIET COMPONENTS Gui QUIET) - -if(NOT Qt5_FOUND) - return() -endif() - -add_library(kime-qt5 SHARED src/plugin.cc src/input_context.cc) - -target_include_directories(kime-qt5 PRIVATE ${Qt5Gui_PRIVATE_INCLUDE_DIRS} ${KIME_INCLUDE}) -target_link_directories(kime-qt5 PRIVATE ${KIME_LIB_DIRS}) -target_link_libraries(kime-qt5 PRIVATE ${KIME_ENGINE} Qt5::Gui) diff --git a/src/frontends/qt5/meson.build b/src/frontends/qt5/meson.build new file mode 100644 index 00000000..b366161a --- /dev/null +++ b/src/frontends/qt5/meson.build @@ -0,0 +1,30 @@ +qt5_mod = import('qt5') +qt5_dep = dependency('qt5', modules: ['Core', 'Gui'], private_headers: true, required: get_option('qt5')) + +if qt5_dep.found() + qt5_plugindir_opt = get_option('qt5_plugindir') + if qt5_plugindir_opt != '' + qt5_plugindir = qt5_plugindir_opt + else + qmake5 = find_program('qmake-qt5', 'qmake5', 'qmake', required: false) + if qmake5.found() + qt5_plugindir = run_command(qmake5, '-query', 'QT_INSTALL_PLUGINS', check: true).stdout().strip() + else + qt5_plugindir = get_option('prefix') / get_option('libdir') / 'qt5' / 'plugins' + endif + endif + + qt5_moc = qt5_mod.preprocess( + moc_headers: ['src/plugin.hpp', 'src/input_context.hpp'], + dependencies: [qt5_dep, kime_engine_dep], + ) + + shared_library('kimeplatforminputcontextplugin', + 'src/plugin.cc', + 'src/input_context.cc', + qt5_moc, + dependencies: [qt5_dep, kime_engine_dep], + install: true, + install_dir: qt5_plugindir / 'platforminputcontexts', + ) +endif diff --git a/src/frontends/qt5/src/plugin.hpp b/src/frontends/qt5/src/plugin.hpp index b38d23af..faee0a4a 100644 --- a/src/frontends/qt5/src/plugin.hpp +++ b/src/frontends/qt5/src/plugin.hpp @@ -6,10 +6,13 @@ #include #include +#ifndef KIME_QT_IID +#define KIME_QT_IID "org.qt-project.Qt.QPlatformInputContextFactoryInterface" +#endif + class KimePlatformInputContextPlugin : public QPlatformInputContextPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID QPlatformInputContextFactoryInterface_iid FILE - "kime.json") + Q_PLUGIN_METADATA(IID KIME_QT_IID FILE "kime.json") private: kime::InputEngine *engine = nullptr; @@ -21,4 +24,4 @@ class KimePlatformInputContextPlugin : public QPlatformInputContextPlugin { QPlatformInputContext *create(const QString &key, const QStringList ¶m_list) override; -}; +}; \ No newline at end of file diff --git a/src/frontends/qt6/CMakeLists.txt b/src/frontends/qt6/CMakeLists.txt deleted file mode 100644 index a5b2b79d..00000000 --- a/src/frontends/qt6/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -set(CMAKE_CXX_STANDARD 20) - -set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTORCC ON) -set(CMAKE_AUTOUIC ON) - -find_package(Qt6 6.0.0 QUIET COMPONENTS Gui QUIET) - -if(NOT Qt6_FOUND) - return() -endif() - -add_library(kime-qt6 SHARED ../qt5/src/plugin.cc ../qt5/src/input_context.cc) - -target_include_directories(kime-qt6 PRIVATE ${Qt6Gui_PRIVATE_INCLUDE_DIRS} ${KIME_INCLUDE}) -target_link_directories(kime-qt6 PRIVATE ${KIME_LIB_DIRS}) -target_link_libraries(kime-qt6 PRIVATE ${KIME_ENGINE} Qt6::Gui) diff --git a/src/frontends/qt6/meson.build b/src/frontends/qt6/meson.build new file mode 100644 index 00000000..e431d8bd --- /dev/null +++ b/src/frontends/qt6/meson.build @@ -0,0 +1,32 @@ +qt6_mod = import('qt6') +qt6_dep = dependency('qt6', modules: ['Core', 'Gui'], private_headers: true, required: get_option('qt6')) + +if qt6_dep.found() + qt6_plugindir_opt = get_option('qt6_plugindir') + if qt6_plugindir_opt != '' + qt6_plugindir = qt6_plugindir_opt + else + qmake6 = find_program('qmake6', 'qmake-qt6', required: false) + if qmake6.found() + qt6_plugindir = run_command(qmake6, '-query', 'QT_INSTALL_PLUGINS', check: true).stdout().strip() + else + qt6_plugindir = get_option('prefix') / get_option('libdir') / 'qt6' / 'plugins' + endif + endif + + qt6_moc = qt6_mod.preprocess( + moc_headers: ['../qt5/src/plugin.hpp', '../qt5/src/input_context.hpp'], + dependencies: [qt6_dep, kime_engine_dep], + moc_extra_arguments: ['-DKIME_QT_IID="org.qt-project.Qt.QPlatformInputContextFactoryInterface.5.1"'], + ) + + shared_library('kimeplatforminputcontextplugin', + '../qt5/src/plugin.cc', + '../qt5/src/input_context.cc', + qt6_moc, + dependencies: [qt6_dep, kime_engine_dep], + cpp_args: ['-DKIME_QT_IID="org.qt-project.Qt.QPlatformInputContextFactoryInterface.5.1"'], + install: true, + install_dir: qt6_plugindir / 'platforminputcontexts', + ) +endif diff --git a/src/frontends/wayland/Cargo.toml b/src/frontends/wayland/Cargo.toml index 0e4ba6ba..8260acb9 100644 --- a/src/frontends/wayland/Cargo.toml +++ b/src/frontends/wayland/Cargo.toml @@ -6,16 +6,19 @@ edition = "2021" license = "GPL-3.0-or-later" [dependencies] -kime-engine-cffi = { path = "../../engine/cffi" } +kime-engine-core = { path = "../../engine/core" } kime-version = { path = "../../tools/version" } -wayland-client = "0.29" -wayland-protocols = { version = "0.29", features = ["client", "unstable_protocols"] } -zwp-virtual-keyboard = "0.2.7" -xkbcommon = { version = "0.7.0", features = ["wayland"] } +wayland-client = "0.31" +wayland-protocols = { version = "0.32", features = [ + "client", + "unstable", +] } +wayland-protocols-misc = { version = "0.3", features = ["client"] } +xkbcommon = { version = "0.9.0", features = ["wayland"] } -libc = "0.2.82" -log = "0.4.13" -pico-args = "0.5.0" -mio = { version = "0.7", features = ["os-ext"] } -mio-timerfd = "0.2" +libc = "0.2" +log = "0.4" +pico-args = "0.5" +mio = { version = "1.0", features = ["os-ext"] } +timerfd-mio = "0.1" diff --git a/src/frontends/wayland/src/input_method_v1.rs b/src/frontends/wayland/src/input_method_v1.rs deleted file mode 100644 index db37ecd9..00000000 --- a/src/frontends/wayland/src/input_method_v1.rs +++ /dev/null @@ -1,492 +0,0 @@ -use std::error::Error; -use std::os::fd::{FromRawFd, OwnedFd}; -use std::time::{Duration, Instant}; - -use wayland_client::{ - event_enum, - protocol::wl_keyboard::{Event as KeyEvent, KeyState, WlKeyboard, REQ_RELEASE_SINCE}, - DispatchData, Display, EventQueue, Filter, GlobalManager, Main, -}; - -use wayland_protocols::unstable::input_method::v1::client::{ - zwp_input_method_context_v1::{Event as ImCtxEvent, ZwpInputMethodContextV1}, - zwp_input_method_v1::{Event as ImEvent, ZwpInputMethodV1}, -}; - -use kime_engine_cffi::*; - -use mio::{unix::SourceFd, Events as MioEvents, Interest, Poll, Token}; -use mio_timerfd::{ClockId, TimerFd}; -use wayland_client::protocol::wl_keyboard::KeymapFormat; -use xkbcommon::xkb::{ - Context, Keycode, Keymap, CONTEXT_NO_FLAGS, KEYMAP_COMPILE_NO_FLAGS, KEYMAP_FORMAT_TEXT_V1, -}; - -use crate::{PressState, RepeatInfo}; - -event_enum! { - Events | - Im => ZwpInputMethodV1, - ImCtx => ZwpInputMethodContextV1, - Key => WlKeyboard -} - -const ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_NONE: u32 = 1; -const ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_UNDERLINE: u32 = 5; - -struct KimeContext { - config: Config, - engine: InputEngine, - mod_state: ModifierState, - im_ctx: Option>, - keyboard: Option>, - numlock: bool, - engine_ready: bool, - keymap: Option, - grab_activate: bool, //? - serial: u32, - timer: TimerFd, - /// `None` if `KimeContext` have never received a `RepeatInfo` or repeat is disabled (i.e. rate - /// is zero). `Some(..)` if `RepeatInfo` is known and kime-wayland started tracking the press - /// state of keys. - repeat_state: Option<(RepeatInfo, PressState)>, -} - -impl Drop for KimeContext { - fn drop(&mut self) { - if let Some(im_ctx) = &mut self.im_ctx { - im_ctx.destroy(); - } - } -} - -impl KimeContext { - pub fn new(timer: TimerFd) -> Self { - let config = Config::load(); - Self { - engine: InputEngine::new(&config), - config, - mod_state: 0, - serial: 0, - numlock: false, - engine_ready: true, - keymap: None, - grab_activate: false, - im_ctx: None, - keyboard: None, - timer, - // Clients with older protocols might not provide repeat info. - // Therefore a default value is required. - repeat_state: Some(( - RepeatInfo { - rate: 20, - delay: 400, - }, - PressState::NotPressing, - )), - } - } - - pub fn new_data<'a>(data: &'a mut DispatchData) -> &'a mut Self { - data.get::().unwrap() - } - - fn process_input_result(&mut self, ret: InputResult) -> bool { - if ret & InputResult_NOT_READY != 0 { - self.engine_ready = false; - } - - if ret & InputResult_LANGUAGE_CHANGED != 0 { - self.engine.update_layout_state(); - } - - if ret & InputResult_HAS_COMMIT != 0 { - self.commit_string(self.engine.commit_str().into()); - self.engine.clear_commit(); - } - - if ret & InputResult_HAS_PREEDIT != 0 { - let preedit = self.engine.preedit_str().into(); - self.preedit(preedit); - } else { - self.clear_preedit(); - } - - ret & InputResult_CONSUMED == 0 - } - - fn commit_string(&mut self, s: String) { - if !s.is_empty() { - if let Some(im_ctx) = &mut self.im_ctx { - im_ctx.commit_string(self.serial, s); - } - } - } - - fn clear_preedit(&mut self) { - if let Some(im_ctx) = &mut self.im_ctx { - im_ctx.preedit_cursor(0); - im_ctx.preedit_styling(0, 0, ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_NONE); - im_ctx.preedit_string(self.serial, String::new(), String::new()); - } - } - - fn preedit(&mut self, s: String) { - if let Some(im_ctx) = &mut self.im_ctx { - im_ctx.preedit_cursor(s.len() as _); - im_ctx.preedit_styling(0, s.len() as _, ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_UNDERLINE); - im_ctx.preedit_string(self.serial, s.clone(), s); - } - } - - fn key(&mut self, time: u32, key: u32, state: KeyState) { - if let Some(im_ctx) = &mut self.im_ctx { - im_ctx.key(self.serial, time, key, state as _); - } - } - - pub fn handle_im_ctx_ev(&mut self, ev: ImCtxEvent) { - match ev { - ImCtxEvent::CommitState { serial } => { - self.serial = serial; - } - _ => {} - } - } - - pub fn handle_key_ev(&mut self, ev: KeyEvent) { - match ev { - KeyEvent::Keymap { format, fd, size } => { - if let KeymapFormat::XkbV1 = format { - unsafe { - self.keymap = Keymap::new_from_fd( - &Context::new(CONTEXT_NO_FLAGS), - OwnedFd::from_raw_fd(fd), - size as usize, - KEYMAP_FORMAT_TEXT_V1, - KEYMAP_COMPILE_NO_FLAGS, - ) - .unwrap_or(None); - } - } else { - unsafe { - libc::close(fd); - } - } - } - KeyEvent::Key { - time, key, state, .. - } => { - if state == KeyState::Pressed { - if self.grab_activate { - let ret = self.engine.press_key( - &self.config, - (key + 8) as u16, - self.numlock, - self.mod_state, - ); - - let bypassed = self.process_input_result(ret); - - if bypassed { - self.key(time, key, state); - } else { - // If the key was not bypassed by IME, key repeat should be handled by the - // IME. Start waiting for the key hold timer event. - match self.repeat_state { - Some((info, ref mut press_state)) - if !press_state.is_pressing(key) => - { - let duration = Duration::from_millis(info.delay as u64); - self.timer.set_timeout(&duration).unwrap(); - *press_state = PressState::Pressing { - pressed_at: Instant::now(), - is_repeating: false, - key, - wayland_time: time, - } - } - _ => {} - } - } - } else { - self.key(time, key, state); - } - } else { - if let Some((.., ref mut press_state)) = self.repeat_state { - if press_state.is_pressing(key) { - self.timer.disarm().unwrap(); - *press_state = PressState::NotPressing; - } - } - - self.key(time, key, state); - } - } - KeyEvent::Modifiers { - mods_depressed, - mods_latched, - mods_locked, - group, - .. - } => { - self.mod_state = 0; - if mods_depressed & 0x1 != 0 { - self.mod_state |= ModifierState_SHIFT; - } - if mods_depressed & 0x4 != 0 { - self.mod_state |= ModifierState_CONTROL; - } - if mods_depressed & 0x8 != 0 { - self.mod_state |= ModifierState_ALT; - } - if mods_depressed & 0x40 != 0 { - self.mod_state |= ModifierState_SUPER; - } - - self.numlock = mods_depressed & 0x10 != 0; - - if let Some(im_ctx) = &mut self.im_ctx { - im_ctx.modifiers( - self.serial, - mods_depressed, - mods_latched, - mods_locked, - group, - ); - } - } - KeyEvent::RepeatInfo { rate, delay } => { - self.repeat_state = if rate == 0 { - None - } else { - let info = RepeatInfo { rate, delay }; - let press_state = self.repeat_state.map(|pair| pair.1); - Some((info, press_state.unwrap_or(PressState::NotPressing))) - } - } - _ => {} - } - } - - pub fn handle_timer_ev(&mut self) -> std::io::Result<()> { - // Read timer, this MUST be called or timer will be broken - let overrun_count = self.timer.read()?; - if overrun_count != 1 { - log::warn!("Some timer events were not properly handled!"); - } - - if let Some(( - info, - PressState::Pressing { - pressed_at, - ref mut is_repeating, - key, - wayland_time, - }, - )) = self.repeat_state - { - if !*is_repeating { - if self - .keymap - .as_ref() - .map_or_else(|| true, |x| x.key_repeats(Keycode::new(key + 8))) - { - // Start repeat - log::trace!("Start repeating {}", key); - let interval = &Duration::from_secs_f64(1.0 / info.rate as f64); - self.timer.set_timeout_interval(interval)?; - *is_repeating = true; - } - } - - let ev = KeyEvent::Key { - serial: self.serial, // Is this fine? - time: wayland_time + pressed_at.elapsed().as_millis() as u32, - key, - state: KeyState::Pressed, - }; - self.handle_key_ev(ev); - } else { - log::warn!("Received timer event when it has never received RepeatInfo."); - } - Ok(()) - } - - pub fn activate(&mut self, im_ctx: Main, keyboard: Main) { - self.engine.update_layout_state(); - if !self.engine_ready { - if self.engine.check_ready() { - let ret = self.engine.end_ready(); - self.process_input_result(ret); - self.engine_ready = true; - } - } - self.grab_activate = true; - - let filter = Filter::new(|ev, _filter, mut data| { - let ctx = KimeContext::new_data(&mut data); - - match ev { - Events::ImCtx { event, .. } => { - ctx.handle_im_ctx_ev(event); - } - Events::Key { event, .. } => { - ctx.handle_key_ev(event); - } - _ => {} - } - }); - - im_ctx.assign(filter.clone()); - keyboard.assign(filter); - - self.im_ctx = Some(im_ctx); - self.keyboard = Some(keyboard); - } - - pub fn deactivate(&mut self) { - // Focus lost, reset states - if self.engine_ready { - self.engine.reset(); - } - self.grab_activate = false; - - // Input deactivated, stop repeating - self.timer.disarm().unwrap(); - if let Some((_, ref mut press_state)) = self.repeat_state { - *press_state = PressState::NotPressing - } - - if let Some(im_ctx) = &mut self.im_ctx { - im_ctx.destroy(); - } - self.im_ctx = None; - - if let Some(keyboard) = &mut self.keyboard { - if keyboard.as_ref().version() >= REQ_RELEASE_SINCE { - keyboard.release(); - } - } - self.keyboard = None; - } -} - -pub fn run( - display: &Display, - event_queue: &mut EventQueue, - globals: &GlobalManager, -) -> Result<(), Box> { - let im_filter = Filter::new(|ev, _filter, mut data| { - let ctx = KimeContext::new_data(&mut data); - match ev { - Events::Im { event, .. } => match event { - ImEvent::Activate { id: im_ctx } => { - let keyboard = im_ctx.grab_keyboard(); - ctx.activate(im_ctx, keyboard); - } - ImEvent::Deactivate { .. } => { - ctx.deactivate(); - } - _ => {} - }, - _ => {} - } - }); - - let im = globals.instantiate_exact::(1)?; - im.assign(im_filter); - - let mut timer = TimerFd::new(ClockId::Monotonic).expect("Initialize timer"); - - let mut poll = Poll::new().expect("Initialize epoll()"); - let registry = poll.registry(); - - const POLL_WAYLAND: Token = Token(0); - registry - .register( - &mut SourceFd(&display.get_connection_fd()), - POLL_WAYLAND, - Interest::READABLE | Interest::WRITABLE, - ) - .expect("Register wayland socket to the epoll()"); - - const POLL_TIMER: Token = Token(1); - registry - .register(&mut timer, POLL_TIMER, Interest::READABLE) - .expect("Register timer to the epoll()"); - - // Initialize kime context - let mut kime_ctx = KimeContext::new(timer); - event_queue - .sync_roundtrip(&mut kime_ctx, |_, _, _| ()) - .unwrap(); - - log::info!("Server init success!"); - - // Non-blocking event loop - // - // Reference: - // https://docs.rs/wayland-client/0.28.3/wayland_client/struct.EventQueue.html - let mut events = MioEvents::with_capacity(1024); - let stop_reason = 'main: loop { - use std::io::ErrorKind; - - // Sleep until next event - if let Err(e) = poll.poll(&mut events, None) { - // Should retry on EINTR - // - // Reference: - // https://www.gnu.org/software/libc/manual/html_node/Interrupted-Primitives.html - if e.kind() == ErrorKind::Interrupted { - continue; - } - break Err(e); - } - - for event in &events { - match event.token() { - POLL_WAYLAND => {} - POLL_TIMER => { - if let Err(e) = kime_ctx.handle_timer_ev() { - break 'main Err(e); - } - } - _ => unreachable!(), - } - } - - // Perform read() only when it's ready, returns None when there're already pending events - if let Some(guard) = event_queue.prepare_read() { - if let Err(e) = guard.read_events() { - // EWOULDBLOCK here means there's no new messages to read - if e.kind() != ErrorKind::WouldBlock { - break Err(e); - } - } - } - - if let Err(e) = event_queue.dispatch_pending(&mut kime_ctx, |_, _, _| {}) { - break Err(e); - } - - // Flush pending writes - if let Err(e) = display.flush() { - // EWOULDBLOCK here means there're so many to write, retry later - if e.kind() != ErrorKind::WouldBlock { - break Err(e); - } - } - }; - - match stop_reason { - Ok(()) => { - log::info!("Server finished gracefully"); - Ok(()) - } - Err(e) => { - log::error!("Server aborted due to IO Error: {}", e); - Err(Box::from(e)) - } - } -} diff --git a/src/frontends/wayland/src/input_method_v2.rs b/src/frontends/wayland/src/input_method_v2.rs deleted file mode 100644 index 1916b973..00000000 --- a/src/frontends/wayland/src/input_method_v2.rs +++ /dev/null @@ -1,471 +0,0 @@ -use std::error::Error; -use std::time::{Duration, Instant}; - -use wayland_client::{ - event_enum, - protocol::{wl_keyboard::KeyState, wl_seat::WlSeat}, - DispatchData, Display, EventQueue, Filter, GlobalManager, Main, -}; - -use wayland_protocols::misc::zwp_input_method_v2::client::{ - zwp_input_method_keyboard_grab_v2::{Event as KeyEvent, ZwpInputMethodKeyboardGrabV2}, - zwp_input_method_manager_v2::ZwpInputMethodManagerV2, - zwp_input_method_v2::{Event as ImEvent, ZwpInputMethodV2}, -}; -use zwp_virtual_keyboard::virtual_keyboard_unstable_v1::{ - zwp_virtual_keyboard_manager_v1::ZwpVirtualKeyboardManagerV1, - zwp_virtual_keyboard_v1::ZwpVirtualKeyboardV1, -}; - -use kime_engine_cffi::*; - -use mio::{unix::SourceFd, Events as MioEvents, Interest, Poll, Token}; -use mio_timerfd::{ClockId, TimerFd}; - -use crate::{PressState, RepeatInfo}; - -event_enum! { - Events | - Key => ZwpInputMethodKeyboardGrabV2, - Im => ZwpInputMethodV2 -} - -struct InputMethodState { - activate: bool, - deactivate: bool, -} - -impl Default for InputMethodState { - fn default() -> Self { - Self { - activate: false, - deactivate: false, - } - } -} - -struct KimeContext { - config: Config, - engine: InputEngine, - mod_state: ModifierState, - current_state: InputMethodState, - pending_state: InputMethodState, - vk: Main, - im: Main, - grab: Main, - numlock: bool, - engine_ready: bool, - keymap_init: bool, - grab_activate: bool, - serial: u32, - // Have to concern Multi seats? - - // Key repeat contexts - timer: TimerFd, - /// `None` if `KimeContext` have never received a `RepeatInfo` or repeat is disabled (i.e. rate - /// is zero). `Some(..)` if `RepeatInfo` is known and kime-wayland started tracking the press - /// state of keys. - repeat_state: Option<(RepeatInfo, PressState)>, -} - -impl Drop for KimeContext { - fn drop(&mut self) { - self.grab.release(); - self.vk.destroy(); - self.im.destroy(); - } -} - -impl KimeContext { - pub fn new( - vk: Main, - im: Main, - grab: Main, - timer: TimerFd, - ) -> Self { - let config = Config::load(); - Self { - engine: InputEngine::new(&config), - config, - mod_state: 0, - current_state: InputMethodState::default(), - pending_state: InputMethodState::default(), - serial: 0, - numlock: false, - engine_ready: true, - keymap_init: false, - grab_activate: false, - vk, - im, - grab, - timer, - repeat_state: None, - } - } - - pub fn new_data<'a>(data: &'a mut DispatchData) -> &'a mut Self { - data.get::().unwrap() - } - - fn process_input_result(&mut self, ret: InputResult) -> bool { - if ret & InputResult_NOT_READY != 0 { - self.engine_ready = false; - } - - if ret & InputResult_LANGUAGE_CHANGED != 0 { - self.engine.update_layout_state(); - } - - if ret & InputResult_HAS_PREEDIT != 0 { - let preedit = self.engine.preedit_str().into(); - self.preedit(preedit); - } else { - self.clear_preedit(); - } - - if ret & InputResult_HAS_COMMIT != 0 { - self.commit_string(self.engine.commit_str().into()); - self.engine.clear_commit(); - } - - self.commit(); - - ret & InputResult_CONSUMED == 0 - } - - fn commit(&mut self) { - self.im.commit(self.serial); - } - - fn commit_string(&mut self, s: String) { - if !s.is_empty() { - self.im.commit_string(s); - } - } - - fn clear_preedit(&mut self) { - self.im.set_preedit_string(String::new(), -1, -1); - } - - fn preedit(&mut self, s: String) { - let len = s.len(); - self.im.set_preedit_string(s, 0, len as _); - } - - pub fn handle_im_ev(&mut self, ev: ImEvent) { - match ev { - ImEvent::Activate => { - self.pending_state.activate = true; - } - ImEvent::Deactivate => { - self.pending_state.deactivate = true; - } - ImEvent::Unavailable => { - log::error!("Receive Unavailable event is another server already running?"); - panic!("Unavailable") - } - ImEvent::Done => { - self.serial += 1; - if !self.current_state.activate && self.pending_state.activate { - self.engine.update_layout_state(); - if !self.engine_ready { - if self.engine.check_ready() { - let ret = self.engine.end_ready(); - self.process_input_result(ret); - self.engine_ready = true; - } - } - self.grab_activate = true; - } else if !self.current_state.deactivate && self.pending_state.deactivate { - // Focus lost, reset states - if self.engine_ready { - self.engine.reset(); - } - self.grab_activate = false; - - // Input deactivated, stop repeating - self.timer.disarm().unwrap(); - if let Some((_, ref mut press_state)) = self.repeat_state { - *press_state = PressState::NotPressing - } - } - self.current_state = std::mem::take(&mut self.pending_state); - } - _ => {} - } - } - - pub fn handle_key_ev(&mut self, ev: KeyEvent) { - match ev { - KeyEvent::Keymap { fd, format, size } => { - if !self.keymap_init { - self.vk.keymap(format as _, fd, size); - self.keymap_init = true; - } - unsafe { - libc::close(fd); - } - } - KeyEvent::Key { - state, key, time, .. - } => { - // NOTE: Never read `serial` of KeyEvent. You should rely on serial of KimeContext - if state == KeyState::Pressed { - if self.grab_activate { - let ret = self.engine.press_key( - &self.config, - (key + 8) as u16, - self.numlock, - self.mod_state, - ); - - let bypassed = self.process_input_result(ret); - - if bypassed { - // Bypassed key's repeat will be handled by the clients. - // - // Reference: - // https://github.com/swaywm/sway/pull/4932#issuecomment-774113129 - self.vk.key(time, key, state as _); - } else { - // If the key was not bypassed by IME, key repeat should be handled by the - // IME. Start waiting for the key hold timer event. - match self.repeat_state { - Some((info, ref mut press_state)) - if !press_state.is_pressing(key) => - { - let duration = Duration::from_millis(info.delay as u64); - self.timer.set_timeout(&duration).unwrap(); - *press_state = PressState::Pressing { - pressed_at: Instant::now(), - is_repeating: false, - key, - wayland_time: time, - }; - } - _ => {} - } - } - } else { - // not activated so just skip - self.vk.key(time, key, state as _); - } - } else { - // If user released the last pressed key, clear the timer and state - if let Some((.., ref mut press_state)) = self.repeat_state { - if press_state.is_pressing(key) { - self.timer.disarm().unwrap(); - *press_state = PressState::NotPressing; - } - } - - self.vk.key(time, key, state as _); - } - } - KeyEvent::Modifiers { - mods_depressed, - mods_latched, - mods_locked, - group, - .. - } => { - self.mod_state = 0; - if mods_depressed & 0x1 != 0 { - self.mod_state |= ModifierState_SHIFT; - } - if mods_depressed & 0x4 != 0 { - self.mod_state |= ModifierState_CONTROL; - } - if mods_depressed & 0x8 != 0 { - self.mod_state |= ModifierState_ALT; - } - if mods_depressed & 0x40 != 0 { - self.mod_state |= ModifierState_SUPER; - } - - self.numlock = mods_depressed & 0x10 != 0; - - self.vk - .modifiers(mods_depressed, mods_latched, mods_locked, group); - } - KeyEvent::RepeatInfo { rate, delay } => { - self.repeat_state = if rate == 0 { - // Zero rate means disabled repeat - // - // Reference: - // https://github.com/swaywm/wlroots/blob/3d46d3f7/protocol/input-method-unstable-v2.xml#L444-L455 - None - } else { - let info = RepeatInfo { rate, delay }; - let press_state = self.repeat_state.map(|pair| pair.1); - Some((info, press_state.unwrap_or(PressState::NotPressing))) - } - } - _ => {} - } - } - - pub fn handle_timer_ev(&mut self) -> std::io::Result<()> { - // Read timer, this MUST be called or timer will be broken - let overrun_count = self.timer.read()?; - if overrun_count != 1 { - log::warn!("Some timer events were not properly handled!"); - } - - if let Some(( - info, - PressState::Pressing { - pressed_at, - ref mut is_repeating, - key, - wayland_time, - }, - )) = self.repeat_state - { - if !*is_repeating { - // Start repeat - log::trace!("Start repeating {}", key); - let interval = &Duration::from_secs_f64(1.0 / info.rate as f64); - self.timer.set_timeout_interval(interval)?; - *is_repeating = true; - } - - // Emit key repeat event - let ev = KeyEvent::Key { - serial: self.serial, - time: wayland_time + pressed_at.elapsed().as_millis() as u32, - key, - state: KeyState::Pressed, - }; - self.handle_key_ev(ev); - } else { - log::warn!("Received timer event when it has never received RepeatInfo."); - } - - Ok(()) - } -} - -pub fn run( - display: &Display, - event_queue: &mut EventQueue, - globals: &GlobalManager, -) -> Result<(), Box> { - let im_manager = globals.instantiate_exact::(1)?; - let vk_manager = globals.instantiate_exact::(1)?; - let seat = globals.instantiate_exact::(1).expect("Load Seat"); - - let filter = Filter::new(|ev, _filter, mut data| { - let ctx = KimeContext::new_data(&mut data); - - match ev { - Events::Key { event, .. } => { - ctx.handle_key_ev(event); - } - Events::Im { event, .. } => { - ctx.handle_im_ev(event); - } - } - }); - - let vk = vk_manager.create_virtual_keyboard(&seat); - let im = im_manager.get_input_method(&seat); - let grab = im.grab_keyboard(); - grab.assign(filter.clone()); - im.assign(filter); - - // Initialize timer - let mut timer = TimerFd::new(ClockId::Monotonic).expect("Initialize timer"); - - // Initialize epoll() object - let mut poll = Poll::new().expect("Initialize epoll()"); - let registry = poll.registry(); - - const POLL_WAYLAND: Token = Token(0); - registry - .register( - &mut SourceFd(&display.get_connection_fd()), - POLL_WAYLAND, - Interest::READABLE | Interest::WRITABLE, - ) - .expect("Register wayland socket to the epoll()"); - - const POLL_TIMER: Token = Token(1); - registry - .register(&mut timer, POLL_TIMER, Interest::READABLE) - .expect("Register timer to the epoll()"); - - // Initialize kime context - let mut kime_ctx = KimeContext::new(vk, im, grab, timer); - event_queue - .sync_roundtrip(&mut kime_ctx, |_, _, _| ()) - .unwrap(); - - log::info!("Server init success!"); - - // Non-blocking event loop - // - // Reference: - // https://docs.rs/wayland-client/0.28.3/wayland_client/struct.EventQueue.html - let mut events = MioEvents::with_capacity(1024); - let stop_reason = 'main: loop { - use std::io::ErrorKind; - - // Sleep until next event - if let Err(e) = poll.poll(&mut events, None) { - // Should retry on EINTR - // - // Reference: - // https://www.gnu.org/software/libc/manual/html_node/Interrupted-Primitives.html - if e.kind() == ErrorKind::Interrupted { - continue; - } - break Err(e); - } - - for event in &events { - match event.token() { - POLL_WAYLAND => {} - POLL_TIMER => { - if let Err(e) = kime_ctx.handle_timer_ev() { - break 'main Err(e); - } - } - _ => unreachable!(), - } - } - - // Perform read() only when it's ready, returns None when there're already pending events - if let Some(guard) = event_queue.prepare_read() { - if let Err(e) = guard.read_events() { - // EWOULDBLOCK here means there's no new messages to read - if e.kind() != ErrorKind::WouldBlock { - break Err(e); - } - } - } - - if let Err(e) = event_queue.dispatch_pending(&mut kime_ctx, |_, _, _| {}) { - break Err(e); - } - - // Flush pending writes - if let Err(e) = display.flush() { - // EWOULDBLOCK here means there're so many to write, retry later - if e.kind() != ErrorKind::WouldBlock { - break Err(e); - } - } - }; - - match stop_reason { - Ok(()) => { - log::info!("Server finished gracefully"); - Ok(()) - } - Err(e) => { - log::error!("Server aborted due to IO Error: {}", e); - Err(Box::from(e)) - } - } -} diff --git a/src/frontends/wayland/src/lib.rs b/src/frontends/wayland/src/lib.rs index 77444a30..99f5d879 100644 --- a/src/frontends/wayland/src/lib.rs +++ b/src/frontends/wayland/src/lib.rs @@ -1,14 +1,13 @@ use std::time::Instant; -pub mod input_method_v1; -pub mod input_method_v2; +pub mod state; #[derive(Clone, Copy)] pub struct RepeatInfo { /// The rate of repeating keys in characters per second - rate: i32, + pub rate: i32, /// Delay in milliseconds since key down until repeating starts - delay: i32, + pub delay: i32, } #[derive(Clone, Copy)] diff --git a/src/frontends/wayland/src/main.rs b/src/frontends/wayland/src/main.rs index 069a5846..8428896f 100644 --- a/src/frontends/wayland/src/main.rs +++ b/src/frontends/wayland/src/main.rs @@ -1,23 +1,58 @@ -use wayland_client::{Display, GlobalManager}; +use wayland_client::Connection; + +use kime_wayland::state::AppState; fn main() { kime_version::cli_boilerplate!((),); - assert!( - kime_engine_cffi::check_api_version(), - "Engine version mismatched" - ); + let conn = Connection::connect_to_env().expect("Failed to connect wayland display"); + let display = conn.display(); + + let mut event_queue = conn.new_event_queue::(); + let qh = event_queue.handle(); + + // Get registry to bind globals + display.get_registry(&qh, ()); - let display = Display::connect_to_env().expect("Failed to connect wayland display"); - let mut event_queue = display.create_event_queue(); - let attached_display = display.attach(event_queue.token()); - let globals = GlobalManager::new(&attached_display); + // Create initial state + let mut state = AppState::new(&conn); - event_queue.sync_roundtrip(&mut (), |_, _, _| ()).unwrap(); + // Initial roundtrip to get globals + event_queue.roundtrip(&mut state).unwrap(); - let result = kime_wayland::input_method_v2::run(&display, &mut event_queue, &globals); + log::debug!( + "Globals: v2={}, vk={}, seat={}, v1={}", + state.has_input_method_v2(), + state.has_vk_manager(), + state.has_seat(), + state.has_input_method_v1() + ); - if let Err(_) = result { - kime_wayland::input_method_v1::run(&display, &mut event_queue, &globals).unwrap(); + // Try v2 first, fall back to v1 + if state.has_input_method_v2() { + log::info!("Using input_method_v2 protocol"); + if let Err(e) = state.setup_input_method_v2(&qh) { + log::warn!("input_method_v2 setup failed: {}, trying v1", e); + if state.has_input_method_v1() { + state.setup_input_method_v1(&qh).unwrap(); + } else { + log::error!("No input method protocol available"); + std::process::exit(1); + } + } + } else if state.has_input_method_v1() { + log::info!("Using input_method_v1 protocol"); + state.setup_input_method_v1(&qh).unwrap(); + } else { + log::error!("No input method protocol available (no zwp_input_method_manager_v2, zwp_virtual_keyboard_manager_v1, or zwp_input_method_v1 found)"); + std::process::exit(1); } + + // Roundtrip after setup + event_queue.roundtrip(&mut state).unwrap(); + + log::info!("Server init success!"); + + // Event loop + state.run_event_loop(&conn, event_queue); } diff --git a/src/frontends/wayland/src/state.rs b/src/frontends/wayland/src/state.rs new file mode 100644 index 00000000..7f68614b --- /dev/null +++ b/src/frontends/wayland/src/state.rs @@ -0,0 +1,952 @@ +use std::error::Error; +use std::os::fd::{AsFd, AsRawFd}; +use std::time::{Duration, Instant}; + +use kime_engine_core::{ + load_engine_config_from_config_dir, Config, InputEngine, InputResult, Key, KeyCode, + ModifierState, +}; + +use mio::{unix::SourceFd, Events as MioEvents, Interest, Poll, Token}; +use timerfd_mio::TimerFd; + +use wayland_client::{ + delegate_noop, event_created_child, + protocol::{ + wl_keyboard::{self, KeyState, KeymapFormat, WlKeyboard}, + wl_registry::{self, WlRegistry}, + wl_seat::{self, WlSeat}, + }, + Connection, Dispatch, EventQueue, Proxy, QueueHandle, WEnum, +}; + +use wayland_protocols_misc::zwp_input_method_v2::client::{ + zwp_input_method_keyboard_grab_v2::{self, ZwpInputMethodKeyboardGrabV2}, + zwp_input_method_manager_v2::ZwpInputMethodManagerV2, + zwp_input_method_v2::{self, ZwpInputMethodV2}, +}; + +use wayland_protocols::wp::input_method::zv1::client::{ + zwp_input_method_context_v1::{self, ZwpInputMethodContextV1}, + zwp_input_method_v1::{self, ZwpInputMethodV1}, +}; + +use wayland_protocols_misc::zwp_virtual_keyboard_v1::client::{ + zwp_virtual_keyboard_manager_v1::ZwpVirtualKeyboardManagerV1, + zwp_virtual_keyboard_v1::ZwpVirtualKeyboardV1, +}; + +use crate::{PressState, RepeatInfo}; + +use xkbcommon::xkb::{ + Context as XkbContext, Keycode, Keymap, CONTEXT_NO_FLAGS, KEYMAP_COMPILE_NO_FLAGS, + KEYMAP_FORMAT_TEXT_V1, +}; + +const ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_UNDERLINE: u32 = 5; + +/// Registry state for binding globals +struct Globals { + seat: Option, + im_manager_v2: Option, + vk_manager: Option, + im_v1: Option, +} + +/// Input method v2 state +struct InputMethodV2State { + im: ZwpInputMethodV2, + #[allow(dead_code)] + grab: ZwpInputMethodKeyboardGrabV2, + vk: ZwpVirtualKeyboardV1, + pending_activate: bool, + pending_deactivate: bool, + current_activate: bool, + current_deactivate: bool, + grab_activate: bool, + keymap_init: bool, +} + +/// Input method v1 state +struct InputMethodV1State { + im_ctx: Option, + keyboard: Option, + keymap: Option, + grab_activate: bool, +} + +/// Main application state +pub struct AppState { + config: Config, + engine: InputEngine, + mod_state: ModifierState, + numlock: bool, + engine_ready: bool, + serial: u32, + timer: TimerFd, + repeat_state: Option<(RepeatInfo, PressState)>, + last_preedit_len: usize, + should_exit: bool, + + // Wayland state + globals: Globals, + im_v2: Option, + im_v1: Option, +} + +impl AppState { + pub fn new(_conn: &Connection) -> Self { + let config = load_engine_config_from_config_dir().unwrap_or_default(); + let timer = TimerFd::new().expect("Initialize timer"); + + Self { + engine: InputEngine::new(&config), + config, + mod_state: ModifierState::empty(), + numlock: false, + engine_ready: true, + serial: 0, + timer, + // For v1, provide default repeat info since older protocols might not provide it + repeat_state: Some(( + RepeatInfo { + rate: 20, + delay: 400, + }, + PressState::NotPressing, + )), + last_preedit_len: 0, + should_exit: false, + globals: Globals { + seat: None, + im_manager_v2: None, + vk_manager: None, + im_v1: None, + }, + im_v2: None, + im_v1: None, + } + } + + pub fn has_input_method_v2(&self) -> bool { + self.globals.im_manager_v2.is_some() + && self.globals.vk_manager.is_some() + && self.globals.seat.is_some() + } + + pub fn has_input_method_v1(&self) -> bool { + self.globals.im_v1.is_some() + } + + pub fn has_vk_manager(&self) -> bool { + self.globals.vk_manager.is_some() + } + + pub fn has_seat(&self) -> bool { + self.globals.seat.is_some() + } + + pub fn setup_input_method_v2(&mut self, qh: &QueueHandle) -> Result<(), Box> { + let seat = self.globals.seat.as_ref().ok_or("No seat")?; + let im_manager = self + .globals + .im_manager_v2 + .as_ref() + .ok_or("No input method manager v2")?; + let vk_manager = self + .globals + .vk_manager + .as_ref() + .ok_or("No virtual keyboard manager")?; + + let im = im_manager.get_input_method(seat, qh, ()); + let grab = im.grab_keyboard(qh, ()); + let vk = vk_manager.create_virtual_keyboard(seat, qh, ()); + + self.im_v2 = Some(InputMethodV2State { + im, + grab, + vk, + pending_activate: false, + pending_deactivate: false, + current_activate: false, + current_deactivate: false, + grab_activate: false, + keymap_init: false, + }); + + Ok(()) + } + + pub fn setup_input_method_v1(&mut self, _qh: &QueueHandle) -> Result<(), Box> { + // v1 is already bound through registry in Dispatch + // The actual context activation happens via the Activate event + if self.globals.im_v1.is_none() { + return Err("No input method v1".into()); + } + + self.im_v1 = Some(InputMethodV1State { + im_ctx: None, + keyboard: None, + keymap: None, + grab_activate: false, + }); + + Ok(()) + } + + pub fn run_event_loop(mut self, conn: &Connection, mut event_queue: EventQueue) { + let mut poll = Poll::new().expect("Initialize epoll()"); + let registry = poll.registry(); + + const POLL_WAYLAND: Token = Token(0); + registry + .register( + &mut SourceFd(&conn.as_fd().as_raw_fd()), + POLL_WAYLAND, + Interest::READABLE | Interest::WRITABLE, + ) + .expect("Register wayland socket to the epoll()"); + + const POLL_TIMER: Token = Token(1); + registry + .register(&mut self.timer, POLL_TIMER, Interest::READABLE) + .expect("Register timer to the epoll()"); + + let mut events = MioEvents::with_capacity(1024); + + loop { + // Flush pending writes first + if let Err(e) = conn.flush() { + if let wayland_client::backend::WaylandError::Io(ref io_err) = e { + if io_err.kind() != std::io::ErrorKind::WouldBlock { + log::error!("Connection flush error: {}", e); + break; + } + } else { + log::error!("Connection flush error: {}", e); + break; + } + } + + // Sleep until next event + if let Err(e) = poll.poll(&mut events, None) { + if e.kind() == std::io::ErrorKind::Interrupted { + continue; + } + log::error!("Poll error: {}", e); + break; + } + + for event in &events { + match event.token() { + POLL_WAYLAND => { + // Read events - prepare_read returns Option + if let Some(guard) = conn.prepare_read() { + if let Err(e) = guard.read() { + if let wayland_client::backend::WaylandError::Io(ref io_err) = e { + if io_err.kind() != std::io::ErrorKind::WouldBlock { + log::error!("Read error: {}", e); + return; + } + } else { + log::error!("Read error: {}", e); + return; + } + } + } + + // Dispatch pending events + if let Err(e) = event_queue.dispatch_pending(&mut self) { + log::error!("Dispatch error: {}", e); + return; + } + + // Check if we should exit (e.g., Unavailable event) + if self.should_exit { + log::info!("Exiting due to should_exit flag"); + return; + } + } + POLL_TIMER => { + if let Err(e) = self.handle_timer_ev() { + log::error!("Timer error: {}", e); + return; + } + } + _ => unreachable!(), + } + } + } + } + + fn handle_timer_ev(&mut self) -> std::io::Result<()> { + let overrun_count = self.timer.read()?; + if overrun_count == 0 { + return Ok(()); + } + if overrun_count != 1 { + log::warn!("Some timer events were not properly handled!"); + } + + if let Some(( + info, + PressState::Pressing { + pressed_at, + ref mut is_repeating, + key, + wayland_time, + }, + )) = self.repeat_state + { + // Check if key should repeat (v1 uses keymap, v2 always repeats) + let should_start_repeat = if let Some(ref im_state) = self.im_v1 { + im_state + .keymap + .as_ref() + .map_or(true, |km| km.key_repeats(Keycode::new(key + 8))) + } else { + true + }; + + if !*is_repeating && should_start_repeat { + log::trace!("Start repeating {}", key); + let interval = Duration::from_secs_f64(1.0 / info.rate as f64); + self.timer.set_timeout_interval(interval, interval)?; + *is_repeating = true; + } + + // Emit key repeat event + let elapsed_ms = pressed_at.elapsed().as_millis() as u32; + let _time = wayland_time.wrapping_add(elapsed_ms); + + // Handle v2 + if let Some(ref mut im_state) = self.im_v2 { + if im_state.grab_activate { + let hwcode = (key + 8) as u16; + if let Some(code) = KeyCode::from_hardware_code(hwcode, self.numlock) { + let ret = self + .engine + .press_key(Key::new(code, self.mod_state), &self.config); + self.process_input_result_v2(ret); + } + } + } + + // Handle v1 + let v1_grab_activate = self + .im_v1 + .as_ref() + .map(|s| s.grab_activate) + .unwrap_or(false); + if v1_grab_activate { + let hwcode = (key + 8) as u16; + if let Some(code) = KeyCode::from_hardware_code(hwcode, self.numlock) { + let ret = self + .engine + .press_key(Key::new(code, self.mod_state), &self.config); + self.process_input_result_v1(ret); + } + } + } + + Ok(()) + } + + fn process_input_result_v2(&mut self, ret: InputResult) -> bool { + if ret.contains(InputResult::NOT_READY) { + self.engine_ready = false; + } + + if ret.contains(InputResult::LANGUAGE_CHANGED) { + self.engine.update_layout_state().ok(); + } + + if let Some(ref im_state) = self.im_v2 { + if ret.contains(InputResult::HAS_PREEDIT) { + let preedit = self.engine.preedit_str(); + let len = preedit.len(); + im_state + .im + .set_preedit_string(preedit.into(), 0, len as i32); + self.last_preedit_len = len; + } else if self.last_preedit_len > 0 { + im_state.im.set_preedit_string(String::new(), -1, -1); + self.last_preedit_len = 0; + } + + if ret.contains(InputResult::HAS_COMMIT) { + let commit_str = self.engine.commit_str(); + if !commit_str.is_empty() { + im_state.im.commit_string(commit_str.into()); + } + self.engine.clear_commit(); + } + + im_state.im.commit(self.serial); + } + + !ret.contains(InputResult::CONSUMED) + } + + fn process_input_result_v1(&mut self, ret: InputResult) -> bool { + if ret.contains(InputResult::NOT_READY) { + self.engine_ready = false; + } + + if ret.contains(InputResult::LANGUAGE_CHANGED) { + self.engine.update_layout_state().ok(); + } + + if let Some(ref im_state) = self.im_v1 { + if let Some(ref im_ctx) = im_state.im_ctx { + if ret.contains(InputResult::HAS_COMMIT) { + let commit_str = self.engine.commit_str(); + if !commit_str.is_empty() { + im_ctx.commit_string(self.serial, commit_str.into()); + } + self.engine.clear_commit(); + } + + if ret.contains(InputResult::HAS_PREEDIT) { + let preedit = self.engine.preedit_str(); + let len = preedit.len(); + im_ctx.preedit_cursor(len as i32); + im_ctx.preedit_styling( + 0, + len as u32, + ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_UNDERLINE, + ); + im_ctx.preedit_string(self.serial, preedit.to_string(), preedit.into()); + self.last_preedit_len = len; + } else if self.last_preedit_len > 0 { + im_ctx.preedit_cursor(0); + im_ctx.preedit_string(self.serial, String::new(), String::new()); + self.last_preedit_len = 0; + } + } + } + + !ret.contains(InputResult::CONSUMED) + } + + fn key_v1(&mut self, time: u32, key: u32, state: KeyState) { + if let Some(ref im_state) = self.im_v1 { + if let Some(ref im_ctx) = im_state.im_ctx { + im_ctx.key(self.serial, time, key, state as u32); + } + } + } + + fn modifiers_v1( + &mut self, + mods_depressed: u32, + mods_latched: u32, + mods_locked: u32, + group: u32, + ) { + if let Some(ref im_state) = self.im_v1 { + if let Some(ref im_ctx) = im_state.im_ctx { + im_ctx.modifiers( + self.serial, + mods_depressed, + mods_latched, + mods_locked, + group, + ); + } + } + } +} + +// Registry dispatch +impl Dispatch for AppState { + fn event( + state: &mut Self, + registry: &WlRegistry, + event: wl_registry::Event, + _data: &(), + _conn: &Connection, + qh: &QueueHandle, + ) { + if let wl_registry::Event::Global { + name, + interface, + version, + } = event + { + log::debug!("Registry global [{}]: {} v{}", name, interface, version); + match interface.as_str() { + "wl_seat" => { + log::debug!("Binding wl_seat"); + let seat = registry.bind::(name, version.min(7), qh, ()); + state.globals.seat = Some(seat); + } + "zwp_input_method_manager_v2" => { + log::debug!("Binding zwp_input_method_manager_v2"); + let mgr = registry.bind::( + name, + version.min(1), + qh, + (), + ); + state.globals.im_manager_v2 = Some(mgr); + } + "zwp_virtual_keyboard_manager_v1" => { + log::debug!("Binding zwp_virtual_keyboard_manager_v1"); + let mgr = registry.bind::( + name, + version.min(1), + qh, + (), + ); + state.globals.vk_manager = Some(mgr); + } + "zwp_input_method_v1" => { + log::debug!("Binding zwp_input_method_v1"); + let im = registry.bind::(name, version.min(1), qh, ()); + state.globals.im_v1 = Some(im); + } + _ => {} + } + } + } +} + +// Seat dispatch (no-op, just need to bind) +impl Dispatch for AppState { + fn event( + _state: &mut Self, + _seat: &WlSeat, + _event: wl_seat::Event, + _data: &(), + _conn: &Connection, + _qh: &QueueHandle, + ) { + } +} + +// Input method manager v2 dispatch (no events) +delegate_noop!(AppState: ignore ZwpInputMethodManagerV2); +delegate_noop!(AppState: ignore ZwpVirtualKeyboardManagerV1); +delegate_noop!(AppState: ignore ZwpVirtualKeyboardV1); + +// Input method v2 dispatch +impl Dispatch for AppState { + fn event( + state: &mut Self, + _im: &ZwpInputMethodV2, + event: zwp_input_method_v2::Event, + _data: &(), + _conn: &Connection, + _qh: &QueueHandle, + ) { + log::trace!("input_method_v2 event: {:?}", event); + match event { + zwp_input_method_v2::Event::Activate => { + if let Some(ref mut im_state) = state.im_v2 { + im_state.pending_activate = true; + } + } + zwp_input_method_v2::Event::Deactivate => { + if let Some(ref mut im_state) = state.im_v2 { + im_state.pending_deactivate = true; + } + } + zwp_input_method_v2::Event::Unavailable => { + log::error!("Receive Unavailable event, is another server already running?"); + state.should_exit = true; + } + zwp_input_method_v2::Event::Done => { + state.serial += 1; + + let (should_activate, should_deactivate) = { + if let Some(ref im_state) = state.im_v2 { + let activate = !im_state.current_activate && im_state.pending_activate; + let deactivate = + !im_state.current_deactivate && im_state.pending_deactivate; + (activate, deactivate) + } else { + (false, false) + } + }; + + if should_activate { + state.engine.update_layout_state().ok(); + if !state.engine_ready && state.engine.check_ready() { + let ret = state.engine.end_ready(); + state.process_input_result_v2(ret); + state.engine_ready = true; + } + if let Some(ref mut im_state) = state.im_v2 { + im_state.grab_activate = true; + } + } else if should_deactivate { + if state.engine_ready { + state.engine.reset(); + } + if let Some(ref mut im_state) = state.im_v2 { + im_state.grab_activate = false; + } + let _ = state.timer.set_timeout_oneshot(Duration::ZERO); + if let Some((_, ref mut ps)) = state.repeat_state { + *ps = PressState::NotPressing; + } + } + + if let Some(ref mut im_state) = state.im_v2 { + im_state.current_activate = im_state.pending_activate; + im_state.current_deactivate = im_state.pending_deactivate; + im_state.pending_activate = false; + im_state.pending_deactivate = false; + } + } + _ => {} + } + } +} + +// Keyboard grab v2 dispatch +impl Dispatch for AppState { + fn event( + state: &mut Self, + _grab: &ZwpInputMethodKeyboardGrabV2, + event: zwp_input_method_keyboard_grab_v2::Event, + _data: &(), + _conn: &Connection, + _qh: &QueueHandle, + ) { + match event { + zwp_input_method_keyboard_grab_v2::Event::Keymap { format, fd, size } => { + if let Some(ref mut im_state) = state.im_v2 { + if !im_state.keymap_init { + im_state.vk.keymap(format.into(), fd.as_fd(), size); + im_state.keymap_init = true; + } + } + } + zwp_input_method_keyboard_grab_v2::Event::Key { + time, + key, + state: key_state, + .. + } => { + let is_pressed = matches!(key_state, WEnum::Value(KeyState::Pressed)) + || key_state == WEnum::Value(KeyState::Pressed) + || matches!(&key_state, WEnum::Unknown(2)); // Repeated + + let grab_activate = state + .im_v2 + .as_ref() + .map(|s| s.grab_activate) + .unwrap_or(false); + + if is_pressed && grab_activate { + let hwcode = (key + 8) as u16; + if let Some(code) = KeyCode::from_hardware_code(hwcode, state.numlock) { + let ret = state + .engine + .press_key(Key::new(code, state.mod_state), &state.config); + + let bypassed = state.process_input_result_v2(ret); + + if bypassed { + if let Some(ref im_state) = state.im_v2 { + im_state.vk.key(time, key, key_state.into()); + } + } else { + // Handle key repeat + if let Some((info, ref mut press_state)) = state.repeat_state { + if !press_state.is_pressing(key) { + let duration = Duration::from_millis(info.delay as u64); + if let Err(e) = state.timer.set_timeout_oneshot(duration) { + log::warn!("failed to set repeat timer: {}", e); + } + *press_state = PressState::Pressing { + pressed_at: Instant::now(), + is_repeating: false, + key, + wayland_time: time, + }; + } + } + } + } else if let Some(ref im_state) = state.im_v2 { + im_state.vk.key(time, key, key_state.into()); + } + } else if matches!(key_state, WEnum::Value(KeyState::Released)) { + if let Some((.., ref mut press_state)) = state.repeat_state { + if press_state.is_pressing(key) { + let _ = state.timer.set_timeout_oneshot(Duration::ZERO); + *press_state = PressState::NotPressing; + } + } + if let Some(ref im_state) = state.im_v2 { + im_state.vk.key(time, key, key_state.into()); + } + } else { + // is_pressed && !grab_activate - bypass + if let Some(ref im_state) = state.im_v2 { + im_state.vk.key(time, key, key_state.into()); + } + } + } + zwp_input_method_keyboard_grab_v2::Event::Modifiers { + mods_depressed, + mods_latched, + mods_locked, + group, + .. + } => { + state.mod_state = ModifierState::empty(); + if mods_depressed & 0x1 != 0 { + state.mod_state |= ModifierState::SHIFT; + } + if mods_depressed & 0x4 != 0 { + state.mod_state |= ModifierState::CONTROL; + } + if mods_depressed & 0x8 != 0 { + state.mod_state |= ModifierState::ALT; + } + if mods_depressed & 0x40 != 0 { + state.mod_state |= ModifierState::SUPER; + } + state.numlock = mods_depressed & 0x10 != 0; + + if let Some(ref im_state) = state.im_v2 { + im_state + .vk + .modifiers(mods_depressed, mods_latched, mods_locked, group); + } + } + zwp_input_method_keyboard_grab_v2::Event::RepeatInfo { rate, delay } => { + state.repeat_state = if rate == 0 { + None + } else { + let info = RepeatInfo { rate, delay }; + let press_state = state + .repeat_state + .map(|pair| pair.1) + .unwrap_or(PressState::NotPressing); + Some((info, press_state)) + }; + } + _ => {} + } + } +} + +// Input method v1 dispatch +impl Dispatch for AppState { + event_created_child!(AppState, ZwpInputMethodV1, [ + // opcode 0 = activate event, creates ZwpInputMethodContextV1 + 0 => (ZwpInputMethodContextV1, ()) + ]); + + fn event( + state: &mut Self, + _im: &ZwpInputMethodV1, + event: zwp_input_method_v1::Event, + _data: &(), + _conn: &Connection, + qh: &QueueHandle, + ) { + match event { + zwp_input_method_v1::Event::Activate { id: im_ctx } => { + log::trace!("input_method_v1: Activate"); + state.engine.update_layout_state().ok(); + if !state.engine_ready && state.engine.check_ready() { + let ret = state.engine.end_ready(); + state.process_input_result_v1(ret); + state.engine_ready = true; + } + + // Grab keyboard + let keyboard = im_ctx.grab_keyboard(qh, ()); + + if let Some(ref mut im_state) = state.im_v1 { + im_state.im_ctx = Some(im_ctx); + im_state.keyboard = Some(keyboard); + im_state.grab_activate = true; + } + } + zwp_input_method_v1::Event::Deactivate { context: im_ctx } => { + log::trace!("input_method_v1: Deactivate"); + if state.engine_ready { + state.engine.reset(); + } + + // Stop repeating + let _ = state.timer.set_timeout_oneshot(Duration::ZERO); + if let Some((_, ref mut press_state)) = state.repeat_state { + *press_state = PressState::NotPressing; + } + + im_ctx.destroy(); + + if let Some(ref mut im_state) = state.im_v1 { + im_state.im_ctx = None; + if let Some(ref keyboard) = im_state.keyboard { + if keyboard.version() >= wl_keyboard::REQ_RELEASE_SINCE { + keyboard.release(); + } + } + im_state.keyboard = None; + im_state.grab_activate = false; + } + } + _ => {} + } + } +} + +// Input method context v1 dispatch +impl Dispatch for AppState { + fn event( + state: &mut Self, + _im_ctx: &ZwpInputMethodContextV1, + event: zwp_input_method_context_v1::Event, + _data: &(), + _conn: &Connection, + _qh: &QueueHandle, + ) { + match event { + zwp_input_method_context_v1::Event::CommitState { serial } => { + state.serial = serial; + } + _ => {} + } + } +} + +// WlKeyboard dispatch for v1 +impl Dispatch for AppState { + fn event( + state: &mut Self, + _keyboard: &WlKeyboard, + event: wl_keyboard::Event, + _data: &(), + _conn: &Connection, + _qh: &QueueHandle, + ) { + match event { + wl_keyboard::Event::Keymap { format, fd, size } => { + if let WEnum::Value(KeymapFormat::XkbV1) = format { + // fd is already OwnedFd in wayland-client 0.31, use it directly + if let Some(ref mut im_state) = state.im_v1 { + im_state.keymap = unsafe { + Keymap::new_from_fd( + &XkbContext::new(CONTEXT_NO_FLAGS), + fd, + size as usize, + KEYMAP_FORMAT_TEXT_V1, + KEYMAP_COMPILE_NO_FLAGS, + ) + .unwrap_or(None) + }; + } + } + } + wl_keyboard::Event::Key { + time, + key, + state: key_state, + .. + } => { + let is_pressed = matches!(key_state, WEnum::Value(KeyState::Pressed)) + || matches!(&key_state, WEnum::Unknown(2)); // Repeated + + let grab_activate = state + .im_v1 + .as_ref() + .map(|s| s.grab_activate) + .unwrap_or(false); + + if is_pressed && grab_activate { + let hwcode = (key + 8) as u16; + if let Some(code) = KeyCode::from_hardware_code(hwcode, state.numlock) { + let ret = state + .engine + .press_key(Key::new(code, state.mod_state), &state.config); + + let bypassed = state.process_input_result_v1(ret); + + if bypassed { + if let WEnum::Value(ks) = key_state { + state.key_v1(time, key, ks); + } + } else { + // Handle key repeat + if let Some((info, ref mut press_state)) = state.repeat_state { + if !press_state.is_pressing(key) { + let duration = Duration::from_millis(info.delay as u64); + if let Err(e) = state.timer.set_timeout_oneshot(duration) { + log::warn!("failed to set repeat timer: {}", e); + } + *press_state = PressState::Pressing { + pressed_at: Instant::now(), + is_repeating: false, + key, + wayland_time: time, + }; + } + } + } + } else if let WEnum::Value(ks) = key_state { + state.key_v1(time, key, ks); + } + } else if matches!(key_state, WEnum::Value(KeyState::Released)) { + if let Some((.., ref mut press_state)) = state.repeat_state { + if press_state.is_pressing(key) { + let _ = state.timer.set_timeout_oneshot(Duration::ZERO); + *press_state = PressState::NotPressing; + } + } + if let WEnum::Value(ks) = key_state { + state.key_v1(time, key, ks); + } + } else if let WEnum::Value(ks) = key_state { + // is_pressed && !grab_activate - bypass + state.key_v1(time, key, ks); + } + } + wl_keyboard::Event::Modifiers { + mods_depressed, + mods_latched, + mods_locked, + group, + .. + } => { + state.mod_state = ModifierState::empty(); + if mods_depressed & 0x1 != 0 { + state.mod_state |= ModifierState::SHIFT; + } + if mods_depressed & 0x4 != 0 { + state.mod_state |= ModifierState::CONTROL; + } + if mods_depressed & 0x8 != 0 { + state.mod_state |= ModifierState::ALT; + } + if mods_depressed & 0x40 != 0 { + state.mod_state |= ModifierState::SUPER; + } + state.numlock = mods_depressed & 0x10 != 0; + + state.modifiers_v1(mods_depressed, mods_latched, mods_locked, group); + } + wl_keyboard::Event::RepeatInfo { rate, delay } => { + state.repeat_state = if rate == 0 { + None + } else { + let info = RepeatInfo { rate, delay }; + let press_state = state + .repeat_state + .map(|pair| pair.1) + .unwrap_or(PressState::NotPressing); + Some((info, press_state)) + }; + } + _ => {} + } + } +} diff --git a/src/frontends/xim/Cargo.toml b/src/frontends/xim/Cargo.toml index a16bc98c..12673ae8 100644 --- a/src/frontends/xim/Cargo.toml +++ b/src/frontends/xim/Cargo.toml @@ -7,16 +7,19 @@ edition = "2021" license = "GPL-3.0-or-later" [dependencies] -kime-engine-cffi = { path = "../../engine/cffi" } +kime-engine-core = { path = "../../engine/core" } kime-version = { path = "../../tools/version" } -xim = { version = "0.2", default-features = false, features = ["x11rb-server"] } +xim = { version = "0.5", default-features = false, features = ["x11rb-server"] } # xim = { path = "../../../../xim-rs", default-features = false, features = ["x11rb-server", "x11rb-xcb"] } ahash = "0.8" -log = "0.4.11" -x11rb = { version = "0.11.0", features = ["render", "image"], default-features = false } +log = "0.4" +x11rb = { version = "0.13", features = [ + "render", + "image", +], default-features = false } pico-args = "0.5.0" -image = "0.24" -imageproc = "0.23" -rusttype = "0.9.2" +image = { version = "0.25", default-features = false, features = ["png"] } +imageproc = { version = "0.26", default-features = false, features = ["text"] } +ab_glyph = "0.2" diff --git a/src/frontends/xim/src/handler.rs b/src/frontends/xim/src/handler.rs index 3ac8d5a0..56537d77 100644 --- a/src/frontends/xim/src/handler.rs +++ b/src/frontends/xim/src/handler.rs @@ -1,7 +1,9 @@ -use std::{num::NonZeroU32, sync::Arc}; +use std::num::NonZeroU32; use crate::pe_window::PeWindow; +use ab_glyph::{FontArc, FontVec}; use ahash::AHashMap; +use kime_engine_core::{Config, InputEngine, InputResult, Key, KeyCode, ModifierState}; use x11rb::{ connection::Connection, protocol::xproto::{ConfigureNotifyEvent, KeyButMask, KeyPressEvent, KEY_PRESS_EVENT}, @@ -11,8 +13,6 @@ use xim::{ InputStyle, Server, ServerHandler, }; -use kime_engine_cffi::*; - pub struct KimeData { engine: InputEngine, pe: Option, @@ -33,25 +33,34 @@ impl KimeData { pub struct KimeHandler { preedit_windows: AHashMap, - font: (Arc>, f32), + font: Option<(FontArc, f32)>, config: Config, screen_num: usize, } impl KimeHandler { pub fn new(screen_num: usize, config: Config) -> Self { - let (font_data, index, font_size) = config.xim_font(); - let font = Arc::new( - rusttype::Font::try_from_vec_and_index(font_data.to_vec(), index) - .unwrap() - .to_owned(), - ); + let (font_data, index, font_size) = &config.xim_preedit_font; + // The preedit font can be missing (e.g. neither the configured + // `xim_preedit_font` nor the fallback is installed), in which case + // `load_font` yields empty data and parsing fails. Degrade gracefully + // by disabling the preedit popup window instead of panicking. See #706. + let font = match FontVec::try_from_vec_and_index(font_data.clone(), *index) { + Ok(font_vec) => Some((FontArc::from(font_vec), *font_size)), + Err(err) => { + log::warn!( + "Failed to load xim preedit font; preedit window is disabled: {}", + err + ); + None + } + }; Self { preedit_windows: AHashMap::new(), - config, screen_num, - font: (font, font_size), + font, + config, } } } @@ -112,6 +121,12 @@ impl KimeHandler { return Ok(()); } + // No usable preedit font was loaded; skip the popup window. See #706. + let font = match self.font.clone() { + Some(font) => font, + None => return Ok(()), + }; + if let Some(pe) = user_ic.user_data.pe.as_mut() { // Draw in server (already have pe_window) let pe = self.preedit_windows.get_mut(pe).unwrap(); @@ -121,7 +136,7 @@ impl KimeHandler { // Draw in server let mut pe = PeWindow::new( server.conn(), - self.font.clone(), + font, user_ic.ic.app_win(), user_ic.ic.preedit_spot(), self.screen_num, @@ -155,30 +170,30 @@ impl KimeHandler { &mut self, server: &mut X11rbServer, user_ic: &mut xim::UserInputContext, - ret: kime_engine_cffi::InputResult, + ret: InputResult, ) -> Result { log::trace!("{:?}", ret); - if ret & InputResult_LANGUAGE_CHANGED != 0 { - user_ic.user_data.engine.update_layout_state(); + if ret.contains(InputResult::LANGUAGE_CHANGED) { + user_ic.user_data.engine.update_layout_state().ok(); } - if ret & InputResult_HAS_PREEDIT == 0 { + if !ret.contains(InputResult::HAS_PREEDIT) { self.clear_preedit(server, user_ic)?; } - if ret & InputResult_HAS_COMMIT != 0 { + if ret.contains(InputResult::HAS_COMMIT) { self.commit(server, user_ic)?; user_ic.user_data.engine.clear_commit(); } - if ret & InputResult_HAS_PREEDIT != 0 { + if ret.contains(InputResult::HAS_PREEDIT) { self.preedit(server, user_ic)?; } - user_ic.user_data.engine_ready = ret & InputResult_NOT_READY == 0; + user_ic.user_data.engine_ready = !ret.contains(InputResult::NOT_READY); - Ok(ret & InputResult_CONSUMED != 0) + Ok(ret.contains(InputResult::CONSUMED)) } fn clear_preedit( @@ -321,7 +336,7 @@ impl ServerHandler> for KimeHandler { log::trace!("{:?}", xev); - let mut state = 0; + let mut state = ModifierState::empty(); macro_rules! check_flag { ($mask:ident) => { @@ -330,30 +345,33 @@ impl ServerHandler> for KimeHandler { } if check_flag!(SHIFT) { - state |= ModifierState_SHIFT; + state.insert(ModifierState::SHIFT); } if check_flag!(CONTROL) { - state |= ModifierState_CONTROL; + state.insert(ModifierState::CONTROL); } if check_flag!(MOD1) { - state |= ModifierState_ALT; + state.insert(ModifierState::ALT); } let numlock = check_flag!(MOD2); if check_flag!(MOD4) { - state |= ModifierState_SUPER; + state.insert(ModifierState::SUPER); } - let ret = - user_ic + if let Some(keycode) = KeyCode::from_hardware_code(xev.detail as u16, numlock) { + let ret = user_ic .user_data .engine - .press_key(&self.config, xev.detail as u16, numlock, state); - - self.process_input_result(server, user_ic, ret) + .press_key(Key::new(keycode, state), &self.config); + self.process_input_result(server, user_ic, ret) + } else { + log::warn!("Unknown hardware keycode: {}", xev.detail); + return Ok(false); + } } fn handle_destroy_ic( @@ -378,7 +396,7 @@ impl ServerHandler> for KimeHandler { server: &mut X11rbServer, user_ic: &mut xim::UserInputContext, ) -> Result<(), xim::ServerError> { - user_ic.user_data.engine.update_layout_state(); + user_ic.user_data.engine.update_layout_state().ok(); if !user_ic.user_data.engine_ready { if user_ic.user_data.engine.check_ready() { @@ -403,3 +421,27 @@ impl ServerHandler> for KimeHandler { } } } + +#[cfg(test)] +mod tests { + use super::KimeHandler; + use kime_engine_core::Config; + + /// Regression test for #706: when the preedit font cannot be loaded + /// (`load_font` returns empty data because no matching font is installed), + /// constructing the handler must not panic. Instead the preedit window is + /// disabled (`font == None`). + #[test] + fn missing_preedit_font_does_not_panic() { + let mut config = Config::default(); + // Simulate a missing font: empty data, as produced by + // `load_font(...).unwrap_or_default()` when no face matches. + config.xim_preedit_font = (Vec::new(), 0, 15.0); + + let handler = KimeHandler::new(0, config); + assert!( + handler.font.is_none(), + "preedit window should be disabled when the font is missing" + ); + } +} diff --git a/src/frontends/xim/src/main.rs b/src/frontends/xim/src/main.rs index e18a2423..67e7c586 100644 --- a/src/frontends/xim/src/main.rs +++ b/src/frontends/xim/src/main.rs @@ -10,12 +10,7 @@ mod pe_window; fn main() { kime_version::cli_boilerplate!((),); - assert!( - kime_engine_cffi::check_api_version(), - "Engine version mismatched" - ); - - let config = kime_engine_cffi::Config::load(); + let config = kime_engine_core::load_engine_config_from_config_dir().unwrap_or_default(); let (conn, screen_num) = x11rb::rust_connection::RustConnection::connect(None).expect("Connect X"); diff --git a/src/frontends/xim/src/pe_window.rs b/src/frontends/xim/src/pe_window.rs index ef244f62..ab8271b7 100644 --- a/src/frontends/xim/src/pe_window.rs +++ b/src/frontends/xim/src/pe_window.rs @@ -1,10 +1,10 @@ mod bgra; use bgra::Bgra; -use std::{num::NonZeroU32, sync::Arc}; +use std::num::NonZeroU32; +use ab_glyph::{FontArc, PxScale}; use image::ImageBuffer; -use rusttype::Font; use x11rb::{ connection::Connection, protocol::xproto::{ @@ -19,15 +19,15 @@ pub struct PeWindow { preedit: String, gc: u32, text_pos: (u32, u32), - text_scale: rusttype::Scale, - font: Arc>, + text_scale: PxScale, + font: FontArc, image_buffer: ImageBuffer>, } impl PeWindow { pub fn new( conn: &impl Connection, - (font, font_size): (Arc>, f32), + (font, font_size): (FontArc, f32), app_win: Option, spot_location: xim::Point, screen_num: usize, @@ -102,7 +102,7 @@ impl PeWindow { gc, font, text_pos: ((font_size * 0.36) as _, (font_size * 0.36) as _), - text_scale: rusttype::Scale::uniform(font_size as f32), + text_scale: PxScale::from(font_size), image_buffer: ImageBuffer::new(size.0 as _, size.1 as _), }) } diff --git a/src/tools/candidate-window/Cargo.toml b/src/tools/candidate-window/Cargo.toml index 837512cf..e509813b 100644 --- a/src/tools/candidate-window/Cargo.toml +++ b/src/tools/candidate-window/Cargo.toml @@ -8,6 +8,6 @@ license = "GPL-3.0-or-later" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -kime-engine-cffi = { path = "../../engine/cffi" } -eframe = "0.20.1" -egui = "0.20.1" +kime-engine-core = { path = "../../engine/core" } +eframe = { version = "0.33", default-features = false, features = ["glow", "default_fonts", "wayland", "x11"] } +egui = "0.33" diff --git a/src/tools/candidate-window/src/main.rs b/src/tools/candidate-window/src/main.rs index 8e25b688..0d7a51ee 100644 --- a/src/tools/candidate-window/src/main.rs +++ b/src/tools/candidate-window/src/main.rs @@ -1,6 +1,7 @@ use std::{ collections::BTreeMap, io::{self, BufRead, Stdout, Write}, + sync::Arc, }; use egui::Widget; @@ -22,15 +23,15 @@ struct CandidateApp { } impl eframe::App for CandidateApp { - fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) { - if ctx.input().key_down(egui::Key::Escape) || ctx.input().key_down(egui::Key::Q) { - frame.close(); + fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { + if ctx.input(|i| i.key_down(egui::Key::Escape)) || ctx.input(|i| i.key_down(egui::Key::Q)) { + ctx.send_viewport_cmd(egui::ViewportCommand::Close); return; } macro_rules! num_hotkey { ($k:expr, $n:expr) => { - if ctx.input().key_down($k) { + if ctx.input(|i| i.key_down($k)) { self.page_index = $n; } }; @@ -47,26 +48,32 @@ impl eframe::App for CandidateApp { num_hotkey!(egui::Key::Num9, 8); num_hotkey!(egui::Key::Num0, 9); - if ctx.input().key_down(egui::Key::ArrowLeft) || ctx.input().key_down(egui::Key::H) { + if ctx.input(|i| i.key_down(egui::Key::ArrowLeft)) + || ctx.input(|i| i.key_down(egui::Key::H)) + { if !self.key_state.left { self.page_index = self.page_index.saturating_sub(1); self.key_state.left = true; } } - if ctx.input().key_released(egui::Key::ArrowLeft) || ctx.input().key_released(egui::Key::H) + if ctx.input(|i| i.key_released(egui::Key::ArrowLeft)) + || ctx.input(|i| i.key_released(egui::Key::H)) { self.key_state.left = false; } - if ctx.input().key_down(egui::Key::ArrowRight) || ctx.input().key_down(egui::Key::L) { + if ctx.input(|i| i.key_down(egui::Key::ArrowRight)) + || ctx.input(|i| i.key_down(egui::Key::L)) + { if !self.key_state.right { self.page_index = self.page_index.saturating_add(1).min(self.max_page_index); self.key_state.right = true; } } - if ctx.input().key_released(egui::Key::ArrowRight) || ctx.input().key_released(egui::Key::L) + if ctx.input(|i| i.key_released(egui::Key::ArrowRight)) + || ctx.input(|i| i.key_released(egui::Key::L)) { self.key_state.right = false; } @@ -91,7 +98,7 @@ impl eframe::App for CandidateApp { if quitted { self.stdout.write_all(key.as_bytes()).unwrap(); - frame.close(); + ctx.send_viewport_cmd(egui::ViewportCommand::Close); return; } } @@ -119,8 +126,6 @@ impl eframe::App for CandidateApp { } fn main() -> io::Result<()> { - assert!(kime_engine_cffi::check_api_version()); - let mut buf = String::with_capacity(4096); let stdin = io::stdin(); let stdout = io::stdout(); @@ -148,21 +153,21 @@ fn main() -> io::Result<()> { eframe::run_native( "kime-candidate", eframe::NativeOptions { - always_on_top: true, - decorated: false, - icon_data: None, - initial_window_size: Some(egui::vec2(400.0, 400.0)), + viewport: egui::ViewportBuilder::default() + .with_inner_size([400.0, 400.0]) + .with_decorations(false) + .with_window_level(egui::WindowLevel::AlwaysOnTop), ..Default::default() }, Box::new(|cc| { - let config = kime_engine_cffi::Config::load(); - let (font_bytes, _index) = config.candidate_font(); - let mut font_data = BTreeMap::<_, egui::FontData>::new(); + let config = kime_engine_core::load_engine_config_from_config_dir().unwrap_or_default(); + let (font_bytes, _index) = config.candidate_font; + let mut font_data = BTreeMap::<_, Arc>::new(); let mut families = BTreeMap::new(); font_data.insert( "Font".to_string(), - egui::FontData::from_owned(font_bytes.to_vec()), + Arc::new(egui::FontData::from_owned(font_bytes.to_vec())), ); families.insert(egui::FontFamily::Proportional, vec!["Font".to_string()]); @@ -173,7 +178,7 @@ fn main() -> io::Result<()> { families, }); - Box::new(CandidateApp { + Ok(Box::new(CandidateApp { stdout, page_index: 0, key_state: KeyState::default(), @@ -183,9 +188,10 @@ fn main() -> io::Result<()> { candidate_list.len() / PAGE_SIZE }, candidate_list, - }) + })) }), - ); + ) + .map_err(|e| io::Error::new(io::ErrorKind::Other, e.to_string()))?; Ok(()) } diff --git a/src/tools/check/Cargo.toml b/src/tools/check/Cargo.toml index 06e29646..a206cd68 100644 --- a/src/tools/check/Cargo.toml +++ b/src/tools/check/Cargo.toml @@ -6,10 +6,9 @@ edition = "2021" license = "GPL-3.0-or-later" [dependencies] -ansi_term = "0.12.1" -kime-engine-cffi = { path = "../../engine/cffi" } +owo-colors = "4" kime-engine-core = { path = "../../engine/core" } pad = "0.1.6" serde_yaml = "0.9" -strum = { version = "0.24", features = ["derive"] } -xdg = "2.2.0" +strum = { version = "0.27", features = ["derive"] } +xdg = "3.0" diff --git a/src/tools/check/src/main.rs b/src/tools/check/src/main.rs index 9d4cbbbe..f67f64d4 100644 --- a/src/tools/check/src/main.rs +++ b/src/tools/check/src/main.rs @@ -1,10 +1,7 @@ -use kime_engine_core::{Key, KeyMap}; +use kime_engine_core::{load_engine_config_from_config_dir, Key, KeyCode, KeyMap}; -use ansi_term::Color; -use kime_engine_cffi::{ - Config, InputCategory, InputEngine, InputResult_CONSUMED, InputResult_HAS_COMMIT, - InputResult_HAS_PREEDIT, -}; +use kime_engine_core::{Config, InputCategory, InputEngine, InputResult}; +use owo_colors::{OwoColorize, Style}; use pad::PadStr; use std::env; use std::io::BufRead; @@ -22,33 +19,31 @@ impl CondResult { matches!(self, Self::Ok | Self::Ignore(..)) } - pub fn color(&self) -> Color { + pub fn style(&self) -> Style { match self { - CondResult::Ok => Color::Green, - CondResult::Fail(..) => Color::Red, - CondResult::Ignore(..) => Color::Purple, + CondResult::Ok => Style::new().green(), + CondResult::Fail(..) => Style::new().red(), + CondResult::Ignore(..) => Style::new().purple(), } } pub fn print(&self, message: &str) { - let c = self.color(); + let s = self.style(); print!( "{} {}", - c.paint(<&str>::from(self).pad_to_width(8)), - Color::White.bold().paint(message.pad_to_width(40)) + <&str>::from(self).pad_to_width(8).style(s), + message.pad_to_width(40).bold().white() ); match self { CondResult::Ok => println!(), - CondResult::Fail(msg) | CondResult::Ignore(msg) => println!("({})", c.paint(msg)), + CondResult::Fail(msg) | CondResult::Ignore(msg) => println!("({})", msg.style(s)), } } } #[derive(Clone, Copy, EnumIter, EnumMessage)] enum Check { - #[strum(message = "Engine api version")] - ApiVersion, #[strum(message = "Check icons exists")] Icons, #[strum(message = "Config file")] @@ -70,16 +65,8 @@ enum Check { impl Check { pub fn cond(self) -> CondResult { match self { - Check::ApiVersion => { - println!("KIME_API_VERSION: {}", kime_engine_cffi::KIME_API_VERSION); - if kime_engine_cffi::check_api_version() { - CondResult::Ok - } else { - CondResult::Fail("Install correct kime engine".into()) - } - } Check::Icons => { - let dirs = xdg::BaseDirectories::new().expect("Load xdg dirs"); + let dirs = xdg::BaseDirectories::new(); let icons = &[ "kime-hangul-black.png", @@ -91,15 +78,15 @@ impl Check { for icon in icons { match dirs.find_data_file(format!("icons/hicolor/64x64/apps/{}", icon)) { Some(path) => println!("Found icon: {}", path.display()), - _ => return CondResult::Fail(format!("Can't find icon {}", icon)), + None => return CondResult::Fail(format!("Can't find icon {}", icon)), } } CondResult::Ok } Check::EngineWorks => { - let config = kime_engine_cffi::Config::default(); - let mut engine = kime_engine_cffi::InputEngine::new(&config); + let config = load_engine_config_from_config_dir().unwrap_or_default(); + let mut engine = InputEngine::new(&config); check_input( &mut engine, @@ -117,8 +104,8 @@ impl Check { ) } Check::Config => { - let dirs = xdg::BaseDirectories::with_prefix("kime").expect("Load xdg dirs"); - let config_path = match dirs.find_config_file("config.yaml") { + let dirs = xdg::BaseDirectories::with_prefix("kime"); + let config_path: std::path::PathBuf = match dirs.find_config_file("config.yaml") { Some(path) => path, _ => { return CondResult::Ignore( @@ -138,7 +125,7 @@ impl Check { match config.engine.translation_layer { Some(ref raw_path) => { - let path = match dirs.find_config_file(raw_path) { + let path: std::path::PathBuf = match dirs.find_config_file(raw_path) { Some(path) => path, _ => { return CondResult::Ignore( @@ -190,8 +177,8 @@ impl Check { let current_desktop = env::var("XDG_CURRENT_DESKTOP").map_or(String::new(), |x| x); let session_type = env::var("XDG_SESSION_TYPE").map_or(String::new(), |x| x); if current_desktop.contains("KDE") && session_type == "wayland" { - let dirs = xdg::BaseDirectories::new().expect("Load xdg dirs"); - let config_path = match dirs.find_config_file("kwinrc") { + let dirs = xdg::BaseDirectories::new(); + let config_path: std::path::PathBuf = match dirs.find_config_file("kwinrc") { Some(path) => path, _ => { return CondResult::Fail( @@ -249,20 +236,23 @@ fn check_input( engine.set_input_category(InputCategory::Hangul); for (key, preedit, commit) in tests.iter().copied() { - let ret = engine.press_key(config, key, false, 0); + let ret = engine.press_key( + Key::normal(KeyCode::from_hardware_code(key, false).unwrap()), + config, + ); let preedit_ret; let commit_ret; - if ret & InputResult_HAS_PREEDIT != 0 { + if ret.contains(InputResult::HAS_PREEDIT) { preedit_ret = preedit == engine.preedit_str(); } else { preedit_ret = preedit.is_empty(); } - if ret & InputResult_CONSUMED == 0 { + if !ret.contains(InputResult::CONSUMED) { commit_ret = commit == format!("{}PASS", engine.commit_str()); - } else if ret & InputResult_HAS_COMMIT != 0 { + } else if ret.contains(InputResult::HAS_COMMIT) { commit_ret = commit == engine.commit_str(); engine.clear_commit(); } else { diff --git a/src/tools/indicator/Cargo.toml b/src/tools/indicator/Cargo.toml index 3aba21fe..6539ddfa 100644 --- a/src/tools/indicator/Cargo.toml +++ b/src/tools/indicator/Cargo.toml @@ -6,11 +6,12 @@ edition = "2021" license = "GPL-3.0-or-later" [dependencies] -kime-engine-cffi = { path = "../../engine/cffi" } +kime-engine-core = { path = "../../engine/core" } kime-version = { path = "../version" } kime-run-dir = { path = "../run_dir" } -anyhow = "1.0.38" -pico-args = "0.5.0" -log = "0.4.14" -ksni = "0.2.0" +anyhow = "1.0" +pico-args = "0.5" +log = "0.4" +ksni = "0.3.3" +tokio = { version = "1.49.0", features = ["full"] } diff --git a/src/tools/indicator/src/main.rs b/src/tools/indicator/src/main.rs index 2de61e38..a7f414f8 100644 --- a/src/tools/indicator/src/main.rs +++ b/src/tools/indicator/src/main.rs @@ -1,13 +1,11 @@ use anyhow::Result; -use kime_engine_cffi::{IconColor, IndicatorConfig as Config}; +use kime_engine_core::{load_raw_config_from_config_dir, IconColor}; use ksni::menu::*; -use std::net::Shutdown; -use std::os::unix::net::{UnixListener, UnixStream}; +use ksni::TrayMethods; use std::path::Path; -use std::{ - io::{Read, Write}, - time::Duration, -}; +use std::time::Duration; +use tokio::io::{AsyncReadExt, AsyncWriteExt}; +use tokio::net::{UnixListener, UnixStream}; #[derive(Clone, Copy, Debug)] enum InputCategory { @@ -82,21 +80,25 @@ impl KimeTray { const EXIT_MESSAGE: &[u8; 1] = b"Z"; -fn try_terminate_previous_server(file_path: &Path) -> Result<()> { - let mut client = UnixStream::connect(file_path)?; +async fn try_terminate_previous_server(file_path: &Path) -> Result<()> { + let mut client = UnixStream::connect(file_path).await?; - client.write_all(EXIT_MESSAGE)?; + client.write_all(EXIT_MESSAGE).await?; Ok(()) } -fn indicator_server(file_path: &Path, color: IconColor) -> Result<()> { - let service = ksni::TrayService::new(KimeTray::new(color)); - let handle = service.handle(); - service.spawn(); +async fn indicator_server(file_path: &Path, color: IconColor) -> Result<()> { + // Use assume_sni_available to handle the case when desktop environment + // is not fully initialized yet. This allows the tray to appear later + // when StatusNotifierWatcher becomes available. + let handle = KimeTray::new(color) + .assume_sni_available(true) + .spawn() + .await?; if file_path.exists() { - try_terminate_previous_server(file_path).ok(); + try_terminate_previous_server(file_path).await.ok(); std::fs::remove_file(file_path).ok(); } @@ -106,13 +108,19 @@ fn indicator_server(file_path: &Path, color: IconColor) -> Result<()> { let mut read_buf = [0; 1]; loop { - let mut client = listener.accept()?.0; - client.set_read_timeout(Some(Duration::from_secs(2))).ok(); - client.set_write_timeout(Some(Duration::from_secs(2))).ok(); - client.write_all(¤t_bytes).ok(); - client.shutdown(Shutdown::Write).ok(); - match client.read_exact(&mut read_buf) { - Ok(_) => { + let (mut client, _) = listener.accept().await?; + + let timeout = Duration::from_secs(2); + + // Write current state with timeout + let _ = tokio::time::timeout(timeout, client.write_all(¤t_bytes)).await; + + // Shutdown write side + let _ = client.shutdown().await; + + // Read with timeout + match tokio::time::timeout(timeout, client.read_exact(&mut read_buf)).await { + Ok(Ok(_)) => { if &read_buf == EXIT_MESSAGE { log::info!("Receive exit message"); return Ok(()); @@ -120,20 +128,25 @@ fn indicator_server(file_path: &Path, color: IconColor) -> Result<()> { current_bytes = read_buf; - handle.update(|tray| { - tray.update_with_bytes(¤t_bytes); - }); + handle + .update(|tray| { + tray.update_with_bytes(¤t_bytes); + }) + .await; } _ => {} } } } -fn main() { +#[tokio::main(flavor = "current_thread")] +async fn main() { kime_version::cli_boilerplate!((),); - let config = Config::load(); + let config = load_raw_config_from_config_dir().indicator; let run_dir = kime_run_dir::get_run_dir(); let file_path = run_dir.join("kime-indicator.sock"); - indicator_server(&file_path, config.icon_color()).unwrap(); + indicator_server(&file_path, config.icon_color) + .await + .unwrap(); } diff --git a/src/tools/kime/Cargo.toml b/src/tools/kime/Cargo.toml index 692b82eb..53fcb4b3 100644 --- a/src/tools/kime/Cargo.toml +++ b/src/tools/kime/Cargo.toml @@ -6,11 +6,11 @@ edition = "2021" license = "GPL-3.0-or-later" [dependencies] -kime-engine-cffi = { path = "../../engine/cffi" } +kime-engine-core = { path = "../../engine/core" } kime-version = { path = "../version" } kime-run-dir = { path = "../run_dir" } -ctrlc = { version = "3.1.8", features = ["termination"] } -daemonize = "0.5.0" -log = "0.4.14" -pico-args = "0.5.0" +ctrlc = { version = "3.4", features = ["termination"] } +nix = { version = "0.30", features = ["process", "fs", "signal"] } +log = "0.4" +pico-args = "0.5" diff --git a/src/tools/kime/src/main.rs b/src/tools/kime/src/main.rs index bb0f48e7..fe2f2b63 100644 --- a/src/tools/kime/src/main.rs +++ b/src/tools/kime/src/main.rs @@ -1,11 +1,14 @@ -use daemonize::Daemonize; -use kime_engine_cffi::{DaemonConfig as Config, DaemonModule as Module}; +use kime_engine_core::{load_raw_config_from_config_dir, DaemonModule as Module}; +use nix::fcntl::{Flock, FlockArg}; +use nix::sys::signal::{kill, Signal}; +use nix::unistd::{daemon, Pid}; +use std::os::unix::io::AsRawFd; use std::sync::atomic::{AtomicBool, Ordering::SeqCst}; +use std::{fs::File, io::Write, path::Path}; use std::{ - env, io, + io, process::{Command, Stdio}, }; -use std::{fs::File, path::Path}; const fn process_name(module: Module) -> &'static str { match module { @@ -15,20 +18,22 @@ const fn process_name(module: Module) -> &'static str { } } -fn kill_daemon(pid: &Path) -> io::Result<()> { - let pid = std::fs::read_to_string(pid)?; - - let ret = Command::new("kill") - .arg(pid) - .spawn()? - .wait_with_output()? - .status; +fn kill_daemon(pid_path: &Path) -> io::Result<()> { + let pid_str = std::fs::read_to_string(pid_path)?; + let pid: i32 = match pid_str.trim().parse() { + Ok(pid) => pid, + Err(err) => { + log::error!("kill return: {}", err); + return Err(io::Error::new(io::ErrorKind::Other, "kill command failed")); + } + }; - if ret.success() { - Ok(()) - } else { - log::error!("kill return: {}", ret); - Err(io::Error::new(io::ErrorKind::Other, "kill command failed")) + match kill(Pid::from_raw(pid), Signal::SIGTERM) { + Ok(_) => Ok(()), + Err(err) => { + log::error!("kill return: {}", err); + Err(io::Error::new(io::ErrorKind::Other, "kill command failed")) + } } } @@ -49,29 +54,59 @@ fn main() -> Result<(), ()> { } if !args.contains(["-D", "--no-daemon"]) { - let stderr = run_dir.join("kime.err"); - let stderr_file = match File::create(stderr) { + let stderr_path = run_dir.join("kime.err"); + let stderr_file = match File::create(&stderr_path) { Ok(file) => file, Err(err) => { log::error!("Can't create stderr file: {}", err); return Err(()); } }; - match Daemonize::new() - .working_directory("/tmp") - .stderr(stderr_file) - .pid_file(&pid) - .start() - { + + // Daemonize: fork and detach from terminal (noclose=true to keep fds open) + match daemon(true, true) { Ok(_) => {} Err(err) => { log::error!("Can't daemonize kime: {}", err); return Err(()); } } + + // Change working directory to /tmp + let _ = std::env::set_current_dir("/tmp"); + + // Redirect stderr to file + unsafe { + nix::libc::dup2(stderr_file.as_raw_fd(), nix::libc::STDERR_FILENO); + } } - let config = Config::load(); + // Create PID file and lock it exclusively to prevent duplicate instances + // Lock must be held until program exits (like daemonize library behavior) + // Possible errors: + // - File::create fails: permission denied, disk full, etc. + // - Flock::lock returns EWOULDBLOCK: another kime instance is running + // - Flock::lock returns other error: unexpected lock failure + let _pid_lock = match File::create(&pid).and_then(|file| { + Flock::lock(file, FlockArg::LockExclusiveNonblock).map_err(|(_, e)| io::Error::from(e)) + }) { + Ok(mut lock) => { + writeln!(lock, "{}", std::process::id()).map_err(|err| { + log::error!("Can't daemonize kime: {}", err); + })?; + Some(lock) + } + Err(err) if err.kind() == io::ErrorKind::WouldBlock => { + log::error!("Another instance of kime daemon is already running."); + return Err(()); + } + Err(err) => { + log::error!("Can't daemonize kime: {}", err); + return Err(()); + } + }; + + let config = load_raw_config_from_config_dir().daemon; static RUN: AtomicBool = AtomicBool::new(true); @@ -84,7 +119,7 @@ fn main() -> Result<(), ()> { log::info!("Initialized"); let mut processes = config - .modules() + .modules .iter() .filter_map(|module| { let name = process_name(module); diff --git a/src/tools/properties_writer/src/main.rs b/src/tools/properties_writer/src/main.rs index 530e9b25..195e72cb 100644 --- a/src/tools/properties_writer/src/main.rs +++ b/src/tools/properties_writer/src/main.rs @@ -68,7 +68,7 @@ fn main() { } include_path.insert("${workspaceFolder}".into()); - include_path.insert("${workspaceFolder}/src/engine/cffi".into()); + include_path.insert("${workspaceFolder}/src/engine/capi".into()); let config = Configuration { name: "include paths".into(), diff --git a/src/tools/version/Cargo.toml b/src/tools/version/Cargo.toml index 9e9d4259..dfb1076d 100644 --- a/src/tools/version/Cargo.toml +++ b/src/tools/version/Cargo.toml @@ -6,5 +6,5 @@ edition = "2021" license = "GPL-3.0-or-later" [dependencies] -kime-engine-cffi = { path = "../../engine/cffi" } +kime-engine-core = { path = "../../engine/core" } kime-log = { path = "../../tools/log" } diff --git a/src/tools/version/src/lib.rs b/src/tools/version/src/lib.rs index f0476574..c8ebf72d 100644 --- a/src/tools/version/src/lib.rs +++ b/src/tools/version/src/lib.rs @@ -1,9 +1,6 @@ #[doc(hidden)] pub use kime_log; -#[doc(hidden)] -pub use kime_engine_cffi; - #[doc(hidden)] pub mod build { pub const VERSION: &str = include_str!("../../../../VERSION"); @@ -33,7 +30,7 @@ macro_rules! cli_boilerplate { .ok() .flatten() .unwrap_or_else(|| { - $crate::kime_engine_cffi::LogConfig::load().global_level().parse().unwrap() + kime_engine_core::load_raw_config_from_config_dir().log.global_level }); $crate::kime_log::enable_logger(log_level);