Class: WM::Window

Inherits:
Object show all
Defined in:
lib/epitools/wm.rb

Constant Summary collapse

KEYMAP =
{
  "`" => "grave",
  " " => "space",
  "~" => "asciitilde",
  "_" => "underscore",
  "\[" => "Escape",
  '"' => "quotedbl",
}

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.allObject


62
63
64
65
# File 'lib/epitools/wm.rb', line 62

def self.all
  # FIXME: Windows owned by linux-namespaced processes (firejail) report their namspaced pid to X11. `window.process` ends up pointing at either nil, or the wrong process.
  `wmctrl -lpG`.lines.map(&:strip).map { |line| Window.from_line(line) }
end

.from_line(line) ⇒ Object


67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/epitools/wm.rb', line 67

def self.from_line(line)
  # 0x01600031 -1 2562   0    0    1680 25   fizz Top Expanded Edge Panel
  # 0x01600003 -1 2562   0    1998 1680 51   fizz Bottom Expanded Edge Panel
  # 0x02c0001f  0 3012   849  173  783  667  fizz Terminal
  # 0x048001f8  5 4080   311  186  1316 835  fizz Gorillaz - Highway (Under Construction)
  # 0x02c28577  4 3012   66   461  1143 548  fizz Terminal
  # 0x07c00003  0 14117  12   73   1298 948  fizz tr1984001_comp_soft.pdf
  # 0x02d767d8  2 3012   520  470  1143 548  fizz Terminal

  fields = line.split
  title  = fields[8..-1].join ' '

  new *(fields[0..7] + [title])
end

Instance Method Details

#activate!Object


105
106
107
# File 'lib/epitools/wm.rb', line 105

def activate!
  system "wmctrl", "-i", "-a", window_id
end

#commandObject


97
98
99
# File 'lib/epitools/wm.rb', line 97

def command
  process && process.command
end

#desktopObject


82
83
84
# File 'lib/epitools/wm.rb', line 82

def desktop
  WM.desktops[desktop_id]
end

#inspectObject


101
102
103
# File 'lib/epitools/wm.rb', line 101

def inspect
  "{ ::#{name}:: [#{desktop_id}]}"
end

#keys_to_events(keys) ⇒ Object


332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
# File 'lib/epitools/wm.rb', line 332

def keys_to_events(keys)

  tokens = keys.scan(/(<[^>]+>|.+?)/)

  tokens.flatten.map do |key|
    mods = []

    if key =~ /^<(.+)>$/

      specials = $1.split("-")
      key = specials.pop

      key.downcase! if key =~ /^[A-Z]$/

      specials.each do |special|
        if special =~ /^(Ctrl|Shift|Alt)$/i
          mods << $1
        else
          raise "Error: unknown modifier #{special}"
        end
      end

    end

    mods << "Shift" if key =~ /^[A-Z\~\!\@\#\$\%\^\&\*\(\)\_\+]$/

    if key =~ /^[A-Z0-9]$/i or key.size > 1
      keyname = key
    else
      keyname = KEYMAP[key] || ("0x%x" % key.ord)
    end

    "#{mods.join(" ")}<Key>#{keyname}"
  end
end

#processObject


93
94
95
# File 'lib/epitools/wm.rb', line 93

def process
  WM.processes[pid]
end

#send_keys(keys) ⇒ Object

string is made up of regular text, plus <>'d keypresses eg: “Hello<Ctrl-T><Ctrl-L><Ctrl-Shift-K><Return>!!!”

TODO: add `xdotool` support


115
116
117
# File 'lib/epitools/wm.rb', line 115

def send_keys(keys)
  xse(keys)
end

#sticky?Boolean


86
87
88
# File 'lib/epitools/wm.rb', line 86

def sticky?
  desktop_id == -1
end

#xse(keys) ⇒ Object


368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
# File 'lib/epitools/wm.rb', line 368

def xse(keys)
  temp   = Tempfile.new("xse")
  events = keys_to_events(keys)

  # p events
  eventstring = events.map { |e| e + "\n" }.join("")

  temp.write eventstring
  temp.flush
  temp.seek 0
  # p [:temp, temp.read]

  cmd = "xse", "-window", window_id, "-file", temp.path
  # p [:cmd, cmd]
  unless system(*cmd)
    raise "Error: couldn't send key commands to 'xse'. (Is xsendevents installed?)"
  end
end