Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package mpv-mpris for openSUSE:Factory 
checked in at 2026-01-08 15:26:14
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/mpv-mpris (Old)
 and      /work/SRC/openSUSE:Factory/.mpv-mpris.new.1928 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "mpv-mpris"

Thu Jan  8 15:26:14 2026 rev:8 rq:1325795 version:1.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/mpv-mpris/mpv-mpris.changes      2024-11-17 
16:42:12.469747497 +0100
+++ /work/SRC/openSUSE:Factory/.mpv-mpris.new.1928/mpv-mpris.changes    
2026-01-08 15:27:15.072614183 +0100
@@ -1,0 +2,15 @@
+Wed Jan  7 14:11:04 UTC 2026 - Mia Herkt <[email protected]>
+
+- Update to 1.2
+  * More consistent external album art finding with mpv
+  * Use audio-client-name when naming mpv session bus
+  * Fix shuffle functionality
+  * Fix race condition at initialisation which sometimes caused
+    error logging
+  * Fix using multiple instances with flatpak by using a random
+    string rather than pid to identify multiple players
+  * Now properly report of Next and previous are available based on
+    current position in playlist
+- Don’t create symlink in no-longer-packaged /etc/mpv directory
+
+-------------------------------------------------------------------

Old:
----
  mpv-mpris-1.1.tar.gz

New:
----
  mpv-mpris-1.2.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ mpv-mpris.spec ++++++
--- /var/tmp/diff_new_pack.hMQ3D2/_old  2026-01-08 15:27:15.576635424 +0100
+++ /var/tmp/diff_new_pack.hMQ3D2/_new  2026-01-08 15:27:15.576635424 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package mpv-mpris
 #
-# Copyright (c) 2024 SUSE LLC
+# Copyright (c) 2026 SUSE LLC and contributors
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,11 +17,10 @@
 
 
 Name:           mpv-mpris
-Version:        1.1
+Version:        1.2
 Release:        0
 Summary:        MPRIS plugin for mpv
 License:        MIT
-Group:          Productivity/Multimedia/Video/Players
 URL:            https://github.com/hoyon/mpv-mpris
 Source0:        
https://github.com/hoyon/mpv-mpris/archive/%{version}.tar.gz#/%{name}-%{version}.tar.gz
 BuildRequires:  dbus-1
@@ -43,16 +42,13 @@
 as well as through tools like playerctl.
 
 %prep
-%setup -q
-%autopatch -p1
+%autosetup -p1
 
 %build
 %make_build
 
 %install
 install -Dm0755 mpris.so %{buildroot}%{_libdir}/mpv/mpris.so
-mkdir -p %{buildroot}%{_sysconfdir}/mpv/scripts
-ln -s %{_libdir}/mpv/mpris.so %{buildroot}%{_sysconfdir}/mpv/scripts/mpris.so
 
 # test suite does not work on OBS VM
 # %%check
@@ -61,6 +57,4 @@
 %files
 %license LICENSE
 %{_libdir}/mpv
-%dir %{_sysconfdir}/mpv/scripts
-%{_sysconfdir}/mpv/scripts/mpris.so
 

++++++ mpv-mpris-1.1.tar.gz -> mpv-mpris-1.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpv-mpris-1.1/.github/workflows/build.yml 
new/mpv-mpris-1.2/.github/workflows/build.yml
--- old/mpv-mpris-1.1/.github/workflows/build.yml       2023-08-30 
19:19:38.000000000 +0200
+++ new/mpv-mpris-1.2/.github/workflows/build.yml       2026-01-01 
23:21:19.000000000 +0100
@@ -15,14 +15,14 @@
           sudo apt install libmpv-dev libglib2.0-dev libavformat-dev
 
       - name: Checkout
-        uses: actions/checkout@v3
+        uses: actions/checkout@v6
 
       - name: Build
         run: |
           make
 
       - name: Upload binary
