gimp but for windows: a wayland compositor
git clone https://github.com/m-col/wimp
Files | Refs | Readme

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