class Uh::WM::Manager

Constants

DEFAULT_GEO
INPUT_MASK
ROOT_MASK

Attributes

clients[R]
display[R]
modifier[R]
modifier_ignore[R]

Public Class Methods

new(events, mod, mod_ignore = [], display = Display.new) click to toggle source
# File lib/uh/wm/manager.rb, line 13
def initialize events, mod, mod_ignore = [], display = Display.new
  @events           = events
  @modifier         = mod
  @modifier_ignore  = mod_ignore
  @display          = display
  @clients          = []
end

Public Instance Methods

configure(window) click to toggle source
# File lib/uh/wm/manager.rb, line 52
def configure window
  if client = client_for(window)
    client.configure
  else
    geo = @events.emit :configure, args: window
    window.configure_event geo ? geo : DEFAULT_GEO
  end
end
connect() click to toggle source
# File lib/uh/wm/manager.rb, line 25
def connect
  @events.emit :connecting, args: @display
  @display.open
  check_other_wm!
  Display.on_error { |*args| handle_error *args }
  @display.sync false
  @events.emit :connected, args: @display
  @display.root.mask = ROOT_MASK
end
destroy(window) click to toggle source
# File lib/uh/wm/manager.rb, line 77
def destroy window
  return unless client = client_for(window)
  unmanage client
end
disconnect() click to toggle source
# File lib/uh/wm/manager.rb, line 35
def disconnect
  @display.close
  @events.emit :disconnected
end
flush() click to toggle source
# File lib/uh/wm/manager.rb, line 40
def flush
  @display.flush
end
grab_key(keysym, mod = nil) click to toggle source
# File lib/uh/wm/manager.rb, line 44
def grab_key keysym, mod = nil
  mod_mask = KEY_MODIFIERS[@modifier]
  mod_mask |= KEY_MODIFIERS[mod] if mod
  combine_modifier_masks(@modifier_ignore) do |ignore_mask|
    @display.grab_key keysym.to_s, mod_mask | ignore_mask
  end
end
handle(event) click to toggle source
# File lib/uh/wm/manager.rb, line 96
def handle event
  @events.emit :xevent, args: event
  return unless respond_to? handler = "handle_#{event.type}".to_sym, true
  send handler, event
end
handle_next_event() click to toggle source
# File lib/uh/wm/manager.rb, line 88
def handle_next_event
  handle @display.next_event
end
handle_pending_events() click to toggle source
# File lib/uh/wm/manager.rb, line 92
def handle_pending_events
  handle_next_event while @display.pending?
end
map(window) click to toggle source
# File lib/uh/wm/manager.rb, line 61
def map window
  return if window.override_redirect? || client_for(window)
  @clients << client = Client.new(window)
  @events.emit :manage, args: client
  @display.listen_events window, Events::PROPERTY_CHANGE_MASK
end
to_io() click to toggle source
# File lib/uh/wm/manager.rb, line 21
def to_io
  IO.new(@display.fileno)
end
unmap(window) click to toggle source
# File lib/uh/wm/manager.rb, line 68
def unmap window
  return unless client = client_for(window)
  if client.unmap_count > 0
    client.unmap_count -= 1
  else
    unmanage client
  end
end
update_properties(window) click to toggle source
# File lib/uh/wm/manager.rb, line 82
def update_properties window
  return unless client = client_for(window)
  client.update_window_properties
  @events.emit :change, args: client
end

Private Instance Methods

check_other_wm!() click to toggle source
# File lib/uh/wm/manager.rb, line 150
def check_other_wm!
  Display.on_error { fail OtherWMRunningError }
  @display.listen_events INPUT_MASK
  @display.sync false
end
client_for(window) click to toggle source
# File lib/uh/wm/manager.rb, line 141
def client_for window
  @clients.find { |e| e.window == window }
end
combine_modifier_masks(mods) { |0| ... } click to toggle source
# File lib/uh/wm/manager.rb, line 156
def combine_modifier_masks mods
  yield 0
  (1..mods.size).flat_map { |n| mods.combination(n).to_a }.each do |cmb|
    yield cmb.map { |e| KEY_MODIFIERS[e] }.inject &:|
  end
end
handle_configure_request(event) click to toggle source
# File lib/uh/wm/manager.rb, line 117
def handle_configure_request event
  configure event.window
end
handle_destroy_notify(event) click to toggle source
# File lib/uh/wm/manager.rb, line 121
def handle_destroy_notify event
  destroy event.window
end
handle_error(*args) click to toggle source
# File lib/uh/wm/manager.rb, line 104
def handle_error *args
  @events.emit :xerror, args: args
end
handle_expose(event) click to toggle source
# File lib/uh/wm/manager.rb, line 125
def handle_expose event
  @events.emit :expose, args: event.window
end
handle_key_press(event) click to toggle source
# File lib/uh/wm/manager.rb, line 108
def handle_key_press event
  case remove_modifier_masks event.modifier_mask, @modifier_ignore
  when KEY_MODIFIERS[@modifier]
    @events.emit :key, event.key.to_sym
  when KEY_MODIFIERS[@modifier] | KEY_MODIFIERS[:shift]
    @events.emit :key, event.key.to_sym, :shift
  end
end
handle_map_request(event) click to toggle source
# File lib/uh/wm/manager.rb, line 129
def handle_map_request event
  map event.window
end
handle_property_notify(event) click to toggle source
# File lib/uh/wm/manager.rb, line 133
def handle_property_notify event
  update_properties event.window
end
handle_unmap_notify(event) click to toggle source
# File lib/uh/wm/manager.rb, line 137
def handle_unmap_notify event
  unmap event.window
end
remove_modifier_masks(mask, remove) click to toggle source
# File lib/uh/wm/manager.rb, line 163
def remove_modifier_masks mask, remove
  return mask unless remove.any?
  mask & ~(@modifier_ignore
    .map    { |e| KEY_MODIFIERS[e] }
    .inject &:|
  )
end
unmanage(client) click to toggle source
# File lib/uh/wm/manager.rb, line 145
def unmanage client
  @clients.delete client
  @events.emit :unmanage, args: client
end