Repository: aome510/spotify-player (language: rust)

Issue:
OpenSpotifyLinkFromClipboard does not work on Wayland
**Describe the bug**
The action OpenSpotifyLinkFromClipboard to paste a spotify URL in spotify_player does not function on Wayland

**To Reproduce**
1. Be on Wayland, no Xwayland
2. Perform the action
3. Observe logs

**Expected behaviour**
It will get pasted and opened

**Log and backtrace**
```
2024-03-11T17:09:02.878456Z ERROR terminal_event{event=Key(KeyEvent { code: Char('O'), modifiers: KeyModifiers(SHIFT), kind: Press, state: KeyEventState(0x0) })}: spotify_player::event: Failed to handle event: get clipboard's content: XCB - couldn't establish conection: DisplayParsingError(DisplayNotSet)
2024-03-11T17:09:06.238562Z ERROR terminal_event{event=Key(KeyEvent { code: Char('O'), modifiers: KeyModifiers(SHIFT), kind: Press, state: KeyEventState(0x0) })}: spotify_player::event: Failed to handle event: get clipboard's content: XCB - couldn't establish conection: DisplayParsingError(DisplayNotSet)
```



Discussion / hints:
The error is pretty self-explained: `DisplayParsingError(DisplayNotSet)`. Can you try to run in the terminal the `copy_command` in your config (default to `xclip -sel c` for linux) to see if that works? 

You can also try different `copy_command`, e.g the one recommended for wayland
Thats for copying. This issue is for pasting.

The routines used for copying `execute_copy_command` is not specific to a system clipboard, unlike pasting, which uses a library and imports XCB. That is why it doesn't work, because the logs are from a library not a specific program error.
ahhh, my bad. Will see if there is a way to fix this with the `copypasta` library.

