Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package kew for openSUSE:Factory checked in 
at 2024-03-13 22:18:29
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/kew (Old)
 and      /work/SRC/openSUSE:Factory/.kew.new.1770 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "kew"

Wed Mar 13 22:18:29 2024 rev:15 rq:1157156 version:2.4.3

Changes:
--------
--- /work/SRC/openSUSE:Factory/kew/kew.changes  2024-02-29 21:50:46.802926930 
+0100
+++ /work/SRC/openSUSE:Factory/.kew.new.1770/kew.changes        2024-03-13 
22:19:37.130572109 +0100
@@ -1,0 +2,10 @@
+Tue Mar 12 10:40:54 UTC 2024 - Muhammad Akbar Yanuar Mantari <mantari...@pm.me>
+
+- Update to version 2.4.3
+  * Fixed covers not being perfectly square on some terminals.
+  * Fixed playlist selector could get 'stuck'.
+  * Code refactoring and minor improvements to playlist view.
+  * Moved the files kewrc and kewlibrary config files from
+    XDG_CONFIG_HOME into XDG_CONFIG_HOME/kew/ or ~/.config/kew.
+
+-------------------------------------------------------------------

Old:
----
  kew-2.4.2.tar.gz

New:
----
  kew-2.4.3.tar.gz

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

Other differences:
------------------
++++++ kew.spec ++++++
--- /var/tmp/diff_new_pack.Jkb2dq/_old  2024-03-13 22:19:37.702593196 +0100
+++ /var/tmp/diff_new_pack.Jkb2dq/_new  2024-03-13 22:19:37.706593344 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           kew
-Version:        2.4.2
+Version:        2.4.3
 Release:        0
 Summary:        A command-line music player
 License:        GPL-2.0-only

++++++ kew-2.4.2.tar.gz -> kew-2.4.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-2.4.2/Makefile new/kew-2.4.3/Makefile
--- old/kew-2.4.2/Makefile      2024-02-29 11:18:12.000000000 +0100
+++ new/kew-2.4.3/Makefile      2024-03-09 09:59:46.000000000 +0100
@@ -13,7 +13,7 @@
 
 OBJDIR = src/obj
 PREFIX = /usr
-SRCS = src/sound.c src/directorytree.c src/soundcommon.c src/player.c 
src/soundbuiltin.c src/mpris.c src/playerops.c src/utils.c src/file.c 
src/chafafunc.c src/cache.c src/songloader.c src/playlist.c src/term.c  
src/settings.c src/visuals.c src/kew.c
+SRCS = src/sound.c src/directorytree.c src/soundcommon.c src/playlist_ui.c 
src/player.c src/soundbuiltin.c src/mpris.c src/playerops.c src/utils.c 
src/file.c src/chafafunc.c src/cache.c src/songloader.c src/playlist.c 
src/term.c  src/settings.c src/visuals.c src/kew.c
 OBJS = $(SRCS:src/%.c=$(OBJDIR)/%.o)
 
 MAN_PAGE = kew.1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-2.4.2/README.md new/kew-2.4.3/README.md
--- old/kew-2.4.2/README.md     2024-02-29 11:18:12.000000000 +0100
+++ new/kew-2.4.3/README.md     2024-03-09 09:59:46.000000000 +0100
@@ -177,10 +177,10 @@
 * Use <kbd>←</kbd>, <kbd>→</kbd> or <kbd>h</kbd>, <kbd>l</kbd> keys to 
switch tracks.
 * <kbd>Space</kbd>, <kbd>P</kbd> to toggle pause.
 * <kbd>F2</kbd> to show/hide the playlist and information about kew.
-* <kbd>F3</kbd> to show/hide library.
-* <kbd>F4</kbd> to show/hide track view.
+* <kbd>F3</kbd> to show/hide the library.
+* <kbd>F4</kbd> to show/hide the track view.
 * <kbd>F5</kbd> to show/hide key bindings.
-* <kbd>u</kbd> to update library.
+* <kbd>u</kbd> to update the library.
 * <kbd>v</kbd> to toggle the spectrum visualizer.
 * <kbd>c</kbd> to toggle album covers.
 * <kbd>i</kbd> to switch between using your regular color scheme or colors 
derived from the track cover.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-2.4.2/docs/kew-manpage.mdoc 
new/kew-2.4.3/docs/kew-manpage.mdoc
--- old/kew-2.4.2/docs/kew-manpage.mdoc 2024-02-29 11:18:12.000000000 +0100
+++ new/kew-2.4.3/docs/kew-manpage.mdoc 2024-03-09 09:59:46.000000000 +0100
@@ -142,6 +142,8 @@
 .Bl -tag -width -compact
 .It Pa "~/<configfolder>/kewrc"
 Config file.
+.It Pa "~/<configfolder>/kew/kewlibrary"
+Music library directory tree cache.
 .It Pa "/<musicfolder>/kew.m3u"
 The 
 .Nm
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-2.4.2/docs/kew.1 new/kew-2.4.3/docs/kew.1
--- old/kew-2.4.2/docs/kew.1    2024-02-29 11:18:12.000000000 +0100
+++ new/kew-2.4.3/docs/kew.1    2024-03-09 09:59:46.000000000 +0100
@@ -169,9 +169,12 @@
 \fBkew\fR.
 .SH "FILES"
 .TP 10n
-\fI~/<configfolder>/kewrc\fR
+\fI~/<configfolder>/kew/kewrc\fR
 Config file.
 .TP 10n
