Bug 480643

Summary: Update slideshow in strict intervals, aligned to UNIX epoch
Product: [Plasma] plasmashell Reporter: bastimeyer123
Component: Image WallpaperAssignee: Plasma Bugs List <plasma-bugs>
Status: RESOLVED FIXED    
Severity: wishlist CC: nate, notmart, qydwhotmail
Priority: NOR Keywords: multiscreen
Version: 5.27.10   
Target Milestone: 1.0   
Platform: unspecified   
OS: Linux   
Latest Commit: Version Fixed In: 6.3.0
Sentry Crash Report:

Description bastimeyer123 2024-01-31 23:19:03 UTC
SUMMARY
The wallpaper-image's slideshow timers are currently not synced between multiple desktops. This is due to desktops on each screen+activity having their own wallpaper configuration.

This causes issues though, which can be quite annoying. I think this could be solved by a rather simple workaround.

Please hear me out:

Issue 1:
Since slideshow timers depend on each desktop separately, this in turn means that slideshow times will only start when the desktop is shown/loaded for the first time. If you have multiple activities set up with each desktop having the same slideshow configuration applied, then the slideshow of the other activities will only start when those activities are activated for the first time, causing the wallpaper slideshow between those desktops to be out of sync.

Issue 2:
Similar to this, the slideshow timer starts on the first activity when the user logs in, which is an arbitrary point in time. Imagine a slideshow configuration where the image is supposed to change every 60 minutes. It would be nice to be able to tell when a full hour mark has passed, just by looking at the wallpaper on your second or third screen. This is currently only possible by timing the exact moment when logging into the Plasma desktop session, namely at the full hour mark. That slideshow timer value is of course just an example, but other values like 10 minutes have exactly the same issue.

Proposed solution:
Add a checkbox to the slideshow configuration which aligns the first slideshow timer with the beginning of the current day (or even 1970-01-01T00:00:00). Either increase or decrease the timer of the first wallpaper, so that wallpapers on all desktops where this option is enabled switch to the next wallpaper exactly at the same time, regardless when the specific desktop was loaded/activated for the first time. This implicitly fixes the desync issues between multiple desktops on multiple screens and activities without having a different synchronization mechanism implemented, and it also solves the second issue I mentioned. For example, a timer of 60 minutes would only ever switch the wallpaper at the full hour mark due to this option, and so would timers of 10 minutes, etc.

The calculation for that should be pretty straightforward. When starting the desktop's first slideshow timer, simply calculate the passed time since midnight of the current day (with the current timezone in mind) and then either increase or decrease the timer by the timer offset (passed time modulo timer duration):

```pseudo
diff = now - midnight_of_current_day;
offset = diff % timer_duration;

// make first timer longer
if (is_first_slideshow) timer_duration += timer_duration - offset;

// or make first timer shorter
if (is_first_slideshow) timer_duration -= offset;
```

Instead of just doing this for the first slideshow timer, this could of course also be done for every slideshow timer. This would fix the issue of slideshows becoming desynced on multiple screens on the same activity in certain cases (different issue in regards to the transition/animation performance and re-scheduling the timer after the transition has been completed).

I don't know C++ or Qt, and I also don't have any idea about the actual implementation of the slideshow, but this is the relevant part in the plasma-workspace repo:
https://invent.kde.org/plasma/plasma-workspace/-/blob/v5.27.10/wallpapers/image/plugin/imagebackend.cpp#L422

Thanks for considering this, I hope this makes sense.


SOFTWARE/OS VERSIONS
Linux/KDE Plasma: Arch Linux
KDE Plasma Version: 5.27.10 (irrelevant, also the case in today's 6.0-rc2)
KDE Frameworks Version: 5.114.0
Qt Version: 5.15.12
Comment 1 bastimeyer123 2024-02-07 00:26:09 UTC
I've applied the following patch to my plasma-workspace build, which works fine for me. This always aligns the timers with unix epoch and makes the slideshows shorter, depending on the time when the slideshows have started in these strict time intervals. This fixes the desync issues when loading a desktop on various screens/activities for the first time, restarting the slideshows, skipping wallpapers, or when there's a random delay during the wallpaper transition (different issue).

I don't really intend to open a pull request, because as said, I'm not familiar with C++/Qt/QML and the plasma-workspace setup, so I wouldn't be able to easily implement a config option for that or make other adjustments if requested.

Please have a look and see if these changes make sense to you. Thanks.

```diff
diff --git a/wallpapers/image/plugin/imagebackend.cpp b/wallpapers/image/plugin/imagebackend.cpp
index ce5b5aac5c..a3c1a531c8 100644
--- a/wallpapers/image/plugin/imagebackend.cpp
+++ b/wallpapers/image/plugin/imagebackend.cpp
@@ -14,6 +14,7 @@
 
 #include <math.h>
 
+#include <QDateTime>
 #include <QFileDialog>
 #include <QGuiApplication>
 #include <QImageReader>
@@ -446,8 +447,15 @@ void ImageBackend::nextSlide()
         m_currentSlide += 1;
         next = m_slideFilterModel->index(m_currentSlide, 0).data(ImageRoles::PackageNameRole).toString();
     }
+
+    QDateTime dtnow = QDateTime::currentDateTimeUtc();
+    qint64 now = dtnow.toMSecsSinceEpoch();
+    int delay_ms = m_delay * 1000;
+    int offset_ms = now % delay_ms;
+    int duration_ms = delay_ms - offset_ms;
+
     m_timer.stop();
-    m_timer.start(m_delay * 1000);
+    m_timer.start(duration_ms);
     if (next.isEmpty()) {
         m_image = QUrl::fromLocalFile(previousPath);
     } else {
```
Comment 2 Nate Graham 2024-08-30 22:45:20 UTC
It might make sense to do this without any option, TBH. So I wouldn't be so quick to assume your patch would be rejected.
Comment 3 bastimeyer123 2024-08-31 01:15:52 UTC
(In reply to Nate Graham from comment #2)
> It might make sense to do this without any option, TBH. So I wouldn't be so quick to assume your patch would be rejected.

As said, I'm not a C++/Qt dev, so I'm not familiar with it, as well as your workflows and other requirements, but I can see if I can submit a pull request with my changes later for you guys to review.

I've been using a slightly different patch for a few months now though, because the diff I've posted earlier had some surprising QTimer precision issues. It's been working well for me without any issues.
Comment 4 Bug Janitor Service 2024-08-31 03:05:11 UTC
A possibly relevant merge request was started @ https://invent.kde.org/plasma/plasma-workspace/-/merge_requests/4665
Comment 5 Nate Graham 2024-09-15 18:50:39 UTC
Implemented by Sebastian Meyer in https://invent.kde.org/plasma/plasma-workspace/-/commit/170a0c9e396028a564c1ee12a0a85207d6fa9fb3 for Plasma 6.3.0!