2
2
3
3
#include < fmt/core.h>
4
4
5
+ #include < chrono>
5
6
#include < optional>
6
7
#include < sstream>
7
8
#include < string>
@@ -26,6 +27,8 @@ Mpris::Mpris(const std::string& id, const Json::Value& config)
26
27
album_len_(-1 ),
27
28
title_len_(-1 ),
28
29
dynamic_len_(-1 ),
30
+ dynamic_scroll_(false ),
31
+ scroll_index_(0 ),
29
32
dynamic_prio_({" title" , " artist" , " album" , " position" , " length" }),
30
33
dynamic_order_({" title" , " artist" , " album" , " position" , " length" }),
31
34
dynamic_separator_(" - " ),
@@ -82,6 +85,9 @@ Mpris::Mpris(const std::string& id, const Json::Value& config)
82
85
if (config[" dynamic-len" ].isUInt ()) {
83
86
dynamic_len_ = config[" dynamic-len" ].asUInt ();
84
87
}
88
+ if (config_[" dynamic-scroll" ].isBool ()) {
89
+ dynamic_scroll_ = config[" dynamic-scroll" ].asBool ();
90
+ }
85
91
// "dynamic-priority" has been kept for backward compatibility
86
92
if (config_[" dynamic-importance-order" ].isArray () || config_[" dynamic-priority" ].isArray ()) {
87
93
dynamic_prio_.clear ();
@@ -167,7 +173,12 @@ Mpris::Mpris(const std::string& id, const Json::Value& config)
167
173
}
168
174
169
175
// allow setting an interval count that triggers periodic refreshes
170
- if (interval_.count () > 0 ) {
176
+ if (dynamic_scroll_) {
177
+ thread_ = [this ] {
178
+ dp.emit ();
179
+ thread_.sleep_for (std::chrono::seconds (2 ));
180
+ };
181
+ } else if (interval_.count () > 0 ) {
171
182
thread_ = [this ] {
172
183
dp.emit ();
173
184
thread_.sleep_for (interval_);
@@ -352,7 +363,8 @@ auto Mpris::getDynamicStr(const PlayerInfo& info, bool truncated, bool html) ->
352
363
}
353
364
}
354
365
355
- std::stringstream dynamic;
366
+ std::stringstream dynamic_first;
367
+ std::stringstream dynamic_second;
356
368
if (html) {
357
369
artist = Glib::Markup::escape_text (artist);
358
370
album = Glib::Markup::escape_text (album);
@@ -367,37 +379,63 @@ auto Mpris::getDynamicStr(const PlayerInfo& info, bool truncated, bool html) ->
367
379
if ((order == " artist" && showArtist) || (order == " album" && showAlbum) ||
368
380
(order == " title" && showTitle)) {
369
381
if (previousShown && previousOrder != " length" && previousOrder != " position" ) {
370
- dynamic << dynamic_separator_;
382
+ dynamic_first << dynamic_separator_;
371
383
}
372
384
373
385
if (order == " artist" ) {
374
- dynamic << artist;
386
+ dynamic_first << artist;
375
387
} else if (order == " album" ) {
376
- dynamic << album;
388
+ dynamic_first << album;
377
389
} else if (order == " title" ) {
378
- dynamic << title;
390
+ dynamic_first << title;
379
391
}
380
392
381
393
previousShown = true ;
382
394
} else if (order == " length" || order == " position" ) {
383
395
if (!lengthOrPositionShown && (showLength || showPos)) {
384
- if (html) dynamic << " <small>" ;
385
- if (previousShown) dynamic << ' ' ;
386
- dynamic << ' [' ;
396
+ if (previousShown) dynamic_second << ' ' ;
397
+ dynamic_second << ' [' ;
387
398
if (showPos) {
388
- dynamic << position;
389
- if (showLength) dynamic << ' /' ;
399
+ dynamic_second << position;
400
+ if (showLength) dynamic_second << ' /' ;
390
401
}
391
- if (showLength) dynamic << length;
392
- dynamic << ' ]' ;
393
- if (!dynamic.str ().empty ()) dynamic << ' ' ;
394
- if (html) dynamic << " </small>" ;
402
+ if (showLength) dynamic_second << length;
403
+ dynamic_second << ' ]' ;
404
+ if (!dynamic_second.str ().empty ()) dynamic_second << ' ' ;
395
405
lengthOrPositionShown = true ;
396
406
}
397
407
}
398
408
previousOrder = order;
399
409
}
400
- return dynamic.str ();
410
+
411
+ auto first = dynamic_first.str ();
412
+ auto second = dynamic_second.str ();
413
+
414
+ if ( scroll_index_ >= first.length () + second.length () ) {
415
+ scroll_index_ = 0 ;
416
+ } else if (scroll_index_ >= first.length () && scroll_index_ < first.length () + second.length ()) {
417
+ dynamic_first.str (" " );
418
+ dynamic_first.clear ();
419
+
420
+ dynamic_second.str (" " );
421
+ dynamic_second.clear ();
422
+
423
+ dynamic_second << second.substr ( first.length () - scroll_index_ );
424
+ } else {
425
+ dynamic_first.str (" " );
426
+ dynamic_first.clear ();
427
+
428
+ dynamic_first << first.substr ( scroll_index_ );
429
+ }
430
+ scroll_index_++;
431
+
432
+ if (html) {
433
+ dynamic_first << " <small>" ;
434
+ dynamic_second << " </small>" ;
435
+ }
436
+ dynamic_first << dynamic_second.str ();
437
+
438
+ return dynamic_first.str ();
401
439
}
402
440
403
441
auto Mpris::onPlayerNameAppeared (PlayerctlPlayerManager* manager, PlayerctlPlayerName* player_name,
@@ -626,7 +664,8 @@ bool Mpris::handleToggle(GdkEventButton* const& e) {
626
664
627
665
auto Mpris::update () -> void {
628
666
const auto now = std::chrono::system_clock::now ();
629
- if (now - last_update_ < interval_) return ;
667
+ auto delta = now - last_update_;
668
+ if (delta < interval_) return ;
630
669
last_update_ = now;
631
670
632
671
auto opt = getPlayerInfo ();
0 commit comments