EVENT_TYPES = { 1 => :create, 2 => :closed, 3 => :enter, 4 => :showed, 5 => :show_request, 6 => :mouse_press, 7 => :mouse_drag, 8 => :mouse_release, 9 => :key_press, 10 => :key_release, 11 => :closed_temp, 12 => :configure_request, 13 => :resize_request }.freeze def handle_event(event) case EVENT_TYPES[event[:type]] when :create $all_windows << event[:window] return unless event[:override_redirect].zero? X.subscribe event[:window] when :closed $all_windows.delete event[:window] $windows[event[:window]]&.delete X.focus $root when :enter X.focus event[:window] when :show_request monitor = current_monitor if $windows[event[:window]].nil? monitor[:workspaces][monitor[:selected_workspace]].create event[:window] X.show event[:window] $all_windows.each do |window| above = `xprop -id #{window} _NET_WM_STATE` X.send_to_top window if above.include?("ABOVE") end end X.focus event[:window] when :mouse_press $mousebind_actions[[event[:btn], event[:state]]]&.call(event) return if event[:is_root] != 0 return if $windows[event[:window]].nil? return if event[:state] != 1 $mouse_data[:btn] = event[:btn] $mouse_data[:window] = $windows[event[:window]] X.grab_pointer $root $mouse_data[:pointer] = X.get_pointer if $mouse_data[:window].floating $mouse_data[:mode] = :floating $mouse_data[:geometry] = X.get_geometry event[:window] else $mouse_data[:mode] = :tiled end when :mouse_drag mouse_pos = X.get_pointer if $mouse_data[:mode] == :floating dx = mouse_pos[:x] - $mouse_data[:pointer][:x] dy = mouse_pos[:y] - $mouse_data[:pointer][:y] if $mouse_data[:btn] == 1 $mouse_data[:window].move $mouse_data[:geometry][:x] + dx, $mouse_data[:geometry][:y] + dy elsif $mouse_data[:btn] == 3 $mouse_data[:window]&.resize [$mouse_data[:geometry][:width] + dx, 50].max, [$mouse_data[:geometry][:height] + dy, 50].max, true end elsif $mouse_data[:mode] == :tiled if $mouse_data[:btn] == 1 monitor = current_monitor find_targets = monitor[:workspaces][monitor[:selected_workspace]].insertion_rects target = drop_target(find_targets, mouse_pos[:x], mouse_pos[:y]) if target if $rect[:target] != target X.destroy $rect[:id] if $rect[:id] $rect[:id] = X.draw_rectangle target[:x], target[:y], target[:width], target[:height], 0x500070 $rect[:target] = target end else X.destroy $rect[:id] if $rect[:id] $rect = {} end elsif $mouse_data[:btn] == 3 # TODO: tile resize . dynamic end end when :mouse_release if $mouse_data[:mode] == :tiled if $mouse_data[:btn] == 1 if $rect[:id] X.destroy $rect[:id] monitor = current_monitor monitor[:workspaces][monitor[:selected_workspace]].drop $rect[:target][:drop], $mouse_data[:window] end $rect = {} end end X.ungrab_pointer $mouse_data = {} when :key_press $keybind_actions[[event[:btn], event[:state]]]&.call(event) when :key_release # TODO when :configure_request $windows[event[:window]]&.resize event[:width], event[:height] when :resize_request $windows[event[:window]]&.resize event[:width], event[:height] end end