mirror of
https://gitlab.freedesktop.org/pipewire/helvum
synced 2026-03-15 19:46:10 +08:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2ee7bca68a | ||
|
|
494d3a383f | ||
|
|
b719e0d2ec | ||
|
|
f64a936dd9 | ||
|
|
179665778d | ||
|
|
be9339472e | ||
|
|
e29ffdeea8 | ||
|
|
add1a96b75 | ||
|
|
9445e173f9 | ||
|
|
58794fe123 | ||
|
|
8d6fbe2997 | ||
|
|
b0bf5e5281 | ||
|
|
edc4064009 | ||
|
|
58cdcd859b | ||
|
|
7977481689 | ||
|
|
f09fd596c8 | ||
|
|
1247b29bae | ||
|
|
74ffb06b40 | ||
|
|
81467154d9 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,2 +1,3 @@
|
|||||||
|
/.flatpak-builder
|
||||||
/.vscode
|
/.vscode
|
||||||
/target
|
/target
|
||||||
|
|||||||
262
Cargo.lock
generated
262
Cargo.lock
generated
@@ -1,10 +1,12 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
version = "0.7.18"
|
version = "0.7.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
|
checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
@@ -20,9 +22,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
version = "1.0.40"
|
version = "1.0.42"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b"
|
checksum = "595d3cfa7a60d4555cb5067b99f07142a08ea778de5cf993f7b75c7d8fabc486"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arrayvec"
|
name = "arrayvec"
|
||||||
@@ -49,15 +51,15 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bindgen"
|
name = "bindgen"
|
||||||
version = "0.58.1"
|
version = "0.59.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0f8523b410d7187a43085e7e064416ea32ded16bd0a4e6fc025e21616d01258f"
|
checksum = "453c49e5950bb0eb63bb3df640e31618846c89d5b7faa54040d76e98e0134375"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"cexpr",
|
"cexpr",
|
||||||
"clang-sys",
|
"clang-sys",
|
||||||
"clap",
|
"clap",
|
||||||
"env_logger",
|
"env_logger 0.8.4",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"lazycell",
|
"lazycell",
|
||||||
"log",
|
"log",
|
||||||
@@ -90,8 +92,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cairo-rs"
|
name = "cairo-rs"
|
||||||
version = "0.14.0"
|
version = "0.14.1"
|
||||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#a6815e75a8803c71b8e7cf7d35bf322376e934d6"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a408c13bbc04c3337b94194c1a4d04067097439b79dbc1dcbceba299d828b9ea"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"cairo-sys-rs",
|
"cairo-sys-rs",
|
||||||
@@ -103,7 +106,8 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "cairo-sys-rs"
|
name = "cairo-sys-rs"
|
||||||
version = "0.14.0"
|
version = "0.14.0"
|
||||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#a6815e75a8803c71b8e7cf7d35bf322376e934d6"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d7c9c3928781e8a017ece15eace05230f04b647457d170d2d9641c94a444ff80"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glib-sys",
|
"glib-sys",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -112,24 +116,24 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.68"
|
version = "1.0.69"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787"
|
checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cexpr"
|
name = "cexpr"
|
||||||
version = "0.4.0"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27"
|
checksum = "db507a7679252d2276ed0dd8113c6875ec56d3089f9225b2b42c30cc1f8e5c89"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"nom 5.1.2",
|
"nom",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-expr"
|
name = "cfg-expr"
|
||||||
version = "0.7.4"
|
version = "0.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "30aa9e2ffbb838c6b451db14f3cd8e63ed622bf859f9956bc93845a10fafc26a"
|
checksum = "b412e83326147c2bb881f8b40edfbf9905b9b8abaebd0e47ca190ba62fda8f0e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"smallvec",
|
"smallvec",
|
||||||
]
|
]
|
||||||
@@ -186,9 +190,22 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "env_logger"
|
name = "env_logger"
|
||||||
version = "0.8.3"
|
version = "0.8.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "17392a012ea30ef05a610aa97dfb49496e71c9f676b27879922ea5bdf60d9d3f"
|
checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3"
|
||||||
|
dependencies = [
|
||||||
|
"atty",
|
||||||
|
"humantime",
|
||||||
|
"log",
|
||||||
|
"regex",
|
||||||
|
"termcolor",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "env_logger"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
"atty",
|
||||||
"humantime",
|
"humantime",
|
||||||
@@ -236,24 +253,24 @@ checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-channel"
|
name = "futures-channel"
|
||||||
version = "0.3.15"
|
version = "0.3.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e682a68b29a882df0545c143dc3646daefe80ba479bcdede94d5a703de2871e2"
|
checksum = "74ed2411805f6e4e3d9bc904c95d5d423b89b3b25dc0250aa74729de20629ff9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-core"
|
name = "futures-core"
|
||||||
version = "0.3.15"
|
version = "0.3.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0402f765d8a89a26043b889b26ce3c4679d268fa6bb22cd7c6aad98340e179d1"
|
checksum = "af51b1b4a7fdff033703db39de8802c673eb91855f2e0d47dcf3bf2c0ef01f99"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-executor"
|
name = "futures-executor"
|
||||||
version = "0.3.15"
|
version = "0.3.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "badaa6a909fac9e7236d0620a2f57f7664640c56575b71a7552fbd68deafab79"
|
checksum = "4d0d535a57b87e1ae31437b892713aee90cd2d7b0ee48727cd11fc72ef54761c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-task",
|
"futures-task",
|
||||||
@@ -262,21 +279,21 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-io"
|
name = "futures-io"
|
||||||
version = "0.3.15"
|
version = "0.3.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "acc499defb3b348f8d8f3f66415835a9131856ff7714bf10dadfc4ec4bdb29a1"
|
checksum = "0b0e06c393068f3a6ef246c75cdca793d6a46347e75286933e5e75fd2fd11582"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-task"
|
name = "futures-task"
|
||||||
version = "0.3.15"
|
version = "0.3.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8a16bef9fc1a4dddb5bee51c989e3fbba26569cbb0e31f5b303c184e3dd33dae"
|
checksum = "bbe54a98670017f3be909561f6ad13e810d9a51f3f061b902062ca3da80799f2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-util"
|
name = "futures-util"
|
||||||
version = "0.3.15"
|
version = "0.3.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "feb5c238d27e2bf94ffdfd27b2c29e3df4a68c4193bb6427384259e2bf191967"
|
checksum = "67eb846bfd58e44a8481a00049e82c43e0ccb5d61f8dc071057cb19249dd4d78"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
@@ -295,7 +312,8 @@ checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "gdk-pixbuf"
|
name = "gdk-pixbuf"
|
||||||
version = "0.14.0"
|
version = "0.14.0"
|
||||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#a6815e75a8803c71b8e7cf7d35bf322376e934d6"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "534192cb8f01daeb8fab2c8d4baa8f9aae5b7a39130525779f5c2608e235b10f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gdk-pixbuf-sys",
|
"gdk-pixbuf-sys",
|
||||||
"gio",
|
"gio",
|
||||||
@@ -306,7 +324,8 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "gdk-pixbuf-sys"
|
name = "gdk-pixbuf-sys"
|
||||||
version = "0.14.0"
|
version = "0.14.0"
|
||||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#a6815e75a8803c71b8e7cf7d35bf322376e934d6"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f097c0704201fbc8f69c1762dc58c6947c8bb188b8ed0bc7e65259f1894fe590"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gio-sys",
|
"gio-sys",
|
||||||
"glib-sys",
|
"glib-sys",
|
||||||
@@ -317,8 +336,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gdk4"
|
name = "gdk4"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/gtk-rs/gtk4-rs/#ff9e0b861ccf59d4ced5ea67bdd004f138419cb7"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8ce41092cc569129a0afa34926e6dd1cf8411e25652d87febdea36859f7ff7ba"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"cairo-rs",
|
"cairo-rs",
|
||||||
@@ -332,8 +352,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gdk4-sys"
|
name = "gdk4-sys"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/gtk-rs/gtk4-rs/#ff9e0b861ccf59d4ced5ea67bdd004f138419cb7"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ce39c71861b5bcde319fd4711a74e1bd6f4f474911170d51096597fef0b56011"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cairo-sys-rs",
|
"cairo-sys-rs",
|
||||||
"gdk-pixbuf-sys",
|
"gdk-pixbuf-sys",
|
||||||
@@ -349,7 +370,8 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "gio"
|
name = "gio"
|
||||||
version = "0.14.0"
|
version = "0.14.0"
|
||||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#a6815e75a8803c71b8e7cf7d35bf322376e934d6"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "86c6823b39d46d22cac2466de261f28d7f049ebc18f7b35296a42c7ed8a88325"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
@@ -365,7 +387,8 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "gio-sys"
|
name = "gio-sys"
|
||||||
version = "0.14.0"
|
version = "0.14.0"
|
||||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#a6815e75a8803c71b8e7cf7d35bf322376e934d6"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c0a41df66e57fcc287c4bcf74fc26b884f31901ea9792ec75607289b456f48fa"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glib-sys",
|
"glib-sys",
|
||||||
"gobject-sys",
|
"gobject-sys",
|
||||||
@@ -376,8 +399,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glib"
|
name = "glib"
|
||||||
version = "0.14.0"
|
version = "0.14.2"
|
||||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#a6815e75a8803c71b8e7cf7d35bf322376e934d6"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dbecad7a3a898ee749d491ce2ae0decb0bce9e736f9747bc49159b1cea5d37f4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
@@ -394,8 +418,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glib-macros"
|
name = "glib-macros"
|
||||||
version = "0.14.0"
|
version = "0.14.1"
|
||||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#a6815e75a8803c71b8e7cf7d35bf322376e934d6"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2aad66361f66796bfc73f530c51ef123970eb895ffba991a234fcf7bea89e518"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"heck",
|
"heck",
|
||||||
@@ -409,7 +434,8 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "glib-sys"
|
name = "glib-sys"
|
||||||
version = "0.14.0"
|
version = "0.14.0"
|
||||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#a6815e75a8803c71b8e7cf7d35bf322376e934d6"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1c1d60554a212445e2a858e42a0e48cece1bd57b311a19a9468f70376cf554ae"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"system-deps",
|
"system-deps",
|
||||||
@@ -424,7 +450,8 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "gobject-sys"
|
name = "gobject-sys"
|
||||||
version = "0.14.0"
|
version = "0.14.0"
|
||||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#a6815e75a8803c71b8e7cf7d35bf322376e934d6"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "aa92cae29759dae34ab5921d73fff5ad54b3d794ab842c117e36cafc7994c3f5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glib-sys",
|
"glib-sys",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -434,7 +461,8 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "graphene-rs"
|
name = "graphene-rs"
|
||||||
version = "0.14.0"
|
version = "0.14.0"
|
||||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#a6815e75a8803c71b8e7cf7d35bf322376e934d6"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f1460a39f06e491e6112f27e71e51435c833ba370723224dd1743dfd1f201f19"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glib",
|
"glib",
|
||||||
"graphene-sys",
|
"graphene-sys",
|
||||||
@@ -444,7 +472,8 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "graphene-sys"
|
name = "graphene-sys"
|
||||||
version = "0.14.0"
|
version = "0.14.0"
|
||||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#a6815e75a8803c71b8e7cf7d35bf322376e934d6"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e7d23fb7a9547e5f072a7e0cd49cd648fedeb786d122b106217511980cbb8962"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glib-sys",
|
"glib-sys",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -454,8 +483,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gsk4"
|
name = "gsk4"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/gtk-rs/gtk4-rs/#ff9e0b861ccf59d4ced5ea67bdd004f138419cb7"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "64932b730eaad3340378a03d633616eeed6d6705b59b81c9f579c88be8932475"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"cairo-rs",
|
"cairo-rs",
|
||||||
@@ -469,8 +499,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gsk4-sys"
|
name = "gsk4-sys"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/gtk-rs/gtk4-rs/#ff9e0b861ccf59d4ced5ea67bdd004f138419cb7"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "685ffc776bedd91d68f47b41239525778b669432889721d7050d045270549b9a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cairo-sys-rs",
|
"cairo-sys-rs",
|
||||||
"gdk4-sys",
|
"gdk4-sys",
|
||||||
@@ -484,8 +515,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gtk4"
|
name = "gtk4"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/gtk-rs/gtk4-rs/#ff9e0b861ccf59d4ced5ea67bdd004f138419cb7"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c49e0311dac847a8ebc05e31f5c44c596314ee3b16c5f638ccfe24086d24bf1b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"cairo-rs",
|
"cairo-rs",
|
||||||
@@ -506,8 +538,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gtk4-macros"
|
name = "gtk4-macros"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/gtk-rs/gtk4-rs/#ff9e0b861ccf59d4ced5ea67bdd004f138419cb7"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bbe4b77996bcf1ef20208c00043edda854ca2091b4be5e6a7c367f0f3846fa67"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"heck",
|
"heck",
|
||||||
@@ -521,8 +554,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gtk4-sys"
|
name = "gtk4-sys"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/gtk-rs/gtk4-rs/#ff9e0b861ccf59d4ced5ea67bdd004f138419cb7"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3737e91619cf4257d8a07834f7a2c035d4daeaf9ad8e3958e56b2c411dbdca18"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cairo-sys-rs",
|
"cairo-sys-rs",
|
||||||
"gdk-pixbuf-sys",
|
"gdk-pixbuf-sys",
|
||||||
@@ -548,9 +582,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "helvum"
|
name = "helvum"
|
||||||
version = "0.2.1"
|
version = "0.3.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"env_logger",
|
"env_logger 0.9.0",
|
||||||
"gtk4",
|
"gtk4",
|
||||||
"log",
|
"log",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
@@ -559,9 +593,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
version = "0.1.18"
|
version = "0.1.19"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
|
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
@@ -574,9 +608,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itertools"
|
name = "itertools"
|
||||||
version = "0.10.0"
|
version = "0.10.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319"
|
checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"either",
|
"either",
|
||||||
]
|
]
|
||||||
@@ -608,9 +642,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.95"
|
version = "0.2.98"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "789da6d93f1b866ffe175afc5322a4d76c038605a1c3319bb57b06967ca98a36"
|
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libloading"
|
name = "libloading"
|
||||||
@@ -624,8 +658,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libspa"
|
name = "libspa"
|
||||||
version = "0.3.0"
|
version = "0.4.1"
|
||||||
source = "git+https://gitlab.freedesktop.org/pipewire/pipewire-rs?branch=main#62ce08ed59e711c2a438bb06fe60d956ececfb07"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "aeb373e8b03740369c5fe48a557c6408b6898982d57e17940de144375d472743"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"cc",
|
"cc",
|
||||||
@@ -633,14 +668,15 @@ dependencies = [
|
|||||||
"errno",
|
"errno",
|
||||||
"libc",
|
"libc",
|
||||||
"libspa-sys",
|
"libspa-sys",
|
||||||
"nom 6.1.2",
|
"nom",
|
||||||
"system-deps",
|
"system-deps",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libspa-sys"
|
name = "libspa-sys"
|
||||||
version = "0.3.0"
|
version = "0.4.1"
|
||||||
source = "git+https://gitlab.freedesktop.org/pipewire/pipewire-rs?branch=main#62ce08ed59e711c2a438bb06fe60d956ececfb07"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d301a2fc2fed0a97c13836408a4d98f419af0c2695ecf74e634a214c17beefa6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bindgen",
|
"bindgen",
|
||||||
"system-deps",
|
"system-deps",
|
||||||
@@ -657,9 +693,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.4.0"
|
version = "2.3.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
|
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memoffset"
|
name = "memoffset"
|
||||||
@@ -685,19 +721,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nom"
|
name = "nom"
|
||||||
version = "5.1.2"
|
version = "6.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
|
checksum = "9c5c51b9083a3c620fa67a2a635d1ce7d95b897e957d6b28ff9a5da960a103a6"
|
||||||
dependencies = [
|
|
||||||
"memchr",
|
|
||||||
"version_check",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "nom"
|
|
||||||
version = "6.1.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e7413f999671bd4745a7b624bd370a569fb6bc574b23c83a3c5ed2e453f3d5e2"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitvec",
|
"bitvec",
|
||||||
"funty",
|
"funty",
|
||||||
@@ -708,14 +734,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.7.2"
|
version = "1.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3"
|
checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pango"
|
name = "pango"
|
||||||
version = "0.14.0"
|
version = "0.14.0"
|
||||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#a6815e75a8803c71b8e7cf7d35bf322376e934d6"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "415823a4fb9f1789785cd6e2d2413816f2ecff92380382969aaca9c400e13a19"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"glib",
|
"glib",
|
||||||
@@ -727,7 +754,8 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "pango-sys"
|
name = "pango-sys"
|
||||||
version = "0.14.0"
|
version = "0.14.0"
|
||||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#a6815e75a8803c71b8e7cf7d35bf322376e934d6"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2367099ca5e761546ba1d501955079f097caa186bb53ce0f718dca99ac1942fe"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glib-sys",
|
"glib-sys",
|
||||||
"gobject-sys",
|
"gobject-sys",
|
||||||
@@ -752,9 +780,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project-lite"
|
name = "pin-project-lite"
|
||||||
version = "0.2.6"
|
version = "0.2.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905"
|
checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-utils"
|
name = "pin-utils"
|
||||||
@@ -764,8 +792,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pipewire"
|
name = "pipewire"
|
||||||
version = "0.3.0"
|
version = "0.4.1"
|
||||||
source = "git+https://gitlab.freedesktop.org/pipewire/pipewire-rs?branch=main#62ce08ed59e711c2a438bb06fe60d956ececfb07"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5de050d879e7b8d9313429ec314b88b26fe48ba29a6ecc3bc8289d3673fee6c8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
@@ -781,8 +810,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pipewire-sys"
|
name = "pipewire-sys"
|
||||||
version = "0.3.0"
|
version = "0.4.1"
|
||||||
source = "git+https://gitlab.freedesktop.org/pipewire/pipewire-rs?branch=main#62ce08ed59e711c2a438bb06fe60d956ececfb07"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9b4aa5ef9f3afef7dbb335106f69bd6bb541259e8796c693810cde20db1eb949"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bindgen",
|
"bindgen",
|
||||||
"libspa-sys",
|
"libspa-sys",
|
||||||
@@ -831,9 +861,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.27"
|
version = "1.0.28"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038"
|
checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
@@ -855,9 +885,9 @@ checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.5.4"
|
version = "1.4.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
|
checksum = "2a26af418b574bd56588335b3a3659a65725d4e636eb1016c2f9e3b38c7cc759"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
@@ -911,9 +941,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.126"
|
version = "1.0.127"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03"
|
checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shlex"
|
name = "shlex"
|
||||||
@@ -933,9 +963,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.3"
|
version = "0.4.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527"
|
checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
@@ -957,15 +987,15 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strum"
|
name = "strum"
|
||||||
version = "0.20.0"
|
version = "0.21.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7318c509b5ba57f18533982607f24070a55d353e90d4cae30c467cdb2ad5ac5c"
|
checksum = "aaf86bbcfd1fa9670b7a129f64fc0c9fcbbfe4f1bc4210e9e98fe71ffc12cde2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strum_macros"
|
name = "strum_macros"
|
||||||
version = "0.20.1"
|
version = "0.21.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ee8bc6b87a5112aeeab1f4a9f7ab634fe6cbefc4850006df31267f4cfb9e3149"
|
checksum = "d06aaeeee809dbc59eb4556183dd927df67db1540de5be8d3ec0b6636358a5ec"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck",
|
"heck",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
@@ -975,9 +1005,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.72"
|
version = "1.0.74"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82"
|
checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -986,9 +1016,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "system-deps"
|
name = "system-deps"
|
||||||
version = "3.1.1"
|
version = "3.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c248107ad7bc1ac07066a4d003cae9e9a7bc2e27d3418f7a9cdcdc8699dbea70"
|
checksum = "480c269f870722b3b08d2f13053ce0c2ab722839f472863c3e2d61ff3a1c2fa6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"cfg-expr",
|
"cfg-expr",
|
||||||
@@ -1028,18 +1058,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.25"
|
version = "1.0.26"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fa6f76457f59514c7eeb4e59d891395fab0b2fd1d40723ae737d64153392e9c6"
|
checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror-impl",
|
"thiserror-impl",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror-impl"
|
name = "thiserror-impl"
|
||||||
version = "1.0.25"
|
version = "1.0.26"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8a36768c0fbf1bb15eca10defa29526bda730a2376c2ab4393ccfa16fb1a318d"
|
checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -1063,9 +1093,9 @@ checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-segmentation"
|
name = "unicode-segmentation"
|
||||||
version = "1.7.1"
|
version = "1.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796"
|
checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-width"
|
name = "unicode-width"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "helvum"
|
name = "helvum"
|
||||||
version = "0.2.1"
|
version = "0.3.0"
|
||||||
authors = ["Tom A. Wagner <tom.a.wagner@protonmail.com>"]
|
authors = ["Tom A. Wagner <tom.a.wagner@protonmail.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
license = "GPL-3.0-only"
|
license = "GPL-3.0-only"
|
||||||
@@ -13,10 +13,10 @@ categories = ["gui", "multimedia"]
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
gtk = { git = "https://github.com/gtk-rs/gtk4-rs/", package = "gtk4" }
|
pipewire = "0.4"
|
||||||
pipewire = { git = "https://gitlab.freedesktop.org/pipewire/pipewire-rs", branch = "main" }
|
gtk = { version = "0.2", package = "gtk4" }
|
||||||
|
|
||||||
log = "0.4.11"
|
log = "0.4.11"
|
||||||
env_logger = "0.8.2"
|
env_logger = "0.9.0"
|
||||||
|
|
||||||
once_cell = "1.7.2"
|
once_cell = "1.7.2"
|
||||||
|
|||||||
33
README.md
33
README.md
@@ -2,6 +2,9 @@ Helvum is a GTK-based patchbay for pipewire, inspired by the JACK tool [catia](h
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
[](https://repology.org/project/helvum/versions)
|
||||||
|
|
||||||
|
|
||||||
# Features planned
|
# Features planned
|
||||||
|
|
||||||
- Volume control
|
- Volume control
|
||||||
@@ -9,13 +12,27 @@ Helvum is a GTK-based patchbay for pipewire, inspired by the JACK tool [catia](h
|
|||||||
|
|
||||||
More suggestions are welcome!
|
More suggestions are welcome!
|
||||||
|
|
||||||
# Distribution packages
|
|
||||||
|
|
||||||
- ArchLinux:
|
|
||||||
- [aur/helvum](https://aur.archlinux.org/packages/helvum)
|
|
||||||
- [aur/helvum-git](https://aur.archlinux.org/packages/helvum-git)
|
|
||||||
|
|
||||||
# Building
|
# Building
|
||||||
|
|
||||||
|
## Via flatpak (recommended)
|
||||||
|
The recommended way to build is using flatpak, which will take care of all dependencies and avoid any problems that may come from different system configurations.
|
||||||
|
|
||||||
|
First, install the required flatpak platform and SDK, if you dont have them already:
|
||||||
|
```shell
|
||||||
|
$ flatpak install org.gnome.{Platform,Sdk}//40 org.freedesktop.Sdk.Extension.rust-stable//20.08
|
||||||
|
```
|
||||||
|
|
||||||
|
To compile and install as a flatpak, run
|
||||||
|
```shell
|
||||||
|
$ flatpak-builder --install flatpak-build/ org.freedesktop.ryuukyu.Helvum.json
|
||||||
|
```
|
||||||
|
|
||||||
|
You can then run the app via
|
||||||
|
```shell
|
||||||
|
flatpak run org.freedesktop.ryuukyu.Helvum
|
||||||
|
```
|
||||||
|
|
||||||
|
## Manually
|
||||||
For compilation, you will need:
|
For compilation, you will need:
|
||||||
|
|
||||||
- An up-to-date rust toolchain
|
- An up-to-date rust toolchain
|
||||||
@@ -28,3 +45,7 @@ To compile, run
|
|||||||
|
|
||||||
in the repository root.
|
in the repository root.
|
||||||
The resulting binary will be at `target/release/helvum`.
|
The resulting binary will be at `target/release/helvum`.
|
||||||
|
|
||||||
|
# License
|
||||||
|
Helvum is distributed under the terms of the GPL3 license.
|
||||||
|
See LICENSE for more information.
|
||||||
36
org.freedesktop.ryuukyu.Helvum.json
Normal file
36
org.freedesktop.ryuukyu.Helvum.json
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"app-id": "org.freedesktop.ryuukyu.Helvum",
|
||||||
|
"runtime": "org.gnome.Platform",
|
||||||
|
"runtime-version": "40",
|
||||||
|
"sdk": "org.gnome.Sdk",
|
||||||
|
"sdk-extensions": ["org.freedesktop.Sdk.Extension.rust-stable"],
|
||||||
|
"command": "helvum",
|
||||||
|
"finish-args" : [
|
||||||
|
"--socket=fallback-x11",
|
||||||
|
"--socket=wayland",
|
||||||
|
"--device=dri",
|
||||||
|
"--share=ipc",
|
||||||
|
"--filesystem=xdg-run/pipewire-0"
|
||||||
|
],
|
||||||
|
"build-options" : {
|
||||||
|
"append-path" : "/usr/lib/sdk/rust-stable/bin",
|
||||||
|
"build-args" : [
|
||||||
|
"--share=network"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"modules": [
|
||||||
|
{
|
||||||
|
"name": "Helvum",
|
||||||
|
"buildsystem": "simple",
|
||||||
|
"build-commands": [
|
||||||
|
"cargo install --path . --root /app --no-track"
|
||||||
|
],
|
||||||
|
"sources": [
|
||||||
|
{
|
||||||
|
"type": "dir",
|
||||||
|
"path": "./"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -83,7 +83,7 @@ impl Application {
|
|||||||
pw_sender: Sender<GtkMessage>,
|
pw_sender: Sender<GtkMessage>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let app: Application =
|
let app: Application =
|
||||||
glib::Object::new(&[("application-id", &"org.freedesktop.ryuukyu.helvum")])
|
glib::Object::new(&[("application-id", &"org.freedesktop.ryuukyu.Helvum")])
|
||||||
.expect("Failed to create new Application");
|
.expect("Failed to create new Application");
|
||||||
|
|
||||||
let imp = imp::Application::from_instance(&app);
|
let imp = imp::Application::from_instance(&app);
|
||||||
@@ -108,9 +108,10 @@ impl Application {
|
|||||||
@weak app => @default-return Continue(true),
|
@weak app => @default-return Continue(true),
|
||||||
move |msg| {
|
move |msg| {
|
||||||
match msg {
|
match msg {
|
||||||
PipewireMessage::NodeAdded{ id, name } => app.add_node(id,name),
|
PipewireMessage::NodeAdded{ id, name } => app.add_node(id, name.as_str()),
|
||||||
PipewireMessage::PortAdded{ id, node_id, name, direction, media_type} => app.add_port(id,name,node_id,direction,media_type),
|
PipewireMessage::PortAdded{ id, node_id, name, direction, media_type } => app.add_port(id, name.as_str(), node_id, direction, media_type),
|
||||||
PipewireMessage::LinkAdded{ id, node_from, port_from, node_to, port_to} => app.add_link(id,node_from,port_from,node_to,port_to),
|
PipewireMessage::LinkAdded{ id, node_from, port_from, node_to, port_to, active} => app.add_link(id, node_from, port_from, node_to, port_to, active),
|
||||||
|
PipewireMessage::LinkStateChanged { id, active } => app.link_state_changed(id, active), // TODO
|
||||||
PipewireMessage::NodeRemoved { id } => app.remove_node(id),
|
PipewireMessage::NodeRemoved { id } => app.remove_node(id),
|
||||||
PipewireMessage::PortRemoved { id, node_id } => app.remove_port(id, node_id),
|
PipewireMessage::PortRemoved { id, node_id } => app.remove_port(id, node_id),
|
||||||
PipewireMessage::LinkRemoved { id } => app.remove_link(id)
|
PipewireMessage::LinkRemoved { id } => app.remove_link(id)
|
||||||
@@ -124,19 +125,19 @@ impl Application {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Add a new node to the view.
|
/// Add a new node to the view.
|
||||||
pub fn add_node(&self, id: u32, name: String) {
|
fn add_node(&self, id: u32, name: &str) {
|
||||||
info!("Adding node to graph: id {}", id);
|
info!("Adding node to graph: id {}", id);
|
||||||
|
|
||||||
imp::Application::from_instance(self)
|
imp::Application::from_instance(self)
|
||||||
.graphview
|
.graphview
|
||||||
.add_node(id, view::Node::new(name.as_str()));
|
.add_node(id, view::Node::new(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a new port to the view.
|
/// Add a new port to the view.
|
||||||
pub fn add_port(
|
fn add_port(
|
||||||
&self,
|
&self,
|
||||||
id: u32,
|
id: u32,
|
||||||
name: String,
|
name: &str,
|
||||||
node_id: u32,
|
node_id: u32,
|
||||||
direction: Direction,
|
direction: Direction,
|
||||||
media_type: Option<MediaType>,
|
media_type: Option<MediaType>,
|
||||||
@@ -145,7 +146,7 @@ impl Application {
|
|||||||
|
|
||||||
let imp = imp::Application::from_instance(self);
|
let imp = imp::Application::from_instance(self);
|
||||||
|
|
||||||
let port = view::Port::new(id, name.as_str(), direction, media_type);
|
let port = view::Port::new(id, name, direction, media_type);
|
||||||
|
|
||||||
// Create or delete a link if the widget emits the "port-toggled" signal.
|
// Create or delete a link if the widget emits the "port-toggled" signal.
|
||||||
if let Err(e) = port.connect_local(
|
if let Err(e) = port.connect_local(
|
||||||
@@ -168,7 +169,15 @@ impl Application {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Add a new link to the view.
|
/// Add a new link to the view.
|
||||||
pub fn add_link(&self, id: u32, node_from: u32, port_from: u32, node_to: u32, port_to: u32) {
|
fn add_link(
|
||||||
|
&self,
|
||||||
|
id: u32,
|
||||||
|
node_from: u32,
|
||||||
|
port_from: u32,
|
||||||
|
node_to: u32,
|
||||||
|
port_to: u32,
|
||||||
|
active: bool,
|
||||||
|
) {
|
||||||
info!("Adding link to graph: id {}", id);
|
info!("Adding link to graph: id {}", id);
|
||||||
|
|
||||||
// FIXME: Links should be colored depending on the data they carry (video, audio, midi) like ports are.
|
// FIXME: Links should be colored depending on the data they carry (video, audio, midi) like ports are.
|
||||||
@@ -182,9 +191,22 @@ impl Application {
|
|||||||
node_to,
|
node_to,
|
||||||
port_to,
|
port_to,
|
||||||
},
|
},
|
||||||
|
active,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn link_state_changed(&self, id: u32, active: bool) {
|
||||||
|
info!(
|
||||||
|
"Link state changed: Link (id={}) is now {}",
|
||||||
|
id,
|
||||||
|
if active { "active" } else { "inactive" }
|
||||||
|
);
|
||||||
|
|
||||||
|
imp::Application::from_instance(self)
|
||||||
|
.graphview
|
||||||
|
.set_link_state(id, active);
|
||||||
|
}
|
||||||
|
|
||||||
// Toggle a link between the two specified ports on the remote pipewire server.
|
// Toggle a link between the two specified ports on the remote pipewire server.
|
||||||
fn toggle_link(&self, port_from: u32, port_to: u32) {
|
fn toggle_link(&self, port_from: u32, port_to: u32) {
|
||||||
let imp = imp::Application::from_instance(self);
|
let imp = imp::Application::from_instance(self);
|
||||||
|
|||||||
@@ -37,6 +37,11 @@ enum PipewireMessage {
|
|||||||
port_from: u32,
|
port_from: u32,
|
||||||
node_to: u32,
|
node_to: u32,
|
||||||
port_to: u32,
|
port_to: u32,
|
||||||
|
active: bool,
|
||||||
|
},
|
||||||
|
LinkStateChanged {
|
||||||
|
id: u32,
|
||||||
|
active: bool,
|
||||||
},
|
},
|
||||||
NodeRemoved {
|
NodeRemoved {
|
||||||
id: u32,
|
id: u32,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use std::{cell::RefCell, collections::HashMap, rc::Rc};
|
|||||||
use gtk::glib::{self, clone};
|
use gtk::glib::{self, clone};
|
||||||
use log::{debug, info, warn};
|
use log::{debug, info, warn};
|
||||||
use pipewire::{
|
use pipewire::{
|
||||||
link::{Link, LinkListener},
|
link::{Link, LinkChangeMask, LinkListener, LinkState},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
properties,
|
properties,
|
||||||
registry::{GlobalObject, Registry},
|
registry::{GlobalObject, Registry},
|
||||||
@@ -100,20 +100,17 @@ fn handle_node(
|
|||||||
);
|
);
|
||||||
|
|
||||||
// FIXME: Instead of checking these props, the "EnumFormat" parameter should be checked instead.
|
// FIXME: Instead of checking these props, the "EnumFormat" parameter should be checked instead.
|
||||||
let media_type = props
|
let media_type = props.get("media.class").and_then(|class| {
|
||||||
.get("media.class")
|
if class.contains("Audio") {
|
||||||
.map(|class| {
|
Some(MediaType::Audio)
|
||||||
if class.contains("Audio") {
|
} else if class.contains("Video") {
|
||||||
Some(MediaType::Audio)
|
Some(MediaType::Video)
|
||||||
} else if class.contains("Video") {
|
} else if class.contains("Midi") {
|
||||||
Some(MediaType::Video)
|
Some(MediaType::Midi)
|
||||||
} else if class.contains("Midi") {
|
} else {
|
||||||
Some(MediaType::Midi)
|
None
|
||||||
} else {
|
}
|
||||||
None
|
});
|
||||||
}
|
|
||||||
})
|
|
||||||
.flatten();
|
|
||||||
|
|
||||||
state.borrow_mut().insert(
|
state.borrow_mut().insert(
|
||||||
node.id,
|
node.id,
|
||||||
@@ -196,7 +193,13 @@ fn handle_link(
|
|||||||
let mut state = state.borrow_mut();
|
let mut state = state.borrow_mut();
|
||||||
if let Some(Item::Link { .. }) = state.get(id) {
|
if let Some(Item::Link { .. }) = state.get(id) {
|
||||||
// Info was an update - figure out if we should notify the gtk thread
|
// Info was an update - figure out if we should notify the gtk thread
|
||||||
// TODO
|
if info.change_mask().contains(LinkChangeMask::STATE) {
|
||||||
|
sender.send(PipewireMessage::LinkStateChanged {
|
||||||
|
id,
|
||||||
|
active: matches!(info.state(), LinkState::Active)
|
||||||
|
}).expect("Failed to send message");
|
||||||
|
}
|
||||||
|
// TODO -- check other values that might have changed
|
||||||
} else {
|
} else {
|
||||||
// First time we get info. We can now notify the gtk thread of a new link.
|
// First time we get info. We can now notify the gtk thread of a new link.
|
||||||
let node_from = info.output_node_id();
|
let node_from = info.output_node_id();
|
||||||
@@ -213,7 +216,8 @@ fn handle_link(
|
|||||||
node_from,
|
node_from,
|
||||||
port_from,
|
port_from,
|
||||||
node_to,
|
node_to,
|
||||||
port_to
|
port_to,
|
||||||
|
active: matches!(info.state(), LinkState::Active)
|
||||||
}).expect(
|
}).expect(
|
||||||
"Failed to send message"
|
"Failed to send message"
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ pub(super) struct State {
|
|||||||
impl State {
|
impl State {
|
||||||
/// Create a new, empty state.
|
/// Create a new, empty state.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Default::default()
|
Self::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a new item under the specified id.
|
/// Add a new item under the specified id.
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use gtk::{
|
|||||||
prelude::*,
|
prelude::*,
|
||||||
subclass::prelude::*,
|
subclass::prelude::*,
|
||||||
};
|
};
|
||||||
|
use log::{error, warn};
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
@@ -19,7 +20,8 @@ mod imp {
|
|||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct GraphView {
|
pub struct GraphView {
|
||||||
pub(super) nodes: RefCell<HashMap<u32, Node>>,
|
pub(super) nodes: RefCell<HashMap<u32, Node>>,
|
||||||
pub(super) links: RefCell<HashMap<u32, crate::PipewireLink>>,
|
/// Stores the link and whether it is currently active.
|
||||||
|
pub(super) links: RefCell<HashMap<u32, (crate::PipewireLink, bool)>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[glib::object_subclass]
|
#[glib::object_subclass]
|
||||||
@@ -96,7 +98,7 @@ mod imp {
|
|||||||
|
|
||||||
let alloc = widget.allocation();
|
let alloc = widget.allocation();
|
||||||
|
|
||||||
let cr = snapshot
|
let background_cr = snapshot
|
||||||
.append_cairo(&graphene::Rect::new(
|
.append_cairo(&graphene::Rect::new(
|
||||||
0.0,
|
0.0,
|
||||||
0.0,
|
0.0,
|
||||||
@@ -107,51 +109,79 @@ mod imp {
|
|||||||
|
|
||||||
// Try to replace the background color with a darker one from the theme.
|
// Try to replace the background color with a darker one from the theme.
|
||||||
if let Some(rgba) = widget.style_context().lookup_color("text_view_bg") {
|
if let Some(rgba) = widget.style_context().lookup_color("text_view_bg") {
|
||||||
cr.set_source_rgb(rgba.red.into(), rgba.green.into(), rgba.blue.into());
|
background_cr.set_source_rgb(rgba.red.into(), rgba.green.into(), rgba.blue.into());
|
||||||
if let Err(e) = cr.paint() {
|
if let Err(e) = background_cr.paint() {
|
||||||
warn!("Failed to paint graphview background: {}", e);
|
warn!("Failed to paint graphview background: {}", e);
|
||||||
};
|
};
|
||||||
} // TODO: else log colour not found
|
} // TODO: else log colour not found
|
||||||
|
|
||||||
// Draw a nice grid on the background.
|
// Draw a nice grid on the background.
|
||||||
cr.set_source_rgb(0.18, 0.18, 0.18);
|
background_cr.set_source_rgb(0.18, 0.18, 0.18);
|
||||||
cr.set_line_width(0.2); // TODO: Set to 1px
|
background_cr.set_line_width(0.2); // TODO: Set to 1px
|
||||||
let mut y = 0.0;
|
let mut y = 0.0;
|
||||||
while y < alloc.height.into() {
|
while y < alloc.height.into() {
|
||||||
cr.move_to(0.0, y);
|
background_cr.move_to(0.0, y);
|
||||||
cr.line_to(alloc.width as f64, y);
|
background_cr.line_to(alloc.width.into(), y);
|
||||||
y += 20.0; // TODO: Change to em;
|
y += 20.0; // TODO: Change to em;
|
||||||
}
|
}
|
||||||
let mut x = 0.0;
|
let mut x = 0.0;
|
||||||
while x < alloc.width as f64 {
|
while x < alloc.width.into() {
|
||||||
cr.move_to(x, 0.0);
|
background_cr.move_to(x, 0.0);
|
||||||
cr.line_to(x, alloc.height as f64);
|
background_cr.line_to(x, alloc.height.into());
|
||||||
x += 20.0; // TODO: Change to em;
|
x += 20.0; // TODO: Change to em;
|
||||||
}
|
}
|
||||||
if let Err(e) = cr.stroke() {
|
if let Err(e) = background_cr.stroke() {
|
||||||
warn!("Failed to draw graphview grid: {}", e);
|
warn!("Failed to draw graphview grid: {}", e);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Draw all links
|
|
||||||
cr.set_line_width(2.0);
|
|
||||||
cr.set_source_rgb(0.0, 0.0, 0.0);
|
|
||||||
for link in self.links.borrow().values() {
|
|
||||||
if let Some((from_x, from_y, to_x, to_y)) = self.get_link_coordinates(link) {
|
|
||||||
cr.move_to(from_x, from_y);
|
|
||||||
cr.curve_to(from_x + 75.0, from_y, to_x - 75.0, to_y, to_x, to_y);
|
|
||||||
if let Err(e) = cr.stroke() {
|
|
||||||
warn!("Failed to draw graphview links: {}", e);
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
log::warn!("Could not get allocation of ports of link: {:?}", link);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw all children
|
// Draw all children
|
||||||
self.nodes
|
self.nodes
|
||||||
.borrow()
|
.borrow()
|
||||||
.values()
|
.values()
|
||||||
.for_each(|node| self.instance().snapshot_child(node, snapshot));
|
.for_each(|node| self.instance().snapshot_child(node, snapshot));
|
||||||
|
|
||||||
|
// Draw all links
|
||||||
|
let link_cr = snapshot
|
||||||
|
.append_cairo(&graphene::Rect::new(
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
alloc.width as f32,
|
||||||
|
alloc.height as f32,
|
||||||
|
))
|
||||||
|
.expect("Failed to get cairo context");
|
||||||
|
link_cr.set_line_width(2.0);
|
||||||
|
link_cr.set_source_rgb(0.0, 0.0, 0.0);
|
||||||
|
for (link, active) in self.links.borrow().values() {
|
||||||
|
if let Some((from_x, from_y, to_x, to_y)) = self.get_link_coordinates(link) {
|
||||||
|
link_cr.move_to(from_x, from_y);
|
||||||
|
|
||||||
|
// Use dashed line for inactive links, full line otherwise.
|
||||||
|
if *active {
|
||||||
|
link_cr.set_dash(&[], 0.0);
|
||||||
|
} else {
|
||||||
|
link_cr.set_dash(&[10.0, 5.0], 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Place curve control offset by half the x distance between the two points.
|
||||||
|
// This makes the curve scale well for varying distances between the two ports,
|
||||||
|
// especially when the output port is farther right than the input port.
|
||||||
|
let half_x_dist = f64::abs(from_x - to_x) / 2.0;
|
||||||
|
link_cr.curve_to(
|
||||||
|
from_x + half_x_dist,
|
||||||
|
from_y,
|
||||||
|
to_x - half_x_dist,
|
||||||
|
to_y,
|
||||||
|
to_x,
|
||||||
|
to_y,
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Err(e) = link_cr.stroke() {
|
||||||
|
warn!("Failed to draw graphview links: {}", e);
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
warn!("Could not get allocation of ports of link: {:?}", link);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,7 +189,7 @@ mod imp {
|
|||||||
/// Get coordinates for the drawn link to start at and to end at.
|
/// Get coordinates for the drawn link to start at and to end at.
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
/// Some((from_x, from_y, to_x, to_y)) if all objects the links refers to exist as widgets.
|
/// `Some((from_x, from_y, to_x, to_y))` if all objects the links refers to exist as widgets.
|
||||||
fn get_link_coordinates(&self, link: &crate::PipewireLink) -> Option<(f64, f64, f64, f64)> {
|
fn get_link_coordinates(&self, link: &crate::PipewireLink) -> Option<(f64, f64, f64, f64)> {
|
||||||
let nodes = self.nodes.borrow();
|
let nodes = self.nodes.borrow();
|
||||||
|
|
||||||
@@ -194,7 +224,7 @@ mod imp {
|
|||||||
tx += tnx;
|
tx += tnx;
|
||||||
ty += tny + (th / 2);
|
ty += tny + (th / 2);
|
||||||
|
|
||||||
Some((fx as f64, fy as f64, tx as f64, ty as f64))
|
Some((fx.into(), fy.into(), tx.into(), ty.into()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -215,8 +245,8 @@ impl GraphView {
|
|||||||
|
|
||||||
// Place widgets in colums of 4, growing down, then right.
|
// Place widgets in colums of 4, growing down, then right.
|
||||||
// TODO: Make a better positioning algorithm.
|
// TODO: Make a better positioning algorithm.
|
||||||
let x = (private.nodes.borrow().len() / 4) as f32 * 400.0; // This relies on integer division rounding down.
|
let x = ((private.nodes.borrow().len() / 4) as f32 * 400.0) + 20.0; // This relies on integer division rounding down.
|
||||||
let y = private.nodes.borrow().len() as f32 % 4.0 * 100.0;
|
let y = (private.nodes.borrow().len() as f32 % 4.0 * 100.0) + 20.0;
|
||||||
|
|
||||||
self.move_node(&node.clone().upcast(), x, y);
|
self.move_node(&node.clone().upcast(), x, y);
|
||||||
|
|
||||||
@@ -228,6 +258,8 @@ impl GraphView {
|
|||||||
let mut nodes = private.nodes.borrow_mut();
|
let mut nodes = private.nodes.borrow_mut();
|
||||||
if let Some(node) = nodes.remove(&id) {
|
if let Some(node) = nodes.remove(&id) {
|
||||||
node.unparent();
|
node.unparent();
|
||||||
|
} else {
|
||||||
|
warn!("Tried to remove non-existant node (id={}) from graph", id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,11 +269,9 @@ impl GraphView {
|
|||||||
if let Some(node) = private.nodes.borrow_mut().get_mut(&node_id) {
|
if let Some(node) = private.nodes.borrow_mut().get_mut(&node_id) {
|
||||||
node.add_port(port_id, port);
|
node.add_port(port_id, port);
|
||||||
} else {
|
} else {
|
||||||
// FIXME: Log this instead
|
error!(
|
||||||
log::error!(
|
|
||||||
"Node with id {} not found when trying to add port with id {} to graph",
|
"Node with id {} not found when trying to add port with id {} to graph",
|
||||||
node_id,
|
node_id, port_id
|
||||||
port_id
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -254,16 +284,22 @@ impl GraphView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a link to the graph.
|
pub fn add_link(&self, link_id: u32, link: crate::PipewireLink, active: bool) {
|
||||||
///
|
|
||||||
/// `add_link` takes three arguments: `link_id` is the id of the link as assigned by the pipewire server,
|
|
||||||
/// `from` and `to` are the id's of the ingoing and outgoing port, respectively.
|
|
||||||
pub fn add_link(&self, link_id: u32, link: crate::PipewireLink) {
|
|
||||||
let private = imp::GraphView::from_instance(self);
|
let private = imp::GraphView::from_instance(self);
|
||||||
private.links.borrow_mut().insert(link_id, link);
|
private.links.borrow_mut().insert(link_id, (link, active));
|
||||||
self.queue_draw();
|
self.queue_draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_link_state(&self, link_id: u32, active: bool) {
|
||||||
|
let private = imp::GraphView::from_instance(self);
|
||||||
|
if let Some((_, state)) = private.links.borrow_mut().get_mut(&link_id) {
|
||||||
|
*state = active;
|
||||||
|
self.queue_draw();
|
||||||
|
} else {
|
||||||
|
warn!("Link state changed on unknown link (id={})", link_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn remove_link(&self, id: u32) {
|
pub fn remove_link(&self, id: u32) {
|
||||||
let private = imp::GraphView::from_instance(self);
|
let private = imp::GraphView::from_instance(self);
|
||||||
let mut links = private.links.borrow_mut();
|
let mut links = private.links.borrow_mut();
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use gtk::{glib, prelude::*, subclass::prelude::*};
|
use gtk::{glib, prelude::*, subclass::prelude::*};
|
||||||
use pipewire::spa::Direction;
|
use pipewire::spa::Direction;
|
||||||
|
|
||||||
use std::{collections::HashMap, rc::Rc};
|
use std::collections::HashMap;
|
||||||
|
|
||||||
mod imp {
|
mod imp {
|
||||||
use super::*;
|
use super::*;
|
||||||
@@ -11,9 +11,9 @@ mod imp {
|
|||||||
pub struct Node {
|
pub struct Node {
|
||||||
pub(super) grid: gtk::Grid,
|
pub(super) grid: gtk::Grid,
|
||||||
pub(super) label: gtk::Label,
|
pub(super) label: gtk::Label,
|
||||||
pub(super) ports: RefCell<HashMap<u32, Rc<crate::view::port::Port>>>,
|
pub(super) ports: RefCell<HashMap<u32, crate::view::port::Port>>,
|
||||||
pub(super) num_ports_in: Cell<u32>,
|
pub(super) num_ports_in: Cell<i32>,
|
||||||
pub(super) num_ports_out: Cell<u32>,
|
pub(super) num_ports_out: Cell<i32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[glib::object_subclass]
|
#[glib::object_subclass]
|
||||||
@@ -81,21 +81,21 @@ impl Node {
|
|||||||
Direction::Input => {
|
Direction::Input => {
|
||||||
private
|
private
|
||||||
.grid
|
.grid
|
||||||
.attach(&port, 0, private.num_ports_in.get() as i32 + 1, 1, 1);
|
.attach(&port, 0, private.num_ports_in.get() + 1, 1, 1);
|
||||||
private.num_ports_in.set(private.num_ports_in.get() + 1);
|
private.num_ports_in.set(private.num_ports_in.get() + 1);
|
||||||
}
|
}
|
||||||
Direction::Output => {
|
Direction::Output => {
|
||||||
private
|
private
|
||||||
.grid
|
.grid
|
||||||
.attach(&port, 1, private.num_ports_out.get() as i32 + 1, 1, 1);
|
.attach(&port, 1, private.num_ports_out.get() + 1, 1, 1);
|
||||||
private.num_ports_out.set(private.num_ports_out.get() + 1);
|
private.num_ports_out.set(private.num_ports_out.get() + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private.ports.borrow_mut().insert(id, Rc::new(port));
|
private.ports.borrow_mut().insert(id, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_port(&self, id: u32) -> Option<Rc<super::port::Port>> {
|
pub fn get_port(&self, id: u32) -> Option<super::port::Port> {
|
||||||
let private = imp::Node::from_instance(self);
|
let private = imp::Node::from_instance(self);
|
||||||
private.ports.borrow_mut().get(&id).cloned()
|
private.ports.borrow_mut().get(&id).cloned()
|
||||||
}
|
}
|
||||||
|
|||||||
138
src/view/port.rs
138
src/view/port.rs
@@ -1,14 +1,26 @@
|
|||||||
use gtk::{
|
use gtk::{
|
||||||
gdk,
|
gdk,
|
||||||
glib::{self, subclass::Signal},
|
glib::{self, clone, subclass::Signal},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
subclass::prelude::*,
|
subclass::prelude::*,
|
||||||
};
|
};
|
||||||
use log::warn;
|
use log::{trace, warn};
|
||||||
use pipewire::spa::Direction;
|
use pipewire::spa::Direction;
|
||||||
|
|
||||||
use crate::MediaType;
|
use crate::MediaType;
|
||||||
|
|
||||||
|
/// A helper struct for linking a output port to an input port.
|
||||||
|
/// It carries the output ports id.
|
||||||
|
#[derive(Clone, Debug, glib::GBoxed)]
|
||||||
|
#[gboxed(type_name = "HelvumForwardLink")]
|
||||||
|
struct ForwardLink(u32);
|
||||||
|
|
||||||
|
/// A helper struct for linking an input to an output port.
|
||||||
|
/// It carries the input ports id.
|
||||||
|
#[derive(Clone, Debug, glib::GBoxed)]
|
||||||
|
#[gboxed(type_name = "HelvumReversedLink")]
|
||||||
|
struct ReversedLink(u32);
|
||||||
|
|
||||||
mod imp {
|
mod imp {
|
||||||
use once_cell::{sync::Lazy, unsync::OnceCell};
|
use once_cell::{sync::Lazy, unsync::OnceCell};
|
||||||
use pipewire::spa::Direction;
|
use pipewire::spa::Direction;
|
||||||
@@ -18,6 +30,7 @@ mod imp {
|
|||||||
/// Graphical representation of a pipewire port.
|
/// Graphical representation of a pipewire port.
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Port {
|
pub struct Port {
|
||||||
|
pub(super) label: OnceCell<gtk::Label>,
|
||||||
pub(super) id: OnceCell<u32>,
|
pub(super) id: OnceCell<u32>,
|
||||||
pub(super) direction: OnceCell<Direction>,
|
pub(super) direction: OnceCell<Direction>,
|
||||||
}
|
}
|
||||||
@@ -26,10 +39,23 @@ mod imp {
|
|||||||
impl ObjectSubclass for Port {
|
impl ObjectSubclass for Port {
|
||||||
const NAME: &'static str = "Port";
|
const NAME: &'static str = "Port";
|
||||||
type Type = super::Port;
|
type Type = super::Port;
|
||||||
type ParentType = gtk::Button;
|
type ParentType = gtk::Widget;
|
||||||
|
|
||||||
|
fn class_init(klass: &mut Self::Class) {
|
||||||
|
klass.set_layout_manager_type::<gtk::BinLayout>();
|
||||||
|
|
||||||
|
// Make it look like a GTK button.
|
||||||
|
klass.set_css_name("button");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ObjectImpl for Port {
|
impl ObjectImpl for Port {
|
||||||
|
fn dispose(&self, _obj: &Self::Type) {
|
||||||
|
if let Some(label) = self.label.get() {
|
||||||
|
label.unparent()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn signals() -> &'static [Signal] {
|
fn signals() -> &'static [Signal] {
|
||||||
static SIGNALS: Lazy<Vec<Signal>> = Lazy::new(|| {
|
static SIGNALS: Lazy<Vec<Signal>> = Lazy::new(|| {
|
||||||
vec![Signal::builder(
|
vec![Signal::builder(
|
||||||
@@ -46,18 +72,18 @@ mod imp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl WidgetImpl for Port {}
|
impl WidgetImpl for Port {}
|
||||||
impl ButtonImpl for Port {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glib::wrapper! {
|
glib::wrapper! {
|
||||||
pub struct Port(ObjectSubclass<imp::Port>)
|
pub struct Port(ObjectSubclass<imp::Port>)
|
||||||
@extends gtk::Button, gtk::Widget;
|
@extends gtk::Widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Port {
|
impl Port {
|
||||||
pub fn new(id: u32, name: &str, direction: Direction, media_type: Option<MediaType>) -> Self {
|
pub fn new(id: u32, name: &str, direction: Direction, media_type: Option<MediaType>) -> Self {
|
||||||
// Create the widget and initialize needed fields
|
// Create the widget and initialize needed fields
|
||||||
let res: Self = glib::Object::new(&[]).expect("Failed to create Port");
|
let res: Self = glib::Object::new(&[]).expect("Failed to create Port");
|
||||||
|
|
||||||
let private = imp::Port::from_instance(&res);
|
let private = imp::Port::from_instance(&res);
|
||||||
private.id.set(id).expect("Port id already set");
|
private.id.set(id).expect("Port id already set");
|
||||||
private
|
private
|
||||||
@@ -65,47 +91,85 @@ impl Port {
|
|||||||
.set(direction)
|
.set(direction)
|
||||||
.expect("Port direction already set");
|
.expect("Port direction already set");
|
||||||
|
|
||||||
res.set_child(Some(>k::Label::new(Some(name))));
|
let label = gtk::Label::new(Some(name));
|
||||||
|
label.set_parent(&res);
|
||||||
|
private
|
||||||
|
.label
|
||||||
|
.set(label)
|
||||||
|
.expect("Port label was already set");
|
||||||
|
|
||||||
// Add either a drag source or drop target controller depending on direction,
|
// Add a drag source and drop target controller with the type depending on direction,
|
||||||
// they will be responsible for link creation by dragging an output port onto an input port.
|
// they will be responsible for link creation by dragging an output port onto an input port or the other way around.
|
||||||
//
|
|
||||||
// FIXME: The type used for dragging is simply a u32.
|
// FIXME: We should protect against different media types, e.g. it should not be possible to drop a video port on an audio port.
|
||||||
// This means that anything that provides a u32 could be dragged onto a input port,
|
|
||||||
// leading to that port trying to create a link to an invalid output port.
|
// The port will simply provide its pipewire id to the drag target.
|
||||||
// We should use a newtype instead of a plain u32.
|
let drag_src = gtk::DragSourceBuilder::new()
|
||||||
// Additionally, this does not protect against e.g. dropping an outgoing audio port on an ingoing video port.
|
.content(&gdk::ContentProvider::for_value(&match direction {
|
||||||
|
Direction::Input => ReversedLink(id).to_value(),
|
||||||
|
Direction::Output => ForwardLink(id).to_value(),
|
||||||
|
}))
|
||||||
|
.build();
|
||||||
|
drag_src.connect_drag_begin(move |_, _| {
|
||||||
|
trace!("Drag started from port {}", id);
|
||||||
|
});
|
||||||
|
drag_src.connect_drag_cancel(move |_, _, _| {
|
||||||
|
trace!("Drag from port {} was cancelled", id);
|
||||||
|
false
|
||||||
|
});
|
||||||
|
res.add_controller(&drag_src);
|
||||||
|
|
||||||
|
// The drop target will accept either a `ForwardLink` or `ReversedLink` depending in its own direction,
|
||||||
|
// and use it to emit its `port-toggled` signal.
|
||||||
|
let drop_target = gtk::DropTarget::new(
|
||||||
|
match direction {
|
||||||
|
Direction::Input => ForwardLink::static_type(),
|
||||||
|
Direction::Output => ReversedLink::static_type(),
|
||||||
|
},
|
||||||
|
gdk::DragAction::COPY,
|
||||||
|
);
|
||||||
match direction {
|
match direction {
|
||||||
Direction::Input => {
|
Direction::Input => {
|
||||||
let drop_target = gtk::DropTarget::new(u32::static_type(), gdk::DragAction::COPY);
|
drop_target.connect_drop(
|
||||||
let this = res.clone();
|
clone!(@weak res as this => @default-panic, move |drop_target, val, _, _| {
|
||||||
drop_target.connect_drop(move |drop_target, val, _, _| {
|
if let Ok(ForwardLink(source_id)) = val.get::<ForwardLink>() {
|
||||||
if let Ok(source_id) = val.get::<u32>() {
|
// Get the callback registered in the widget and call it
|
||||||
// Get the callback registered in the widget and call it
|
drop_target
|
||||||
drop_target
|
.widget()
|
||||||
.widget()
|
.expect("Drop target has no widget")
|
||||||
.expect("Drop target has no widget")
|
.emit_by_name("port-toggled", &[&source_id, &this.id()])
|
||||||
.emit_by_name("port-toggled", &[&source_id, &this.id()])
|
.expect("Failed to send signal");
|
||||||
.expect("Failed to send signal");
|
} else {
|
||||||
} else {
|
warn!("Invalid type dropped on ingoing port");
|
||||||
warn!("Invalid type dropped on ingoing port");
|
}
|
||||||
}
|
|
||||||
|
|
||||||
true
|
true
|
||||||
});
|
}),
|
||||||
res.add_controller(&drop_target);
|
);
|
||||||
}
|
}
|
||||||
Direction::Output => {
|
Direction::Output => {
|
||||||
// The port will simply provide its pipewire id to the drag target.
|
drop_target.connect_drop(
|
||||||
let drag_src = gtk::DragSourceBuilder::new()
|
clone!(@weak res as this => @default-panic, move |drop_target, val, _, _| {
|
||||||
.content(&gdk::ContentProvider::for_value(&(id.to_value())))
|
if let Ok(ReversedLink(target_id)) = val.get::<ReversedLink>() {
|
||||||
.build();
|
// Get the callback registered in the widget and call it
|
||||||
res.add_controller(&drag_src);
|
drop_target
|
||||||
|
.widget()
|
||||||
|
.expect("Drop target has no widget")
|
||||||
|
.emit_by_name("port-toggled", &[&this.id(), &target_id])
|
||||||
|
.expect("Failed to send signal");
|
||||||
|
} else {
|
||||||
|
warn!("Invalid type dropped on outgoing port");
|
||||||
|
}
|
||||||
|
|
||||||
// Display a grab cursor when the mouse is over the port so the user knows it can be dragged to another port.
|
true
|
||||||
res.set_cursor(gtk::gdk::Cursor::from_name("grab", None).as_ref());
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
res.add_controller(&drop_target);
|
||||||
|
|
||||||
|
// Display a grab cursor when the mouse is over the port so the user knows it can be dragged to another port.
|
||||||
|
res.set_cursor(gtk::gdk::Cursor::from_name("grab", None).as_ref());
|
||||||
|
|
||||||
// Color the port according to its media type.
|
// Color the port according to its media type.
|
||||||
match media_type {
|
match media_type {
|
||||||
|
|||||||
Reference in New Issue
Block a user