Note: This bug is displayed in read-only format because the product is no longer active in Red Hat Bugzilla.
RHEL Engineering is moving the tracking of its product development work on RHEL 6 through RHEL 9 to Red Hat Jira (issues.redhat.com). If you're a Red Hat customer, please continue to file support cases via the Red Hat customer portal. If you're not, please head to the "RHEL project" in Red Hat Jira and file new tickets here. Individual Bugzilla bugs in the statuses "NEW", "ASSIGNED", and "POST" are being migrated throughout September 2023. Bugs of Red Hat partners with an assigned Engineering Partner Manager (EPM) are migrated in late September as per pre-agreed dates. Bugs against components "kernel", "kernel-rt", and "kpatch" are only migrated if still in "NEW" or "ASSIGNED". If you cannot log in to RH Jira, please consult article #7032570. That failing, please send an e-mail to the RH Jira admins at rh-issues@redhat.com to troubleshoot your issue as a user management inquiry. The email creates a ServiceNow ticket with Red Hat. Individual Bugzilla bugs that are migrated will be moved to status "CLOSED", resolution "MIGRATED", and set with "MigratedToJIRA" in "Keywords". The link to the successor Jira issue will be found under "Links", have a little "two-footprint" icon next to it, and direct you to the "RHEL project" in Red Hat Jira (issue links are of type "https://issues.redhat.com/browse/RHEL-XXXX", where "X" is a digit). This same link will be available in a blue banner at the top of the page informing you that that bug has been migrated.

Bug 927357

Summary: virt-manager: ungrab mouse pointer when machine goes idle, so screen saver can kick in
Product: Red Hat Enterprise Linux 6 Reporter: Cole Robinson <crobinso>
Component: virt-managerAssignee: Martin Kletzander <mkletzan>
Status: CLOSED CURRENTRELEASE QA Contact: Virtualization Bugs <virt-bugs>
Severity: medium Docs Contact:
Priority: medium    
Version: 6.5CC: acathrow, acavalla, an.euroford, ayadav, codong, crobinso, cwei, dallan, gscrivan, jn, lcui, mjenner, mkletzan, mzhan, pkrempa, rstrode, sgraf, tzheng
Target Milestone: rcKeywords: Reopened
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
: 947295 (view as bug list) Environment:
Last Closed: 2014-07-16 13:51:52 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 947295    

Description Cole Robinson 2013-03-25 18:19:33 UTC
This comes from:

https://bugzilla.redhat.com/show_bug.cgi?id=710966

If VNC has the pointer grabbed, the host screensaver won't kick in no matter how long we wait. Fixing this at the X level is unlikely to happen anytime soon but there are customers that want a fix. It was suggested in that bug that virt-manager could work around this:

> We could probably fix the virt-manager specific case by changing it to
> listen for
> 
> org.gnome.SessionManager.Presence.StatusChange and having it release its
> grab when status goes to IDLE.

Comment 1 Ray Strode [halfline] 2013-03-26 15:11:56 UTC
*** Bug 834785 has been marked as a duplicate of this bug. ***

Comment 4 CongDong 2013-04-02 05:01:36 UTC
I can reproduce this bug. 
If your pointer is in guest's window, the screensaver of host can't start, and I found if you keep your pointer in guest longer than the time set up in screensaver, then you move the pointer to host, screensaver will start immediatelly.

Comment 5 Ray Strode [halfline] 2013-06-05 12:26:59 UTC
*** Bug 923514 has been marked as a duplicate of this bug. ***

Comment 6 Martin Kletzander 2013-08-26 14:31:58 UTC
I coded in listening and reactions for the signal from screensaver.  Unfortunately, screensaver sends this signal once before its trying to do the lock and does not retry if it fails.  Thus there's a race and if it tries to lock before we manage to ungrab the pointer, it fails.  I happened only once to me that the lock was successful.

