17 Commits

Author SHA1 Message Date
c4bce75866 Bump version, update NEWS
All checks were successful
Arch Linux AUR Success
Alpine 3.19 Success
2024-02-27 00:39:23 +01:00
08b87bccbd Bump liberty, fix a dead link 2024-02-27 00:30:39 +01:00
fa460b97cf Fix info plugins installation
They could never become executable.
2024-02-25 05:15:00 +01:00
ef19337bad Bump version, update NEWS 2024-02-10 18:39:57 +01:00
9699b80e9d Very mildly improve stream handling 2024-02-10 18:35:10 +01:00
7601a754af Bump liberty 2024-02-10 12:50:39 +01:00
31d975604b README.adoc: remove unintended line break 2024-02-10 10:21:09 +01:00
59f82b7a72 Bump liberty, set the window icon 2024-02-10 10:09:32 +01:00
8bcdb0afd5 Bump liberty, install rasterized icons 2024-02-10 06:04:39 +01:00
9dfd89ef06 CMakeLists.txt: declare compatibility with 3.27
Sadly, the 3.5 deprecation warning doesn't go away after this.
2023-08-01 03:01:06 +02:00
4b592ec295 Fix build in bare configurations 2023-08-01 02:37:48 +02:00
58eb7edfd5 Make the scroll wheel act on the gauge and volume 2023-07-23 15:51:22 +02:00
48fc9bdb19 Add vertical padding to the status bar as well
For symmetry, if for nothing else.
2023-07-23 15:36:37 +02:00
9ab5ab6928 Change volume in finer steps 2023-07-20 13:20:34 +02:00
93e0d7027a Fix build on systems without A_ITALIC
Unfortunately, this font style doesn't work in X11 either in that case.
2023-07-04 06:45:33 +02:00
5900b0708a README.adoc: update package information 2023-07-01 22:00:34 +02:00
5f97b95026 Bump liberty 2023-06-28 16:27:05 +02:00
6 changed files with 105 additions and 33 deletions

View File

@@ -1,5 +1,5 @@
cmake_minimum_required (VERSION 3.0) cmake_minimum_required (VERSION 3.0...3.27)
project (nncmpp VERSION 2.0.0 LANGUAGES C) project (nncmpp VERSION 2.1.1 LANGUAGES C)
# Moar warnings # Moar warnings
if ("${CMAKE_C_COMPILER_ID}" MATCHES "GNU" OR CMAKE_COMPILER_IS_GNUCC) if ("${CMAKE_C_COMPILER_ID}" MATCHES "GNU" OR CMAKE_COMPILER_IS_GNUCC)
@@ -68,7 +68,7 @@ if (WITH_PULSE)
list (APPEND extra_libraries ${libpulse_LIBRARIES}) list (APPEND extra_libraries ${libpulse_LIBRARIES})
endif () endif ()
pkg_check_modules (x11 x11 xrender xft fontconfig) pkg_check_modules (x11 x11 xrender xft fontconfig libpng)
add_option (WITH_X11 "Build with X11 support" "${x11_FOUND}") add_option (WITH_X11 "Build with X11 support" "${x11_FOUND}")
if (WITH_X11) if (WITH_X11)
if (NOT x11_FOUND) if (NOT x11_FOUND)
@@ -128,10 +128,25 @@ add_threads (${PROJECT_NAME})
install (TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) install (TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR})
install (FILES LICENSE DESTINATION ${CMAKE_INSTALL_DOCDIR}) install (FILES LICENSE DESTINATION ${CMAKE_INSTALL_DOCDIR})
install (DIRECTORY contrib DESTINATION ${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}) install (DIRECTORY contrib DESTINATION ${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME})
install (DIRECTORY info DESTINATION ${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}) install (DIRECTORY info DESTINATION ${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}
USE_SOURCE_PERMISSIONS)
if (WITH_X11) if (WITH_X11)
include (IconUtils)
set (icon_base ${PROJECT_BINARY_DIR}/icons)
set (icon_png_list)
foreach (icon_size 16 32 48)
icon_to_png (${PROJECT_NAME} ${PROJECT_SOURCE_DIR}/${PROJECT_NAME}.svg
${icon_size} ${icon_base} icon_png)
list (APPEND icon_png_list ${icon_png})
endforeach ()
add_custom_target (icons ALL DEPENDS ${icon_png_list})
install (FILES ${PROJECT_NAME}.svg install (FILES ${PROJECT_NAME}.svg
DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/scalable/apps) DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/scalable/apps)
install (DIRECTORY ${icon_base}
DESTINATION ${CMAKE_INSTALL_DATADIR})
install (FILES ${PROJECT_NAME}.desktop install (FILES ${PROJECT_NAME}.desktop
DESTINATION ${CMAKE_INSTALL_DATADIR}/applications) DESTINATION ${CMAKE_INSTALL_DATADIR}/applications)
endif () endif ()

