class Sapristi::Linux::WindowManager

Constants

EXTENDED_HINTS
GRAVITY
LABELS
TIME_TO_APPLY_DIMENSIONS

Attributes

display[R]

Public Class Methods

new(display = WMCtrl.display) click to toggle source
# File lib/sapristi/adapters/linux/window_manager.rb, line 8
def initialize(display = WMCtrl.display)
  @display = display
end

Private Class Methods

text_diff(actual, expected) click to toggle source
# File lib/sapristi/adapters/linux/window_manager.rb, line 94
def self.text_diff(actual, expected)
  diffs = 4.times.filter { |index| !expected[index].eql? actual[index] }
  diffs.map do |diff_index|
    "#{LABELS[diff_index]}: expected=#{expected[diff_index]}, actual=#{actual[diff_index]}"
  end.join(', ')
end

Public Instance Methods

close(window) click to toggle source
# File lib/sapristi/adapters/linux/window_manager.rb, line 14
def close(window)
  @display.action_window(window.id, :close)

  #
  # sleep to allow a Graceful Dead to the window process
  #
  # X Error of failed request:  BadWindow (invalid Window parameter)
  #   Major opcode of failed request:  20 (X_GetProperty)
  #   Resource id in failed request:  0x2200008
  #   Serial number of failed request:  1095
  #   Current serial number in output stream:  1095
  sleep TIME_TO_APPLY_DIMENSIONS
end
move(window, x_position, y_position) click to toggle source
# File lib/sapristi/adapters/linux/window_manager.rb, line 39
def move(window, x_position, y_position)
  geometry = complete_geometry(window.id, x_position: x_position, y_position: y_position)
  move_resize(window, geometry)
end
move_resize(window, requested) click to toggle source
# File lib/sapristi/adapters/linux/window_manager.rb, line 49
def move_resize(window, requested)
  remove_extended_hints(window) if window.maximized_horizontally? || window.maximized_vertically?

  geometry = requested.clone
  left, right, top, bottom = window.frame_extents || [0, 0, 0, 0]
  geometry[2] -= left + right
  geometry[3] -= top + bottom

  @display.action_window(window.id, :move_resize, GRAVITY, *geometry)
  sleep TIME_TO_APPLY_DIMENSIONS
  check_expected_geometry window, requested
end
resize(window, width, height) click to toggle source
# File lib/sapristi/adapters/linux/window_manager.rb, line 44
def resize(window, width, height)
  geometry = complete_geometry(window.id, width: width, height: height)
  move_resize(window, geometry)
end
to_workspace(window, workspace) click to toggle source
# File lib/sapristi/adapters/linux/window_manager.rb, line 62
def to_workspace(window, workspace)
  @display.action_window(window.id, :move_to_desktop, workspace)
  sleep TIME_TO_APPLY_DIMENSIONS
end
windows(args = {}) click to toggle source
# File lib/sapristi/adapters/linux/window_manager.rb, line 28
def windows(args = {})
  @display.windows args
end
workspaces() click to toggle source
# File lib/sapristi/adapters/linux/window_manager.rb, line 32
def workspaces
  @display.desktops
end

Private Instance Methods

check_expected_geometry(window, expected) click to toggle source
# File lib/sapristi/adapters/linux/window_manager.rb, line 83
def check_expected_geometry(window, expected)
  actual_window = @display.windows(id: window.id).first
  actual = actual_window.exterior_frame || actual_window.geometry

  return if actual.eql? expected

  # rubocop:disable Layout/LineLength
  ::Sapristi.logger.warn "Geometry mismatch #{WindowManager.text_diff(actual, expected)}, requested=#{expected}, window=#{window.title}"
  # rubocop:enable Layout/LineLength
end
complete_geometry(window_id, requested) click to toggle source
# File lib/sapristi/adapters/linux/window_manager.rb, line 76
def complete_geometry(window_id, requested)
  window = @display.windows(id: window_id).first
  Geometry.new(window).merge(requested)
end
remove_extended_hints(window) click to toggle source
# File lib/sapristi/adapters/linux/window_manager.rb, line 71
def remove_extended_hints(window)
  display.action_window(window.id, :change_state, 'remove', *EXTENDED_HINTS)
  sleep TIME_TO_APPLY_DIMENSIONS
end