This started as one bug fix, but after a lot of testing and fiddling it turned into three.
Note: This fix is no longer applicable - a commit has been added to revert it as Marco Martin already has an MR with a better fix for this problem. The other two bug fixes are still applicable.
In AppletsLayout::AppletsLayout, there is code designed to relayout the user's widgets in the event of a screen resolution change. While this helps keep the widgets in better positions during an intentional resolution change, it causes serious problems if a resolution change occurs automatically while KDE is still starting (like can happen with virtual machines, some NVIDIA cards (at least my NVIDIA card anyway), and possibly other setups). I believe when an early-startup resolution change occurs, the widgets end up getting scrambled around as described in https://bugs.kde.org/show_bug.cgi?id=413645.
To work around this issue, all that is necessary is to create a flag in the AppletsLayout object for detecting whether the relevant relayout code is being executed for the first time. If so, any screen resolution changes are ignored. After this first run, screen resolution changes are again taken into consideration for laying out widgets. This allows a resolution change during early KDE startup to be ignored, while still preserving the useful behavior of the relayout code.
This bug was reported as https://bugs.kde.org/show_bug.cgi?id=413645.
Sometimes, after a resolution change or logout-login cycle, the widgets would get moved around in a different way than in Bug 1. The exact way to trigger this, I'm not sure, but the problems ceased to occur after removing a heuristic layout function call. I'm not exactly sure what the function was supposed to do or where it was even defined (I looked!), but removing it entirely seemed to have made everything behave itself better.
If the user intentionally changed their screen resolution to a size that they had not previously set their screen to, the widgets would be laid out in a new pattern so as to be approximately where they were supposed to be. However, the widget positions would not be saved after this happened, so if the user then proceeded to log out and log back in, the widgets would end up in strange places (I think probably from KDE loading the widget positions for a different resolution and trying to put them there). To solve this, the code now saves the widget layout immediately after repositioning the widgets after a resolution change. This makes the widgets stay where they are supposed to be after logging out and logging back in.
Note that all of these changes were only tested in a GNOME Boxes VM with a single screen. I do not yet know how this code behaves in a multi-monitor setup, so it should probably be tested there, too.