<div dir="ltr"><div><div><div><div><div><div><div>Hello Hans,<br><br>Finally I've found time to continue with this topic. Have sought for better solution and only come to improved previous one. <br><br></div><div><b>Requirements</b><br>


</div><br>Let's start with clarifying requirements.<br></div>req-1. As a user I want to have my desktop effect settings untouched if connected under normal conditions. </div>
req-2. As a user I want to have a few desktop effect settings disabled if connected under bad conditions.<br>The list of settings shall be configurable (as of now - wallpaper, animations, font smoothing) - if this isn't true in oVirt, I'd need work on it as well, because disabling all of them may reduce user experience to unacceptable level, resulting in feature becoming useless for many users.<br>



</div>Bad conditions can be identified by the user himself (via UI), or automatically - to be implemented later.<br></div><br></div>Both these stories taken together implicitly require:<br></div>req-3. After connecting under bad conditions and having effects disabled and then connecting under good conditions, as a user I want my desktop effect settings restored to their normal (previous) values.<br>



<div><div><div><div><br></div><div>Non-functional requirements:<br></div><div>req-4. Robustness. Crash-proof solution: upon vdagent crash, qemu crash or forced guest shutdown, correct state of effect settings must be restored for next session.<br>



</div><div>req-5. Simplicity. KISS, "Choose simplest possible implementation".<br><br></div><div>DEs to support:<br>req-6. Main: Gnome3, KDE4, Unity; Stretch goal: XFce, LXDE<br></div><div><br>
digression {<br>
Or do we need to talk about Window Managers here? Or display servers?<br>
</div><div>req-7. Solution shall be display server agnostic (X.Org, Wayland, XMir, Mir...).<br></div><div>req-8. Solution shall be window manager/shell agnostic (Mutter/Gnome Shell, KWin/Plasma, Compiz/Unity, Cinnamon probably - if we even bother of Ubutu, why don't respect Mint... etc).<br>



</div><div><br></div><div>Seems my lack of expertise in display system stacks in Linux is blocking me here; probably solution cannot be fully WM/shell agnostic. I'm going to try using DE abstraction level over WM specifics... if this makes sense.<br>



</div><div><br>All this profusion of DE/WM/Display servers nowadays results in a fact that without some standard implemented by them, it won't be possible to support all of them (and EWMH isn't even near the level of required interop...).<br>



</div><div>
</div><div>}<br><br></div><div>I know you'd like to weaken functional requirements if higher simplicity is possible. Could you please try specifying these weakened requirements - I cannot think up them myself.<br><br>
</div>

<div><b>Solution.</b><br></div></div></div></div><div class="gmail_extra">
<br></div><div class="gmail_extra">Given the fact there are so many different display systems in Linux, it isn't practically possible to support all of them. On the other hand, supporting only few and not providing any means for developers of other systems to add similar support themselves doesn't make sense to me. So I suggest following architecture:<br>

</div><div class="gmail_extra"><vdagent> --DBus-- <DE-specific display effects daemon> -- <DE API for effects><br></div><div class="gmail_extra">Basically vdagent (session, not system one) is to use DBus interface for toggling effects. The feature will be available only if the interface is implemented in the system. And this implementation should be DE-specific and maybe even part of DE. But as we (Spice) are concerned with major DEs, sample implementation will be provided for Gnome3, KDE4 and Unity. Eventually I'm going to open tickets for these systems to include the new DBus interface implementation in their systems (like gnome-desktop-daemon). This should generate a good feedback upon interface itself (i.e. need to create an interface acceptable for all these DEs).<br>

