def map_modifiers(self): gdk_modifiers =(Gdk.ModifierType.CONTROL_MASK, Gdk.ModifierType.SHIFT_MASK, Gdk.ModifierType.MOD1_MASK, Gdk.ModifierType.MOD2_MASK, Gdk.ModifierType.MOD3_MASK, Gdk.ModifierType.MOD4_MASK, Gdk.ModifierType.MOD5_MASK, Gdk.ModifierType.SUPER_MASK, Gdk.ModifierType.HYPER_MASK) self.known_modifiers_mask = 0 for modifier in gdk_modifiers: if "Mod" not in Gtk.accelerator_name(0, modifier) or "Mod4" in Gtk.accelerator_name(0, modifier): self.known_modifiers_mask |= modifier
def GetAcceleratorName(key, mods): accel = Gtk.accelerator_name(key, mods) for mod in KeyModifier: if "%s_L" % mod in accel: accel = accel.replace("%s_L" % mod, "<%s>" % mod) if "%s_R" % mod in accel: accel = accel.replace("%s_R" % mod, "<%s>" % mod) accel = Gtk.accelerator_name(*Gtk.accelerator_parse(accel)) for alias in KeyModifierAlias: accel = accel.replace("<%s>" % alias[0], "<%s>" % alias[1]) return accel
def GetAcceleratorName(key, mods): accel = Gtk.accelerator_name(key, mods) for mod in KeyModifier: if "%s_L" % mod in accel: accel = accel.replace ("%s_L" % mod, "<%s>" % mod) if "%s_R" % mod in accel: accel = accel.replace ("%s_R" % mod, "<%s>" % mod) accel = Gtk.accelerator_name(*Gtk.accelerator_parse(accel)) for alias in KeyModifierAlias: accel = accel.replace("<%s>" % alias[0], "<%s>" % alias[1]) return accel
def is_accel(event, *accels): """Checks if the given keypress Gdk.Event matches any of accelerator strings. example: is_accel(event, "<shift><ctrl>z") """ assert accels if event.type != Gdk.EventType.KEY_PRESS: return False # ctrl+shift+x gives us ctrl+shift+X and accelerator_parse returns # lowercase values for matching, so lowercase it if possible keyval = event.keyval if not keyval & ~0xFF: keyval = ord(chr(keyval).lower()) default_mod = Gtk.accelerator_get_default_mod_mask() for accel in accels: accel_keyval, accel_mod = Gtk.accelerator_parse(accel) # If the accel contains non default modifiers matching will # never work and since no one should use them, complain non_default = accel_mod & ~default_mod if non_default: print_w("Accelerator '%s' contains a non default modifier '%s'." % (accel, Gtk.accelerator_name(0, non_default) or "")) # Remove everything except default modifiers and compare if (accel_keyval, accel_mod) == (keyval, event.state & default_mod): return True return False
def set_accelerator(self, keyval, mod): # Check whether accelerator already exists self.remove_accelerator(self.current_node) name = Gtk.accelerator_name(keyval, mod) if name == "": self.current_node.shorcut = None self.save_current_tool() return True col = self.accelerator_collision(name, self.current_node) if col: dialog = Gtk.MessageDialog( self.dialog, Gtk.DIALOG_MODAL, Gtk.MESSAGE_ERROR, Gtk.BUTTONS_OK, _("This accelerator is already bound to %s") % (", ".join(map(lambda x: x.name, col)),), ) dialog.run() dialog.destroy() self.add_accelerator(self.current_node) return False self.current_node.shortcut = name self.add_accelerator(self.current_node) self.save_current_tool() return True
def on_accel_edited(self, cellrenderer, path, accel_key, accel_mods, keycode): """ Updates accelerators display in the list """ accel = Gtk.accelerator_name(accel_key, accel_mods) iter = self.list.get_iter(path) self.list.set_value(iter, 1, accel)
def on_craccel_unity_switcher_windows_accel_edited(self, craccel, path, key, mods, hwcode, model = None): model = self.ui['list_unity_switcher_windows_accelerators'] accel = Gtk.accelerator_name(key, mods) titer = model.get_iter(path) model.set_value(titer, 1, accel) # Python has no switch statement, right? if path == '0': gsettings.unityshell.set_string('alt-tab-forward', accel) elif path == '1': gsettings.unityshell.set_string('alt-tab-prev', accel) elif path == '2': gsettings.unityshell.set_string('alt-tab-forward-all', accel) elif path == '3': gsettings.unityshell.set_string('alt-tab-prev-all', accel) elif path == '4': gsettings.unityshell.set_string('alt-tab-right', accel) elif path == '5': gsettings.unityshell.set_string('alt-tab-left', accel) elif path == '6': gsettings.unityshell.set_string('alt-tab-detail-start', accel) elif path == '7': gsettings.unityshell.set_string('alt-tab-detail-stop', accel) elif path == '8': gsettings.unityshell.set_string('alt-tab-next-window', accel) elif path == '9': gsettings.unityshell.set_string('alt-tab-prev-window', accel)
def on_accel_edited(renderer, path, accel_key, accel_mods, hardware_keycode): iter = self.treestore.get_iter(path) col = column + 3 # accel cells start from 3 position old_accel = self.treestore.get(iter, col)[0] new_accel = Gtk.accelerator_name(accel_key, accel_mods) self.treestore.set_value(iter, col, new_accel) action_name = self.treestore.get_value(iter, 1) affected_action = self.keymanager.edit_accel( action_name, new_accel, old_accel) # Find affected row and cell if affected_action == action_name: for idx in range(0, self.accel_column_num): if idx != column and self.treestore.get( iter, idx + 3)[0] == new_accel: self.treestore.set_value(iter, idx + 3, "") elif affected_action is not None: titer = self.action_treeiter_map[affected_action] for idx in range(0, self.accel_column_num): if self.treestore.get(titer, idx + 3)[0] == new_accel: self.treestore.set_value(titer, idx + 3, "") # updating gtk accelerator for label in menu if self.keymanager.get_bindings_for_action(action_name)[0] == ( accel_key, accel_mods): Gtk.AccelMap.change_entry( '<Actions>/mcomix-main/%s' % action_name, accel_key, accel_mods, True)
def refresh_model(self): """ Initializes the model from data provided by the keybinding manager. """ self.treestore.clear() section_order = list( set(d['group'] for d in keybindings.BINDING_INFO.values())) section_order.sort() section_parent_map = {} for section_name in section_order: row = [section_name, None, False] row.extend([ None, ] * self.accel_column_num) section_parent_map[section_name] = self.treestore.append(None, row) action_treeiter_map = self.action_treeiter_map = {} # Sort actions by action name actions = sorted(keybindings.BINDING_INFO.items(), key=lambda item: item[1]['title']) for action_name, action_data in actions: title = action_data['title'] group_name = action_data['group'] old_bindings = self.keymanager.get_bindings_for_action(action_name) acc_list = [ "", ] * self.accel_column_num for idx in range(0, self.accel_column_num): if len(old_bindings) > idx: acc_list[idx] = Gtk.accelerator_name(*old_bindings[idx]) row = [title, action_name, True] row.extend(acc_list) treeiter = self.treestore.append(section_parent_map[group_name], row) action_treeiter_map[action_name] = treeiter
def keyPressCommand(self, event): ''' Create command lines for variuos key presses. @param event: Key press at-spi event. @type event: Accessibility.DeviceEvent ''' if event.id in self.MODIFIERS or \ event.event_string.startswith('ISO'): return if event.modifiers in (0, Gdk.EventMask.SHIFT_MASK) and \ Gdk.keyval_to_unicode(event.id): self.typed_text += unichr(Gdk.keyval_to_unicode(event.id)) else: if self.app_name: self.commands_queue.put_nowait('focus.application("%s")\n' % \ self.app_name) self.app_name = '' if self.frame_name: self.commands_queue.put_nowait('focus.frame("%s")\n' % \ self.frame_name) self.frame_name = '' if self.typed_text: self.commands_queue.put_nowait('type("%s")\n' % \ self.typed_text) self.typed_text = '' self.commands_queue.put_nowait('keyCombo("%s")\n' % \ Gtk.accelerator_name(event.id, event.modifiers))
def _on_accel_edited(self, renderer, iter_, key, mods, *args): iterator = self._store.get_iter_from_string(iter_) if not iterator: self._show_message(version.APP_NAME, _('Can\'t change hotkey.')) return accel_name = Gtk.accelerator_name(key, mods) settings_key = self._store.get_value( iterator, KeybindingsWidget.Columns.SETTINGS_KEY ) ex_key, ex_name = self._get_existed(key, mods) if ex_key: msg = _('"{accel_name}" already taken for "{action_name}"') msg = msg.format(accel_name=accel_name, action_name=ex_name) self._show_message(version.APP_NAME, msg) return columns = [ KeybindingsWidget.Columns.MODS, KeybindingsWidget.Columns.KEY ] self._store.set(iterator, columns, [mods, key]) common.SETTINGS[settings_key] = accel_name
def keyPressCommand(self, event): ''' Create command lines for variuos key presses. @param event: Key press at-spi event. @type event: Accessibility.DeviceEvent ''' if event.id in self.MODIFIERS or \ event.event_string.startswith('ISO'): return if event.modifiers in (0, Gdk.ModifierType.SHIFT_MASK) and \ Gdk.keyval_to_unicode(event.id): self.typed_text += chr(Gdk.keyval_to_unicode(event.id)) else: if self.frame_name: self.commands_queue.put_nowait('waittillguiexist("%s")\n' % \ self.frame_name) self.frame_name = '' if self.typed_text: self.commands_queue.put_nowait('generatekeyevent("%s")\n' % \ self.typed_text) self.typed_text = '' self.commands_queue.put_nowait('generatekeyevent("%s")\n' % \ Gtk.accelerator_name(event.id, Gdk.ModifierType(event.modifiers)))
def keyPressCommand(self, event): if event.id in self.MODIFIERS or \ (event.event_string.startswith('ISO') and \ event.event_string != 'ISO_Left_Tab'): return if isinstance(event, pyatspi.deviceevent.DeviceEvent): # If it's a fake one, then it is a global WM hotkey, no need for context. self._prependContext() if event.modifiers in (0, Gdk.ModifierType.SHIFT_MASK) and \ Gdk.keyval_to_unicode(event.id): self.typed_text += chr(Gdk.keyval_to_unicode(event.id)) else: if self.frame_name: if isinstance(event, pyatspi.deviceevent.DeviceEvent): self.commands_queue.put_nowait( 'sequence.append(WaitForWindowActivate("%s", None))\n' % \ self.frame_name.replace('"','\"')) self.frame_name = '' if self.last_focused: name, path, role = self.last_focused self.commands_queue.put_nowait( '%ssequence.append(WaitForFocus("%s", acc_role=pyatspi.%s))\n' % \ (self._focus_comment, name.replace('"','\"'), repr(role))) self.last_focused = None if self.typed_text: self.commands_queue.put_nowait( 'sequence.append(TypeAction("%s"))\n' % \ self.typed_text.replace('"','\"')) self.typed_text = '' self.commands_queue.put_nowait( 'sequence.append(KeyComboAction("%s"))\n' % \ Gtk.accelerator_name(event.id, Gdk.ModifierType(event.modifiers)))
def set_accelerator(self, keyval, mod): # Check whether accelerator already exists self.remove_accelerator(self.current_node) name = Gtk.accelerator_name(keyval, mod) if name == '': self.current_node.shorcut = None self.save_current_tool() return True col = self.accelerator_collision(name, self.current_node) if col: dialog = Gtk.MessageDialog(self.dialog, Gtk.DialogFlags.MODAL, Gtk.MessageType.ERROR, Gtk.ButtonsType.CLOSE, _('This accelerator is already bound to %s') % (', '.join(map(lambda x: x.name, col)),)) dialog.run() dialog.destroy() self.add_accelerator(self.current_node) return False self.current_node.shortcut = name self.add_accelerator(self.current_node) self.save_current_tool() return True
def do_key_press_event(self, event): """Handles key press events and detects valid accelerators.""" keyval = event.keyval mask = event.state if keyval == Gdk.KEY_Escape: self.destroy() return self.accelerator = Gtk.accelerator_name(keyval, mask) accelerator = Gtk.accelerator_get_label(keyval, mask) self.accelerator_label.set_markup("<span size='20000'><b>%s</b></span>" % accelerator) valid = Gtk.accelerator_valid(keyval, mask) self.conflicting_action = self.app.shortcuts.get_conflicting_action( self.customised_item.action_name, keyval, mask) if valid and self.conflicting_action: title = self.app.shortcuts.titles[self.conflicting_action] self.conflict_label.set_markup( _("This key combination is already used by <b>%s</b>." " Press Replace to use it for <b>%s</b> instead.") % (title, self.customised_item.title)) # Set visibility according to the booleans set above. self.apply_button.set_visible(valid and not bool(self.conflicting_action)) self.accelerator_label.set_visible(valid) self.conflict_label.set_visible(valid and bool(self.conflicting_action)) self.replace_button.set_visible(valid and bool(self.conflicting_action)) self.invalid_label.set_visible(not valid)
def on_got_key(self, widget, key, mods, cell_data): cell, path = cell_data new = Gtk.accelerator_name(key, Gdk.ModifierType(mods)) if new in ('BackSpace', 'Delete', 'Escape', ''): self.on_clean_clicked(cell, path) return True for mod in KeyModifier: if "%s_L" % mod in new: new = new.replace("%s_L" % mod, "<%s>" % mod) if "%s_R" % mod in new: new = new.replace("%s_R" % mod, "<%s>" % mod) widget.destroy() client = GConf.Client.get_default() column = cell.get_data("id") iter = self.model.get_iter_from_string(cell.get_data("path_string")) id = self.model.get_value(iter, self.COLUMN_ID) client.set_string( "/apps/metacity/global_keybindings/run_command_%d" % id, new) self.model.set_value(iter, self.COLUMN_KEY, new)
def on_key_release(self, widget, event): self.disconnect(self.event_id) self.ungrab() self.event_id = None if ((int(event.state) & 0xff & ~IGNORED_MOD_MASK) == 0) and event.keyval == Gdk.KEY_Escape: self.set_button_text() self.teaching = False self.teach_button = None return True if ((int(event.state) & 0xff & ~IGNORED_MOD_MASK) == 0) and event.keyval == Gdk.KEY_BackSpace: self.teaching = False self.value = self.place_value("") self.set_val(self.value) self.set_button_text() self.teach_button = None return True accel_string = Gtk.accelerator_name(event.keyval, event.state) accel_string = self.sanitize(accel_string) self.value = self.place_value(accel_string) self.set_val(self.value) self.set_button_text() self.teaching = False self.teach_button = None return True
def on_port_set_shortcut_clicked(self, btn: Gtk.Button): """Signal handler: Port keyboard shortcut button clicked.""" cfg = self.get_current_port_config() if cfg is None: return # Show a grab shortcut dialog dlg = KeyboardShortcutDialog(self._dlg.prefs_dialog) shortcut = dlg.run() dlg.destroy() # None means grabbing was canceled if shortcut is None: return # So does Escape key_name = Gtk.accelerator_name(*shortcut) if key_name == 'Escape': return # BackSpace means shortkey removal if key_name == 'BackSpace': key_name = None # Remove any current mapping of this shortcut if key_name: self.remove_shortcut_binding(key_name) # Update the button and the port config self.b_port_set_shortcut.set_label(key_name or _('(none)')) cfg['shortcut'] = key_name # Schedule a delayed setting refresh self.schedule_refresh()
def refresh_model(self): """ Initializes the model from data provided by the keybinding manager """ self.__treestore.clear() section_order = list(set(d.info.group for d in self.__keybindings_map.values())) section_order.sort() section_parent_map = {} for section_name in section_order: row = [section_name, None, False] row.extend([None, ] * self.__accel_column_num) section_parent_map[section_name] = self.__treestore.append(None, row) action_treeiter_map = self.__action_treeiter_map = {} for action_name, action_data in self.__keybindings_map.items(): title = action_data.info.title group_name = action_data.info.group old_bindings = self.__keybindings.get_bindings_for_action(action_name) acc_list = ['', ] * self.__accel_column_num for idx in range(self.__accel_column_num): if len(old_bindings) > idx: acc_list[idx] = Gtk.accelerator_name(*old_bindings[idx]) row = [title, action_name, True] row.extend(acc_list) treeiter = self.__treestore.append(section_parent_map[group_name], row) action_treeiter_map[action_name] = treeiter
def on_key_edited(self, renderer, path, keycode, mask, keyval, model): """Callback that handles key edition in cellrenderer. It makes some tests to validate the key, like looking for already in use keys and look for [A-Z][a-z][0-9] to avoid problems with these common keys. If all tests are ok, the value will be stored in gconf. """ giter = model.get_iter(path) gconf_path = model.get_value(giter, 0) oldkey = model.get_value(giter, 2) hotkey = KeyEntry(keycode, mask) key = Gtk.accelerator_name(keycode, mask) keylabel = Gtk.accelerator_get_label(keycode, mask) # we needn't to change anything, the user is trying to set the # same key that is already set. if oldkey == hotkey: return False # looking for already used keybindings def each_key(model, path, subiter): keyentry = model.get_value(subiter, 2) if keyentry and keyentry == hotkey: msg = _("The shortcut \"%s\" is already in use.") % keylabel ShowableError(self.window, _('Error setting keybinding.'), msg, -1) raise Exception( 'This is ok, we just use it to break the foreach loop!') model.foreach(each_key) # avoiding problems with common keys if ((mask == 0 and keycode != 0) and ((keycode >= ord('a') and keycode <= ord('z')) or (keycode >= ord('A') and keycode <= ord('Z')) or (keycode >= ord('0') and keycode <= ord('9')))): dialog = Gtk.MessageDialog( self.get_widget('config-window'), Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.WARNING, Gtk.ButtonsType.OK, _("The shortcut \"%s\" cannot be used " "because it will become impossible to " "type using this key.\n\n" "Please try with a key such as " "Control, Alt or Shift at the same " "time.\n") % key) dialog.run() dialog.destroy() return False # setting new value in ui giter = model.get_iter(path) model.set_value(giter, 2, hotkey) # setting the new value in gconf if gconf_path == "show-hide": self.settings.keybindingsGlobal.set_string(gconf_path, key) else: self.settings.keybindingsLocal.set_string(gconf_path, key)
def handle_keypress(self, xevent: XKeyPress): """Resolve :class:`Xlib.protocol.event.KeyPress` events to the :class:`quicktile.commands.CommandRegistry` commands associated with them and then call the commands. .. todo:: Use a proper ``index`` argument for :meth:`Xlib.display.Display.keycode_to_keysym` in :meth:`handle_keypress`'s debug messaging. .. todo:: Only call the code to look up a human-readable name for a key event if the log level is high enough that it won't be wasted. """ keysig = (xevent.detail, xevent.state) if keysig not in self._keys: logging.error( "Received an event for an unrecognized keybind: " "%s, %s", xevent.detail, xevent.state) return # Display a meaningful debug message ksym = self.xdisp.keycode_to_keysym(keysig[0], 0) gmod = Gdk.ModifierType(keysig[1]) kbstr = Gtk.accelerator_name(ksym, gmod) logging.debug("Received keybind: %s", kbstr) # Call the associated callback self._keys[keysig]()
def add(self, accel, callback, data=None): num = len(accel.accelerators) mapping = self.accelerators for i in range(num): parsed = Gtk.accelerator_parse(accel.accelerators[i]) if not Gtk.accelerator_valid(*parsed): return named = Gtk.accelerator_name(*parsed) inmap = named in mapping if i == num - 1 and inmap: # Last one cannot be in the map return elif inmap and isinstance(mapping[named], AccelCallback): # It's already mapped... return else: if not inmap: mapping[named] = {} if i == num - 1: mapping[named] = AccelCallback(accel, callback, data) mapping = mapping[named]
def on_show_keyname_keypress_event(entry, evt, *args): """Show keyname on keypress event Allow multiple keynames seperated by ", " """ # remove <Mode2> Which is NumLock ON # https://developer.gnome.org/gtk3/stable/checklist-modifiers.html modifier = evt.state & Gtk.accelerator_get_default_mod_mask() accel_name = Gtk.accelerator_name(evt.keyval, modifier) # single modifier keys not allowed pure_modifiers = set() mbases = ["Control", "Alt", "Super", "Shift"] for base in mbases: pure_modifiers.add(base) pure_modifiers.add(base + "_L") pure_modifiers.add(base + "_R") if accel_name in pure_modifiers: return True # Action can be bind to multiple shortcuts, seperated by space. old_text = entry.get_text() if old_text.rstrip().endswith(","): old_text = EditShortCutDialog.split_comma(old_text) accel_name = ", ".join(old_text + [accel_name]) elif "," in old_text: old_text = EditShortCutDialog.split_comma(old_text) old_text.pop() # replace last entry accel_name = ", ".join(old_text + [accel_name]) entry.set_text(accel_name) entry.set_position(-1) return True
def on_key_press(self, _, event): # remove GDK_MOD2_MASK, because it seems unnecessary mask = event.state if mask & Gdk.ModifierType.MOD2_MASK: mask ^= Gdk.ModifierType.MOD2_MASK if mask & Gdk.ModifierType.MOD4_MASK: mask ^= Gdk.ModifierType.MOD4_MASK accel_name = Gtk.accelerator_name(event.keyval, mask) display_name = Gtk.accelerator_get_label(event.keyval, mask) if accel_name == 'Return': # emit hotkey-set signal self.emit('hotkey-set', self._accel_name, self._display_name) self.hide() if accel_name == 'Escape': self.hide() return # do nothing for invalid hotkeys if not self.is_valid_hotkey(display_name, accel_name): logger.debug("Invalid hotkey '%s', ('%s') is not allowed", display_name, accel_name) return self._accel_name = accel_name self._display_name = display_name self._hotkey_input.set_text(display_name)
def on_shortcut_key_cell_edited(self, accel, path, key, mod, hardware_keycode): accel_key = Gtk.accelerator_name(key, mod) name = self.shortcut_liststore[path][NAME_COL] self.shortcut_liststore[path][KEY_COL] = key self.shortcut_liststore[path][MOD_COL] = int(mod) self.app.conf['custom-shortcut'][name] = accel_key
def onEntryChanged(self, cell, path, keyval, mask, keycode, entry_store): accel_string = Gtk.accelerator_name(keyval, mask) accel_string = accel_string.replace("<Mod2>", "") iter = entry_store.get_iter(path) keybindings, kb_iter = self.kb_tree.get_selection().get_selected() if kb_iter: current_keybinding = keybindings[kb_iter][1] # Check for bad keys or modifiers if (mask == 0 or mask == Gdk.ModifierType.SHIFT_MASK) and keycode != 0: if ((keyval >= Gdk.KEY_a and keyval <= Gdk.KEY_z) or (keyval >= Gdk.KEY_A and keyval <= Gdk.KEY_Z) or (keyval >= Gdk.KEY_0 and keyval <= Gdk.KEY_9) or (keyval >= Gdk.KEY_kana_fullstop and keyval <= Gdk.KEY_semivoicedsound) or (keyval >= Gdk.KEY_Arabic_comma and keyval <= Gdk.KEY_Arabic_sukun) or (keyval >= Gdk.KEY_Serbian_dje and keyval <= Gdk.KEY_Cyrillic_HARDSIGN) or (keyval >= Gdk.KEY_Greek_ALPHAaccent and keyval <= Gdk.KEY_Greek_omega) or (keyval >= Gdk.KEY_hebrew_doublelowline and keyval <= Gdk.KEY_hebrew_taf) or (keyval >= Gdk.KEY_Thai_kokai and keyval <= Gdk.KEY_Thai_lekkao) or (keyval >= Gdk.KEY_Hangul and keyval <= Gdk.KEY_Hangul_Special) or (keyval >= Gdk.KEY_Hangul_Kiyeog and keyval <= Gdk.KEY_Hangul_J_YeorinHieuh) or keyval in FORBIDDEN_KEYVALS): dialog = Gtk.MessageDialog(None, Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.ERROR, Gtk.ButtonsType.OK, None) dialog.set_default_size(400, 200) msg = _("\nThis key combination, \'<b>%s</b>\' cannot be used because it would become impossible to type using this key.\n\n") msg += _("Please try again with a modifier key such as Control, Alt or Super (Windows key) at the same time.\n") dialog.set_markup(msg % clean_kb(accel_string)) dialog.show_all() response = dialog.run() dialog.destroy() return # Check for duplicates for category in self.main_store: for keybinding in category.keybindings: for entry in keybinding.entries: if accel_string == entry and keybinding.label != current_keybinding.label: dialog = Gtk.MessageDialog(None, Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.QUESTION, Gtk.ButtonsType.YES_NO, None) dialog.set_default_size(400, 200) msg = _("This key combination, \'<b>%s</b>\' is currently in use by \'<b>%s</b>\'. ") msg += _("If you continue, the combination will be reassigned to \'<b>%s</b>.\'\n\n") msg += _("Do you want to continue with this operation?") dialog.set_markup(msg % (clean_kb(accel_string), cgi.escape(keybinding.label), cgi.escape(current_keybinding.label))) dialog.show_all() response = dialog.run() dialog.destroy() if response == Gtk.ResponseType.YES: keybinding.setBinding(keybinding.entries.index(accel_string), None) elif response == Gtk.ResponseType.NO: return current_keybinding.setBinding(int(path), accel_string) self.onKeyBindingChanged(self.kb_tree) self.entry_tree.get_selection().select_path(path)
def _on_accel_edited(renderer, path: str, accel_key: int, accel_mods, hardware_keycode: int): _iter = self.__treestore.get_iter(path) col = column + 3 # accel cells start from 3 position old_accel = self.__treestore.get(_iter, col)[0] new_accel = Gtk.accelerator_name(accel_key, accel_mods) self.__treestore.set_value(_iter, col, new_accel) action_name = self.__treestore.get_value(_iter, 1) affected_action = self.__keybindings.edit_accel( action_name, new_accel, old_accel) # Find affected row and cell if affected_action == action_name: for idx in range(self.__accel_column_num): if idx != column and self.__treestore.get( _iter, idx + 3)[0] == new_accel: self.__treestore.set_value(_iter, idx + 3, '') elif affected_action is not None: titer = self.__action_treeiter_map[affected_action] for idx in range(self.__accel_column_num): if self.__treestore.get(titer, idx + 3)[0] == new_accel: self.__treestore.set_value(titer, idx + 3, '') # updating gtk accelerator for label in menu if self.__keybindings.get_bindings_for_action(action_name)[0] == ( accel_key, accel_mods): Gtk.AccelMap.change_entry( f'<Actions>/mcomix-master/{action_name}', accel_key, accel_mods, True)
def is_accel(self, event, *accels): #Checks if the given keypress Gdk.Event matches any of accelerator strings assert accels if event.type != Gdk.EventType.KEY_PRESS: return False # ctrl+shift+x gives us ctrl+shift+X and accelerator_parse returns # lowercase values for matching, so lowercase it if possible keyval = event.keyval if not keyval & ~0xFF: keyval = ord(chr(keyval).lower()) default_mod = Gtk.accelerator_get_default_mod_mask() for accel in accels: accel_keyval, accel_mod = Gtk.accelerator_parse(accel) # If the accel contains non default modifiers matching will # never work and since no one should use them, complain non_default = accel_mod & ~default_mod if non_default: print_w("Accelerator '%s' contains a non default modifier '%s'." % (accel, Gtk.accelerator_name(0, non_default) or "")) # Remove everything except default modifiers and compare if (accel_keyval, accel_mod) == (keyval, event.state & default_mod): return True return False
def on_craccel_unity_additional_accel_edited(self, craccel, path, key, mods, hwcode, model=None): # Glade has a habit of swapping arguments. beware. model = self.ui['list_unity_additional_accelerators'] accel = Gtk.accelerator_name(key, mods) titer = model.get_iter(path) model.set_value(titer, 1, accel) # Python has no switch statement, right? # You are right, jokerdino. Python has no switch statement. # That is against OOP principles. -jpm if path == '0': gsettings.unityshell.set_string('show-hud', accel) elif path == '1': gsettings.unityshell.set_string('show-launcher', accel) elif path == '2': gsettings.unityshell.set_string('execute-command', accel) elif path == '3': gsettings.unityshell.set_string('keyboard-focus', accel) else: gsettings.unityshell.set_string('panel-first-menu', accel)
def event_handler_accel_name(self, name): handler = self._event_handlers[name] keyval = handler[0][0] modmask = handler[1] return Gtk.accelerator_name(keyval, modmask)
def do_key_press_event(self, event): """Handles key press events and detects valid accelerators.""" keyval = event.keyval mask = event.state if keyval == Gdk.KEY_Escape: self.destroy() return self.accelerator = Gtk.accelerator_name(keyval, mask) accelerator = Gtk.accelerator_get_label(keyval, mask) self.accelerator_label.set_markup( "<span size='20000'><b>%s</b></span>" % accelerator) valid = Gtk.accelerator_valid(keyval, mask) self.conflicting_action = self.app.shortcuts.get_conflicting_action( self.customised_item.action_name, keyval, mask) if valid and self.conflicting_action: title = self.app.shortcuts.titles[self.conflicting_action] self.conflict_label.set_markup( _("This key combination is already used by <b>%s</b>." " Press Replace to use it for <b>%s</b> instead.") % (title, self.customised_item.title)) # Set visibility according to the booleans set above. self.apply_button.set_visible(valid and not bool(self.conflicting_action)) self.accelerator_label.set_visible(valid) self.conflict_label.set_visible(valid and bool(self.conflicting_action)) self.replace_button.set_visible(valid and bool(self.conflicting_action)) self.invalid_label.set_visible(not valid)
def __on_change(self, src, *args): property, mode = args[-2:] args = args[:-2] value = None if (mode == self.CHANGE_ENTRY): value = src.get_text() elif (mode == self.CHANGE_OPTION): value = src.get_model()[src.get_active()][1] elif (mode == self.CHANGE_CHECKBOX): value = src.get_active() elif (mode == self.CHANGE_SPIN): value = src.get_value_as_int() elif (mode == self.CHANGE_FLOAT_SPIN): value = src.get_value() elif (mode == self.CHANGE_TEXT): value = src.get_text(*src.get_bounds() + (False, )) elif (mode == self.CHANGE_ACCELERATOR): value = Gtk.accelerator_name(src.key, src.mods) else: logger.info("Unknown type %s", str(mode)) if value is not None: self.__set_config(property, value)
def __on_change(self, src, *args): property, mode = args[-2:] args = args[:-2] value = None if (mode == self.CHANGE_ENTRY): value = src.get_text() elif (mode == self.CHANGE_OPTION): value = src.get_model()[src.get_active()][1] elif (mode == self.CHANGE_CHECKBOX): value = src.get_active() elif (mode == self.CHANGE_SPIN): value = src.get_value_as_int() elif (mode == self.CHANGE_FLOAT_SPIN): value = src.get_value() elif (mode == self.CHANGE_TEXT): value = src.get_text(*src.get_bounds() + ( False, )) elif (mode == self.CHANGE_ACCELERATOR): value = Gtk.accelerator_name(src.key, src.mods) else: logger.info("Unknown type %s", str(mode)) if value is not None: self.__set_config(property, value)
def on_craccel_compiz_windows_spread_accel_edited(self, craccel, path, key, mods, hwcode, model = None): accel = Gtk.accelerator_name(key, mods) titer = self.ui['list_compiz_windows_spread_accelerators'].get_iter(path) self.ui['list_compiz_windows_spread_accelerators'].set_value(titer, 1, accel) if path == '0': gsettings.scale.set_string("initiate-key", accel) else: gsettings.scale.set_string("initiate-all-key", accel)
def test_change_existing_accel(self): known, key = Gtk.AccelMap.lookup_entry(TEST_ACCEL_PATH) self.assertTrue(known) self.assertEqual('t', Gtk.accelerator_name(key.accel_key, key.accel_mods)) change_accel(TEST_ACCEL_PATH, 'q') self.assertEqual('q', ACCELS[TEST_ACCEL_PATH].current) self.assertEqual('t', ACCELS[TEST_ACCEL_PATH].default)
def on_craccel_compiz_general_zoom_accel_edited(self, craccel, path, key, mods, hwcode, model = None): model = self.ui['list_compiz_general_zoom_accelerators'] accel = Gtk.accelerator_name(key, mods) titer = model.get_iter(path) model.set_value(titer, 1, accel) if path == '0': gsettings.zoom.set_string('zoom-in-key', accel) elif path == '1': gsettings.zoom.set_string('zoom-out-key', accel)
def _on_accel_edited(self, *args): tree_iter = self.shortcuts_treeview.get_model().get_iter_from_string( args[1]) self.shortcuts_treeview.get_model().set( tree_iter, [2, 3], [args[2], int(args[3])]) setting_id = self.shortcuts_treeview.get_model().get_value( tree_iter, 0) accelString = Gtk.accelerator_name(args[2], args[3]) self._kb_settings.set_strv(setting_id, [accelString])
def test_change_new_accel(self): path = '<Actions>/NewAction' known, key = Gtk.AccelMap.lookup_entry(path) self.assertFalse(known) self.assertEqual('', Gtk.accelerator_name(key.accel_key, key.accel_mods)) change_accel(path, 'n') self.assertEqual('n', ACCELS[path].current) self.assertEqual('', ACCELS[path].default)
def dialog_key_press_cb(self, source, event): keyval = event.keyval modifier_mask = event.state & gtk.accelerator_get_default_mod_mask() if gtk.accelerator_valid(keyval, modifier_mask): self.set_value(gtk.accelerator_name(keyval, modifier_mask)) self.emit('changed') gdk.Device.ungrab(gtk.get_current_event_device(), gtk.get_current_event_time()) self.dialog.hide()
def _set_accelmap_entry(cls, path, keyval, mods): cls._delete_clashing_accelmap_entries(keyval, mods, path) accel_name = Gtk.accelerator_name(keyval, mods) logger.info("Changing entry %r: %r", accel_name, path) if Gtk.AccelMap.change_entry(path, keyval, mods, True): logger.debug("Updated %r successfully", path) else: logger.error("Failed to update %r", path) entry_exists, junk = Gtk.AccelMap.lookup_entry(path) assert entry_exists
def map_modifiers(self): gdk_modifiers =(Gdk.ModifierType.CONTROL_MASK, Gdk.ModifierType.SHIFT_MASK, Gdk.ModifierType.MOD1_MASK, Gdk.ModifierType.MOD2_MASK, Gdk.ModifierType.MOD3_MASK, Gdk.ModifierType.MOD4_MASK, Gdk.ModifierType.MOD5_MASK, Gdk.ModifierType.SUPER_MASK, Gdk.ModifierType.HYPER_MASK) self.known_modifiers_mask = 0 for modifier in gdk_modifiers: # Do you know how to handle unknown "Mod*" keys? # They are usually Locks and something like that if "Mod" not in Gtk.accelerator_name(0, modifier): self.known_modifiers_mask |= modifier
def on_craccel_unity_switcher_launcher_accel_edited(self, craccel, path, key, mods, hwcode, model = None): model = self.ui['list_unity_switcher_launcher_accelerators'] accel = Gtk.accelerator_name(key, mods) titer = model.get_iter(path) model.set_value(titer, 1, accel) # Python has no switch statement, right? if path == '0': gsettings.unityshell.set_string('launcher-switcher-forward', accel) else: gsettings.unityshell.set_string('launcher-switcher-prev', accel)
def on_accel_edited(self, accel, path, key, mods, hardware_keycode): value = Gtk.accelerator_name(key, mods) iterator = self.accel_model.get_iter_from_string(path) if not iterator: raise Exception(_("Failed to update keybinding")) name = self.accel_model.get_value(iterator, 3) self.accel_model.set(iterator, [1, 2], [mods, key]) self._settings.set_strv(name, [value])
def on_craccel_compiz_general_keys_accel_edited(self, craccel, path, key, mods, hwcode, model = None): model = self.ui['list_compiz_general_keys_accelerators'] accel = Gtk.accelerator_name(key, mods) titer = model.get_iter(path) model.set_value(titer, 1, accel) if path == '0': gsettings.core.set_string('close-window-key', accel) elif path == '1': gsettings.move.set_string('initiate-key', accel) else: gsettings.core.set_string('show-desktop-key', accel)
def change_accel(accel_path, accel_name): key, mods = Gtk.accelerator_parse(accel_name) info = ACCELS.get(accel_path) if info == None: known, entry = Gtk.AccelMap.lookup_entry(accel_path) name = Gtk.accelerator_name(entry.accel_key, entry.accel_mods) info = AccelInfo(name, name) ACCELS[accel_path] = info if Gtk.AccelMap.change_entry(accel_path, key, mods, True): info.current = accel_name return True return False
def activate(self, key, mod): named = Gtk.accelerator_name(key, mod) if not named in self.accelerators: return None accel = self.accelerators[named] if isinstance(accel, AccelCallback): return accel else: return AccelGroup(self, named, accel)
def _delete_clashing_accelmap_entries(cls, keyval, mods, path_to_keep): accel_name = Gtk.accelerator_name(keyval, mods) for path, k, m, changed in cls._get_accel_map_entries(): if path == path_to_keep: continue if (k, m) != (keyval, mods): continue if not Gtk.AccelMap.change_entry(path, 0, 0, True): logger.warning("Failed to delete clashing use of %r (%r)", accel_name, path) else: logger.debug("Deleted clashing use of %r (was %r)", accel_name, path)