1use super::{Config, DisplayEvent, Manager, Mode};
2use crate::display_action::DisplayAction;
3use crate::display_servers::DisplayServer;
4use crate::models::{Handle, WindowHandle, WindowState};
5use crate::State;
6
7impl<H: Handle, C: Config, SERVER: DisplayServer<H>> Manager<H, C, SERVER> {
8 pub fn display_event_handler(&mut self, event: DisplayEvent<H>) -> bool {
11 let state = &mut self.state;
12 match event {
13 DisplayEvent::ScreenCreate(s) => self.screen_create_handler(s),
14 DisplayEvent::WindowCreate(w, x, y) => self.window_created_handler(w, x, y),
15 DisplayEvent::WindowChange(w) => self.window_changed_handler(w),
16 DisplayEvent::WindowDestroy(handle) => self.window_destroyed_handler(&handle),
17 DisplayEvent::SendCommand(command) => self.command_handler(&command),
18 DisplayEvent::MouseCombo(mod_mask, button, handle, x, y) => self
19 .state
20 .mouse_combo_handler(&mod_mask, button, handle, x, y),
21
22 DisplayEvent::WindowTakeFocus(handle) => from_window_take_focus(state, handle),
23 DisplayEvent::HandleWindowFocus(handle) => from_handle_window_focus(state, handle),
24 DisplayEvent::MoveFocusTo(x, y) => from_move_focus_to(state, x, y),
25 DisplayEvent::VerifyFocusedAt(handle) => from_verify_focus_at(state, handle),
26 DisplayEvent::ChangeToNormalMode => from_change_to_normal_mode(state),
27 DisplayEvent::Movement(handle, x, y) => from_movement(state, handle, x, y),
28 DisplayEvent::MoveWindow(handle, x, y) => from_move_window(self, handle, x, y),
29 DisplayEvent::ResizeWindow(handle, x, y) => from_resize_window(self, handle, x, y),
30 DisplayEvent::ConfigureXlibWindow(handle) => from_configure_xlib_window(state, handle),
31 }
32 }
33}
34
35fn from_window_take_focus<H: Handle>(state: &mut State<H>, handle: WindowHandle<H>) -> bool {
36 state.focus_window(&handle);
37 false
38}
39
40fn from_handle_window_focus<H: Handle>(state: &mut State<H>, handle: WindowHandle<H>) -> bool {
41 state.handle_window_focus(&handle);
42 false
43}
44
45fn from_move_focus_to<H: Handle>(state: &mut State<H>, x: i32, y: i32) -> bool {
46 state.focus_window_with_point(x, y);
47 false
48}
49
50fn from_verify_focus_at<H: Handle>(state: &mut State<H>, handle: WindowHandle<H>) -> bool {
51 if state.focus_manager.behaviour.is_sloppy() {
52 state.validate_focus_at(&handle);
53 }
54 false
55}
56
57fn from_change_to_normal_mode<H: Handle>(state: &mut State<H>) -> bool {
58 match state.mode {
59 Mode::MovingWindow(h) | Mode::ResizingWindow(h) => {
60 if let Some(window) = state.windows.iter_mut().find(|w| w.handle == h) {
66 let loc = window.calculated_xyhw();
67 let (center_x, center_y) = loc.center();
68 let (margin_multiplier, tag, normal) = if let Some(ws) = state
69 .workspaces
70 .iter()
71 .find(|ws| ws.contains_point(center_x, center_y))
72 {
73 (ws.margin_multiplier(), ws.tag, ws.xyhw)
74 } else if let Some(ws) = state.workspaces.iter().find(|ws| {
75 let dx =
76 ws.xyhw.x() <= loc.x() + loc.w() && ws.xyhw.x() + ws.xyhw.w() >= loc.x();
77 let dy =
78 ws.xyhw.y() <= loc.y() + loc.h() && ws.xyhw.y() + ws.xyhw.h() >= loc.y();
79 dx && dy
80 }) {
81 (ws.margin_multiplier(), ws.tag, ws.xyhw)
82 } else {
83 tracing::debug!("No matching workspace found for {:?}", window.handle);
84 (1.0, Some(1), window.normal)
85 };
86 let mut offset = window.get_floating_offsets().unwrap_or_default();
87 let exact = window.normal + offset;
89 offset = exact - normal;
90 window.set_floating_offsets(Some(offset));
91 window.tag = tag;
92 window.apply_margin_multiplier(margin_multiplier);
93 let act = DisplayAction::SetWindowTag(window.handle, tag);
94 state.actions.push_back(act);
95 }
96 state.focus_window(&h);
97 }
98 _ => {}
99 }
100 state.mode = Mode::Normal;
101 true
102}
103
104fn from_movement<H: Handle>(state: &mut State<H>, handle: WindowHandle<H>, x: i32, y: i32) -> bool {
105 if state.screens.iter().any(|s| s.root == handle) {
106 state.focus_workspace_with_point(x, y);
107 }
108 false
109}
110
111fn from_move_window<H: Handle, C: Config, SERVER: DisplayServer<H>>(
114 manager: &mut Manager<H, C, SERVER>,
115 handle: WindowHandle<H>,
116 x: i32,
117 y: i32,
118) -> bool {
119 if let Mode::ReadyToMove(h) = manager.state.mode {
121 manager.state.mode = Mode::MovingWindow(h);
122 prepare_window(&mut manager.state, h);
123 }
124 manager.window_move_handler(&handle, x, y)
125}
126
127fn from_resize_window<H: Handle, C: Config, SERVER: DisplayServer<H>>(
130 manager: &mut Manager<H, C, SERVER>,
131 handle: WindowHandle<H>,
132 x: i32,
133 y: i32,
134) -> bool {
135 if let Mode::ReadyToResize(h) = manager.state.mode {
137 manager.state.mode = Mode::ResizingWindow(h);
138 prepare_window(&mut manager.state, h);
139 }
140 manager.window_resize_handler(&handle, x, y)
141}
142
143fn from_configure_xlib_window<H: Handle>(state: &mut State<H>, handle: WindowHandle<H>) -> bool {
146 if let Some(window) = state.windows.iter().find(|w| w.handle == handle) {
147 let act = DisplayAction::ConfigureXlibWindow(window.clone());
148 state.actions.push_back(act);
149 }
150 false
151}
152
153fn prepare_window<H: Handle>(state: &mut State<H>, handle: WindowHandle<H>) {
155 if let Some(w) = state.windows.iter_mut().find(|w| w.handle == handle) {
156 if w.is_fullscreen() {
158 w.reset_float_offset();
159 state.actions.push_back(DisplayAction::SetState(
160 handle,
161 false,
162 WindowState::Fullscreen,
163 ));
164 w.states.retain(|s| s != &WindowState::Fullscreen);
165 state.mode = Mode::ReadyToResize(handle);
167 }
168 if w.is_maximized() {
169 w.reset_float_offset();
170 state.actions.push_back(DisplayAction::SetState(
171 handle,
172 false,
173 WindowState::Maximized,
174 ));
175 w.states.retain(|s| s != &WindowState::Maximized);
176 w.states.retain(|s| s != &WindowState::MaximizedHorz);
177 w.states.retain(|s| s != &WindowState::MaximizedVert);
178 state.mode = Mode::ReadyToResize(handle);
180 }
181 if w.floating() {
182 let offset = w.get_floating_offsets().unwrap_or_default();
183 w.start_loc = Some(offset);
184 } else {
185 let container = w.container_size.unwrap_or_default();
186 let normal = w.normal;
187 let floating = normal - container;
188 w.set_floating_offsets(Some(floating));
189 w.start_loc = Some(floating);
190 w.set_floating(true);
191 state.mode = Mode::ReadyToResize(handle);
193 }
194 }
195 state.move_to_top(&handle);
196}