+\fI~/<configfolder>/kew/kewlibrary\fR
+Music library directory tree cache.
+.TP 10n
 \fI/<musicfolder>/kew.m3u\fR
 The
 \fBkew\fR
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-2.4.2/src/chafafunc.c 
new/kew-2.4.3/src/chafafunc.c
--- old/kew-2.4.2/src/chafafunc.c       2024-02-29 11:18:12.000000000 +0100
+++ new/kew-2.4.3/src/chafafunc.c       2024-03-09 09:59:46.000000000 +0100
@@ -358,16 +358,66 @@
 
         chafa_calc_canvas_geometry(pix_width, pix_height, &width_cells, 
&height_cells, font_ratio, TRUE, FALSE);
 
-        /* Convert the image to a printable string */
+        // Convert image to a printable string
         printable = convert_image(pixels, pix_width, pix_height, pix_width * 
n_channels, CHAFA_PIXEL_BGRA8_UNASSOCIATED,
                                   width, height, cell_width, cell_height);
 
-        /* Print the string */
-
         fwrite(printable->str, sizeof(char), printable->len, stdout);
         g_string_free(printable, TRUE);
 }
 
+void printSquareBitmapCentered(FIBITMAP *bitmap, int baseHeight)
+{
+    if (bitmap == NULL)
+    {
+        return;
+    }
+    int pix_width = FreeImage_GetWidth(bitmap);
+    int pix_height = FreeImage_GetHeight(bitmap);
+    int n_channels = FreeImage_GetBPP(bitmap) / 8;
+    unsigned char *pixels = (unsigned char *)FreeImage_GetBits(bitmap);
+
+    TermSize term_size;
+    GString *printable;
+    gint cell_width = -1, cell_height = -1;
+
+    tty_init();
+    get_tty_size(&term_size);
+
+    if (term_size.width_cells > 0 && term_size.height_cells > 0 && 
term_size.width_pixels > 0 && term_size.height_pixels > 0)
+    {
+        cell_width = term_size.width_pixels / term_size.width_cells;
+        cell_height = term_size.height_pixels / term_size.height_cells;
+    }
+
+    // Set default for some terminals
+    if (cell_width == -1 && cell_height == -1)
+    {
+        cell_width = 8;
+        cell_height = 16;
+    }
+    float aspect_ratio_correction = (float)cell_height / (float)cell_width;
+
+    int correctedWidth = (int)(baseHeight * aspect_ratio_correction);
+
+    // Convert image to a printable string
+    printable = convert_image(pixels, pix_width, pix_height, pix_width * 
n_channels, CHAFA_PIXEL_BGRA8_UNASSOCIATED,
+                              correctedWidth, baseHeight, cell_width, 
cell_height);
+    g_string_append_c(printable, '\0');
+    const gchar *delimiters = "\n";
+    gchar **lines = g_strsplit(printable->str, delimiters, -1);
+
+    int indentation = ((term_size.width_cells - correctedWidth) / 2) + 1;   
+
+    for (int i = 0; lines[i] != NULL; i++)
+    {
+        printf("\n%*s%s", indentation, "", lines[i]);
+    }
+
+    g_strfreev(lines);
+    g_string_free(printable, TRUE);
+}
+
 void printBitmapCentered(FIBITMAP *bitmap, int width, int height)
 {
         if (bitmap == NULL)
@@ -392,6 +442,7 @@
                 cell_height = term_size.height_pixels / term_size.height_cells;
         }
 
+        // Convert image to a printable string
         printable = convert_image(pixels, pix_width, pix_height, pix_width * 
n_channels, CHAFA_PIXEL_BGRA8_UNASSOCIATED,
                                   width, height, cell_width, cell_height);
         g_string_append_c(printable, '\0');
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-2.4.2/src/chafafunc.h 
new/kew-2.4.3/src/chafafunc.h
--- old/kew-2.4.2/src/chafafunc.h       2024-02-29 11:18:12.000000000 +0100
+++ new/kew-2.4.3/src/chafafunc.h       2024-03-09 09:59:46.000000000 +0100
@@ -11,4 +11,5 @@
 FIBITMAP *getBitmap(const char *image_path);
 void printBitmap(FIBITMAP *bitmap, int width, int height);
 void printBitmapCentered(FIBITMAP *bitmap, int width, int height);
+void printSquareBitmapCentered(FIBITMAP *bitmap, int baseHeight);
 int getCoverColor(FIBITMAP *bitmap, unsigned char *r, unsigned char *g, 
unsigned char *b);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-2.4.2/src/directorytree.h 
new/kew-2.4.3/src/directorytree.h
--- old/kew-2.4.2/src/directorytree.h   2024-02-29 11:18:12.000000000 +0100
+++ new/kew-2.4.3/src/directorytree.h   2024-03-09 09:59:46.000000000 +0100
@@ -1,3 +1,6 @@
+#ifndef DIRECTORYTREE_H
+#define DIRECTORYTREE_H
+
 #include <ctype.h>
 #include <dirent.h>
 #include <regex.h>
@@ -34,3 +37,5 @@
 void freeTree(FileSystemEntry *root);
 void freeAndWriteTree(FileSystemEntry *root, const char *filename);
 FileSystemEntry *reconstructTreeFromFile(const char *filename, const char 
*startMusicPath, int *numDirectoryEntries);
+
+#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-2.4.2/src/kew.c new/kew-2.4.3/src/kew.c
--- old/kew-2.4.2/src/kew.c     2024-02-29 11:18:12.000000000 +0100
+++ new/kew-2.4.3/src/kew.c     2024-03-09 09:59:46.000000000 +0100
@@ -942,8 +942,8 @@
         pthread_mutex_init(&(loadingdata.mutex), NULL);
         pthread_mutex_init(&(playlist.mutex), NULL);
         nerdFontsEnabled = hasNerdFonts();
-        fflush(stdout);
         createLibrary(&settings);
