def rpc_send_keycode(keycodes): # very hard to get it right, not fully tested and fail proof. # just the basics. from kivy.core.window import Keyboard keys = keycodes.split("+") scancode = 0 key = None sym = "" modifiers = [] for el in keys: if re.match("^[A-Z]", el): lower_el = el.lower() # modifier detected ? add it if lower_el in ("ctrl", "meta", "alt", "shift"): modifiers.append(lower_el) continue # not a modifier, convert to scancode sym = lower_el key = Keyboard.keycodes.get(lower_el, 0) else: # may fail, so nothing would be done. try: key = int(el) sym = unichr(key) except: traceback.print_exc() return False _send_keycode(key, scancode, sym, modifiers) return True
def mainloop(self): # for android/iOS, we don't want to have any event nor executing our # main loop while the pause is going on. This loop wait any event (not # handled by the event filter), and remove them from the queue. # Nothing happen during the pause on iOS, except gyroscope value sent # over joystick. So it's safe. while self._pause_loop: self._win.wait_event() if not self._pause_loop: break event = self._win.poll() if event is None: continue # As dropfile is send was the app is still in pause.loop # we need to dispatch it action, args = event[0], event[1:] if action == 'dropfile': dropfile = args self.dispatch('on_dropfile', dropfile[0]) while True: event = self._win.poll() if event is False: break if event is None: continue action, args = event[0], event[1:] if action == 'quit': if self.dispatch('on_request_close'): continue EventLoop.quit = True break elif action in ('fingermotion', 'fingerdown', 'fingerup'): # for finger, pass the raw event to SDL motion event provider # XXX this is problematic. On OSX, it generates touches with 0, # 0 coordinates, at the same times as mouse. But it works. # We have a conflict of using either the mouse or the finger. # Right now, we have no mechanism that we could use to know # which is the preferred one for the application. if platform in ('ios', 'android'): SDL2MotionEventProvider.q.appendleft(event) pass elif action == 'mousemotion': x, y = args x, y = self._fix_mouse_pos(x, y) self._mouse_x = x self._mouse_y = y # don't dispatch motion if no button are pressed if len(self._mouse_buttons_down) == 0: continue self._mouse_meta = self.modifiers self.dispatch('on_mouse_move', x, y, self.modifiers) elif action in ('mousebuttondown', 'mousebuttonup'): x, y, button = args x, y = self._fix_mouse_pos(x, y) btn = 'left' if button == 3: btn = 'right' elif button == 2: btn = 'middle' elif button == 4: btn = "mouse4" elif button == 5: btn = "mouse5" eventname = 'on_mouse_down' self._mouse_buttons_down.add(button) if action == 'mousebuttonup': eventname = 'on_mouse_up' self._mouse_buttons_down.remove(button) self._mouse_x = x self._mouse_y = y self.dispatch(eventname, x, y, btn, self.modifiers) elif action.startswith('mousewheel'): self._update_modifiers() x, y, button = args btn = 'scrolldown' if action.endswith('up'): btn = 'scrollup' elif action.endswith('right'): btn = 'scrollright' elif action.endswith('left'): btn = 'scrollleft' self._mouse_meta = self.modifiers self._mouse_btn = btn # times = x if y == 0 else y # times = min(abs(times), 100) # for k in range(times): self._mouse_down = True self.dispatch('on_mouse_down', self._mouse_x, self._mouse_y, btn, self.modifiers) self._mouse_down = False self.dispatch('on_mouse_up', self._mouse_x, self._mouse_y, btn, self.modifiers) elif action == 'dropfile': dropfile = args self.dispatch('on_dropfile', dropfile[0]) # video resize elif action == 'windowresized': self._size = self._win.window_size # don't use trigger here, we want to delay the resize event ev = self._do_resize_ev if ev is None: ev = Clock.schedule_once(self._do_resize, .1) self._do_resize_ev = ev else: ev() elif action == 'windowmoved': self.dispatch('on_move') elif action == 'windowrestored': self.dispatch('on_restore') self.canvas.ask_update() elif action == 'windowexposed': self.canvas.ask_update() elif action == 'windowminimized': self.dispatch('on_minimize') if Config.getboolean('kivy', 'pause_on_minimize'): self.do_pause() elif action == 'windowmaximized': self.dispatch('on_maximize') elif action == 'windowhidden': self.dispatch('on_hide') elif action == 'windowshown': self.dispatch('on_show') elif action == 'windowfocusgained': self._focus = True elif action == 'windowfocuslost': self._focus = False elif action == 'windowenter': self.dispatch('on_cursor_enter') elif action == 'windowleave': self.dispatch('on_cursor_leave') elif action == 'joyaxismotion': stickid, axisid, value = args self.dispatch('on_joy_axis', stickid, axisid, value) elif action == 'joyhatmotion': stickid, hatid, value = args self.dispatch('on_joy_hat', stickid, hatid, value) elif action == 'joyballmotion': stickid, ballid, xrel, yrel = args self.dispatch('on_joy_ball', stickid, ballid, xrel, yrel) elif action == 'joybuttondown': stickid, buttonid = args self.dispatch('on_joy_button_down', stickid, buttonid) elif action == 'joybuttonup': stickid, buttonid = args self.dispatch('on_joy_button_up', stickid, buttonid) elif action in ('keydown', 'keyup'): mod, key, scancode, kstr = args try: key = self.key_map[key] except KeyError: pass if action == 'keydown': self._update_modifiers(mod, key) else: # ignore the key, it has been released self._update_modifiers(mod) # if mod in self._meta_keys: if (key not in self._modifiers and key not in self.command_keys.keys()): try: kstr_chr = unichr(key) try: # On android, there is no 'encoding' attribute. # On other platforms, if stdout is redirected, # 'encoding' may be None encoding = getattr(sys.stdout, 'encoding', 'utf8') or 'utf8' kstr_chr.encode(encoding) kstr = kstr_chr except UnicodeError: pass except ValueError: pass # if 'shift' in self._modifiers and key\ # not in self.command_keys.keys(): # return if action == 'keyup': self.dispatch('on_key_up', key, scancode) continue # don't dispatch more key if down event is accepted if self.dispatch('on_key_down', key, scancode, kstr, self.modifiers): continue self.dispatch('on_keyboard', key, scancode, kstr, self.modifiers) elif action == 'textinput': text = args[0] self.dispatch('on_textinput', text) elif action == 'textedit': text = args[0] self.dispatch('on_textedit', text) # unhandled event ! else: Logger.trace('WindowSDL: Unhandled event %s' % str(event))
def _mainloop(self): EventLoop.idle() while True: event = self._win.poll() if event is False: break if event is None: continue action, args = event[0], event[1:] if action == 'quit': EventLoop.quit = True self.close() break elif action in ('fingermotion', 'fingerdown', 'fingerup'): # for finger, pass the raw event to SDL motion event provider SDL2MotionEventProvider.q.appendleft(event) if action == 'mousemotion': x, y = args self.mouse_pos = x, self.system_size[1] - y # don't dispatch motion if no button are pressed self._mouse_x = x self._mouse_y = y self._mouse_meta = self.modifiers self.dispatch('on_mouse_move', x, y, self.modifiers) elif action in ('mousebuttondown', 'mousebuttonup'): x, y, button = args btn = 'left' if button == 3: btn = 'right' elif button == 2: btn = 'middle' eventname = 'on_mouse_down' if action == 'mousebuttonup': eventname = 'on_mouse_up' self.dispatch(eventname, x, y, btn, self.modifiers) elif action.startswith('mousewheel'): self._update_modifiers() x, y, button = args btn = 'scrolldown' if action.endswith('up'): btn = 'scrollup' elif action.endswith('right'): btn = 'scrollright' elif action.endswith('left'): btn = 'scrollleft' self._mouse_meta = self.modifiers self._mouse_btn = btn #times = x if y == 0 else y #times = min(abs(times), 100) #for k in range(times): self._mouse_down = True self.dispatch('on_mouse_down', self._mouse_x, self._mouse_y, btn, self.modifiers) self._mouse_down = False self.dispatch('on_mouse_up', self._mouse_x, self._mouse_y, btn, self.modifiers) elif action == 'dropfile': dropfile = args self.dispatch('on_dropfile', dropfile[0]) # video resize elif action == 'windowresized': self._size = args # don't use trigger here, we want to delay the resize event cb = self._do_resize Clock.unschedule(cb) Clock.schedule_once(cb, .1) elif action == 'windowresized': self.canvas.ask_update() elif action == 'windowrestored': self.canvas.ask_update() elif action == 'windowminimized': self.do_pause() elif action == 'joyaxismotion': stickid, axisid, value = args self.dispatch('on_joy_axis', stickid, axisid, value) elif action == 'joyhatmotion': stickid, hatid, value = args self.dispatch('on_joy_hat', stickid, hatid, value) elif action == 'joyballmotion': stickid, ballid, xrel, yrel = args self.dispatch('on_joy_ball', stickid, ballid, xrel, yrel) elif action == 'joybuttondown': stickid, buttonid = args self.dispatch('on_joy_button_down', stickid, buttonid) elif action == 'joybuttonup': stickid, buttonid = args self.dispatch('on_joy_button_up', stickid, buttonid) elif action in ('keydown', 'keyup'): mod, key, scancode, kstr = args if mod in self._meta_keys: try: kstr = unichr(key) except ValueError: pass # XXX ios keyboard suck, when backspace is hit, the delete # keycode is sent. fix it. key_swap = {127: 8, # back SDLK_LEFT: 276, SDLK_RIGHT: 275, SDLK_UP: 273, SDLK_DOWN: 274, SDLK_HOME: 278, SDLK_END: 279, SDLK_PAGEDOWN: 281, SDLK_PAGEUP: 280, SDLK_SHIFTL: 303, SDLK_SHIFTR: 304} try: key = key_swap[key] except KeyError: pass self._update_modifiers(mod) if action == 'keyup': self.dispatch('on_key_up', key, scancode) continue # don't dispatch more key if down event is accepted if self.dispatch('on_key_down', key, scancode, kstr, self.modifiers): continue self.dispatch('on_keyboard', key, scancode, kstr, self.modifiers) elif action == 'textinput': key = args[0][0] # XXX on IOS, keydown/up don't send unicode anymore. # With latest sdl, the text is sent over textinput # Right now, redo keydown/up, but we need to seperate both call # too. (and adapt on_key_* API.) self.dispatch('on_key_down', key, None, args[0], self.modifiers) self.dispatch('on_keyboard', None, None, args[0], self.modifiers) self.dispatch('on_key_up', key, None, args[0], self.modifiers)
def _mainloop(self): EventLoop.idle() while True: event = self._win.poll() if event is False: break if event is None: continue action, args = event[0], event[1:] if action == 'quit': if self.dispatch('on_request_close'): continue EventLoop.quit = True self.close() break elif action in ('fingermotion', 'fingerdown', 'fingerup'): # for finger, pass the raw event to SDL motion event provider # XXX this is problematic. On OSX, it generates touches with 0, # 0 coordinates, at the same times as mouse. But it works. # We have a conflict of using either the mouse or the finger. # Right now, we have no mechanism that we could use to know # which is the preferred one for the application. if platform == "ios": SDL2MotionEventProvider.q.appendleft(event) pass elif action == 'mousemotion': x, y = args x, y = self._fix_mouse_pos(x, y) self._mouse_x = x self._mouse_y = y # don't dispatch motion if no button are pressed if len(self._mouse_buttons_down) == 0: continue self._mouse_meta = self.modifiers self.dispatch('on_mouse_move', x, y, self.modifiers) elif action in ('mousebuttondown', 'mousebuttonup'): x, y, button = args x, y = self._fix_mouse_pos(x, y) btn = 'left' if button == 3: btn = 'right' elif button == 2: btn = 'middle' eventname = 'on_mouse_down' self._mouse_buttons_down.add(button) if action == 'mousebuttonup': eventname = 'on_mouse_up' self._mouse_buttons_down.remove(button) self._mouse_x = x self._mouse_y = y self.dispatch(eventname, x, y, btn, self.modifiers) elif action.startswith('mousewheel'): self._update_modifiers() x, y, button = args btn = 'scrolldown' if action.endswith('up'): btn = 'scrollup' elif action.endswith('right'): btn = 'scrollright' elif action.endswith('left'): btn = 'scrollleft' self._mouse_meta = self.modifiers self._mouse_btn = btn #times = x if y == 0 else y #times = min(abs(times), 100) #for k in range(times): self._mouse_down = True self.dispatch('on_mouse_down', self._mouse_x, self._mouse_y, btn, self.modifiers) self._mouse_down = False self.dispatch('on_mouse_up', self._mouse_x, self._mouse_y, btn, self.modifiers) elif action == 'dropfile': dropfile = args self.dispatch('on_dropfile', dropfile[0]) # video resize elif action == 'windowresized': self._size = self._win.window_size # don't use trigger here, we want to delay the resize event cb = self._do_resize Clock.unschedule(cb) Clock.schedule_once(cb, .1) elif action == 'windowresized': self.canvas.ask_update() elif action == 'windowrestored': self.canvas.ask_update() elif action == 'windowexposed': self.canvas.ask_update() elif action == 'windowminimized': if Config.getboolean('kivy', 'pause_on_minimize'): self.do_pause() elif action == 'joyaxismotion': stickid, axisid, value = args self.dispatch('on_joy_axis', stickid, axisid, value) elif action == 'joyhatmotion': stickid, hatid, value = args self.dispatch('on_joy_hat', stickid, hatid, value) elif action == 'joyballmotion': stickid, ballid, xrel, yrel = args self.dispatch('on_joy_ball', stickid, ballid, xrel, yrel) elif action == 'joybuttondown': stickid, buttonid = args self.dispatch('on_joy_button_down', stickid, buttonid) elif action == 'joybuttonup': stickid, buttonid = args self.dispatch('on_joy_button_up', stickid, buttonid) elif action in ('keydown', 'keyup'): mod, key, scancode, kstr = args key_swap = { SDLK_LEFT: 276, SDLK_RIGHT: 275, SDLK_UP: 273, SDLK_DOWN: 274, SDLK_HOME: 278, SDLK_END: 279, SDLK_PAGEDOWN: 281, SDLK_PAGEUP: 280, SDLK_SHIFTR: 303, SDLK_SHIFTL: 304, SDLK_SUPER: 309, SDLK_LCTRL: 305, SDLK_RCTRL: 306, SDLK_LALT: 308, SDLK_RALT: 307, SDLK_CAPS: 301, SDLK_INSERT: 277, SDLK_F1: 282, SDLK_F2: 283, SDLK_F3: 284, SDLK_F4: 285, SDLK_F5: 286, SDLK_F6: 287, SDLK_F7: 288, SDLK_F8: 289, SDLK_F9: 290, SDLK_F10: 291, SDLK_F11: 292, SDLK_F12: 293, SDLK_F13: 294, SDLK_F14: 295, SDLK_F15: 296, SDLK_KEYPADNUM: 300, SDLK_KP_DEVIDE: 267, SDLK_KP_MULTIPLY: 268, SDLK_KP_MINUS: 269, SDLK_KP_PLUS: 270, SDLK_KP_ENTER: 271, SDLK_KP_DOT: 266, SDLK_KP_0: 256, SDLK_KP_1: 257, SDLK_KP_2: 258, SDLK_KP_3: 259, SDLK_KP_4: 260, SDLK_KP_5: 261, SDLK_KP_6: 262, SDLK_KP_7: 263, SDLK_KP_8: 264, SDLK_KP_9: 265} if platform == 'ios': # XXX ios keyboard suck, when backspace is hit, the delete # keycode is sent. fix it. key_swap[127] = 8 # back try: key = key_swap[key] except KeyError: pass if action == 'keydown': self._update_modifiers(mod, key) else: self._update_modifiers(mod) # ignore the key, it # has been released # if mod in self._meta_keys: if (key not in self._modifiers and key not in self.command_keys.keys()): try: kstr = unichr(key) except ValueError: pass #if 'shift' in self._modifiers and key\ # not in self.command_keys.keys(): # return if action == 'keyup': self.dispatch('on_key_up', key, scancode) continue # don't dispatch more key if down event is accepted if self.dispatch('on_key_down', key, scancode, kstr, self.modifiers): continue self.dispatch('on_keyboard', key, scancode, kstr, self.modifiers) elif action == 'textinput': text = args[0] self.dispatch('on_textinput', text) # XXX on IOS, keydown/up don't send unicode anymore. # With latest sdl, the text is sent over textinput # Right now, redo keydown/up, but we need to seperate both call # too. (and adapt on_key_* API.) #self.dispatch() #self.dispatch('on_key_down', key, None, args[0], # self.modifiers) #self.dispatch('on_keyboard', None, None, args[0], # self.modifiers) #self.dispatch('on_key_up', key, None, args[0], # self.modifiers) # unhandled event ! else: Logger.trace('WindowSDL: Unhandled event %s' % str(event))
def _mainloop(self): EventLoop.idle() # for android/iOS, we don't want to have any event nor executing our # main loop while the pause is going on. This loop wait any event (not # handled by the event filter), and remove them from the queue. # Nothing happen during the pause on iOS, except gyroscope value sent # over joystick. So it's safe. while self._pause_loop: self._win.wait_event() if not self._pause_loop: break self._win.poll() while True: event = self._win.poll() if event is False: break if event is None: continue action, args = event[0], event[1:] if action == 'quit': if self.dispatch('on_request_close'): continue EventLoop.quit = True self.close() break elif action in ('fingermotion', 'fingerdown', 'fingerup'): # for finger, pass the raw event to SDL motion event provider # XXX this is problematic. On OSX, it generates touches with 0, # 0 coordinates, at the same times as mouse. But it works. # We have a conflict of using either the mouse or the finger. # Right now, we have no mechanism that we could use to know # which is the preferred one for the application. if platform in ('ios', 'android'): SDL2MotionEventProvider.q.appendleft(event) pass elif action == 'mousemotion': x, y = args x, y = self._fix_mouse_pos(x, y) self._mouse_x = x self._mouse_y = y # don't dispatch motion if no button are pressed if len(self._mouse_buttons_down) == 0: continue self._mouse_meta = self.modifiers self.dispatch('on_mouse_move', x, y, self.modifiers) elif action in ('mousebuttondown', 'mousebuttonup'): x, y, button = args x, y = self._fix_mouse_pos(x, y) btn = 'left' if button == 3: btn = 'right' elif button == 2: btn = 'middle' eventname = 'on_mouse_down' self._mouse_buttons_down.add(button) if action == 'mousebuttonup': eventname = 'on_mouse_up' self._mouse_buttons_down.remove(button) self._mouse_x = x self._mouse_y = y self.dispatch(eventname, x, y, btn, self.modifiers) elif action.startswith('mousewheel'): self._update_modifiers() x, y, button = args btn = 'scrolldown' if action.endswith('up'): btn = 'scrollup' elif action.endswith('right'): btn = 'scrollright' elif action.endswith('left'): btn = 'scrollleft' self._mouse_meta = self.modifiers self._mouse_btn = btn #times = x if y == 0 else y #times = min(abs(times), 100) #for k in range(times): self._mouse_down = True self.dispatch('on_mouse_down', self._mouse_x, self._mouse_y, btn, self.modifiers) self._mouse_down = False self.dispatch('on_mouse_up', self._mouse_x, self._mouse_y, btn, self.modifiers) elif action == 'dropfile': dropfile = args self.dispatch('on_dropfile', dropfile[0]) # video resize elif action == 'windowresized': self._size = self._win.window_size # don't use trigger here, we want to delay the resize event ev = self._do_resize_ev if ev is None: ev = self._do_resize_ev = Clock.schedule_once(self._do_resize, .1) else: ev() elif action == 'windowresized': self.canvas.ask_update() elif action == 'windowrestored': self.dispatch('on_restore') self.canvas.ask_update() elif action == 'windowexposed': self.canvas.ask_update() elif action == 'windowminimized': self.dispatch('on_minimize') if Config.getboolean('kivy', 'pause_on_minimize'): self.do_pause() elif action == 'windowmaximized': self.dispatch('on_maximize') elif action == 'windowhidden': self.dispatch('on_hide') elif action == 'windowshown': self.dispatch('on_show') elif action == 'windowfocusgained': self._focus = True elif action == 'windowfocuslost': self._focus = False elif action == 'windowenter': self.dispatch('on_cursor_enter') elif action == 'windowleave': self.dispatch('on_cursor_leave') elif action == 'joyaxismotion': stickid, axisid, value = args self.dispatch('on_joy_axis', stickid, axisid, value) elif action == 'joyhatmotion': stickid, hatid, value = args self.dispatch('on_joy_hat', stickid, hatid, value) elif action == 'joyballmotion': stickid, ballid, xrel, yrel = args self.dispatch('on_joy_ball', stickid, ballid, xrel, yrel) elif action == 'joybuttondown': stickid, buttonid = args self.dispatch('on_joy_button_down', stickid, buttonid) elif action == 'joybuttonup': stickid, buttonid = args self.dispatch('on_joy_button_up', stickid, buttonid) elif action in ('keydown', 'keyup'): mod, key, scancode, kstr = args try: key = self.key_map[key] except KeyError: pass if action == 'keydown': self._update_modifiers(mod, key) else: self._update_modifiers(mod) # ignore the key, it # has been released # if mod in self._meta_keys: if (key not in self._modifiers and key not in self.command_keys.keys()): try: kstr = unichr(key) except ValueError: pass #if 'shift' in self._modifiers and key\ # not in self.command_keys.keys(): # return if action == 'keyup': self.dispatch('on_key_up', key, scancode) continue # don't dispatch more key if down event is accepted if self.dispatch('on_key_down', key, scancode, kstr, self.modifiers): continue self.dispatch('on_keyboard', key, scancode, kstr, self.modifiers) elif action == 'textinput': text = args[0] self.dispatch('on_textinput', text) # unhandled event ! else: Logger.trace('WindowSDL: Unhandled event %s' % str(event))
def _mainloop(self): EventLoop.idle() # for android/iOS, we don't want to have any event nor executing our # main loop while the pause is going on. This loop wait any event (not # handled by the event filter), and remove them from the queue. # Nothing happen during the pause on iOS, except gyroscope value sended # over joystick. So it's safe. while self._pause_loop: self._win.wait_event() if not self._pause_loop: break self._win.poll() while True: event = self._win.poll() if event is False: break if event is None: continue action, args = event[0], event[1:] if action == 'quit': if self.dispatch('on_request_close'): continue EventLoop.quit = True self.close() break elif action in ('fingermotion', 'fingerdown', 'fingerup'): # for finger, pass the raw event to SDL motion event provider # XXX this is problematic. On OSX, it generates touches with 0, # 0 coordinates, at the same times as mouse. But it works. # We have a conflict of using either the mouse or the finger. # Right now, we have no mechanism that we could use to know # which is the preferred one for the application. if platform in ('ios', 'android'): SDL2MotionEventProvider.q.appendleft(event) pass elif action == 'mousemotion': x, y = args x, y = self._fix_mouse_pos(x, y) self._mouse_x = x self._mouse_y = y # don't dispatch motion if no button are pressed if len(self._mouse_buttons_down) == 0: continue self._mouse_meta = self.modifiers self.dispatch('on_mouse_move', x, y, self.modifiers) elif action in ('mousebuttondown', 'mousebuttonup'): x, y, button = args x, y = self._fix_mouse_pos(x, y) btn = 'left' if button == 3: btn = 'right' elif button == 2: btn = 'middle' eventname = 'on_mouse_down' self._mouse_buttons_down.add(button) if action == 'mousebuttonup': eventname = 'on_mouse_up' self._mouse_buttons_down.remove(button) self._mouse_x = x self._mouse_y = y self.dispatch(eventname, x, y, btn, self.modifiers) elif action.startswith('mousewheel'): self._update_modifiers() x, y, button = args btn = 'scrolldown' if action.endswith('up'): btn = 'scrollup' elif action.endswith('right'): btn = 'scrollright' elif action.endswith('left'): btn = 'scrollleft' self._mouse_meta = self.modifiers self._mouse_btn = btn #times = x if y == 0 else y #times = min(abs(times), 100) #for k in range(times): self._mouse_down = True self.dispatch('on_mouse_down', self._mouse_x, self._mouse_y, btn, self.modifiers) self._mouse_down = False self.dispatch('on_mouse_up', self._mouse_x, self._mouse_y, btn, self.modifiers) elif action == 'dropfile': dropfile = args self.dispatch('on_dropfile', dropfile[0]) # video resize elif action == 'windowresized': self._size = self._win.window_size # don't use trigger here, we want to delay the resize event cb = self._do_resize Clock.unschedule(cb) Clock.schedule_once(cb, .1) elif action == 'windowresized': self.canvas.ask_update() elif action == 'windowrestored': self.canvas.ask_update() elif action == 'windowexposed': self.canvas.ask_update() elif action == 'windowminimized': if Config.getboolean('kivy', 'pause_on_minimize'): self.do_pause() elif action == 'joyaxismotion': stickid, axisid, value = args self.dispatch('on_joy_axis', stickid, axisid, value) elif action == 'joyhatmotion': stickid, hatid, value = args self.dispatch('on_joy_hat', stickid, hatid, value) elif action == 'joyballmotion': stickid, ballid, xrel, yrel = args self.dispatch('on_joy_ball', stickid, ballid, xrel, yrel) elif action == 'joybuttondown': stickid, buttonid = args self.dispatch('on_joy_button_down', stickid, buttonid) elif action == 'joybuttonup': stickid, buttonid = args self.dispatch('on_joy_button_up', stickid, buttonid) elif action in ('keydown', 'keyup'): mod, key, scancode, kstr = args key_swap = { SDLK_LEFT: 276, SDLK_RIGHT: 275, SDLK_UP: 273, SDLK_DOWN: 274, SDLK_HOME: 278, SDLK_END: 279, SDLK_PAGEDOWN: 281, SDLK_PAGEUP: 280, SDLK_SHIFTR: 303, SDLK_SHIFTL: 304, SDLK_SUPER: 309, SDLK_LCTRL: 305, SDLK_RCTRL: 306, SDLK_LALT: 308, SDLK_RALT: 307, SDLK_CAPS: 301, SDLK_INSERT: 277, SDLK_F1: 282, SDLK_F2: 283, SDLK_F3: 284, SDLK_F4: 285, SDLK_F5: 286, SDLK_F6: 287, SDLK_F7: 288, SDLK_F8: 289, SDLK_F9: 290, SDLK_F10: 291, SDLK_F11: 292, SDLK_F12: 293, SDLK_F13: 294, SDLK_F14: 295, SDLK_F15: 296, SDLK_KEYPADNUM: 300, SDLK_KP_DEVIDE: 267, SDLK_KP_MULTIPLY: 268, SDLK_KP_MINUS: 269, SDLK_KP_PLUS: 270, SDLK_KP_ENTER: 271, SDLK_KP_DOT: 266, SDLK_KP_0: 256, SDLK_KP_1: 257, SDLK_KP_2: 258, SDLK_KP_3: 259, SDLK_KP_4: 260, SDLK_KP_5: 261, SDLK_KP_6: 262, SDLK_KP_7: 263, SDLK_KP_8: 264, SDLK_KP_9: 265 } if platform == 'ios': # XXX ios keyboard suck, when backspace is hit, the delete # keycode is sent. fix it. key_swap[127] = 8 # back try: key = key_swap[key] except KeyError: pass if action == 'keydown': self._update_modifiers(mod, key) else: self._update_modifiers(mod) # ignore the key, it # has been released # if mod in self._meta_keys: if (key not in self._modifiers and key not in self.command_keys.keys()): try: kstr = unichr(key) except ValueError: pass #if 'shift' in self._modifiers and key\ # not in self.command_keys.keys(): # return if action == 'keyup': self.dispatch('on_key_up', key, scancode) continue # don't dispatch more key if down event is accepted if self.dispatch('on_key_down', key, scancode, kstr, self.modifiers): continue self.dispatch('on_keyboard', key, scancode, kstr, self.modifiers) elif action == 'textinput': text = args[0] self.dispatch('on_textinput', text) # unhandled event ! else: Logger.trace('WindowSDL: Unhandled event %s' % str(event))
def _mainloop(self): EventLoop.idle() while True: event = self._win.poll() if event is False: break if event is None: continue action, args = event[0], event[1:] if action == 'quit': EventLoop.quit = True self.close() break elif action in ('fingermotion', 'fingerdown', 'fingerup'): # for finger, pass the raw event to SDL motion event provider # XXX this is problematic. On OSX, it generates touches with 0, # 0 coordinates, at the same times as mouse. But it works. # We have a conflict of using either the mouse or the finger. # Right now, we have no mechanism that we could use to know # which is the preferred one for the application. #SDL2MotionEventProvider.q.appendleft(event) pass elif action == 'mousemotion': x, y = args self.mouse_pos = x, self.system_size[1] - y self._mouse_x = x self._mouse_y = y # don't dispatch motion if no button are pressed if len(self._mouse_buttons_down) == 0: continue self._mouse_meta = self.modifiers self.dispatch('on_mouse_move', x, y, self.modifiers) elif action in ('mousebuttondown', 'mousebuttonup'): x, y, button = args btn = 'left' if button == 3: btn = 'right' elif button == 2: btn = 'middle' eventname = 'on_mouse_down' self._mouse_buttons_down.add(button) if action == 'mousebuttonup': eventname = 'on_mouse_up' self._mouse_buttons_down.remove(button) self._mouse_x = x self._mouse_y = y self.dispatch(eventname, x, y, btn, self.modifiers) elif action.startswith('mousewheel'): self._update_modifiers() x, y, button = args btn = 'scrolldown' if action.endswith('up'): btn = 'scrollup' elif action.endswith('right'): btn = 'scrollright' elif action.endswith('left'): btn = 'scrollleft' self._mouse_meta = self.modifiers self._mouse_btn = btn #times = x if y == 0 else y #times = min(abs(times), 100) #for k in range(times): self._mouse_down = True self.dispatch('on_mouse_down', self._mouse_x, self._mouse_y, btn, self.modifiers) self._mouse_down = False self.dispatch('on_mouse_up', self._mouse_x, self._mouse_y, btn, self.modifiers) elif action == 'dropfile': dropfile = args self.dispatch('on_dropfile', dropfile[0]) # video resize elif action == 'windowresized': self._size = args # don't use trigger here, we want to delay the resize event cb = self._do_resize Clock.unschedule(cb) Clock.schedule_once(cb, .1) elif action == 'windowresized': self.canvas.ask_update() elif action == 'windowrestored': self.canvas.ask_update() elif action == 'windowexposed': self.canvas.ask_update() elif action == 'windowminimized': if Config.getboolean('kivy', 'pause_on_minimize'): self.do_pause() elif action == 'joyaxismotion': stickid, axisid, value = args self.dispatch('on_joy_axis', stickid, axisid, value) elif action == 'joyhatmotion': stickid, hatid, value = args self.dispatch('on_joy_hat', stickid, hatid, value) elif action == 'joyballmotion': stickid, ballid, xrel, yrel = args self.dispatch('on_joy_ball', stickid, ballid, xrel, yrel) elif action == 'joybuttondown': stickid, buttonid = args self.dispatch('on_joy_button_down', stickid, buttonid) elif action == 'joybuttonup': stickid, buttonid = args self.dispatch('on_joy_button_up', stickid, buttonid) elif action in ('keydown', 'keyup'): mod, key, scancode, kstr = args if mod in self._meta_keys: try: kstr = unichr(key) except ValueError: pass key_swap = { SDLK_LEFT: 276, SDLK_RIGHT: 275, SDLK_UP: 273, SDLK_DOWN: 274, SDLK_HOME: 278, SDLK_END: 279, SDLK_PAGEDOWN: 281, SDLK_PAGEUP: 280, SDLK_SHIFTL: 303, SDLK_SHIFTR: 304, SDLK_LCTRL: KMOD_LCTRL, SDLK_RCTRL: KMOD_RCTRL, SDLK_LALT: KMOD_LALT, SDLK_RALT: KMOD_RALT } if platform == 'ios': # XXX ios keyboard suck, when backspace is hit, the delete # keycode is sent. fix it. key_swap[127] = 8 # back try: key = key_swap[key] except KeyError: pass if action == 'keydown': self._update_modifiers(mod, key) else: self._update_modifiers(mod) # ignore the key, it # has been released if 'shift' in self._modifiers and key\ not in self.command_keys.keys(): return if action == 'keyup': self.dispatch('on_key_up', key, scancode) continue # don't dispatch more key if down event is accepted if self.dispatch('on_key_down', key, scancode, kstr, self.modifiers): continue self.dispatch('on_keyboard', key, scancode, kstr, self.modifiers) elif action == 'textinput': key = args[0][0] # XXX on IOS, keydown/up don't send unicode anymore. # With latest sdl, the text is sent over textinput # Right now, redo keydown/up, but we need to seperate both call # too. (and adapt on_key_* API.) self.dispatch('on_key_down', key, None, args[0], self.modifiers) self.dispatch('on_keyboard', None, None, args[0], self.modifiers) self.dispatch('on_key_up', key, None, args[0], self.modifiers) # unhandled event ! else: Logger.trace('WindowSDL: Unhandled event %s' % str(event))