</div><div class="gmail_extra"><br></div><div class="gmail_extra">Interface (subject to renames):<br><br>bool SetMinimumDesktopBackground() // if already minimum, do nothing; save current desktop background settings; set solid background, saved color (if none, use default)<br>
</div><div class="gmail_extra">bool RestoreDesktopBackground() // if nothing is saved, do nothing; if solid desktop background, save the color; restore desktop background settings<br><br></div><div class="gmail_extra">bool SetMinimumFontSmooth() // if already minimum, do nothing; save current font smoothing settings; set antialiasing and hinting to the minimum yet acceptable level<br>
</div><div class="gmail_extra">bool RestoreFontSmooth() // if nothing is saved, do nothing; restore font smoothing settings<br><br></div><div class="gmail_extra">bool SetMinimumAnimations() // if already minimum, do nothing; save current animation settings; disable all decorative window animation effects, but keep meaningful animations like spinnings enabled (if possible)<br>
</div><div class="gmail_extra">bool RestoreAnimations() // if nothing is saved, do nothing; restore animation settings<br></div><div class="gmail_extra"><br><br></div><div class="gmail_extra">To satisfy functional requirements, vdagent is going to use the interface in following way:<br>
</div><div class="gmail_extra">1. If received VDAgentDisplayConfig with flag to disable an effect, call appropriate SetMinimumXXX()<br></div><div class="gmail_extra">2. If received VDAgentDisplayConfig without flag for an effect, call appropriate RestoreXXX()<br>
</div><div class="gmail_extra">One of these is always executed upon user's re-connect (unless failures in other system parts prevent delivery of VDAgentDisplayConfig message).<br></div><div class="gmail_extra">This is the same logic VDAgent for Windows is following currently. <br>
</div><div class="gmail_extra"><br></div><div class="gmail_extra">This approach makes the implementation in vdagent very simple and stateless. All effects managing logic is moved to DE-specific module. Robustness of vdagent is achieved as it is stateless and crashes can affect only current session. After vdagent restart (e.g. user re-login), correct state will be restored.<br>
<br></div><div class="gmail_extra">Robustness of display-effects-daemon is achieved via storing all the settings to DE-specific settings storage (persistent, like a file). The issues may arise only when crash/failure happens mid-transition. Correct recovery is achieved using 'transition started' and 'transition successfully ended' flags, IsRestored and IsMinimum, saved to the same storage as a first and last steps of transition. For example, when SetMinimumDesktopBackground() is called:<br>
</div><div class="gmail_extra"></div><div class="gmail_extra">1)if (storage.get(MinimumDesktopBackground, IsMinimum)) // check last transition status<br></div><div class="gmail_extra">  return true;<br></div><div class="gmail_extra">
2)if (!storage.set(StashedDesktopBackground, IsRestored, false)) // indicate start of transition<br></div><div class="gmail_extra">  return false;<br></div><div class="gmail_extra">3)if (!storage.copy(StashedDesktopBackground, DE.GetDesktopBackground()) // save current settings<br>
</div><div class="gmail_extra">   return false;<br></div><div class="gmail_extra">4)if (!DE.SetDesktopBackground(storage.get(MinimumDesktopBackground)) { // apply minimum settings<br></div><div class="gmail_extra">  if(DE.SetDesktopBackground(storage.get(StashedDesktopBackground))) // restore previous state if possible<br>
</div><div class="gmail_extra">    storage.set(StashedDesktopBackground, IsRestored, true);<br></div><div class="gmail_extra"></div><div class="gmail_extra">  return false;<br>}<br></div><div class="gmail_extra">5)if(!storage.set(MinimumDesktopBackground, IsMinimum, true)) // finalize the transition status<br>
</div><div class="gmail_extra">  return false;<br></div><div class="gmail_extra">retrun true;<br></div><div class="gmail_extra"><br></div><div class="gmail_extra">So in case of crash in any of steps 1-5, the next call of SetMinimumDesktopBackground() will be executed normally, and restore the correct state.<br>
</div><div class="gmail_extra">In case of failure to set new desktop background, attempt to restore to saved one will be made (if fails, state will be corrupted - "IsMinimum=false, IsRestored=false", so any next call of SetMinimum or Restore will be fully executed again, restoring the state if possible).<br>
</div><div class="gmail_extra"><br></div><div class="gmail_extra">Same for RestoreDesktopBackground():<br></div><div class="gmail_extra">1)if (storage.get(StashedDesktopBackground, IsRestored) // check last transaction status; by default, IsRestored == true, to catch the case when SetMinimum is never called.<br>
</div><div class="gmail_extra">  return true;<br></div><div class="gmail_extra"><div class="gmail_extra">2)if (!storage.set(MinimumDesktopBackground, IsMinimum, false)) // indicate start of transaction<br></div><div class="gmail_extra">
  return false;<br></div><div class="gmail_extra">3)if (!storage.set(MinimumDesktopBackground, color, DE.GetSolidDesktopBackgroundColor())) // save current background color<br></div><div class="gmail_extra">   return false;<br>