+        fflush(stdout);        
 
 #ifdef DEBUG
         g_setenv("G_MESSAGES_DEBUG", "all", TRUE);
@@ -1083,6 +1083,7 @@
                 exit(0);
         }
 
+        moveConfigFiles(); // move from old location to new
         getConfig(&settings);
 
         if (argc == 3 && (strcmp(argv[1], "path") == 0))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-2.4.2/src/player.c new/kew-2.4.3/src/player.c
--- old/kew-2.4.2/src/player.c  2024-02-29 11:18:12.000000000 +0100
+++ new/kew-2.4.3/src/player.c  2024-03-09 09:59:46.000000000 +0100
@@ -22,7 +22,7 @@
 } PixelData;
 #endif
 
-const char VERSION[] = "2.4.2";
+const char VERSION[] = "2.4.3";
 int mainColor = 6;
 int titleColor = 6;
 int artistColor = 6;
@@ -48,7 +48,6 @@
 int elapsedBars = 0;
 int chosenRow = 0;
 int chosenSong = 0;
-int startIter = 0;
 int aboutHeight = 8;
 int visualizerHeight = 5;
 int minWidth = ABSOLUTE_MIN_WIDTH;
@@ -183,16 +182,6 @@
         calcIdealImgSize(&preferredWidth, &preferredHeight, (visualizerEnabled 
? visualizerHeight : 0), calcMetadataHeight());
 }
 
-void shortenString(char *str, size_t maxLength)
-{
-        size_t length = strlen(str);
-
-        if (length > maxLength)
-        {
-                str[maxLength] = '\0';
-        }
-}
-
 void printHelp()
 {
         printf(" kew - a command-line music player.\n");
@@ -313,7 +302,7 @@
 
         if (!ansii)
         {
-                printBitmapCentered(cover, width, height);
+                printSquareBitmapCentered(cover, height);
         }
         else
         {
@@ -624,38 +613,6 @@
         return numRows;
 }
 
-void removeUnneededChars(char *str)
-{
-        if (strlen(str) < 6)
-        {
-                return;
-        }
-
-        int i;
-        for (i = 0; i < 3 && str[i] != '\0' && str[i] != ' '; i++)
-        {
-                if (isdigit(str[i]) || str[i] == '-' || str[i] == ' ')
-                {
-                        int j;
-                        for (j = i; str[j] != '\0'; j++)
-                        {
-                                str[j] = str[j + 1];
-                        }
-                        str[j] = '\0';
-                        i--; // Decrement i to re-check the current index
-                }
-        }
-        i = 0;
-        while (str[i] != '\0')
-        {
-                if (str[i] == '-' || str[i] == '_')
-                {
-                        str[i] = ' ';
-                }
-                i++;
-        }
-}
-
 int showKeyBindings(SongData *songdata, AppSettings *settings)
 {
         int numPrintedRows = 0;
@@ -765,6 +722,7 @@
         else if (appState.currentView == PLAYLIST_VIEW)
         {
                 chosenRow += maxListSize - 1;
+                chosenRow = (chosenRow >= originalPlaylist->count) ? 
originalPlaylist->count - 1 : chosenRow;
                 refresh = true;
         }
 }
@@ -780,6 +738,7 @@
         else if (appState.currentView == PLAYLIST_VIEW)
         {
                 chosenRow -= maxListSize;
+                chosenRow = (chosenRow > 0) ? chosenRow : 0;
                 refresh = true;
         }
 }
@@ -789,6 +748,7 @@
         if (appState.currentView == PLAYLIST_VIEW)
         {
                 chosenRow++;
+                chosenRow = (chosenRow >= originalPlaylist->count) ? 
originalPlaylist->count - 1 : chosenRow;
                 refresh = true;
         }
         else if (appState.currentView == LIBRARY_VIEW)
@@ -803,6 +763,7 @@
         if (appState.currentView == PLAYLIST_VIEW)
         {
                 chosenRow--;
+                chosenRow = (chosenRow > 0) ? chosenRow : 0;
                 refresh = true;
         }
         else if (appState.currentView == LIBRARY_VIEW)
@@ -825,180 +786,34 @@
         return row;
 }
 
-int showPlaylist(SongData *songData)
+int printLogoAndAdjustments(SongData *songData, int termWidth, bool hideHelp, 
int indentation)
 {
-        Node *node = originalPlaylist->head;
-        Node *foundNode = NULL;
-        bool startFromCurrent = false;
-        int term_w, term_h;
-        getTermSize(&term_w, &term_h);
-        int totalHeight = term_h;
-        maxListSize = totalHeight - 3;
-        int numRows = 0;
-        int numPrintedRows = 0;
-        int foundAt = -1;
-
-        numRows++;
-
         int aboutRows = printLogo(songData);
-        maxListSize -= aboutRows - 1;
-
-        setDefaultTextColor();
-
-        printBlankSpaces(indent);
-        if (term_w > 52 && !hideHelp)
+        if (termWidth > 52 && !hideHelp)
         {
-                maxListSize -= 3;
-                printf(" Use ↑, ↓ or k, j to choose. Enter to accept.\n");
+                setDefaultTextColor();
                 printBlankSpaces(indent);
+                printf(" Use ↑, ↓ or k, j to choose. Enter to accept.\n");
+                printBlankSpaces(indentation);
                 printf(" Pg Up and Pg Dn to scroll. Del to remove entry.\n\n");
+                return aboutRows + 3;
         }
+        return aboutRows;
+}
 
