def connection_monitor(self): connection_status_text = self.ids.connection_status device_name = self.ids.device_name device_address = self.ids.device_address adapter_status = self.ids.adapter_status service_status = self.ids.service_status mode = self.ids.press_mode while True: if not self.bluetooth_service.bluetooth_available: print("Bluetooth is Not Enabled") adapter_status.text = "Adapter Status: Bluetooth is Not Enabled or Not Available" device_name.disabled = True device_name.text = "Client Name: Unknown" device_address.disabled = True device_address.text = "Client Address: None" service_status.text = "Service Status: Dead Network Found. please enable the Bluetooth and restart" break else: adapter_status.text = "Adapter Status: Bluetooth Adapter Enabled" if self.bluetooth_service.discovered: service_status.text = "Service Status: Ready" if self.bluetooth_service.connected: device_address.disabled = False device_address.text = "Client Address: "+self.bluetooth_service.get_client_address() device_name.disabled = False device_name.text = "Client Name: "+self.bluetooth_service.get_client_name() set_mode(mode.active) else: connection_status_text.text = "No Connection" device_address.disabled = True device_address.text = "Client Address: None" device_name.disabled = True device_name.text = "Client Name: Unknown" if self.bluetooth_service.connected or self.wifi_service.connected: connection_status_text.text = "Connected" if self.wifi_service.connected: self.ids.port_text_input.disabled = True self.ids.refresh_port.disabled = True if Config.getboolean("kivy", "update_profiles"): thread.start_new(self.wifi_service.update_profiles, ()) if self.bluetooth_service.connected: if Config.getboolean("kivy", "update_profiles"): thread.start_new(self.bluetooth_service.update_profiles, ()) else: connection_status_text.text = "No Connection" self.ids.port_text_input.disabled = False self.ids.refresh_port.disabled = False global HOTSPOT_ENABLED HOTSPOT_ENABLED = self.ids.hotspot_switch.active self.ids.listening_ip_addresses.text = "Listening IP Addresses : " + sharescripter.get_listening_ips() time.sleep(1)
def _wnd_proc(self, hwnd, msg, wParam, lParam): from kivy.input.providers.wm_common import WM_DPICHANGED, WM_NCCALCSIZE from ctypes import windll if msg == WM_DPICHANGED: ow, oh = self.window.size old_dpi = self.window.dpi def clock_callback(*args): if x_dpi != y_dpi: raise ValueError( 'Can only handle DPI that are same for x and y') self.window.dpi = x_dpi # maintain the same window size ratio = x_dpi / old_dpi self.window.size = ratio * ow, ratio * oh x_dpi = wParam & 0xFFFF y_dpi = wParam >> 16 Clock.schedule_once(clock_callback, -1) elif Config.getboolean('graphics', 'resizable') \ and msg == WM_NCCALCSIZE and self.window.custom_titlebar: return 0 return windll.user32.CallWindowProcW(self.old_windProc, hwnd, msg, wParam, lParam)
def create_window(self, *largs): if self._fake_fullscreen: if not self.borderless: self.fullscreen = self._fake_fullscreen = False elif not self.fullscreen or self.fullscreen == 'auto': self.borderless = self._fake_fullscreen = False if self.fullscreen == 'fake': self.borderless = self._fake_fullscreen = True Logger.warning("The 'fake' fullscreen option has been " "deprecated, use Window.borderless or the " "borderless Config option instead.") if not self.initialized: if self.position == 'auto': pos = None, None elif self.position == 'custom': pos = self.left, self.top # setup ! w, h = self._size resizable = Config.getboolean('graphics', 'resizable') gl_size = self._win.setup_window(pos[0], pos[1], w, h, self.borderless, self.fullscreen, resizable) # never stay with a None pos, application using w.center # will be fired. self._pos = (0, 0) else: w, h = self._size self._win.resize_window(w, h) self._win.set_border_state(self.borderless) self._win.set_fullscreen_mode(self.fullscreen) super(WindowSDL, self).create_window() # auto add input provider Logger.info('Window: auto add sdl input provider') from kivy.base import EventLoop SDL2MotionEventProvider.win = self EventLoop.add_input_provider(SDL2MotionEventProvider('sdl', '')) # set window icon before calling set_mode try: filename_icon = self.icon or Config.get('kivy', 'window_icon') if filename_icon == '': logo_size = 32 if platform == 'macosx': logo_size = 512 elif platform == 'win': logo_size = 64 filename_icon = 'kivy-icon-{}.png'.format(logo_size) filename_icon = resource_find( join(kivy_data_dir, 'logo', filename_icon)) self.set_icon(filename_icon) except: Logger.exception('Window: cannot set icon')
def __init__(self, **kwargs): super(DwellOnScatter, self).__init__(**kwargs) self.global_ignore_momentum = Config.getboolean('dwell', 'global_ignore_momentum') # Do not do momentum if change in dx, dy due to rotational change # Only apply momentum for translations self.original_rotation = 0
def save_window_size(self): '''Save window size on exit. ''' return bool( int( self.app_settings.config_parser.getdefault( 'desktop', 'save_window_size', 1))) if Config.getboolean( 'kivy', 'desktop') else False
def build(self, *args, **kwargs): self.draw_fps = True self.fps = Fps() self.time = 0. self.last_time = 0. self.time_mult = 1. self.time_mult_pause = None Clock.schedule_interval(self.update, 0) self.event_once = None self.root = Space() Config.read('config.ini') # For my window header # dx, dy = -1, -32 dx, dy = 0, 0 if Config.get('graphics', 'position') != 'auto': Window.left, Window.top, Window.size = Config.getint('graphics', 'left') + dx, \ Config.getint('graphics', 'top') + dy, \ (Config.getint('graphics', 'width'), \ Config.getint('graphics', 'height'),) if Config.getboolean('graphics', 'maximize'): Window.maximize() Window.show() self.root.bind(on_touch_down=self.on_touch_down, on_touch_move=self.on_touch_move, on_touch_up=self.on_touch_up) if self.filename: Clock.schedule_once( partial( import_module(self.filename).set_state, self.root, self), 1) return self.root
def build(self): self.light_control_client = LightController() if Config.getboolean("light_controls", "device_enabled"): self.light_control_client.start() self.weather_service = WeatherService() self.weather_service.start() self.sm = CustomScreenManager() self.main_screen = MainScreen(name="main") self.sm.add_widget(self.main_screen) self.settings_screen = SettingsScreen(name="settings") self.sm.add_widget(self.settings_screen) self.idle_screen = IdleScreen(name="idle") self.sm.add_widget(self.idle_screen) return self.sm
This code is still experimental, and its API is subject to change in a future version. ''' __all__ = ('FocusBehavior', ) from kivy.properties import OptionProperty, ObjectProperty, BooleanProperty, \ AliasProperty from kivy.config import Config from kivy.base import EventLoop # When we are generating documentation, Config doesn't exist _is_desktop = False _keyboard_mode = 'system' if Config: _is_desktop = Config.getboolean('kivy', 'desktop') _keyboard_mode = Config.get('kivy', 'keyboard_mode') class FocusBehavior(object): '''Provides keyboard focus behavior. When combined with other FocusBehavior widgets it allows one to cycle focus among them by pressing tab. Please see the :mod:`focus behavior module documentation <kivy.uix.behaviors.focus>` for more information. .. versionadded:: 1.9.0 ''' _requested_keyboard = False
class WindowBase(EventDispatcher): '''WindowBase is an abstract window widget for any window implementation. :Parameters: `fullscreen`: str, one of ('0', '1', 'auto', 'fake') Make the window fullscreen. Check the :mod:`~kivy.config` documentation for a more detailed explanation on the values. `width`: int Width of the window. `height`: int Height of the window. :Events: `on_motion`: etype, motionevent Fired when a new :class:`~kivy.input.motionevent.MotionEvent` is dispatched `on_touch_down`: Fired when a new touch event is initiated. `on_touch_move`: Fired when an existing touch event changes location. `on_touch_up`: Fired when an existing touch event is terminated. `on_draw`: Fired when the :class:`Window` is being drawn. `on_flip`: Fired when the :class:`Window` GL surface is being flipped. `on_rotate`: rotation Fired when the :class:`Window` is being rotated. `on_close`: Fired when the :class:`Window` is closed. `on_request_close`: Fired when the event loop wants to close the window, or if the escape key is pressed and `exit_on_escape` is `True`. If a function bound to this event returns `True`, the window will not be closed. If the the event is triggered because of the keyboard escape key, the keyword argument `source` is dispatched along with a value of `keyboard` to the bound functions. `on_keyboard`: key, scancode, codepoint, modifier Fired when the keyboard is used for input. .. versionchanged:: 1.3.0 The *unicode* parameter has been deprecated in favor of codepoint, and will be removed completely in future versions. `on_key_down`: key, scancode, codepoint Fired when a key pressed. .. versionchanged:: 1.3.0 The *unicode* parameter has been deprecated in favor of codepoint, and will be removed completely in future versions. `on_key_up`: key, scancode, codepoint Fired when a key is released. .. versionchanged:: 1.3.0 The *unicode* parameter has be deprecated in favor of codepoint, and will be removed completely in future versions. `on_dropfile`: str Fired when a file is dropped on the application. .. versionchanged:: 1.9.0 `on_request_close` has been added. ''' __instance = None __initialized = False # private properties _size = ListProperty([0, 0]) _modifiers = ListProperty([]) _rotation = NumericProperty(0) _clearcolor = ObjectProperty([0, 0, 0, 1]) children = ListProperty([]) '''List of the children of this window. :attr:`children` is a :class:`~kivy.properties.ListProperty` instance and defaults to an empty list. Use :meth:`add_widget` and :meth:`remove_widget` to manipulate the list of children. Don't manipulate the list directly unless you know what you are doing. ''' parent = ObjectProperty(None, allownone=True) '''Parent of this window. :attr:`parent` is a :class:`~kivy.properties.ObjectProperty` instance and defaults to None. When created, the parent is set to the window itself. You must take care of it if you are doing a recursive check. ''' icon = StringProperty() def _get_modifiers(self): return self._modifiers modifiers = AliasProperty(_get_modifiers, None) '''List of keyboard modifiers currently active. ''' def _get_size(self): r = self._rotation w, h = self._size if self.softinput_mode == 'resize': h -= self.keyboard_height if r in (0, 180): return w, h return h, w def _set_size(self, size): if self._size != size: r = self._rotation if r in (0, 180): self._size = size else: self._size = size[1], size[0] self.dispatch('on_resize', *size) return True else: return False size = AliasProperty(_get_size, _set_size, bind=('_size', )) '''Get the rotated size of the window. If :attr:`rotation` is set, then the size will change to reflect the rotation. ''' def _get_clearcolor(self): return self._clearcolor def _set_clearcolor(self, value): if value is not None: if type(value) not in (list, tuple): raise Exception('Clearcolor must be a list or tuple') if len(value) != 4: raise Exception('Clearcolor must contain 4 values') self._clearcolor = value clearcolor = AliasProperty(_get_clearcolor, _set_clearcolor, bind=('_clearcolor', )) '''Color used to clear the window. :: from kivy.core.window import Window # red background color Window.clearcolor = (1, 0, 0, 1) # don't clear background at all Window.clearcolor = None .. versionchanged:: 1.7.2 The clearcolor default value is now: (0, 0, 0, 1). ''' # make some property read-only def _get_width(self): r = self._rotation if r == 0 or r == 180: return self._size[0] return self._size[1] width = AliasProperty(_get_width, None, bind=('_rotation', '_size')) '''Rotated window width. :attr:`width` is a read-only :class:`~kivy.properties.AliasProperty`. ''' def _get_height(self): '''Rotated window height''' r = self._rotation kb = self.keyboard_height if self.softinput_mode == 'resize' else 0 if r == 0 or r == 180: return self._size[1] - kb return self._size[0] - kb height = AliasProperty(_get_height, None, bind=('_rotation', '_size')) '''Rotated window height. :attr:`height` is a read-only :class:`~kivy.properties.AliasProperty`. ''' def _get_center(self): return self.width / 2., self.height / 2. center = AliasProperty(_get_center, None, bind=('width', 'height')) '''Center of the rotated window. :attr:`center` is a :class:`~kivy.properties.AliasProperty`. ''' def _get_rotation(self): return self._rotation def _set_rotation(self, x): x = int(x % 360) if x == self._rotation: return if x not in (0, 90, 180, 270): raise ValueError('can rotate only 0, 90, 180, 270 degrees') self._rotation = x if self.initialized is False: return self.dispatch('on_resize', *self.size) self.dispatch('on_rotate', x) rotation = AliasProperty(_get_rotation, _set_rotation, bind=('_rotation', )) '''Get/set the window content rotation. Can be one of 0, 90, 180, 270 degrees. ''' softinput_mode = OptionProperty('', options=('', 'pan', 'scale', 'resize')) '''This specifies the behavior of window contents on display of soft keyboard on mobile platform. Can be one of '', 'pan', 'scale', 'resize'. When '' The main window is left as it is allowing the user to use :attr:`keyboard_height` to manage the window contents the way they want. when 'pan' The main window pans moving the bottom part of the window to be always on top of the keyboard. when 'resize' The window is resized and the contents scaled to fit the remaining space. ..versionadded::1.9.0 :attr:`softinput_mode` is a :class:`OptionProperty` defaults to None. ''' _keyboard_changed = BooleanProperty(False) def _upd_kbd_height(self, *kargs): self._keyboard_changed = not self._keyboard_changed def _get_ios_kheight(self): return 0 def _get_android_kheight(self): global android if not android: import android return android.get_keyboard_height() def _get_kheight(self): if platform == 'android': return self._get_android_kheight() if platform == 'ios': return self._get_ios_kheight() return 0 keyboard_height = AliasProperty(_get_kheight, None, bind=('_keyboard_changed',)) '''Rerturns the height of the softkeyboard/IME on mobile platforms. Will return 0 if not on mobile platform or if IME is not active. ..versionadded:: 1.9.0 :attr:`keyboard_height` is a read-only :class:`AliasProperty` defaults to 0. ''' def _set_system_size(self, size): self._size = size def _get_system_size(self): if self.softinput_mode == 'resize': return self._size[0], self._size[1] - self.keyboard_height return self._size system_size = AliasProperty( _get_system_size, _set_system_size, bind=('_size', )) '''Real size of the window ignoring rotation. ''' fullscreen = OptionProperty(False, options=(True, False, 'auto', 'fake')) '''This property sets the fullscreen mode of the window. Available options are: True, False, 'auto', 'fake'. Check the :mod:`~kivy.config` documentation for a more detailed explanation on the values. .. versionadded:: 1.2.0 ''' mouse_pos = ObjectProperty([0, 0]) '''2d position of the mouse within the window. .. versionadded:: 1.2.0 ''' @property def __self__(self): return self top = NumericProperty(None, allownone=True) left = NumericProperty(None, allownone=True) position = OptionProperty('auto', options=['auto', 'custom']) render_context = ObjectProperty(None) canvas = ObjectProperty(None) title = StringProperty('Kivy') __events__ = ('on_draw', 'on_flip', 'on_rotate', 'on_resize', 'on_close', 'on_motion', 'on_touch_down', 'on_touch_move', 'on_touch_up', 'on_mouse_down', 'on_mouse_move', 'on_mouse_up', 'on_keyboard', 'on_key_down', 'on_key_up', 'on_dropfile', 'on_request_close') def __new__(cls, **kwargs): if cls.__instance is None: cls.__instance = EventDispatcher.__new__(cls) return cls.__instance def __init__(self, **kwargs): kwargs.setdefault('force', False) # don't init window 2 times, # except if force is specified if WindowBase.__instance is not None and not kwargs.get('force'): return self.initialized = False # create a trigger for update/create the window when one of window # property changes self.trigger_create_window = Clock.create_trigger( self.create_window, -1) # Create a trigger for updating the keyboard height self.trigger_keyboard_height = Clock.create_trigger( self._upd_kbd_height, .5) # set the default window parameter according to the configuration if 'fullscreen' not in kwargs: fullscreen = Config.get('graphics', 'fullscreen') if fullscreen not in ('auto', 'fake'): fullscreen = fullscreen.lower() in ('true', '1', 'yes', 'yup') kwargs['fullscreen'] = fullscreen if 'width' not in kwargs: kwargs['width'] = Config.getint('graphics', 'width') if 'height' not in kwargs: kwargs['height'] = Config.getint('graphics', 'height') if 'rotation' not in kwargs: kwargs['rotation'] = Config.getint('graphics', 'rotation') if 'position' not in kwargs: kwargs['position'] = Config.getdefault('graphics', 'position', 'auto') if 'top' in kwargs: kwargs['position'] = 'custom' kwargs['top'] = kwargs['top'] else: kwargs['top'] = Config.getint('graphics', 'top') if 'left' in kwargs: kwargs['position'] = 'custom' kwargs['left'] = kwargs['left'] else: kwargs['left'] = Config.getint('graphics', 'left') kwargs['_size'] = (kwargs.pop('width'), kwargs.pop('height')) super(WindowBase, self).__init__(**kwargs) # bind all the properties that need to recreate the window for prop in ( 'fullscreen', 'position', 'top', 'left', '_size', 'system_size'): self.bind(**{prop: self.trigger_create_window}) self.bind(size=self.trigger_keyboard_height, rotation=self.trigger_keyboard_height) self.bind(softinput_mode=lambda *dt: self.update_viewport(), keyboard_height=lambda *dt: self.update_viewport()) # init privates self._system_keyboard = Keyboard(window=self) self._keyboards = {'system': self._system_keyboard} self._vkeyboard_cls = None self.children = [] self.parent = self # before creating the window import kivy.core.gl # NOQA # configure the window self.create_window() # attach modules + listener event EventLoop.set_window(self) Modules.register_window(self) EventLoop.add_event_listener(self) # manage keyboard(s) self.configure_keyboards() # assign the default context of the widget creation if not hasattr(self, '_context'): self._context = get_current_context() # mark as initialized self.initialized = True def toggle_fullscreen(self): '''Toggle fullscreen on window''' pass def close(self): '''Close the window''' pass def create_window(self, *largs): '''Will create the main window and configure it. .. warning:: This method is called automatically at runtime. If you call it, it will recreate a RenderContext and Canvas. This means you'll have a new graphics tree, and the old one will be unusable. This method exist to permit the creation of a new OpenGL context AFTER closing the first one. (Like using runTouchApp() and stopTouchApp()). This method has only been tested in a unittest environment and is not suitable for Applications. Again, don't use this method unless you know exactly what you are doing! ''' # just to be sure, if the trigger is set, and if this method is # manually called, unset the trigger Clock.unschedule(self.create_window) if not self.initialized: from kivy.core.gl import init_gl init_gl() # create the render context and canvas, only the first time. from kivy.graphics import RenderContext, Canvas self.render_context = RenderContext() self.canvas = Canvas() self.render_context.add(self.canvas) else: # if we get initialized more than once, then reload opengl state # after the second time. # XXX check how it's working on embed platform. if platform == 'linux' or Window.__class__.__name__ == 'WindowSDL': # on linux, it's safe for just sending a resize. self.dispatch('on_resize', *self.system_size) else: # on other platform, window are recreated, we need to reload. from kivy.graphics.context import get_context get_context().reload() Clock.schedule_once(lambda x: self.canvas.ask_update(), 0) self.dispatch('on_resize', *self.system_size) # ensure the gl viewport is correct self.update_viewport() def on_flip(self): '''Flip between buffers (event)''' self.flip() def flip(self): '''Flip between buffers''' pass def _update_childsize(self, instance, value): self.update_childsize([instance]) def add_widget(self, widget): '''Add a widget to a window''' widget.parent = self self.children.insert(0, widget) self.canvas.add(widget.canvas) self.update_childsize([widget]) widget.bind( pos_hint=self._update_childsize, size_hint=self._update_childsize, size=self._update_childsize, pos=self._update_childsize) def remove_widget(self, widget): '''Remove a widget from a window ''' if not widget in self.children: return self.children.remove(widget) self.canvas.remove(widget.canvas) widget.parent = None widget.unbind( pos_hint=self._update_childsize, size_hint=self._update_childsize, size=self._update_childsize, pos=self._update_childsize) def clear(self): '''Clear the window with the background color''' # XXX FIXME use late binding from kivy.graphics.opengl import glClearColor, glClear, \ GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT cc = self._clearcolor if cc is not None: glClearColor(*cc) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT) def set_title(self, title): '''Set the window title. .. versionadded:: 1.0.5 ''' self.title = title def set_icon(self, filename): '''Set the icon of the window. .. versionadded:: 1.0.5 ''' self.icon = filename def to_widget(self, x, y, initial=True, relative=False): return (x, y) def to_window(self, x, y, initial=True, relative=False): return (x, y) def get_root_window(self): return self def get_parent_window(self): return self def get_parent_layout(self): return None def on_draw(self): self.clear() self.render_context.draw() def on_motion(self, etype, me): '''Event called when a Motion Event is received. :Parameters: `etype`: str One of 'begin', 'update', 'end' `me`: :class:`~kivy.input.motionevent.MotionEvent` The Motion Event currently dispatched. ''' if me.is_touch: w, h = self.system_size me.scale_for_screen(w, h, rotation=self._rotation, smode=self.softinput_mode, kheight=self.keyboard_height) if etype == 'begin': self.dispatch('on_touch_down', me) elif etype == 'update': self.dispatch('on_touch_move', me) elif etype == 'end': self.dispatch('on_touch_up', me) def on_touch_down(self, touch): '''Event called when a touch down event is initiated. .. versionchanged:: 1.9.0 The touch `pos` is now transformed to window coordinates before this method is called. Before, the touch `pos` coordinate would be `(0, 0)` when this method was called. ''' for w in self.children[:]: if w.dispatch('on_touch_down', touch): return True def on_touch_move(self, touch): '''Event called when a touch event moves (changes location). .. versionchanged:: 1.9.0 The touch `pos` is now transformed to window coordinates before this method is called. Before, the touch `pos` coordinate would be `(0, 0)` when this method was called. ''' for w in self.children[:]: if w.dispatch('on_touch_move', touch): return True def on_touch_up(self, touch): '''Event called when a touch event is released (terminated). .. versionchanged:: 1.9.0 The touch `pos` is now transformed to window coordinates before this method is called. Before, the touch `pos` coordinate would be `(0, 0)` when this method was called. ''' for w in self.children[:]: if w.dispatch('on_touch_up', touch): return True def on_resize(self, width, height): '''Event called when the window is resized.''' self.update_viewport() def update_viewport(self): from kivy.graphics.opengl import glViewport from kivy.graphics.transformation import Matrix from math import radians w, h = self.system_size smode = self.softinput_mode kheight = self.keyboard_height w2, h2 = w / 2., h / 2. r = radians(self.rotation) x, y = 0, 0 _h = h if smode: y = kheight if smode == 'scale': _h -= kheight # prepare the viewport glViewport(x, y, w, _h) # do projection matrix projection_mat = Matrix() projection_mat.view_clip(0.0, w, 0.0, h, -1.0, 1.0, 0) self.render_context['projection_mat'] = projection_mat # do modelview matrix modelview_mat = Matrix().translate(w2, h2, 0) modelview_mat = modelview_mat.multiply(Matrix().rotate(r, 0, 0, 1)) w, h = self.size w2, h2 = w / 2., h / 2. modelview_mat = modelview_mat.multiply(Matrix().translate(-w2, -h2, 0)) self.render_context['modelview_mat'] = modelview_mat # redraw canvas self.canvas.ask_update() # and update childs self.update_childsize() def update_childsize(self, childs=None): width, height = self.size if childs is None: childs = self.children for w in childs: shw, shh = w.size_hint if shw and shh: w.size = shw * width, shh * height elif shw: w.width = shw * width elif shh: w.height = shh * height for key, value in w.pos_hint.items(): if key == 'x': w.x = value * width elif key == 'right': w.right = value * width elif key == 'y': w.y = value * height elif key == 'top': w.top = value * height elif key == 'center_x': w.center_x = value * width elif key == 'center_y': w.center_y = value * height def screenshot(self, name='screenshot{:04d}.png'): '''Save the actual displayed image in a file ''' i = 0 path = None if name != 'screenshot{:04d}.png': _ext = name.split('.')[-1] name = ''.join((name[:-(len(_ext) + 1)], '{:04d}.', _ext)) while True: i += 1 path = join(getcwd(), name.format(i)) if not exists(path): break return path def on_rotate(self, rotation): '''Event called when the screen has been rotated. ''' pass def on_close(self, *largs): '''Event called when the window is closed''' Modules.unregister_window(self) EventLoop.remove_event_listener(self) def on_request_close(self, *largs, **kwargs): '''Event called before we close the window. If a bound function returns `True`, the window will not be closed. If the the event is triggered because of the keyboard escape key, the keyword argument `source` is dispatched along with a value of `keyboard` to the bound functions. .. warning:: When the bound function returns True the window will not be closed, so use with care because the user would not be able to close the program, even if the red X is clicked. ''' pass def on_mouse_down(self, x, y, button, modifiers): '''Event called when the mouse is used (pressed/released)''' pass def on_mouse_move(self, x, y, modifiers): '''Event called when the mouse is moved with buttons pressed''' pass def on_mouse_up(self, x, y, button, modifiers): '''Event called when the mouse is moved with buttons pressed''' pass def on_keyboard(self, key, scancode=None, codepoint=None, modifier=None, **kwargs): '''Event called when keyboard is used. .. warning:: Some providers may omit `scancode`, `codepoint` and/or `modifier`! ''' if 'unicode' in kwargs: Logger.warning("The use of the unicode parameter is deprecated, " "and will be removed in future versions. Use " "codepoint instead, which has identical " "semantics.") # Quit if user presses ESC or the typical OSX shortcuts CMD+q or CMD+w # TODO If just CMD+w is pressed, only the window should be closed. is_osx = platform == 'darwin' if WindowBase.on_keyboard.exit_on_escape: if key == 27 or all([is_osx, key in [113, 119], modifier == 1024]): if not self.dispatch('on_request_close', source='keyboard'): stopTouchApp() self.close() return True if Config: on_keyboard.exit_on_escape = Config.getboolean('kivy', 'exit_on_escape') def __exit(section, name, value): WindowBase.__dict__['on_keyboard'].exit_on_escape = \ Config.getboolean('kivy', 'exit_on_escape') Config.add_callback(__exit, 'kivy', 'exit_on_escape') def on_key_down(self, key, scancode=None, codepoint=None, modifier=None, **kwargs): '''Event called when a key is down (same arguments as on_keyboard)''' if 'unicode' in kwargs: Logger.warning("The use of the unicode parameter is deprecated, " "and will be removed in future versions. Use " "codepoint instead, which has identical " "semantics.") def on_key_up(self, key, scancode=None, codepoint=None, modifier=None, **kwargs): '''Event called when a key is released (same arguments as on_keyboard) ''' if 'unicode' in kwargs: Logger.warning("The use of the unicode parameter is deprecated, " "and will be removed in future versions. Use " "codepoint instead, which has identical " "semantics.") def on_dropfile(self, filename): '''Event called when a file is dropped on the application. .. warning:: This event is currently used only on MacOSX with a patched version of pygame, but is left in place for further evolution (ios, android etc.) .. versionadded:: 1.2.0 ''' pass @reify def dpi(self): '''Return the DPI of the screen. If the implementation doesn't support any DPI lookup, it will just return 96. .. warning:: This value is not cross-platform. Use :attr:`kivy.base.EventLoop.dpi` instead. ''' return 96. def configure_keyboards(self): # Configure how to provide keyboards (virtual or not) # register system keyboard to listening keys from window sk = self._system_keyboard self.bind( on_key_down=sk._on_window_key_down, on_key_up=sk._on_window_key_up) # use the device's real keyboard self.use_syskeyboard = True # use the device's real keyboard self.allow_vkeyboard = False # one single vkeyboard shared between all widgets self.single_vkeyboard = True # the single vkeyboard is always sitting at the same position self.docked_vkeyboard = False # now read the configuration mode = Config.get('kivy', 'keyboard_mode') if mode not in ('', 'system', 'dock', 'multi', 'systemanddock', 'systemandmulti'): Logger.critical('Window: unknown keyboard mode %r' % mode) # adapt mode according to the configuration if mode == 'system': self.use_syskeyboard = True self.allow_vkeyboard = False self.single_vkeyboard = True self.docked_vkeyboard = False elif mode == 'dock': self.use_syskeyboard = False self.allow_vkeyboard = True self.single_vkeyboard = True self.docked_vkeyboard = True elif mode == 'multi': self.use_syskeyboard = False self.allow_vkeyboard = True self.single_vkeyboard = False self.docked_vkeyboard = False elif mode == 'systemanddock': self.use_syskeyboard = True self.allow_vkeyboard = True self.single_vkeyboard = True self.docked_vkeyboard = True elif mode == 'systemandmulti': self.use_syskeyboard = True self.allow_vkeyboard = True self.single_vkeyboard = False self.docked_vkeyboard = False Logger.info( 'Window: virtual keyboard %sallowed, %s, %s' % ( '' if self.allow_vkeyboard else 'not ', 'single mode' if self.single_vkeyboard else 'multiuser mode', 'docked' if self.docked_vkeyboard else 'not docked')) def set_vkeyboard_class(self, cls): '''.. versionadded:: 1.0.8 Set the VKeyboard class to use. If set to None, it will use the :class:`kivy.uix.vkeyboard.VKeyboard`. ''' self._vkeyboard_cls = cls def release_all_keyboards(self): '''.. versionadded:: 1.0.8 This will ensure that no virtual keyboard / system keyboard is requested. All instances will be closed. ''' for key in list(self._keyboards.keys())[:]: keyboard = self._keyboards[key] if keyboard: keyboard.release() def request_keyboard(self, callback, target, input_type='text'): '''.. versionadded:: 1.0.4 Internal widget method to request the keyboard. This method is rarely required by the end-user as it is handled automatically by the :class:`~kivy.uix.textinput.TextInput`. We expose it in case you want to handle the keyboard manually for unique input scenarios. A widget can request the keyboard, indicating a callback to call when the keyboard is released (or taken by another widget). :Parameters: `callback`: func Callback that will be called when the keyboard is closed. This can be because somebody else requested the keyboard or the user closed it. `target`: Widget Attach the keyboard to the specified `target`. This should be the widget that requested the keyboard. Ensure you have a different target attached to each keyboard if you're working in a multi user mode. .. versionadded:: 1.0.8 `input_type`: string Choose the type of soft keyboard to request. Can be one of 'text', 'number', 'url', 'mail', 'datetime', 'tel', 'address'. .. note:: `input_type` is currently only honored on mobile devices. .. versionadded:: 1.8.0 :Return: An instance of :class:`Keyboard` containing the callback, target, and if the configuration allows it, a :class:`~kivy.uix.vkeyboard.VKeyboard` instance attached as a *.widget* property. .. note:: The behavior of this function is heavily influenced by the current `keyboard_mode`. Please see the Config's :ref:`configuration tokens <configuration-tokens>` section for more information. ''' # release any previous keyboard attached. self.release_keyboard(target) # if we can use virtual vkeyboard, activate it. if self.allow_vkeyboard: keyboard = None # late import global VKeyboard if VKeyboard is None and self._vkeyboard_cls is None: from kivy.uix.vkeyboard import VKeyboard self._vkeyboard_cls = VKeyboard # if the keyboard doesn't exist, create it. key = 'single' if self.single_vkeyboard else target if key not in self._keyboards: vkeyboard = self._vkeyboard_cls() keyboard = Keyboard(widget=vkeyboard, window=self) vkeyboard.bind( on_key_down=keyboard._on_vkeyboard_key_down, on_key_up=keyboard._on_vkeyboard_key_up) self._keyboards[key] = keyboard else: keyboard = self._keyboards[key] # configure vkeyboard keyboard.target = keyboard.widget.target = target keyboard.callback = keyboard.widget.callback = callback # add to the window self.add_widget(keyboard.widget) # only after add, do dock mode keyboard.widget.docked = self.docked_vkeyboard keyboard.widget.setup_mode() else: # system keyboard, just register the callback. keyboard = self._system_keyboard keyboard.callback = callback keyboard.target = target # use system (hardware) keyboard according to flag if self.allow_vkeyboard and self.use_syskeyboard: self.unbind( on_key_down=keyboard._on_window_key_down, on_key_up=keyboard._on_window_key_up) self.bind( on_key_down=keyboard._on_window_key_down, on_key_up=keyboard._on_window_key_up) return keyboard def release_keyboard(self, target=None): '''.. versionadded:: 1.0.4 Internal method for the widget to release the real-keyboard. Check :meth:`request_keyboard` to understand how it works. ''' if self.allow_vkeyboard: key = 'single' if self.single_vkeyboard else target if key not in self._keyboards: return keyboard = self._keyboards[key] callback = keyboard.callback if callback: keyboard.callback = None callback() keyboard.target = None self.remove_widget(keyboard.widget) if key != 'single' and key in self._keyboards: del self._keyboards[key] elif self._system_keyboard.callback: # this way will prevent possible recursion. callback = self._system_keyboard.callback self._system_keyboard.callback = None callback() return True
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))
This code is still experimental, and its API is subject to change in a future version. ''' __all__ = ('CompoundSelectionBehavior', ) from time import time from os import environ from kivy.config import Config from kivy.properties import NumericProperty, BooleanProperty, ListProperty if 'KIVY_DOC' not in environ: _is_desktop = Config.getboolean('kivy', 'desktop') else: _is_desktop = False class CompoundSelectionBehavior(object): '''The Selection behavior `mixin <https://en.wikipedia.org/wiki/Mixin>`_ implements the logic behind keyboard and touch selection of selectable widgets managed by the derived widget. Please see the :mod:`compound selection behaviors module <kivy.uix.behaviors.compoundselection>` documentation for more information. .. versionadded:: 1.9.0 '''
def __init__(self, **kwargs): kwargs.setdefault('force', False) # don't init window 2 times, # except if force is specified if WindowBase.__instance is not None and not kwargs.get('force'): return self.initialized = False self._is_desktop = Config.getboolean('kivy', 'desktop') # create a trigger for update/create the window when one of window # property changes self.trigger_create_window = Clock.create_trigger( self.create_window, -1) # Create a trigger for updating the keyboard height self.trigger_keyboard_height = Clock.create_trigger( self._upd_kbd_height, .5) # set the default window parameter according to the configuration if 'borderless' not in kwargs: kwargs['borderless'] = Config.getboolean('graphics', 'borderless') if 'fullscreen' not in kwargs: fullscreen = Config.get('graphics', 'fullscreen') if fullscreen not in ('auto', 'fake'): fullscreen = fullscreen.lower() in ('true', '1', 'yes', 'yup') kwargs['fullscreen'] = fullscreen if 'width' not in kwargs: kwargs['width'] = Config.getint('graphics', 'width') if 'height' not in kwargs: kwargs['height'] = Config.getint('graphics', 'height') if 'rotation' not in kwargs: kwargs['rotation'] = Config.getint('graphics', 'rotation') if 'position' not in kwargs: kwargs['position'] = Config.getdefault('graphics', 'position', 'auto') if 'top' in kwargs: kwargs['position'] = 'custom' kwargs['top'] = kwargs['top'] else: kwargs['top'] = Config.getint('graphics', 'top') if 'left' in kwargs: kwargs['position'] = 'custom' kwargs['left'] = kwargs['left'] else: kwargs['left'] = Config.getint('graphics', 'left') kwargs['_size'] = (kwargs.pop('width'), kwargs.pop('height')) super(WindowBase, self).__init__(**kwargs) # bind all the properties that need to recreate the window self._bind_create_window() self.bind(size=self.trigger_keyboard_height, rotation=self.trigger_keyboard_height) self.bind(softinput_mode=lambda *dt: self.update_viewport(), keyboard_height=lambda *dt: self.update_viewport()) # init privates self._system_keyboard = Keyboard(window=self) self._keyboards = {'system': self._system_keyboard} self._vkeyboard_cls = None self.children = [] self.parent = self # before creating the window import kivy.core.gl # NOQA # configure the window self.create_window() # attach modules + listener event EventLoop.set_window(self) Modules.register_window(self) EventLoop.add_event_listener(self) # manage keyboard(s) self.configure_keyboards() # assign the default context of the widget creation if not hasattr(self, '_context'): self._context = get_current_context() # mark as initialized self.initialized = True
def create_window(self, *largs): # ensure the mouse is still not up after window creation, otherwise, we # have some weird bugs self.dispatch('on_mouse_up', 0, 0, 'all', []) # force display to show (available only for fullscreen) displayidx = Config.getint('graphics', 'display') if 'SDL_VIDEO_FULLSCREEN_HEAD' not in environ and displayidx != -1: environ['SDL_VIDEO_FULLSCREEN_HEAD'] = '%d' % displayidx # init some opengl, same as before. self.flags = pygame.HWSURFACE | pygame.OPENGL | pygame.DOUBLEBUF # right now, activate resizable window only on linux. # on window / macosx, the opengl context is lost, and we need to # reconstruct everything. Check #168 for a state of the work. if platform in ('linux', 'macosx', 'win') and \ Config.getboolean('graphics', 'resizable'): self.flags |= pygame.RESIZABLE try: pygame.display.init() except pygame.error as e: raise CoreCriticalException(e.message) multisamples = Config.getint('graphics', 'multisamples') if multisamples > 0: pygame.display.gl_set_attribute(pygame.GL_MULTISAMPLEBUFFERS, 1) pygame.display.gl_set_attribute(pygame.GL_MULTISAMPLESAMPLES, multisamples) pygame.display.gl_set_attribute(pygame.GL_DEPTH_SIZE, 16) pygame.display.gl_set_attribute(pygame.GL_STENCIL_SIZE, 1) pygame.display.set_caption(self.title) if self.position == 'auto': self._pos = None elif self.position == 'custom': self._pos = self.left, self.top else: raise ValueError('position token in configuration accept only ' '"auto" or "custom"') if self._fake_fullscreen: if not self.borderless: self.fullscreen = self._fake_fullscreen = False elif not self.fullscreen or self.fullscreen == 'auto': self.borderless = self._fake_fullscreen = False if self.fullscreen == 'fake': self.borderless = self._fake_fullscreen = True Logger.warning("The 'fake' fullscreen option has been " "deprecated, use Window.borderless or the " "borderless Config option instead.") if self.fullscreen == 'fake' or self.borderless: Logger.debug('WinPygame: Set window to borderless mode.') self.flags |= pygame.NOFRAME # If no position set in borderless mode, we always need # to set the position. So use 0, 0. if self._pos is None: self._pos = (0, 0) environ['SDL_VIDEO_WINDOW_POS'] = '%d,%d' % self._pos elif self.fullscreen in ('auto', True): Logger.debug('WinPygame: Set window to fullscreen mode') self.flags |= pygame.FULLSCREEN elif self._pos is not None: environ['SDL_VIDEO_WINDOW_POS'] = '%d,%d' % self._pos # never stay with a None pos, application using w.center will be fired. self._pos = (0, 0) # prepare keyboard repeat_delay = int(Config.get('kivy', 'keyboard_repeat_delay')) repeat_rate = float(Config.get('kivy', 'keyboard_repeat_rate')) pygame.key.set_repeat(repeat_delay, int(1000. / repeat_rate)) # set window icon before calling set_mode try: filename_icon = self.icon or Config.get('kivy', 'window_icon') if filename_icon == '': logo_size = 32 if platform == 'macosx': logo_size = 512 elif platform == 'win': logo_size = 64 filename_icon = 'kivy-icon-{}.png'.format(logo_size) filename_icon = resource_find( join(kivy_data_dir, 'logo', filename_icon)) self.set_icon(filename_icon) except: Logger.exception('Window: cannot set icon') # try to use mode with multisamples try: self._pygame_set_mode() except pygame.error as e: if multisamples: Logger.warning('WinPygame: Video: failed (multisamples=%d)' % multisamples) Logger.warning('WinPygame: trying without antialiasing') pygame.display.gl_set_attribute( pygame.GL_MULTISAMPLEBUFFERS, 0) pygame.display.gl_set_attribute( pygame.GL_MULTISAMPLESAMPLES, 0) multisamples = 0 try: self._pygame_set_mode() except pygame.error as e: raise CoreCriticalException(e.message) else: raise CoreCriticalException(e.message) if pygame.RESIZABLE & self.flags: self._pygame_set_mode() info = pygame.display.Info() self._size = (info.current_w, info.current_h) # self.dispatch('on_resize', *self._size) # in order to debug futur issue with pygame/display, let's show # more debug output. Logger.debug('Window: Display driver ' + pygame.display.get_driver()) Logger.debug('Window: Actual window size: %dx%d', info.current_w, info.current_h) if platform != 'android': # unsupported platform, such as android that doesn't support # gl_get_attribute. Logger.debug( 'Window: Actual color bits r%d g%d b%d a%d', pygame.display.gl_get_attribute(pygame.GL_RED_SIZE), pygame.display.gl_get_attribute(pygame.GL_GREEN_SIZE), pygame.display.gl_get_attribute(pygame.GL_BLUE_SIZE), pygame.display.gl_get_attribute(pygame.GL_ALPHA_SIZE)) Logger.debug( 'Window: Actual depth bits: %d', pygame.display.gl_get_attribute(pygame.GL_DEPTH_SIZE)) Logger.debug( 'Window: Actual stencil bits: %d', pygame.display.gl_get_attribute(pygame.GL_STENCIL_SIZE)) Logger.debug( 'Window: Actual multisampling samples: %d', pygame.display.gl_get_attribute(pygame.GL_MULTISAMPLESAMPLES)) super(WindowPygame, self).create_window() # set mouse visibility self._set_cursor_state(self.show_cursor) # if we are on android platform, automatically create hooks if android: from kivy.support import install_android install_android()
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))
multisamples = 0 try: self._pygame_set_mode() except pygame.error, e: raise CoreCriticalException(e.message) else: raise CoreCriticalException(e.message) info = pygame.display.Info() self._size = (info.current_w, info.current_h) # self.dispatch('on_resize', *self._size) super(WindowPygame, self).create_window() # set mouse visibility pygame.mouse.set_visible(Config.getboolean("graphics", "show_cursor")) # if we are on android platform, automaticly create hooks if android: from kivy.support import install_android install_android() def close(self): pygame.display.quit() self.dispatch("on_close") def on_title(self, instance, value): if self.initialized: pygame.display.set_caption(self.title)
def create_window(self, *largs): # ensure the mouse is still not up after window creation, otherwise, we # have some weird bugs self.dispatch("on_mouse_up", 0, 0, "all", []) # force display to show (available only for fullscreen) displayidx = Config.getint("graphics", "display") if not "SDL_VIDEO_FULLSCREEN_HEAD" in environ and displayidx != -1: environ["SDL_VIDEO_FULLSCREEN_HEAD"] = "%d" % displayidx # init some opengl, same as before. self.flags = pygame.HWSURFACE | pygame.OPENGL | pygame.DOUBLEBUF # right now, activate resizable window only on linux. # on window / macosx, the opengl context is lost, and we need to # reconstruct everything. Check #168 for a state of the work. if platform in ("linux", "macosx", "win") and Config.getboolean("graphics", "resizable"): self.flags |= pygame.RESIZABLE try: pygame.display.init() except pygame.error as e: raise CoreCriticalException(e.message) multisamples = Config.getint("graphics", "multisamples") if multisamples > 0: pygame.display.gl_set_attribute(pygame.GL_MULTISAMPLEBUFFERS, 1) pygame.display.gl_set_attribute(pygame.GL_MULTISAMPLESAMPLES, multisamples) pygame.display.gl_set_attribute(pygame.GL_DEPTH_SIZE, 16) pygame.display.gl_set_attribute(pygame.GL_STENCIL_SIZE, 1) pygame.display.set_caption(self.title) if self.position == "auto": self._pos = None elif self.position == "custom": self._pos = self.left, self.top else: raise ValueError("position token in configuration accept only " '"auto" or "custom"') if self._fake_fullscreen: if not self.borderless: self.fullscreen = self._fake_fullscreen = False elif not self.fullscreen or self.fullscreen == "auto": self.borderless = self._fake_fullscreen = False if self.fullscreen == "fake": self.borderless = self._fake_fullscreen = True Logger.warning( "The 'fake' fullscreen option has been " "deprecated, use Window.borderless or the " "borderless Config option instead." ) if self.fullscreen == "fake" or self.borderless: Logger.debug("WinPygame: Set window to borderless mode.") self.flags |= pygame.NOFRAME # If no position set in borderless mode, we always need # to set the position. So use 0, 0. if self._pos is None: self._pos = (0, 0) environ["SDL_VIDEO_WINDOW_POS"] = "%d,%d" % self._pos elif self.fullscreen in ("auto", True): Logger.debug("WinPygame: Set window to fullscreen mode") self.flags |= pygame.FULLSCREEN elif self._pos is not None: environ["SDL_VIDEO_WINDOW_POS"] = "%d,%d" % self._pos # never stay with a None pos, application using w.center will be fired. self._pos = (0, 0) # prepare keyboard repeat_delay = int(Config.get("kivy", "keyboard_repeat_delay")) repeat_rate = float(Config.get("kivy", "keyboard_repeat_rate")) pygame.key.set_repeat(repeat_delay, int(1000.0 / repeat_rate)) # set window icon before calling set_mode try: filename_icon = self.icon or Config.get("kivy", "window_icon") if filename_icon == "": logo_size = 32 if platform == "macosx": logo_size = 512 elif platform == "win": logo_size = 64 filename_icon = "kivy-icon-{}.png".format(logo_size) filename_icon = resource_find(join(kivy_data_dir, "logo", filename_icon)) self.set_icon(filename_icon) except: Logger.exception("Window: cannot set icon") # try to use mode with multisamples try: self._pygame_set_mode() except pygame.error as e: if multisamples: Logger.warning("WinPygame: Video: failed (multisamples=%d)" % multisamples) Logger.warning("WinPygame: trying without antialiasing") pygame.display.gl_set_attribute(pygame.GL_MULTISAMPLEBUFFERS, 0) pygame.display.gl_set_attribute(pygame.GL_MULTISAMPLESAMPLES, 0) multisamples = 0 try: self._pygame_set_mode() except pygame.error as e: raise CoreCriticalException(e.message) else: raise CoreCriticalException(e.message) if pygame.RESIZABLE & self.flags: self._pygame_set_mode() info = pygame.display.Info() self._size = (info.current_w, info.current_h) # self.dispatch('on_resize', *self._size) # in order to debug futur issue with pygame/display, let's show # more debug output. Logger.debug("Window: Display driver " + pygame.display.get_driver()) Logger.debug("Window: Actual window size: %dx%d", info.current_w, info.current_h) if platform != "android": # unsupported platform, such as android that doesn't support # gl_get_attribute. Logger.debug( "Window: Actual color bits r%d g%d b%d a%d", pygame.display.gl_get_attribute(pygame.GL_RED_SIZE), pygame.display.gl_get_attribute(pygame.GL_GREEN_SIZE), pygame.display.gl_get_attribute(pygame.GL_BLUE_SIZE), pygame.display.gl_get_attribute(pygame.GL_ALPHA_SIZE), ) Logger.debug("Window: Actual depth bits: %d", pygame.display.gl_get_attribute(pygame.GL_DEPTH_SIZE)) Logger.debug("Window: Actual stencil bits: %d", pygame.display.gl_get_attribute(pygame.GL_STENCIL_SIZE)) Logger.debug( "Window: Actual multisampling samples: %d", pygame.display.gl_get_attribute(pygame.GL_MULTISAMPLESAMPLES), ) super(WindowPygame, self).create_window() # set mouse visibility self._set_cursor_state(self.show_cursor) # if we are on android platform, automaticly create hooks if android: from kivy.support import install_android install_android()
def create_window(self): params = self.params # force display to show (available only for fullscreen) displayidx = Config.getint('graphics', 'display') if not 'SDL_VIDEO_FULLSCREEN_HEAD' in os.environ and displayidx != -1: os.environ['SDL_VIDEO_FULLSCREEN_HEAD'] = '%d' % displayidx # init some opengl, same as before. self.flags = pygame.HWSURFACE | pygame.OPENGL | \ pygame.DOUBLEBUF | pygame.RESIZABLE pygame.display.init() multisamples = Config.getint('graphics', 'multisamples') if multisamples > 0: pygame.display.gl_set_attribute(pygame.GL_MULTISAMPLEBUFFERS, 1) pygame.display.gl_set_attribute(pygame.GL_MULTISAMPLESAMPLES, multisamples) pygame.display.gl_set_attribute(pygame.GL_DEPTH_SIZE, 16) pygame.display.gl_set_attribute(pygame.GL_STENCIL_SIZE, 1) pygame.display.gl_set_attribute(pygame.GL_ALPHA_SIZE, 8) pygame.display.set_caption('kivy') if params['position'] == 'auto': self._pos = None elif params['position'] == 'custom': self._pos = params['left'], params['top'] else: raise ValueError('position token in configuration accept only ' '"auto" or "custom"') self._fullscreenmode = params['fullscreen'] if self._fullscreenmode == 'fake': Logger.debug('WinPygame: Set window to fake fullscreen mode') self.flags |= pygame.NOFRAME # if no position set, in fake mode, we always need to set the # position. so replace 0, 0. if self._pos is None: self._pos = (0, 0) os.environ['SDL_VIDEO_WINDOW_POS'] = '%d,%d' % self._pos elif self._fullscreenmode: Logger.debug('WinPygame: Set window to fullscreen mode') self.flags |= pygame.FULLSCREEN elif self._pos is not None: os.environ['SDL_VIDEO_WINDOW_POS'] = '%d,%d' % self._pos # never stay with a None pos, application using w.center will be fired. self._pos = (0, 0) # prepare keyboard repeat_delay = int(Config.get('kivy', 'keyboard_repeat_delay')) repeat_rate = float(Config.get('kivy', 'keyboard_repeat_rate')) pygame.key.set_repeat(repeat_delay, int(1000. / repeat_rate)) # set window icon before calling set_mode filename_icon = Config.get('kivy', 'window_icon') self.set_icon(filename_icon) # init ourself size + setmode # before calling on_resize self._size = params['width'], params['height'] # try to use mode with multisamples try: self._pygame_set_mode() except pygame.error: if multisamples: Logger.warning('WinPygame: Video: failed (multisamples=%d)' % multisamples) Logger.warning('WinPygame: trying without antialiasing') pygame.display.gl_set_attribute(pygame.GL_MULTISAMPLEBUFFERS, 0) pygame.display.gl_set_attribute(pygame.GL_MULTISAMPLESAMPLES, 0) multisamples = 0 self._pygame_set_mode() else: Logger.warning('WinPygame: Video setup failed :-(') raise super(WindowPygame, self).create_window() # set mouse visibility pygame.mouse.set_visible( Config.getboolean('graphics', 'show_cursor')) # set rotation self.rotation = params['rotation']
def create_window(self, *largs): if self._fake_fullscreen: if not self.borderless: self.fullscreen = self._fake_fullscreen = False elif not self.fullscreen or self.fullscreen == 'auto': self.custom_titlebar = \ self.borderless = self._fake_fullscreen = False elif self.custom_titlebar: if platform == 'win': # use custom behaviour # To handle aero snapping and rounded corners self.borderless = False if self.fullscreen == 'fake': self.borderless = self._fake_fullscreen = True Logger.warning("The 'fake' fullscreen option has been " "deprecated, use Window.borderless or the " "borderless Config option instead.") if not self.initialized: if self.position == 'auto': pos = None, None elif self.position == 'custom': pos = self.left, self.top # ensure we have an event filter self._win.set_event_filter(self._event_filter) # setup window w, h = self.system_size resizable = Config.getboolean('graphics', 'resizable') state = (Config.get('graphics', 'window_state') if self._is_desktop else None) self.system_size = _size = self._win.setup_window( pos[0], pos[1], w, h, self.borderless, self.fullscreen, resizable, state, self.get_gl_backend_name()) # calculate density/dpi if platform == 'win': from ctypes import windll self._density = 1. try: hwnd = windll.user32.GetActiveWindow() self.dpi = float(windll.user32.GetDpiForWindow(hwnd)) except AttributeError: pass else: sz = self._win._get_gl_size()[0] self._density = density = sz / _size[0] if self._is_desktop and self.size[0] != _size[0]: self.dpi = density * 96. # never stay with a None pos, application using w.center # will be fired. self._pos = (0, 0) self._set_minimum_size() self._set_allow_screensaver() if state == 'hidden': self._focus = False else: w, h = self.system_size self._win.resize_window(w, h) if platform == 'win': if self.custom_titlebar: # check dragging+resize or just dragging if Config.getboolean('graphics', 'resizable'): import win32con import ctypes self._win.set_border_state(False) # make windows dispatch, # WM_NCCALCSIZE explicitly ctypes.windll.user32.SetWindowPos( self._win.get_window_info().window, win32con.HWND_TOP, *self._win.get_window_pos(), *self.system_size, win32con.SWP_FRAMECHANGED) else: self._win.set_border_state(True) else: self._win.set_border_state(self.borderless) else: self._win.set_border_state(self.borderless or self.custom_titlebar) self._win.set_fullscreen_mode(self.fullscreen) super(WindowSDL, self).create_window() # set mouse visibility self._set_cursor_state(self.show_cursor) if self.initialized: return # auto add input provider Logger.info('Window: auto add sdl2 input provider') from kivy.base import EventLoop SDL2MotionEventProvider.win = self EventLoop.add_input_provider(SDL2MotionEventProvider('sdl', '')) # set window icon before calling set_mode try: filename_icon = self.icon or Config.get('kivy', 'window_icon') if filename_icon == '': logo_size = 32 if platform == 'macosx': logo_size = 512 elif platform == 'win': logo_size = 64 filename_icon = 'kivy-icon-{}.png'.format(logo_size) filename_icon = resource_find( join(kivy_data_dir, 'logo', filename_icon)) self.set_icon(filename_icon) except: Logger.exception('Window: cannot set icon') if platform == 'win' and self._win_dpi_watch is None: self._win_dpi_watch = _WindowsSysDPIWatch(window=self) self._win_dpi_watch.start()
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': 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 # 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 create_window(self): params = self.params # force display to show (available only for fullscreen) displayidx = Config.getint('graphics', 'display') if not 'SDL_VIDEO_FULLSCREEN_HEAD' in os.environ and displayidx != -1: os.environ['SDL_VIDEO_FULLSCREEN_HEAD'] = '%d' % displayidx # init some opengl, same as before. self.flags = pygame.HWSURFACE | pygame.OPENGL | pygame.DOUBLEBUF pygame.display.init() multisamples = Config.getint('graphics', 'multisamples') if multisamples > 0: pygame.display.gl_set_attribute(pygame.GL_MULTISAMPLEBUFFERS, 1) pygame.display.gl_set_attribute(pygame.GL_MULTISAMPLESAMPLES, multisamples) pygame.display.gl_set_attribute(pygame.GL_DEPTH_SIZE, 16) pygame.display.gl_set_attribute(pygame.GL_STENCIL_SIZE, 1) pygame.display.gl_set_attribute(pygame.GL_ALPHA_SIZE, 8) pygame.display.set_caption('kivy') if params['position'] == 'auto': self._pos = None elif params['position'] == 'custom': self._pos = params['left'], params['top'] else: raise ValueError('position token in configuration accept only ' '"auto" or "custom"') self._fullscreenmode = params['fullscreen'] if self._fullscreenmode == 'fake': Logger.debug('WinPygame: Set window to fake fullscreen mode') self.flags |= pygame.NOFRAME # if no position set, in fake mode, we always need to set the # position. so replace 0, 0. if self._pos is None: self._pos = (0, 0) os.environ['SDL_VIDEO_WINDOW_POS'] = '%d,%d' % self._pos elif self._fullscreenmode: Logger.debug('WinPygame: Set window to fullscreen mode') self.flags |= pygame.FULLSCREEN elif self._pos is not None: os.environ['SDL_VIDEO_WINDOW_POS'] = '%d,%d' % self._pos # never stay with a None pos, application using w.center will be fired. self._pos = (0, 0) # prepare keyboard repeat_delay = int(Config.get('kivy', 'keyboard_repeat_delay')) repeat_rate = float(Config.get('kivy', 'keyboard_repeat_rate')) pygame.key.set_repeat(repeat_delay, int(1000. / repeat_rate)) # set window icon before calling set_mode filename_icon = Config.get('kivy', 'window_icon') if exists(filename_icon): icon = pygame.image.load(filename_icon) pygame.display.set_icon(icon) # init ourself size + setmode # before calling on_resize self._size = params['width'], params['height'] # try to use mode with multisamples try: self._pygame_set_mode() except pygame.error: if multisamples: Logger.warning('WinPygame: Video: failed (multisamples=%d)' % multisamples) Logger.warning('Video: trying without antialiasing') pygame.display.gl_set_attribute(pygame.GL_MULTISAMPLEBUFFERS, 0) pygame.display.gl_set_attribute(pygame.GL_MULTISAMPLESAMPLES, 0) multisamples = 0 self._pygame_set_mode() else: Logger.warning('WinPygame: Video setup failed :-(') raise super(WindowPygame, self).create_window() # set mouse visibility pygame.mouse.set_visible( Config.getboolean('graphics', 'show_cursor')) # set rotation self.rotation = params['rotation']
def __exit(section, name, value): WindowBase.__dict__['on_keyboard'].exit_on_escape = \ Config.getboolean('kivy', 'exit_on_escape')
def __init__(self, **kwargs): force = kwargs.pop("force", False) # don't init window 2 times, # except if force is specified if WindowBase.__instance is not None and not force: return self.initialized = False self._is_desktop = Config.getboolean("kivy", "desktop") # create a trigger for update/create the window when one of window # property changes self.trigger_create_window = Clock.create_trigger(self.create_window, -1) # Create a trigger for updating the keyboard height self.trigger_keyboard_height = Clock.create_trigger(self._upd_kbd_height, 0.5) # set the default window parameter according to the configuration if "borderless" not in kwargs: kwargs["borderless"] = Config.getboolean("graphics", "borderless") if "fullscreen" not in kwargs: fullscreen = Config.get("graphics", "fullscreen") if fullscreen not in ("auto", "fake"): fullscreen = fullscreen.lower() in ("true", "1", "yes", "yup") kwargs["fullscreen"] = fullscreen if "width" not in kwargs: kwargs["width"] = Config.getint("graphics", "width") if "height" not in kwargs: kwargs["height"] = Config.getint("graphics", "height") if "rotation" not in kwargs: kwargs["rotation"] = Config.getint("graphics", "rotation") if "position" not in kwargs: kwargs["position"] = Config.getdefault("graphics", "position", "auto") if "top" in kwargs: kwargs["position"] = "custom" kwargs["top"] = kwargs["top"] else: kwargs["top"] = Config.getint("graphics", "top") if "left" in kwargs: kwargs["position"] = "custom" kwargs["left"] = kwargs["left"] else: kwargs["left"] = Config.getint("graphics", "left") kwargs["_size"] = (kwargs.pop("width"), kwargs.pop("height")) super(WindowBase, self).__init__(**kwargs) # bind all the properties that need to recreate the window self._bind_create_window() self.bind(size=self.trigger_keyboard_height, rotation=self.trigger_keyboard_height) self.bind(softinput_mode=lambda *dt: self.update_viewport(), keyboard_height=lambda *dt: self.update_viewport()) # init privates self._system_keyboard = Keyboard(window=self) self._keyboards = {"system": self._system_keyboard} self._vkeyboard_cls = None self.children = [] self.parent = self # before creating the window import kivy.core.gl # NOQA # configure the window self.create_window() # attach modules + listener event EventLoop.set_window(self) Modules.register_window(self) EventLoop.add_event_listener(self) # manage keyboard(s) self.configure_keyboards() # assign the default context of the widget creation if not hasattr(self, "_context"): self._context = get_current_context() # mark as initialized self.initialized = True
Logger.debug('Window: Actual color bits r%d g%d b%d a%d', pygame.display.gl_get_attribute(pygame.GL_RED_SIZE), pygame.display.gl_get_attribute(pygame.GL_GREEN_SIZE), pygame.display.gl_get_attribute(pygame.GL_BLUE_SIZE), pygame.display.gl_get_attribute(pygame.GL_ALPHA_SIZE)) Logger.debug('Window: Actual depth bits: %d', pygame.display.gl_get_attribute(pygame.GL_DEPTH_SIZE)) Logger.debug('Window: Actual stencil bits: %d', pygame.display.gl_get_attribute(pygame.GL_STENCIL_SIZE)) Logger.debug('Window: Actual multisampling samples: %d', pygame.display.gl_get_attribute(pygame.GL_MULTISAMPLESAMPLES)) super(WindowPygame, self).create_window() # set mouse visibility pygame.mouse.set_visible( Config.getboolean('graphics', 'show_cursor')) # if we are on android platform, automaticly create hooks if android: from kivy.support import install_android install_android() def close(self): pygame.display.quit() self.dispatch('on_close') def on_title(self, instance, value): if self.initialized: pygame.display.set_caption(self.title) def set_icon(self, filename):
def __exit(section, name, value): WindowBase.__dict__["on_keyboard"].exit_on_escape = Config.getboolean("kivy", "exit_on_escape")
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': 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 self._update_modifiers(mod) 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)
pygame.display.gl_get_attribute(pygame.GL_RED_SIZE), pygame.display.gl_get_attribute(pygame.GL_GREEN_SIZE), pygame.display.gl_get_attribute(pygame.GL_BLUE_SIZE), pygame.display.gl_get_attribute(pygame.GL_ALPHA_SIZE)) Logger.debug('Window: Actual depth bits: %d', pygame.display.gl_get_attribute(pygame.GL_DEPTH_SIZE)) Logger.debug( 'Window: Actual stencil bits: %d', pygame.display.gl_get_attribute(pygame.GL_STENCIL_SIZE)) Logger.debug( 'Window: Actual multisampling samples: %d', pygame.display.gl_get_attribute(pygame.GL_MULTISAMPLESAMPLES)) super(WindowPygame, self).create_window() # set mouse visibility pygame.mouse.set_visible(Config.getboolean('graphics', 'show_cursor')) # if we are on android platform, automaticly create hooks if android: from kivy.support import install_android install_android() def close(self): pygame.display.quit() self.dispatch('on_close') def on_title(self, instance, value): if self.initialized: pygame.display.set_caption(self.title) def set_icon(self, filename):
pygame.display.gl_get_attribute(pygame.GL_RED_SIZE), pygame.display.gl_get_attribute(pygame.GL_GREEN_SIZE), pygame.display.gl_get_attribute(pygame.GL_BLUE_SIZE), pygame.display.gl_get_attribute(pygame.GL_ALPHA_SIZE)) Logger.debug('Window: Actual depth bits: %d', pygame.display.gl_get_attribute(pygame.GL_DEPTH_SIZE)) Logger.debug('Window: Actual stencil bits: %d', pygame.display.gl_get_attribute(pygame.GL_STENCIL_SIZE)) Logger.debug('Window: Actual multisampling samples: %d', pygame.display.gl_get_attribute( pygame.GL_MULTISAMPLESAMPLES)) super(WindowPygame, self).create_window() # set mouse visibility pygame.mouse.set_visible( Config.getboolean('graphics', 'show_cursor')) # if we are on android platform, automaticly create hooks if android: from kivy.support import install_android install_android() def close(self): pygame.display.quit() self.dispatch('on_close') def on_title(self, instance, value): if self.initialized: pygame.display.set_caption(self.title) def set_icon(self, filename):
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 create_window(self, *largs): if self._fake_fullscreen: if not self.borderless: self.fullscreen = self._fake_fullscreen = False elif not self.fullscreen or self.fullscreen == 'auto': self.borderless = self._fake_fullscreen = False if self.fullscreen == 'fake': self.borderless = self._fake_fullscreen = True Logger.warning("The 'fake' fullscreen option has been " "deprecated, use Window.borderless or the " "borderless Config option instead.") if not self.initialized: if self.position == 'auto': pos = None, None elif self.position == 'custom': pos = self.left, self.top # ensure we have an event filter self._win.set_event_filter(self._event_filter) # setup window w, h = self.system_size resizable = Config.getboolean('graphics', 'resizable') state = (Config.get('graphics', 'window_state') if self._is_desktop else None) self.system_size = _size = self._win.setup_window( pos[0], pos[1], w, h, self.borderless, self.fullscreen, resizable, state) # calculate density sz = self._win._get_gl_size()[0] self._density = density = sz / _size[0] if self._is_desktop and self.size[0] != _size[0]: self.dpi = density * 96. # never stay with a None pos, application using w.center # will be fired. self._pos = (0, 0) self._set_minimum_size() if state == 'hidden': self._focus = False else: w, h = self.system_size self._win.resize_window(w, h) self._win.set_border_state(self.borderless) self._win.set_fullscreen_mode(self.fullscreen) super(WindowSDL, self).create_window() # set mouse visibility self._set_cursor_state(self.show_cursor) if self.initialized: return # auto add input provider Logger.info('Window: auto add sdl2 input provider') from kivy.base import EventLoop SDL2MotionEventProvider.win = self EventLoop.add_input_provider(SDL2MotionEventProvider('sdl', '')) # set window icon before calling set_mode try: filename_icon = self.icon or Config.get('kivy', 'window_icon') if filename_icon == '': logo_size = 32 if platform == 'macosx': logo_size = 512 elif platform == 'win': logo_size = 64 filename_icon = 'kivy-icon-{}.png'.format(logo_size) filename_icon = resource_find( join(kivy_data_dir, 'logo', filename_icon)) self.set_icon(filename_icon) except: Logger.exception('Window: cannot set icon')
AliasProperty, ) from kivy.config import Config from kivy.metrics import sp from kivy.base import EventLoop from kivy.logger import Logger from functools import partial from weakref import ref # When we are generating documentation, Config doesn't exist _scroll_timeout = _scroll_distance = 0 _is_desktop = False if Config: _scroll_timeout = Config.getint("widgets", "scroll_timeout") _scroll_distance = Config.getint("widgets", "scroll_distance") _is_desktop = Config.getboolean("kivy", "desktop") class ButtonBehavior(object): """Button behavior. :Events: `on_press` Fired when the button is pressed. `on_release` Fired when the button is released (i.e. the touch/click that pressed the button goes away). """ state = OptionProperty("normal", options=("normal", "down")) """State of the button, must be one of 'normal' or 'down'.
def __init__(self, **kwargs): force = kwargs.pop('force', False) # don't init window 2 times, # except if force is specified if WindowBase.__instance is not None and not force: return self.initialized = False self._is_desktop = Config.getboolean('kivy', 'desktop') # create a trigger for update/create the window when one of window # property changes self.trigger_create_window = Clock.create_trigger( self.create_window, -1) # Create a trigger for updating the keyboard height self.trigger_keyboard_height = Clock.create_trigger( self._upd_kbd_height, .5) # set the default window parameter according to the configuration if 'borderless' not in kwargs: kwargs['borderless'] = Config.getboolean('graphics', 'borderless') if 'fullscreen' not in kwargs: fullscreen = Config.get('graphics', 'fullscreen') if fullscreen not in ('auto', 'fake'): fullscreen = fullscreen.lower() in ('true', '1', 'yes', 'yup') kwargs['fullscreen'] = fullscreen if 'width' not in kwargs: kwargs['width'] = Config.getint('graphics', 'width') if 'height' not in kwargs: kwargs['height'] = Config.getint('graphics', 'height') if 'rotation' not in kwargs: kwargs['rotation'] = Config.getint('graphics', 'rotation') if 'position' not in kwargs: kwargs['position'] = Config.getdefault('graphics', 'position', 'auto') if 'top' in kwargs: kwargs['position'] = 'custom' kwargs['top'] = kwargs['top'] else: kwargs['top'] = Config.getint('graphics', 'top') if 'left' in kwargs: kwargs['position'] = 'custom' kwargs['left'] = kwargs['left'] else: kwargs['left'] = Config.getint('graphics', 'left') kwargs['_size'] = (kwargs.pop('width'), kwargs.pop('height')) super(WindowBase, self).__init__(**kwargs) # bind all the properties that need to recreate the window self._bind_create_window() self.bind(size=self.trigger_keyboard_height, rotation=self.trigger_keyboard_height) self.bind(softinput_mode=lambda *dt: self.update_viewport(), keyboard_height=lambda *dt: self.update_viewport()) # init privates self._system_keyboard = Keyboard(window=self) self._keyboards = {'system': self._system_keyboard} self._vkeyboard_cls = None self.children = [] self.parent = self # before creating the window import kivy.core.gl # NOQA # configure the window self.create_window() # attach modules + listener event EventLoop.set_window(self) Modules.register_window(self) EventLoop.add_event_listener(self) # manage keyboard(s) self.configure_keyboards() # assign the default context of the widget creation if not hasattr(self, '_context'): self._context = get_current_context() # mark as initialized self.initialized = True
def create_window(self, *largs): if self._fake_fullscreen: if not self.borderless: self.fullscreen = self._fake_fullscreen = False elif not self.fullscreen or self.fullscreen == 'auto': self.borderless = self._fake_fullscreen = False if self.fullscreen == 'fake': self.borderless = self._fake_fullscreen = True Logger.warning("The 'fake' fullscreen option has been " "deprecated, use Window.borderless or the " "borderless Config option instead.") if not self.initialized: if self.position == 'auto': pos = None, None elif self.position == 'custom': pos = self.left, self.top # ensure we have an event filter self._win.set_event_filter(self._event_filter) # setup window w, h = self.system_size resizable = Config.getboolean('graphics', 'resizable') state = (Config.get('graphics', 'window_state') if self._is_desktop else None) self.system_size = _size = self._win.setup_window( pos[0], pos[1], w, h, self.borderless, self.fullscreen, resizable, state, self.get_gl_backend_name()) # calculate density sz = self._win._get_gl_size()[0] self._density = density = sz / _size[0] if self._is_desktop and self.size[0] != _size[0]: self.dpi = density * 96. # never stay with a None pos, application using w.center # will be fired. self._pos = (0, 0) self._set_minimum_size() self._set_allow_screensaver() if state == 'hidden': self._focus = False else: w, h = self.system_size self._win.resize_window(w, h) self._win.set_border_state(self.borderless) self._win.set_fullscreen_mode(self.fullscreen) super(WindowSDL, self).create_window() # set mouse visibility self._set_cursor_state(self.show_cursor) if self.initialized: return # auto add input provider Logger.info('Window: auto add sdl2 input provider') from kivy.base import EventLoop SDL2MotionEventProvider.win = self EventLoop.add_input_provider(SDL2MotionEventProvider('sdl', '')) # set window icon before calling set_mode try: filename_icon = self.icon or Config.get('kivy', 'window_icon') if filename_icon == '': logo_size = 32 if platform == 'macosx': logo_size = 512 elif platform == 'win': logo_size = 64 filename_icon = 'kivy-icon-{}.png'.format(logo_size) filename_icon = resource_find( join(kivy_data_dir, 'logo', filename_icon)) self.set_icon(filename_icon) except: Logger.exception('Window: cannot set icon')
from kivy.core.window import WindowBase from kivy.core import CoreCriticalException from os import environ from os.path import exists, join from kivy.config import Config from kivy import kivy_data_dir from kivy.base import ExceptionManager from kivy.logger import Logger from kivy.base import stopTouchApp, EventLoop from kivy.utils import platform from kivy.resources import resource_find # When we are generating documentation, Config doesn't exist _exit_on_escape = True if Config: _exit_on_escape = Config.getboolean('kivy', 'exit_on_escape') try: android = None if platform == 'android': import android except ImportError: pass # late binding glReadPixels = GL_RGBA = GL_UNSIGNED_BYTE = None class WindowPygame(WindowBase): def create_window(self, *largs): # ensure the mouse is still not up after window creation, otherwise, we
def create_window(self, *largs): # ensure the mouse is still not up after window creation, otherwise, we # have some weird bugs self.dispatch('on_mouse_up', 0, 0, 'all', []) # force display to show (available only for fullscreen) displayidx = Config.getint('graphics', 'display') if not 'SDL_VIDEO_FULLSCREEN_HEAD' in environ and displayidx != -1: environ['SDL_VIDEO_FULLSCREEN_HEAD'] = '%d' % displayidx # init some opengl, same as before. self.flags = pygame.HWSURFACE | pygame.OPENGL | pygame.DOUBLEBUF # right now, activate resizable window only on linux. # on window / macosx, the opengl context is lost, and we need to # reconstruct everything. Check #168 for a state of the work. if platform in ('linux', 'macosx', 'win') and \ Config.getint('graphics', 'resizable'): self.flags |= pygame.RESIZABLE try: pygame.display.init() except pygame.error as e: raise CoreCriticalException(e.message) multisamples = Config.getint('graphics', 'multisamples') if multisamples > 0: pygame.display.gl_set_attribute(pygame.GL_MULTISAMPLEBUFFERS, 1) pygame.display.gl_set_attribute(pygame.GL_MULTISAMPLESAMPLES, multisamples) pygame.display.gl_set_attribute(pygame.GL_DEPTH_SIZE, 16) pygame.display.gl_set_attribute(pygame.GL_STENCIL_SIZE, 1) pygame.display.set_caption(self.title) if self.position == 'auto': self._pos = None elif self.position == 'custom': self._pos = self.left, self.top else: raise ValueError('position token in configuration accept only ' '"auto" or "custom"') if self.fullscreen == 'fake': Logger.debug('WinPygame: Set window to fake fullscreen mode') self.flags |= pygame.NOFRAME # if no position set, in fake mode, we always need to set the # position. so replace 0, 0. if self._pos is None: self._pos = (0, 0) environ['SDL_VIDEO_WINDOW_POS'] = '%d,%d' % self._pos elif self.fullscreen in ('auto', True): Logger.debug('WinPygame: Set window to fullscreen mode') self.flags |= pygame.FULLSCREEN elif self._pos is not None: environ['SDL_VIDEO_WINDOW_POS'] = '%d,%d' % self._pos # never stay with a None pos, application using w.center will be fired. self._pos = (0, 0) # prepare keyboard repeat_delay = int(Config.get('kivy', 'keyboard_repeat_delay')) repeat_rate = float(Config.get('kivy', 'keyboard_repeat_rate')) pygame.key.set_repeat(repeat_delay, int(1000. / repeat_rate)) # set window icon before calling set_mode try: filename_icon = self.icon or Config.get('kivy', 'window_icon') if filename_icon == '': logo_size = 32 if platform == 'macosx': logo_size = 512 elif platform == 'win': logo_size = 64 filename_icon = 'kivy-icon-{}.png'.format(logo_size) filename_icon = resource_find( join(kivy_data_dir, 'logo', filename_icon)) self.set_icon(filename_icon) except: Logger.exception('Window: cannot set icon') # try to use mode with multisamples try: self._pygame_set_mode() except pygame.error as e: if multisamples: Logger.warning('WinPygame: Video: failed (multisamples=%d)' % multisamples) Logger.warning('WinPygame: trying without antialiasing') pygame.display.gl_set_attribute( pygame.GL_MULTISAMPLEBUFFERS, 0) pygame.display.gl_set_attribute( pygame.GL_MULTISAMPLESAMPLES, 0) multisamples = 0 try: self._pygame_set_mode() except pygame.error as e: raise CoreCriticalException(e.message) else: raise CoreCriticalException(e.message) info = pygame.display.Info() self._size = (info.current_w, info.current_h) #self.dispatch('on_resize', *self._size) # in order to debug futur issue with pygame/display, let's show # more debug output. Logger.debug('Window: Display driver ' + pygame.display.get_driver()) Logger.debug('Window: Actual window size: %dx%d', info.current_w, info.current_h) if platform != 'android': # unsupported platform, such as android that doesn't support # gl_get_attribute. Logger.debug( 'Window: Actual color bits r%d g%d b%d a%d', pygame.display.gl_get_attribute(pygame.GL_RED_SIZE), pygame.display.gl_get_attribute(pygame.GL_GREEN_SIZE), pygame.display.gl_get_attribute(pygame.GL_BLUE_SIZE), pygame.display.gl_get_attribute(pygame.GL_ALPHA_SIZE)) Logger.debug( 'Window: Actual depth bits: %d', pygame.display.gl_get_attribute(pygame.GL_DEPTH_SIZE)) Logger.debug( 'Window: Actual stencil bits: %d', pygame.display.gl_get_attribute(pygame.GL_STENCIL_SIZE)) Logger.debug( 'Window: Actual multisampling samples: %d', pygame.display.gl_get_attribute(pygame.GL_MULTISAMPLESAMPLES)) super(WindowPygame, self).create_window() # set mouse visibility pygame.mouse.set_visible( Config.getboolean('graphics', 'show_cursor')) # if we are on android platform, automaticly create hooks if android: from kivy.support import install_android install_android()
try: from kivy.core.window import sdl except: Logger.warning('WinPygame: SDL wrapper failed to import!') raise from kivy.input.provider import MotionEventProvider from kivy.input.motionevent import MotionEvent from collections import deque # When we are generating documentation, Config doesn't exist _exit_on_escape = True if Config: _exit_on_escape = Config.getboolean('kivy', 'exit_on_escape') class SDLMotionEvent(MotionEvent): def depack(self, args): self.is_touch = True self.profile = ('pos', ) self.sx, self.sy = args super(SDLMotionEvent, self).depack(args) class SDLMotionEventProvider(MotionEventProvider): win = None q = deque() touchmap = {}