fix(pynput): Convert keysym to keycode according to the system input source
This commit is contained in:
		
							parent
							
								
									ef1f34cefa
								
							
						
					
					
						commit
						1833b8c2dc
					
				@ -1,65 +1,32 @@
 | 
				
			|||||||
from pynput.keyboard import Key, Controller
 | 
					from pynput.keyboard import Key, Controller
 | 
				
			||||||
from pynput.keyboard._xorg import KeyCode
 | 
					from pynput.keyboard._xorg import KeyCode
 | 
				
			||||||
from pynput._util.xorg import display_manager
 | 
					from pynput._util.xorg import display_manager
 | 
				
			||||||
import Xlib
 | 
					 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
import sys
 | 
					import sys
 | 
				
			||||||
import socket
 | 
					import socket
 | 
				
			||||||
 | 
					from Xlib.ext.xtest import fake_input
 | 
				
			||||||
 | 
					from Xlib import X
 | 
				
			||||||
 | 
					
 | 
				
			||||||
KeyCode._from_symbol("\0")  # test
 | 
					KeyCode._from_symbol("\0")  # test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MyController(Controller):
 | 
					class MyController(Controller):
 | 
				
			||||||
    def _handle(self, key, is_press):
 | 
					    def _handle(self, key, is_press):
 | 
				
			||||||
        """Resolves a key identifier and sends a keyboard event.
 | 
					        """Resolves a key identifier and sends a keyboard event.
 | 
				
			||||||
        :param event: The *X* keyboard event.
 | 
					        :param event: The *X* keyboard event.
 | 
				
			||||||
        :param int keysym: The keysym to handle.
 | 
					        :param int keysym: The keysym to handle.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        event = Xlib.display.event.KeyPress if is_press \
 | 
					        event = X.KeyPress if is_press \
 | 
				
			||||||
            else Xlib.display.event.KeyRelease
 | 
					            else X.KeyRelease
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        keysym = self._keysym(key)
 | 
					        keysym = self._keysym(key)
 | 
				
			||||||
 | 
					        # Get keycode according to system language
 | 
				
			||||||
 | 
					        keycode = self._display.keysym_to_keycode(keysym)
 | 
				
			||||||
 | 
					        print(keycode)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Make sure to verify that the key was resolved
 | 
					        fake_input(self._display, event,  keycode)
 | 
				
			||||||
        if keysym is None:
 | 
					        self._display.sync()
 | 
				
			||||||
            raise self.InvalidKeyException(key)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # If the key has a virtual key code, use that immediately with
 | 
					 | 
				
			||||||
        # fake_input; fake input,being an X server extension, has access to
 | 
					 | 
				
			||||||
        # more internal state that we do
 | 
					 | 
				
			||||||
        if key.vk is not None:
 | 
					 | 
				
			||||||
            with display_manager(self._display) as dm:
 | 
					 | 
				
			||||||
                Xlib.ext.xtest.fake_input(
 | 
					 | 
				
			||||||
                    dm,
 | 
					 | 
				
			||||||
                    Xlib.X.KeyPress if is_press else Xlib.X.KeyRelease,
 | 
					 | 
				
			||||||
                    dm.keysym_to_keycode(key.vk))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Otherwise use XSendEvent; we need to use this in the general case to
 | 
					 | 
				
			||||||
        # work around problems with keyboard layouts
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            try:
 | 
					 | 
				
			||||||
                keycode, shift_state = self.keyboard_mapping[keysym]
 | 
					 | 
				
			||||||
                with self.modifiers as modifiers:
 | 
					 | 
				
			||||||
                    alt_gr = Key.alt_gr in modifiers
 | 
					 | 
				
			||||||
                if alt_gr:
 | 
					 | 
				
			||||||
                    self._send_key(event, keycode, shift_state)
 | 
					 | 
				
			||||||
                else:
 | 
					 | 
				
			||||||
                    with display_manager(self._display) as dm:
 | 
					 | 
				
			||||||
                        Xlib.ext.xtest.fake_input(
 | 
					 | 
				
			||||||
                            dm,
 | 
					 | 
				
			||||||
                            Xlib.X.KeyPress if is_press else Xlib.X.KeyRelease,
 | 
					 | 
				
			||||||
                            keycode)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            except KeyError:
 | 
					 | 
				
			||||||
                with self._borrow_lock:
 | 
					 | 
				
			||||||
                    keycode, index, count = self._borrows[keysym]
 | 
					 | 
				
			||||||
                    self._send_key(
 | 
					 | 
				
			||||||
                        event,
 | 
					 | 
				
			||||||
                        keycode,
 | 
					 | 
				
			||||||
                        index_to_shift(self._display, index))
 | 
					 | 
				
			||||||
                    count += 1 if is_press else -1
 | 
					 | 
				
			||||||
                    self._borrows[keysym] = (keycode, index, count)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Notify any running listeners
 | 
					 | 
				
			||||||
        self._emit('_on_fake_event', key, is_press)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
keyboard = MyController()
 | 
					keyboard = MyController()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -121,4 +88,3 @@ def loop():
 | 
				
			|||||||
loop()
 | 
					loop()
 | 
				
			||||||
clientsocket.close()
 | 
					clientsocket.close()
 | 
				
			||||||
server.close()
 | 
					server.close()
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user