17
NEWS
View File

@@ -1,4 +1,13 @@
Unreleased 2.1.1 (2024-02-27)
* Fixed installation of Info tab plugins
* Fixed display of playback mode toggles in the terminal user interface
* Fixed a dead link in the manual page
2.1.0 (2024-02-11)
* Added ability to look up song lyrics, * Added ability to look up song lyrics,
using a new scriptable extension interface for the Info tab using a new scriptable extension interface for the Info tab
@@ -13,12 +22,18 @@ Unreleased
* X11: fixed rendering of overflowing, partially visible list items * X11: fixed rendering of overflowing, partially visible list items
* X11: fixed a crash when resizing the window to zero dimensions
* Added a "o" binding to select the currently playing song * Added a "o" binding to select the currently playing song
* Added Readline-like M-u, M-l, M-c editor bindings * Added Readline-like M-u, M-l, M-c editor bindings
* Made the scroll wheel work on the elapsed time gauge and the volume display
* Changed volume adjustment bindings to use +/- keys * Changed volume adjustment bindings to use +/- keys
* Changed volume adjustment to go in steps of 5 rather than 10 %
2.0.0 (2022-09-03) 2.0.0 (2022-09-03)

View File

@@ -28,8 +28,10 @@ image::nncmpp.png[align="center"]
Packages Packages
-------- --------
Regular releases are sporadic. git master should be stable enough. You can get Regular releases are sporadic. git master should be stable enough.
a package with the latest development version from Archlinux's AUR. You can get a package with the latest development version using Arch Linux's
https://aur.archlinux.org/packages/nncmpp-git[AUR],
or as a https://git.janouch.name/p/nixexprs[Nix derivation].
Documentation Documentation
------------- -------------
@@ -38,10 +40,12 @@ The rest of this README will concern itself with externalities.
Building Building
-------- --------
Build dependencies: CMake, pkg-config, awk, liberty (included), Build-only dependencies: CMake, pkg-config, awk, liberty (included),
termo (included), asciidoctor or asciidoc (recommended but optional) + termo (included), asciidoctor or asciidoc (recommended but optional),
rsvg-convert (X11) +
Runtime dependencies: ncursesw, libunistring, cURL + Runtime dependencies: ncursesw, libunistring, cURL +
Optional runtime dependencies: fftw3, libpulse, x11, xft, Perl + cURL (lyrics) Optional runtime dependencies: fftw3, libpulse, x11 + xft + libpng (X11),
Perl + cURL (lyrics)
$ git clone --recursive https://git.janouch.name/p/nncmpp.git $ git clone --recursive https://git.janouch.name/p/nncmpp.git
$ mkdir nncmpp/build $ mkdir nncmpp/build

Submodule liberty updated: d01a1ff034...969a4cfc3e

View File

@@ -69,7 +69,7 @@ colors = {
scrollbar = "" scrollbar = ""
} }
streams = { streams = {
"dnbradio.com" = "http://www.dnbradio.com/hi.m3u" "dnbradio.com" = "https://dnbradio.com/hi.pls"
"BassDrive.com" = "http://bassdrive.com/v2/streams/BassDrive.pls" "BassDrive.com" = "http://bassdrive.com/v2/streams/BassDrive.pls"
} }
.... ....

View File

