Commits

Anonymous committed eb11fed

changeset: 2637:899040b75349
tag: tip
user: Younes Manton <younes.m@gmail.com>
date: Fri Apr 27 15:25:45 2012 -0400
summary: Use X server auto-repeat detection when possible.

Comments (0)

Files changed (1)

pyglet/window/xlib/__init__.py

         ('status', c_uint32)
     ]
 
+# XXX: wraptypes can't parse the header this function is in yet
+XkbSetDetectableAutoRepeat = xlib._lib.XkbSetDetectableAutoRepeat
+XkbSetDetectableAutoRepeat.restype = c_int
+XkbSetDetectableAutoRepeat.argtypes = [POINTER(xlib.Display), c_int, POINTER(c_int)]
+_can_detect_autorepeat = None
+
 XA_CARDINAL = 6 # Xatom.h:14
 
 # Do we have the November 2000 UTF8 extension?
                     self._event_handlers[message] = func 
 
         super(XlibWindow, self).__init__(*args, **kwargs)
-        
+
+        global _can_detect_autorepeat
+        if _can_detect_autorepeat == None:
+            supported_rtrn = c_int()
+            _can_detect_autorepeat = XkbSetDetectableAutoRepeat(self.display._display, c_int(1), byref(supported_rtrn))
+        if _can_detect_autorepeat:
+            self.pressed_keys = set()
+
     def _recreate(self, changes):
         # If flipping to/from fullscreen, need to recreate the window.  (This
         # is the case with both override_redirect method and
     @XlibEventHandler(xlib.KeyPress)
     @XlibEventHandler(xlib.KeyRelease)
     def _event_key_view(self, ev):
-        if ev.type == xlib.KeyRelease:
+        # Try to detect autorepeat ourselves if the server doesn't support it
+        # XXX: Doesn't always work, better off letting the server do it
+        global _can_detect_autorepeat
+        if not _can_detect_autorepeat and ev.type == xlib.KeyRelease:
             # Look in the queue for a matching KeyPress with same timestamp,
             # indicating an auto-repeat rather than actual key event.
             saved = []
         motion = self._event_text_motion(symbol, modifiers)
 
         if ev.type == xlib.KeyPress:
-            if symbol:
+            if symbol and (not _can_detect_autorepeat or symbol not in self.pressed_keys):
                 self.dispatch_event('on_key_press', symbol, modifiers)
+                if _can_detect_autorepeat:
+                    self.pressed_keys.add(symbol)
             if motion:
                 if modifiers & key.MOD_SHIFT:
                     self.dispatch_event('on_text_motion_select', motion)
         elif ev.type == xlib.KeyRelease:
             if symbol:
                 self.dispatch_event('on_key_release', symbol, modifiers)
+                if _can_detect_autorepeat:
+                    self.pressed_keys.remove(symbol)
 
     @XlibEventHandler(xlib.KeyPress)
     @XlibEventHandler(xlib.KeyRelease)