def read_context(self, accessible): """ Extract prediction context from the accessible """ # get caret position from selection selection = None try: sel = accessible.get_selection(0) # Gtk-2 applications return 0,0 when there is no selection. # Gtk-3 applications return caret positions in that case. # LibreOffice Writer in Vivid initially returns -1,-1 when there # is no selection, later the caret position. start = sel.start_offset end = sel.end_offset if start > 0 and \ end > 0 and \ start <= end: selection = (sel.start_offset, sel.end_offset) except Exception as ex: # Private exception gi._glib.GErro _logger.info("DomainGenericText.read_context(), selection: " \ + unicode_str(ex)) # get text around the caret position try: if selection is None: offset = accessible.get_caret_offset() selection = (offset, offset) r = accessible.get_text_at_offset( selection[0], Atspi.TextBoundaryType.LINE_START) count = accessible.get_character_count() except Exception as ex: # Private exception gi._glib.GError when # gedit became unresponsive. _logger.info("DomainGenericText.read_context(), text: " \ + unicode_str(ex)) return None line = unicode_str(r.content).replace("\n", "") line_caret = max(selection[0] - r.start_offset, 0) begin = max(selection[0] - 256, 0) end = min(selection[0] + 100, count) try: text = Atspi.Text.get_text(accessible, begin, end) except Exception as ex: # Private exception gi._glib.GError when # gedit became unresponsive. _logger.info("DomainGenericText.read_context(), text2: " \ + unicode_str(ex)) return None text = unicode_str(text) # Not all text may be available for large selections. We only need the # part before the begin of the selection/caret. selection_span = TextSpan(selection[0], selection[1] - selection[0], text, begin) context = text[:selection[0] - begin] begin_of_text = begin == 0 begin_of_text_offset = 0 return (context, line, line_caret, selection_span, begin_of_text, begin_of_text_offset)
def read_context(self, accessible): """ Extract prediction context from the accessible """ # get caret position from selection selection = None try: sel = accessible.get_selection(0) # Gtk-2 applications return 0,0 when there is no selection. # Gtk-3 applications return caret positions in that case. # LibreOffice Writer in Vivid initially returns -1,-1 when there # is no selection, later the caret position. start = sel.start_offset end = sel.end_offset if start > 0 and \ end > 0 and \ start <= end: selection = (sel.start_offset, sel.end_offset) except Exception as ex: # Private exception gi._glib.GErro _logger.info("DomainGenericText.read_context(), selection: " \ + unicode_str(ex)) # get text around the caret position try: if selection is None: offset = accessible.get_caret_offset() selection = (offset, offset) r = accessible.get_text_at_offset(selection[0], Atspi.TextBoundaryType.LINE_START) count = accessible.get_character_count() except Exception as ex: # Private exception gi._glib.GError when # gedit became unresponsive. _logger.info("DomainGenericText.read_context(), text: " \ + unicode_str(ex)) return None line = unicode_str(r.content).replace("\n","") line_caret = max(selection[0] - r.start_offset, 0) begin = max(selection[0] - 256, 0) end = min(selection[0] + 100, count) try: text = Atspi.Text.get_text(accessible, begin, end) except Exception as ex: # Private exception gi._glib.GError when # gedit became unresponsive. _logger.info("DomainGenericText.read_context(), text2: " \ + unicode_str(ex)) return None text = unicode_str(text) # Not all text may be available for large selections. We only need the # part before the begin of the selection/caret. selection_span = TextSpan(selection[0], selection[1]-selection[0], text, begin) context = text[:selection[0] - begin] begin_of_text = begin == 0 begin_of_text_offset = 0 return (context, line, line_caret, selection_span, begin_of_text, begin_of_text_offset)
def read_context(self, keyboard, accessible): """ Extract prediction context from the accessible """ # get caret position from selection selection = accessible.get_selection() # get text around the caret position try: count = accessible.get_character_count() if selection is None: offset = accessible.get_caret_offset() # In Zesty, firefox 50.1 often returns caret position -1 # when typing into the urlbar. Assume we are at the end # of the text when that happens. if offset < 0: _logger.warning("DomainGenericText.read_context(): " "Atspi.Text.get_caret_offset() " "returned invalid {}. " "Pretending the cursor is at the end " "of the text at offset {}." .format(offset, count)) offset = count selection = (offset, offset) r = accessible.get_text_at_offset( selection[0], Atspi.TextBoundaryType.LINE_START) except Exception as ex: # Private exception gi._glib.GError when # gedit became unresponsive. _logger.info("DomainGenericText.read_context(), text: " + unicode_str(ex)) return None line = unicode_str(r.content).replace("\n", "") line_caret = max(selection[0] - r.start_offset, 0) begin = max(selection[0] - 256, 0) end = min(selection[0] + 100, count) try: text = accessible.get_text(begin, end) except Exception as ex: # Private exception gi._glib.GError when # gedit became unresponsive. _logger.info("DomainGenericText.read_context(), text2: " + unicode_str(ex)) return None text = unicode_str(text) # Not all text may be available for large selections. We only need the # part before the begin of the selection/caret. selection_span = TextSpan(selection[0], selection[1] - selection[0], text, begin) context = text[:selection[0] - begin] begin_of_text = begin == 0 begin_of_text_offset = 0 return (context, line, line_caret, selection_span, begin_of_text, begin_of_text_offset)
def _read_initial_accessible_state(self, accessible): """ Read just enough to find out if we are interested in this accessible. """ state = {} if accessible is not None: try: state["role"] = accessible.get_role() state["state-set"] = accessible.get_state_set() state["id"] = accessible.get_id() # Private exception gi._glib.GError when # gedit became unresponsive. except Exception as ex: _logger.info("_read_initial_accessible_state(): " "invalid accessible, failed to read state: " + unicode_str(ex)) try: state["pid"] = accessible.get_process_id() # Private exception gi._glib.GError when # gedit became unresponsive. except Exception as ex: _logger.info("_read_initial_accessible_state(): " "failed to get pid: " + unicode_str(ex)) try: app = accessible.get_application() state["app-name"] = app.get_name() # Private exception gi._glib.GError when # gedit became unresponsive. except Exception as ex: _logger.info("_read_initial_accessible_state(): " "failed to get app-name: " + unicode_str(ex)) return state
def read_context(self, accessible): """ Extract prediction context from the accessible """ try: offset = accessible.get_caret_offset() r = accessible.get_text_at_offset( offset, Atspi.TextBoundaryType.LINE_START) count = accessible.get_character_count() except Exception as ex: # Private exception gi._glib.GError when # gedit became unresponsive. _logger.info("DomainGenericText.read_context(): " \ + unicode_str(ex)) return None line = unicode_str(r.content).replace("\n", "") line_cursor = max(offset - r.start_offset, 0) begin = max(offset - 256, 0) end = min(offset + 100, count) text = Atspi.Text.get_text(accessible, begin, end) text = unicode_str(text) cursor_span = TextSpan(offset, 0, text, begin) context = text[:offset - begin] begin_of_text = begin == 0 begin_of_text_offset = 0 return (context, line, line_cursor, cursor_span, begin_of_text, begin_of_text_offset)
def read_context(self, accessible): """ Extract prediction context from the accessible """ try: offset = accessible.get_caret_offset() r = accessible.get_text_at_offset(offset, Atspi.TextBoundaryType.LINE_START) count = accessible.get_character_count() except Exception as ex: # Private exception gi._glib.GError when # gedit became unresponsive. _logger.info("DomainGenericText.read_context(): " \ + unicode_str(ex)) return None line = unicode_str(r.content).replace("\n","") line_cursor = max(offset - r.start_offset, 0) begin = max(offset - 256, 0) end = min(offset + 100, count) text = Atspi.Text.get_text(accessible, begin, end) text = unicode_str(text) cursor_span = TextSpan(offset, 0, text, begin) context = text[:offset - begin] begin_of_text = begin == 0 begin_of_text_offset = 0 return (context, line, line_cursor, cursor_span, begin_of_text, begin_of_text_offset)
def update_devices(self): devices = {} for info in self._osk_devices.list(): device = XIDevice() device._device_manager = self ( device.name, device.id, device.use, device.master, device.enabled, device.vendor, device.product, touch_mode, ) = info device.source = XIDevice.classify_source(device.name, device.use, touch_mode) if sys.version_info.major == 2: device.name = unicode_str(device.name) if not device.name in self.blacklist: devices[device.id] = device self._devices = devices
def update_devices(self): devices = {} self._last_device_blacklist_ids = [] for info in self._osk_devices.list(): device = XIDevice() device._device_manager = self ( device.name, device.id, device.use, device.master, device.enabled, device.vendor, device.product, touch_mode, ) = info device.source = XIDevice.classify_source(device.name, device.use, touch_mode) if sys.version_info.major == 2: device.name = unicode_str(device.name) if not device.name in self.blacklist: devices[device.id] = device if device.name in self.last_device_blacklist: self._last_device_blacklist_ids.append(device.id) self._devices = devices self._last_click_device_id = None self._last_motion_device_id = None
def _get_xembed_background_image(self): """ load the desktop background image in Unity """ try: pixbuf = self._xid_background_image except AttributeError: size, size_mm = get_monitor_dimensions(self) filename = config.get_desktop_background_filename() if not filename or \ size[0] <= 0 or size[1] <= 0: pixbuf = None else: try: # load image pixbuf = GdkPixbuf.Pixbuf.new_from_file(filename) # Scale image to mimic the behavior of gnome-screen-saver. # Take the largest, aspect correct, centered rectangle # that fits on the monitor. rm = Rect(0, 0, size[0], size[1]) rp = Rect(0, 0, pixbuf.get_width(), pixbuf.get_height()) ra = rm.inscribe_with_aspect(rp) pixbuf = pixbuf.new_subpixbuf(*ra) pixbuf = pixbuf.scale_simple(size[0], size[1], GdkPixbuf.InterpType.BILINEAR) except Exception as ex: # private exception gi._glib.GError when # librsvg2-common wasn't installed _logger.error("_get_xembed_background_image(): " + \ unicode_str(ex)) pixbuf = None self._xid_background_image = pixbuf return pixbuf
def do_load_model(model, filename, class_): _logger.info("Loading language model '{}'.".format(filename)) if not os.path.exists(filename): if class_ == "system": _logger.warning("System language model '{}' " "doesn't exist, skipping.".format(filename)) else: try: model.load(filename) except IOError as ex: if ex.errno is not None: # not n-gram count mismatch errno = ex.errno errstr = os.strerror(errno) msg = _format( "Failed to load language model '{}': {} ({})", filename, errstr, errno) else: msg = unicode_str(ex) _logger.error(msg) model.load_error_msg = msg if class_ == "user": _logger.error("Saving word suggestions disabled " "to prevent further data loss.")
def init(self): self._menu = ContextMenu() sip = config.status_icon_provider if sip == StatusIconProviderEnum.auto: # auto-detection if config.prefer_gtkstatusicon(): sip = StatusIconProviderEnum.GtkStatusIcon else: sip = StatusIconProviderEnum.AppIndicator if sip == StatusIconProviderEnum.GtkStatusIcon: backends = [BackendGtkStatusIcon] elif sip == StatusIconProviderEnum.AppIndicator: backends = [BackendAppIndicator, BackendGtkStatusIcon] else: backends = [BackendAppIndicator, BackendGtkStatusIcon] self._backend = None for backend in backends: try: self._backend = backend(self._menu) break except RuntimeError as ex: _logger.info("Status icon provider: '{}' unavailable: {}" .format(backend.__name__, unicode_str(ex))) _logger.info("Status icon provider: '{}' selected" .format(backend.__name__)) if self._backend: self._backend.set_visible(False)
def classify_source(name, use, touch_mode): """ Determine the source type (Gdk.InputSource) of the device. Logic taken from GDK, gdk/x11/gdkdevicemanager-xi2.c """ if use == XIDeviceType.MasterKeyboard or \ use == XIDeviceType.SlaveKeyboard: input_source = Gdk.InputSource.KEYBOARD elif use == XIDeviceType.SlavePointer and \ touch_mode: if touch_mode == XITouchMode.DirectTouch: input_source = Gdk.InputSource.TOUCHSCREEN else: input_source = Gdk.InputSource.TOUCHPAD else: name = unicode_str(name.lower()) if "eraser" in name: input_source = Gdk.InputSource.ERASER elif "cursor" in name: input_source = Gdk.InputSource.CURSOR elif "wacom" in name or \ "pen" in name: # uh oh, false positives? input_source = Gdk.InputSource.PEN else: input_source = Gdk.InputSource.MOUSE return input_source
def _get_accessible_frame(accessible): """ Accessible of the top level window to which accessible belongs. """ frame = None _logger.atspi("_get_accessible_frame(): searching for top level:") try: parent = accessible while True: parent = parent.get_parent() if not parent: break role = parent.get_role() _logger.atspi("parent: {}".format(role)) if role == Atspi.Role.FRAME or \ role == Atspi.Role.DIALOG or \ role == Atspi.Role.WINDOW or \ role == Atspi.Role.NOTIFICATION: frame = parent break # private exception gi._glib.GError when # right clicking onboards unity2d launcher (Precise) except Exception as ex: _logger.atspi("Invalid accessible," " failed to get top level accessible: " + unicode_str(ex)) return frame
def _get_xembed_background_image(self): """ load the desktop background image in Unity """ try: pixbuf = self._xid_background_image except AttributeError: size, size_mm = get_monitor_dimensions(self) filename = config.get_desktop_background_filename() if not filename: pixbuf = None else: try: # load image pixbuf = GdkPixbuf.Pixbuf.new_from_file(filename) # Scale image to mimic the behavior of gnome-screen-saver. # Take the largest, aspect correct, centered rectangle # that fits on the monitor. rm = Rect(0, 0, size[0], size[1]) rp = Rect(0, 0, pixbuf.get_width(), pixbuf.get_height()) ra = rm.inscribe_with_aspect(rp) pixbuf = pixbuf.new_subpixbuf(*ra) pixbuf = pixbuf.scale_simple(size[0], size[1], GdkPixbuf.InterpType.BILINEAR) except Exception as ex: # private exception gi._glib.GError when # librsvg2-common wasn't installed _logger.error("_get_xembed_background_image(): " + \ unicode_str(ex)) pixbuf = None self._xid_background_image = pixbuf return pixbuf
def enable(self): """ Enable canberra audio output """ try: if self.is_valid(): self._osk_audio.enable() except Exception as ex: _logger.warning("Failed to enable audio: " + unicode_str(ex))
def load_system_defaults(self, paths): """ System default settings can be optionally provided for distribution specific customization or branding. They are stored in simple ini-style files, residing in a small choice of directories. The last setting found in the list of paths wins. """ _logger.info( _format("Looking for system defaults in {paths}", paths=paths)) filename = None parser = configparser.SafeConfigParser() try: if sys.version_info.major == 2: filename = parser.read(paths) else: filename = parser.read(paths, "UTF-8") except configparser.ParsingError as ex: _logger.error(_("Failed to read system defaults. " + \ unicode_str(ex))) if not filename: _logger.info(_("No system defaults found.")) else: _logger.info( _format("Loading system defaults from {filename}", filename=filename)) self._read_sysdef_section(parser)
def _set_active_accessible(self, accessible): self._active_accessible = accessible if self._active_accessible is not None or \ self._last_active_accessible is not None: if accessible is not None: try: self._state.update( self._read_remaining_accessible_state(accessible)) # Private exception gi._glib.GError when # gedit became unresponsive. except Exception as ex: _logger.atspi("_set_active_accessible(): " "invalid accessible, failed to " "read remaining state: " + unicode_str(ex)) # notify listeners self.emit("text-entry-activated", self._active_accessible) self._last_active_accessible = self._active_accessible self._active_accessible_activation_time = time.time()
def gsettings_get(self): """ Get value from gsettings. """ value = self.default try: # Bug in Gio, gir1.2-glib-2.0, Oneiric # Onboard is accumulating open file handles # at "/home/<user>/.config/dconf/<user>' when # reading from gsettings before writing. # Check with: # lsof -w -p $( pgrep gio-test ) -Fn |sort|uniq -c|sort -n|tail # value = self.settings[self.key] if self.enum: value = self.settings.get_enum(self.key) elif self.type_string: value = self.settings.get_value(self.key).unpack() else: _type = type(self.default) if _type == str: value = self.settings.get_string(self.key) elif _type == int: value = self.settings.get_int(self.key) elif _type == float: value = self.settings.get_double(self.key) else: value = self.settings[self.key] except KeyError as ex: _logger.error(_("Failed to get gsettings value. ") + unicode_str(ex)) return value
def cancel(self): """ Cancel all playing sounds """ try: if self.is_valid(): self._osk_audio.cancel() except Exception as ex: _logger.warning("Failed to cancel sound: " + unicode_str(ex))
def migrate_dconf_value(self, dconf_key, gskey): """ Copy the value of dconf_key into the given gskey """ if not self._osk_dconf: self._osk_dconf = osk.DConf() try: value = self._osk_dconf.read_key(dconf_key) except (ValueError, TypeError) as e: value = None _logger.warning("migrate_dconf_value: {}".format(e)) if not value is None: # Enums are stored as strings in dconf, convert them to int. if gskey.enum: value = gskey.enum.get(value, 0) # Optionally convert from gsettings value to property value. hook = _UNPACK_HOOK + gskey.prop if hasattr(self, hook): v = value value = getattr(self, hook)(value) _logger.info("migrate_dconf_value: {key} -> {path} {gskey}, value={value}" \ .format(key=dconf_key, path=self.schema, gskey=gskey.key, value=value)) try: setattr(self, gskey.prop, value) except Exception as ex: _logger.error("Migrating dconf key failed: '{key}={value}'; " "possibly due to incompatible dconf type; " "skipping this key. " "Exception: {exception}" \ .format(key=dconf_key, value=value, exception=unicode_str(ex)))
def read_context(self, accessible, offset=None): """ Extract prediction context from the accessible """ if offset is None: try: offset = accessible.get_caret_offset() except Exception as ex: # Private exception gi._glib.GError when # gedit became unresponsive. _logger.info("DomainTerminal.read_context(): " \ + unicode_str(ex)) return None # remove prompt from the current or previous lines context, context_start, line, line_start, line_cursor = \ self._read_after_prompt(accessible, offset) if context_start: begin_of_text = True begin_of_text_offset = line_start else: begin_of_text = False begin_of_text_offset = None # remove newlines context = context.replace("\n", "") #cursor_span = TextSpan(offset, 0, text, begin) cursor_span = TextSpan(offset, 0, line, line_start) result = (context, line, line_cursor, cursor_span, begin_of_text, begin_of_text_offset) return result
def read_context(self, accessible, offset=None): """ Extract prediction context from the accessible """ if offset is None: try: offset = accessible.get_caret_offset() except Exception as ex: # Private exception gi._glib.GError # when gedit became unresponsive. _logger.info("DomainTerminal.read_context(): " + unicode_str(ex)) return None context_lines, prompt_length, line, line_start, line_caret = \ self._get_text_after_prompt(accessible, offset) if prompt_length: begin_of_text = True begin_of_text_offset = line_start else: begin_of_text = False begin_of_text_offset = None context = "".join(context_lines) before_line = "".join(context_lines[:-1]) selection_span = TextSpan(offset, 0, before_line + line, line_start - len(before_line)) result = (context, line, line_caret, selection_span, begin_of_text, begin_of_text_offset) return result
def set_theme(self, name): """ Set the XDG sound theme """ try: if self.is_valid(): self._osk_audio.set_theme(name) except Exception as ex: _logger.warning("Failed to set sound theme: " + unicode_str(ex))
def gsettings_get(self): """ Get value from gsettings. """ value = self.default try: # Bug in Gio, gir1.2-glib-2.0, Oneiric # Onboard is accumulating open file handles # at "/home/<user>/.config/dconf/<user>' when # reading from gsettings before writing. # Check with: # lsof -w -p $( pgrep gio-test ) -Fn |sort|uniq -c|sort -n|tail #value = self.settings[self.key] if self.enum: value = self.settings.get_enum(self.key) elif self.type_string: value = self.settings.get_value(self.key).unpack() else: _type = type(self.default) if _type == str: value = self.settings.get_string(self.key) elif _type == int: value = self.settings.get_int(self.key) elif _type == float: value = self.settings.get_double(self.key) else: value = self.settings[self.key] except KeyError as ex: _logger.error(_("Failed to get gsettings value. ") + \ unicode_str(ex)) return value
def play(self, event_id, x, y): """ Play a sound """ try: if self.is_valid(): self._osk_audio.play(event_id, x, y) except Exception as ex: _logger.warning("Failed to play sound: " + unicode_str(ex))
def cache_sample(self, event_id): """ Upload sample to the sound server. Blocking call. """ try: if self.is_valid(): self._osk_audio.cache_sample(event_id) except Exception as ex: _logger.warning("Failed to cache sample: " + unicode_str(ex))
def _list_to_dict(_list, key_type = str, num_values = 2): """ Get dictionary from a gsettings list key """ if sys.version_info.major == 2: _list = [unicode_str(x) for x in _list] # translate to unicode return unpack_name_value_list(_list, key_type=key_type, num_values = num_values)
def play(self, event_id, x, y, xs, ys): """ Play a sound """ try: if self.is_valid(): self._osk_audio.play(event_id, x, y, xs, ys) except Exception as ex: _logger.warning("Failed to play sound: " + unicode_str(ex))
def init(self): self._menu = ContextMenu() sip = config.status_icon_provider if sip == StatusIconProviderEnum.auto: # auto-detection if config.prefer_gtkstatusicon(): sip = StatusIconProviderEnum.GtkStatusIcon else: sip = StatusIconProviderEnum.AppIndicator if sip == StatusIconProviderEnum.GtkStatusIcon: backends = [BackendGtkStatusIcon] elif sip == StatusIconProviderEnum.AppIndicator: backends = [BackendAppIndicator, BackendGtkStatusIcon] else: backends = [BackendAppIndicator, BackendGtkStatusIcon] self._backend = None for backend in backends: try: self._backend = backend(self._menu) break except RuntimeError as ex: _logger.info( "Status icon provider: '{}' unavailable: {}".format( backend.__name__, unicode_str(ex))) _logger.info("Status icon provider: '{}' selected".format( backend.__name__)) if self._backend: self._backend.set_visible(False)
def migrate_dconf_value(self, dconf_key, gskey): """ Copy the value of dconf_key to the given gskey """ if not self._osk_dconf: self._osk_dconf = osk.DConf() try: value = self._osk_dconf.read_key(dconf_key) except (ValueError, TypeError) as e: value = None _logger.warning("migrate_dconf_value: {}".format(e)) if value is not None: # Enums are stored as strings in dconf, convert them to int. if gskey.enum: value = gskey.enum.get(value, 0) # Optionally convert from gsettings value to property value. hook = _UNPACK_HOOK + gskey.prop if hasattr(self, hook): value = getattr(self, hook)(value) _logger.info("migrate_dconf_value: " "{key} -> {path} {gskey}, value={value}" .format(key=dconf_key, path=self.schema, gskey=gskey.key, value=value)) try: setattr(self, gskey.prop, value) except Exception as ex: _logger.error("Migrating dconf key failed: '{key}={value}'; " "possibly due to incompatible dconf type; " "skipping this key. " "Exception: {exception}" .format(key=dconf_key, value=value, exception=unicode_str(ex)))
def read_context(self, accessible, offset = None): """ Extract prediction context from the accessible """ if offset is None: try: offset = accessible.get_caret_offset() except Exception as ex: # Private exception gi._glib.GError when # gedit became unresponsive. _logger.info("DomainTerminal.read_context(): " \ + unicode_str(ex)) return None # remove prompt from the current or previous lines context, context_start, line, line_start, line_cursor = \ self._read_after_prompt(accessible, offset) if context_start: begin_of_text = True begin_of_text_offset = line_start else: begin_of_text = False begin_of_text_offset = None # remove newlines context = context.replace("\n","") #cursor_span = TextSpan(offset, 0, text, begin) cursor_span = TextSpan(offset, 0, line, line_start) result = (context, line, line_cursor, cursor_span, begin_of_text, begin_of_text_offset) return result
def load_system_defaults(self, paths): """ System default settings can be optionally provided for distribution specific customization or branding. They are stored in simple ini-style files, residing in a small choice of directories. The last setting found in the list of paths wins. """ _logger.info(_format("Looking for system defaults in {paths}", paths=paths)) filename = None parser = configparser.ConfigParser() try: if sys.version_info.major == 2: filename = parser.read(paths) else: filename = parser.read(paths, "UTF-8") except configparser.ParsingError as ex: _logger.error(_("Failed to read system defaults. " + unicode_str(ex))) if not filename: _logger.info(_("No system defaults found.")) else: _logger.info(_format("Loading system defaults from {filename}", filename=filename)) self._read_sysdef_section(parser)
def get_character_count(self): try: count = self._accessible.get_character_count() except Exception as ex: # Private exception gi._glib.GErro _logger.info("CachedAccessible.get_character_count(): " + unicode_str(ex)) raise ex return count
def get_text_at_offset(self, offset, boundary_type): try: text = self._accessible.get_text_at_offset(offset, boundary_type) except Exception as ex: # Private exception gi._glib.GErro _logger.info("CachedAccessible.get_text_at_offset(): " + unicode_str(ex)) raise ex return text
def get_caret_offset(self): try: offset = self._accessible.get_caret_offset() except Exception as ex: # Private exception gi._glib.GErro _logger.info("CachedAccessible.get_caret_offset(): " + unicode_str(ex)) raise ex return offset
def __init__(self, menu): BackendBase.__init__(self, menu) try: from gi.repository import AyatanaAppIndicator3 as AppIndicator except ImportError as ex: raise RuntimeError(ex) self._indicator = AppIndicator.Indicator.new( self.id, self.icon_name, AppIndicator.IndicatorCategory.APPLICATION_STATUS) self._indicator.set_icon_full(self.icon_name, self.icon_desc) self._indicator.set_menu(menu._menu) self._indicator.set_secondary_activate_target( menu._menu.get_children()[0]) if "dbus" in globals(): # Watch left-click Activate() calls on desktops that send them # (KDE Plasma). There is still "No such method 'Activate'" in # AppIndicator. try: self._bus = dbus.SessionBus() except dbus.exceptions.DBusException as ex: _logger.warning("D-Bus session bus unavailable, " "no left-click Activate() for AppIndicator: " + unicode_str(ex)) else: try: self._bus.add_match_string( "type='method_call'," "eavesdrop=true," "path='{}'," "interface='{}'," "member='{}'" .format(self.STATUSNOTIFIER_OBJECT, self.STATUSNOTIFIER_IFACE, self.ACTIVATE_METHOD)) self._bus.add_message_filter(self._on_activate_method) except dbus.exceptions.DBusException as ex: _logger.warning("Failed to setup D-Bus match rule, " "no left-click Activate() for AppIndicator: " + unicode_str(ex))
def add_optional_child(self, type): """ Add child ConfigObject or None if it's schema doesn't exist. """ try: co = type(self) self.children.append(co) except SchemaError as e: _logger.warning(unicode_str(e)) co = None return co
def construct(self): self._osk_audio = None try: self._osk_audio = osk.Audio() except Exception as ex: _logger.warning("Failed to create osk.Audio: " + unicode_str(ex)) self.enable() self.cache_sample(self.key_feedback)
def get_text(self, begin, end): """ Text of the given accessible, no caching """ try: text = Atspi.Text.get_text(self._accessible, begin, end) # private exception gi._glib.GError: timeout from dbind # with web search in firefox. except Exception as ex: _logger.atspi("CachedAccessible.get_text(): " + unicode_str(ex)) raise ex return text
def delete_text_before_caret(self, length=1): """ Delete directly, without going through faking key presses. """ try: caret_offset = self._accessible.get_caret_offset() except Exception as ex: # Private exception gi._glib.GError when _logger.info("TextContext.delete_text_before_caret(): " + unicode_str(ex)) return self.delete_text(caret_offset - length, length)
def get_accessible_extents(accessible): """ Screen rect of the given accessible, no caching """ try: ext = accessible.get_extents(Atspi.CoordType.SCREEN) except Exception as ex: # private exception gi._glib.GError when # right clicking onboards unity2d launcher (Precise) _logger.info("AutoShow: Invalid accessible," " failed to get extents: " + unicode_str(ex)) return Rect() return Rect(ext.x, ext.y, ext.width, ext.height)
def get_accessible_extents(accessible): """ Screen rect of the given accessible, no caching """ try: rect = AtspiStateTracker._get_accessible_extents(accessible) # private exception gi._glib.GError when # right clicking onboards unity2d launcher (Precise) except Exception as ex: _logger.atspi("Invalid accessible," " failed to get extents: " + unicode_str(ex)) rect = Rect() return rect
def _init_keys(self): """ Create key descriptions """ self.schema = SCHEMA_ONBOARD self.sysdef_section = "main" self.add_key("schema-version", "") # is assigned SCHEMA_VERSION on first start self.add_key("use-system-defaults", False) self.layout_key = \ self.add_key("layout", DEFAULT_LAYOUT) self.theme_key = \ self.add_key("theme", DEFAULT_THEME) self.add_key("system-theme-tracking-enabled", True) self.add_key("system-theme-associations", {}) self.add_key("snippets", {}) self.add_key("show-status-icon", True) self.add_key("start-minimized", False) self.add_key("xembed-onboard", False, "onboard_xembed_enabled") self.add_key("show-tooltips", True) self.add_key("key-label-font", "") # default font for all themes self.add_key("key-label-overrides", {}) # default labels for all themes self.add_key("current-settings-page", 0) self.keyboard = ConfigKeyboard() self.window = ConfigWindow() self.icp = ConfigICP(self) self.auto_show = ConfigAutoShow() self.universal_access = ConfigUniversalAccess(self) self.theme_settings = ConfigTheme(self) self.lockdown = ConfigLockdown(self) self.gss = ConfigGSS(self) self.gdi = ConfigGDI(self) self.scanner = ConfigScanner(self) self.children = [self.keyboard, self.window, self.icp, self.auto_show, self.universal_access, self.theme_settings, self.lockdown, self.gss, self.gdi, self.scanner] try: self.mousetweaks = Mousetweaks() self.children.append(self.mousetweaks) except (SchemaError, ImportError) as e: _logger.warning(unicode_str(e)) self.mousetweaks = None self.clickmapper = ClickMapper()
def get_accessible_character_extents(accessible, offset): """ Screen rect of the character at offset of the accessible """ try: rect = AtspiStateTracker._get_accessible_character_extents( accessible, offset) except Exception as ex: # private exception gi._glib.GError when # right clicking onboards unity2d launcher (Precise) _logger.atspi("Invalid accessible," " failed to get character extents: " + unicode_str(ex)) rect = Rect() return rect
def get_accessible_text(accessible, begin, end): """ Text of the given accessible, no caching """ try: text = Atspi.Text.get_text(accessible, begin, end) # private exception gi._glib.GError: timeout from dbind # with web search in firefox. except Exception as ex: _logger.atspi("Invalid accessible," " failed to get text: " + unicode_str(ex)) return None return text
def get_vk(self): if not self._vk: try: # may fail if there is no X keyboard (LP: 526791) self._vk = virtkey.virtkey() except virtkey.error as e: t = time.time() if t > self._vk_error_time + .2: # rate limit to once per 200ms _logger.warning("vk: " + unicode_str(e)) self._vk_error_time = t return self._vk
def _hide_click_type_window(self, hide): """ Hide/unhide mousetweaks' native click selection window. """ try: if hide: if self._bus and self._mt_hide_name_status is None: self._mt_hide_name_status = \ self._bus.request_name(self._MT_HIDE_CLICKSELECTION_NAME) else: if self._bus and self._mt_hide_name_status: self._bus.release_name(self._MT_HIDE_CLICKSELECTION_NAME) self._mt_hide_name_status = None except dbus.DBusException as e: _logger.error(unicode_str(e))
def _read_after_prompt(self, accessible, offset): r = accessible.get_text_at_offset(offset, Atspi.TextBoundaryType.LINE_START) line = unicode_str(r.content).replace("\n","") line_start = r.start_offset line_cursor = offset - line_start # remove prompt from the current or previous lines context = "" context_start = None l = line[:line_cursor] for i in range(2): # blacklist matches? -> cancel whole context if self._find_blacklisted_prompt(l): context = "" context_start = None break context_start = self._find_prompt(l) context = l[context_start:] + context if i == 0: line = line[context_start:] # cut prompt from input line line_start += context_start line_cursor -= context_start if context_start: break # no prompt yet -> let context reach # across one more line break r = accessible.get_text_before_offset(offset, Atspi.TextBoundaryType.LINE_START) l = unicode_str(r.content).replace("\n","") result = (context, context_start, line, line_start, line_cursor) return result