</div><div class="gmail_extra">4)if (!DE.SetDesktopBackground(storage.get(StashedDesktopBackground)) { // apply desktop background settings from stash<br></div><div class="gmail_extra">  if (DE.SetDesktopBackground(storage.get(MinimumDesktopBackground))) // restore previous state if possible<br>
</div><div class="gmail_extra">    storage.set(MinimumDesktopBackground, IsMinimum, true);<br></div><div class="gmail_extra">  return false;<br>}<br></div><div class="gmail_extra">5)if(!storage.set(StashedDesktopBackground, IsRestored, true)) // finalize the transaction status<br>
</div><div class="gmail_extra">  return false;<br></div><div class="gmail_extra">retrun true;<br></div><div class="gmail_extra"><br></div></div><div class="gmail_extra">Note: I'm by no means an expert in transition failure and recovery scenarios, I'd love your comments on this approach and welcome better solutions (mine is just an ad-hoc one). <br>
</div><div class="gmail_extra"><br></div>-- <br>Best regards,<br>Fedor
<div class="gmail_extra"><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Aug 6, 2013 at 10:16 AM, Hans de Goede <span dir="ltr"><<a href="mailto:hdegoede@redhat.com" target="_blank">hdegoede@redhat.com</a>></span> wrote:<br>


<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Hi,<div><br>
<br>
On 08/06/2013 12:47 AM, Fedor Lyakhov wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Hi,<br>
<br>
I've finally looked in vdagent for Windows and find out that it works<br>
differently. From a quick grasp I get following:<br>
Vdagent for Windows applies settings listed --disable-effects=... to<br>
current session via WinAPI call<br>
For settings not listed there, a reload is done - settings are<br>
restored to values from Windows registry of current active user (looks<br>
like API call that disables them doesn't affect register, at least<br>
that place).<br>
</blockquote>
<br></div>
This windows behavior sounds good, but not something we can easily do<br>
...<div><br>
<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
So my question is - should I stick with the plan (i), or go for the<br>
approach as at Windows vdagent (similar to my previous idea (ii))?<br>
Instead of implementing '--reset-effects' option I need to store<br>
values of settings somewhere before disabling them and restore them<br>
back when connected without setting listed in --disable-effects.<br>
Preserving user changes is a challenge. I think it should be doable<br>
though - at least via implementing similar environment to Windows case<br>
- vdagent will need to maintain an analog of Windows register storage<br>
for effect settings and track user changes of their real counterparts<br>
of Gnome settings... Seems doable using GSettings.<br>
</blockquote>
<br></div>
Doable yes, but what if the agent crashes, or the machine is forced off<br>
while agent settings are in force, will the agent detects it has crashed<br>
and restore the user settings from some sort of non volatile storage?<br>
<br>
This is likely doable (ignoring possible races wrt crash scenarios), but<br>
not very KISS. I would like to see a much more KISS solution if possible,<br>
even if that means it will be less nice.<br>
<br>
Regards,<br>
<br>
Hans<br>
</blockquote></div><br></div></div>