Fix patch:
diff --git a/.dir-locals.el b/.dir-locals.el
index c8fe8be5..7f682403 100644
--- a/.dir-locals.el
+++ b/.dir-locals.el
@@ -2,5 +2,5 @@
 ;;; For more information see (info "(emacs) Directory Variables")
 
 ((rustic-mode . ((eglot-workspace-configuration
-                  . (:rust-analyzer (:cargo (:features ["lyric-finder" "image" "notify" "clipboard"])
+                  . (:rust-analyzer (:cargo (:features ["lyric-finder" "image" "notify"])
                                      :check (:command "clippy")))))))
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 41151b6a..715b9efa 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -9,7 +9,7 @@ on:
 env:
   CARGO_TERM_COLOR: always
   RUST_BACKTRACE: 1
-  RUST_FEATURES: "rodio-backend,lyric-finder,media-control,image,notify,clipboard"
+  RUST_FEATURES: "rodio-backend,lyric-finder,media-control,image,notify"
 
 jobs:
   rust-ci:
diff --git a/Cargo.lock b/Cargo.lock
index 2ed16e39..62b7482d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -610,16 +610,6 @@ version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
 
-[[package]]
-name = "clipboard-win"
-version = "3.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9fdf5e01086b6be750428ba4a40619f847eb2e95756eee84b18e06e5f0b50342"
-dependencies = [
- "lazy-bytes-cast",
- "winapi",
-]
-
 [[package]]
 name = "cocoa"
 version = "0.24.1"
@@ -729,20 +719,6 @@ dependencies = [
  "windows-sys 0.52.0",
 ]
 
-[[package]]
-name = "copypasta"
-version = "0.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "deb85422867ca93da58b7f95fb5c0c10f6183ed6e1ef8841568968a896d3a858"
-dependencies = [
- "clipboard-win",
- "objc",
- "objc-foundation",
- "objc_id",
- "smithay-clipboard",
- "x11-clipboard",
-]
-
 [[package]]
 name = "core-foundation"
 version = "0.9.4"
@@ -2166,12 +2142,6 @@ dependencies = [
  "wasm-bindgen",
 ]
 
-[[package]]
-name = "lazy-bytes-cast"
-version = "5.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10257499f089cd156ad82d0a9cd57d9501fa2c989068992a97eb3c27836f206b"
-
 [[package]]
 name = "lazy_static"
 version = "1.4.0"
@@ -4261,17 +4231,6 @@ dependencies = [
  "xkeysym",
 ]
 
-[[package]]
-name = "smithay-clipboard"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c091e7354ea8059d6ad99eace06dd13ddeedbb0ac72d40a9a6e7ff790525882d"
-dependencies = [
- "libc",
- "smithay-client-toolkit",
- "wayland-backend",
-]
-
 [[package]]
 name = "smol_str"
 version = "0.2.1"
@@ -4338,7 +4297,6 @@ dependencies = [
  "clap",
  "clap_complete",
  "config_parser2",
- "copypasta",
  "crossterm",
  "daemonize",
  "dirs-next",
@@ -5655,16 +5613,6 @@ dependencies = [
  "windows-sys 0.48.0",
 ]
 
-[[package]]
-name = "x11-clipboard"
-version = "0.9.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b98785a09322d7446e28a13203d2cae1059a0dd3dfb32cb06d0a225f023d8286"
-dependencies = [
- "libc",
- "x11rb",
-]
-
 [[package]]
 name = "x11-dl"
 version = "2.21.0"
diff --git a/README.md b/README.md
index 4fda4667..b4d62153 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,6 @@
   - [Spotify Connect](#spotify-connect)
   - [Streaming](#streaming)
   - [Lyric](#lyric)
-  - [Clipboard](#clipboard)
   - [Media Control](#media-control)
   - [Image](#image)
   - [Notify](#notify)
@@ -63,10 +62,10 @@ A Spotify Premium account is **required**.
 ##### Linux
 
 - [Rust and cargo](https://www.rust-lang.org/tools/install) as the build dependencies
-- install `openssl`, `alsa-lib` (`streaming` feature), `libdbus` (`media-control` feature), `libxcb` (`clipboard` feature) system libraries.
+- install `openssl`, `alsa-lib` (`streaming` feature), `libdbus` (`media-control` feature).
   - For example, on Debian based systems, run the below command to install application's dependencies:
     ```shell
-    sudo apt install libssl-dev libasound2-dev libdbus-1-dev libxcb-shape0-dev libxcb-xfixes0-dev
+    sudo apt install libssl-dev libasound2-dev libdbus-1-dev
     ```
 
 ### Binaries
@@ -195,10 +194,6 @@ User can view lyric of the currently playing track by calling the `LyricPage` co
 
 Under the hood, `spotify_player` retrieves the song's lyric using [Genius.com](https://genius.com).
 
-### Clipboard
-
-To enable clipboard support, `spotify_player` needs to be built/installed with `clipboard` feature (**enabled** by default).
-
 ### Media Control
 
 To enable media control support, `spotify_player` needs to be built/installed with `media-control` feature (**enabled** by default) and set the `enable_media_control` config option to `true` in the [general configuration file](docs/config.md#media-control).
@@ -349,7 +344,7 @@ List of supported commands:
 | `SearchPage`                   | go to the search page                                                   | `g s`              |
 | `BrowsePage`                   | go to the browse page                                                   | `g b`              |
 | `PreviousPage`                 | go to the previous page                                                 | `backspace`, `C-q` |
-| `OpenSpotifyLinkFromClipboard` | open a Spotify link from clipboard (`clipboard` feature only)           | `O`                |
+| `OpenSpotifyLinkFromClipboard` | open a Spotify link from clipboard                                      | `O`                |
 | `SortTrackByTitle`             | sort the track table (if any) by track's title                          | `s t`              |
 | `SortTrackByArtists`           | sort the track table (if any) by track's artists                        | `s a`              |
 | `SortTrackByAlbum`             | sort the track table (if any) by track's album                          | `s A`              |
diff --git a/docs/config.md b/docs/config.md
index 6c45aea6..5f586ec6 100644
--- a/docs/config.md
+++ b/docs/config.md
@@ -21,37 +21,38 @@ All configuration files should be placed inside the application's configuration
 
 `spotify_player` uses `app.toml` to configure general application configurations:
 
-| Option                            | Description                                                                              | Default                                                    |
-| --------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------- |
-| `client_id`                       | the Spotify client's ID                                                                  | `65b708073fc0480ea92a077233ca87bd`                         |
-| `client_port`                     | the port that the application's client is running on to handle CLI commands              | `8080`                                                     |
-| `tracks_playback_limit`           | the limit for the number of tracks played in a **tracks** playback                       | `50`                                                       |
-| `playback_format`                 | the format of the text in the playback's window                                          | `{track} • {artists}\n{album}\n{metadata}`                 |
-| `notify_format`                   | the format of a notification (`notify` feature only)                                     | `{ summary = "{track} • {artists}", body = "{album}" }`    |
-| `copy_command`                    | the command used to execute a copy-to-clipboard action                                   | `xclip -sel c` (Linux), `pbcopy` (MacOS), `clip` (Windows) |
-| `player_event_hook_command`       | the hook command executed when there is a new player event                               | `None`                                                     |
-| `ap_port`                         | the application's Spotify session connection port                                        | `None`                                                     |
-| `proxy`                           | the application's Spotify session connection proxy                                       | `None`                                                     |
-| `theme`                           | the application's theme                                                                  | `default`                                                  |
-| `app_refresh_duration_in_ms`      | the duration (in ms) between two consecutive application refreshes                       | `32`                                                       |
-| `playback_refresh_duration_in_ms` | the duration (in ms) between two consecutive playback refreshes                          | `0`                                                        |
-| `page_size_in_rows`               | a page's size expressed as a number of rows (for page-navigation commands)               | `20`                                                       |
-| `enable_media_control`            | enable application media control support (`media-control` feature only)                  | `true` (Linux), `false` (Windows and MacOS)                |
-| `enable_streaming`                | enable streaming (`streaming` feature only)                                              | `Always`                                                   |
-| `enable_notify`                   | enable notification (`notify` feature only)                                              | `true`                                                     |
-| `enable_cover_image_cache`        | store album's cover images in the cache folder                                           | `true`                                                     |
-| `notify_streaming_only`           | only send notification when streaming is enabled (`streaming` and `notify` feature only) | `false`                                                    |
-| `default_device`                  | the default device to connect to on startup if no playing device found                   | `spotify-player`                                           |
-| `play_icon`                       | the icon to indicate playing state of a Spotify item                                     | `▶`                                                       |
-| `pause_icon`                      | the icon to indicate pause state of a Spotify item                                       | `▌▌`                                                       |
-| `liked_icon`                      | the icon to indicate the liked state of a song                                           | `♥`                                                       |
-| `border_type`                     | the type of the application's borders                                                    | `Plain`                                                    |
-| `progress_bar_type`               | the type of the playback progress bar                                                    | `Rectangle`                                                |
-| `playback_window_position`        | the position of the playback window                                                      | `Top`                                                      |
-| `playback_window_width`           | the width of the playback window                                                         | `6`                                                        |
-| `cover_img_width`                 | the width of the cover image (`image` feature only)                                      | `5`                                                        |
-| `cover_img_length`                | the length of the cover image (`image` feature only)                                     | `9`                                                        |
-| `cover_img_scale`                 | the scale of the cover image (`image` feature only)                                      | `1.0`                                                      |
+| Option                            | Description                                                                              | Default                                                                                                          |
+| --------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
+| `client_id`                       | the Spotify client's ID                                                                  | `65b708073fc0480ea92a077233ca87bd`                                                                               |
+| `client_port`                     | the port that the application's client is running on to handle CLI commands              | `8080`                                                                                                           |
+| `tracks_playback_limit`           | the limit for the number of tracks played in a **tracks** playback                       | `50`                                                                                                             |
+| `playback_format`                 | the format of the text in the playback's window                                          | `{track} • {artists}\n{album}\n{metadata}`                                                                       |
+| `notify_format`                   | the format of a notification (`notify` feature only)                                     | `{ summary = "{track} • {artists}", body = "{album}" }`                                                          |
+| `copy_command`                    | the command used to execute a copy-to-clipboard action                                   | depends on the OS, see [example config](https://github.com/aome510/spotify-player/blob/master/examples/app.toml) |
+| `paste_command`                   | the command used to get clipboard's content                                              | depends on the OS, see [example config](https://github.com/aome510/spotify-player/blob/master/examples/app.toml) |
+| `player_event_hook_command`       | the hook command executed when there is a new player event                               | `None`                                                                                                           |
+| `ap_port`                         | the application's Spotify session connection port                                        | `None`                                                                                                           |
+| `proxy`                           | the application's Spotify session connection proxy                                       | `None`                                                                                                           |
+| `theme`                           | the application's theme                                                                  | `default`                                                                                                        |
+| `app_refresh_duration_in_ms`      | the duration (in ms) between two consecutive application refreshes                       | `32`                                                                                                             |
+| `playback_refresh_duration_in_ms` | the duration (in ms) between two consecutive playback refreshes                          | `0`                                                                                                              |
+| `page_size_in_rows`               | a page's size expressed as a number of rows (for page-navigation commands)               | `20`                                                                                                             |
+| `enable_media_control`            | enable application media control support (`media-control` feature only)                  | `true` (Linux), `false` (Windows and MacOS)                                                                      |
+| `enable_streaming`                | enable streaming (`streaming` feature only)                                              | `Always`                                                                                                         |
+| `enable_notify`                   | enable notification (`notify` feature only)                                              | `true`                                                                                                           |
+| `enable_cover_image_cache`        | store album's cover images in the cache folder                                           | `true`                                                                                                           |
+| `notify_streaming_only`           | only send notification when streaming is enabled (`streaming` and `notify` feature only) | `false`                                                                                                          |
+| `default_device`                  | the default device to connect to on startup if no playing device found                   | `spotify-player`                                                                                                 |
+| `play_icon`                       | the icon to indicate playing state of a Spotify item                                     | `▶`                                                                                                             |
+| `pause_icon`                      | the icon to indicate pause state of a Spotify item                                       | `▌▌`                                                                                                             |
+| `liked_icon`                      | the icon to indicate the liked state of a song                                           | `♥`                                                                                                             |
+| `border_type`                     | the type of the application's borders                                                    | `Plain`                                                                                                          |
+| `progress_bar_type`               | the type of the playback progress bar                                                    | `Rectangle`                                                                                                      |
+| `playback_window_position`        | the position of the playback window                                                      | `Top`                                                                                                            |
+| `playback_window_width`           | the width of the playback window                                                         | `6`                                                                                                              |
+| `cover_img_width`                 | the width of the cover image (`image` feature only)                                      | `5`                                                                                                              |
+| `cover_img_length`                | the length of the cover image (`image` feature only)                                     | `9`                                                                                                              |
+| `cover_img_scale`                 | the scale of the cover image (`image` feature only)                                      | `1.0`                                                                                                            |
 
 ### Notes
 
@@ -74,7 +75,12 @@ All configuration files should be placed inside the application's configuration
   **Note**: the above list might not be up-to-date.
 
 - An example of event that triggers a playback update is the one happening when the current track ends.
-- `copy_command` is represented by a struct with two fields `command` and `args`. For example, `copy_command = { command = "xclip", args = ["-sel", "c"] }`. The copy command should read input from **standard input**.
+- `copy_command` or `paste_command` is represented by an object with two fields `command` and `args`. For example,
+  ```toml
+  copy_command = { command = "xclip", args = ["-sel", "c"] }
+  paste_command = { command = "xclip", args = ["-o", "-sel", "c"] }
+  ```
+  The copy command should read input from **stdin** while the paste command should print output to **stdout**.
 - `enable_streaming` can be either `Always`, `Never` or `DaemonOnly`. For backwards compatibility, `true` and `false` are still accepted as aliases for `Always` and `Never`.
 - `playback_window_position` can only be either `Top` or `Bottom`.
 - `border_type` can be either `Hidden`, `Plain`, `Rounded`, `Double` or `Thick`.
@@ -89,7 +95,7 @@ MacOS and Windows require **an open window** to listen to OS media event. As a r
 
 ### Player event hook command
 
-Similar to `copy_command`, if specified, `player_event_hook_command` should be a struct with two fields `command` and `args`. Each time `spotify_player` receives a new player event, `player_event_hook_command` is executed with the event's data as the script's arguments.
+Similar to `copy_command`, if specified, `player_event_hook_command` should be an object with two fields `command` and `args`. Each time `spotify_player` receives a new player event, `player_event_hook_command` is executed with the event's data as the script's arguments.
 
 A player event is represented as a list of arguments with either of the following values:
 
diff --git a/examples/app.toml b/examples/app.toml
index c20163d6..c35f3128 100644
--- a/examples/app.toml
+++ b/examples/app.toml
@@ -5,9 +5,12 @@ tracks_playback_limit = 50
 playback_format = "{track} • {artists}\n{album}\n{metadata}"
 notify_format = { summary = "{track} • {artists}", body = "{album}" }
 # the default `copy_command` is based on the OS
-# copy_command = { command = "pbcopy", args = [] } # macos
+# copy_command = { command = "pbcopy" } # macos
 # copy_command = { command = "xclip", args = ["-sel", "c"] } # linux
 # copy_command = { command = "clip", args = [] } # windows
+# paste_command = { command = "pbpaste" } # macos
+# paste_command = { command = "xclip", args = ["-o", "-sel", "c"] } # linux
+# paste_command = { command = "powershell", args = ["-command", "Get-Clipboard"] } # windows
 app_refresh_duration_in_ms = 32
 playback_refresh_duration_in_ms = 0
 page_size_in_rows = 20
diff --git a/spotify_player/Cargo.toml b/spotify_player/Cargo.toml
index d90e0776..134b6e65 100644
--- a/spotify_player/Cargo.toml
+++ b/spotify_player/Cargo.toml
@@ -45,7 +45,6 @@ once_cell = "1.19.0"
 regex = "1.10.4"
 daemonize = { version = "0.5.0", optional = true }
 ttl_cache = "0.5.1"
-copypasta = { version = "0.10.1", optional = true }
 clap_complete = "4.5.1"
 
 [target.'cfg(any(target_os = "windows", target_os = "macos"))'.dependencies.winit]
@@ -77,10 +76,9 @@ media-control = ["souvlaki", "winit", "windows"]
 image = ["viuer", "dep:image"]
 sixel = ["image", "viuer/sixel"]
 notify = ["notify-rust"]
-clipboard = ["copypasta"]
 daemon = ["daemonize", "streaming"]
 
-default = ["rodio-backend", "media-control", "clipboard"]
+default = ["rodio-backend", "media-control"]
 
 [package.metadata.binstall]
 pkg-url = "{ repo }/releases/download/v{ version }/{ name }_{ target }{ archive-suffix }"
diff --git a/spotify_player/src/command.rs b/spotify_player/src/command.rs
index 887a0426..2ac77330 100644
--- a/spotify_player/src/command.rs
+++ b/spotify_player/src/command.rs
@@ -63,7 +63,6 @@ pub enum Command {
     SearchPage,
     BrowsePage,
     PreviousPage,
-    #[cfg(feature = "clipboard")]
     OpenSpotifyLinkFromClipboard,
 
     SortTrackByTitle,
@@ -253,7 +252,6 @@ impl Command {
             Self::SearchPage => "go to the search page",
             Self::BrowsePage => "go to the browse page",
             Self::PreviousPage => "go to the previous page",
-            #[cfg(feature = "clipboard")]
             Self::OpenSpotifyLinkFromClipboard => "open a Spotify link from clipboard",
             Self::SortTrackByTitle => "sort the track table (if any) by track's title",
             Self::SortTrackByArtists => "sort the track table (if any) by track's artists",
diff --git a/spotify_player/src/config/keymap.rs b/spotify_player/src/config/keymap.rs
index c525ab6b..15a5632c 100644
--- a/spotify_player/src/config/keymap.rs
+++ b/spotify_player/src/config/keymap.rs
@@ -186,7 +186,6 @@ impl Default for KeymapConfig {
                     key_sequence: "C-q".into(),
                     command: Command::PreviousPage,
                 },
-                #[cfg(feature = "clipboard")]
                 Keymap {
                     key_sequence: "O".into(),
                     command: Command::OpenSpotifyLinkFromClipboard,
diff --git a/spotify_player/src/config/mod.rs b/spotify_player/src/config/mod.rs
index b63794b1..1ad2c106 100644
--- a/spotify_player/src/config/mod.rs
+++ b/spotify_player/src/config/mod.rs
@@ -26,6 +26,8 @@ pub struct AppConfig {
     pub client_port: u16,
 
     pub copy_command: Command,
+    pub paste_command: Command,
+
     pub player_event_hook_command: Option<Command>,
 
     pub playback_format: String,
@@ -110,6 +112,7 @@ config_parser_impl!(ProgressBarType);
 #[derive(Debug, Deserialize, Serialize, ConfigParse, Clone)]
 pub struct Command {
     pub command: String,
+    #[serde(default)]
     pub args: Vec<String>,
 }
 
@@ -201,6 +204,23 @@ impl Default for AppConfig {
                 args: vec![],
             },
 
+            #[cfg(target_os = "macos")]
+            paste_command: Command {
+                command: "pbpaste".to_string(),
+                args: vec![],
+            },
+            #[cfg(all(unix, not(target_os = "macos")))]
+            paste_command: Command {
+                command: "xclip".to_string(),
+                args: vec!["-o".to_string(), "-sel".to_string(), "c".to_string()],
+            },
+            // based on https://stackoverflow.com/a/54910545
+            #[cfg(target_os = "windows")]
+            paste_command: Command {
+                command: "powershell".to_string(),
+                args: vec!["-command".to_string(), "Get-Clipboard".to_string()],
+            },
+
             player_event_hook_command: None,
 
             proxy: None,
diff --git a/spotify_player/src/event/mod.rs b/spotify_player/src/event/mod.rs
index a870615d..92f0a3ed 100644
--- a/spotify_player/src/event/mod.rs
+++ b/spotify_player/src/event/mod.rs
@@ -1,5 +1,6 @@
 use crate::{
     command::{self, Command},
+    config,
     key::{Key, KeySequence},
     state::*,
     ui::single_line_input::LineInput,
@@ -8,11 +9,7 @@ use crate::{
 
 #[cfg(feature = "lyric-finder")]
 use crate::utils::map_join;
-#[cfg(feature = "clipboard")]
-use anyhow::Context as _;
-use anyhow::Result;
-#[cfg(feature = "clipboard")]
-use copypasta::{ClipboardContext, ClipboardProvider};
+use anyhow::{Context as _, Result};
 
 mod page;
 mod popup;
@@ -374,9 +371,9 @@ fn handle_global_command(
                 ui.popup = None;
             }
         }
-        #[cfg(feature = "clipboard")]
         Command::OpenSpotifyLinkFromClipboard => {
-            let content = get_clipboard_content().context("get clipboard's content")?;
+            let content = get_clipboard_content(&state.configs.app_config.paste_command)
+                .context("get clipboard's content")?;
             let re = regex::Regex::new(
                 r"https://open.spotify.com/(?P<type>.*?)/(?P<id>[[:alnum:]]*).*",
             )?;
@@ -484,15 +481,9 @@ fn handle_global_command(
     Ok(true)
 }
 
-#[cfg(feature = "clipboard")]
-fn get_clipboard_content() -> Result<String> {
-    let mut clipboard_ctx = match ClipboardContext::new() {
-        Ok(ctx) => ctx,
-        Err(err) => anyhow::bail!("{err:#}"),
-    };
-    let content = match clipboard_ctx.get_contents() {
-        Ok(content) => content,
-        Err(err) => anyhow::bail!("{err:#}"),
-    };
-    Ok(content)
+fn get_clipboard_content(cmd: &config::Command) -> Result<String> {
+    let output = std::process::Command::new(&cmd.command)
+        .args(&cmd.args)
+        .output()?;
+    Ok(String::from_utf8(output.stdout)?)
 }
diff --git a/spotify_player/src/event/popup.rs b/spotify_player/src/event/popup.rs
index 752033ad..c56fba73 100644
--- a/spotify_player/src/event/popup.rs
+++ b/spotify_player/src/event/popup.rs
@@ -536,18 +536,19 @@ fn execute_copy_command(cmd: &config::Command, text: String) -> Result<()> {
         .args(&cmd.args)
         .stdin(std::process::Stdio::piped())
         .stdout(std::process::Stdio::piped())
+        .stderr(std::process::Stdio::piped())
         .spawn()?;
 
-    let result = match child.stdin.take() {
-        Some(mut stdin) => stdin
-            .write_all(text.as_bytes())
-            .map_err(anyhow::Error::from),
-        None => Err(anyhow::anyhow!("no stdin found in the child command")),
-    };
-
-    child.wait()?;
+    if let Some(mut stdin) = child.stdin.take() {
+        stdin.write_all(text.as_bytes())?;
+    }
 
-    result
+    let output = child.wait_with_output()?;
+    if output.status.success() {
+        Ok(())
+    } else {
+        anyhow::bail!("copy command failed: {}", String::from_utf8(output.stderr)?);
+    }
 }
 
 /// handles a key sequence for an action list popup


Test patch: