Commit ab6be9c260a8f8556020af2f9ffbd4b1340544e4 Parent: eda920e395627606974e1258c85716b06b421eac Author: mcol <mcol@posteo.net> Date: 2020-11-22 23:47:03 +0000 Committer: mcol <mcol@posteo.net> Committed: 2020-11-22 23:47:03 +0000 implement vi-like marks for saving positions
src/types.h Modified
@@ -39,6 +39,8 @@ int desk_count; struct desk *current_desk; bool can_steal_focus; + struct wl_list marks; + bool mark_waiting; struct wlr_cursor *cursor; struct wlr_xcursor_manager *cursor_manager; @@ -123,4 +125,11 @@ SCROLL, }; +struct mark { + struct wl_list link; + uint32_t key; + struct desk *desk; + double zoom, x, y; +}; + #endif
src/input.c Modified
@@ -5,6 +5,7 @@ #include <wlr/types/wlr_data_device.h> #include <wlr/types/wlr_xcursor_manager.h> +#include "action.h" #include "input.h" #include "shell.h" #include "types.h" @@ -248,26 +249,38 @@ int nsyms = xkb_state_key_get_syms( keyboard->device->keyboard->xkb_state, keycode, &syms); - bool handled = false; - uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); - struct binding *kb; - if ((modifiers & server->mod) && event->state == WLR_KEY_PRESSED) { - modifiers &= ~server->mod; - for (int i = 0; i < nsyms; i++) { - wl_list_for_each(kb, &server->key_bindings, link) { - if (syms[i] == kb->key && modifiers == kb->mods) { - kb->action(server, kb->data); - handled = true; + if (event->state == WLR_KEY_PRESSED) { + if (server->mark_waiting) { + server->mark_waiting = false; + struct mark *mark; + mark = wl_container_of(server->marks.next, mark, link); + if (mark->key == 0) { + actually_set_mark(server, syms[0]); + } else { + actually_go_to_mark(server, syms[0]); + } + return; + } + + uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); + struct binding *kb; + if ((modifiers & server->mod)) { + modifiers &= ~server->mod; + for (int i = 0; i < nsyms; i++) { + wl_list_for_each(kb, &server->key_bindings, link) { + if (syms[i] == kb->key && modifiers == kb->mods) { + kb->action(server, kb->data); + return; + } } } } } - if (!handled) { - // forward to client - wlr_seat_keyboard_notify_key(seat, event->time_msec, - event->keycode, event->state); - } + // forward to client + wlr_seat_keyboard_notify_key( + seat, event->time_msec, event->keycode, event->state + ); }
src/config.c Modified
@@ -69,6 +69,10 @@ kb->data = calloc(1, sizeof(int)); *(int *)(kb->data) = -1; } + else if (strcasecmp(name, "set_mark") == 0) + kb->action = &set_mark; + else if (strcasecmp(name, "go_to_mark") == 0) + kb->action = &go_to_mark; else if (strcasecmp(name, "exec") == 0) { kb->action = &exec_command; kb->data = calloc(strlen(data), sizeof(char)); @@ -226,6 +230,9 @@ server->zoom_max = 3; server->reverse_scrolling = false; server->vt_switching = true; + + wl_list_init(&server->marks); + server->mark_waiting = false; }
src/action.h Modified
@@ -13,5 +13,9 @@ void reset_pan(struct server *server, void *data); void save_pan(struct server *server, void *data); void zoom_desk(struct server *server, void *data); +void set_mark(struct server *server, void *data); +void actually_set_mark(struct server *server, const xkb_keysym_t sym); +void go_to_mark(struct server *server, void *data); +void actually_go_to_mark(struct server *server, const xkb_keysym_t sym); #endif
src/action.c Modified
@@ -112,3 +112,69 @@ desk->panned_x -= fx; desk->panned_y -= fy; } + + +void set_mark(struct server *server, void *data) { + struct mark *mark = calloc(1, sizeof(struct mark)); + struct desk *desk = server->current_desk; + mark->desk = desk; + mark->x = desk->panned_x; + mark->y = desk->panned_y; + mark->zoom = desk->zoom; + mark->key = 0; + server->mark_waiting = true; + wl_list_insert(&server->marks, &mark->link); +} + + +void actually_set_mark(struct server *server, const xkb_keysym_t sym) { + struct mark *mark; + struct mark *existing = NULL; + + if (sym == XKB_KEY_Escape) { + mark = wl_container_of(server->marks.next, mark, link); + wl_list_remove(&mark->link); + free(mark); + return; + } + + wl_list_for_each(mark, &server->marks, link) { + if (mark->key == sym) { + existing = mark; + break; + } + } + if (existing) { + wl_list_remove(&existing->link); + free(existing); + } + + mark = wl_container_of(server->marks.next, mark, link); + mark->key = sym; +} + + +void go_to_mark(struct server *server, void *data) { + server->mark_waiting = true; +} + + +void actually_go_to_mark(struct server *server, const xkb_keysym_t sym) { + struct mark *mark; + + if (sym == XKB_KEY_Escape) + return; + + wl_list_for_each(mark, &server->marks, link) { + if (mark->key == sym) { + struct motion motion = { + .dx = mark->x - mark->desk->panned_x, + .dy = mark->y - mark->desk->panned_y, + }; + mark->desk->zoom = mark->zoom; + set_desk(server, mark->desk); + pan_desk(server, &motion); + return; + } + } +}
readme.rst Modified
@@ -20,7 +20,6 @@ - functions to shift focus - functions to shift desk view - screenshots protocol - - vim-like marks to save desk views - handle fullscreening - pinch gestures for desk zooming - draw rect with mouse when zoomed out to set new view
deskwm.conf Modified
@@ -42,6 +42,14 @@ # The line after 'exec' is executed by /bin/sh bind Return exec wterm +# These two actions can be used to mark and go to set positions. Each one, once +# pressed, waits for the following key press and uses that as the 'mark', e.g. +# hitting 'mod + m' then 'a' will save the current position, then hitting +# 'mod + `' then 'a' later will move to that marked position. These can be +# cancelled with the escape key. +bind m set_mark +bind grave go_to_mark + # Possible mouse bindings: motion, scroll (+ additional modifiers) bind scroll pan_desk bind Shift scroll zoom_desk