diff --git a/Cargo.lock b/Cargo.lock
index 3f9fbea..1625420 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -141,8 +141,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7d78656ba01f1b93024b7c3a0467f1608e4be67d725749fdcd7d2c7678fd7a2"
dependencies = [
"proc-macro2",
- "quote",
- "syn",
+ "quote 1.0.21",
+ "syn 1.0.105",
]
[[package]]
@@ -158,8 +158,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31e6e93155431f3931513b243d371981bb2770112b370c82745a1d19d2f99364"
dependencies = [
"proc-macro2",
- "quote",
- "syn",
+ "quote 1.0.21",
+ "syn 1.0.105",
]
[[package]]
@@ -456,9 +456,9 @@ dependencies = [
"codespan-reporting",
"once_cell",
"proc-macro2",
- "quote",
+ "quote 1.0.21",
"scratch",
- "syn",
+ "syn 1.0.105",
]
[[package]]
@@ -474,8 +474,54 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1362b0ddcfc4eb0a1f57b68bd77dd99f0e826958a96abd0ae9bd092e114ffed6"
dependencies = [
"proc-macro2",
- "quote",
- "syn",
+ "quote 1.0.21",
+ "syn 1.0.105",
+]
+
+[[package]]
+name = "darling"
+version = "0.13.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c"
+dependencies = [
+ "darling_core",
+ "darling_macro",
+]
+
+[[package]]
+name = "darling_core"
+version = "0.13.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610"
+dependencies = [
+ "fnv",
+ "ident_case",
+ "proc-macro2",
+ "quote 1.0.21",
+ "strsim",
+ "syn 1.0.105",
+]
+
+[[package]]
+name = "darling_macro"
+version = "0.13.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835"
+dependencies = [
+ "darling_core",
+ "quote 1.0.21",
+ "syn 1.0.105",
+]
+
+[[package]]
+name = "dbus"
+version = "0.9.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6f8bcdd56d2e5c4ed26a529c5a9029f5db8290d433497506f958eae3be148eb6"
+dependencies = [
+ "libc",
+ "libdbus-sys",
+ "winapi",
]
[[package]]
@@ -485,8 +531,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
dependencies = [
"proc-macro2",
- "quote",
- "syn",
+ "quote 1.0.21",
+ "syn 1.0.105",
+]
+
+[[package]]
+name = "derive_is_enum_variant"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d0ac8859845146979953797f03cc5b282fb4396891807cdb3d04929a88418197"
+dependencies = [
+ "heck 0.3.3",
+ "quote 0.3.15",
+ "syn 0.11.11",
]
[[package]]
@@ -540,6 +597,17 @@ version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
+[[package]]
+name = "enum-kinds"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4e40a16955681d469ab3da85aaa6b42ff656b3c67b52e1d8d3dd36afe97fd462"
+dependencies = [
+ "proc-macro2",
+ "quote 1.0.21",
+ "syn 1.0.105",
+]
+
[[package]]
name = "enumflags2"
version = "0.7.5"
@@ -557,8 +625,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f58dc3c5e468259f19f2d46304a6b28f1c3d034442e14b322d2b850e36f6d5ae"
dependencies = [
"proc-macro2",
- "quote",
- "syn",
+ "quote 1.0.21",
+ "syn 1.0.105",
]
[[package]]
@@ -608,6 +676,33 @@ dependencies = [
"windows-sys",
]
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
+name = "from_variants"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7cf36180ca6f3c021e91b194e16b670ef5cbdd0cea48354ff6f5f83e3c2d1629"
+dependencies = [
+ "from_variants_impl",
+]
+
+[[package]]
+name = "from_variants_impl"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "13abfd95d43eabb051a8d4b408ef92dfe6d8d4aa17651e5786d5c761e5e6e7ad"
+dependencies = [
+ "darling",
+ "proc-macro2",
+ "quote 1.0.21",
+ "syn 1.0.105",
+]
+
[[package]]
name = "futures-channel"
version = "0.3.25"
@@ -662,8 +757,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d"
dependencies = [
"proc-macro2",
- "quote",
- "syn",
+ "quote 1.0.21",
+ "syn 1.0.105",
]
[[package]]
@@ -841,12 +936,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e084807350b01348b6d9dbabb724d1a0bb987f47a2c85de200e98e12e30733bf"
dependencies = [
"anyhow",
- "heck",
+ "heck 0.4.0",
"proc-macro-crate",
"proc-macro-error",
"proc-macro2",
- "quote",
- "syn",
+ "quote 1.0.21",
+ "syn 1.0.105",
]
[[package]]
@@ -949,8 +1044,8 @@ dependencies = [
"proc-macro-crate",
"proc-macro-error",
"proc-macro2",
- "quote",
- "syn",
+ "quote 1.0.21",
+ "syn 1.0.105",
]
[[package]]
@@ -959,6 +1054,15 @@ version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+[[package]]
+name = "heck"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
+dependencies = [
+ "unicode-segmentation",
+]
+
[[package]]
name = "heck"
version = "0.4.0"
@@ -1004,6 +1108,12 @@ dependencies = [
"cxx-build",
]
+[[package]]
+name = "ident_case"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
+
[[package]]
name = "indenter"
version = "0.3.3"
@@ -1065,6 +1175,7 @@ dependencies = [
"lazy_static",
"libcorn",
"mpd_client",
+ "mpris",
"notify",
"regex",
"serde",
@@ -1146,6 +1257,15 @@ dependencies = [
"toml",
]
+[[package]]
+name = "libdbus-sys"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c185b5b7ad900923ef3a8ff594083d4d9b5aea80bb4f32b8342363138c0d456b"
+dependencies = [
+ "pkg-config",
+]
+
[[package]]
name = "libloading"
version = "0.7.4"
@@ -1278,6 +1398,19 @@ dependencies = [
"tracing",
]
+[[package]]
+name = "mpris"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e3d377fd27d9d5c7145341cd3affcb83839c24c73e7460488b3ae0a3f9c5166"
+dependencies = [
+ "dbus",
+ "derive_is_enum_variant",
+ "enum-kinds",
+ "from_variants",
+ "thiserror",
+]
+
[[package]]
name = "nix"
version = "0.23.2"
@@ -1511,8 +1644,8 @@ dependencies = [
"pest",
"pest_meta",
"proc-macro2",
- "quote",
- "syn",
+ "quote 1.0.21",
+ "syn 1.0.105",
]
[[package]]
@@ -1583,8 +1716,8 @@ checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
"proc-macro-error-attr",
"proc-macro2",
- "quote",
- "syn",
+ "quote 1.0.21",
+ "syn 1.0.105",
"version_check",
]
@@ -1595,7 +1728,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
"proc-macro2",
- "quote",
+ "quote 1.0.21",
"version_check",
]
@@ -1608,6 +1741,12 @@ dependencies = [
"unicode-ident",
]
+[[package]]
+name = "quote"
+version = "0.3.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
+
[[package]]
name = "quote"
version = "1.0.21"
@@ -1800,8 +1939,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4eae9b04cbffdfd550eb462ed33bc6a1b68c935127d008b27444d08380f94e4"
dependencies = [
"proc-macro2",
- "quote",
- "syn",
+ "quote 1.0.21",
+ "syn 1.0.105",
]
[[package]]
@@ -1822,8 +1961,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fe39d9fbb0ebf5eb2c7cb7e2a47e4f462fad1379f1166b8ae49ad9eae89a7ca"
dependencies = [
"proc-macro2",
- "quote",
- "syn",
+ "quote 1.0.21",
+ "syn 1.0.105",
]
[[package]]
@@ -1969,6 +2108,12 @@ dependencies = [
"vte",
]
+[[package]]
+name = "strsim"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
+
[[package]]
name = "swayipc-async"
version = "2.0.1"
@@ -1994,6 +2139,17 @@ dependencies = [
"thiserror",
]
+[[package]]
+name = "syn"
+version = "0.11.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
+dependencies = [
+ "quote 0.3.15",
+ "synom",
+ "unicode-xid",
+]
+
[[package]]
name = "syn"
version = "1.0.105"
@@ -2001,10 +2157,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908"
dependencies = [
"proc-macro2",
- "quote",
+ "quote 1.0.21",
"unicode-ident",
]
+[[package]]
+name = "synom"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
+dependencies = [
+ "unicode-xid",
+]
+
[[package]]
name = "sysinfo"
version = "0.27.0"
@@ -2027,7 +2192,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2955b1fe31e1fa2fbd1976b71cc69a606d7d4da16f6de3333d0c92d51419aeff"
dependencies = [
"cfg-expr",
- "heck",
+ "heck 0.4.0",
"pkg-config",
"toml",
"version-compare",
@@ -2072,8 +2237,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb"
dependencies = [
"proc-macro2",
- "quote",
- "syn",
+ "quote 1.0.21",
+ "syn 1.0.105",
]
[[package]]
@@ -2149,8 +2314,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8"
dependencies = [
"proc-macro2",
- "quote",
- "syn",
+ "quote 1.0.21",
+ "syn 1.0.105",
]
[[package]]
@@ -2203,8 +2368,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a"
dependencies = [
"proc-macro2",
- "quote",
- "syn",
+ "quote 1.0.21",
+ "syn 1.0.105",
]
[[package]]
@@ -2284,12 +2449,24 @@ version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
+[[package]]
+name = "unicode-segmentation"
+version = "1.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a"
+
[[package]]
name = "unicode-width"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
+[[package]]
+name = "unicode-xid"
+version = "0.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
+
[[package]]
name = "unsafe-libyaml"
version = "0.2.4"
@@ -2344,7 +2521,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d257817081c7dffcdbab24b9e62d2def62e2ff7d00b1c20062551e6cccc145ff"
dependencies = [
"proc-macro2",
- "quote",
+ "quote 1.0.21",
]
[[package]]
@@ -2396,8 +2573,8 @@ dependencies = [
"log",
"once_cell",
"proc-macro2",
- "quote",
- "syn",
+ "quote 1.0.21",
+ "syn 1.0.105",
"wasm-bindgen-shared",
]
@@ -2407,7 +2584,7 @@ version = "0.2.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
dependencies = [
- "quote",
+ "quote 1.0.21",
"wasm-bindgen-macro-support",
]
@@ -2418,8 +2595,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
dependencies = [
"proc-macro2",
- "quote",
- "syn",
+ "quote 1.0.21",
+ "syn 1.0.105",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@@ -2487,7 +2664,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f4303d8fa22ab852f789e75a967f0a2cdc430a607751c0499bada3e451cbd53"
dependencies = [
"proc-macro2",
- "quote",
+ "quote 1.0.21",
"xml-rs",
]
@@ -2660,9 +2837,9 @@ checksum = "1f8fb5186d1c87ae88cf234974c240671238b4a679158ad3b94ec465237349a6"
dependencies = [
"proc-macro-crate",
"proc-macro2",
- "quote",
+ "quote 1.0.21",
"regex",
- "syn",
+ "syn 1.0.105",
]
[[package]]
@@ -2698,6 +2875,6 @@ checksum = "155247a5d1ab55e335421c104ccd95d64f17cebbd02f50cdbc1c33385f9c4d81"
dependencies = [
"proc-macro-crate",
"proc-macro2",
- "quote",
- "syn",
+ "quote 1.0.21",
+ "syn 1.0.105",
]
diff --git a/Cargo.toml b/Cargo.toml
index 89361cf..8be0b1e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -32,8 +32,9 @@ dirs = "4.0.0"
walkdir = "2.3.2"
notify = { version = "5.0.0", default-features = false }
mpd_client = "1.0.0"
+mpris = "2.0.0"
swayipc-async = { version = "2.0.1" }
sysinfo = "0.27.0"
wayland-client = "0.29.5"
wayland-protocols = { version = "0.29.5", features = ["unstable_protocols", "client"] }
-smithay-client-toolkit = { version = "0.16.0", default-features = false, features = ["calloop"] }
\ No newline at end of file
+smithay-client-toolkit = { version = "0.16.0", default-features = false, features = ["calloop"] }
diff --git a/docs/_Sidebar.md b/docs/_Sidebar.md
index 33b5791..32641df 100644
--- a/docs/_Sidebar.md
+++ b/docs/_Sidebar.md
@@ -19,7 +19,7 @@
- [Custom](custom)
- [Focused](focused)
- [Launcher](launcher)
-- [MPD](mpd)
+- [Music](music)
- [Script](script)
- [Sys_Info](sys-info)
- [Tray](tray)
diff --git a/docs/modules/MPD.md b/docs/modules/MPD.md
deleted file mode 100644
index 0cfd8b6..0000000
--- a/docs/modules/MPD.md
+++ /dev/null
@@ -1,131 +0,0 @@
-Displays currently playing song from MPD.
-Clicking on the widget opens a popout displaying info about the current song, album art
-and playback controls.
-
-
-
-## Configuration
-
-> Type: `mpd`
-
-| | Type | Default | Description |
-|----------------|----------|-----------------------------|-----------------------------------------------------------------------|
-| `host` | `string` | `localhost:6600` | TCP or Unix socket for the MPD server. |
-| `format` | `string` | `{icon} {title} / {artist}` | Format string for the widget. More info below. |
-| `icons.play` | `string` | `` | Icon to show when playing. |
-| `icons.pause` | `string` | `` | Icon to show when paused. |
-| `icons.volume` | `string` | `墳` | Icon to show under popup volume slider. |
-| `music_dir` | `string` | `$HOME/Music` | Path to MPD server's music directory on disc. Required for album art. |
-
-
-JSON
-
-```json
-{
- "start": [
- {
- "type": "mpd",
- "format": "{icon} {title} / {artist}",
- "icons": {
- "play": "",
- "pause": ""
- },
- "music_dir": "/home/jake/Music"
- }
- ]
-}
-```
-
-
-
-
-TOML
-
-```toml
-[[start]]
-type = "mpd"
-format = "{icon} {title} / {artist}"
-music_dir = "/home/jake/Music"
-
-[[start.icons]]
-play = ""
-pause = ""
-```
-
-
-
-
-YAML
-
-```yaml
-start:
- - type: "mpd"
- format: "{icon} {title} / {artist}"
- icons:
- play: ""
- pause: ""
- music_dir: "/home/jake/Music"
-```
-
-
-
-
-Corn
-
-```corn
-{
- start = [
- {
- type = "mpd"
- format = "{icon} {title} / {artist}"
- icons.play = ""
- icons.pause = ""
- music_dir = "/home/jake/Music"
- }
- ]
-}
-```
-
-
-
-### Formatting Tokens
-
-The following tokens can be used in the `format` config option,
-and will be replaced with values from the currently playing track:
-
-| Token | Description |
-|--------------|--------------------------------------|
-| `{icon}` | Either `icons.play` or `icons.pause` |
-| `{title}` | Title |
-| `{album}` | Album name |
-| `{artist}` | Artist name |
-| `{date}` | Release date |
-| `{track}` | Track number |
-| `{disc}` | Disc number |
-| `{genre}` | Genre |
-| `{duration}` | Duration in `mm:ss` |
-| `{elapsed}` | Time elapsed in `mm:ss` |
-
-## Styling
-
-| Selector | Description |
-|----------------------------------------|------------------------------------------|
-| `#mpd` | Tray widget button |
-| `#popup-mpd` | Popup box |
-| `#popup-mpd #album-art` | Album art image inside popup box |
-| `#popup-mpd #title` | Track title container inside popup box |
-| `#popup-mpd #title .icon` | Track title icon label inside popup box |
-| `#popup-mpd #title .label` | Track title label inside popup box |
-| `#popup-mpd #album` | Track album container inside popup box |
-| `#popup-mpd #album .icon` | Track album icon label inside popup box |
-| `#popup-mpd #album .label` | Track album label inside popup box |
-| `#popup-mpd #artist` | Track artist container inside popup box |
-| `#popup-mpd #artist .icon` | Track artist icon label inside popup box |
-| `#popup-mpd #artist .label` | Track artist label inside popup box |
-| `#popup-mpd #controls` | Controls container inside popup box |
-| `#popup-mpd #controls #btn-prev` | Previous button inside popup box |
-| `#popup-mpd #controls #btn-play-pause` | Play/pause button inside popup box |
-| `#popup-mpd #controls #btn-next` | Next button inside popup box |
-| `#popup-mpd #volume` | Volume container inside popup box |
-| `#popup-mpd #volume #slider` | Volume slider popup box |
-| `#popup-mpd #volume .icon` | Volume icon label inside popup box |
\ No newline at end of file
diff --git a/docs/modules/Music.md b/docs/modules/Music.md
new file mode 100644
index 0000000..51fbbff
--- /dev/null
+++ b/docs/modules/Music.md
@@ -0,0 +1,139 @@
+Displays currently playing song from your music player.
+This module supports both MPRIS players and MPD servers.
+Clicking on the widget opens a popout displaying info about the current song, album art
+and playback controls.
+
+in MPRIS mode, the widget will listen to all players and automatically detect/display the active one.
+
+
+
+## Configuration
+
+> Type: `music`
+
+| | Type | Default | Description |
+|----------------|------------------|-----------------------------|----------------------------------------------------------------------------------|
+| `player_type` | `mpris` or `mpd` | `mpris` | Whether to connect to MPRIS players or an MPD server. |
+| `format` | `string` | `{icon} {title} / {artist}` | Format string for the widget. More info below. |
+| `icons.play` | `string` | `` | Icon to show when playing. |
+| `icons.pause` | `string` | `` | Icon to show when paused. |
+| `icons.volume` | `string` | `墳` | Icon to show under popup volume slider. |
+| `host` | `string` | `localhost:6600` | [MPD Only] TCP or Unix socket for the MPD server. |
+| `music_dir` | `string` | `$HOME/Music` | [MPD Only] Path to MPD server's music directory on disc. Required for album art. |
+
+
+JSON
+
+```json
+{
+ "start": [
+ {
+ "type": "music",
+ "player_type": "mpd",
+ "format": "{icon} {title} / {artist}",
+ "icons": {
+ "play": "",
+ "pause": ""
+ },
+ "music_dir": "/home/jake/Music"
+ }
+ ]
+}
+```
+
+
+
+
+TOML
+
+```toml
+[[start]]
+type = "music"
+player_type = "mpd"
+format = "{icon} {title} / {artist}"
+music_dir = "/home/jake/Music"
+
+[[start.icons]]
+play = ""
+pause = ""
+```
+
+
+
+
+YAML
+
+```yaml
+start:
+ - type: "music"
+ player_type: "mpd"
+ format: "{icon} {title} / {artist}"
+ icons:
+ play: ""
+ pause: ""
+ music_dir: "/home/jake/Music"
+```
+
+
+
+
+Corn
+
+```corn
+{
+ start = [
+ {
+ type = "music"
+ player_type = "mpd"
+ format = "{icon} {title} / {artist}"
+ icons.play = ""
+ icons.pause = ""
+ music_dir = "/home/jake/Music"
+ }
+ ]
+}
+```
+
+
+
+### Formatting Tokens
+
+The following tokens can be used in the `format` config option,
+and will be replaced with values from the currently playing track:
+
+| Token | Description |
+|--------------|--------------------------------------|
+| `{icon}` | Either `icons.play` or `icons.pause` |
+| `{title}` | Title |
+| `{album}` | Album name |
+| `{artist}` | Artist name |
+| `{date}` | Release date |
+| `{track}` | Track number |
+| `{disc}` | Disc number |
+| `{genre}` | Genre |
+| `{duration}` | Duration in `mm:ss` |
+| `{elapsed}` | Time elapsed in `mm:ss` |
+
+## Styling
+
+| Selector | Description |
+|------------------------------------------|------------------------------------------|
+| `#music` | Tray widget button |
+| `#popup-music` | Popup box |
+| `#popup-music #album-art` | Album art image inside popup box |
+| `#popup-music #title` | Track title container inside popup box |
+| `#popup-music #title .icon` | Track title icon label inside popup box |
+| `#popup-music #title .label` | Track title label inside popup box |
+| `#popup-music #album` | Track album container inside popup box |
+| `#popup-music #album .icon` | Track album icon label inside popup box |
+| `#popup-music #album .label` | Track album label inside popup box |
+| `#popup-music #artist` | Track artist container inside popup box |
+| `#popup-music #artist .icon` | Track artist icon label inside popup box |
+| `#popup-music #artist .label` | Track artist label inside popup box |
+| `#popup-music #controls` | Controls container inside popup box |
+| `#popup-music #controls #btn-prev` | Previous button inside popup box |
+| `#popup-music #controls #btn-play-pause` | Play/pause button inside popup box |
+| `#popup-music #controls #btn-next` | Next button inside popup box |
+| `#popup-music #volume` | Volume container inside popup box |
+| `#popup-music #volume #slider` | Volume slider popup box |
+| `#popup-music #volume .icon` | Volume icon label inside popup box |
\ No newline at end of file
diff --git a/src/bar.rs b/src/bar.rs
index ce7d83d..c5db9a6 100644
--- a/src/bar.rs
+++ b/src/bar.rs
@@ -195,7 +195,7 @@ fn add_modules(content: >k::Box, modules: Vec, info: &ModuleInfo
ModuleConfig::Focused(mut module) => add_module!(module, id),
ModuleConfig::Workspaces(mut module) => add_module!(module, id),
ModuleConfig::Tray(mut module) => add_module!(module, id),
- ModuleConfig::Mpd(mut module) => add_module!(module, id),
+ ModuleConfig::Music(mut module) => add_module!(module, id),
ModuleConfig::Launcher(mut module) => add_module!(module, id),
ModuleConfig::Custom(mut module) => add_module!(module, id),
}
diff --git a/src/clients/mod.rs b/src/clients/mod.rs
index ea192bd..3fbfac8 100644
--- a/src/clients/mod.rs
+++ b/src/clients/mod.rs
@@ -1,4 +1,4 @@
-pub mod mpd;
+pub mod music;
pub mod sway;
pub mod system_tray;
pub mod wayland;
diff --git a/src/clients/mpd.rs b/src/clients/mpd.rs
deleted file mode 100644
index 852750f..0000000
--- a/src/clients/mpd.rs
+++ /dev/null
@@ -1,167 +0,0 @@
-use lazy_static::lazy_static;
-use mpd_client::client::{CommandError, Connection, ConnectionEvent, Subsystem};
-use mpd_client::commands::Command;
-use mpd_client::protocol::MpdProtocolError;
-use mpd_client::responses::Status;
-use mpd_client::Client;
-use std::collections::HashMap;
-use std::fmt::{Display, Formatter};
-use std::os::unix::fs::FileTypeExt;
-use std::path::PathBuf;
-use std::sync::Arc;
-use std::time::Duration;
-use tokio::net::{TcpStream, UnixStream};
-use tokio::spawn;
-use tokio::sync::broadcast::{channel, error::SendError, Receiver, Sender};
-use tokio::sync::Mutex;
-use tokio::time::sleep;
-use tracing::debug;
-
-lazy_static! {
- static ref CONNECTIONS: Arc>>> =
- Arc::new(Mutex::new(HashMap::new()));
-}
-
-pub struct MpdClient {
- client: Client,
- tx: Sender<()>,
- _rx: Receiver<()>,
-}
-
-#[derive(Debug)]
-pub enum MpdConnectionError {
- MaxRetries,
- ProtocolError(MpdProtocolError),
-}
-
-impl Display for MpdConnectionError {
- fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
- match self {
- Self::MaxRetries => write!(f, "Reached max retries"),
- Self::ProtocolError(e) => write!(f, "{:?}", e),
- }
- }
-}
-
-impl std::error::Error for MpdConnectionError {}
-
-impl MpdClient {
- async fn new(host: &str) -> Result {
- debug!("Creating new MPD connection to {}", host);
-
- let (client, mut state_changes) =
- wait_for_connection(host, Duration::from_secs(5), None).await?;
-
- let (tx, rx) = channel(16);
- let tx2 = tx.clone();
-
- spawn(async move {
- while let Some(change) = state_changes.next().await {
- debug!("Received state change: {:?}", change);
-
- if let ConnectionEvent::SubsystemChange(
- Subsystem::Player | Subsystem::Queue | Subsystem::Mixer,
- ) = change
- {
- tx2.send(())?;
- }
- }
-
- Ok::<(), SendError<()>>(())
- });
-
- Ok(Self {
- client,
- tx,
- _rx: rx,
- })
- }
-
- pub fn subscribe(&self) -> Receiver<()> {
- self.tx.subscribe()
- }
-
- pub async fn command(&self, command: C) -> Result {
- self.client.command(command).await
- }
-}
-
-pub async fn get_client(host: &str) -> Result, MpdConnectionError> {
- let mut connections = CONNECTIONS.lock().await;
- match connections.get(host) {
- None => {
- let client = MpdClient::new(host).await?;
- let client = Arc::new(client);
- connections.insert(host.to_string(), Arc::clone(&client));
- Ok(client)
- }
- Some(client) => Ok(Arc::clone(client)),
- }
-}
-
-async fn wait_for_connection(
- host: &str,
- interval: Duration,
- max_retries: Option,
-) -> Result {
- let mut retries = 0;
- let max_retries = max_retries.unwrap_or(usize::MAX);
-
- loop {
- if retries == max_retries {
- break Err(MpdConnectionError::MaxRetries);
- }
-
- retries += 1;
-
- match try_get_mpd_conn(host).await {
- Ok(conn) => break Ok(conn),
- Err(err) => {
- if retries == max_retries {
- break Err(MpdConnectionError::ProtocolError(err));
- }
- }
- }
-
- sleep(interval).await;
- }
-}
-
-/// Cycles through each MPD host and
-/// returns the first one which connects,
-/// or none if there are none
-async fn try_get_mpd_conn(host: &str) -> Result {
- if is_unix_socket(host) {
- connect_unix(host).await
- } else {
- connect_tcp(host).await
- }
-}
-
-fn is_unix_socket(host: &str) -> bool {
- let path = PathBuf::from(host);
- path.exists()
- && path
- .metadata()
- .map_or(false, |metadata| metadata.file_type().is_socket())
-}
-
-async fn connect_unix(host: &str) -> Result {
- let connection = UnixStream::connect(host).await?;
- Client::connect(connection).await
-}
-
-async fn connect_tcp(host: &str) -> Result {
- let connection = TcpStream::connect(host).await?;
- Client::connect(connection).await
-}
-
-/// Gets the duration of the current song
-pub fn get_duration(status: &Status) -> Option {
- status.duration.map(|duration| duration.as_secs())
-}
-
-/// Gets the elapsed time of the current song
-pub fn get_elapsed(status: &Status) -> Option {
- status.elapsed.map(|duration| duration.as_secs())
-}
diff --git a/src/clients/music/mod.rs b/src/clients/music/mod.rs
new file mode 100644
index 0000000..6c3edd2
--- /dev/null
+++ b/src/clients/music/mod.rs
@@ -0,0 +1,66 @@
+use color_eyre::Result;
+use std::path::PathBuf;
+use std::sync::Arc;
+use std::time::Duration;
+use tokio::sync::broadcast;
+
+pub mod mpd;
+pub mod mpris;
+
+pub type PlayerUpdate = (Option