I see four ways out of this (but only one meing effective):

 1) We can dup this bug on gnome-screensaver saying that we want it to retry the lock until successful (this will probably not be acted upon as that's probably not what they intended the signal for, even though there is different one for successful (de)activation of the lock).

 2) We can force the lock after ungrabbing the pointer (this will, however, keep the "unsuccessful lock" message appearing)

 3) We can check with X Server about how long the user has been idle and ungrab the pointer at intervals (that makes another race pop up and it might not be reliable)

 4) We can do it like virt-viewer does -- don't grab the pointer when it's not needed

I, personally, like the fourth option.  When creating a Viewer display, we can check whether the domain has tablet device, probably check that the mouse is set to "client" mode (in case of spice) and then set whether grabbing is needed at all.  This would effectively mean that the window behaves like a normal one.  The only thing I'm not sure about is whether all keys would be transferred to the guest (hotkeys settings, etc.) and thus whether this is acceptable change for users.

I'm rather asking here as the audience here is more related to the issue.  In case of insufficient information found here, I'll raise this question upstream.

Comment 7 John Newbigin 2013-08-27 00:27:15 UTC
I am glad someone is working on this. Here is my 2c:

I was planning to code up #3 for our in-house use. My plan was that if the mouse has been idle for x seconds, release & re-grab the pointer to allow the screensaver a chance to do it's thing. As you point out it may well still be a race.

I also use a number of vnc viewers and none have this kind of problem. I am guessing that they operate like #4 which does seem the most useful.

Comment 8 Cole Robinson 2013-08-27 15:16:09 UTC
I think virt-manager should try to match virt-viewer behavior as much as possible. virt-viewer gets more attention from people who care about particular console behavior, is multi platform, etc. so it's probably safest to just do what they do.

Comment 9 Martin Kletzander 2013-08-29 08:03:33 UTC
Some more info I've found out.

Not only the grab depends on mouse mode, it is also dynamically changing according to the client<->server communication (both can change it on-the-fly).  Both virt-viewer and virt-manager *already exhibit* the same behaviour when it comes to mouse/keyboard grabbing.  The experience depends highly on guest OS.

When one tries to create a machine with tablet device, spice graphics, qxl video, install fedora inside and run the domain, then immediately after start the grab works as usual.  After kernel is loaded, the mode is changed and grab is no longer needed as the guest supports all the devices.  This however works with vnc, cirrus and no tablet as well, but not before X start up.  I suspect graphic and input drivers are those who change the behaviour.  I'll ask around in spice/qemu circles about details.

Comment 10 Martin Kletzander 2013-08-29 08:08:45 UTC
I can't find better person to ask about gnome-screensaver, but feel free to redirect me.  Do you think the case #1 mentioned in comment #6 would be possible to at least as a workaround?  To summarize that, could gnome-screensaver try to lock the screen let's say every second (or at least a few times) and not just once?  We are able to react on DBus event, even though this is not the cleanest design.  Thanks in advance.

Comment 11 Ray Strode [halfline] 2013-08-29 17:19:41 UTC
i'm a little confused by comment 6.

