Module: Teek::UI::Keysyms

Defined in:
lib/teek/ui/keysyms.rb

Overview

Translates the DSL's Tk-free key vocabulary (friendly symbols, "Ctrl-x" style modifier strings) into real Tk bind event patterns. Its own small lookup, kept separate from Handle so it's easy to extend.

Constant Summary collapse

FRIENDLY =

Friendly name -> Tk keysym. Anything not listed here passes through as the literal keysym (so e.g. :q or "q" still works for plain letter keys without needing an entry).

{
  enter: 'Return', return: 'Return', escape: 'Escape', tab: 'Tab',
  space: 'space', backspace: 'BackSpace', delete: 'Delete', insert: 'Insert',
  up: 'Up', down: 'Down', left: 'Left', right: 'Right',
  home: 'Home', end: 'End', page_up: 'Prior', page_down: 'Next',
}.merge((1..12).to_h { |n| [:"f#{n}", "F#{n}"] }).freeze
MODIFIER_ALIASES =

"Ctrl"/"Cmd"/etc, however people spell them -> Tk's own modifier keyword.

{
  'ctrl' => 'Control', 'control' => 'Control',
  'alt' => 'Alt', 'option' => 'Alt', 'opt' => 'Alt',
  'shift' => 'Shift',
  'cmd' => 'Command', 'command' => 'Command', 'meta' => 'Meta',
}.freeze

Class Method Summary collapse

Class Method Details

.patterns_for(modifiers, keysym) ⇒ Array<String>

Tk event patterns to bind for a resolved [modifiers, keysym] pair - usually just one, but Shift+Tab is a known cross-platform gotcha: X11 delivers it as the distinct keysym ISO_Left_Tab, not Tab with a Shift modifier, so binding only silently never fires there. Bind every spelling so the handler fires regardless of platform; on platforms where a given spelling never occurs, that binding is simply inert.

Parameters:

  • modifiers (Array<String>)
  • keysym (String)

Returns:

  • (Array<String>)

    Tk bind event patterns, e.g. ["<Control-s>"]



50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/teek/ui/keysyms.rb', line 50

def self.patterns_for(modifiers, keysym)
  if keysym == 'Tab' && modifiers.include?('Shift')
    without_shift = modifiers - ['Shift']
    [
      pattern(modifiers, 'Tab'),
      pattern(without_shift, 'ISO_Left_Tab'),
      pattern(modifiers, 'ISO_Left_Tab'),
    ].uniq
  else
    [pattern(modifiers, keysym)]
  end
end

.resolve(spec) ⇒ Array(Array<String>, String)

Returns [tk_modifiers, tk_keysym].

Parameters:

  • spec (Symbol, String)

    a friendly key (+:enter+) or a "Modifier-Modifier-Key" string (+"Ctrl-Shift-s"+)

Returns:

  • (Array(Array<String>, String))

    [tk_modifiers, tk_keysym]



30
31
32
33
34
35
36
37
38
# File 'lib/teek/ui/keysyms.rb', line 30

def self.resolve(spec)
  return [[], FRIENDLY.fetch(spec) { spec.to_s }] if spec.is_a?(Symbol)

  parts = spec.to_s.split('-')
  base = parts.pop
  keysym = FRIENDLY.fetch(base.downcase.to_sym) { base }
  modifiers = parts.map { |part| MODIFIER_ALIASES.fetch(part.downcase, part) }
  [modifiers, keysym]
end