#pragma once #include "WindowUtils.hpp" #include #include #include #include struct wl_display; namespace gsr { struct Region { mgl::vec2i pos; mgl::vec2i size; }; struct RegionWindow { Window window = None; mgl::vec2i pos; mgl::vec2i size; }; class RegionSelector { public: enum class SelectionType { NONE, REGION, WINDOW }; RegionSelector(); RegionSelector(const RegionSelector&) = delete; RegionSelector& operator=(const RegionSelector&) = delete; ~RegionSelector(); bool start(SelectionType selection_type, mgl::Color border_color); void stop(); bool is_started() const; bool failed() const; bool poll_events(); bool take_selection(); bool take_canceled(); Region get_region_selection(Display *x11_dpy, struct wl_display *wayland_dpy) const; // Returns None (0) if none is selected Window get_window_selection() const; SelectionType get_selection_type() const; private: void on_button_press(const void *de); void on_button_release(const void *de); void on_mouse_motion(const void *de); private: Display *dpy = nullptr; unsigned long region_window = 0; unsigned long cursor_window = 0; unsigned long region_window_colormap = 0; int xi_opcode = 0; GC region_gc = nullptr; GC cursor_gc = nullptr; Region region; bool selecting_region = false; bool selected = false; bool canceled = false; bool is_wayland = false; std::vector monitors; std::vector windows; // First window is the window that is on top std::optional focused_window; mgl::vec2i cursor_pos; SelectionType selection_type = SelectionType::NONE; }; }