[Spice-commits] Branch '0.6' - 2 commits - client/x11

Hans de Goede jwrdegoede at kemper.freedesktop.org
Mon Nov 22 10:45:16 PST 2010


 client/x11/red_window.cpp |   16 ++++++++++++++++
 1 file changed, 16 insertions(+)

New commits:
commit 0e7a79ae11a905cee128c2429a7738fe43e30586
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Mon Nov 22 16:09:15 2010 +0100

    spicec-x11: Fix modifier keys getting stuck (rhbz#655048)
    
    Currently modifier keys (ctrl, alt) can get stuck when using the x11 client.
    To reproduce under gnome:
    -focus the client window without causing it to grab the keyborad (click on
     the title bar not the window)
    -press crlt + alt + right arrow to switch virtual desktop
    -press crlt + alt + left arrow to switch back
    -notice ctrl + alt are stuck pressed
    
    What is happening here is:
    -We get a focus out event, caused by the hotkey combi key grab, focus event
     notify mode == NotifyGrab, and release all keys -> good
    -We get another focus out event, as we really loose the focus.
     notify mode == NotifyWhileGrabbed, which we ignore as we already lost
     focus before
    -We get a focus in event, as the focus is returning to us, but we don't
     really have the focus yet, as the hotkey combi key grab is still active
     (ie ctrl + alt are still pressed).
     We now sync the vm's modifier key state with the current X-server state,
     telling the vm ctrl + alt are pressed. Note we do this by directly reading
     the X-server keyboard status, we are not getting any key press events from the
     X-server -> bad
    -We get another focus in event, as we really get the focus back,
     notify mode == NotifyUngrab. We ignore this one as already have gained the
     focus before. If we were to sync the vm modifier state here, all would be
     well we would no longer see the modifier keys pressed, or if we would we
     would get a release event when they get released (testing has shown both).
    
    The solution here is to ignore the first focus in event, and do the modifier
    sync on the second focus in event, or more in general to ignore focus events
    where notify mode == NotifyWhileGrabbed.

diff --git a/client/x11/red_window.cpp b/client/x11/red_window.cpp
index c50e307..6e8cd58 100644
--- a/client/x11/red_window.cpp
+++ b/client/x11/red_window.cpp
@@ -866,6 +866,11 @@ void RedWindow_p::win_proc(XEvent& event)
         break;
     }
     case FocusIn:
+        /* Ignore focus events caused by grabbed (hotkeys) */
+        if (event.xfocus.mode == NotifyWhileGrabbed) {
+            break;
+        }
+
         if (event.xany.serial < focus_serial) {
             DBG(0, "Ignored FocusIn win=%p (serial=%d, Last foucs serial=%d)",
                    red_window,  event.xany.serial, focus_serial);
@@ -886,6 +891,11 @@ void RedWindow_p::win_proc(XEvent& event)
         }
         break;
     case FocusOut:
+        /* Ignore focus events caused by grabbed (hotkeys) */
+        if (event.xfocus.mode == NotifyWhileGrabbed) {
+            break;
+        }
+
         if (event.xany.serial <= focus_serial) {
             DBG(0, "Ignored FocusOut win=%p (serial=%d, Last foucs serial=%d)",
                    red_window, event.xany.serial, focus_serial);
commit c5a903b6655f4f6dacb333fa897d60636aa92d58
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Wed Nov 17 12:19:41 2010 +0100

    spicec-x11: Add a few missing XLockDisplay calls (rhbz#654265)
    
    The XIM functions end up waiting for a reply from the server, so they
    need locking around them. Idem for the XLookupString call.

diff --git a/client/x11/red_window.cpp b/client/x11/red_window.cpp
index c3ee1b0..c50e307 100644
--- a/client/x11/red_window.cpp
+++ b/client/x11/red_window.cpp
@@ -733,7 +733,9 @@ void RedWindow_p::handle_key_press_event(RedWindow& window, XKeyEvent* event)
 
     if (x_input_context != NULL) {
         for (;;) {
+            XLockDisplay(x_display);
             len = XwcLookupString(x_input_context, event, utf32_buf, buf_size, &key_sym, &status);
+            XUnlockDisplay(x_display);
             if (status != XBufferOverflow) {
                 break;
             }
@@ -767,7 +769,9 @@ void RedWindow_p::handle_key_press_event(RedWindow& window, XKeyEvent* event)
         unsigned char buffer[16];
         int i;
 
+        XLockDisplay(x_display);
         len = XLookupString(event, (char *)buffer, sizeof(buffer), NULL, NULL);
+        XUnlockDisplay(x_display);
         for (i = 0; i < len; i++) {
             window.get_listener().on_char((uint32_t)buffer[i]);
         }
@@ -2135,7 +2139,9 @@ void RedWindow::on_focus_in()
     }
     _focused = true;
     if (x_input_context) {
+        XLockDisplay(x_display);
         XwcResetIC(x_input_context);
+        XUnlockDisplay(x_display);
     }
     XPlatform::on_focus_in();
     get_listener().on_activate();


More information about the Spice-commits mailing list