-        uses: actions/upload-artifact@v3
+        uses: actions/upload-artifact@v6
         with:
           name: mpris.so
           path: mpris.so
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpv-mpris-1.1/mpris.c new/mpv-mpris-1.2/mpris.c
--- old/mpv-mpris-1.1/mpris.c   2023-08-30 19:19:38.000000000 +0200
+++ new/mpv-mpris-1.2/mpris.c   2026-01-01 23:21:19.000000000 +0100
@@ -72,19 +72,26 @@
 {
     mpv_handle *mpv;
     GMainLoop *loop;
+    GMainContext *ctx;
+    int wakeup_pipe[2];
     gint bus_id;
     GDBusConnection *connection;
     GDBusInterfaceInfo *root_interface_info;
     GDBusInterfaceInfo *player_interface_info;
     guint root_interface_id;
     guint player_interface_id;
+    char *client_name;
     const char *status;
     const char *loop_status;
+    gboolean shuffle;
     GHashTable *changed_properties;
     GVariant *metadata;
     gboolean seek_expected;
     gboolean idle;
     gboolean paused;
+    gboolean events_setup;
+    int64_t playlist_count;
+    int64_t playlist_pos;
 } UserData;
 
 static const char *STATUS_PLAYING = "Playing";
@@ -94,6 +101,10 @@
 static const char *LOOP_TRACK = "Track";
 static const char *LOOP_PLAYLIST = "Playlist";
 
+static void setup_mpv_event_sources(UserData *ud);
+static gboolean can_go_next(UserData *ud);
+static gboolean can_go_previous(UserData *ud);
+
 static gchar *string_to_utf8(gchar *maybe_utf8)
 {
     gchar *attempted_validation;
@@ -156,9 +167,6 @@
 
 static gchar *path_to_uri(mpv_handle *mpv, char *path)
 {
-#if GLIB_CHECK_VERSION(2, 58, 0)
-    // version which uses g_canonicalize_filename which expands .. and .
-    // and makes the uris neater
     char* working_dir;
     gchar* canonical;
     gchar *uri;
@@ -171,25 +179,6 @@
     g_free(canonical);
 
     return uri;
-#else
-    // for compatibility with older versions of glib
-    gchar *converted;
-    if (g_path_is_absolute(path)) {
-        converted = g_filename_to_uri(path, NULL, NULL);
-    } else {
-        char* working_dir;
-        gchar* absolute;
-
-        working_dir = mpv_get_property_string(mpv, "working-directory");
-        absolute = g_build_filename(working_dir, path, NULL);
-        converted = g_filename_to_uri(absolute, NULL, NULL);
-
-        mpv_free(working_dir);
-        g_free(absolute);
-    }
-
-    return converted;
-#endif
 }
 
 static void add_metadata_uri(mpv_handle *mpv, GVariantDict *dict)
@@ -215,46 +204,62 @@
     mpv_free(path);
 }
 
