tagtree: defer context menu disk access

When the database isn't loaded into RAM,
or the "quick" load setting is enabled,
filenames for tracks must be retrieved
from disk.

With a single track selected, this
can cause a delay before its context
menu is displayed.

Since filenames are only needed after the
user has selected something from the menu,
it makes sense to defer retrieval until
disk access becomes inevitable.

Change-Id: I72b57eff3102b50f3e19441119e20aad903b1f2b
This commit is contained in:
Christian Soffke 2025-04-14 23:00:22 +02:00 committed by Solomon Peachy
parent be47d646f0
commit 93b1611474
5 changed files with 57 additions and 23 deletions

View file

@ -64,6 +64,9 @@
#include "pathfuncs.h" #include "pathfuncs.h"
#include "shortcuts.h" #include "shortcuts.h"
#include "misc.h" #include "misc.h"
#ifdef HAVE_DISK_STORAGE
#include "storage.h"
#endif
static int onplay_result = ONPLAY_OK; static int onplay_result = ONPLAY_OK;
static bool in_queue_submenu = false; static bool in_queue_submenu = false;
@ -267,6 +270,11 @@ static void op_playlist_insert_selected(int position, bool queue)
ctx_current_playlist_insert(position, queue, false); ctx_current_playlist_insert(position, queue, false);
return; return;
} }
else if (selected_file.context == CONTEXT_ID3DB)
{
tagtree_current_playlist_insert(position, queue);
return;
}
#endif #endif
if ((selected_file.attr & FILE_ATTR_MASK) == FILE_ATTR_AUDIO) if ((selected_file.attr & FILE_ATTR_MASK) == FILE_ATTR_AUDIO)
playlist_insert_track(NULL, selected_file.path, position, queue, true); playlist_insert_track(NULL, selected_file.path, position, queue, true);
@ -274,13 +282,6 @@ static void op_playlist_insert_selected(int position, bool queue)
playlist_insert_playlist(NULL, selected_file.path, position, queue); playlist_insert_playlist(NULL, selected_file.path, position, queue);
else if (selected_file.attr & ATTR_DIRECTORY) else if (selected_file.attr & ATTR_DIRECTORY)
{ {
#ifdef HAVE_TAGCACHE
if (selected_file.context == CONTEXT_ID3DB)
{
tagtree_current_playlist_insert(position, queue);
return;
}
#endif
bool recurse = (global_settings.recursive_dir_insert == RECURSE_ON); bool recurse = (global_settings.recursive_dir_insert == RECURSE_ON);
if (global_settings.recursive_dir_insert == RECURSE_ASK) if (global_settings.recursive_dir_insert == RECURSE_ASK)
{ {
@ -839,16 +840,33 @@ static bool list_viewers(void)
#ifdef HAVE_TAGCACHE #ifdef HAVE_TAGCACHE
static bool prepare_database_sel(void *param) static bool prepare_database_sel(void *param)
{ {
if (selected_file.context == CONTEXT_ID3DB && if (selected_file.context == CONTEXT_ID3DB)
(selected_file.attr & FILE_ATTR_MASK) != FILE_ATTR_AUDIO)
{ {
if (!strcmp(param, "properties")) if (param && !strcmp(param, "properties")
&& (selected_file.attr & FILE_ATTR_MASK) != FILE_ATTR_AUDIO)
{
strmemccpy(selected_file.buf, MAKE_ACT_STR(ACTIVITY_DATABASEBROWSER), strmemccpy(selected_file.buf, MAKE_ACT_STR(ACTIVITY_DATABASEBROWSER),
sizeof(selected_file.buf)); sizeof(selected_file.buf));
else if (!tagtree_get_subentry_filename(selected_file.buf, MAX_PATH)) }
else
{ {
onplay_result = ONPLAY_RELOAD_DIR; /* If database is not loaded into RAM, or tagcache_ram is
return false; set to "quick", filename needs to be retrieved from disk! */
#ifdef HAVE_DISK_STORAGE
if ((selected_file.attr & FILE_ATTR_MASK) == FILE_ATTR_AUDIO
&& !storage_disk_is_active()
#ifdef HAVE_TC_RAMCACHE
&& (global_settings.tagcache_ram != TAGCACHE_RAM_ON
|| !tagcache_is_in_ram())
#endif
)
splash(0, ID2P(LANG_WAIT));
#endif
if (!tagtree_get_subentry_filename(selected_file.buf, MAX_PATH))
{
onplay_result = ONPLAY_RELOAD_DIR;
return false;
}
} }
selected_file.path = selected_file.buf; selected_file.path = selected_file.buf;
@ -1173,6 +1191,9 @@ static bool hotkey_delete_item(void)
if (selected_file.context == CONTEXT_ID3DB && if (selected_file.context == CONTEXT_ID3DB &&
(selected_file.attr & FILE_ATTR_MASK) != FILE_ATTR_AUDIO) (selected_file.attr & FILE_ATTR_MASK) != FILE_ATTR_AUDIO)
return false; return false;
if (!prepare_database_sel(NULL))
return false;
#endif #endif
return clipboard_delete_selected_fileobject(); return clipboard_delete_selected_fileobject();
@ -1186,6 +1207,10 @@ static bool hotkey_open_with(void)
#ifdef HAVE_MULTIVOLUME #ifdef HAVE_MULTIVOLUME
if (selected_file.attr & ATTR_VOLUME) if (selected_file.attr & ATTR_VOLUME)
return false; return false;
#endif
#ifdef HAVE_TAGCACHE
if (!prepare_database_sel(NULL))
return false;
#endif #endif
return list_viewers(); return list_viewers();
} }
@ -1341,8 +1366,7 @@ int onplay(char* file, int attr, int from_context, bool hotkey, int customaction
selected_file_set(from_context, NULL, attr); selected_file_set(from_context, NULL, attr);
#ifdef HAVE_TAGCACHE #ifdef HAVE_TAGCACHE
if (from_context == CONTEXT_ID3DB && if (from_context == CONTEXT_ID3DB)
(attr & FILE_ATTR_MASK) != FILE_ATTR_AUDIO)
{ {
ctx_add_to_playlist = tagtree_add_to_playlist; ctx_add_to_playlist = tagtree_add_to_playlist;
if (file != NULL) if (file != NULL)

View file

@ -286,8 +286,8 @@ static int add_track_to_playlist(char* filename, void* context)
/* Add "sel" file into specified "playlist". How to insert depends on type /* Add "sel" file into specified "playlist". How to insert depends on type
of file */ of file */
static int add_to_playlist(const char* playlist, bool new_playlist, int catalog_insert_into(const char* playlist, bool new_playlist,
const char* sel, int sel_attr) const char* sel, int sel_attr)
{ {
int fd; int fd;
int result = -1; int result = -1;
@ -514,7 +514,7 @@ bool catalog_add_to_a_playlist(const char* sel, int sel_attr,
result = ctx_add_to_playlist(playlist, new_playlist); result = ctx_add_to_playlist(playlist, new_playlist);
} }
else else
result = add_to_playlist(playlist, new_playlist, sel, sel_attr); result = catalog_insert_into(playlist, new_playlist, sel, sel_attr);
return (result == 0); return (result == 0);
} }

View file

@ -27,7 +27,7 @@ void catalog_get_directory(char* dirbuf, size_t dirbuf_sz);
/* Set the playlist catalog dir */ /* Set the playlist catalog dir */
void catalog_set_directory(const char* directory); void catalog_set_directory(const char* directory);
/* /*
* View list of playlists in catalog. * View list of playlists in catalog.
* ret : true if item was selected * ret : true if item was selected
*/ */
@ -36,7 +36,10 @@ bool catalog_view_playlists(void);
bool catalog_pick_new_playlist_name(char *pl_name, size_t buf_size, bool catalog_pick_new_playlist_name(char *pl_name, size_t buf_size,
const char* curr_pl_name); const char* curr_pl_name);
/* int catalog_insert_into(const char* playlist, bool new_playlist,
const char* sel, int sel_attr);
/*
* Add something to a playlist (new or select from list of playlists in * Add something to a playlist (new or select from list of playlists in
* catalog). * catalog).
* sel : the path of the music file, playlist or directory to add * sel : the path of the music file, playlist or directory to add

View file

@ -59,6 +59,7 @@
#include "onplay.h" #include "onplay.h"
#include "plugin.h" #include "plugin.h"
#include "language.h" #include "language.h"
#include "playlist_catalog.h"
#define str_or_empty(x) (x ? x : "(NULL)") #define str_or_empty(x) (x ? x : "(NULL)")
@ -2544,7 +2545,10 @@ static bool tagtree_insert_selection(int position, bool queue,
if (tagtree_get_filename(tc, buf, sizeof buf) < 0) if (tagtree_get_filename(tc, buf, sizeof buf) < 0)
return false; return false;
playlist_insert_track(NULL, buf, position, queue, true); if (!playlist)
playlist_insert_track(NULL, buf, position, queue, true);
else
catalog_insert_into(playlist, new_playlist, buf, FILE_ATTR_AUDIO);
return true; return true;
} }

View file

@ -919,7 +919,10 @@ static int dirbrowse(void)
if (tagtree_get_attr(&tc) == FILE_ATTR_AUDIO) if (tagtree_get_attr(&tc) == FILE_ATTR_AUDIO)
{ {
attr = FILE_ATTR_AUDIO; attr = FILE_ATTR_AUDIO;
tagtree_get_filename(&tc, buf, sizeof(buf));
/* Look up the filename only once it is needed, so we
don't have to wait for the disk to wake up here. */
buf[0] = '\0';
} }
else else
{ {
@ -1261,7 +1264,7 @@ bool bookmark_play(char *resume_file, int index, unsigned long elapsed,
if (peek_filename == NULL) if (peek_filename == NULL)
{ {
if (index == 0) /* searched every entry didn't find a match */ if (index == 0) /* searched every entry didn't find a match */
return false; return false;
/* playlist has shrunk, search from the top */ /* playlist has shrunk, search from the top */
i = 0; i = 0;