diff options
-rw-r--r-- | include/config.h | 2 | ||||
-rw-r--r-- | include/handlers.h | 2 | ||||
-rw-r--r-- | sway/commands.c | 13 | ||||
-rw-r--r-- | sway/handlers.c | 130 |
4 files changed, 134 insertions, 13 deletions
diff --git a/include/config.h b/include/config.h index 38e93eb8..b9511aac 100644 --- a/include/config.h +++ b/include/config.h | |||
@@ -3,6 +3,7 @@ | |||
3 | 3 | ||
4 | #include <stdint.h> | 4 | #include <stdint.h> |
5 | #include <wlc/wlc.h> | 5 | #include <wlc/wlc.h> |
6 | #include <xkbcommon/xkbcommon.h> | ||
6 | #include "list.h" | 7 | #include "list.h" |
7 | 8 | ||
8 | struct sway_variable { | 9 | struct sway_variable { |
@@ -32,6 +33,7 @@ struct sway_config { | |||
32 | list_t *cmd_queue; | 33 | list_t *cmd_queue; |
33 | list_t *workspace_outputs; | 34 | list_t *workspace_outputs; |
34 | struct sway_mode *current_mode; | 35 | struct sway_mode *current_mode; |
36 | uint32_t floating_mod; | ||
35 | 37 | ||
36 | // Flags | 38 | // Flags |
37 | bool focus_follows_mouse; | 39 | bool focus_follows_mouse; |
diff --git a/include/handlers.h b/include/handlers.h index d1742cce..c954ce61 100644 --- a/include/handlers.h +++ b/include/handlers.h | |||
@@ -5,7 +5,7 @@ | |||
5 | #include <wlc/wlc.h> | 5 | #include <wlc/wlc.h> |
6 | 6 | ||
7 | extern struct wlc_interface interface; | 7 | extern struct wlc_interface interface; |
8 | 8 | extern uint32_t keys_pressed[32]; | |
9 | //set focus to current pointer location and return focused container | 9 | //set focus to current pointer location and return focused container |
10 | swayc_t *focus_pointer(void); | 10 | swayc_t *focus_pointer(void); |
11 | 11 | ||
diff --git a/sway/commands.c b/sway/commands.c index 444e6159..f47edd2f 100644 --- a/sway/commands.c +++ b/sway/commands.c | |||
@@ -171,6 +171,10 @@ static bool cmd_exit(struct sway_config *config, int argc, char **argv) { | |||
171 | } | 171 | } |
172 | 172 | ||
173 | static bool cmd_floating(struct sway_config *config, int argc, char **argv) { | 173 | static bool cmd_floating(struct sway_config *config, int argc, char **argv) { |
174 | if (!checkarg(argc, "floating", EXPECTED_EQUAL_TO, 1)) { | ||
175 | return false; | ||
176 | } | ||
177 | |||
174 | if (strcasecmp(argv[0], "toggle") == 0) { | 178 | if (strcasecmp(argv[0], "toggle") == 0) { |
175 | swayc_t *view = get_focused_container(&root_container); | 179 | swayc_t *view = get_focused_container(&root_container); |
176 | // Prevent running floating commands on things like workspaces | 180 | // Prevent running floating commands on things like workspaces |
@@ -241,6 +245,14 @@ static bool cmd_floating(struct sway_config *config, int argc, char **argv) { | |||
241 | return true; | 245 | return true; |
242 | } | 246 | } |
243 | 247 | ||
248 | static bool cmd_floating_mod(struct sway_config *config, int argc, char **argv) { | ||
249 | if (!checkarg(argc, "floating_modifier", EXPECTED_EQUAL_TO, 1)) { | ||
250 | return false; | ||
251 | } | ||
252 | config->floating_mod = xkb_keysym_from_name(argv[0], XKB_KEYSYM_CASE_INSENSITIVE); | ||
253 | return true; | ||
254 | } | ||
255 | |||
244 | static bool cmd_focus(struct sway_config *config, int argc, char **argv) { | 256 | static bool cmd_focus(struct sway_config *config, int argc, char **argv) { |
245 | if (!checkarg(argc, "focus", EXPECTED_EQUAL_TO, 1)) { | 257 | if (!checkarg(argc, "focus", EXPECTED_EQUAL_TO, 1)) { |
246 | return false; | 258 | return false; |
@@ -465,6 +477,7 @@ static struct cmd_handler handlers[] = { | |||
465 | { "exec_always", cmd_exec_always }, | 477 | { "exec_always", cmd_exec_always }, |
466 | { "exit", cmd_exit }, | 478 | { "exit", cmd_exit }, |
467 | { "floating", cmd_floating }, | 479 | { "floating", cmd_floating }, |
480 | { "floating_modifier", cmd_floating_mod }, | ||
468 | { "focus", cmd_focus }, | 481 | { "focus", cmd_focus }, |
469 | { "focus_follows_mouse", cmd_focus_follows_mouse }, | 482 | { "focus_follows_mouse", cmd_focus_follows_mouse }, |
470 | { "fullscreen", cmd_fullscreen }, | 483 | { "fullscreen", cmd_fullscreen }, |
diff --git a/sway/handlers.c b/sway/handlers.c index e17aefee..c39c1628 100644 --- a/sway/handlers.c +++ b/sway/handlers.c | |||
@@ -12,10 +12,15 @@ | |||
12 | #include "workspace.h" | 12 | #include "workspace.h" |
13 | #include "container.h" | 13 | #include "container.h" |
14 | 14 | ||
15 | uint32_t keys_pressed[32]; | ||
16 | |||
15 | static struct wlc_origin mouse_origin; | 17 | static struct wlc_origin mouse_origin; |
16 | //Keyboard input is being overrided by window (dmenu) | 18 | //Keyboard input is being overrided by window (dmenu) |
17 | static bool override_redirect = false; | 19 | static bool override_redirect = false; |
18 | 20 | ||
21 | static bool m1_held = false; | ||
22 | static bool m2_held = false; | ||
23 | |||
19 | static bool pointer_test(swayc_t *view, void *_origin) { | 24 | static bool pointer_test(swayc_t *view, void *_origin) { |
20 | const struct wlc_origin *origin = _origin; | 25 | const struct wlc_origin *origin = _origin; |
21 | //Determine the output that the view is under | 26 | //Determine the output that the view is under |
@@ -186,7 +191,7 @@ static void handle_view_geometry_request(wlc_handle handle, const struct wlc_geo | |||
186 | view->x = geometry->origin.x; | 191 | view->x = geometry->origin.x; |
187 | view->y = geometry->origin.y; | 192 | view->y = geometry->origin.y; |
188 | arrange_windows(view->parent, -1, -1); | 193 | arrange_windows(view->parent, -1, -1); |
189 | } | 194 | } |
190 | } | 195 | } |
191 | } | 196 | } |
192 | 197 | ||
@@ -230,7 +235,6 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier | |||
230 | return false; | 235 | return false; |
231 | } | 236 | } |
232 | static uint8_t head = 0; | 237 | static uint8_t head = 0; |
233 | static uint32_t array[QSIZE]; | ||
234 | bool cmd_success = false; | 238 | bool cmd_success = false; |
235 | 239 | ||
236 | struct sway_mode *mode = config->current_mode; | 240 | struct sway_mode *mode = config->current_mode; |
@@ -239,13 +243,13 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier | |||
239 | 243 | ||
240 | //Find key, if it has been pressed | 244 | //Find key, if it has been pressed |
241 | int mid = 0; | 245 | int mid = 0; |
242 | while (mid < head && array[mid] != sym) { | 246 | while (mid < head && keys_pressed[mid] != sym) { |
243 | ++mid; | 247 | ++mid; |
244 | } | 248 | } |
245 | if (state == WLC_KEY_STATE_PRESSED && mid == head && head + 1 < QSIZE) { | 249 | if (state == WLC_KEY_STATE_PRESSED && mid == head && head + 1 < QSIZE) { |
246 | array[head++] = sym; | 250 | keys_pressed[head++] = sym; |
247 | } else if (state == WLC_KEY_STATE_RELEASED && mid < head) { | 251 | } else if (state == WLC_KEY_STATE_RELEASED && mid < head) { |
248 | memmove(array + mid, array + mid + 1, sizeof*array * (--head - mid)); | 252 | memmove(keys_pressed + mid, keys_pressed + mid + 1, sizeof*keys_pressed * (--head - mid)); |
249 | } | 253 | } |
250 | // TODO: reminder to check conflicts with mod+q+a versus mod+q | 254 | // TODO: reminder to check conflicts with mod+q+a versus mod+q |
251 | int i; | 255 | int i; |
@@ -260,7 +264,7 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier | |||
260 | xkb_keysym_t *key = binding->keys->items[j]; | 264 | xkb_keysym_t *key = binding->keys->items[j]; |
261 | uint8_t k; | 265 | uint8_t k; |
262 | for (k = 0; k < head; ++k) { | 266 | for (k = 0; k < head; ++k) { |
263 | if (array[k] == *key) { | 267 | if (keys_pressed[k] == *key) { |
264 | match = true; | 268 | match = true; |
265 | break; | 269 | break; |
266 | } | 270 | } |
@@ -271,12 +275,12 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier | |||
271 | } | 275 | } |
272 | 276 | ||
273 | if (match) { | 277 | if (match) { |
274 | //Remove matched keys from array | 278 | //Remove matched keys from keys_pressed |
275 | int j; | 279 | int j; |
276 | for (j = 0; j < binding->keys->length; ++j) { | 280 | for (j = 0; j < binding->keys->length; ++j) { |
277 | uint8_t k; | 281 | uint8_t k; |
278 | for (k = 0; k < head; ++k) { | 282 | for (k = 0; k < head; ++k) { |
279 | memmove(array + k, array + k + 1, sizeof*array * (--head - k)); | 283 | memmove(keys_pressed + k, keys_pressed + k + 1, sizeof*keys_pressed * (--head - k)); |
280 | break; | 284 | break; |
281 | } | 285 | } |
282 | } | 286 | } |
@@ -291,13 +295,100 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier | |||
291 | return cmd_success; | 295 | return cmd_success; |
292 | } | 296 | } |
293 | 297 | ||
294 | static bool handle_pointer_motion(wlc_handle view, uint32_t time, const struct wlc_origin *origin) { | 298 | static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct wlc_origin *origin) { |
295 | static wlc_handle prev_view = 0; | 299 | static struct wlc_origin prev_pos; |
300 | static wlc_handle prev_handle = 0; | ||
296 | mouse_origin = *origin; | 301 | mouse_origin = *origin; |
297 | if (config->focus_follows_mouse && prev_view != view) { | 302 | bool changed_floating = false; |
303 | int i = 0; | ||
304 | // Do checks to determine if proper keys are being held | ||
305 | swayc_t *view = active_workspace->focused; | ||
306 | if (m1_held) { | ||
307 | if (view->is_floating) { | ||
308 | while (keys_pressed[i++]) { | ||
309 | if (keys_pressed[i] == config->floating_mod) { | ||
310 | int dx = mouse_origin.x - prev_pos.x; | ||
311 | int dy = mouse_origin.y - prev_pos.y; | ||
312 | 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); | ||
313 | sway_log(L_DEBUG, "Moving: dx: %d, dy: %d", dx, dy); | ||
314 | |||
315 | view->x += dx; | ||
316 | view->y += dy; | ||
317 | changed_floating = true; | ||
318 | break; | ||
319 | } | ||
320 | } | ||
321 | } | ||
322 | } else if (m2_held) { | ||
323 | if (view->is_floating) { | ||
324 | while (keys_pressed[i++]) { | ||
325 | if (keys_pressed[i] == config->floating_mod) { | ||
326 | int dx = mouse_origin.x - prev_pos.x; | ||
327 | int dy = mouse_origin.y - prev_pos.y; | ||
328 | 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); | ||
329 | sway_log(L_INFO, "Moving: dx: %d, dy: %d", dx, dy); | ||
330 | |||
331 | // Move and resize the view based on the dx/dy and mouse position | ||
332 | int midway_x = view->x + view->width/2; | ||
333 | int midway_y = view->y + view->height/2; | ||
334 | |||
335 | if (dx < 0) { | ||
336 | changed_floating = true; | ||
337 | if (mouse_origin.x > midway_x) { | ||
338 | sway_log(L_INFO, "Downsizing view to the left"); | ||
339 | view->width += dx; | ||
340 | } else { | ||
341 | sway_log(L_INFO, "Upsizing view to the left"); | ||
342 | view->x += dx; | ||
343 | view->width -= dx; | ||
344 | } | ||
345 | } else if (dx > 0){ | ||
346 | changed_floating = true; | ||
347 | if (mouse_origin.x > midway_x) { | ||
348 | sway_log(L_INFO, "Upsizing to the right"); | ||
349 | view->width += dx; | ||
350 | } else { | ||
351 | sway_log(L_INFO, "Downsizing to the right"); | ||
352 | view->x += dx; | ||
353 | view->width -= dx; | ||
354 | } | ||
355 | } | ||
356 | |||
357 | if (dy < 0) { | ||
358 | changed_floating = true; | ||
359 | if (mouse_origin.y > midway_y) { | ||
360 | sway_log(L_INFO, "Downsizing view to the top"); | ||
361 | view->height += dy; | ||
362 | } else { | ||
363 | sway_log(L_INFO, "Upsizing the view to the top"); | ||
364 | view->y += dy; | ||
365 | view->height -= dy; | ||
366 | } | ||
367 | } else if (dy > 0) { | ||
368 | changed_floating = true; | ||
369 | if (mouse_origin.y > midway_y) { | ||
370 | sway_log(L_INFO, "Upsizing to the bottom"); | ||
371 | view->height += dy; | ||
372 | } else { | ||
373 | sway_log(L_INFO, "Downsizing to the bottom"); | ||
374 | view->y += dy; | ||
375 | view->height -= dy; | ||
376 | } | ||
377 | } | ||
378 | break; | ||
379 | } | ||
380 | } | ||
381 | } | ||
382 | } | ||
383 | if (config->focus_follows_mouse && prev_handle != handle) { | ||
298 | focus_pointer(); | 384 | focus_pointer(); |
299 | } | 385 | } |
300 | prev_view = view; | 386 | prev_handle = handle; |
387 | prev_pos = mouse_origin; | ||
388 | if (changed_floating) { | ||
389 | arrange_windows(view, -1, -1); | ||
390 | return true; | ||
391 | } | ||
301 | return false; | 392 | return false; |
302 | } | 393 | } |
303 | 394 | ||
@@ -305,8 +396,23 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w | |||
305 | uint32_t button, enum wlc_button_state state) { | 396 | uint32_t button, enum wlc_button_state state) { |
306 | swayc_t *focused = get_focused_container(&root_container); | 397 | swayc_t *focused = get_focused_container(&root_container); |
307 | if (state == WLC_BUTTON_STATE_PRESSED) { | 398 | if (state == WLC_BUTTON_STATE_PRESSED) { |
399 | sway_log(L_DEBUG, "Mouse button %u pressed", button); | ||
400 | if (button == 272) { | ||
401 | m1_held = true; | ||
402 | } | ||
403 | if (button == 273) { | ||
404 | m2_held = true; | ||
405 | } | ||
308 | swayc_t *pointer = focus_pointer(); | 406 | swayc_t *pointer = focus_pointer(); |
309 | return (pointer && pointer != focused); | 407 | return (pointer && pointer != focused); |
408 | } else { | ||
409 | sway_log(L_DEBUG, "Mouse button %u released", button); | ||
410 | if (button == 272) { | ||
411 | m1_held = false; | ||
412 | } | ||
413 | if (button == 273) { | ||
414 | m2_held = false; | ||
415 | } | ||
310 | } | 416 | } |
311 | return false; | 417 | return false; |
312 | } | 418 | } |