-// Copied from 
https://github.com/videolan/vlc/blob/master/modules/meta_engine/folder.c
-static const char art_files[][20] = {
-    "Folder.jpg",           /* Windows */
-    "Folder.png",
-    "AlbumArtSmall.jpg",    /* Windows */
-    "AlbumArt.jpg",         /* Windows */
-    "Album.jpg",
-    ".folder.png",          /* KDE?    */
-    "cover.jpg",            /* rockbox */
-    "cover.png",
-    "cover.gif",
-    "front.jpg",
-    "front.png",
-    "front.gif",
-    "front.bmp",
-    "thumb.jpg",
-};
+static gchar* try_get_cover_art_file(mpv_handle *mpv)
+{
+    char *files_str = mpv_get_property_string(mpv, "cover-art-files");
+    if (!files_str || files_str[0] == '\0') {
+        mpv_free(files_str);
+        return NULL;
+    }
 
-static const int art_files_count = sizeof(art_files) / sizeof(art_files[0]);
+    // cover-art-files is a comma-separated list, use the first one
+    gchar **files = g_strsplit(files_str, ",", -1);
+    mpv_free(files_str);
 
-static gchar* try_get_local_art(mpv_handle *mpv, char *path)
-{
-    gchar *dirname = g_path_get_dirname(path), *out = NULL;
-    gboolean found = FALSE;
+    gchar *out = NULL;
+    if (files[0] && files[0][0] != '\0') {
+        out = path_to_uri(mpv, files[0]);
+    }
+
+    g_strfreev(files);
+    return out;
+}
 
-    for (int i = 0; i < art_files_count; i++) {
-        gchar *filename = g_build_filename(dirname, art_files[i], NULL);
+static gchar* try_get_folder_art(mpv_handle *mpv, char *path)
+{
+    gchar *out = NULL;
+    gchar *dirname = g_path_get_dirname(path);
 
-        if (g_file_test(filename, G_FILE_TEST_EXISTS)) {
-            out = path_to_uri(mpv, filename);
-            found = TRUE;
-        }
+    char *exts_str = mpv_get_property_string(mpv, "image-exts");
+    char *names_str = mpv_get_property_string(mpv, "cover-art-whitelist");
 
-        g_free(filename);
+    if (!exts_str || !names_str) {
+        mpv_free(exts_str);
+        mpv_free(names_str);
+        g_free(dirname);
+        return NULL;
+    }
 
-        if (found) {
-            break;
+    gchar **exts = g_strsplit(exts_str, ",", -1);
+    gchar **names = g_strsplit(names_str, ",", -1);
+    mpv_free(exts_str);
+    mpv_free(names_str);
+
+    for (gchar **name = names; *name; ++name) {
+        for (gchar **ext = exts; *ext; ++ext) {
+            gchar *filename = g_strdup_printf("%s/%s.%s", dirname, *name, 
*ext);
+            if (g_file_test(filename, G_FILE_TEST_EXISTS)) {
+                out = path_to_uri(mpv, filename);
+                g_free(filename);
+                goto done;
+            }
+            g_free(filename);
         }
     }
 
+done:
+    g_strfreev(exts);
+    g_strfreev(names);
     g_free(dirname);
     return out;
 }
@@ -286,15 +291,16 @@
 }
 
 static gchar* extract_embedded_art(AVFormatContext *context) {
-    if (avformat_find_stream_info(context, NULL) < 0) {
-        g_printerr("failed to find stream info");
-        return NULL;
-    }
-
     AVPacket *packet = NULL;
     for (unsigned int i = 0; i < context->nb_streams; i++) {
         if (context->streams[i]->disposition & AV_DISPOSITION_ATTACHED_PIC) {
-            packet = &context->streams[i]->attached_pic;
+            AVPacket *p = &context->streams[i]->attached_pic;
+
+            // Skip the thumbnail if the size is bigger than 25MiB to avoid 
crashes
+            if (p->size <= 25*0x100000) {
+                packet = p;
+                break;
+            }
         }
     }
     if (!packet) {
@@ -320,6 +326,23 @@
     return out;
 }
 
+static gchar* get_art_url(mpv_handle *mpv, char *path)
+{
+    gchar *url;
+    gboolean is_remote = g_str_has_prefix(path, "http");
+
+    if ((url = try_get_cover_art_file(mpv)))
+        return url;
+    if (is_remote && (url = try_get_youtube_thumbnail(path)))
+        return url;
+    if (!is_remote && (url = try_get_embedded_art(path)))
+        return url;
+    if (!is_remote && (url = try_get_folder_art(mpv, path)))
+        return url;
+
+    return NULL;
+}
+
 // cached last file path, owned by mpv
 static char *cached_path = NULL;
 
@@ -339,15 +362,7 @@
         mpv_free(cached_path);
         g_free(cached_art_url);
         cached_path = path;
-
-        if (g_str_has_prefix(path, "http")) {
-            cached_art_url = try_get_youtube_thumbnail(path);
-        } else {
-            cached_art_url = try_get_embedded_art(path);
-            if (!cached_art_url) {
-                cached_art_url = try_get_local_art(mpv, path);
-            }
-        }
+        cached_art_url = get_art_url(mpv, path);
     } else {
         mpv_free(path);
     }
@@ -388,7 +403,6 @@
 static GVariant *create_metadata(UserData *ud)
 {
     GVariantDict dict;
-    int64_t track;
     double duration;
     char *temp_str;
     int res;
@@ -396,12 +410,11 @@
     g_variant_dict_init(&dict, NULL);
 
     // mpris:trackid
-    mpv_get_property(ud->mpv, "playlist-pos", MPV_FORMAT_INT64, &track);
-    // playlist-pos < 0 if there is no playlist or current track
-    if (track < 0) {
+    // playlist_pos < 0 if there is no playlist or current track
+    if (ud->playlist_pos < 0) {
         temp_str = g_strdup("/noplaylist");
     } else {
-        temp_str = g_strdup_printf("/%" PRId64, track);
+        temp_str = g_strdup_printf("/%" PRId64, ud->playlist_pos);
     }
     g_variant_dict_insert(&dict, "mpris:trackid", "o", temp_str);
     g_free(temp_str);
@@ -412,10 +425,7 @@
         g_variant_dict_insert(&dict, "mpris:length", "x", (int64_t)(duration * 
1000000.0));
     }
 
-    // initial value. Replaced with metadata value if available
     add_metadata_item_string(ud->mpv, &dict, "media-title", "xesam:title");
-
-    add_metadata_item_string(ud->mpv, &dict, "metadata/by-key/Title", 
"xesam:title");
     add_metadata_item_string(ud->mpv, &dict, "metadata/by-key/Album", 
"xesam:album");
     add_metadata_item_string(ud->mpv, &dict, "metadata/by-key/Genre", 
"xesam:genre");
 
@@ -632,16 +642,14 @@
         g_free(offset_str);
 
     } else if (g_strcmp0(method_name, "SetPosition") == 0) {
-        int64_t current_id;
         char *object_path;
         double new_position_s;
         int64_t new_position_us;
 
-        mpv_get_property(ud->mpv, "playlist-pos", MPV_FORMAT_INT64, 
&current_id);
         g_variant_get(parameters, "(&ox)", &object_path, &new_position_us);
         new_position_s = ((float)new_position_us) / 1000000.0; // us -> s
 
-        if (current_id == g_ascii_strtoll(object_path + 1, NULL, 10)) {
+        if (ud->playlist_pos == g_ascii_strtoll(object_path + 1, NULL, 10)) {
             mpv_set_property(ud->mpv, "time-pos", MPV_FORMAT_DOUBLE, 
&new_position_s);
         }
 
@@ -684,7 +692,7 @@
 
     } else if (g_strcmp0(property_name, "Shuffle") == 0) {
         int shuffle;
-        mpv_get_property(ud->mpv, "playlist-shuffle", MPV_FORMAT_FLAG, 
&shuffle);
+        mpv_get_property(ud->mpv, "shuffle", MPV_FORMAT_FLAG, &shuffle);
         ret = g_variant_new_boolean(shuffle);
 
     } else if (g_strcmp0(property_name, "Metadata") == 0) {
@@ -715,10 +723,10 @@
         ret = g_variant_new_double(100);
 
     } else if (g_strcmp0(property_name, "CanGoNext") == 0) {
-        ret = g_variant_new_boolean(TRUE);
+        ret = g_variant_new_boolean(can_go_next(ud));
 
     } else if (g_strcmp0(property_name, "CanGoPrevious") == 0) {
-        ret = g_variant_new_boolean(TRUE);
+        ret = g_variant_new_boolean(can_go_previous(ud));
 
     } else if (g_strcmp0(property_name, "CanPlay") == 0) {
         ret = g_variant_new_boolean(TRUE);
@@ -774,7 +782,14 @@
 
     } else if (g_strcmp0(property_name, "Shuffle") == 0) {
         int shuffle = g_variant_get_boolean(value);
-        mpv_set_property(ud->mpv, "playlist-shuffle", MPV_FORMAT_FLAG, 
&shuffle);
+        if (shuffle && !ud->shuffle) {
+            const char *cmd[] = {"playlist-shuffle", NULL};
+            mpv_command_async(ud->mpv, 0, cmd);
+        } else if (!shuffle && ud->shuffle) {
+            const char *cmd[] = {"playlist-unshuffle", NULL};
+            mpv_command_async(ud->mpv, 0, cmd);
+        }
+        mpv_set_property(ud->mpv, "shuffle", MPV_FORMAT_FLAG, &shuffle);
 
     } else if (g_strcmp0(property_name, "Volume") == 0) {
         double volume = g_variant_get_double(value);
@@ -826,6 +841,7 @@
                                       params, &error);
         if (error != NULL) {
             g_printerr("%s", error->message);
+            g_clear_error(&error);
         }
 
         g_hash_table_remove_all(ud->changed_properties);
@@ -851,9 +867,32 @@
 
     if (error != NULL) {
         g_printerr("%s", error->message);
+        g_clear_error(&error);
     }
 }
 
+static gboolean can_go_next(UserData *ud)
+{
+    if (ud->playlist_pos < 0 || ud->playlist_count <= 0)
+        return FALSE;
+    if (ud->playlist_count == 1)
+        return FALSE;
+    if (g_strcmp0(ud->loop_status, LOOP_PLAYLIST) == 0)
+        return TRUE;
+    return ud->playlist_pos < ud->playlist_count - 1;
+}
+
+static gboolean can_go_previous(UserData *ud)
+{
+    if (ud->playlist_pos < 0 || ud->playlist_count <= 0)
+        return FALSE;
+    if (ud->playlist_count == 1)
+        return FALSE;
+    if (g_strcmp0(ud->loop_status, LOOP_PLAYLIST) == 0)
+        return TRUE;
+    return ud->playlist_pos > 0;
+}
+
 static GVariant * set_playback_status(UserData *ud)
 {
     if (ud->idle) {
@@ -879,7 +918,7 @@
   emit_property_changes(ud);
 }
 
-// Register D-Bus object and interfaces
+// Register D-Bus object and interfaces, then set up mpv event handlers
 static void on_bus_acquired(GDBusConnection *connection,
                             G_GNUC_UNUSED const char *name,
                             gpointer user_data)
@@ -888,39 +927,84 @@
     UserData *ud = user_data;
     ud->connection = connection;
 
-    ud->root_interface_id =
-        g_dbus_connection_register_object(connection, 
"/org/mpris/MediaPlayer2",
-                                          ud->root_interface_info,
-                                          &vtable_root,
-                                          user_data, NULL, &error);
-    if (error != NULL) {
-        g_printerr("%s", error->message);
+    if (ud->root_interface_id == 0) {
+        ud->root_interface_id =
+            g_dbus_connection_register_object(connection, 
"/org/mpris/MediaPlayer2",
+                                              ud->root_interface_info,
+                                              &vtable_root,
+                                              user_data, NULL, &error);
+        if (error != NULL) {
+            g_printerr("Failed to register root interface: %s\n", 
error->message);
+            g_clear_error(&error);
+        }
     }
 
-    ud->player_interface_id =
-        g_dbus_connection_register_object(connection, 
"/org/mpris/MediaPlayer2",
-                                        ud->player_interface_info,
-                                        &vtable_player,
-                                        user_data, NULL, &error);
-    if (error != NULL) {
-        g_printerr("%s", error->message);
+    if (ud->player_interface_id == 0) {
+        ud->player_interface_id =
+            g_dbus_connection_register_object(connection, 
"/org/mpris/MediaPlayer2",
+                                              ud->player_interface_info,
+                                              &vtable_player,
+                                              user_data, NULL, &error);
+        if (error != NULL) {
+            g_printerr("Failed to register player interface: %s\n", 
error->message);
+            g_clear_error(&error);
+        }
     }
+
+    if (!ud->events_setup) {
+        setup_mpv_event_sources(ud);
+        ud->events_setup = TRUE;
+    }
+}
+
+static char *generate_random_id(void)
+{
+    static const char alpha[] = 
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+    const int len = 8;
+
+    char *id = g_malloc(len + 1);
+    for (int i = 0; i < len; i++) {
+        id[i] = alpha[g_random_int_range(0, sizeof(alpha) - 1)];
+    }
+    id[len] = '\0';
+    return id;
+}
+
+static char *build_bus_name(const char *client_name, gboolean unique_suffix)
+{
+    GString *name = g_string_new("org.mpris.MediaPlayer2.mpv");
+
+    // don't append client name if it is the default value 'mpv'
+    if (g_strcmp0(client_name, "mpv") != 0) {
+        g_string_append_printf(name, ".%s", client_name);
+    }
+
+    if (unique_suffix) {
+        char *id = generate_random_id();
+        g_string_append_printf(name, ".instance-%s", id);
+        g_free(id);
+    }
+
+    return g_string_free(name, FALSE);
 }
 
 static void on_name_lost(GDBusConnection *connection,
                          G_GNUC_UNUSED const char *_name,
                          gpointer user_data)
 {
+    UserData *ud = user_data;
+
     if (connection) {
-        UserData *ud = user_data;
-        pid_t pid = getpid();
-        char *name = g_strdup_printf("org.mpris.MediaPlayer2.mpv.instance%d", 
pid);
+        char *name = build_bus_name(ud->client_name, TRUE);
         ud->bus_id = g_bus_own_name(G_BUS_TYPE_SESSION,
                                     name,
                                     G_BUS_NAME_OWNER_FLAGS_NONE,
                                     NULL, NULL, NULL,
                                     &ud, NULL);
         g_free(name);
+    } else {
+      ud->root_interface_id = 0;
+      ud->player_interface_id = 0;
     }
 }
 
@@ -928,6 +1012,8 @@
 {
     const char *prop_name = NULL;
     GVariant *prop_value = NULL;
+    gboolean update_can_go_next_prev = FALSE;
+
     if (g_strcmp0(name, "pause") == 0) {
         ud->paused = *(int*)data;
         prop_name = "PlaybackStatus";
@@ -975,6 +1061,7 @@
         }
         prop_name = "LoopStatus";
         prop_value = g_variant_new_string(ud->loop_status);
+        update_can_go_next_prev = TRUE;
 
     } else if (g_strcmp0(name, "loop-playlist") == 0) {
         char *status = *(char **)data;
@@ -992,12 +1079,26 @@
         }
         prop_name = "LoopStatus";
         prop_value = g_variant_new_string(ud->loop_status);
+        update_can_go_next_prev = TRUE;
+
+    } else if (g_strcmp0(name, "shuffle") == 0) {
+        int shuffle = *(int*)data;
+        ud->shuffle = shuffle;
+        prop_name = "Shuffle";
+        prop_value = g_variant_new_boolean(shuffle);
 
     } else if (g_strcmp0(name, "fullscreen") == 0) {
         gboolean *status = data;
         prop_name = "Fullscreen";
         prop_value = g_variant_new_boolean(*status);
 
+    } else if (g_strcmp0(name, "playlist-count") == 0) {
+      ud->playlist_count = *(int64_t *)data;
+      update_can_go_next_prev = TRUE;
+
+    } else if (g_strcmp0(name, "playlist-pos") == 0) {
+      ud->playlist_pos = *(int64_t *)data;
+      update_can_go_next_prev = TRUE;
     }
 
     if (prop_name) {
@@ -1007,6 +1108,13 @@
         g_hash_table_insert(ud->changed_properties,
                             (gpointer)prop_name, prop_value);
     }
+
+    if (update_can_go_next_prev) {
+        g_hash_table_insert(ud->changed_properties, "CanGoNext",
+                            g_variant_new_boolean(can_go_next(ud)));
+        g_hash_table_insert(ud->changed_properties, "CanGoPrevious",
+                            g_variant_new_boolean(can_go_previous(ud)));
+    }
 }
 
 static gboolean event_handler(int fd, G_GNUC_UNUSED GIOCondition condition, 
gpointer data)
@@ -1054,6 +1162,37 @@
     (void)!write(*((int*)fd), "0", 1);
 }
 
+static void setup_mpv_event_sources(UserData *ud)
+{
+    GError *error = NULL;
+    GSource *mpv_pipe_source;
+    GSource *timeout_source;
+
+    g_unix_open_pipe(ud->wakeup_pipe, 0, &error);
+    if (error != NULL) {
+        g_printerr("%s", error->message);
+        g_clear_error(&error);
+    }
+    fcntl(ud->wakeup_pipe[0], F_SETFL, O_NONBLOCK);
+    mpv_set_wakeup_callback(ud->mpv, wakeup_handler, &ud->wakeup_pipe[1]);
+
+    mpv_pipe_source = g_unix_fd_source_new(ud->wakeup_pipe[0], G_IO_IN);
+    g_source_set_callback(mpv_pipe_source,
+                          G_SOURCE_FUNC(event_handler),
+                          ud,
+                          NULL);
+    g_source_attach(mpv_pipe_source, ud->ctx);
+    g_source_unref(mpv_pipe_source);
+
+    timeout_source = g_timeout_source_new(100);
+    g_source_set_callback(timeout_source,
+                          G_SOURCE_FUNC(emit_property_changes),
+                          ud,
+                          NULL);
+    g_source_attach(timeout_source, ud->ctx);
+    g_source_unref(timeout_source);
+}
+
 // Plugin entry point
 int mpv_open_cplugin(mpv_handle *mpv)
 {
@@ -1062,9 +1201,6 @@
     UserData ud = {0};
     GError *error = NULL;
     GDBusNodeInfo *introspection_data = NULL;
-    int pipe[2];
-    GSource *mpv_pipe_source;
-    GSource *timeout_source;
 
     ctx = g_main_context_new();
     loop = g_main_loop_new(ctx, FALSE);
@@ -1073,6 +1209,7 @@
     introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, 
&error);
     if (error != NULL) {
         g_printerr("%s", error->message);
+        g_clear_error(&error);
     }
     ud.root_interface_info =
         g_dbus_node_info_lookup_interface(introspection_data, 
"org.mpris.MediaPlayer2");
@@ -1081,22 +1218,29 @@
 
     ud.mpv = mpv;
     ud.loop = loop;
+    ud.ctx = ctx;
     ud.status = STATUS_STOPPED;
     ud.loop_status = LOOP_NONE;
     ud.changed_properties = g_hash_table_new(g_str_hash, g_str_equal);
     ud.seek_expected = FALSE;
     ud.idle = FALSE;
     ud.paused = FALSE;
+    ud.shuffle = FALSE;
+    ud.client_name = mpv_get_property_string(mpv, "audio-client-name");
+    mpv_get_property(mpv, "playlist-count", MPV_FORMAT_INT64, 
&ud.playlist_count);
+    mpv_get_property(mpv, "playlist-pos", MPV_FORMAT_INT64, &ud.playlist_pos);
 
+    char *bus_name = build_bus_name(ud.client_name, FALSE);
     g_main_context_push_thread_default(ctx);
     ud.bus_id = g_bus_own_name(G_BUS_TYPE_SESSION,
-                               "org.mpris.MediaPlayer2.mpv",
+                               bus_name,
                                G_BUS_NAME_OWNER_FLAGS_DO_NOT_QUEUE,
                                on_bus_acquired,
                                NULL,
                                on_name_lost,
                                &ud, NULL);
     g_main_context_pop_thread_default(ctx);
+    g_free(bus_name);
 
     // Receive event for property changes
     mpv_observe_property(mpv, 0, "pause", MPV_FORMAT_FLAG);
@@ -1107,35 +1251,13 @@
     mpv_observe_property(mpv, 0, "loop-file", MPV_FORMAT_STRING);
     mpv_observe_property(mpv, 0, "loop-playlist", MPV_FORMAT_STRING);
     mpv_observe_property(mpv, 0, "duration", MPV_FORMAT_INT64);
+    mpv_observe_property(mpv, 0, "shuffle", MPV_FORMAT_FLAG);
     mpv_observe_property(mpv, 0, "fullscreen", MPV_FORMAT_FLAG);
-
-    // Run callback whenever there are events
-    g_unix_open_pipe(pipe, 0, &error);
-    if (error != NULL) {
-        g_printerr("%s", error->message);
-    }
-    fcntl(pipe[0], F_SETFL, O_NONBLOCK);
-    mpv_set_wakeup_callback(mpv, wakeup_handler, &pipe[1]);
-    mpv_pipe_source = g_unix_fd_source_new(pipe[0], G_IO_IN);
-    g_source_set_callback(mpv_pipe_source,
-                          G_SOURCE_FUNC(event_handler),
-                          &ud,
-                          NULL);
-    g_source_attach(mpv_pipe_source, ctx);
-
-    // Emit any new property changes every 100ms
-    timeout_source = g_timeout_source_new(100);
-    g_source_set_callback(timeout_source,
-                          G_SOURCE_FUNC(emit_property_changes),
-                          &ud,
-                          NULL);
-    g_source_attach(timeout_source, ctx);
+    mpv_observe_property(mpv, 0, "playlist-count", MPV_FORMAT_INT64);
+    mpv_observe_property(mpv, 0, "playlist-pos", MPV_FORMAT_INT64);
 
     g_main_loop_run(loop);
 
-    g_source_unref(mpv_pipe_source);
-    g_source_unref(timeout_source);
-
     g_dbus_connection_unregister_object(ud.connection, ud.root_interface_id);
     g_dbus_connection_unregister_object(ud.connection, ud.player_interface_id);
 
@@ -1143,6 +1265,7 @@
     g_main_loop_unref(loop);
     g_main_context_unref(ctx);
     g_dbus_node_info_unref(introspection_data);
+    mpv_free(ud.client_name);
 
     return 0;
 }

Reply via email to