diff options
Diffstat (limited to 'sway/handlers.c')
-rw-r--r-- | sway/handlers.c | 326 |
1 files changed, 182 insertions, 144 deletions
diff --git a/sway/handlers.c b/sway/handlers.c index 534b4e4f..79628fe5 100644 --- a/sway/handlers.c +++ b/sway/handlers.c | |||
@@ -13,21 +13,14 @@ | |||
13 | #include "workspace.h" | 13 | #include "workspace.h" |
14 | #include "container.h" | 14 | #include "container.h" |
15 | #include "focus.h" | 15 | #include "focus.h" |
16 | 16 | #include "input_state.h" | |
17 | uint32_t keys_pressed[32]; | ||
18 | 17 | ||
19 | static struct wlc_origin mouse_origin; | 18 | static struct wlc_origin mouse_origin; |
20 | 19 | ||
21 | static bool m1_held = false; | ||
22 | static bool m2_held = false; | ||
23 | |||
24 | static bool pointer_test(swayc_t *view, void *_origin) { | 20 | static bool pointer_test(swayc_t *view, void *_origin) { |
25 | const struct wlc_origin *origin = _origin; | 21 | const struct wlc_origin *origin = _origin; |
26 | // Determine the output that the view is under | 22 | // Determine the output that the view is under |
27 | swayc_t *parent = view; | 23 | swayc_t *parent = swayc_parent_by_type(view, C_OUTPUT); |
28 | while (parent->type != C_OUTPUT) { | ||
29 | parent = parent->parent; | ||
30 | } | ||
31 | if (origin->x >= view->x && origin->y >= view->y | 24 | if (origin->x >= view->x && origin->y >= view->y |
32 | && origin->x < view->x + view->width && origin->y < view->y + view->height | 25 | && origin->x < view->x + view->width && origin->y < view->y + view->height |
33 | && view->visible && parent == root_container.focused) { | 26 | && view->visible && parent == root_container.focused) { |
@@ -86,10 +79,12 @@ swayc_t *container_under_pointer(void) { | |||
86 | return lookup; | 79 | return lookup; |
87 | } | 80 | } |
88 | 81 | ||
82 | /* Handles */ | ||
83 | |||
89 | static bool handle_output_created(wlc_handle output) { | 84 | static bool handle_output_created(wlc_handle output) { |
90 | swayc_t *op = new_output(output); | 85 | swayc_t *op = new_output(output); |
91 | 86 | ||
92 | //Switch to workspace if we need to | 87 | // Switch to workspace if we need to |
93 | if (active_workspace == NULL) { | 88 | if (active_workspace == NULL) { |
94 | swayc_t *ws = op->children->items[0]; | 89 | swayc_t *ws = op->children->items[0]; |
95 | workspace_switch(ws); | 90 | workspace_switch(ws); |
@@ -111,7 +106,7 @@ static void handle_output_destroyed(wlc_handle output) { | |||
111 | if (list->length == 0) { | 106 | if (list->length == 0) { |
112 | active_workspace = NULL; | 107 | active_workspace = NULL; |
113 | } else { | 108 | } else { |
114 | //switch to other outputs active workspace | 109 | // switch to other outputs active workspace |
115 | workspace_switch(((swayc_t *)root_container.children->items[0])->focused); | 110 | workspace_switch(((swayc_t *)root_container.children->items[0])->focused); |
116 | } | 111 | } |
117 | } | 112 | } |
@@ -137,38 +132,64 @@ static void handle_output_focused(wlc_handle output, bool focus) { | |||
137 | } | 132 | } |
138 | 133 | ||
139 | static bool handle_view_created(wlc_handle handle) { | 134 | static bool handle_view_created(wlc_handle handle) { |
140 | swayc_t *focused = get_focused_container(&root_container); | 135 | // if view is child of another view, the use that as focused container |
136 | wlc_handle parent = wlc_view_get_parent(handle); | ||
137 | swayc_t *focused = NULL; | ||
141 | swayc_t *newview = NULL; | 138 | swayc_t *newview = NULL; |
139 | |||
140 | // Get parent container, to add view in | ||
141 | if (parent) { | ||
142 | focused = get_swayc_for_handle(parent, &root_container); | ||
143 | } | ||
144 | if (!focused || focused->type == C_OUTPUT) { | ||
145 | focused = get_focused_container(&root_container); | ||
146 | } | ||
147 | sway_log(L_DEBUG, "handle:%ld type:%x state:%x parent:%ld " | ||
148 | "mask:%d (x:%d y:%d w:%d h:%d) title:%s " | ||
149 | "class:%s appid:%s", | ||
150 | handle, wlc_view_get_type(handle), wlc_view_get_state(handle), parent, | ||
151 | wlc_view_get_mask(handle), wlc_view_get_geometry(handle)->origin.x, | ||
152 | wlc_view_get_geometry(handle)->origin.y,wlc_view_get_geometry(handle)->size.w, | ||
153 | wlc_view_get_geometry(handle)->size.h, wlc_view_get_title(handle), | ||
154 | wlc_view_get_class(handle), wlc_view_get_app_id(handle)); | ||
155 | |||
156 | // TODO properly figure out how each window should be handled. | ||
142 | switch (wlc_view_get_type(handle)) { | 157 | switch (wlc_view_get_type(handle)) { |
143 | // regular view created regularly | 158 | // regular view created regularly |
144 | case 0: | 159 | case 0: |
145 | newview = new_view(focused, handle); | 160 | newview = new_view(focused, handle); |
146 | wlc_view_set_state(handle, WLC_BIT_MAXIMIZED, true); | 161 | wlc_view_set_state(handle, WLC_BIT_MAXIMIZED, true); |
147 | break; | 162 | break; |
148 | // takes keyboard focus | 163 | |
164 | // Dmenu keeps viewfocus, but others with this flag dont, for now simulate | ||
165 | // dmenu | ||
149 | case WLC_BIT_OVERRIDE_REDIRECT: | 166 | case WLC_BIT_OVERRIDE_REDIRECT: |
150 | sway_log(L_DEBUG, "view %ld with OVERRIDE_REDIRECT", handle); | 167 | // locked_view_focus = true; |
151 | locked_view_focus = true; | ||
152 | wlc_view_focus(handle); | 168 | wlc_view_focus(handle); |
153 | wlc_view_set_state(handle, WLC_BIT_ACTIVATED, true); | 169 | wlc_view_set_state(handle, WLC_BIT_ACTIVATED, true); |
154 | wlc_view_bring_to_front(handle); | 170 | wlc_view_bring_to_front(handle); |
155 | break; | 171 | break; |
156 | // Takes container focus | 172 | |
173 | // Firefox popups have this flag set. | ||
157 | case WLC_BIT_OVERRIDE_REDIRECT|WLC_BIT_UNMANAGED: | 174 | case WLC_BIT_OVERRIDE_REDIRECT|WLC_BIT_UNMANAGED: |
158 | sway_log(L_DEBUG, "view %ld with OVERRIDE_REDIRECT|WLC_BIT_MANAGED", handle); | ||
159 | wlc_view_bring_to_front(handle); | 175 | wlc_view_bring_to_front(handle); |
160 | locked_container_focus = true; | 176 | locked_container_focus = true; |
161 | break; | 177 | break; |
162 | // set modals as floating containers | 178 | |
179 | // Modals, get focus, popups do not | ||
163 | case WLC_BIT_MODAL: | 180 | case WLC_BIT_MODAL: |
181 | wlc_view_focus(handle); | ||
164 | wlc_view_bring_to_front(handle); | 182 | wlc_view_bring_to_front(handle); |
165 | newview = new_floating_view(handle); | 183 | newview = new_floating_view(handle); |
166 | case WLC_BIT_POPUP: | 184 | case WLC_BIT_POPUP: |
185 | wlc_view_bring_to_front(handle); | ||
167 | break; | 186 | break; |
168 | } | 187 | } |
188 | |||
169 | if (newview) { | 189 | if (newview) { |
170 | set_focused_container(newview); | 190 | set_focused_container(newview); |
171 | arrange_windows(newview->parent, -1, -1); | 191 | swayc_t *output = swayc_parent_by_type(newview, C_OUTPUT); |
192 | arrange_windows(output, -1, -1); | ||
172 | } | 193 | } |
173 | return true; | 194 | return true; |
174 | } | 195 | } |
@@ -181,19 +202,19 @@ static void handle_view_destroyed(wlc_handle handle) { | |||
181 | // regular view created regularly | 202 | // regular view created regularly |
182 | case 0: | 203 | case 0: |
183 | case WLC_BIT_MODAL: | 204 | case WLC_BIT_MODAL: |
205 | case WLC_BIT_POPUP: | ||
184 | if (view) { | 206 | if (view) { |
185 | swayc_t *parent = destroy_view(view); | 207 | swayc_t *parent = destroy_view(view); |
186 | arrange_windows(parent, -1, -1); | 208 | arrange_windows(parent, -1, -1); |
187 | } | 209 | } |
188 | break; | 210 | break; |
189 | // takes keyboard focus | 211 | // DMENU has this flag, and takes view_focus, but other things with this |
212 | // flag dont | ||
190 | case WLC_BIT_OVERRIDE_REDIRECT: | 213 | case WLC_BIT_OVERRIDE_REDIRECT: |
191 | locked_view_focus = false; | 214 | // locked_view_focus = false; |
192 | break; | 215 | break; |
193 | // Takes container focus | ||
194 | case WLC_BIT_OVERRIDE_REDIRECT|WLC_BIT_UNMANAGED: | 216 | case WLC_BIT_OVERRIDE_REDIRECT|WLC_BIT_UNMANAGED: |
195 | locked_container_focus = false; | 217 | locked_container_focus = false; |
196 | case WLC_BIT_POPUP: | ||
197 | break; | 218 | break; |
198 | } | 219 | } |
199 | set_focused_container(get_focused_view(&root_container)); | 220 | set_focused_container(get_focused_view(&root_container)); |
@@ -205,7 +226,7 @@ static void handle_view_focus(wlc_handle view, bool focus) { | |||
205 | 226 | ||
206 | static void handle_view_geometry_request(wlc_handle handle, const struct wlc_geometry *geometry) { | 227 | static void handle_view_geometry_request(wlc_handle handle, const struct wlc_geometry *geometry) { |
207 | sway_log(L_DEBUG, "geometry request %d x %d : %d x %d", | 228 | sway_log(L_DEBUG, "geometry request %d x %d : %d x %d", |
208 | geometry->origin.x, geometry->origin.y, geometry->size.w,geometry->size.h); | 229 | geometry->origin.x, geometry->origin.y, geometry->size.w, geometry->size.h); |
209 | // If the view is floating, then apply the geometry. | 230 | // If the view is floating, then apply the geometry. |
210 | // Otherwise save the desired width/height for the view. | 231 | // Otherwise save the desired width/height for the view. |
211 | // This will not do anything for the time being as WLC improperly sends geometry requests | 232 | // This will not do anything for the time being as WLC improperly sends geometry requests |
@@ -225,21 +246,17 @@ static void handle_view_geometry_request(wlc_handle handle, const struct wlc_geo | |||
225 | } | 246 | } |
226 | 247 | ||
227 | static void handle_view_state_request(wlc_handle view, enum wlc_view_state_bit state, bool toggle) { | 248 | static void handle_view_state_request(wlc_handle view, enum wlc_view_state_bit state, bool toggle) { |
228 | swayc_t *c = NULL; | 249 | swayc_t *c = get_swayc_for_handle(view, &root_container); |
229 | switch(state) { | 250 | switch (state) { |
230 | case WLC_BIT_FULLSCREEN: | 251 | case WLC_BIT_FULLSCREEN: |
231 | // i3 just lets it become fullscreen | 252 | // i3 just lets it become fullscreen |
232 | wlc_view_set_state(view, state, toggle); | 253 | wlc_view_set_state(view, state, toggle); |
233 | c = get_swayc_for_handle(view, &root_container); | ||
234 | sway_log(L_DEBUG, "setting view %ld %s, fullscreen %d",view,c->name,toggle); | ||
235 | if (c) { | 254 | if (c) { |
255 | sway_log(L_DEBUG, "setting view %ld %s, fullscreen %d", view, c->name, toggle); | ||
236 | arrange_windows(c->parent, -1, -1); | 256 | arrange_windows(c->parent, -1, -1); |
237 | // Set it as focused window for that workspace if its going fullscreen | 257 | // Set it as focused window for that workspace if its going fullscreen |
238 | if (toggle) { | 258 | if (toggle) { |
239 | swayc_t *ws = c; | 259 | swayc_t *ws = swayc_parent_by_type(c, C_WORKSPACE); |
240 | while (ws->type != C_WORKSPACE) { | ||
241 | ws = ws->parent; | ||
242 | } | ||
243 | // Set ws focus to c | 260 | // Set ws focus to c |
244 | set_focused_container_for(ws, c); | 261 | set_focused_container_for(ws, c); |
245 | } | 262 | } |
@@ -248,7 +265,9 @@ static void handle_view_state_request(wlc_handle view, enum wlc_view_state_bit s | |||
248 | case WLC_BIT_MAXIMIZED: | 265 | case WLC_BIT_MAXIMIZED: |
249 | case WLC_BIT_RESIZING: | 266 | case WLC_BIT_RESIZING: |
250 | case WLC_BIT_MOVING: | 267 | case WLC_BIT_MOVING: |
268 | break; | ||
251 | case WLC_BIT_ACTIVATED: | 269 | case WLC_BIT_ACTIVATED: |
270 | sway_log(L_DEBUG, "View %p requested to be activated", c); | ||
252 | break; | 271 | break; |
253 | } | 272 | } |
254 | return; | 273 | return; |
@@ -257,29 +276,38 @@ static void handle_view_state_request(wlc_handle view, enum wlc_view_state_bit s | |||
257 | 276 | ||
258 | static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifiers *modifiers, | 277 | static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifiers *modifiers, |
259 | uint32_t key, uint32_t sym, enum wlc_key_state state) { | 278 | uint32_t key, uint32_t sym, enum wlc_key_state state) { |
260 | enum { QSIZE = 32 }; | 279 | |
261 | if (locked_view_focus && state == WLC_KEY_STATE_PRESSED) { | 280 | if (locked_view_focus && state == WLC_KEY_STATE_PRESSED) { |
262 | return false; | 281 | return false; |
263 | } | 282 | } |
264 | static uint8_t head = 0; | 283 | |
265 | bool cmd_success = false; | 284 | // Revert floating container back to original position on keypress |
285 | if (state == WLC_KEY_STATE_PRESSED && | ||
286 | (pointer_state.floating.drag || pointer_state.floating.resize)) { | ||
287 | reset_floating(get_focused_view(&root_container)); | ||
288 | } | ||
266 | 289 | ||
267 | struct sway_mode *mode = config->current_mode; | 290 | struct sway_mode *mode = config->current_mode; |
291 | |||
292 | if (sym < 70000 /* bullshit made up number */) { | ||
293 | if (!isalnum(sym) && sym != ' ' && sym != XKB_KEY_Escape && sym != XKB_KEY_Tab) { | ||
294 | // God fucking dammit | ||
295 | return false; | ||
296 | } | ||
297 | } | ||
298 | |||
268 | // Lowercase if necessary | 299 | // Lowercase if necessary |
269 | sym = tolower(sym); | 300 | sym = tolower(sym); |
270 | 301 | ||
271 | // Find key, if it has been pressed | 302 | int i; |
272 | int mid = 0; | 303 | |
273 | while (mid < head && keys_pressed[mid] != sym) { | 304 | if (state == WLC_KEY_STATE_PRESSED) { |
274 | ++mid; | 305 | press_key(sym); |
275 | } | 306 | } else { // WLC_KEY_STATE_RELEASED |
276 | if (state == WLC_KEY_STATE_PRESSED && mid == head && head + 1 < QSIZE) { | 307 | release_key(sym); |
277 | keys_pressed[head++] = sym; | ||
278 | } else if (state == WLC_KEY_STATE_RELEASED && mid < head) { | ||
279 | memmove(keys_pressed + mid, keys_pressed + mid + 1, sizeof*keys_pressed * (--head - mid)); | ||
280 | } | 308 | } |
309 | |||
281 | // TODO: reminder to check conflicts with mod+q+a versus mod+q | 310 | // TODO: reminder to check conflicts with mod+q+a versus mod+q |
282 | int i; | ||
283 | for (i = 0; i < mode->bindings->length; ++i) { | 311 | for (i = 0; i < mode->bindings->length; ++i) { |
284 | struct sway_binding *binding = mode->bindings->items[i]; | 312 | struct sway_binding *binding = mode->bindings->items[i]; |
285 | 313 | ||
@@ -287,39 +315,22 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier | |||
287 | bool match; | 315 | bool match; |
288 | int j; | 316 | int j; |
289 | for (j = 0; j < binding->keys->length; ++j) { | 317 | for (j = 0; j < binding->keys->length; ++j) { |
290 | match = false; | ||
291 | xkb_keysym_t *key = binding->keys->items[j]; | 318 | xkb_keysym_t *key = binding->keys->items[j]; |
292 | uint8_t k; | 319 | if ((match = check_key(*key)) == false) { |
293 | for (k = 0; k < head; ++k) { | ||
294 | if (keys_pressed[k] == *key) { | ||
295 | match = true; | ||
296 | break; | ||
297 | } | ||
298 | } | ||
299 | if (match == false) { | ||
300 | break; | 320 | break; |
301 | } | 321 | } |
302 | } | 322 | } |
303 | |||
304 | if (match) { | 323 | if (match) { |
305 | // Remove matched keys from keys_pressed | ||
306 | int j; | ||
307 | for (j = 0; j < binding->keys->length; ++j) { | ||
308 | uint8_t k; | ||
309 | for (k = 0; k < head; ++k) { | ||
310 | memmove(keys_pressed + k, keys_pressed + k + 1, sizeof*keys_pressed * (--head - k)); | ||
311 | break; | ||
312 | } | ||
313 | } | ||
314 | if (state == WLC_KEY_STATE_PRESSED) { | 324 | if (state == WLC_KEY_STATE_PRESSED) { |
315 | cmd_success = handle_command(config, binding->command); | 325 | handle_command(config, binding->command); |
326 | return true; | ||
316 | } else if (state == WLC_KEY_STATE_RELEASED) { | 327 | } else if (state == WLC_KEY_STATE_RELEASED) { |
317 | // TODO: --released | 328 | // TODO: --released |
318 | } | 329 | } |
319 | } | 330 | } |
320 | } | 331 | } |
321 | } | 332 | } |
322 | return cmd_success; | 333 | return false; |
323 | } | 334 | } |
324 | 335 | ||
325 | static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct wlc_origin *origin) { | 336 | static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct wlc_origin *origin) { |
@@ -327,119 +338,129 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct | |||
327 | static wlc_handle prev_handle = 0; | 338 | static wlc_handle prev_handle = 0; |
328 | mouse_origin = *origin; | 339 | mouse_origin = *origin; |
329 | bool changed_floating = false; | 340 | bool changed_floating = false; |
330 | int i = 0; | ||
331 | if (!active_workspace) { | 341 | if (!active_workspace) { |
332 | return false; | 342 | return false; |
333 | } | 343 | } |
334 | // Do checks to determine if proper keys are being held | 344 | // Do checks to determine if proper keys are being held |
335 | swayc_t *view = active_workspace->focused; | 345 | swayc_t *view = get_focused_view(active_workspace); |
336 | if (m1_held && view) { | 346 | uint32_t edge = 0; |
347 | if (pointer_state.floating.drag && view) { | ||
337 | if (view->is_floating) { | 348 | if (view->is_floating) { |
338 | while (keys_pressed[i++]) { | 349 | int dx = mouse_origin.x - prev_pos.x; |
339 | if (keys_pressed[i] == config->floating_mod) { | 350 | int dy = mouse_origin.y - prev_pos.y; |
340 | int dx = mouse_origin.x - prev_pos.x; | 351 | view->x += dx; |
341 | int dy = mouse_origin.y - prev_pos.y; | 352 | view->y += dy; |
342 | sway_log(L_DEBUG, "Moving from px: %d to cx: %d and from py: %d to cy: %d", prev_pos.x, mouse_origin.x, prev_pos.y, mouse_origin.y); | 353 | changed_floating = true; |
343 | sway_log(L_DEBUG, "Moving: dx: %d, dy: %d", dx, dy); | ||
344 | |||
345 | view->x += dx; | ||
346 | view->y += dy; | ||
347 | changed_floating = true; | ||
348 | break; | ||
349 | } | ||
350 | } | ||
351 | } | 354 | } |
352 | } else if (m2_held && view) { | 355 | } else if (pointer_state.floating.resize && view) { |
353 | if (view->is_floating) { | 356 | if (view->is_floating) { |
354 | while (keys_pressed[i++]) { | 357 | int dx = mouse_origin.x - prev_pos.x; |
355 | if (keys_pressed[i] == config->floating_mod) { | 358 | int dy = mouse_origin.y - prev_pos.y; |
356 | int dx = mouse_origin.x - prev_pos.x; | 359 | int min_sane_w = 100; |
357 | int dy = mouse_origin.y - prev_pos.y; | 360 | int min_sane_h = 60; |
358 | sway_log(L_DEBUG, "Moving from px: %d to cx: %d and from py: %d to cy: %d", prev_pos.x, mouse_origin.x, prev_pos.y, mouse_origin.y); | 361 | |
359 | sway_log(L_INFO, "Moving: dx: %d, dy: %d", dx, dy); | 362 | // Move and resize the view based on the dx/dy and mouse position |
360 | 363 | int midway_x = view->x + view->width/2; | |
361 | // Move and resize the view based on the dx/dy and mouse position | 364 | int midway_y = view->y + view->height/2; |
362 | int midway_x = view->x + view->width/2; | 365 | if (dx < 0) { |
363 | int midway_y = view->y + view->height/2; | 366 | if (!pointer_state.lock.right) { |
364 | 367 | if (view->width > min_sane_w) { | |
365 | if (dx < 0) { | ||
366 | changed_floating = true; | 368 | changed_floating = true; |
367 | if (mouse_origin.x > midway_x) { | 369 | view->width += dx; |
368 | sway_log(L_INFO, "Downsizing view to the left"); | 370 | edge += WLC_RESIZE_EDGE_RIGHT; |
369 | view->width += dx; | 371 | } |
370 | } else { | 372 | } else if (mouse_origin.x < midway_x && !pointer_state.lock.left) { |
371 | sway_log(L_INFO, "Upsizing view to the left"); | 373 | changed_floating = true; |
372 | view->x += dx; | 374 | view->x += dx; |
373 | view->width -= dx; | 375 | view->width -= dx; |
374 | } | 376 | edge += WLC_RESIZE_EDGE_LEFT; |
375 | } else if (dx > 0){ | 377 | } |
378 | } else if (dx > 0) { | ||
379 | if (mouse_origin.x > midway_x && !pointer_state.lock.right) { | ||
380 | changed_floating = true; | ||
381 | view->width += dx; | ||
382 | edge += WLC_RESIZE_EDGE_RIGHT; | ||
383 | } else if (!pointer_state.lock.left) { | ||
384 | if (view->width > min_sane_w) { | ||
376 | changed_floating = true; | 385 | changed_floating = true; |
377 | if (mouse_origin.x > midway_x) { | 386 | view->x += dx; |
378 | sway_log(L_INFO, "Upsizing to the right"); | 387 | view->width -= dx; |
379 | view->width += dx; | 388 | edge += WLC_RESIZE_EDGE_LEFT; |
380 | } else { | ||
381 | sway_log(L_INFO, "Downsizing to the right"); | ||
382 | view->x += dx; | ||
383 | view->width -= dx; | ||
384 | } | ||
385 | } | 389 | } |
390 | } | ||
391 | } | ||
386 | 392 | ||
387 | if (dy < 0) { | 393 | if (dy < 0) { |
394 | if (!pointer_state.lock.bottom) { | ||
395 | if (view->height > min_sane_h) { | ||
388 | changed_floating = true; | 396 | changed_floating = true; |
389 | if (mouse_origin.y > midway_y) { | 397 | view->height += dy; |
390 | sway_log(L_INFO, "Downsizing view to the top"); | 398 | edge += WLC_RESIZE_EDGE_BOTTOM; |
391 | view->height += dy; | 399 | } |
392 | } else { | 400 | } else if (mouse_origin.y < midway_y && !pointer_state.lock.top) { |
393 | sway_log(L_INFO, "Upsizing the view to the top"); | 401 | changed_floating = true; |
394 | view->y += dy; | 402 | view->y += dy; |
395 | view->height -= dy; | 403 | view->height -= dy; |
396 | } | 404 | edge += WLC_RESIZE_EDGE_TOP; |
397 | } else if (dy > 0) { | 405 | } |
406 | } else if (dy > 0) { | ||
407 | if (mouse_origin.y > midway_y && !pointer_state.lock.bottom) { | ||
408 | changed_floating = true; | ||
409 | view->height += dy; | ||
410 | edge += WLC_RESIZE_EDGE_BOTTOM; | ||
411 | } else if (!pointer_state.lock.top) { | ||
412 | if (view->height > min_sane_h) { | ||
398 | changed_floating = true; | 413 | changed_floating = true; |
399 | if (mouse_origin.y > midway_y) { | 414 | view->y += dy; |
400 | sway_log(L_INFO, "Upsizing to the bottom"); | 415 | view->height -= dy; |
401 | view->height += dy; | 416 | edge += WLC_RESIZE_EDGE_TOP; |
402 | } else { | ||
403 | sway_log(L_INFO, "Downsizing to the bottom"); | ||
404 | view->y += dy; | ||
405 | view->height -= dy; | ||
406 | } | ||
407 | } | 417 | } |
408 | break; | ||
409 | } | 418 | } |
410 | } | 419 | } |
411 | } | 420 | } |
412 | } | 421 | } |
413 | if (config->focus_follows_mouse && prev_handle != handle) { | 422 | if (config->focus_follows_mouse && prev_handle != handle) { |
414 | //Dont change focus if fullscreen | 423 | // Dont change focus if fullscreen |
415 | swayc_t *focused = get_focused_view(view); | 424 | swayc_t *focused = get_focused_view(view); |
416 | if (!(focused->type == C_VIEW && wlc_view_get_state(focused->handle) & WLC_BIT_FULLSCREEN)) { | 425 | if (!(focused->type == C_VIEW && wlc_view_get_state(focused->handle) & WLC_BIT_FULLSCREEN) |
426 | && !(pointer_state.l_held || pointer_state.r_held)) { | ||
417 | set_focused_container(container_under_pointer()); | 427 | set_focused_container(container_under_pointer()); |
418 | } | 428 | } |
419 | } | 429 | } |
420 | prev_handle = handle; | 430 | prev_handle = handle; |
421 | prev_pos = mouse_origin; | 431 | prev_pos = mouse_origin; |
422 | if (changed_floating) { | 432 | if (changed_floating) { |
423 | arrange_windows(view, -1, -1); | 433 | struct wlc_geometry geometry = { |
434 | .origin = { | ||
435 | .x = view->x, | ||
436 | .y = view->y | ||
437 | }, | ||
438 | .size = { | ||
439 | .w = view->width, | ||
440 | .h = view->height | ||
441 | } | ||
442 | }; | ||
443 | wlc_view_set_geometry(view->handle, edge, &geometry); | ||
424 | return true; | 444 | return true; |
425 | } | 445 | } |
426 | return false; | 446 | return false; |
427 | } | 447 | } |
428 | 448 | ||
449 | |||
429 | static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct wlc_modifiers *modifiers, | 450 | static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct wlc_modifiers *modifiers, |
430 | uint32_t button, enum wlc_button_state state) { | 451 | uint32_t button, enum wlc_button_state state, const struct wlc_origin *origin) { |
431 | swayc_t *focused = get_focused_container(&root_container); | 452 | swayc_t *focused = get_focused_container(&root_container); |
432 | //dont change focus if fullscreen | 453 | // dont change focus if fullscreen |
433 | if (focused->type == C_VIEW && wlc_view_get_state(focused->handle) & WLC_BIT_FULLSCREEN) { | 454 | if (focused->type == C_VIEW && wlc_view_get_state(focused->handle) & WLC_BIT_FULLSCREEN) { |
434 | return false; | 455 | return false; |
435 | } | 456 | } |
436 | if (state == WLC_BUTTON_STATE_PRESSED) { | 457 | if (state == WLC_BUTTON_STATE_PRESSED) { |
437 | sway_log(L_DEBUG, "Mouse button %u pressed", button); | 458 | sway_log(L_DEBUG, "Mouse button %u pressed", button); |
438 | if (button == 272) { | 459 | if (button == M_LEFT_CLICK) { |
439 | m1_held = true; | 460 | pointer_state.l_held = true; |
440 | } | 461 | } |
441 | if (button == 273) { | 462 | if (button == M_RIGHT_CLICK) { |
442 | m2_held = true; | 463 | pointer_state.r_held = true; |
443 | } | 464 | } |
444 | swayc_t *pointer = container_under_pointer(); | 465 | swayc_t *pointer = container_under_pointer(); |
445 | set_focused_container(pointer); | 466 | set_focused_container(pointer); |
@@ -453,15 +474,32 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w | |||
453 | } | 474 | } |
454 | } | 475 | } |
455 | arrange_windows(pointer->parent, -1, -1); | 476 | arrange_windows(pointer->parent, -1, -1); |
477 | if (modifiers->mods & config->floating_mod) { | ||
478 | int midway_x = pointer->x + pointer->width/2; | ||
479 | int midway_y = pointer->y + pointer->height/2; | ||
480 | |||
481 | pointer_state.floating.drag = pointer_state.l_held; | ||
482 | pointer_state.floating.resize = pointer_state.r_held; | ||
483 | pointer_state.lock.bottom = origin->y < midway_y; | ||
484 | pointer_state.lock.top = !pointer_state.lock.bottom; | ||
485 | pointer_state.lock.right = origin->x < midway_x; | ||
486 | pointer_state.lock.left = !pointer_state.lock.right; | ||
487 | start_floating(pointer); | ||
488 | } | ||
489 | // Dont want pointer sent to window while dragging or resizing | ||
490 | return (pointer_state.floating.drag || pointer_state.floating.resize); | ||
456 | } | 491 | } |
457 | return (pointer && pointer != focused); | 492 | return (pointer && pointer != focused); |
458 | } else { | 493 | } else { |
459 | sway_log(L_DEBUG, "Mouse button %u released", button); | 494 | sway_log(L_DEBUG, "Mouse button %u released", button); |
460 | if (button == 272) { | 495 | if (button == M_LEFT_CLICK) { |
461 | m1_held = false; | 496 | pointer_state.l_held = false; |
497 | pointer_state.floating.drag = false; | ||
462 | } | 498 | } |
463 | if (button == 273) { | 499 | if (button == M_RIGHT_CLICK) { |
464 | m2_held = false; | 500 | pointer_state.r_held = false; |
501 | pointer_state.floating.resize = false; | ||
502 | pointer_state.lock = (struct pointer_lock){false ,false ,false ,false}; | ||
465 | } | 503 | } |
466 | } | 504 | } |
467 | return false; | 505 | return false; |