Looking in the code I see gnome-screensaver connects to the org.gnome.SessionManager.Presence.StatusChange signal in gs-watcher-x11.c connect_presence_watcher:


        watcher->priv->presence_proxy = dbus_g_proxy_new_for_name_owner (bus,•
                                                                         "org.gnome.SessionManager",•                                                         
                                                                         "/org/gnome/SessionManager/Presence",•
                                                                         "org.gnome.SessionManager.Presence",•                                                
                                                                         &error);•                                                                            
        if (watcher->priv->presence_proxy != NULL) {•                         
                DBusGProxy *proxy;•
•                                        
                dbus_g_proxy_add_signal (watcher->priv->presence_proxy,•      
                                         "StatusChanged",•                    
                                         G_TYPE_UINT,•
                                         G_TYPE_INVALID);•
                dbus_g_proxy_connect_signal (watcher->priv->presence_proxy,•
                                             "StatusChanged",•                
                                             G_CALLBACK (on_presence_status_changed),•         
                                             watcher,•                        
                                             NULL);•

When it gets the signal on_presence_status_changed is called which (roughly) does:

   watcher->priv->idle_id = g_timeout_add (10000,•
                                           (GSourceFunc)on_idle_timeout,
                                           watcher);•

on_idle_timeout does:

        res = _gs_watcher_set_session_idle (watcher, TRUE);•

which trickles down to through a few layers of code until ultimately the screen gets locked.  So the screen isn't locked for a full 10 seconds after gnome-session has said the user is idle.  Are you saying it takes virt-manager more than 10 seconds to react to the signal and drop its grab, and at the 10 second mark gnome-screensaver tries to take a grab and fails?  That doesn't make sense to me either because gnome-screensaver does try to lock in a loop.  See comment 4.

Do you mind posting your in-progress patches for me to look at?

Comment 12 Ray Strode [halfline] 2013-08-29 17:44:17 UTC
as a proof of concept of what i was proposing you can do this little experiment, which i just tried:

1) run gnome-terminal --disable-factory . Pretend this is virt-manager
2) open a menu and leave it open and wait.
3) notice the screen doesn't lock as long as the menu is open.  Pretend the menu being open is virt-manage when it's grabbed
4) in the terminal type this:

$ dbus-monitor --session "type='signal',interface='org.gnome.SessionManager.Presence'" | while read line; do echo $line; echo $line |grep -q "uint32 3" && echo "IDLE NOW SCREENAVER WILL LOCK IN 10 SECONDS" && xkill -id $WINDOWID ; done

5) wait the idle timeout.  Notice the terminal gets killed and 10 seconds later the screen locks.

what that snippet is doing is listening for the org.gnome.SessionManager.Presence.StatusChanged signal and reacting when it changes to 3 (IDLE), by killing the window it's running in.  i used --disable-factory in step 1, so it won't kill any other terminals at the same time.

Comment 13 Ray Strode [halfline] 2013-08-29 17:45:46 UTC
between step 4 and step 5 there should be a "4.5) repeat step 2"

Comment 14 Martin Kletzander 2013-09-02 13:30:46 UTC
(In reply to Ray Strode [halfline] from comment #12)
I did what you said and managed to get to the same point as with virt-manager.  After the timeout (1 minute on my system, acutally a testing VM), I received a message saying "Unable to lock: Lock was blocked by an application" and at the same time the terminal window was destroyed, there was not just no 10 second timeout, but no noticeable delay at all.

Note: "--disable-factory" hadn't worked for me, but that shouldn't change anything with the fact that I reproduced the behaviour with your procedure.

Is there something I might be missing?

Comment 15 Ray Strode [halfline] 2013-09-04 13:20:42 UTC
are you running RHEL 6?

Comment 16 Martin Kletzander 2013-09-04 13:26:29 UTC
I'm testing this on F19 because I wanted to fix it first upstream.  Haven't thought that this might be so different.  I'll test it on RHEL 6, but does that mean it won't work on newer systems?

Comment 17 Ray Strode [halfline] 2013-09-04 14:21:03 UTC
well F19 doesn't have gnome-screensaver. It uses gnome-shell to handle screenlocking. As you've observed, gnome-shell pops up a notification if screen lock fails rather than trying in a loop.

If you want a more upstreamable workaround that's less platform specific, you could watch when the XSync IDLETIME counter hits some specific threshhold then drop grabs, and reacquire the grabs when the counter drops to 0. As long as the threshold value is small enough (less than the screensaver lock timeout) you'll side-step the issues you're seeing.

Comment 18 Ray Strode [halfline] 2013-09-04 14:28:48 UTC
For reference here is code that works with XSync counters:

https://git.gnome.org/browse/gnome-session/tree/gnome-session/gs-idle-monitor.c?h=gnome-2-32