diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-10-18 08:01:08 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-10-18 08:01:08 +0300 |
commit | b31764ed2a12d27053dba8ec7a6780f730d426e5 (patch) | |
tree | 2db1e94cde259c7fb42ea34d21b010ffa37b9872 /src/ui/documentwidget.c | |
parent | 6329646833a719097ef2e7eec42665ab0437d91f (diff) |
DocumentWidget: Improved audio player UI refresh
There is no need to prioritize animation smoothness when it comes to audio players. Just post timer events at a relaxed 15 Hz when active players are visible.
Fixes an issue on macOS (and possibly other platforms) where moving the window was very glitchy if a player was active.
Diffstat (limited to 'src/ui/documentwidget.c')
-rw-r--r-- | src/ui/documentwidget.c | 70 |
1 files changed, 58 insertions, 12 deletions
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index 85c17a5b..827e2810 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c | |||
@@ -143,7 +143,7 @@ struct Impl_OutlineItem { | |||
143 | 143 | ||
144 | /*----------------------------------------------------------------------------------------------*/ | 144 | /*----------------------------------------------------------------------------------------------*/ |
145 | 145 | ||
146 | static void animatePlayingAudio_DocumentWidget_(void *); | 146 | static void animatePlayingAudio_DocumentWidget_(iDocumentWidget *d); |
147 | 147 | ||
148 | static const int smoothSpeed_DocumentWidget_ = 120; /* unit: gap_Text per second */ | 148 | static const int smoothSpeed_DocumentWidget_ = 120; /* unit: gap_Text per second */ |
149 | static const int outlineMinWidth_DocumentWdiget_ = 45; /* times gap_UI */ | 149 | static const int outlineMinWidth_DocumentWdiget_ = 45; /* times gap_UI */ |
@@ -181,6 +181,7 @@ struct Impl_DocumentWidget { | |||
181 | iPtrArray visiblePlayers; /* currently playing audio */ | 181 | iPtrArray visiblePlayers; /* currently playing audio */ |
182 | const iGmRun * grabbedPlayer; /* currently adjusting volume in a player */ | 182 | const iGmRun * grabbedPlayer; /* currently adjusting volume in a player */ |
183 | float grabbedStartVolume; | 183 | float grabbedStartVolume; |
184 | int playerTimer; | ||
184 | const iGmRun * hoverLink; | 185 | const iGmRun * hoverLink; |
185 | const iGmRun * contextLink; | 186 | const iGmRun * contextLink; |
186 | iBool noHoverWhileScrolling; | 187 | iBool noHoverWhileScrolling; |
@@ -248,6 +249,7 @@ void init_DocumentWidget(iDocumentWidget *d) { | |||
248 | init_PtrArray(&d->visibleLinks); | 249 | init_PtrArray(&d->visibleLinks); |
249 | init_PtrArray(&d->visiblePlayers); | 250 | init_PtrArray(&d->visiblePlayers); |
250 | d->grabbedPlayer = NULL; | 251 | d->grabbedPlayer = NULL; |
252 | d->playerTimer = 0; | ||
251 | init_Click(&d->click, d, SDL_BUTTON_LEFT); | 253 | init_Click(&d->click, d, SDL_BUTTON_LEFT); |
252 | addChild_Widget(w, iClob(d->scroll = new_ScrollWidget())); | 254 | addChild_Widget(w, iClob(d->scroll = new_ScrollWidget())); |
253 | d->menu = NULL; /* created when clicking */ | 255 | d->menu = NULL; /* created when clicking */ |
@@ -261,7 +263,6 @@ void init_DocumentWidget(iDocumentWidget *d) { | |||
261 | } | 263 | } |
262 | 264 | ||
263 | void deinit_DocumentWidget(iDocumentWidget *d) { | 265 | void deinit_DocumentWidget(iDocumentWidget *d) { |
264 | removeTicker_App(animatePlayingAudio_DocumentWidget_, d); | ||
265 | delete_VisBuf(d->visBuf); | 266 | delete_VisBuf(d->visBuf); |
266 | delete_PtrSet(d->invalidRuns); | 267 | delete_PtrSet(d->invalidRuns); |
267 | deinit_Array(&d->outline); | 268 | deinit_Array(&d->outline); |
@@ -270,6 +271,9 @@ void deinit_DocumentWidget(iDocumentWidget *d) { | |||
270 | deinit_Block(&d->sourceContent); | 271 | deinit_Block(&d->sourceContent); |
271 | deinit_String(&d->sourceMime); | 272 | deinit_String(&d->sourceMime); |
272 | iRelease(d->doc); | 273 | iRelease(d->doc); |
274 | if (d->playerTimer) { | ||
275 | SDL_RemoveTimer(d->playerTimer); | ||
276 | } | ||
273 | deinit_PtrArray(&d->visiblePlayers); | 277 | deinit_PtrArray(&d->visiblePlayers); |
274 | deinit_PtrArray(&d->visibleLinks); | 278 | deinit_PtrArray(&d->visibleLinks); |
275 | delete_String(d->certSubject); | 279 | delete_String(d->certSubject); |
@@ -455,21 +459,58 @@ static void updateOutlineOpacity_DocumentWidget_(iDocumentWidget *d) { | |||
455 | animate_DocumentWidget_(d); | 459 | animate_DocumentWidget_(d); |
456 | } | 460 | } |
457 | 461 | ||
458 | static void animatePlayingAudio_DocumentWidget_(void *widget) { | 462 | static uint32_t playerUpdateInterval_DocumentWidget_(const iDocumentWidget *d) { |
459 | iDocumentWidget *d = widget; | 463 | if (document_App() != d) { |
460 | if (document_App() != d) return; | 464 | return 0; |
465 | } | ||
466 | uint32_t interval = 0; | ||
461 | iConstForEach(PtrArray, i, &d->visiblePlayers) { | 467 | iConstForEach(PtrArray, i, &d->visiblePlayers) { |
462 | const iGmRun *run = i.ptr; | 468 | const iGmRun *run = i.ptr; |
463 | iPlayer * plr = audioPlayer_Media(media_GmDocument(d->doc), run->audioId); | 469 | iPlayer * plr = audioPlayer_Media(media_GmDocument(d->doc), run->audioId); |
464 | if (idleTimeMs_Player(plr) > 3000 && ~flags_Player(plr) & volumeGrabbed_PlayerFlag && | 470 | if (flags_Player(plr) & adjustingVolume_PlayerFlag || |
465 | flags_Player(plr) & adjustingVolume_PlayerFlag) { | 471 | (isStarted_Player(plr) && !isPaused_Player(plr))) { |
466 | setFlags_Player(plr, adjustingVolume_PlayerFlag, iFalse); | 472 | interval = 1000 / 15; |
467 | refresh_Widget(d); | 473 | } |
474 | } | ||
475 | return interval; | ||
476 | } | ||
477 | |||
478 | static uint32_t postPlayerUpdate_DocumentWidget_(uint32_t interval, void *context) { | ||
479 | /* Called in timer thread; don't access the widget. */ | ||
480 | iUnused(context); | ||
481 | postCommand_App("media.player.update"); | ||
482 | return interval; | ||
483 | } | ||
484 | |||
485 | static void updateAudioPlayers_DocumentWidget_(iDocumentWidget *d) { | ||
486 | if (document_App() == d) { | ||
487 | refresh_Widget(d); | ||
488 | iConstForEach(PtrArray, i, &d->visiblePlayers) { | ||
489 | const iGmRun *run = i.ptr; | ||
490 | iPlayer * plr = audioPlayer_Media(media_GmDocument(d->doc), run->audioId); | ||
491 | if (idleTimeMs_Player(plr) > 3000 && ~flags_Player(plr) & volumeGrabbed_PlayerFlag && | ||
492 | flags_Player(plr) & adjustingVolume_PlayerFlag) { | ||
493 | setFlags_Player(plr, adjustingVolume_PlayerFlag, iFalse); | ||
494 | } | ||
468 | } | 495 | } |
469 | if (isStarted_Player(plr) && !isPaused_Player(plr)) { | 496 | } |
470 | refresh_Widget(d); | 497 | if (d->playerTimer && playerUpdateInterval_DocumentWidget_(d) == 0) { |
471 | addTicker_App(animatePlayingAudio_DocumentWidget_, d); | 498 | SDL_RemoveTimer(d->playerTimer); |
499 | d->playerTimer = 0; | ||
500 | } | ||
501 | } | ||
502 | |||
503 | static void animatePlayingAudio_DocumentWidget_(iDocumentWidget *d) { | ||
504 | if (document_App() != d) { | ||
505 | if (d->playerTimer) { | ||
506 | SDL_RemoveTimer(d->playerTimer); | ||
507 | d->playerTimer = 0; | ||
472 | } | 508 | } |
509 | return; | ||
510 | } | ||
511 | uint32_t interval = playerUpdateInterval_DocumentWidget_(d); | ||
512 | if (interval && !d->playerTimer) { | ||
513 | d->playerTimer = SDL_AddTimer(interval, postPlayerUpdate_DocumentWidget_, d); | ||
473 | } | 514 | } |
474 | } | 515 | } |
475 | 516 | ||
@@ -1349,6 +1390,10 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) | |||
1349 | } | 1390 | } |
1350 | } | 1391 | } |
1351 | } | 1392 | } |
1393 | else if (equal_Command(cmd, "media.player.update")) { | ||
1394 | updateAudioPlayers_DocumentWidget_(d); | ||
1395 | return iFalse; | ||
1396 | } | ||
1352 | else if (equal_Command(cmd, "document.stop") && document_App() == d) { | 1397 | else if (equal_Command(cmd, "document.stop") && document_App() == d) { |
1353 | if (d->request) { | 1398 | if (d->request) { |
1354 | postCommandf_App( | 1399 | postCommandf_App( |
@@ -1622,6 +1667,7 @@ static iBool processAudioPlayerEvents_DocumentWidget_(iDocumentWidget *d, const | |||
1622 | setFlags_Player(plr, | 1667 | setFlags_Player(plr, |
1623 | adjustingVolume_PlayerFlag, | 1668 | adjustingVolume_PlayerFlag, |
1624 | !(flags_Player(plr) & adjustingVolume_PlayerFlag)); | 1669 | !(flags_Player(plr) & adjustingVolume_PlayerFlag)); |
1670 | animatePlayingAudio_DocumentWidget_(d); | ||
1625 | refresh_Widget(d); | 1671 | refresh_Widget(d); |
1626 | return iTrue; | 1672 | return iTrue; |
1627 | } | 1673 | } |