summaryrefslogtreecommitdiffstats
path: root/sway/handlers.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/handlers.c')
-rw-r--r--sway/handlers.c326
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"
17uint32_t keys_pressed[32];
18 17
19static struct wlc_origin mouse_origin; 18static struct wlc_origin mouse_origin;
20 19
21static bool m1_held = false;
22static bool m2_held = false;
23
24static bool pointer_test(swayc_t *view, void *_origin) { 20static 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
89static bool handle_output_created(wlc_handle output) { 84static 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
139static bool handle_view_created(wlc_handle handle) { 134static 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
206static void handle_view_geometry_request(wlc_handle handle, const struct wlc_geometry *geometry) { 227static 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
227static void handle_view_state_request(wlc_handle view, enum wlc_view_state_bit state, bool toggle) { 248static 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
258static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifiers *modifiers, 277static 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
325static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct wlc_origin *origin) { 336static 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
429static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct wlc_modifiers *modifiers, 450static 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;