model.hh (11439B)
1 #ifndef __MODEL_H_GUARD__ 2 #define __MODEL_H_GUARD__ 3 4 #include "../winsys/connection.hh" 5 #include "../winsys/event.hh" 6 #include "bindings.hh" 7 #include "client.hh" 8 #include "config.hh" 9 #include "context.hh" 10 #include "cycle.hh" 11 #include "layout.hh" 12 #include "partition.hh" 13 #include "partition.hh" 14 #include "rules.hh" 15 #include "search.hh" 16 #include "stack.hh" 17 #include "workspace.hh" 18 19 #include <atomic> 20 #include <cstddef> 21 #include <unordered_map> 22 #include <vector> 23 24 class Model; 25 class Model final 26 { 27 public: 28 Model(winsys::Connection&); 29 ~Model(); 30 31 void run(); 32 33 private: 34 static void wait_children(int); 35 static void handle_signal(int); 36 37 void init_signals() const; 38 39 void handle_mouse(winsys::MouseEvent); 40 void handle_key(winsys::KeyEvent); 41 void handle_map_request(winsys::MapRequestEvent); 42 void handle_map(winsys::MapEvent); 43 void handle_enter(winsys::EnterEvent); 44 void handle_leave(winsys::LeaveEvent); 45 void handle_destroy(winsys::DestroyEvent); 46 void handle_expose(winsys::ExposeEvent); 47 void handle_unmap(winsys::UnmapEvent); 48 void handle_state_request(winsys::StateRequestEvent); 49 void handle_focus_request(winsys::FocusRequestEvent); 50 void handle_close_request(winsys::CloseRequestEvent); 51 void handle_workspace_request(winsys::WorkspaceRequestEvent); 52 void handle_placement_request(winsys::PlacementRequestEvent); 53 void handle_grip_request(winsys::GripRequestEvent); 54 void handle_restack_request(winsys::RestackRequestEvent); 55 void handle_configure(winsys::ConfigureEvent); 56 void handle_property(winsys::PropertyEvent); 57 void handle_frame_extents_request(winsys::FrameExtentsRequestEvent); 58 void handle_screen_change(); 59 60 void process_command(winsys::CommandMessage); 61 void process_config(winsys::ConfigMessage); 62 void process_client(winsys::WindowMessage); 63 void process_workspace(winsys::WorkspaceMessage); 64 void process_query(winsys::QueryMessage); 65 66 void acquire_partitions(); 67 void resolve_active_partition(winsys::Pos); 68 69 winsys::Screen& active_screen(); 70 const winsys::Screen& active_screen() const; 71 72 Client_ptr get_client(winsys::Window); 73 Client_ptr get_const_client(winsys::Window) const; 74 75 Client_ptr search_client(SearchSelector const&); 76 bool client_matches_search(Client_ptr, SearchSelector const&) const; 77 78 Partition_ptr active_partition() const; 79 Partition_ptr get_partition(Index) const; 80 81 Context_ptr active_context() const; 82 Context_ptr get_context(Index) const; 83 84 Workspace_ptr active_workspace() const; 85 Workspace_ptr get_workspace(Index) const; 86 87 bool is_free(Client_ptr) const; 88 89 void place_client(Placement&); 90 91 void map_client(Client_ptr); 92 void unmap_client(Client_ptr); 93 94 void focus_client(Client_ptr); 95 void unfocus_client(Client_ptr); 96 void sync_focus(); 97 98 void attach_next_client(); 99 100 void toggle_partition(); 101 void activate_next_partition(winsys::Direction); 102 void activate_partition(Util::Change<Index>); 103 void activate_partition(Partition_ptr); 104 105 void toggle_context(); 106 void activate_next_context(winsys::Direction); 107 void activate_context(Util::Change<Index>); 108 void activate_context(Context_ptr); 109 110 void toggle_workspace(); 111 void toggle_workspace_current_context(); 112 void activate_next_workspace(winsys::Direction); 113 void activate_next_workspace_current_context(winsys::Direction); 114 void activate_workspace(Util::Change<Index>); 115 void activate_workspace_current_context(Util::Change<Index>); 116 void activate_workspace(Workspace_ptr); 117 118 void render_decoration(Client_ptr); 119 120 Rules retrieve_rules(Client_ptr) const; 121 122 void manage(const winsys::Window, const bool, const bool); 123 void unmanage(Client_ptr); 124 125 void start_moving(Client_ptr); 126 void start_resizing(Client_ptr); 127 128 void stop_moving(); 129 void stop_resizing(); 130 131 void perform_move(winsys::Pos&); 132 void perform_resize(winsys::Pos&); 133 134 void set_focus_follows_mouse(winsys::Toggle, Index); 135 void set_focus_follows_mouse(winsys::Toggle, Workspace_ptr); 136 137 void apply_layout(Index); 138 void apply_layout(Workspace_ptr); 139 140 void apply_stack(Index); 141 void apply_stack(Workspace_ptr); 142 143 void cycle_focus(winsys::Direction); 144 void drag_focus(winsys::Direction); 145 146 void reverse_clients(); 147 void rotate_clients(winsys::Direction); 148 void shuffle_main(winsys::Direction); 149 void shuffle_stack(winsys::Direction); 150 151 void move_focus_to_next_workspace(winsys::Direction); 152 void move_client_to_next_workspace(winsys::Direction, Client_ptr); 153 void move_focus_to_workspace(Index); 154 void move_client_to_workspace(Index, Client_ptr); 155 156 void toggle_layout(); 157 void set_layout(LayoutHandler::LayoutKind); 158 void set_layout_retain_region(LayoutHandler::LayoutKind); 159 160 void toggle_layout_data(); 161 void cycle_layout_data(winsys::Direction); 162 void copy_data_from_prev_layout(); 163 164 void change_gap_size(Util::Change<int>); 165 void change_main_count(Util::Change<int>); 166 void change_main_factor(Util::Change<float>); 167 void change_margin(Util::Change<int>); 168 void change_margin(winsys::Edge, Util::Change<int>); 169 void reset_gap_size(); 170 void reset_margin(); 171 void reset_layout_data(); 172 173 void save_layout(std::size_t) const; 174 void load_layout(std::size_t); 175 176 void kill_focus(); 177 void kill_client(Client_ptr); 178 179 void jump_client(SearchSelector const&); 180 181 void set_floating_focus(winsys::Toggle); 182 void set_floating_client(winsys::Toggle, Client_ptr); 183 void set_fullscreen_focus(winsys::Toggle); 184 void set_fullscreen_client(winsys::Toggle, Client_ptr); 185 void set_sticky_focus(winsys::Toggle); 186 void set_sticky_client(winsys::Toggle, Client_ptr); 187 void set_contained_focus(winsys::Toggle); 188 void set_contained_client(winsys::Toggle, Client_ptr); 189 void set_invincible_focus(winsys::Toggle); 190 void set_invincible_client(winsys::Toggle, Client_ptr); 191 void set_producing_focus(winsys::Toggle); 192 void set_producing_client(winsys::Toggle, Client_ptr); 193 void set_iconifyable_focus(winsys::Toggle); 194 void set_iconifyable_client(winsys::Toggle, Client_ptr); 195 void set_iconify_focus(winsys::Toggle); 196 void set_iconify_client(winsys::Toggle, Client_ptr); 197 198 void consume_client(Client_ptr, Client_ptr); 199 void check_unconsume_client(Client_ptr, bool = true); 200 201 void center_focus(); 202 void center_client(Client_ptr); 203 void nudge_focus(winsys::Edge, Util::Change<std::size_t>); 204 void nudge_client(winsys::Edge, Util::Change<std::size_t>, Client_ptr); 205 void stretch_focus(winsys::Edge, Util::Change<int>); 206 void stretch_client(winsys::Edge, Util::Change<int>, Client_ptr); 207 void inflate_focus(Util::Change<int>); 208 void inflate_client(Util::Change<int>, Client_ptr); 209 void snap_focus(winsys::Edge); 210 void snap_client(winsys::Edge, Client_ptr); 211 212 void activate_screen_struts(winsys::Toggle); 213 214 void pop_deiconify(); 215 void deiconify_all(); 216 217 void spawn_external(std::string&&) const; 218 219 void exit(); 220 221 winsys::Connection& m_conn; 222 223 bool m_running; 224 225 Cycle<Partition_ptr> m_partitions; 226 Cycle<Context_ptr> m_contexts; 227 Cycle<Workspace_ptr> m_workspaces; 228 229 Partition_ptr mp_partition; 230 Context_ptr mp_context; 231 Workspace_ptr mp_workspace; 232 233 Partition_ptr mp_prev_partition; 234 Context_ptr mp_prev_context; 235 Workspace_ptr mp_prev_workspace; 236 237 std::atomic<Workspace_ptr> mp_attachment; 238 239 Buffer m_move_buffer; 240 Buffer m_resize_buffer; 241 242 StackHandler m_stack; 243 std::vector<winsys::Window> m_order; 244 245 std::unordered_map<winsys::Window, Client_ptr> m_client_map; 246 std::unordered_map<winsys::Pid, Client_ptr> m_pid_map; 247 std::unordered_map<Client_ptr, winsys::Region> m_fullscreen_map; 248 std::unordered_map<winsys::Window, std::vector<Client_ptr>> m_leader_map; 249 250 std::vector<Client_ptr> m_sticky_clients; 251 std::vector<winsys::Window> m_unmanaged_windows; 252 253 Client_ptr mp_focus; 254 Client_ptr mp_jumped_from; 255 256 KeyBindings m_key_bindings; 257 MouseBindings m_mouse_bindings; 258 259 struct EventVisitor final 260 { 261 EventVisitor(Model& model): m_model(model) {} 262 263 void operator()(std::monostate) {} 264 265 void operator()(winsys::MouseEvent event) { 266 m_model.handle_mouse(event); 267 } 268 269 void operator()(winsys::KeyEvent event) { 270 m_model.handle_key(event); 271 } 272 273 void operator()(winsys::MapRequestEvent event) { 274 m_model.handle_map_request(event); 275 } 276 277 void operator()(winsys::MapEvent event) { 278 m_model.handle_map(event); 279 } 280 281 void operator()(winsys::EnterEvent event) { 282 m_model.handle_enter(event); 283 } 284 285 void operator()(winsys::LeaveEvent event) { 286 m_model.handle_leave(event); 287 } 288 289 void operator()(winsys::DestroyEvent event) { 290 m_model.handle_destroy(event); 291 } 292 293 void operator()(winsys::ExposeEvent event) { 294 m_model.handle_expose(event); 295 } 296 297 void operator()(winsys::UnmapEvent event) { 298 m_model.handle_unmap(event); 299 } 300 301 void operator()(winsys::StateRequestEvent event) { 302 m_model.handle_state_request(event); 303 } 304 305 void operator()(winsys::FocusRequestEvent event) { 306 m_model.handle_focus_request(event); 307 } 308 309 void operator()(winsys::CloseRequestEvent event) { 310 m_model.handle_close_request(event); 311 } 312 313 void operator()(winsys::WorkspaceRequestEvent event) { 314 m_model.handle_workspace_request(event); 315 } 316 317 void operator()(winsys::PlacementRequestEvent event) { 318 m_model.handle_placement_request(event); 319 } 320 321 void operator()(winsys::GripRequestEvent event) { 322 m_model.handle_grip_request(event); 323 } 324 325 void operator()(winsys::RestackRequestEvent event) { 326 m_model.handle_restack_request(event); 327 } 328 329 void operator()(winsys::ConfigureEvent event) { 330 m_model.handle_configure(event); 331 } 332 333 void operator()(winsys::PropertyEvent event) { 334 m_model.handle_property(event); 335 } 336 337 void operator()(winsys::FrameExtentsRequestEvent event) { 338 m_model.handle_frame_extents_request(event); 339 } 340 341 void operator()(winsys::ScreenChangeEvent) { 342 m_model.handle_screen_change(); 343 } 344 345 private: 346 Model& m_model; 347 348 } m_event_visitor = EventVisitor(*this); 349 350 struct MessageVisitor final 351 { 352 MessageVisitor(Model& model): m_model(model) {} 353 354 void operator()(std::monostate) {} 355 356 void operator()(winsys::CommandMessage message) { 357 m_model.process_command(message); 358 } 359 360 void operator()(winsys::ConfigMessage message) { 361 m_model.process_config(message); 362 } 363 364 void operator()(winsys::WindowMessage message) { 365 m_model.process_client(message); 366 } 367 368 void operator()(winsys::WorkspaceMessage message) { 369 m_model.process_workspace(message); 370 } 371 372 void operator()(winsys::QueryMessage message) { 373 m_model.process_query(message); 374 } 375 376 private: 377 Model& m_model; 378 379 } m_message_visitor = MessageVisitor(*this); 380 381 Config m_config; 382 383 }; 384 385 #endif//__MODEL_H_GUARD__