Compare commits

...

48 Commits

Author SHA1 Message Date
dependabot[bot] aebbcc82ee Bump serde_json from 1.0.116 to 1.0.117
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.116 to 1.0.117.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.116...v1.0.117)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
4 weeks ago
dependabot[bot] 8c7eff3baa Bump serde from 1.0.200 to 1.0.203
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.200 to 1.0.203.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.200...v1.0.203)

---
updated-dependencies:
- dependency-name: serde
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
4 weeks ago
dependabot[bot] 931c484eba Bump toml from 0.8.12 to 0.8.13
Bumps [toml](https://github.com/toml-rs/toml) from 0.8.12 to 0.8.13.
- [Commits](https://github.com/toml-rs/toml/compare/toml-v0.8.12...toml-v0.8.13)

---
updated-dependencies:
- dependency-name: toml
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
4 weeks ago
dependabot[bot] b2330d39a6 Bump x11rb from 0.13.0 to 0.13.1
Bumps [x11rb](https://github.com/psychon/x11rb) from 0.13.0 to 0.13.1.
- [Changelog](https://github.com/psychon/x11rb/blob/master/doc/changelog.md)
- [Commits](https://github.com/psychon/x11rb/compare/v0.13.0...v0.13.1)

---
updated-dependencies:
- dependency-name: x11rb
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
4 weeks ago
Takashi Kokubun f42ec7bdb4 Add maintainers to README 1 month ago
Takashi Kokubun d1b17c4b99 Version 0.10.0 1 month ago
Takashi Kokubun b99d09107e
Drop sway and hypr clients (#479) 1 month ago
Takashi Kokubun 98bb9ee1b1 Version 0.9.0 1 month ago
κeen 1aaafb1cd1
enable wheel by default (#478) 1 month ago
Takashi Kokubun 823b749635 Update CHANGELOG 2 months ago
Chakib Benziane ac0f4aa3ee
better to send no key for skip event (#462)
I didn't think much about it on my first patch but when skip_key_event
is set the KEY_UNKNOWN is repeated. Better to send no key at all.
2 months ago
dependabot[bot] 69ac3b08d8 Bump serde from 1.0.197 to 1.0.200
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.197 to 1.0.200.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.197...v1.0.200)

---
updated-dependencies:
- dependency-name: serde
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2 months ago
dependabot[bot] 2130d92f01 Bump serde_json from 1.0.115 to 1.0.116
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.115 to 1.0.116.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.115...v1.0.116)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2 months ago
dependabot[bot] 1aa43d2398 Bump serde_with from 3.7.0 to 3.8.1
Bumps [serde_with](https://github.com/jonasbb/serde_with) from 3.7.0 to 3.8.1.
- [Release notes](https://github.com/jonasbb/serde_with/releases)
- [Commits](https://github.com/jonasbb/serde_with/compare/v3.7.0...v3.8.1)

---
updated-dependencies:
- dependency-name: serde_with
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2 months ago
dependabot[bot] 755acd45a1 Bump anyhow from 1.0.81 to 1.0.82
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.81 to 1.0.82.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.81...1.0.82)

---
updated-dependencies:
- dependency-name: anyhow
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2 months ago
Takashi Kokubun f39afb076b Revert the held/alone description back to a regular one 2 months ago
dependabot[bot] 3a693d26af Bump indoc from 2.0.4 to 2.0.5
Bumps [indoc](https://github.com/dtolnay/indoc) from 2.0.4 to 2.0.5.
- [Release notes](https://github.com/dtolnay/indoc/releases)
- [Commits](https://github.com/dtolnay/indoc/compare/2.0.4...2.0.5)

---
updated-dependencies:
- dependency-name: indoc
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
3 months ago
dependabot[bot] 4c485588e2 Bump regex from 1.10.3 to 1.10.4
Bumps [regex](https://github.com/rust-lang/regex) from 1.10.3 to 1.10.4.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.10.3...1.10.4)

---
updated-dependencies:
- dependency-name: regex
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
3 months ago
dependabot[bot] 5fa4d475d3 Bump serde_json from 1.0.114 to 1.0.115
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.114 to 1.0.115.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.114...v1.0.115)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
3 months ago
dependabot[bot] 9f3c480760 Bump serde_yaml from 0.9.33 to 0.9.34+deprecated
Bumps [serde_yaml](https://github.com/dtolnay/serde-yaml) from 0.9.33 to 0.9.34+deprecated.
- [Release notes](https://github.com/dtolnay/serde-yaml/releases)
- [Commits](https://github.com/dtolnay/serde-yaml/compare/0.9.33...0.9.34)

---
updated-dependencies:
- dependency-name: serde_yaml
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
3 months ago
dependabot[bot] dca06838e1 Bump serde_with from 3.6.0 to 3.7.0
Bumps [serde_with](https://github.com/jonasbb/serde_with) from 3.6.0 to 3.7.0.
- [Release notes](https://github.com/jonasbb/serde_with/releases)
- [Commits](https://github.com/jonasbb/serde_with/compare/v3.6.0...v3.7.0)

---
updated-dependencies:
- dependency-name: serde_with
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
3 months ago
Takashi Kokubun 53a6d0553d Version 0.8.18 3 months ago
Takashi Kokubun 3ce9b7a89d Revert "Version 0.8.18"
This reverts commit 429133067e.
3 months ago
Takashi Kokubun 2f22c52b12 Split release and publish 3 months ago
Takashi Kokubun 429133067e Version 0.8.18 3 months ago
Takashi Kokubun b1640a39e6 The username has been changed to xremap 3 months ago
Takashi Kokubun 1c0f123efd Revert "Version 0.8.18"
This reverts commit 2697d66d4f.
3 months ago
Takashi Kokubun 2697d66d4f Version 0.8.18 3 months ago
Takashi Kokubun 3ed63efc10 Reorder release operations 3 months ago
Takashi Kokubun e283960fab Update GHR_VERSION 3 months ago
N4tus 9262ff47ed Version 0.8.17 3 months ago
N4tus e54fc8ac4a
KDE: Add support for window matching. (#448)
KDE: Add support for window matching.
3 months ago
Takashi Kokubun 9405ce0516 Add an entry to CHANGELOG 3 months ago
Takashi Kokubun fa6db2c6dd Version 0.8.16 3 months ago
jixiuf f6b10cebc0
Window matcher for modmap and keymap (wlroots client only) (#447) 3 months ago
N4tus 8dede9f0b1
Merge pull request #437 from N4tus/master
Handle new KWin-6 API for the kde-backend.
3 months ago
dependabot[bot] 347fc54ce4 Bump log from 0.4.20 to 0.4.21
Bumps [log](https://github.com/rust-lang/log) from 0.4.20 to 0.4.21.
- [Release notes](https://github.com/rust-lang/log/releases)
- [Changelog](https://github.com/rust-lang/log/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/log/compare/0.4.20...0.4.21)

---
updated-dependencies:
- dependency-name: log
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
3 months ago
dependabot[bot] 5d605234d1 Bump fork from 0.1.22 to 0.1.23
Bumps [fork](https://github.com/immortal/fork) from 0.1.22 to 0.1.23.
- [Commits](https://github.com/immortal/fork/compare/0.1.22...0.1.23)

---
updated-dependencies:
- dependency-name: fork
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
3 months ago
dependabot[bot] b40c3767c1 Bump serde_yaml from 0.9.31 to 0.9.33
Bumps [serde_yaml](https://github.com/dtolnay/serde-yaml) from 0.9.31 to 0.9.33.
- [Release notes](https://github.com/dtolnay/serde-yaml/releases)
- [Commits](https://github.com/dtolnay/serde-yaml/compare/0.9.31...0.9.33)

---
updated-dependencies:
- dependency-name: serde_yaml
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
3 months ago
dependabot[bot] f8dc468583 Bump toml from 0.8.9 to 0.8.12
Bumps [toml](https://github.com/toml-rs/toml) from 0.8.9 to 0.8.12.
- [Commits](https://github.com/toml-rs/toml/compare/toml-v0.8.9...toml-v0.8.12)

---
updated-dependencies:
- dependency-name: toml
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
3 months ago
dependabot[bot] e822101ef1 Bump anyhow from 1.0.79 to 1.0.81
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.79 to 1.0.81.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.79...1.0.81)

---
updated-dependencies:
- dependency-name: anyhow
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
3 months ago
Takashi Kokubun c4127eec24 Use `xremap config.yml` consistently 3 months ago
Rocco Goßmann 47427fb887
Added info on how to find unknown keynames to Readme. (#438) 3 months ago
N4tus 93a17a042f Handle new KWin API for kde-backend. 3 months ago
dependabot[bot] 9ecf5f77f7 Bump serde_json from 1.0.109 to 1.0.114
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.109 to 1.0.114.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.109...v1.0.114)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
4 months ago
dependabot[bot] d6cd715130 Bump hyprland from 0.3.12 to 0.3.13
Bumps [hyprland](https://github.com/hyprland-community/hyprland-rs) from 0.3.12 to 0.3.13.
- [Release notes](https://github.com/hyprland-community/hyprland-rs/releases)
- [Commits](https://github.com/hyprland-community/hyprland-rs/compare/0.3.12...0.3.13)

---
updated-dependencies:
- dependency-name: hyprland
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
4 months ago
dependabot[bot] ff0963082e Bump env_logger from 0.10.1 to 0.10.2
Bumps [env_logger](https://github.com/rust-cli/env_logger) from 0.10.1 to 0.10.2.
- [Release notes](https://github.com/rust-cli/env_logger/releases)
- [Changelog](https://github.com/rust-cli/env_logger/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-cli/env_logger/compare/v0.10.1...v0.10.2)

---
updated-dependencies:
- dependency-name: env_logger
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
4 months ago
dependabot[bot] 02ff58b53a Bump serde from 1.0.196 to 1.0.197
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.196 to 1.0.197.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.196...v1.0.197)

---
updated-dependencies:
- dependency-name: serde
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
4 months ago

@ -22,7 +22,7 @@ jobs:
fail-fast: false
matrix:
arch: [x86_64, aarch64]
feature: [x11, gnome, kde, sway, hypr, wlroots]
feature: [x11, gnome, kde, wlroots]
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
@ -62,7 +62,8 @@ jobs:
key: ubuntu-latest
- run: cargo test
publish:
# Release xremap binaries on GitHub
release:
runs-on: ubuntu-latest
needs:
- build
@ -75,31 +76,17 @@ jobs:
profile: minimal
toolchain: stable
override: true
- uses: Swatinem/rust-cache@v1
with:
key: ubuntu-latest
# Release crate
- name: cargo login
run: cargo login "$CARGO_TOKEN"
env:
CARGO_TOKEN: ${{ secrets.CARGO_TOKEN }}
- run: cargo publish
# Fetch x86_64 binary
- { uses: actions/download-artifact@v3, with: { name: xremap-x86_64-x11, path: package/ } }
- { uses: actions/download-artifact@v3, with: { name: xremap-x86_64-gnome, path: package/ } }
- { uses: actions/download-artifact@v3, with: { name: xremap-x86_64-kde, path: package/ } }
- { uses: actions/download-artifact@v3, with: { name: xremap-x86_64-sway, path: package/ } }
- { uses: actions/download-artifact@v3, with: { name: xremap-x86_64-hypr, path: package/ } }
- { uses: actions/download-artifact@v3, with: { name: xremap-x86_64-wlroots, path: package/ } }
# Fetch aarch64 binary
- { uses: actions/download-artifact@v3, with: { name: xremap-aarch64-x11, path: package/ } }
- { uses: actions/download-artifact@v3, with: { name: xremap-aarch64-gnome, path: package/ } }
- { uses: actions/download-artifact@v3, with: { name: xremap-aarch64-kde, path: package/ } }
- { uses: actions/download-artifact@v3, with: { name: xremap-aarch64-sway, path: package/ } }
- { uses: actions/download-artifact@v3, with: { name: xremap-aarch64-hypr, path: package/ } }
- { uses: actions/download-artifact@v3, with: { name: xremap-aarch64-wlroots, path: package/ } }
# Release binary
@ -107,7 +94,32 @@ jobs:
run: |
export VERSION=$(echo "$GITHUB_REF" | sed -e 's!refs/tags/!!')
curl -L "https://github.com/tcnksm/ghr/releases/download/${GHR_VERSION}/ghr_${GHR_VERSION}_linux_amd64.tar.gz" | tar xvz
"ghr_${GHR_VERSION}_linux_amd64/ghr" -u k0kubun -r xremap -replace -n "$VERSION" "$VERSION" package/
"ghr_${GHR_VERSION}_linux_amd64/ghr" -u xremap -r xremap -replace -n "$VERSION" "$VERSION" package/
env:
GHR_VERSION: v0.14.0
GHR_VERSION: v0.16.2
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Publish xremap to crates.io
publish:
runs-on: ubuntu-latest
needs:
- build
- test
if: ${{ startsWith(github.ref, 'refs/tags/') }}
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- uses: Swatinem/rust-cache@v1
with:
key: ubuntu-latest
# Release crate
- name: cargo login
run: cargo login "$CARGO_TOKEN"
env:
CARGO_TOKEN: ${{ secrets.CARGO_TOKEN }}
- run: cargo publish

@ -1,3 +1,31 @@
## v0.10.0
- Drop `sway` and `hypr` clients [#479](https://github.com/xremap/xremap/pull/479)
- As recommended since v0.8.9, please use `wlroots` client instead.
## v0.9.0
- Add `enable_wheel` option in the config [#478](https://github.com/xremap/xremap/pull/478)
- Enable `REL_WHEEL` and `REL_HWHEEL` by default regardless of `--mouse` option.
[#478](https://github.com/xremap/xremap/pull/478)
- This reverts v0.8.2 and v0.8.10.
- Arch Linux users on systemd-253-1 can continue to disable them by top-level `enable_wheel: false`.
See [#260](https://github.com/xremap/xremap/pull/260) for details.
- Emit no key event instead of `KEY_UNKNOWN` on `skip_key_event` [#462](https://github.com/xremap/xremap/pull/462)
## v0.8.18
- Fix issues in the release pipeline
## v0.8.17
- Add `window` matcher for the `kde` client [#448](https://github.com/xremap/xremap/pull/448)
## v0.8.16
- Add `window` matcher for the `wlroots` client [#447](https://github.com/k0kubun/xremap/issues/447)
- Handle new KWin API for the `kde` client [#437](https://github.com/k0kubun/xremap/issues/437)
## v0.8.15
- Add `skip_key_event` option to `press`/`release` modmap action [#420](https://github.com/k0kubun/xremap/issues/420)

423
Cargo.lock generated

@ -2,21 +2,6 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "addr2line"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3"
dependencies = [
"gimli",
]
[[package]]
name = "adler"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "aho-corasick"
version = "1.0.2"
@ -92,9 +77,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.79"
version = "1.0.82"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca"
checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519"
[[package]]
name = "async-io"
@ -125,43 +110,17 @@ dependencies = [
"event-listener",
]
[[package]]
name = "async-trait"
version = "0.1.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc6dde6e4ed435a4c1ee4e73592f5ba9da2151af10076cc04858746af9352d09"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.48",
]
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "backtrace"
version = "0.3.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12"
dependencies = [
"addr2line",
"cc",
"cfg-if",
"libc",
"miniz_oxide",
"object",
"rustc-demangle",
]
[[package]]
name = "base64"
version = "0.21.3"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "414dcefbc63d77c526a76b3afcf6fbb9b5e2791c19c3aa2297733208750c6e53"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "bitflags"
@ -199,12 +158,6 @@ version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "bytes"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
[[package]]
name = "cc"
version = "1.0.80"
@ -298,12 +251,6 @@ dependencies = [
"crossbeam-utils",
]
[[package]]
name = "convert_case"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
[[package]]
name = "core-foundation-sys"
version = "0.8.4"
@ -385,19 +332,6 @@ dependencies = [
"syn 2.0.48",
]
[[package]]
name = "derive_more"
version = "0.99.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
dependencies = [
"convert_case",
"proc-macro2",
"quote",
"rustc_version",
"syn 1.0.109",
]
[[package]]
name = "dlib"
version = "0.5.2"
@ -407,12 +341,6 @@ dependencies = [
"libloading",
]
[[package]]
name = "doc-comment"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
[[package]]
name = "downcast-rs"
version = "1.2.0"
@ -442,9 +370,9 @@ dependencies = [
[[package]]
name = "env_logger"
version = "0.10.1"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece"
checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580"
dependencies = [
"humantime",
"is-terminal",
@ -516,9 +444,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "fork"
version = "0.1.22"
version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf2ca97a59201425e7ee4d197c9c4fea282fe87a97d666a580bda889b95b8e88"
checksum = "60e74d3423998a57e9d906e49252fb79eb4a04d5cdfe188fb1b7ff9fc076a8ed"
dependencies = [
"libc",
]
@ -643,12 +571,6 @@ dependencies = [
"windows-targets",
]
[[package]]
name = "gimli"
version = "0.27.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e"
[[package]]
name = "hashbrown"
version = "0.12.3"
@ -685,39 +607,6 @@ version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]]
name = "hyprland"
version = "0.3.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfa94ae7899f3f1bdcad21dcd50366a60f323375a25610889246f276d7f9fb06"
dependencies = [
"async-trait",
"derive_more",
"doc-comment",
"futures",
"hex",
"hyprland-macros",
"lazy_static",
"num-traits",
"paste",
"regex",
"serde",
"serde_json",
"serde_repr",
"strum",
"tokio",
]
[[package]]
name = "hyprland-macros"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c941d3d52e979612af8cb94e8de49000c7fada2014a7791d173ab41339f4e4eb"
dependencies = [
"quote",
"syn 2.0.48",
]
[[package]]
name = "iana-time-zone"
version = "0.1.57"
@ -771,9 +660,9 @@ dependencies = [
[[package]]
name = "indoc"
version = "2.0.4"
version = "2.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e186cfbae8084e513daff4240b4797e342f988cecda4fb6c939150f96315fd8"
checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5"
[[package]]
name = "instant"
@ -855,21 +744,11 @@ version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503"
[[package]]
name = "lock_api"
version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16"
dependencies = [
"autocfg",
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.20"
version = "0.4.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
[[package]]
name = "memchr"
@ -895,26 +774,6 @@ dependencies = [
"autocfg",
]
[[package]]
name = "miniz_oxide"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
dependencies = [
"adler",
]
[[package]]
name = "mio"
version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2"
dependencies = [
"libc",
"wasi",
"windows-sys",
]
[[package]]
name = "nb-connect"
version = "1.2.0"
@ -974,25 +833,6 @@ dependencies = [
"autocfg",
]
[[package]]
name = "num_cpus"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
dependencies = [
"hermit-abi",
"libc",
]
[[package]]
name = "object"
version = "0.31.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1"
dependencies = [
"memchr",
]
[[package]]
name = "once_cell"
version = "1.18.0"
@ -1005,35 +845,6 @@ version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e"
[[package]]
name = "parking_lot"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
dependencies = [
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"smallvec",
"windows-targets",
]
[[package]]
name = "paste"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
[[package]]
name = "pin-project-lite"
version = "0.2.10"
@ -1120,20 +931,11 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
[[package]]
name = "redox_syscall"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
dependencies = [
"bitflags 1.3.2",
]
[[package]]
name = "regex"
version = "1.10.3"
version = "1.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15"
checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
dependencies = [
"aho-corasick",
"memchr",
@ -1158,21 +960,6 @@ version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
[[package]]
name = "rustc-demangle"
version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
[[package]]
name = "rustc_version"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
dependencies = [
"semver",
]
[[package]]
name = "rustix"
version = "0.37.23"
@ -1200,12 +987,6 @@ dependencies = [
"windows-sys",
]
[[package]]
name = "rustversion"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
[[package]]
name = "ryu"
version = "1.0.15"
@ -1218,32 +999,20 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "semver"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918"
[[package]]
name = "serde"
version = "1.0.196"
version = "1.0.203"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32"
checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.196"
version = "1.0.203"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67"
checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba"
dependencies = [
"proc-macro2",
"quote",
@ -1252,9 +1021,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.109"
version = "1.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb0652c533506ad7a2e353cce269330d6afd8bdfb6d75e0ace5b35aacbd7b9e9"
checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3"
dependencies = [
"itoa",
"ryu",
@ -1274,18 +1043,18 @@ dependencies = [
[[package]]
name = "serde_spanned"
version = "0.6.5"
version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1"
checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0"
dependencies = [
"serde",
]
[[package]]
name = "serde_with"
version = "3.6.0"
version = "3.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b0ed1662c5a68664f45b76d18deb0e234aff37207086803165c961eb695e981"
checksum = "0ad483d2ab0149d5a5ebcd9972a3852711e0153d863bf5a5d0391d28883c4a20"
dependencies = [
"base64",
"chrono",
@ -1293,6 +1062,7 @@ dependencies = [
"indexmap 1.9.3",
"indexmap 2.2.2",
"serde",
"serde_derive",
"serde_json",
"serde_with_macros",
"time",
@ -1300,9 +1070,9 @@ dependencies = [
[[package]]
name = "serde_with_macros"
version = "3.6.0"
version = "3.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "568577ff0ef47b879f736cd66740e022f3672788cdf002a05a4e609ea5a6fb15"
checksum = "65569b702f41443e8bc8bbb1c5779bd0450bbe723b56198980e80ec45780bce2"
dependencies = [
"darling",
"proc-macro2",
@ -1312,9 +1082,9 @@ dependencies = [
[[package]]
name = "serde_yaml"
version = "0.9.31"
version = "0.9.34+deprecated"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adf8a49373e98a4c5f0ceb5d05aa7c648d75f63774981ed95b7c7443bbd50c6e"
checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
dependencies = [
"indexmap 2.2.2",
"itoa",
@ -1323,15 +1093,6 @@ dependencies = [
"unsafe-libyaml",
]
[[package]]
name = "signal-hook-registry"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
dependencies = [
"libc",
]
[[package]]
name = "slab"
version = "0.4.8"
@ -1369,50 +1130,6 @@ version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "strum"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125"
dependencies = [
"strum_macros",
]
[[package]]
name = "strum_macros"
version = "0.25.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad8d03b598d3d0fff69bf533ee3ef19b8eeb342729596df84bcc7e1f96ec4059"
dependencies = [
"heck",
"proc-macro2",
"quote",
"rustversion",
"syn 2.0.48",
]
[[package]]
name = "swayipc"
version = "3.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab1dcff328b223d85d7ca767b2e4aadbc13dad550d36b4c6b929b9ad4d26ee9a"
dependencies = [
"serde",
"serde_json",
"swayipc-types",
]
[[package]]
name = "swayipc-types"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44b43b4059d825ccc04adf9726f944d0e3aa20938f4cff3b5c6b53198afcd6b3"
dependencies = [
"serde",
"serde_json",
"thiserror",
]
[[package]]
name = "syn"
version = "1.0.109"
@ -1498,37 +1215,6 @@ dependencies = [
"time-core",
]
[[package]]
name = "tokio"
version = "1.29.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da"
dependencies = [
"autocfg",
"backtrace",
"bytes",
"libc",
"mio",
"num_cpus",
"parking_lot",
"pin-project-lite",
"signal-hook-registry",
"socket2",
"tokio-macros",
"windows-sys",
]
[[package]]
name = "tokio-macros"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.48",
]
[[package]]
name = "toml"
version = "0.5.11"
@ -1540,21 +1226,21 @@ dependencies = [
[[package]]
name = "toml"
version = "0.8.9"
version = "0.8.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6a4b9e8023eb94392d3dca65d717c53abc5dad49c07cb65bb8fcd87115fa325"
checksum = "a4e43f8cc456c9704c851ae29c67e17ef65d2c30017c17a9765b89c382dc8bba"
dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
"toml_edit 0.21.1",
"toml_edit 0.22.13",
]
[[package]]
name = "toml_datetime"
version = "0.6.5"
version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf"
dependencies = [
"serde",
]
@ -1567,20 +1253,20 @@ checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a"
dependencies = [
"indexmap 2.2.2",
"toml_datetime",
"winnow",
"winnow 0.5.3",
]
[[package]]
name = "toml_edit"
version = "0.21.1"
version = "0.22.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1"
checksum = "c127785850e8c20836d49732ae6abfa47616e60bf9d9f57c43c250361a9db96c"
dependencies = [
"indexmap 2.2.2",
"serde",
"serde_spanned",
"toml_datetime",
"winnow",
"winnow 0.6.5",
]
[[package]]
@ -1591,9 +1277,9 @@ checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
[[package]]
name = "unsafe-libyaml"
version = "0.2.10"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab4c90930b95a82d00dc9e9ac071b4991924390d46cbd0dfe566148667605e4b"
checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
[[package]]
name = "utf8parse"
@ -1607,12 +1293,6 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca"
[[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.87"
@ -1856,6 +1536,15 @@ dependencies = [
"memchr",
]
[[package]]
name = "winnow"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8"
dependencies = [
"memchr",
]
[[package]]
name = "wyz"
version = "0.5.1"
@ -1867,9 +1556,9 @@ dependencies = [
[[package]]
name = "x11rb"
version = "0.13.0"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8f25ead8c7e4cba123243a6367da5d3990e0d3affa708ea19dce96356bd9f1a"
checksum = "5d91ffca73ee7f68ce055750bf9f6eca0780b8c85eff9bc046a3b0da41755e12"
dependencies = [
"gethostname",
"rustix 0.38.4",
@ -1878,13 +1567,13 @@ dependencies = [
[[package]]
name = "x11rb-protocol"
version = "0.13.0"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e63e71c4b8bd9ffec2c963173a4dc4cbde9ee96961d4fcb4429db9929b606c34"
checksum = "ec107c4503ea0b4a98ef47356329af139c0a4f7750e621cf2973cd3385ebcb3d"
[[package]]
name = "xremap"
version = "0.8.15"
version = "0.10.0"
dependencies = [
"anyhow",
"clap",
@ -1893,7 +1582,6 @@ dependencies = [
"env_logger",
"evdev",
"fork",
"hyprland",
"indoc",
"lazy_static",
"log",
@ -1903,8 +1591,7 @@ dependencies = [
"serde_json",
"serde_with",
"serde_yaml",
"swayipc",
"toml 0.8.9",
"toml 0.8.13",
"wayland-client",
"wayland-protocols-wlr",
"x11rb",

@ -1,6 +1,6 @@
[package]
name = "xremap"
version = "0.8.15"
version = "0.10.0"
edition = "2021"
description = "Dynamic key remapp for X and Wayland"
license = "MIT"
@ -8,34 +8,30 @@ repository = "https://github.com/k0kubun/xremap"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
anyhow = "1.0.79"
anyhow = "1.0.82"
clap = { version = "4.3.19", features = ["derive"] }
clap_complete = "4.3.2"
derive-where = "1.2.7"
env_logger = "0.10.1"
env_logger = "0.10.2"
evdev = "0.12.1"
fork = "0.1"
indoc = "2.0"
lazy_static = "1.4.0"
log = "0.4.20"
log = "0.4.21"
nix = "0.26.2"
regex = "1.10.3"
regex = "1.10.4"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
serde_with = { version = "3.6", features = ["chrono"] }
serde_with = { version = "3.8", features = ["chrono"] }
serde_yaml = "0.9"
swayipc = { version = "3.0.1", optional = true }
wayland-client = { version = "0.30", optional = true }
wayland-protocols-wlr = { version = "0.1", features = ["client"], optional = true }
x11rb = { version = "0.13.0", optional = true }
x11rb = { version = "0.13.1", optional = true }
zbus = { version = "1.9.2", optional = true }
hyprland = { version = "0.3.12", optional = true }
toml = "0.8.9"
toml = "0.8.13"
[features]
gnome = ["zbus"]
sway = ["swayipc"]
x11 = ["x11rb"]
hypr = ["hyprland"]
kde = ["zbus"]
wlroots = ["wayland-client", "wayland-protocols-wlr"]

@ -196,8 +196,8 @@ modmap:
KEY_XXX: KEY_YYY # Required
# Dispatch different keys depending on whether you hold it or press it alone
KEY_XXX:
held: [KEY_YYY] # Required
alone: [KEY_ZZZ] # Required
held: KEY_YYY # Required, also accepts arrays
alone: KEY_ZZZ # Required, also accepts arrays
alone_timeout_millis: 1000 # Optional
# Hook `keymap` action on key press/release events.
KEY_XXX:
@ -208,6 +208,10 @@ modmap:
not: [Application, ...]
# or
only: [Application, ...]
window: # Optional (only wlroots/kde clients supported)
not: [/regex of window title/, ...]
# or
only: [/regex of window title/, ...]
device: # Optional
not: [Device, ...]
# or
@ -218,6 +222,14 @@ For `KEY_XXX` and `KEY_YYY`, use [these names](https://github.com/emberian/evdev
You can skip `KEY_` and the name is case-insensitive. So `KEY_CAPSLOCK`, `CAPSLOCK`, and `CapsLock` are the same thing.
Some [custom aliases](src/config/key.rs) like `SHIFT_R`, `CONTROL_L`, etc. are provided.
In case you don't know the name of a key, you can find out by enabling the xremap debug output:
```bash
RUST_LOG=debug xremap config.yml
# or
sudo RUST_LOG=debug xremap config.yml
```
Then press the key you want to know the name of.
If you specify a map containing `held` and `alone`, you can use the key for two purposes.
The key is considered `alone` if it's pressed and released within `alone_timeout_millis` (default: 1000)
before any other key is pressed. Otherwise it's considered `held`.
@ -254,6 +266,10 @@ keymap:
not: [Application, ...]
# or
only: [Application, ...]
window: # Optional (only wlroots/kde clients supported)
not: [/regex of window title/, ...]
# or
only: [/regex of window title/, ...]
device: # Optional
not: [Device, ...]
# or
@ -328,7 +344,7 @@ However, it will only start printing, once a mapping has been triggered that use
So you have to create a mapping with a filter using a dummy application name and trigger it.
Then each time you switch to a new window xremap will print its caption, class, and name in the following style:
`active window: caption: '<caption>', class: '<class>', name: '<name>'`
You want to use the class for the filter.
The `class` property should be used for application matching, while the `caption` property should be used for window matching.
If you use a systemd-daemon to manage xremap, the prints will be visible in the system-logs (Can be opened with `journalctl -f`)
@ -429,6 +445,12 @@ keymap:
remap: *some_remaps # and we can reuse a map here.
```
## Maintainers
- @k0kubun
- @N4tus (KDE client)
- @jixiuf (wlroots client)
## License
`xremap` is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).

@ -24,6 +24,10 @@ impl Client for GnomeClient {
self.connect();
self.current_application().is_some()
}
fn current_window(&mut self) -> Option<String> {
// TODO: not implemented
None
}
fn current_application(&mut self) -> Option<String> {
self.connect();

@ -1,24 +0,0 @@
use crate::client::Client;
use hyprland::{data::Client as HyprClient, prelude::*};
pub struct HyprlandClient;
impl HyprlandClient {
pub fn new() -> HyprlandClient {
HyprlandClient {}
}
}
impl Client for HyprlandClient {
fn supported(&mut self) -> bool {
true
}
fn current_application(&mut self) -> Option<String> {
if let Ok(win_opt) = HyprClient::get_active() {
if let Some(win) = win_opt {
return Some(win.class);
}
}
None
}
}

@ -29,14 +29,14 @@ impl Drop for KwinScriptTempFile {
}
trait KWinScripting {
fn load_script(&self, path: &Path) -> Result<String, ConnectionError>;
fn load_script(&self, path: &Path) -> Result<i32, ConnectionError>;
fn unload_script(&self) -> Result<bool, ConnectionError>;
fn start_script(&self, script_obj_path: &str) -> Result<(), ConnectionError>;
fn start_script(&self, script_obj_id: i32) -> Result<(), ConnectionError>;
fn is_script_loaded(&self) -> Result<bool, ConnectionError>;
}
impl KWinScripting for Connection {
fn load_script(&self, path: &Path) -> Result<String, ConnectionError> {
fn load_script(&self, path: &Path) -> Result<i32, ConnectionError> {
self.call_method(
Some("org.kde.KWin"),
"/Scripting",
@ -48,7 +48,6 @@ impl KWinScripting for Connection {
.map_err(|_| ConnectionError::LoadScriptCall)?
.body::<i32>()
.map_err(|_| ConnectionError::InvalidLoadScriptResult)
.map(|obj_path| format!("/{obj_path}"))
}
fn unload_script(&self) -> Result<bool, ConnectionError> {
@ -65,10 +64,22 @@ impl KWinScripting for Connection {
.map_err(|_| ConnectionError::InvalidUnloadScriptResult)
}
fn start_script(&self, script_obj_path: &str) -> Result<(), ConnectionError> {
self.call_method(Some("org.kde.KWin"), script_obj_path, Some("org.kde.kwin.Script"), "run", &())
.map_err(|_| ConnectionError::StartScriptCall)
.map(|_| ())
fn start_script(&self, script_obj_id: i32) -> Result<(), ConnectionError> {
for script_obj_path_fn in [|id| format!("/{id}"), |id| format!("/Scripting/Script{id}")] {
if self
.call_method(
Some("org.kde.KWin"),
script_obj_path_fn(script_obj_id).as_str(),
Some("org.kde.kwin.Script"),
"run",
&(),
)
.is_ok()
{
return Ok(());
}
}
Err(ConnectionError::StartScriptCall)
}
fn is_script_loaded(&self) -> Result<bool, ConnectionError> {
@ -91,8 +102,8 @@ fn load_kwin_script() -> Result<(), ConnectionError> {
let init_script = || {
let temp_file_path = KwinScriptTempFile::new();
std::fs::write(&temp_file_path.0, KWIN_SCRIPT).map_err(|_| ConnectionError::WriteScriptToTempFile)?;
let script_obj_path = dbus.load_script(&temp_file_path.0)?;
dbus.start_script(&script_obj_path)?;
let script_obj_id = dbus.load_script(&temp_file_path.0)?;
dbus.start_script(script_obj_id)?;
Ok(())
};
if let Err(err) = init_script() {
@ -162,9 +173,13 @@ impl Client for KdeClient {
}
conn_res.is_ok()
}
fn current_window(&mut self) -> Option<String> {
let aw = self.active_window.lock().ok()?;
Some(aw.title.clone())
}
fn current_application(&mut self) -> Option<String> {
let aw = self.active_window.lock().unwrap();
let aw = self.active_window.lock().ok()?;
Some(aw.res_class.clone())
}
}

@ -1,4 +1,4 @@
workspace.clientActivated.connect(function(client){
function notifyActiveWindow(client) {
callDBus(
"com.k0kubun.Xremap",
"/com/k0kubun/Xremap",
@ -8,4 +8,12 @@ workspace.clientActivated.connect(function(client){
"resourceClass" in client ? client.resourceClass : "",
"resourceName" in client ? client.resourceName : ""
);
});
}
if (workspace.windowList) {
// kde 6
workspace.windowActivated.connect(notifyActiveWindow);
} else {
// kde 5
workspace.clientActivated.connect(notifyActiveWindow);
}

@ -1,6 +1,7 @@
pub trait Client {
fn supported(&mut self) -> bool;
fn current_application(&mut self) -> Option<String>;
fn current_window(&mut self) -> Option<String>;
}
pub struct WMClient {
@ -8,6 +9,7 @@ pub struct WMClient {
client: Box<dyn Client>,
supported: Option<bool>,
last_application: String,
last_window: String,
}
impl WMClient {
@ -17,8 +19,28 @@ impl WMClient {
client,
supported: None,
last_application: String::new(),
last_window: String::new(),
}
}
pub fn current_window(&mut self) -> Option<String> {
if self.supported.is_none() {
let supported = self.client.supported();
self.supported = Some(supported);
println!("application-client: {} (supported: {})", self.name, supported);
}
if !self.supported.unwrap() {
return None;
}
let result = self.client.current_window();
if let Some(window) = &result {
if &self.last_window != window {
self.last_window = window.clone();
println!("window: {}", window);
}
}
result
}
pub fn current_application(&mut self) -> Option<String> {
if self.supported.is_none() {
@ -55,20 +77,6 @@ pub fn build_client() -> WMClient {
WMClient::new("KDE", Box::new(kde_client::KdeClient::new()))
}
#[cfg(feature = "sway")]
mod sway_client;
#[cfg(feature = "sway")]
pub fn build_client() -> WMClient {
WMClient::new("Sway", Box::new(sway_client::SwayClient::new()))
}
#[cfg(feature = "hypr")]
mod hypr_client;
#[cfg(feature = "hypr")]
pub fn build_client() -> WMClient {
WMClient::new("Hypr", Box::new(hypr_client::HyprlandClient::new()))
}
#[cfg(feature = "x11")]
mod x11_client;
#[cfg(feature = "x11")]

@ -6,6 +6,9 @@ impl Client for NullClient {
fn supported(&mut self) -> bool {
false
}
fn current_window(&mut self) -> Option<String> {
None
}
fn current_application(&mut self) -> Option<String> {
None

@ -1,80 +0,0 @@
use crate::client::Client;
use std::env;
use std::fs::read_dir;
use std::os::unix::ffi::OsStrExt;
use swayipc::Connection;
pub struct SwayClient {
connection: Option<Connection>,
}
impl SwayClient {
pub fn new() -> SwayClient {
SwayClient { connection: None }
}
fn connect(&mut self) {
if let None = self.connection {
if let Err(env::VarError::NotPresent) = env::var("SWAYSOCK") {
let path = match find_socket() {
Some(path) => path,
None => {
println!("Failed to locate a SWAYSOCK from /run/user/1000/sway-ipc.*");
return;
}
};
println!("$SWAYSOCK is not set. Defaulting to \"{}\"", path);
env::set_var("SWAYSOCK", path);
}
match Connection::new() {
Ok(connection) => self.connection = Some(connection),
Err(e) => println!("SwayClient#connect() failed: {}", e),
}
}
}
}
impl Client for SwayClient {
fn supported(&mut self) -> bool {
self.connect();
self.connection.is_some()
}
fn current_application(&mut self) -> Option<String> {
self.connect();
let connection = match &mut self.connection {
Some(connection) => connection,
None => return None,
};
if let Ok(node) = connection.get_tree() {
if let Some(node) = node.find_focused(|n| n.focused) {
if node.app_id.is_some() {
return node.app_id;
} else if let Some(wp) = node.window_properties {
return wp.class;
}
}
}
None
}
}
// e.g. "/run/user/1000/sway-ipc.1000.2575.sock"
fn find_socket() -> Option<String> {
let uid = 1000; // Assume a first nornal Linux user. TODO: Make it configurable
if let Some(run_user) = read_dir(format!("/run/user/{}", uid)).as_mut().ok() {
while let Some(entry) = run_user.next() {
let path = entry.ok()?.path();
if let Some(fname) = path.file_name() {
if fname.as_bytes().starts_with(b"sway-ipc.") {
if let Ok(path) = path.into_os_string().into_string() {
return Some(path);
}
}
}
}
}
None
}

@ -20,6 +20,7 @@ use crate::client::Client;
struct State {
active_window: Option<ObjectId>,
windows: HashMap<ObjectId, String>,
titles: HashMap<ObjectId, String>,
}
#[derive(Default)]
@ -59,6 +60,22 @@ impl Client for WlRootsClient {
}
}
}
fn current_window(&mut self) -> Option<String> {
let queue = self.queue.as_mut()?;
if let Err(_) = queue.roundtrip(&mut self.state) {
// try to reconnect
if let Err(err) = self.connect() {
log::error!("{err}");
return None;
}
log::debug!("Reconnected to wayland");
}
let id = self.state.active_window.as_ref()?;
self.state.titles.get(id).cloned()
}
fn current_application(&mut self) -> Option<String> {
let queue = self.queue.as_mut()?;
@ -102,6 +119,7 @@ impl Dispatch<ZwlrForeignToplevelManagerV1, ()> for State {
) {
if let ManagerEvent::Toplevel { toplevel } = event {
state.windows.insert(toplevel.id(), "<unknown>".into());
state.titles.insert(toplevel.id(), "<unknown>".into());
}
}
@ -123,8 +141,12 @@ impl Dispatch<ZwlrForeignToplevelHandleV1, ()> for State {
HandleEvent::AppId { app_id } => {
state.windows.insert(handle.id(), app_id);
}
HandleEvent::Title { title } => {
state.titles.insert(handle.id(), title);
}
HandleEvent::Closed => {
state.windows.remove(&handle.id());
state.titles.remove(&handle.id());
}
HandleEvent::State { state: handle_state } => {
let activated = HandleState::Activated as u8;

@ -48,6 +48,10 @@ impl Client for X11Client {
return self.connection.is_some();
// TODO: Test XGetInputFocus and focused_window > 0?
}
fn current_window(&mut self) -> Option<String> {
// TODO: not implemented
None
}
fn current_application(&mut self) -> Option<String> {
self.connect();

@ -7,7 +7,7 @@ use serde::{Deserialize, Deserializer};
// TODO: Use trait to allow only either `only` or `not`
#[derive(Clone, Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Application {
pub struct OnlyOrNot {
#[serde(default, deserialize_with = "deserialize_matchers")]
pub only: Option<Vec<ApplicationMatcher>>,
#[serde(default, deserialize_with = "deserialize_matchers")]

@ -1,5 +1,5 @@
use crate::config::application::deserialize_string_or_vec;
use crate::config::application::Application;
use crate::config::application::OnlyOrNot;
use crate::config::key_press::KeyPress;
use crate::config::keymap_action::{Actions, KeymapAction};
use evdev::Key;
@ -17,7 +17,8 @@ pub struct Keymap {
pub name: String,
#[serde(deserialize_with = "deserialize_remap")]
pub remap: HashMap<KeyPress, Vec<KeymapAction>>,
pub application: Option<Application>,
pub application: Option<OnlyOrNot>,
pub window: Option<OnlyOrNot>,
pub device: Option<Device>,
#[serde(default, deserialize_with = "deserialize_string_or_vec")]
pub mode: Option<Vec<String>>,
@ -41,7 +42,8 @@ where
pub struct KeymapEntry {
pub actions: Vec<KeymapAction>,
pub modifiers: Vec<Modifier>,
pub application: Option<Application>,
pub application: Option<OnlyOrNot>,
pub title: Option<OnlyOrNot>,
pub device: Option<Device>,
pub mode: Option<Vec<String>>,
pub exact_match: bool,
@ -65,6 +67,7 @@ pub fn build_keymap_table(keymaps: &Vec<Keymap>) -> HashMap<Key, Vec<KeymapEntry
actions: actions.to_vec(),
modifiers: key_press.modifiers.clone(),
application: keymap.application.clone(),
title: keymap.window.clone(),
device: keymap.device.clone(),
mode: keymap.mode.clone(),
exact_match: keymap.exact_match,

@ -18,7 +18,7 @@ use evdev::Key;
use keymap::Keymap;
use modmap::Modmap;
use nix::sys::inotify::{AddWatchFlags, InitFlags, Inotify};
use serde::{Deserialize, Deserializer, de::IgnoredAny};
use serde::{de::IgnoredAny, Deserialize, Deserializer};
use std::{collections::HashMap, error, fs, path::PathBuf, time::SystemTime};
use self::{
@ -51,6 +51,8 @@ pub struct Config {
pub modify_time: Option<SystemTime>,
#[serde(skip)]
pub keymap_table: HashMap<Key, Vec<KeymapEntry>>,
#[serde(default = "const_true")]
pub enable_wheel: bool,
}
enum ConfigFiletype {
@ -66,7 +68,7 @@ fn get_file_ext(filename: &PathBuf) -> ConfigFiletype {
} else {
ConfigFiletype::Yaml
}
},
}
_ => ConfigFiletype::Yaml,
}
}
@ -79,7 +81,7 @@ pub fn load_configs(filenames: &Vec<PathBuf>) -> Result<Config, Box<dyn error::E
ConfigFiletype::Yaml => serde_yaml::from_str(&config_contents)?,
ConfigFiletype::Toml => toml::from_str(&config_contents)?,
};
for filename in &filenames[1..] {
let config_contents = fs::read_to_string(&filename)?;
let c: Config = match get_file_ext(&filename) {
@ -132,3 +134,7 @@ where
}
return Ok(keys);
}
fn const_true() -> bool {
true
}

@ -1,4 +1,4 @@
use crate::config::application::Application;
use crate::config::application::OnlyOrNot;
use crate::config::key::deserialize_key;
use crate::config::modmap_action::ModmapAction;
use evdev::Key;
@ -14,7 +14,8 @@ pub struct Modmap {
pub name: String,
#[serde(deserialize_with = "deserialize_remap")]
pub remap: HashMap<Key, ModmapAction>,
pub application: Option<Application>,
pub application: Option<OnlyOrNot>,
pub window: Option<OnlyOrNot>,
pub device: Option<Device>,
}

@ -40,7 +40,7 @@ static MOUSE_BTNS: [&str; 20] = [
static mut DEVICE_NAME: Option<String> = None;
// Credit: https://github.com/mooz/xkeysnail/blob/bf3c93b4fe6efd42893db4e6588e5ef1c4909cfb/xkeysnail/output.py#L10-L32
pub fn output_device(bus_type: Option<BusType>, mouse: bool) -> Result<VirtualDevice, Box<dyn Error>> {
pub fn output_device(bus_type: Option<BusType>, enable_wheel: bool) -> Result<VirtualDevice, Box<dyn Error>> {
let mut keys: AttributeSet<Key> = AttributeSet::new();
for code in Key::KEY_RESERVED.code()..Key::BTN_TRIGGER_HAPPY40.code() {
let key = Key::new(code);
@ -53,7 +53,7 @@ pub fn output_device(bus_type: Option<BusType>, mouse: bool) -> Result<VirtualDe
let mut relative_axes: AttributeSet<RelativeAxisType> = AttributeSet::new();
relative_axes.insert(RelativeAxisType::REL_X);
relative_axes.insert(RelativeAxisType::REL_Y);
if mouse {
if enable_wheel {
relative_axes.insert(RelativeAxisType::REL_HWHEEL);
relative_axes.insert(RelativeAxisType::REL_WHEEL);
}

@ -1,6 +1,6 @@
use crate::action::Action;
use crate::client::WMClient;
use crate::config::application::Application;
use crate::config::application::OnlyOrNot;
use crate::config::key_press::{KeyPress, Modifier};
use crate::config::keymap::{build_override_table, OverrideEntry};
use crate::config::keymap_action::KeymapAction;
@ -35,6 +35,7 @@ pub struct EventHandler {
// Check the currently active application
application_client: WMClient,
application_cache: Option<String>,
title_cache: Option<String>,
// State machine for multi-purpose keys
multi_purpose_keys: HashMap<Key, MultiPurposeKeyState>,
// Current nested remaps
@ -68,6 +69,7 @@ impl EventHandler {
pressed_keys: HashMap::new(),
application_client,
application_cache: None,
title_cache: None,
multi_purpose_keys: HashMap::new(),
override_remaps: vec![],
override_timeout_key: None,
@ -113,6 +115,7 @@ impl EventHandler {
device: &InputDeviceInfo,
) -> Result<bool, Box<dyn Error>> {
self.application_cache = None; // expire cache
self.title_cache = None; // expire cache
let key = Key::new(event.code());
debug!("=> {}: {:?}", event.value(), &key);
@ -329,7 +332,11 @@ impl EventHandler {
// fallthrough on state discrepancy
vec![(key, value)]
}
ModmapAction::PressReleaseKey(PressReleaseKey { skip_key_event, press, release }) => {
ModmapAction::PressReleaseKey(PressReleaseKey {
skip_key_event,
press,
release,
}) => {
// Just hook actions, and then emit the original event. We might want to
// support reordering the key event and dispatched actions later.
if value == PRESS || value == RELEASE {
@ -347,7 +354,7 @@ impl EventHandler {
if skip_key_event {
// Do not dispatch the original key
vec![(Key::KEY_UNKNOWN, value)]
vec![]
} else {
// dispatch the original key
vec![(key, value)]
@ -381,6 +388,11 @@ impl EventHandler {
fn find_modmap(&mut self, config: &Config, key: &Key, device: &InputDeviceInfo) -> Option<ModmapAction> {
for modmap in &config.modmap {
if let Some(key_action) = modmap.remap.get(key) {
if let Some(window_matcher) = &modmap.window {
if !self.match_window(window_matcher) {
continue;
}
}
if let Some(application_matcher) = &modmap.application {
if !self.match_application(application_matcher) {
continue;
@ -454,6 +466,12 @@ impl EventHandler {
if (exact_match && extra_modifiers.len() > 0) || missing_modifiers.len() > 0 {
continue;
}
if let Some(window_matcher) = &entry.title {
if !self.match_window(window_matcher) {
continue;
}
}
if let Some(application_matcher) = &entry.application {
if !self.match_application(application_matcher) {
continue;
@ -619,8 +637,27 @@ impl EventHandler {
Modifier::Key(key) => self.modifiers.contains(key),
}
}
fn match_window(&mut self, window_matcher: &OnlyOrNot) -> bool {
// Lazily fill the wm_class cache
if self.title_cache.is_none() {
match self.application_client.current_window() {
Some(title) => self.title_cache = Some(title),
None => self.title_cache = Some(String::new()),
}
}
if let Some(title) = &self.title_cache {
if let Some(title_only) = &window_matcher.only {
return title_only.iter().any(|m| m.matches(title));
}
if let Some(title_not) = &window_matcher.not {
return title_not.iter().all(|m| !m.matches(title));
}
}
false
}
fn match_application(&mut self, application_matcher: &Application) -> bool {
fn match_application(&mut self, application_matcher: &OnlyOrNot) -> bool {
// Lazily fill the wm_class cache
if self.application_cache.is_none() {
match self.application_client.current_application() {

@ -122,10 +122,11 @@ fn main() -> anyhow::Result<()> {
let config_watcher = config_watcher(watch_config, &config_paths).context("Setting up config watcher")?;
let watchers: Vec<_> = device_watcher.iter().chain(config_watcher.iter()).collect();
let mut handler = EventHandler::new(timer, &config.default_mode, delay, build_client());
let output_device = match output_device(input_devices.values().next().map(InputDevice::bus_type), mouse) {
Ok(output_device) => output_device,
Err(e) => bail!("Failed to prepare an output device: {}", e),
};
let output_device =
match output_device(input_devices.values().next().map(InputDevice::bus_type), config.enable_wheel) {
Ok(output_device) => output_device,
Err(e) => bail!("Failed to prepare an output device: {}", e),
};
let mut dispatcher = ActionDispatcher::new(output_device);
// Main loop

@ -23,6 +23,9 @@ impl Client for StaticClient {
fn supported(&mut self) -> bool {
true
}
fn current_window(&mut self) -> Option<String> {
None
}
fn current_application(&mut self) -> Option<String> {
self.current_application.clone()

Loading…
Cancel
Save