91 lines
2.5 KiB
Ruby
91 lines
2.5 KiB
Ruby
def godot_window?(window)
|
|
`xprop -id #{window} WM_CLASS`.downcase.include?("godot")
|
|
end
|
|
|
|
class Window
|
|
attr_accessor :window_id, :floating, :workspace, :def_floating, :size, :x, :y, :width, :height
|
|
|
|
def initialize(window_id, workspace)
|
|
@size = 0
|
|
@workspace = workspace
|
|
@window_id = window_id
|
|
geometry = X.get_geometry(window_id)
|
|
@x = geometry[:x]
|
|
@y = geometry[:y]
|
|
@width = geometry[:width]
|
|
@height = geometry[:height]
|
|
wm_n_hints = X.get_wm_n_hints(window_id)
|
|
@floating = godot_window?(window_id)
|
|
@def_floating = @floating
|
|
if wm_n_hints
|
|
if fixed_size_or_aspect?(wm_n_hints)
|
|
@floating = true
|
|
@def_floating = true
|
|
@width = wm_n_hints[:max_width]
|
|
if wm_n_hints[:flags] & 128 != 0
|
|
@height = wm_n_hints[:max_width] * (wm_n_hints[:min_aspect_num] / wm_n_hints[:min_aspect_den])
|
|
else
|
|
@height = wm_n_hints[:max_height]
|
|
end
|
|
@x = $monitors[@workspace.monitor_id][:width] / 2 - @width / 2
|
|
@y = $monitors[@workspace.monitor_id][:height] / 2 - @height / 2
|
|
apply_geometry!
|
|
end
|
|
end
|
|
X.set_wm_state window_id, 1
|
|
transient_for = X.get_wm_transient_for(window_id)
|
|
if !transient_for.zero? && !godot_window?(window_id)
|
|
@floating = true
|
|
@def_floating = true
|
|
@width = wm_n_hints[:max_width]
|
|
if wm_n_hints[:flags] & 128 != 0
|
|
@height = wm_n_hints[:max_width] * (wm_n_hints[:min_aspect_num] / wm_n_hints[:min_aspect_den])
|
|
else
|
|
@height = wm_n_hints[:max_height]
|
|
end
|
|
@x = $monitors[@workspace.monitor_id][:width] / 2 - @width / 2
|
|
@y = $monitors[@workspace.monitor_id][:height] / 2 - @height / 2
|
|
apply_geometry!
|
|
end
|
|
super()
|
|
end
|
|
|
|
def delete
|
|
@workspace.remove self
|
|
end
|
|
|
|
def each_leaf(&block)
|
|
block.call(self)
|
|
end
|
|
|
|
def toggle_floating
|
|
if !@def_floating
|
|
@floating = !@floating
|
|
@workspace.check_floating self
|
|
apply_geometry!
|
|
end
|
|
end
|
|
|
|
def move(x, y)
|
|
return unless @floating
|
|
@x, @y = x, y
|
|
apply_geometry!
|
|
end
|
|
|
|
def resize(width, height, force = false)
|
|
return unless @floating
|
|
@width, @height = width, height
|
|
if !force
|
|
@x = $monitors[@workspace.monitor_id][:width] / 2 - @width / 2
|
|
@y = $monitors[@workspace.monitor_id][:height] / 2 - @height / 2
|
|
end
|
|
apply_geometry!
|
|
end
|
|
|
|
def apply_geometry!
|
|
X.send_to_top @window_id if @floating
|
|
X.move_window @window_id, @x, @y
|
|
X.resize_window @window_id, @width, @height
|
|
end
|
|
end
|