diff --git a/pkgs/afk-cmds/afk-cmds/.vscode/launch.json b/pkgs/afk-cmds/afk-cmds/.vscode/launch.json new file mode 100644 index 0000000..47a2bb2 --- /dev/null +++ b/pkgs/afk-cmds/afk-cmds/.vscode/launch.json @@ -0,0 +1,45 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "lldb", + "request": "launch", + "name": "Debug executable 'afk-cmds'", + "cargo": { + "args": [ + "run", + "--bin=afk-cmds", + "--package=afk-cmds" + ], + "filter": { + "name": "afk-cmds", + "kind": "bin" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug unit tests in executable 'afk-cmds'", + "cargo": { + "args": [ + "test", + "--no-run", + "--bin=afk-cmds", + "--package=afk-cmds" + ], + "filter": { + "name": "afk-cmds", + "kind": "bin" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + } + ] +} \ No newline at end of file diff --git a/pkgs/afk-cmds/afk-cmds/.vscode/settings.json b/pkgs/afk-cmds/afk-cmds/.vscode/settings.json new file mode 100644 index 0000000..a03ffe4 --- /dev/null +++ b/pkgs/afk-cmds/afk-cmds/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "nixEnvSelector.suggestion": false +} \ No newline at end of file diff --git a/pkgs/afk-cmds/afk-cmds/Cargo.lock b/pkgs/afk-cmds/afk-cmds/Cargo.lock new file mode 100644 index 0000000..74e46c5 --- /dev/null +++ b/pkgs/afk-cmds/afk-cmds/Cargo.lock @@ -0,0 +1,800 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "afk-cmds" +version = "0.1.0" +dependencies = [ + "ctrlc", + "gtk", + "libappindicator", + "serde", + "serde_json", + "single-instance", + "subprocess", + "winapi", + "x11", +] + +[[package]] +name = "anyhow" +version = "1.0.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602" + +[[package]] +name = "atk" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c3d816ce6f0e2909a96830d6911c2aff044370b1ef92d7f267b43bae5addedd" +dependencies = [ + "atk-sys", + "bitflags", + "glib", + "libc", +] + +[[package]] +name = "atk-sys" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58aeb089fb698e06db8089971c7ee317ab9644bade33383f63631437b03aafb6" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "cairo-rs" +version = "0.15.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c76ee391b03d35510d9fa917357c7f1855bd9a6659c95a1b392e33f49b3369bc" +dependencies = [ + "bitflags", + "cairo-sys-rs", + "glib", + "libc", + "thiserror", +] + +[[package]] +name = "cairo-sys-rs" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c55d429bef56ac9172d25fecb85dc8068307d17acd74b377866b7a1ef25d3c8" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "cc" +version = "1.0.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" + +[[package]] +name = "cfg-expr" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0aacacf4d96c24b2ad6eb8ee6df040e4f27b0d0b39a5710c30091baa830485db" +dependencies = [ + "smallvec", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "ctrlc" +version = "3.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d91974fbbe88ec1df0c24a4f00f99583667a7e2e6272b2b92d294d81e462173" +dependencies = [ + "nix 0.25.0", + "winapi", +] + +[[package]] +name = "field-offset" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e1c54951450cbd39f3dbcf1005ac413b49487dabf18a720ad2383eccfeffb92" +dependencies = [ + "memoffset", + "rustc_version", +] + +[[package]] +name = "futures-channel" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30bdd20c28fadd505d0fd6712cdfcb0d4b5648baf45faef7f852afb2399bb050" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e5aa3de05362c3fb88de6531e6296e85cde7739cccad4b9dfeeb7f6ebce56bf" + +[[package]] +name = "futures-executor" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ff63c23854bee61b6e9cd331d523909f238fc7636290b96826e9cfa5faa00ab" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbf4d2a7a308fd4578637c0b17c7e1c7ba127b8f6ba00b29f717e9655d85eb68" + +[[package]] +name = "futures-task" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6508c467c73851293f390476d4491cf4d227dbabcd4170f3bb6044959b294f1" + +[[package]] +name = "futures-util" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44fb6cb1be61cc1d2e43b262516aafcf63b241cffdb1d3fa115f91d9c7b09c90" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "gdk" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6e05c1f572ab0e1f15be94217f0dc29088c248b14f792a5ff0af0d84bcda9e8" +dependencies = [ + "bitflags", + "cairo-rs", + "gdk-pixbuf", + "gdk-sys", + "gio", + "glib", + "libc", + "pango", +] + +[[package]] +name = "gdk-pixbuf" +version = "0.15.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad38dd9cc8b099cceecdf41375bb6d481b1b5a7cd5cd603e10a69a9383f8619a" +dependencies = [ + "bitflags", + "gdk-pixbuf-sys", + "gio", + "glib", + "libc", +] + +[[package]] +name = "gdk-pixbuf-sys" +version = "0.15.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "140b2f5378256527150350a8346dbdb08fadc13453a7a2d73aecd5fab3c402a7" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gdk-sys" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e7a08c1e8f06f4177fb7e51a777b8c1689f743a7bc11ea91d44d2226073a88" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "pkg-config", + "system-deps", +] + +[[package]] +name = "gio" +version = "0.15.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68fdbc90312d462781a395f7a16d96a2b379bb6ef8cd6310a2df272771c4283b" +dependencies = [ + "bitflags", + "futures-channel", + "futures-core", + "futures-io", + "gio-sys", + "glib", + "libc", + "once_cell", + "thiserror", +] + +[[package]] +name = "gio-sys" +version = "0.15.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32157a475271e2c4a023382e9cab31c4584ee30a97da41d3c4e9fdd605abcf8d" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", + "winapi", +] + +[[package]] +name = "glib" +version = "0.15.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edb0306fbad0ab5428b0ca674a23893db909a98582969c9b537be4ced78c505d" +dependencies = [ + "bitflags", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "glib-macros", + "glib-sys", + "gobject-sys", + "libc", + "once_cell", + "smallvec", + "thiserror", +] + +[[package]] +name = "glib-macros" +version = "0.15.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25a68131a662b04931e71891fb14aaf65ee4b44d08e8abc10f49e77418c86c64" +dependencies = [ + "anyhow", + "heck", + "proc-macro-crate", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "glib-sys" +version = "0.15.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef4b192f8e65e9cf76cbf4ea71fa8e3be4a0e18ffe3d68b8da6836974cc5bad4" +dependencies = [ + "libc", + "system-deps", +] + +[[package]] +name = "gobject-sys" +version = "0.15.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d57ce44246becd17153bd035ab4d32cfee096a657fc01f2231c9278378d1e0a" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gtk" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e3004a2d5d6d8b5057d2b57b3712c9529b62e82c77f25c1fecde1fd5c23bd0" +dependencies = [ + "atk", + "bitflags", + "cairo-rs", + "field-offset", + "futures-channel", + "gdk", + "gdk-pixbuf", + "gio", + "glib", + "gtk-sys", + "gtk3-macros", + "libc", + "once_cell", + "pango", + "pkg-config", +] + +[[package]] +name = "gtk-sys" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5bc2f0587cba247f60246a0ca11fe25fb733eabc3de12d1965fc07efab87c84" +dependencies = [ + "atk-sys", + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "gtk3-macros" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24f518afe90c23fba585b2d7697856f9e6a7bbc62f65588035e66f6afb01a2e9" +dependencies = [ + "anyhow", + "proc-macro-crate", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + +[[package]] +name = "itoa" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" + +[[package]] +name = "libappindicator" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2d3cb96d092b4824cb306c9e544c856a4cb6210c1081945187f7f1924b47e8" +dependencies = [ + "glib", + "gtk", + "gtk-sys", + "libappindicator-sys", + "log", +] + +[[package]] +name = "libappindicator-sys" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1b3b6681973cea8cc3bce7391e6d7d5502720b80a581c9a95c9cbaf592826aa" +dependencies = [ + "gtk-sys", + "libloading", + "once_cell", +] + +[[package]] +name = "libc" +version = "0.2.132" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" + +[[package]] +name = "libloading" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "nix" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6" +dependencies = [ + "bitflags", + "cc", + "cfg-if", + "libc", + "memoffset", +] + +[[package]] +name = "nix" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e322c04a9e3440c327fca7b6c8a63e6890a32fa2ad689db972425f07e0d22abb" +dependencies = [ + "autocfg", + "bitflags", + "cfg-if", + "libc", +] + +[[package]] +name = "once_cell" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" + +[[package]] +name = "pango" +version = "0.15.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e4045548659aee5313bde6c582b0d83a627b7904dd20dc2d9ef0895d414e4f" +dependencies = [ + "bitflags", + "glib", + "libc", + "once_cell", + "pango-sys", +] + +[[package]] +name = "pango-sys" +version = "0.15.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2a00081cde4661982ed91d80ef437c20eacaf6aa1a5962c0279ae194662c3aa" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "pest" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb779fcf4bb850fbbb0edc96ff6cf34fd90c4b1a112ce042653280d9a7364048" +dependencies = [ + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" + +[[package]] +name = "proc-macro-crate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eda0fc3b0fb7c975631757e14d9049da17374063edb6ebbcbc54d880d4fe94e9" +dependencies = [ + "once_cell", + "thiserror", + "toml", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver", +] + +[[package]] +name = "ryu" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" + +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] + +[[package]] +name = "serde" +version = "1.0.144" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.144" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "single-instance" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4637485391f8545c9d3dbf60f9d9aab27a90c789a700999677583bcb17c8795d" +dependencies = [ + "libc", + "nix 0.23.1", + "thiserror", + "widestring", + "winapi", +] + +[[package]] +name = "slab" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" + +[[package]] +name = "subprocess" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c2e86926081dda636c546d8c5e641661049d7562a68f5488be4a1f7f66f6086" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "syn" +version = "1.0.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "system-deps" +version = "6.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a45a1c4c9015217e12347f2a411b57ce2c4fc543913b14b6fe40483328e709" +dependencies = [ + "cfg-expr", + "heck", + "pkg-config", + "toml", + "version-compare", +] + +[[package]] +name = "thiserror" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c53f98874615aea268107765aa1ed8f6116782501d18e53d08b471733bea6c85" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8b463991b4eab2d801e724172285ec4195c650e8ec79b149e6c2a8e6dd3f783" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "toml" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +dependencies = [ + "serde", +] + +[[package]] +name = "ucd-trie" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" + +[[package]] +name = "unicode-ident" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd" + +[[package]] +name = "version-compare" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe88247b92c1df6b6de80ddc290f3976dbdf2f5f5d3fd049a9fb598c6dd5ca73" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "widestring" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +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 = "x11" +version = "2.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7ae97874a928d821b061fce3d1fc52f08071dd53c89a6102bc06efcac3b2908" +dependencies = [ + "libc", + "pkg-config", +] diff --git a/pkgs/afk-cmds/afk-cmds/Cargo.toml b/pkgs/afk-cmds/afk-cmds/Cargo.toml new file mode 100644 index 0000000..b0baba5 --- /dev/null +++ b/pkgs/afk-cmds/afk-cmds/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "afk-cmds" +version = "0.1.0" +edition = "2021" +build = "build.rs" + +[target.'cfg(windows)'.dependencies] +winapi = { version = "0.3.8", features = ["winuser", "sysinfoapi", "errhandlingapi"] } +[target.'cfg(unix)'.dependencies] +x11 = {version = "2.20.0" } +gtk = {version = "0.15.5"} +libappindicator = {version = "0.7.1"} +[dependencies] +serde_json = { version = "1.0.85" } +serde = {version = "1.0.144", features = ["derive"]} +ctrlc = { version = "3.0", features = ["termination"] } +single-instance = "0.3.3" +subprocess = "0.2.9" +[profile.release] +strip = true +opt-level = "z" +lto = true +codegen-units = 1 +panic = "abort" + diff --git a/pkgs/afk-cmds/afk-cmds/LICENSE b/pkgs/afk-cmds/afk-cmds/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/pkgs/afk-cmds/afk-cmds/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/pkgs/afk-cmds/afk-cmds/afk-cmds.iml b/pkgs/afk-cmds/afk-cmds/afk-cmds.iml new file mode 100644 index 0000000..2fecef3 --- /dev/null +++ b/pkgs/afk-cmds/afk-cmds/afk-cmds.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/pkgs/afk-cmds/afk-cmds/afk-icon.png b/pkgs/afk-cmds/afk-cmds/afk-icon.png new file mode 100644 index 0000000..7270399 Binary files /dev/null and b/pkgs/afk-cmds/afk-cmds/afk-icon.png differ diff --git a/pkgs/afk-cmds/afk-cmds/build.rs b/pkgs/afk-cmds/afk-cmds/build.rs new file mode 100644 index 0000000..7444598 --- /dev/null +++ b/pkgs/afk-cmds/afk-cmds/build.rs @@ -0,0 +1,6 @@ +fn main() { +#[cfg(windows)] +return; +println!("cargo:rustc-link-lib=X11"); +println!("cargo:rustc-link-lib=Xss"); +} diff --git a/pkgs/afk-cmds/afk-cmds/shell.nix b/pkgs/afk-cmds/afk-cmds/shell.nix new file mode 100644 index 0000000..41bd46d --- /dev/null +++ b/pkgs/afk-cmds/afk-cmds/shell.nix @@ -0,0 +1,18 @@ +let +pkgs = import {}; +in +with pkgs; +mkShell rec { + buildInputs = with pkgs; [ + xorg.libXScrnSaver + xorg.libX11 + # Dev dependencies + rustup + pkg-config + gdk-pixbuf + gtkmm3 + libappindicator-gtk3 + ]; + LD_LIBRARY_PATH = "${lib.makeLibraryPath buildInputs}"; + RUST_BACKTRACE = 1; +} diff --git a/pkgs/afk-cmds/afk-cmds/src/main.rs b/pkgs/afk-cmds/afk-cmds/src/main.rs new file mode 100644 index 0000000..f759c1c --- /dev/null +++ b/pkgs/afk-cmds/afk-cmds/src/main.rs @@ -0,0 +1,213 @@ +#![windows_subsystem = "windows"] + +use ctrlc; +use ctrlc::set_handler; +use serde::{Deserialize, Serialize}; +use single_instance::SingleInstance; +use std::sync::Arc; +use subprocess::{Popen, PopenConfig, Redirection}; + +use std::env; +use std::env::current_exe; +use std::ffi::OsString; +use std::fs::File; +use std::io::Read; +use std::path::PathBuf; +use std::process::exit; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::thread::sleep; +use std::time::Duration; +use std::vec; +#[cfg(unix)] +use unix::*; +#[cfg(windows)] +use windows::*; + +#[cfg(unix)] +mod unix; +#[cfg(windows)] +mod windows; + +mod tray_icon; +use tray_icon::*; +#[derive(Deserialize, Serialize, Debug, Clone)] +pub struct ProcessInfo { + enabled: bool, + path: String, + cwd: String, + args: Vec, + show_window: bool, + while_afk: bool, + kill: bool, +} + +#[derive(Deserialize, Serialize, Debug)] +struct Jason { + process_info: Vec, + afk_seconds: u64, +} + +fn read_config() -> Jason { + let mut config_path = Default::default(); + let args: Vec = env::args_os().collect(); + if !args.is_empty() { + match args + .iter() + .position(|r| (r == &OsString::from("--config") || r == &OsString::from("-c"))) + { + Some(x) => { + if x < args.len() { + config_path = PathBuf::from(&args[x + 1 as usize]); + } else { + println!("please specify a config file"); + } + } + None => { + config_path = current_exe().expect("Could not get exe location to find config.json"); + config_path.pop(); + config_path.push("config.json"); + } + }; + } + if config_path.exists() { + let mut data = String::new(); + File::open(config_path) + .unwrap() + .read_to_string(&mut data) + .unwrap(); + return serde_json::from_str(&data).expect("Invalid config format"); + } else { + println! {"{}","Couldn't read config"}; + exit(1); + } +} + +fn start(mut group: &mut Group, movable: i32) { + if group.started { + return; + } + group.started = true; + let mut i = 0; + for info in group.process_info.iter() { + let mut argv = vec![OsString::from(&info.path)]; + for arg in &info.args { + argv.push(OsString::from(arg)); + } + let mut child = Popen::create( + &argv, + PopenConfig { + cwd: Option::from(OsString::from(&info.cwd)), + stdin: Redirection::Pipe, + ..Default::default() + }, + ) + .expect("couldn't start child "); + sleep(Duration::from_secs(1)); + + if info.while_afk { + if info.show_window { + move_window(child.pid().expect("couldn't get pid"), i, movable); + i += 1 + } else { + hide_window(child.pid().expect("couldn't get pid")); + } + } + if info.kill { + group.children.push(child); + } else { + child.detach(); + } + } +} + +fn stop(mut group: &mut Group) { + if !group.started { + return; + } + group.started = false; + let children = &mut group.children; + for i in 0..children.len() { + children[i].terminate().expect("Couldn't exit process"); + let _ = children[i].wait_timeout(Duration::from_secs(1)); + } + if !children.is_empty() { + children.clear(); + } +} + +struct Group { + process_info: Vec, + children: Vec, + started: bool, +} + +fn main() { + wait_for_display(); + let running_arc = Arc::new(AtomicBool::new(true)); + let pause_arc = Arc::new(AtomicBool::new(false)); + let r_clone = running_arc.clone(); + let p_clone = pause_arc.clone(); + + let instance = SingleInstance::new("afk-cmds").unwrap(); + if !instance.is_single() { + println!("Another instance is running"); + exit(1); + } + let mut json = read_config(); + tray_icon(r_clone, p_clone); + //catch ctrl-c as gracefully as possible + let running_clone = running_arc.clone(); + set_handler(move || { + println!("{}", "Exit signal received exiting...."); + running_clone.store(false, Ordering::Relaxed) + }) + .unwrap(); + + let mut afk = Group { + process_info: vec![], + children: vec![], + started: false, + }; + let mut active = Group { + process_info: vec![], + children: vec![], + started: false, + }; + let mut movable = 0; + for info in &json.process_info { + if !info.enabled { + continue; + } + if info.while_afk { + afk.process_info.push(info.clone()); + if info.show_window { + movable += 1; + } + } else { + active.process_info.push(info.clone()); + } + } + json.process_info.clear(); + println!("{}", "Started"); + while running_arc.load(Ordering::Relaxed) { + if pause_arc.load(Ordering::Relaxed) { + sleep(Duration::from_secs(1)); + continue; + }; + + let idle_time = get_idle_time(); + if idle_time >= json.afk_seconds { + stop(&mut active); + start(&mut afk, movable); + } else { + stop(&mut afk); + start(&mut active, 0); + sleep(Duration::from_secs(1)) + } + sleep(Duration::from_secs(1)); + } + stop(&mut afk); + stop(&mut active); + println!("{}", "Exited normally"); + exit(0); +} diff --git a/pkgs/afk-cmds/afk-cmds/src/tray_icon.rs b/pkgs/afk-cmds/afk-cmds/src/tray_icon.rs new file mode 100644 index 0000000..e4d60b5 --- /dev/null +++ b/pkgs/afk-cmds/afk-cmds/src/tray_icon.rs @@ -0,0 +1,29 @@ +use std::sync::Arc; +use core::sync::atomic::{AtomicBool,Ordering}; +use gtk::prelude::*; +use libappindicator::{AppIndicator, AppIndicatorStatus}; +use std::thread; + +pub fn tray_icon(running_arc:Arc, pause_arc:Arc) { + thread::spawn(move || { + gtk::init().unwrap(); + let mut indicator = AppIndicator::new("afk-cmds", ""); //temporary logo + indicator.set_status(AppIndicatorStatus::Active); + let mut menu = gtk::Menu::new(); + let pause = gtk::CheckMenuItem::with_label("Paused"); + pause.connect_activate(move |_| { + pause_arc.store(!pause_arc.load(Ordering::Relaxed), Ordering::Relaxed); + }); + menu.append(&pause); + + let quit = gtk::MenuItem::with_label("Quit"); + quit.connect_activate(move |_| { + running_arc.store(false, Ordering::Relaxed); + }); + menu.append(&quit); + + indicator.set_menu(&mut menu); + menu.show_all(); + gtk::main() + }); +} diff --git a/pkgs/afk-cmds/afk-cmds/src/unix-cfg.json b/pkgs/afk-cmds/afk-cmds/src/unix-cfg.json new file mode 100644 index 0000000..16519c1 --- /dev/null +++ b/pkgs/afk-cmds/afk-cmds/src/unix-cfg.json @@ -0,0 +1,17 @@ +{ + "process_info": [ + { + "enabled": true, + "path": "/run/current-system/sw/bin/st", + "cwd": "/home/gerg/", + "args": [ + "ping", + "1.1.1.1" + ], + "show_window": true, + "while_afk": true, + "kill": true + } + ], + "afk_seconds": 3 +} \ No newline at end of file diff --git a/pkgs/afk-cmds/afk-cmds/src/unix.rs b/pkgs/afk-cmds/afk-cmds/src/unix.rs new file mode 100644 index 0000000..4994523 --- /dev/null +++ b/pkgs/afk-cmds/afk-cmds/src/unix.rs @@ -0,0 +1,162 @@ +use x11::xlib::{ + Atom, CWOverrideRedirect, Display, Window, XChangeWindowAttributes, XCloseDisplay, + XDefaultRootWindow, XDefaultScreen, XDisplayHeight, XDisplayWidth, XFlush, XFree, + XGetWindowProperty, XInternAtom, XMapWindow, XMoveResizeWindow, XOpenDisplay, XQueryTree, + XSetWindowAttributes, XUnmapWindow, XA_CARDINAL, +}; +use x11::xss::{XScreenSaverAllocInfo, XScreenSaverQueryInfo}; + +use std::ffi::c_void; +use std::os::raw::c_int; +use std::ptr::null; +use std::thread; +use std::time::Duration; + +pub fn get_idle_time() -> u64 { + unsafe { + let dpy = XOpenDisplay(null()); + if dpy.is_null() { + println!("{}","Couldn't access display in fn get_idle_time()"); + thread::sleep(Duration::from_secs(10)); + return 0; + } + let info = XScreenSaverAllocInfo(); + XScreenSaverQueryInfo(dpy, XDefaultRootWindow(dpy), info); + let r = (*info).idle; + XFree(info as *mut c_void); + XCloseDisplay(dpy); + return (r / 1000) as u64; + } +} + +pub fn wait_for_display() { + loop { + unsafe { + let dpy = XOpenDisplay(null()); + if !dpy.is_null() { + XCloseDisplay(dpy); + println!("{}","Starting..."); + return; + } + println!("{}", "Waiting for X"); + thread::sleep(Duration::from_secs(10)); + } + } +} + +pub fn move_window(pid: u32, num: i32, count: i32) { + let _ = pid; + unsafe { + let dpy: *mut Display = XOpenDisplay(null()); + if dpy.is_null() { + println!("{}","Couldn't access display in fn move_window()"); + return; + } + let scr: c_int = XDefaultScreen(dpy); + let width: c_int = XDisplayWidth(dpy, scr) / count; + let height: c_int = XDisplayHeight(dpy, scr); + let window = get_by_pid(dpy, pid); + if window == 0 { + print!("{}","Couldn't move window"); + XCloseDisplay(dpy); + return; + } + let mut wattr: XSetWindowAttributes = std::mem::zeroed(); + wattr.override_redirect = 1; + XChangeWindowAttributes(dpy, window, CWOverrideRedirect, &mut wattr); + XUnmapWindow(dpy, window); + XFlush(dpy); + XMapWindow(dpy, window); + XFlush(dpy); + XMoveResizeWindow(dpy, window, width * num, 0, width as u32, height as u32); + XCloseDisplay(dpy); + } +} + +pub fn hide_window(pid: u32) { + let _ = pid; + unsafe { + let dpy: *mut Display = XOpenDisplay(std::ptr::null()); + let window = get_by_pid(dpy, pid); + let mut wattr: XSetWindowAttributes = std::mem::zeroed(); + wattr.override_redirect = 1; + XChangeWindowAttributes(dpy, window, CWOverrideRedirect, &mut wattr); + XUnmapWindow(dpy, window); + XFlush(dpy); + XCloseDisplay(dpy); + } +} + +unsafe fn recursion( + display: *mut Display, + pid: u32, + atom_pid: Atom, + window: Window, + results: &mut Vec, +) { + let mut typew: u64 = 0; + let mut format: i32 = 0; + let mut n_items: u64 = 0; + let mut bytes_after: u64 = 0; + let mut prop_pid: *mut u8 = 0 as *mut _; + if XGetWindowProperty( + display, + window, + atom_pid, + 0, + 1, + 0, + XA_CARDINAL, + &mut typew, + &mut format, + &mut n_items, + &mut bytes_after, + &mut prop_pid, + ) == 0 + { + if prop_pid != 0 as *mut _ { + if pid as u64 == *(prop_pid as *const u64) { + results.push(window); + } + + XFree(prop_pid as *mut c_void); + } + } + let mut root_window: u64 = 0; + let mut parent_window: u64 = 0; + let mut children: *mut u64 = 0 as *mut _; + let mut children_count: u32 = 0; + if XQueryTree( + display, + window, + &mut root_window, + &mut parent_window, + &mut children, + &mut children_count, + ) != 0 + { + let slice = std::slice::from_raw_parts(children, children_count as usize); + for window in slice { + recursion(display, pid, atom_pid, *window, results); + } + } +} + +unsafe fn get_by_pid(display: *mut Display, pid: u32) -> Window { + if display.is_null() { + return 0; + } + + let root: Window = XDefaultRootWindow(display); + let atom = XInternAtom(display, "_NET_WM_PID\0".as_ptr() as *const i8, 1); + if atom == 0 { + return 0; + } + + let mut results: Vec = Vec::new(); + recursion(display, pid, atom, root, &mut results); + if results.is_empty() { + return 0; + } + return results[0]; +} diff --git a/pkgs/afk-cmds/afk-cmds/src/win-cfg.json b/pkgs/afk-cmds/afk-cmds/src/win-cfg.json new file mode 100644 index 0000000..b28b5f8 --- /dev/null +++ b/pkgs/afk-cmds/afk-cmds/src/win-cfg.json @@ -0,0 +1,17 @@ +{ + "process_info": [ + { + "enabled": true, + "path": "C:\\Windows\\system32\\cmd.exe", + "cwd": "C:\\", + "args": [ + "/K", + "ping 1.1.1.1" + ], + "show_window": true, + "while_afk": true, + "kill": true + } + ], + "afk_seconds": 3 +} \ No newline at end of file diff --git a/pkgs/afk-cmds/afk-cmds/src/windows.rs b/pkgs/afk-cmds/afk-cmds/src/windows.rs new file mode 100644 index 0000000..3bbd7c5 --- /dev/null +++ b/pkgs/afk-cmds/afk-cmds/src/windows.rs @@ -0,0 +1,100 @@ +use std::mem::size_of; +use winapi; +use winapi::shared::minwindef::{DWORD, LPARAM, LPDWORD, TRUE}; +use winapi::shared::windef::HWND; +pub use winapi::shared::winerror::{ERROR_ACCESS_DENIED, ERROR_BAD_PATHNAME}; +use winapi::um::winuser::{ + GetWindow, IsWindowVisible, SetWindowPos, GW_OWNER, HWND_BOTTOM, HWND_TOP, SWP_HIDEWINDOW, + SWP_NOSENDCHANGING, SWP_SHOWWINDOW, +}; +use winapi::um::{ + sysinfoapi::GetTickCount64, + winuser, + winuser::{GetLastInputInfo, GetSystemMetrics, LASTINPUTINFO, SM_CXSCREEN, SM_CYSCREEN}, +}; + +pub fn get_idle_time() -> u64 { + unsafe { + let last_input = &mut LASTINPUTINFO { + cbSize: 0, + dwTime: 0, + } as *mut LASTINPUTINFO; + (*last_input).cbSize = size_of::() as u32; + let _ = GetLastInputInfo(last_input); + return (GetTickCount64() - ((*last_input).dwTime) as u64) / 1000; + } +} + +pub fn move_window(pid: u32, num: i32, count: i32) { + unsafe { + let width = (GetSystemMetrics(SM_CXSCREEN)) / count; + let height = GetSystemMetrics(SM_CYSCREEN); + let window = find_window(pid); + SetWindowPos( + window, + HWND_TOP, + (width * num) - 7, + 0, + width + 15, + height, + SWP_SHOWWINDOW + SWP_NOSENDCHANGING, + ); + } +} + +pub fn hide_window(pid: u32) { + unsafe { + let window = find_window(pid); + SetWindowPos( + window, + HWND_BOTTOM, + 0, + 0, + 10, + 10, + SWP_HIDEWINDOW + SWP_NOSENDCHANGING, + ); + } +} + +struct HandleData { + process_id: LPDWORD, + window_handle: HWND, +} + +fn is_main_window(handle: HWND) -> bool { + unsafe { + return GetWindow(handle, GW_OWNER) == 0 as HWND && (IsWindowVisible(handle) == TRUE); + } +} + +unsafe fn find_window(pid: u32) -> HWND { + let mut data = HandleData { + process_id: pid as LPDWORD, + window_handle: 0 as HWND, + }; + winuser::EnumWindows( + Some(enum_windows_proc), + &mut data as *mut HandleData as LPARAM, + ); + return data.window_handle; +} + +extern "system" fn enum_windows_proc(handle: HWND, l_param: LPARAM) -> i32 { + let data = unsafe { &mut *(l_param as *mut HandleData) }; + let process_id: LPDWORD = 0 as LPDWORD; + unsafe { GetWindowThreadProcessId(handle, &process_id) }; + if data.process_id != process_id || !is_main_window(handle) { + return 1; + } + data.window_handle = handle; + return 0; +} + +extern "system" { + fn GetWindowThreadProcessId(hWnd: HWND, lpdwProcessId: &LPDWORD) -> DWORD; +} + +pub fn wait_for_display() { + return; +} diff --git a/pkgs/afk-cmds/default.nix b/pkgs/afk-cmds/default.nix index d8ad412..c06f37a 100644 --- a/pkgs/afk-cmds/default.nix +++ b/pkgs/afk-cmds/default.nix @@ -17,12 +17,7 @@ rustPlatform.buildRustPackage rec { pname = "afk-cmds"; version= "1.0.0"; - src = fetchFromGitHub { - owner = "ISnortPennies"; - repo = "afk-cmds"; - rev = "b345d5a038a86c6ca31d3bd8800ac759da912a22"; - sha256 = "sha256-yleq8bg3ZnilbYTNXRteBALiJ/fIXOxXxqf966OokqQ="; - }; + src = ./afk-cmds; buildInputs = [ libX11