@@ -1148,8 +1148,8 @@ pulse_volume_status (struct pulse *self, struct str *s)
// Widget identification, mostly for mouse events. // Widget identification, mostly for mouse events.
enum enum
{ {
WIDGET_NONE = 0, WIDGET_BUTTON, WIDGET_GAUGE, WIDGET_TAB, WIDGET_SPECTRUM, WIDGET_NONE = 0, WIDGET_BUTTON, WIDGET_GAUGE, WIDGET_VOLUME,
WIDGET_LIST, WIDGET_SCROLLBAR, WIDGET_MESSAGE, WIDGET_TAB, WIDGET_SPECTRUM, WIDGET_LIST, WIDGET_SCROLLBAR, WIDGET_MESSAGE,
}; };
struct layout struct layout
@@ -1616,7 +1616,7 @@ app_append_layout (struct layout *l, struct layout *dest)
{ {
// Assuming there is no unclaimed vertical space. // Assuming there is no unclaimed vertical space.
LIST_FOR_EACH (struct widget, w, l->head) LIST_FOR_EACH (struct widget, w, l->head)
widget_move (w, 0, last->y + last->height - w->y); widget_move (w, 0, last->y + last->height);
last->next = l->head; last->next = l->head;
l->head->prev = last; l->head->prev = last;
@@ -1866,7 +1866,8 @@ app_layout_status (struct layout *out)
if (volume.len) if (volume.len)
{ {
app_push (&l, g.ui->padding (attrs[0], 1, 1)); app_push (&l, g.ui->padding (attrs[0], 1, 1));
app_push (&l, g.ui->label (attrs[0], volume.str)); app_push (&l, g.ui->label (attrs[0], volume.str))
->id = WIDGET_VOLUME;
} }
str_free (&volume); str_free (&volume);
@@ -1913,20 +1914,22 @@ app_layout_tabs (struct layout *out)
app_flush_layout (&l, out); app_flush_layout (&l, out);
} }
static void
app_layout_padding (chtype attrs, struct layout *out)
{
struct layout l = {};
app_push_fill (&l, g.ui->padding (attrs, 0, 0.125));
app_flush_layout (&l, out);
}
static void static void
app_layout_header (struct layout *out) app_layout_header (struct layout *out)
{ {
if (g.client.state == MPD_CONNECTED) if (g.client.state == MPD_CONNECTED)
{ {
struct layout lt = {}; app_layout_padding (APP_ATTR (NORMAL), out);
app_push_fill (&lt, g.ui->padding (APP_ATTR (NORMAL), 0, 0.125));
app_flush_layout (&lt, out);
app_layout_status (out); app_layout_status (out);
app_layout_padding (APP_ATTR (NORMAL), out);
struct layout lb = {};
app_push_fill (&lb, g.ui->padding (APP_ATTR (NORMAL), 0, 0.125));
app_flush_layout (&lb, out);
} }
app_layout_tabs (out); app_layout_tabs (out);
@@ -2136,8 +2139,10 @@ app_layout_mpd_status (struct layout *out)
static void static void
app_layout_statusbar (struct layout *out) app_layout_statusbar (struct layout *out)
{ {
struct layout l = {};
chtype attrs[2] = { APP_ATTR (NORMAL), APP_ATTR (HIGHLIGHT) }; chtype attrs[2] = { APP_ATTR (NORMAL), APP_ATTR (HIGHLIGHT) };
app_layout_padding (attrs[0], out);
struct layout l = {};
if (g.message) if (g.message)
{ {
app_push (&l, g.ui->padding (attrs[0], 0.25, 1)); app_push (&l, g.ui->padding (attrs[0], 0.25, 1));
@@ -2167,6 +2172,8 @@ app_layout_statusbar (struct layout *out)
app_layout_text ("Connecting to MPD...", attrs[0], out); app_layout_text ("Connecting to MPD...", attrs[0], out);
else if (g.client.state == MPD_DISCONNECTED) else if (g.client.state == MPD_DISCONNECTED)
app_layout_text ("Disconnected", attrs[0], out); app_layout_text ("Disconnected", attrs[0], out);
app_layout_padding (attrs[0], out);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -2619,12 +2626,12 @@ app_process_action (enum action action)
case ACTION_MPD_CONSUME: return app_mpd_toggle ("consume"); case ACTION_MPD_CONSUME: return app_mpd_toggle ("consume");
case ACTION_MPD_UPDATE_DB: return MPD_SIMPLE ("update"); case ACTION_MPD_UPDATE_DB: return MPD_SIMPLE ("update");
case ACTION_MPD_VOLUME_UP: return app_setvol (g.volume + 10); case ACTION_MPD_VOLUME_UP: return app_setvol (g.volume + 5);
case ACTION_MPD_VOLUME_DOWN: return app_setvol (g.volume - 10); case ACTION_MPD_VOLUME_DOWN: return app_setvol (g.volume - 5);
#ifdef WITH_PULSE #ifdef WITH_PULSE
case ACTION_PULSE_VOLUME_UP: return pulse_volume_set (&g.pulse, +10); case ACTION_PULSE_VOLUME_UP: return pulse_volume_set (&g.pulse, +5);
case ACTION_PULSE_VOLUME_DOWN: return pulse_volume_set (&g.pulse, -10); case ACTION_PULSE_VOLUME_DOWN: return pulse_volume_set (&g.pulse, -5);
case ACTION_PULSE_MUTE: return pulse_volume_mute (&g.pulse); case ACTION_PULSE_MUTE: return pulse_volume_mute (&g.pulse);
#endif // WITH_PULSE #endif // WITH_PULSE
@@ -2848,12 +2855,34 @@ app_process_mouse (termo_mouse_event_t type, int x, int y, int button,
g.ui_dragging = target->id; g.ui_dragging = target->id;
return app_process_left_mouse_click (target, x, y, modifiers); return app_process_left_mouse_click (target, x, y, modifiers);
case 4: case 4:
if (target->id == WIDGET_LIST) switch (target->id)
{
case WIDGET_LIST:
return app_process_action (ACTION_SCROLL_UP); return app_process_action (ACTION_SCROLL_UP);
case WIDGET_VOLUME:
return app_process_action (
#ifdef WITH_PULSE
g.pulse_control_requested ? ACTION_PULSE_VOLUME_UP :
#endif // WITH_PULSE
ACTION_MPD_VOLUME_UP);
case WIDGET_GAUGE:
return app_process_action (ACTION_MPD_FORWARD);
}
break; break;
case 5: case 5:
if (target->id == WIDGET_LIST) switch (target->id)
{
case WIDGET_LIST:
return app_process_action (ACTION_SCROLL_DOWN); return app_process_action (ACTION_SCROLL_DOWN);
case WIDGET_VOLUME:
return app_process_action (
#ifdef WITH_PULSE
g.pulse_control_requested ? ACTION_PULSE_VOLUME_DOWN :
#endif // WITH_PULSE
ACTION_MPD_VOLUME_DOWN);
case WIDGET_GAUGE:
return app_process_action (ACTION_MPD_BACKWARD);
}
break; break;
} }
return false; return false;
@@ -3814,8 +3843,13 @@ streams_tab_parse_playlist (const char *playlist, const char *content_type,
|| (content_type && is_content_type (content_type, "audio", "x-scpls"))) || (content_type && is_content_type (content_type, "audio", "x-scpls")))
extract_re = "^File[^=]*=(.+)"; extract_re = "^File[^=]*=(.+)";
else if ((lines.len && !strcasecmp_ascii (lines.vector[0], "#EXTM3U")) else if ((lines.len && !strcasecmp_ascii (lines.vector[0], "#EXTM3U"))
|| (content_type && is_content_type (content_type, "audio", "mpegurl"))
|| (content_type && is_content_type (content_type, "audio", "x-mpegurl"))) || (content_type && is_content_type (content_type, "audio", "x-mpegurl")))
extract_re = "^([^#].*)"; // This could be "^([^#].*)", however 1. we would need to resolve
// relative URIs, and 2. relative URIs probably mean a Media Playlist,
// which must be passed to MPD. The better thing to do here would be to
// reject anything with EXT-X-TARGETDURATION, and to resolve the URIs.
extract_re = "^(https?://.+)";
regex_t *re = regex_compile (extract_re, REG_EXTENDED, NULL); regex_t *re = regex_compile (extract_re, REG_EXTENDED, NULL);
hard_assert (re != NULL); hard_assert (re != NULL);
@@ -3838,7 +3872,7 @@ streams_tab_extract_links (struct str *data, const char *content_type,
} }
streams_tab_parse_playlist (data->str, content_type, out); streams_tab_parse_playlist (data->str, content_type, out);
return true; return out->len != 0;
} }
static void static void
@@ -4194,7 +4228,11 @@ info_tab_format_decode_toggle (char c)
case '\x01': case '\x01':
return A_BOLD; return A_BOLD;
case '\x02': case '\x02':
#ifdef A_ITALIC
return A_ITALIC; return A_ITALIC;
#else
return A_UNDERLINE;
#endif
default: default:
return 0; return 0;
} }