diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..154b331 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,7 @@ +root = true + +[*] +end_of_line = lf +indent_style = space +charset = utf-8 + diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..1e83faa --- /dev/null +++ b/.envrc @@ -0,0 +1,10 @@ +# shellcheck shell=sh +if ! has nix_direnv_version || ! nix_direnv_version 2.4.0; then + source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/2.4.0/direnvrc" "sha256-XQzUAvL6pysIJnRJyR7uVpmUSZfc7LSgWQwq/4mBr1U=" +fi + +nix_direnv_watch_file flake.nix + +if ! use flake . --accept-flake-config --impure; then + echo "devenv could not be built. The devenv environment was not loaded. Make the necessary changes to devenv.nix and hit enter to try again." >&2 +fi diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..c05bb5a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,9 @@ +--- + name: CI + + on: + pull_request: + + jobs: + test: + uses: semantic-release-action/rust/.github/workflows/ci.yml@v5 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..465c97f --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,22 @@ +--- + name: Release + + on: + push: + branches: + - main + - next + - next-major + - beta + - alpha + - "[0-9]+.[0-9]+.x" + - "[0-9]+.x" + + jobs: + release: + uses: semantic-release-action/rust/.github/workflows/release-binary.yml@v5 + with: + targets: | + x86_64-unknown-linux-gnu + secrets: + cargo-registry-token: ${{ secrets.CARGO_REGISTRY_TOKEN }} diff --git a/.gitignore b/.gitignore index ea8c4bf..bdf7846 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,6 @@ -/target +target + +.devenv +.direnv + +.pre-commit-config.yaml diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..f26e014 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,50 @@ +{ + "editor.codeActionsOnSave": { + "source.fixAll": true + }, + "eslint.options": { + // "overrideConfigFile": "eslint.config.js" + }, + "rust-analyzer.linkedProjects": ["Cargo.toml"], + "nixEnvSelector.nixFile": "${workspaceRoot}/flake.nix", + "[rust]": { + "editor.defaultFormatter": "statiolake.vscode-rustfmt", + "editor.tabSize": 2 + }, + "rust-analyzer.rustfmt.extraArgs": ["--config", "tab_spaces=2"], + "typescript.preferences.importModuleSpecifier": "non-relative", + "javascript.preferences.importModuleSpecifier": "non-relative", + "[objective-c]": { + "editor.defaultFormatter": "xaver.clang-format" + }, + "[typescript]": { + "editor.defaultFormatter": "numso.prettier-standard-vscode", + "editor.formatOnSave": false + }, + "[javascript]": { + "editor.defaultFormatter": "numso.prettier-standard-vscode", + "editor.formatOnSave": false + }, + "[jsonc]": { + "editor.defaultFormatter": "numso.prettier-standard-vscode", + "editor.formatOnSave": true + }, + "[json]": { + "editor.defaultFormatter": "numso.prettier-standard-vscode" + }, + "[md]": { + "editor.defaultFormatter": "numso.prettier-standard-vscode", + "editor.formatOnSave": true + } + // "runOnSave.statusMessageTimeout": 3000, + // "runOnSave.commands": [ + // { + // // Match less files except names start with `_`. + // "globMatch": "**/[^_]*.*", + // "command": "treefmt ${file}", + // "runIn": "backend", + // "runningStatusMessage": "Formating ${fileBasename}", + // "finishStatusMessage": "${fileBasename} formated" + // } + // ] +} diff --git a/Cargo.lock b/Cargo.lock index 94fd19f..9451467 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,24 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "advance" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17a4eb65a5640c5b3767dc6adb1d3dc23444ebae7073aca839a6d74fdf362340" - -[[package]] -name = "ahash" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" -dependencies = [ - "const-random", - "getrandom", - "once_cell", - "version_check", -] - [[package]] name = "autocfg" version = "1.1.0" @@ -30,7 +12,7 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" name = "autohide-tdrop" version = "1.0.2" dependencies = [ - "breadx", + "x11rb", ] [[package]] @@ -39,220 +21,49 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "breadx" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51265dcd9119613c859db85d9dc4148f05995f4b42cc6efbe1984d0c63ccb0d5" -dependencies = [ - "advance", - "ahash", - "bytemuck", - "cfg-if", - "fionread", - "gethostname", - "hashbrown", - "nix 0.24.2", - "socket2", - "tracing", - "x11rb-protocol", -] - -[[package]] -name = "bytemuck" -version = "1.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f5715e491b5a1598fc2bef5a606847b5dc1d48ea625bd3c02c00de8285591da" - -[[package]] -name = "cc" -version = "1.0.73" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" - [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "const-random" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f590d95d011aa80b063ffe3253422ed5aa462af4e9867d43ce8337562bac77c4" -dependencies = [ - "const-random-macro", - "proc-macro-hack", -] - -[[package]] -name = "const-random-macro" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "615f6e27d000a2bffbc7f2f6a8669179378fa27ee4d0a509e985dfc0a7defb40" -dependencies = [ - "getrandom", - "lazy_static", - "proc-macro-hack", - "tiny-keccak", -] - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - -[[package]] -name = "fionread" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff330b19fcc7e88d40667b9582beb1600c8dc7e62d154a9dfd7b2878a6681d32" -dependencies = [ - "nix 0.23.1", - "windows-sys", -] - [[package]] name = "gethostname" -version = "0.2.3" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ebd34e35c46e00bb73e81363248d627782724609fe1b6396f553f68fe3862e" +checksum = "bb65d4ba3173c56a500b555b532f72c42e8d1fe64962b518897f8959fae2c177" dependencies = [ "libc", "winapi", ] -[[package]] -name = "getrandom" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - [[package]] name = "libc" -version = "0.2.135" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68783febc7782c6c5cb401fbda4de5a9898be1762314da0bb2c10ced61f18b0c" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] name = "memoffset" -version = "0.6.5" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" dependencies = [ "autocfg", ] [[package]] name = "nix" -version = "0.23.1" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" dependencies = [ "bitflags", - "cc", "cfg-if", "libc", "memoffset", ] -[[package]] -name = "nix" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "195cdbc1741b8134346d515b3a56a1c94b0912758009cfd53f99ea0f57b065fc" -dependencies = [ - "bitflags", - "cfg-if", - "libc", - "memoffset", -] - -[[package]] -name = "once_cell" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" - -[[package]] -name = "pin-project-lite" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" - -[[package]] -name = "proc-macro-hack" -version = "0.5.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" - -[[package]] -name = "socket2" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "tiny-keccak" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" -dependencies = [ - "crunchy", -] - -[[package]] -name = "tracing" -version = "0.1.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" -dependencies = [ - "cfg-if", - "pin-project-lite", - "tracing-core", -] - -[[package]] -name = "tracing-core" -version = "0.1.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - [[package]] name = "winapi" version = "0.3.9" @@ -270,59 +81,38 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-sys" -version = "0.32.0" +name = "winapi-wsapoll" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3df6e476185f92a12c072be4a189a0210dcdcf512a1891d6dff9edb874deadc6" +checksum = "44c17110f57155602a80dca10be03852116403c9ff3cd25b079d666f2aa3df6e" dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", + "winapi", ] [[package]] -name = "windows_aarch64_msvc" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8e92753b1c443191654ec532f14c199742964a061be25d77d7a96f09db20bf5" - -[[package]] -name = "windows_i686_gnu" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a711c68811799e017b6038e0922cb27a5e2f43a2ddb609fe0b6f3eeda9de615" - -[[package]] -name = "windows_i686_msvc" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c11bb1a02615db74680b32a68e2d61f553cc24c4eb5b4ca10311740e44172" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.32.0" +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c912b12f7454c6620635bbff3450962753834be2a594819bd5e945af18ec64bc" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "windows_x86_64_msvc" -version = "0.32.0" +name = "x11rb" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "504a2476202769977a040c6364301a3f65d0cc9e3fb08600b2bda150a0488316" +checksum = "b1641b26d4dec61337c35a1b1aaf9e3cba8f46f0b43636c609ab0291a648040a" +dependencies = [ + "gethostname", + "nix", + "winapi", + "winapi-wsapoll", + "x11rb-protocol", +] [[package]] name = "x11rb-protocol" -version = "0.10.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56b245751c0ac9db0e006dc812031482784e434630205a93c73cfefcaabeac67" +checksum = "82d6c3f9a0fb6701fab8f6cea9b0c0bd5d6876f1f89f7fada07e558077c344bc" dependencies = [ - "nix 0.24.2", + "nix", ] diff --git a/Cargo.toml b/Cargo.toml index d39bfb1..2604017 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,4 +17,4 @@ path = "src/main.rs" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -breadx = "3.1.0" +x11rb = "0.12.0" diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..02a8b43 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 I-Want-ToBelieve + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..249e528 --- /dev/null +++ b/flake.lock @@ -0,0 +1,432 @@ +{ + "nodes": { + "devenv": { + "inputs": { + "flake-compat": "flake-compat", + "nix": "nix", + "nixpkgs": "nixpkgs", + "pre-commit-hooks": "pre-commit-hooks" + }, + "locked": { + "lastModified": 1701187605, + "narHash": "sha256-NctguPdUeDVLXFsv6vI1RlEiHLsXkeW3pgZe/mwn1BU=", + "owner": "cachix", + "repo": "devenv", + "rev": "a7c4dd8f4eb1f98a6b8f04bf08364954e1e73e4f", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "devenv", + "type": "github" + } + }, + "fenix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ], + "rust-analyzer-src": "rust-analyzer-src" + }, + "locked": { + "lastModified": 1701671019, + "narHash": "sha256-ctG01Syj/7TrfV4arc3qyN4a3mAvgXbivYrdXKqdL8U=", + "owner": "nix-community", + "repo": "fenix", + "rev": "5e6667eda7fb055c0a8388172372fb89e5b33e05", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "fenix", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1673956053, + "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1698882062, + "narHash": "sha256-HkhafUayIqxXyHH1X8d9RDl1M2CkFgZLjKD3MzabiEo=", + "path": "/nix/store/vf5ra8smwlqy3pi0300s580g5msc3xp7-source", + "rev": "8c9fa2545007b49a5db5f650ae91f227672c3877", + "type": "path" + }, + "original": { + "id": "flake-parts", + "type": "indirect" + } + }, + "flake-root": { + "locked": { + "lastModified": 1692742795, + "narHash": "sha256-f+Y0YhVCIJ06LemO+3Xx00lIcqQxSKJHXT/yk1RTKxw=", + "owner": "srid", + "repo": "flake-root", + "rev": "d9a70d9c7a5fd7f3258ccf48da9335e9b47c3937", + "type": "github" + }, + "original": { + "owner": "srid", + "repo": "flake-root", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1685518550, + "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "inputs": { + "systems": "systems_2" + }, + "locked": { + "lastModified": 1694529238, + "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "devenv", + "pre-commit-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1660459072, + "narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "a20de23b925fd8264fd7fad6454652e142fd7f73", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "lowdown-src": { + "flake": false, + "locked": { + "lastModified": 1633514407, + "narHash": "sha256-Dw32tiMjdK9t3ETl5fzGrutQTzh2rufgZV4A/BbxuD4=", + "owner": "kristapsdz", + "repo": "lowdown", + "rev": "d2c2b44ff6c27b936ec27358a2653caaef8f73b8", + "type": "github" + }, + "original": { + "owner": "kristapsdz", + "repo": "lowdown", + "type": "github" + } + }, + "mk-shell-bin": { + "locked": { + "lastModified": 1677004959, + "narHash": "sha256-/uEkr1UkJrh11vD02aqufCxtbF5YnhRTIKlx5kyvf+I=", + "owner": "rrbutani", + "repo": "nix-mk-shell-bin", + "rev": "ff5d8bd4d68a347be5042e2f16caee391cd75887", + "type": "github" + }, + "original": { + "owner": "rrbutani", + "repo": "nix-mk-shell-bin", + "type": "github" + } + }, + "nix": { + "inputs": { + "lowdown-src": "lowdown-src", + "nixpkgs": [ + "devenv", + "nixpkgs" + ], + "nixpkgs-regression": "nixpkgs-regression" + }, + "locked": { + "lastModified": 1676545802, + "narHash": "sha256-EK4rZ+Hd5hsvXnzSzk2ikhStJnD63odF7SzsQ8CuSPU=", + "owner": "domenkozar", + "repo": "nix", + "rev": "7c91803598ffbcfe4a55c44ac6d49b2cf07a527f", + "type": "github" + }, + "original": { + "owner": "domenkozar", + "ref": "relaxed-flakes", + "repo": "nix", + "type": "github" + } + }, + "nix2container": { + "inputs": { + "flake-utils": "flake-utils_2", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1700389764, + "narHash": "sha256-hMsZ741ri9c4ZQpB6mgLY8KErk0yXVAOUjfNkP1nbbw=", + "owner": "nlewo", + "repo": "nix2container", + "rev": "4400b77e14f3095ee3215a9a5e0f9143bc0e8f2d", + "type": "github" + }, + "original": { + "owner": "nlewo", + "repo": "nix2container", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1678875422, + "narHash": "sha256-T3o6NcQPwXjxJMn2shz86Chch4ljXgZn746c2caGxd8=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "126f49a01de5b7e35a43fd43f891ecf6d3a51459", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "dir": "lib", + "lastModified": 1698611440, + "narHash": "sha256-jPjHjrerhYDy3q9+s5EAsuhyhuknNfowY6yt6pjn9pc=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "0cbe9f69c234a7700596e943bfae7ef27a31b735", + "type": "github" + }, + "original": { + "dir": "lib", + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-regression": { + "locked": { + "lastModified": 1643052045, + "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + } + }, + "nixpkgs-stable": { + "locked": { + "lastModified": 1685801374, + "narHash": "sha256-otaSUoFEMM+LjBI1XL/xGB5ao6IwnZOXc47qhIgJe8U=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "c37ca420157f4abc31e26f436c1145f8951ff373", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-23.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1701253981, + "narHash": "sha256-ztaDIyZ7HrTAfEEUt9AtTDNoCYxUdSd6NrRHaYOIxtk=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "e92039b55bcd58469325ded85d4f58dd5a4eaf58", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1695644571, + "narHash": "sha256-asS9dCCdlt1lPq0DLwkVBbVoEKuEuz+Zi3DG7pR/RxA=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "6500b4580c2a1f3d0f980d32d285739d8e156d92", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "pre-commit-hooks": { + "inputs": { + "flake-compat": [ + "devenv", + "flake-compat" + ], + "flake-utils": "flake-utils", + "gitignore": "gitignore", + "nixpkgs": [ + "devenv", + "nixpkgs" + ], + "nixpkgs-stable": "nixpkgs-stable" + }, + "locked": { + "lastModified": 1688056373, + "narHash": "sha256-2+SDlNRTKsgo3LBRiMUcoEUb6sDViRNQhzJquZ4koOI=", + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "rev": "5843cf069272d92b60c3ed9e55b7a8989c01d4c7", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "type": "github" + } + }, + "root": { + "inputs": { + "devenv": "devenv", + "fenix": "fenix", + "flake-parts": "flake-parts", + "flake-root": "flake-root", + "mk-shell-bin": "mk-shell-bin", + "nix2container": "nix2container", + "nixpkgs": "nixpkgs_2", + "treefmt-nix": "treefmt-nix" + } + }, + "rust-analyzer-src": { + "flake": false, + "locked": { + "lastModified": 1701447636, + "narHash": "sha256-WaCcxLNAqo/FAK0QtYqweKCUVTGcbKpFIHClc+k2YlI=", + "owner": "rust-lang", + "repo": "rust-analyzer", + "rev": "e402c494b7c7d94a37c6d789a216187aaf9ccd3e", + "type": "github" + }, + "original": { + "owner": "rust-lang", + "ref": "nightly", + "repo": "rust-analyzer", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "treefmt-nix": { + "inputs": { + "nixpkgs": "nixpkgs_3" + }, + "locked": { + "lastModified": 1699786194, + "narHash": "sha256-3h3EH1FXQkIeAuzaWB+nK0XK54uSD46pp+dMD3gAcB4=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "e82f32aa7f06bbbd56d7b12186d555223dc399d1", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..504b720 --- /dev/null +++ b/flake.nix @@ -0,0 +1,138 @@ +{ + description = "100% pure rust implementation that can automatically hide terminals or other applications managed by tdrop when they lose focus"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + devenv.url = "github:cachix/devenv"; + nix2container.url = "github:nlewo/nix2container"; + nix2container.inputs.nixpkgs.follows = "nixpkgs"; + mk-shell-bin.url = "github:rrbutani/nix-mk-shell-bin"; + fenix = { + url = "github:nix-community/fenix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + treefmt-nix.url = "github:numtide/treefmt-nix"; + flake-root.url = "github:srid/flake-root"; + }; + + nixConfig = { + extra-trusted-public-keys = "devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw="; + extra-substituters = [ + "https://mirrors.tuna.tsinghua.edu.cn/nix-channels/store" + "https://mirrors.ustc.edu.cn/nix-channels/store" + "https://devenv.cachix.org" + ]; + }; + + outputs = inputs @ { + flake-parts, + nixpkgs, + ... + }: + flake-parts.lib.mkFlake {inherit inputs;} { + imports = [inputs.devenv.flakeModule inputs.treefmt-nix.flakeModule inputs.flake-root.flakeModule]; + systems = [ + "x86_64-linux" + "i686-linux" + "x86_64-darwin" + "aarch64-linux" + "aarch64-darwin" + ]; + + perSystem = { + config, + self', + inputs', + pkgs, + system, + ... + }: let + cargoBuildInputs = + pkgs.lib.optionals pkgs.stdenv.isDarwin + (with pkgs.darwin.apple_sdk; [ + frameworks.Security + frameworks.CoreServices + ]); + in { + # Per-system attributes can be defined here. The self' and inputs' + # module parameters provide easy access to attributes of the same + # system. + devenv.shells.default = { + name = "autohide-tdrop repo"; + + imports = [ + # This is just like the imports in devenv.nix. + # See https://devenv.sh/guides/using-with-flake-parts/#import-a-devenv-module + # ./devenv-foo.nix + ]; + + # https://devenv.sh/reference/options/ + packages = with pkgs; []; + + # https://devenv.sh/basics/ + env = { + GREET = "🛠️ Let's hack 🧑🏻‍💻"; + }; + + # https://devenv.sh/scripts/ + scripts.hello.exec = "echo $GREET"; + scripts."autohide-tdrop:build".exec = '' + cargo build --release + ''; + scripts."git-user:setup".exec = '' + git config user.name I-Want-ToBelieve + git config user.email i.want.tobelieve.dev@gmail.com + ''; + + enterShell = '' + hello + ''; + + # https://devenv.sh/languages/ + + # autohide-tdrop + languages.rust = { + enable = true; + channel = "stable"; + components = ["rustc" "cargo" "clippy" "rustfmt" "rust-analyzer"]; + }; + + # Make diffs fantastic + difftastic.enable = true; + + # https://devenv.sh/pre-commit-hooks/ + pre-commit.hooks = { + # commons + editorconfig-checker.enable = true; + + # configs + yamllint.enable = true; + + # nix + alejandra.enable = true; + + # rust + rustfmt.enable = true; + clippy.enable = true; + }; + + # Plugin configuration + pre-commit.settings = {yamllint.relaxed = true;}; + }; + + treefmt.config = { + inherit (config.flake-root) projectRootFile; + # This is the default, and can be overriden. + package = pkgs.treefmt; + + # formats .nix files + programs.alejandra.enable = true; + }; + }; + flake = { + # The usual flake attributes can be defined here, including system- + # agnostic ones like nixosModule and system-enumerating ones, although + # those are more easily expressed in perSystem. + }; + }; +} diff --git a/src/main.rs b/src/main.rs index 0d2f9f1..c84f24a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,26 +1,20 @@ -use breadx::{ - connection::BufConnection, - display::{BasicDisplay, DisplayConnection}, - prelude::{Display, DisplayBase, DisplayFunctionsExt}, - protocol::{ - xproto::{AtomEnum, ChangeWindowAttributesAux, EventMask}, - Event::PropertyNotify, - }, - NameConnection, -}; - use std::error::Error; +use x11rb::protocol::Event; +use x11rb::{ + connection::Connection, + protocol::xproto::{self, AtomEnum, ConnectionExt, EventMask, Window}, + rust_connection::RustConnection, +}; -/** - * @see https://github.com/dimusic/active-win-pos-rs/blob/c0bec6433f79d3a8986c9d73fbe318a13562c641/src/linux/platform_api.rs#L98 - */ fn get_active_window( - connection: &mut BasicDisplay>, - root: u32, - atom: u32, -) -> Result { + connection: &RustConnection, + root: Window, + atom: xproto::Atom, +) -> Result { let response = connection - .get_property_immediate(false, root, atom, u8::from(AtomEnum::WINDOW), 0, 1) + .get_property::<_, u32>(false, root, atom, AtomEnum::WINDOW.into(), 0, 1) + .unwrap() + .reply() .unwrap(); if response.value32().is_none() { @@ -31,64 +25,65 @@ fn get_active_window( } fn main() -> Result<(), Box> { - /* - * @see https://docs.rs/breadx/3.1.0/breadx/ - */ - let mut connection = DisplayConnection::connect(None).expect("should connect to x11 server"); - let root = connection.default_screen().root; + let (connection, screen_num) = RustConnection::connect(None)?; + let screen = &connection.setup().roots[screen_num]; + let root = screen.root; let net_active_window = connection - .intern_atom_immediate(true, "_NET_ACTIVE_WINDOW") + .intern_atom(false, b"_NET_ACTIVE_WINDOW") + .unwrap() + .reply() .unwrap() .atom; - /* - * @see https://gist.github.com/ssokolow/e7c9aae63fb7973e4d64cff969a78ae8 - */ - if let Ok(active_window) = get_active_window(&mut connection, root, net_active_window) { - let window_id = &active_window; + let active_window = get_active_window(&connection, root, net_active_window); + if active_window.is_err() { + eprintln!("Error getting initial active window, exiting program."); + return Err(Box::new(std::io::Error::new( + std::io::ErrorKind::Other, + "Error getting initial active window, exiting program.", + ))); + } + + let window_id = active_window.unwrap(); + + xproto::change_window_attributes( + &connection, + root, + &xproto::ChangeWindowAttributesAux::new().event_mask(EventMask::PROPERTY_CHANGE), + )?; - connection.change_window_attributes_checked( - root, - ChangeWindowAttributesAux { - event_mask: EventMask::PROPERTY_CHANGE.into(), - background_pixmap: None, - background_pixel: None, - border_pixmap: None, - border_pixel: None, - bit_gravity: None, - win_gravity: None, - backing_store: None, - backing_planes: None, - backing_pixel: None, - override_redirect: None, - save_under: None, - do_not_propogate_mask: None, - colormap: None, - cursor: None, - }, - )?; + connection.flush()?; - // primary event loop - loop { - let event = connection.wait_for_event()?; + loop { + let event = connection.wait_for_event(); - match event { - // match on the Event struct in here - PropertyNotify(e) => { - if e.atom == net_active_window { - if let Ok(active_window) = - get_active_window(&mut connection, root, net_active_window) - { - if &active_window != window_id { - connection.unmap_window_checked(*window_id)?; - } - } - } - } - _ => {} + if let Ok(Event::PropertyNotify(e)) = event { + if e.atom != net_active_window { + continue; } + + let active_window = get_active_window(&connection, root, net_active_window); + + if active_window.is_err() { + eprintln!("Error getting active window"); + continue; + } + + if active_window.unwrap() == window_id { + continue; + } + + if let Err(err) = connection.unmap_window(window_id) { + eprintln!("Error unmapping window: {:?}", err); + } else { + connection.flush()?; + } + } else { + eprintln!("X11 server has crashed, exiting program."); + return Err(Box::new(std::io::Error::new( + std::io::ErrorKind::Other, + "X11 server has crashed, exiting program.", + ))); } } - - Ok(()) }