-        int numSongs = 0;
-        for (int i = 0; i < originalPlaylist->count; i++)
-        {
-                if (node == NULL)
-                        break;
-
-                if (currentSong != NULL && currentSong->id == node->id)
-                {
-                        foundAt = numSongs;
-                        foundNode = node;
-                }
-
-                node = node->next;
-                numSongs++;
-                if (numSongs > maxListSize)
-                {
-                        startFromCurrent = true;
-                        if (foundAt > -1)
-                                break;
-                }
-        }
-
-        if (startFromCurrent)
-                node = foundNode;
-        else
-                node = originalPlaylist->head;
-
-        if (chosenRow >= originalPlaylist->count)
-        {
-                chosenRow = originalPlaylist->count - 1;
-        }
-
-        chosenSong = chosenRow;
-        chosenSong = (chosenSong < 0) ? 0 : chosenSong;
-
-        if (chosenSong < startIter)
-        {
-                startIter = chosenSong;
-        }
-
-        if (chosenRow > startIter + maxListSize - round(maxListSize / 2))
-        {
-                startIter = chosenRow - maxListSize + round(maxListSize / 2);
-        }
-
-        if (startIter == 0 && chosenRow < 0)
-        {
-                chosenRow = 0;
-        }
-
-        if (resetPlaylistDisplay && !audioData.endOfListReached)
-        {
-                startIter = chosenRow = chosenSong = foundAt;
-        }
-
-        for (int i = foundAt; i > startIter; i--)
-        {
-                if (i > 0 && node->prev != NULL)
-                        node = node->prev;
-        }
-
-        if (foundAt > -1)
-        {
-                for (int i = foundAt; i < startIter; i++)
-                {
-                        if (node->next != NULL)
-                                node = node->next;
-                }
-        }
-
-        for (int i = (startFromCurrent ? startIter : 0); i < (startFromCurrent 
? startIter : 0) + maxListSize; i++)
-        {
-                setDefaultTextColor();
-
-                if (node == NULL)
-                        break;
-                char filePath[MAXPATHLEN];
-                c_strcpy(filePath, sizeof(filePath), node->song.filePath);
-                char *lastSlash = strrchr(filePath, '/');
-                char *lastDot = strrchr(filePath, '.');
-                printf("\r");
-                printBlankSpaces(indent);
-
-                if (lastSlash != NULL && lastDot != NULL && lastDot > 
lastSlash)
-                {
-                        char copiedString[256];
-                        strncpy(copiedString, lastSlash + 1, lastDot - 
lastSlash - 1);
-                        copiedString[lastDot - lastSlash - 1] = '\0';
-                        removeUnneededChars(copiedString);
-
-                        if (i == chosenSong)
-                        {
-                                chosenNodeId = node->id;
-
-                                printf("\x1b[7m");
-                        }
-
-                        if (foundNode != NULL && foundNode->id == node->id)
-                        {
-                                printf("\e[1m\e[39m");
-                        }
-
-                        shortenString(copiedString, term_w - 10 - indent);
-                        trim(copiedString);
-
-                        if (i + 1 < 10)
-                                printf(" ");
-
-                        if (startFromCurrent)
-                        {
-                                printf(" %d. %s \n", i + 1, copiedString);
-                        }
-                        else
-                        {
-                                printf(" %d. %s \n", numRows, copiedString);
-                        }
+void showPlaylist(SongData *songData, PlayList *list, int *chosenSong, int 
*chosenNodeId)
+{
+        int term_w, term_h;
+        getTermSize(&term_w, &term_h);        
+        maxListSize = term_h - 2;
 
-                        numPrintedRows++;
-                        numRows++;
+        int aboutRows = printLogoAndAdjustments(songData, term_w, hideHelp, 
indent);
+        maxListSize -= aboutRows;        
 
-                        setTextColorRGB2(color.r, color.g, color.b);
+        displayPlaylist(list, maxListSize, indent, chosenSong, chosenNodeId, 
resetPlaylistDisplay);       
 
-                        setDefaultTextColor();
-                }
-                node = node->next;
-        }
         printf("\n");
-        numPrintedRows++;
         printLastRow();
-        if (numRows > 1)
-        {
-                while (numPrintedRows < maxListSize)
-                {
-                        printf("\n");
-                        numPrintedRows++;
-                }
-        }
-        numPrintedRows += 2;
-        numPrintedRows += aboutRows;
-        if (term_w > 46)
-        {
-                numPrintedRows += 2;
-        }
-        resetPlaylistDisplay = false;
-        return numPrintedRows;
 }
 
 void printElapsedBars(int elapsedBars)
@@ -1407,9 +1222,8 @@
         else if (appState.currentView == PLAYLIST_VIEW && refresh)
         {
                 clearScreen();
-                int height = showPlaylist(songdata);
-                cursorJump(height);
-                saveCursorPosition();
+                showPlaylist(songdata, originalPlaylist, &chosenRow, 
&chosenNodeId);
+                resetPlaylistDisplay = false;                
                 refresh = false;
         }
         else if (appState.currentView == LIBRARY_VIEW && refresh)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-2.4.2/src/player.h new/kew-2.4.3/src/player.h
--- old/kew-2.4.2/src/player.h  2024-02-29 11:18:12.000000000 +0100
+++ new/kew-2.4.3/src/player.h  2024-03-09 09:59:46.000000000 +0100
@@ -10,6 +10,7 @@
 #include "chafafunc.h"
 #include "directorytree.h"
 #include "playlist.h"
+#include "playlist_ui.h"
 #include "songloader.h"
 #include "sound.h"
 #include "term.h"
@@ -93,4 +94,3 @@
 void resetChosenDir();
 
 #endif
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-2.4.2/src/playerops.c 
new/kew-2.4.3/src/playerops.c
--- old/kew-2.4.2/src/playerops.c       2024-02-29 11:18:12.000000000 +0100
+++ new/kew-2.4.3/src/playerops.c       2024-03-09 09:59:46.000000000 +0100
@@ -12,7 +12,7 @@
 #endif
 
 #ifndef ASK_IF_USE_CACHE_LIMIT_SECONDS
