summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/config.h2
-rw-r--r--include/handlers.h2
-rw-r--r--sway/commands.c13
-rw-r--r--sway/handlers.c130
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
8struct sway_variable { 9struct 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
7extern struct wlc_interface interface; 7extern struct wlc_interface interface;
8 8extern 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
10swayc_t *focus_pointer(void); 10swayc_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
173static bool cmd_floating(struct sway_config *config, int argc, char **argv) { 173static 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
248static 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
244static bool cmd_focus(struct sway_config *config, int argc, char **argv) { 256static 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
15uint32_t keys_pressed[32];
16
15static struct wlc_origin mouse_origin; 17static struct wlc_origin mouse_origin;
16//Keyboard input is being overrided by window (dmenu) 18//Keyboard input is being overrided by window (dmenu)
17static bool override_redirect = false; 19static bool override_redirect = false;
18 20
21static bool m1_held = false;
22static bool m2_held = false;
23
19static bool pointer_test(swayc_t *view, void *_origin) { 24static 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
294static bool handle_pointer_motion(wlc_handle view, uint32_t time, const struct wlc_origin *origin) { 298static 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}