class Window < Node attr_accessor :window_id, :x, :y, :width, :height, :state, :floating, :workspace def initialize(window_id, workspace) @workspace = workspace @window_id = window_id @name = X.get_wm_name(window_id) @wm_n_hints = X.get_wm_n_hints(window_id) @floating = false if @wm_n_hints if fixed_size_or_aspect?(@wm_n_hints) @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 = @workspace.width / 2 - @width / 2 @y = @workspace.height / 2 - @height / 2 apply_geometry! end end @wm_hints = X.get_wm_hints(window_id) if @wm_hints if @wm_hints[:flags] & 1 != 0 && @wm_hints[:initial_state] == 3 X.set_wm_state window_id, 1 end end @transient_for = X.get_wm_transient_for(window_id) @floating = true unless @transient_for.zero? super() end def delete @workspace.remove self end def each_leaf(&block) block.call(self) end def move(x, y) return unless @floating @x, @y = x, y apply_geometry! end def resize(width, height) return unless @floating @x = @workspace.width / 2 - width / 2 @y = @workspace.height / 2 - height / 2 @width, @height = width, height apply_geometry! end def apply_geometry! X.move_window @window_id, @x, @y X.resize_window @window_id, @width, @height end end