-#define ASK_IF_USE_CACHE_LIMIT_SECONDS 1
+#define ASK_IF_USE_CACHE_LIMIT_SECONDS 4
 #endif
 
 struct timespec current_time;
@@ -328,7 +328,7 @@
         if (currentSong == NULL)
                 return NULL;
 
-        return (audioData.currentFileIndex == 0) ? userData.songdataA : 
userData.songdataB;                
+        return (audioData.currentFileIndex == 0) ? userData.songdataA : 
userData.songdataB;
 }
 
 void calcElapsedTime()
@@ -362,7 +362,6 @@
                 if (currentSong != NULL && timeSinceLastUpdate >= 1.0)
                 {
                         updatePlaybackPosition(elapsedSeconds);
-                        // Update the last update time to the current time
                         lastUpdateTime = current_time;
                 }
         }
@@ -778,6 +777,12 @@
         bool rebuild = false;
 
         Node *node = findSelectedEntry(originalPlaylist, chosenRow);
+
+        if (node == NULL)
+        {
+                return;
+        }
+
         Node *song = getNextSong();
         int id = node->id;
 
@@ -1125,7 +1130,7 @@
         songLoading = true;
         forceSkip = false;
 
-        playbackPlay(&totalPauseSeconds, &pauseSeconds);        
+        playbackPlay(&totalPauseSeconds, &pauseSeconds);
 
         loadingdata.loadA = !usingSongDataA;
         loadingdata.loadingFirstDecoder = true;
@@ -1325,7 +1330,7 @@
         enableInputBuffering();
         showCursor();
 
-        printf("Would you like to enable the library cache for quicker startup 
times?\nYou can update the cache at any time by pressing 'u'. (y/n): ");
+        printf("Would you like to enable a (local) library cache for quicker 
startup times?\nYou can update the cache at any time by pressing 'u'. (y/n): ");
 
         fflush(stdout);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-2.4.2/src/playlist_ui.c 
new/kew-2.4.3/src/playlist_ui.c
--- old/kew-2.4.2/src/playlist_ui.c     1970-01-01 01:00:00.000000000 +0100
+++ new/kew-2.4.3/src/playlist_ui.c     2024-03-09 09:59:46.000000000 +0100
@@ -0,0 +1,176 @@
+#include "playlist_ui.h"
+
+int startIter = 0;
+
+void getTerminalSize(int *width, int *height)
+{
+        getTermSize(width, height);
+}
+
+Node *determineStartNode(Node *head, int *foundAt, bool *startFromCurrent, int 
listSize)
+{
+        Node *node = head;
+        Node *foundNode = NULL;
+        int numSongs = 0;
+        *foundAt = -1;
+
+        while (node != NULL && numSongs <= listSize)
+        {
+                if (currentSong != NULL && currentSong->id == node->id)
+                {
+                        *foundAt = numSongs;
+                        foundNode = node;
+                        break;
+                }
+                node = node->next;
+                numSongs++;
+        }
+
+        *startFromCurrent = (*foundAt > -1) ? true : false;
+        return foundNode ? foundNode : head;
+}
+
+void preparePlaylistString(Node *node, char *buffer, int bufferSize, int 
shortenAmount)
+{
+        if (node == NULL || buffer == NULL)
+        {
+                buffer[0] = '\0';
+                return;
+        }
+
+        char filePath[MAXPATHLEN];
+        c_strcpy(filePath, sizeof(filePath), node->song.filePath);
+        char *lastSlash = strrchr(filePath, '/');
+        char *lastDot = strrchr(filePath, '.');
+
+        if (lastSlash != NULL && lastDot != NULL && lastDot > lastSlash)
+        {
+                int nameLength = lastDot - lastSlash - 1;
+                nameLength = (nameLength < bufferSize - 1) ? nameLength : 
bufferSize - 1;
+
+                strncpy(buffer, lastSlash + 1, nameLength);
+                buffer[nameLength] = '\0';
+                removeUnneededChars(buffer);
+                shortenString(buffer, shortenAmount);
+                trim(buffer);
+        }
+        else
+        {
+                buffer[0] = '\0';
+        }
+}
+
+int displayPlaylistItems(Node *startNode, int startIter, int maxListSize, int 
termWidth, int indent, bool startFromCurrent, int chosenSong, int *chosenNodeId)
+{
+        int numPrintedRows = 0;
+        Node *node = startNode;
+
+        char *buffer = (char *)malloc(MAXPATHLEN * sizeof(char));
+
+        if (!buffer)
+        {
+                return 0;
+        }
+
+        for (int i = startIter; node != NULL && i < startIter + maxListSize; 
i++)
+        {
+                preparePlaylistString(node, buffer, MAXPATHLEN, termWidth - 
indent - 10);
+                if (buffer[0] != '\0')
+                {
+                        setDefaultTextColor();
+                        printBlankSpaces(indent);
+
+                        if (i == chosenSong)
+                        {
+                                *chosenNodeId = node->id;
+
+                                printf("\x1b[7m");
+                        }
+
+                        if (currentSong != NULL && currentSong->id == node->id)
+                        {
+                                printf("\e[1m\e[39m");
+                        }
+
+                        if (i + 1 < 10)
+                                printf(" ");
+
+                        printf(" %d. %s \n", i + 1, buffer);
+
+                        numPrintedRows++;
+                }
+
+                node = node->next;
+        }
+
+        free(buffer);
+        return numPrintedRows;
+}
+
+int displayPlaylist(PlayList *list, int maxListSize, int indent, int 
*chosenSong, int *chosenNodeId, bool reset)
+{
+        int termWidth, termHeight;
+        getTerminalSize(&termWidth, &termHeight);
+
+        int foundAt = -1;
+        bool startFromCurrent = false;
+        Node *startNode = determineStartNode(list->head, &foundAt, 
&startFromCurrent, list->count);
+
+        // Determine chosen song
+        if (*chosenSong >= list->count)
+        {
+                *chosenSong = list->count - 1;
+        }
+
+        if (*chosenSong < 0)
+        {
+                *chosenSong = 0;
+        } 
+
+        int startIter = 0;
+
+        // Determine where to start iterating
+        startIter = (startFromCurrent && (foundAt < startIter || foundAt > 
startIter + maxListSize)) ? foundAt : startIter;
+
+        if (*chosenSong < startIter)
+        {
+                startIter = *chosenSong;
+        }
+    
+        if (*chosenSong > startIter + maxListSize - round(maxListSize / 2))
+        {
+                startIter = *chosenSong - maxListSize + round(maxListSize / 2);
+        }
+
+        if (reset && !audioData.endOfListReached) 
+        {
+                startIter = *chosenSong = foundAt;
+        }
+        
+        // Go up to find the starting node
+        for (int i = foundAt; i > startIter; i--)
+        {
+                if (i > 0 && startNode->prev != NULL)
+                        startNode = startNode->prev;
+        }
+        
+        // Go down to adjust the startNode
+        for (int i = (foundAt == -1) ? 0 : foundAt; i < startIter; i++)
+        {
+                if (startNode->next != NULL)
+                        startNode = startNode->next;
+        }
+
+        int printedRows = displayPlaylistItems(startNode, startIter, 
maxListSize, termWidth, indent, startFromCurrent, *chosenSong, chosenNodeId);
+
+        if (printedRows > 1)
+        {
+                while (printedRows < maxListSize)
+                {
+                        printf("\n");
+                        printedRows++;
+                }
+        }         
+
+        return printedRows;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-2.4.2/src/playlist_ui.h 
new/kew-2.4.3/src/playlist_ui.h
--- old/kew-2.4.2/src/playlist_ui.h     1970-01-01 01:00:00.000000000 +0100
+++ new/kew-2.4.3/src/playlist_ui.h     2024-03-09 09:59:46.000000000 +0100
@@ -0,0 +1,11 @@
+#ifndef PLAYLIST_UI_H
+#define PLAYLIST_UI_H
+
+#include "playlist.h"
+#include "songloader.h"
+#include "term.h"
+#include "utils.h"
+
+int displayPlaylist(PlayList *list, int maxListSize, int indent, int 
*chosenSong, int *chosenNodeId, bool reset);
+
+#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-2.4.2/src/settings.c new/kew-2.4.3/src/settings.c
--- old/kew-2.4.2/src/settings.c        2024-02-29 11:18:12.000000000 +0100
+++ new/kew-2.4.3/src/settings.c        2024-03-09 09:59:46.000000000 +0100
@@ -434,7 +434,7 @@
         fprintf(file, "hideHelp=%s\n", settings->hideHelp);
         fprintf(file, "lastVolume=%s\n", settings->lastVolume);
 
-        fprintf(file, "\n# Cache: Set to 1 to use cache of the library for 
faster startup times.\n");
+        fprintf(file, "\n# Cache: Set to 1 to use cache of the music library 
directory tree for faster startup times.\n");
         fprintf(file, "cacheLibrary=%s\n", settings->cacheLibrary);
 
         fprintf(file, "\n# Color values are 0=Black, 1=Red, 2=Green, 3=Yellow, 
4=Blue, 5=Magenta, 6=Cyan, 7=White\n");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-2.4.2/src/soundcommon.c 
new/kew-2.4.3/src/soundcommon.c
--- old/kew-2.4.2/src/soundcommon.c     2024-02-29 11:18:12.000000000 +0100
+++ new/kew-2.4.3/src/soundcommon.c     2024-03-09 09:59:46.000000000 +0100
@@ -1126,33 +1126,49 @@
         return output;
 }
 
-int displaySongNotification(const char *artist, const char *title, const char 
*cover)
-{
-        if (!allowNotifications)
-                return 0;
-
-        char command[MAXPATHLEN + 1024];
-        char sanitized_cover[MAXPATHLEN];
-
-        const char *blacklist = "&;`|*~<>^()[]{}$\\\"";
-        char *sanitizedArtist = remove_blacklisted_chars(artist, blacklist);
-        char *sanitizedTitle = remove_blacklisted_chars(title, blacklist);
+int displaySongNotification(const char *artist, const char *title, const char 
*cover) {
+    if (!allowNotifications)
+        return 0;
 
-        sanitize_filepath(cover, sanitized_cover, sizeof(sanitized_cover));
+    char sanitized_cover[MAXPATHLEN];
 
-        if (strlen(artist) <= 0)
-        {
-                snprintf(command, sizeof(command), "notify-send -a \"kew\" 
\"%s\" --icon \"%s\"", sanitizedTitle, sanitized_cover);
-        }
-        else
-        {
-                snprintf(command, sizeof(command), "notify-send -a \"kew\" 
\"%s - %s\" --icon \"%s\"", sanitizedArtist, sanitizedTitle, sanitized_cover);
+    const char *blacklist = "&;`|*~<>^()[]{}$\\\"";
+    char *sanitizedArtist = remove_blacklisted_chars(artist, blacklist);
+    char *sanitizedTitle = remove_blacklisted_chars(title, blacklist);
+
+    sanitize_filepath(cover, sanitized_cover, sizeof(sanitized_cover));
+
+    char message[MAXPATHLEN + 1024];
+    if (strlen(artist) > 0) {
+        snprintf(message, sizeof(message), "%s - %s", sanitizedArtist, 
sanitizedTitle);
+    } else {
+        snprintf(message, sizeof(message), "%s", sanitizedTitle);
+    }
+
+    char *args[] = {"notify-send", "-a", "kew", message, "--icon", 
sanitized_cover, NULL};
+
+    pid_t pid = fork();
+    if (pid == -1) {
+        // Handle error
+        perror("fork");
+    } else if (pid > 0) {
+        // Parent process
+        int status;
+        waitpid(pid, &status, 0);
+    } else {
+        // Child process
+        extern char **environ;
+        if (execve("/usr/bin/notify-send", args, environ) == -1) {
+            // Handle error
+            perror("execve");
+            _Exit(EXIT_FAILURE);
         }
+    }
 
-        free(sanitizedArtist);
-        free(sanitizedTitle);
+    free(sanitizedArtist);
+    free(sanitizedTitle);
 
-        return system(command);
+    return 0;
 }
 
 void executeSwitch(AudioData *pAudioData)
@@ -1222,12 +1238,12 @@
 {
         int sysVol = getSystemVolume();
 
-        if (sysVol == 0) 
+        if (sysVol == 0)
                 return 0;
 
         int step = 100 / sysVol * 5;
 
-        int relativeVolChange = volumeChange / 5  * step;
+        int relativeVolChange = volumeChange / 5 * step;
 
         soundVolume += relativeVolChange;
 
@@ -1239,15 +1255,15 @@
 ma_uint64 lastCursor = 0;
 
 void m4a_read_pcm_frames(ma_data_source *pDataSource, void *pFramesOut, 
ma_uint64 frameCount, ma_uint64 *pFramesRead)
-{        
+{
         m4a_decoder *m4a = (m4a_decoder *)pDataSource;
-        AudioData *pAudioData = (AudioData *)m4a->pReadSeekTellUserData;       
 
+        AudioData *pAudioData = (AudioData *)m4a->pReadSeekTellUserData;
         ma_uint64 framesRead = 0;
 
         while (framesRead < frameCount)
         {
                 if (doQuit)
-                        return;                        
+                        return;
 
                 if (isImplSwitchReached())
                         return;
@@ -1255,7 +1271,7 @@
                 if (pthread_mutex_trylock(&dataSourceMutex) != 0)
                 {
                         return;
-                }                        
+                }
 
                 // Check if a file switch is required
                 if (pAudioData->switchFiles)
@@ -1372,7 +1388,7 @@
         while (framesRead < frameCount)
         {
                 if (doQuit)
-                        return;                        
+                        return;
 
                 if (isImplSwitchReached())
                         return;
@@ -1380,7 +1396,7 @@
                 if (pthread_mutex_trylock(&dataSourceMutex) != 0)
                 {
                         return;
-                }                        
+                }
 
                 // Check if a file switch is required
                 if (pAudioData->switchFiles)
@@ -1498,11 +1514,10 @@
                 if (isImplSwitchReached())
                         return;
 
-
                 if (pthread_mutex_trylock(&dataSourceMutex) != 0)
                 {
                         return;
-                }                        
+                }
 
                 // Check if a file switch is required
                 if (pAudioData->switchFiles)
@@ -1512,7 +1527,7 @@
                         break; // Exit the loop after the file switch
                 }
 
-                ma_libvorbis *decoder = getCurrentVorbisDecoder();             
   
+                ma_libvorbis *decoder = getCurrentVorbisDecoder();
 
                 if ((getCurrentImplementationType() != VORBIS && 
!isSkipToNext()) || (decoder == NULL))
                 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-2.4.2/src/soundcommon.h 
new/kew-2.4.3/src/soundcommon.h
--- old/kew-2.4.2/src/soundcommon.h     2024-02-29 11:18:12.000000000 +0100
+++ new/kew-2.4.3/src/soundcommon.h     2024-03-09 09:59:46.000000000 +0100
@@ -6,6 +6,7 @@
 #include <miniaudio.h>
 #include <miniaudio_libopus.h>
 #include <miniaudio_libvorbis.h>
+#include <sys/wait.h>
 #include "m4a.h"
 #include <stdatomic.h>
 #include <stdbool.h>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-2.4.2/src/utils.c new/kew-2.4.3/src/utils.c
--- old/kew-2.4.2/src/utils.c   2024-02-29 11:18:12.000000000 +0100
+++ new/kew-2.4.3/src/utils.c   2024-03-09 09:59:46.000000000 +0100
@@ -4,7 +4,7 @@
  utils.c
 
  Utility functions for instance for replacing some standard functions with 
safer alterantives.
- 
+
 */
 void c_sleep(int milliseconds)
 {
@@ -135,15 +135,15 @@
 
 int startsWith(const char *str, const char *prefix)
 {
-    size_t strLength = strlen(str);
-    size_t prefixLength = strlen(prefix);
+        size_t strLength = strlen(str);
+        size_t prefixLength = strlen(prefix);
 
-    if (prefixLength > strLength)
-    {
-        return 0;
-    }
+        if (prefixLength > strLength)
+        {
+                return 0;
+        }
 
-    return strncmp(str, prefix, prefixLength) == 0;
+        return strncmp(str, prefix, prefixLength) == 0;
 }
 
 void trim(char *str)
@@ -186,7 +186,7 @@
         return xdgHome;
 }
 
-char *getConfigPath()
+char *getConfigPathOld()
 {
         char *configPath = malloc(MAXPATHLEN);
         if (!configPath)
@@ -221,3 +221,132 @@
 
         return configPath;
 }
+
+char *getConfigPath()
+{
+        char *configPath = malloc(MAXPATHLEN);
+        if (!configPath)
+                return NULL;
+
+        const char *xdgConfig = getenv("XDG_CONFIG_HOME");
+        if (xdgConfig)
+        {
+                snprintf(configPath, MAXPATHLEN, "%s/kew", xdgConfig);
+        }
+        else
+        {
+                const char *home = getHomePath();
+                if (home)
+                {
+                        snprintf(configPath, MAXPATHLEN, "%s/.config/kew", 
home);
+                }
+                else
+                {
+                        struct passwd *pw = getpwuid(getuid());
+                        if (pw)
+                        {
+                                snprintf(configPath, MAXPATHLEN, 
"%s/.config/kew", pw->pw_dir);
+                        }
+                        else
+                        {
+                                free(configPath);
+                                return NULL;
+                        }
+                }
+        }
+
+        return configPath;
+}
+
+int moveConfigFiles()
+{
+        char *oldPath = getConfigPathOld();
+        char *newPath = getConfigPath();
+        if (!oldPath || !newPath)
+        {
+
+                free(oldPath);
+                free(newPath);
+                return -1;
+        }
+
+        struct stat st = {0};
+        if (stat(newPath, &st) == -1)
+        {
+                mkdir(newPath, 0700);
+        }
+
+        char oldFileLibrary[MAXPATHLEN];
+        char newFileLibrary[MAXPATHLEN];
+        char oldFileRc[MAXPATHLEN];
+        char newFileRc[MAXPATHLEN];
+
+        snprintf(oldFileLibrary, MAXPATHLEN, "%s/kewlibrary", oldPath);
+        snprintf(newFileLibrary, MAXPATHLEN, "%s/kewlibrary", newPath);
+        snprintf(oldFileRc, MAXPATHLEN, "%s/kewrc", oldPath);
+        snprintf(newFileRc, MAXPATHLEN, "%s/kewrc", newPath);
+
+        if (access(oldFileLibrary, F_OK) == 0)
+        {
+                rename(oldFileLibrary, newFileLibrary);
+        }
+        if (access(oldFileRc, F_OK) == 0)
+        {
+                rename(oldFileRc, newFileRc);
+        }
+
+        free(oldPath);
+        free(newPath);
+
+        return 0;
+}
+
+void removeUnneededChars(char *str)
+{
+        if (strlen(str) < 6)
+        {
+                return;
+        }
+
+        int i;
+        for (i = 0; i < 3 && str[i] != '\0' && str[i] != ' '; i++)
+        {
+                if (isdigit(str[i]) || str[i] == '-' || str[i] == ' ')
+                {
+                        int j;
+                        for (j = i; str[j] != '\0'; j++)
+                        {
+                                str[j] = str[j + 1];
+                        }
+                        str[j] = '\0';
+                        i--; // Decrement i to re-check the current index
+                }
+        }
+        i = 0;
+        while (str[i] != '\0')
+        {
+                if (str[i] == '-' || str[i] == '_')
+                {
+                        str[i] = ' ';
+                }
+                i++;
+        }
+}
+
+void shortenString(char *str, size_t maxLength)
+{
+        size_t length = strlen(str);
+
+        if (length > maxLength)
+        {
+                str[maxLength] = '\0';
+        }
+}
+
+void printBlankSpaces(int numSpaces)
+{
+        for (int i = 0; i < numSpaces; i++)
+        {
+                printf(" ");
+        }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-2.4.2/src/utils.h new/kew-2.4.3/src/utils.h
--- old/kew-2.4.2/src/utils.h   2024-02-29 11:18:12.000000000 +0100
+++ new/kew-2.4.3/src/utils.h   2024-03-09 09:59:46.000000000 +0100
@@ -14,6 +14,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/param.h>
+#include <sys/stat.h>
 #include <unistd.h>
 #include <string.h>
 #include <time.h>
@@ -46,6 +47,16 @@
 
 const char *getHomePath();
 
+char *getConfigPathOld();
+
 char *getConfigPath();
 
+int moveConfigFiles(void);
+
+void removeUnneededChars(char *str);
+
+void shortenString(char *str, size_t maxLength);
+
+void printBlankSpaces(int numSpaces);
+
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-2.4.2/src/visuals.c new/kew-2.4.3/src/visuals.c
--- old/kew-2.4.2/src/visuals.c 2024-02-29 11:18:12.000000000 +0100
+++ new/kew-2.4.3/src/visuals.c 2024-03-09 09:59:46.000000000 +0100
@@ -33,14 +33,6 @@
                 unicodeSupport = true;
 }
 
-void printBlankSpaces(int numSpaces)
-{
-        for (int i = 0; i < numSpaces; i++)
-        {
-                printf(" ");
-        }
-}
-
 void updateMagnitudes(int height, int width, float maxMagnitude, float 
*magnitudes)
 {
         float exponent = 1.0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kew-2.4.2/src/visuals.h new/kew-2.4.3/src/visuals.h
--- old/kew-2.4.2/src/visuals.h 2024-02-29 11:18:12.000000000 +0100
+++ new/kew-2.4.3/src/visuals.h 2024-03-09 09:59:46.000000000 +0100
@@ -9,6 +9,7 @@
 #include <stdlib.h>
 #include "sound.h"
 #include "term.h"
+#include "utils.h"
 
 #ifndef PIXELDATA_STRUCT
 #define PIXELDATA_STRUCT
@@ -27,5 +28,3 @@
 void drawSpectrumVisualizer(int height, int width, PixelData c, int 
indentation, bool useProfileColors);
 
 PixelData increaseLuminosity(PixelData pixel, int amount);
-
-void printBlankSpaces(int numSpaces);

Reply via email to