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

Commit 576012ae48953683109778ccaae76ebbb5f05bc8
Parent: febede681273cb27d570ce228d4dcda26f44b2d8
Author: mcol <mcol@posteo.net>
Date: 2021-01-30 16:21:24 +0000
Committer: mcol <mcol@posteo.net>
Committed: 2021-01-30 16:21:30 +0000

add pinch gesture bindings with pinch zoom action

Closes #4

wimp.conf Modified

@@ -90,7 +90,8 @@
 bind		m		set_mark
 bind		grave		go_to_mark
 
-# Possible mouse bindings: motion, scroll, drag{1,2,3} (+ additional modifiers)
-bind		scroll		pan_desk_mouse
-bind	Shift	scroll		zoom_mouse
+# Possible mouse bindings: motion, scroll, pinch, drag{1,2,3} (+ additional modifiers)
+bind		scroll		pan_desk
+bind		pinch		zoom
+bind	Shift	scroll		zoom
 bind		drag1		move_window

src/types.h Modified

@@ -92,6 +92,8 @@
     action on_drag1;
     action on_drag2;
     action on_drag3;
+    action on_pinch;
+    action on_pinch_begin;
 
     bool reverse_scrolling;
     enum cursor_mode cursor_mode;
@@ -166,6 +168,7 @@
     enum wlr_keyboard_modifier mods;
     uint32_t key;
     action action;
+    action begin;
     void *data;
 };
 
@@ -181,6 +184,7 @@
     DRAG1 = 3,
     DRAG2 = 4,
     DRAG3 = 5,
+    PINCH = 6,
 };
 
 struct mark {

src/main.c Modified

@@ -29,6 +29,7 @@
     .on_drag1 = NULL,
     .on_drag2 = NULL,
     .on_drag3 = NULL,
+    .on_pinch = NULL,
     .can_steal_focus = true,
     .desk_count = 0,
     .mark_waiting = false,

src/keyboard.c Modified

@@ -38,6 +38,10 @@
 		    case DRAG3:
 			wimp.on_drag3 = kb->action;
 			break;
+		    case PINCH:
+			wimp.on_pinch = kb->action;
+			wimp.on_pinch_begin = kb->begin;
+			break;
 		}
 		wimp.cursor_mode = CURSOR_MOD;
 		handled = true;

src/cursor.c Modified

@@ -219,27 +219,40 @@
 
 static void on_pinch_end(struct wl_listener *listener, void *data) {
     struct wlr_event_pointer_pinch_end *event = data;
-    wlr_pointer_gestures_v1_send_pinch_end(
-	wimp.pointer_gestures, wimp.seat, event->time_msec, event->cancelled
-    );
+    if (wimp.cursor_mode == CURSOR_PASSTHROUGH) {
+	wlr_pointer_gestures_v1_send_pinch_end(
+	    wimp.pointer_gestures, wimp.seat, event->time_msec, event->cancelled
+	);
+    }
 }
 
 
 static void on_pinch_update(struct wl_listener *listener, void *data) {
     struct wlr_event_pointer_pinch_update *event = data;
-    wlr_pointer_gestures_v1_send_pinch_update(
-	wimp.pointer_gestures, wimp.seat, event->time_msec,
-	event->dx, event->dy, event->scale, event->rotation
-    );
+    if (wimp.cursor_mode == CURSOR_MOD) {
+	if (wimp.on_pinch) {
+	    wimp.on_pinch(&event->scale);
+	}
+    } else {
+	wlr_pointer_gestures_v1_send_pinch_update(
+	    wimp.pointer_gestures, wimp.seat, event->time_msec,
+	    event->dx, event->dy, event->scale, event->rotation
+	);
+    }
 }
 
 
 static void on_pinch_begin(struct wl_listener *listener, void *data) {
     struct wlr_event_pointer_pinch_begin *event = data;
-    wlr_pointer_gestures_v1_send_pinch_begin(
-	wimp.pointer_gestures, wimp.seat, event->time_msec, event->fingers
-    );
-
+    if (wimp.cursor_mode == CURSOR_MOD) {
+	if (wimp.on_pinch_begin) {
+	    wimp.on_pinch_begin(NULL);
+	}
+    } else {
+	wlr_pointer_gestures_v1_send_pinch_begin(
+	    wimp.pointer_gestures, wimp.seat, event->time_msec, event->fingers
+	);
+    }
 }
 
 

src/config.c Modified

@@ -79,6 +79,7 @@
     { "drag1", DRAG1 },
     { "drag2", DRAG2 },
     { "drag3", DRAG3 },
+    { "pinch", PINCH },
 };
 
 
@@ -150,10 +151,8 @@
     { "next_desk", &next_desk, NULL },
     { "prev_desk", &prev_desk, NULL },
     { "pan_desk", &pan_desk, &motion_handler },
-    { "pan_desk_mouse", &pan_desk, NULL },
     { "reset_zoom", &reset_zoom, NULL },
     { "zoom", &zoom, &str_handler },
-    { "zoom_mouse", &zoom_mouse, NULL },
     { "set_mark", &set_mark, NULL },
     { "go_to_mark", &go_to_mark, NULL },
     { "toggle_fullscreen", &toggle_fullscreen, NULL },
@@ -162,21 +161,60 @@
     { "send_to_desk", &send_to_desk, &str_handler },
 };
 
-static const int num_actions = sizeof(action_map) / sizeof(action_map[0]);
+
+static struct {
+    const char *name;
+    const action action;
+    const action begin;
+} pinch_map[] = {
+    { "zoom", &zoom_pinch, &zoom_pinch_begin },
+};
+
+
+static struct {
+    const char *name;
+    const action action;
+} scroll_map[] = {
+    { "zoom", &zoom_scroll },
+    { "pan_desk", &pan_desk },
+};
 
 
 static bool assign_action(const char *name, char *data, struct binding *kb) {
     kb->action = NULL;
     kb->data = NULL;
-
-    for (int i = 0; i < num_actions; i++) {
-	if (strcmp(action_map[i].name, name) == 0) {
-	    kb->action = action_map[i].action;
-	    if (action_map[i].data_handler != NULL)
-		action_map[i].data_handler(kb, data);
-	    return true;
-	}
+    size_t i;
+
+    switch (kb->key) {
+	case PINCH:
+	    for (i = 0; i < sizeof(pinch_map) / sizeof(pinch_map[0]); i++) {
+		if (strcmp(pinch_map[i].name, name) == 0) {
+		    kb->action = pinch_map[i].action;
+		    kb->begin = pinch_map[i].begin;
+		    return true;
+		}
+	    }
+	    break;
+	case SCROLL:
+	    for (i = 0; i < sizeof(scroll_map) / sizeof(scroll_map[0]); i++) {
+		if (strcmp(scroll_map[i].name, name) == 0) {
+		    kb->action = scroll_map[i].action;
+		    return true;
+		}
+	    }
+	    break;
+	default:
+	    for (i = 0; i < sizeof(action_map) / sizeof(action_map[0]); i++) {
+		if (strcmp(action_map[i].name, name) == 0) {
+		    kb->action = action_map[i].action;
+		    if (action_map[i].data_handler != NULL) {
+			action_map[i].data_handler(kb, data);
+		    }
+		    return true;
+		}
+	    }
     }
+
     return false;
 }
 

src/action.h Modified

@@ -14,7 +14,9 @@
 void pan_desk(void *data);
 void reset_zoom(void *data);
 void zoom(void *data);
-void zoom_mouse(void *data);
+void zoom_scroll(void *data);
+void zoom_pinch(void *data);
+void zoom_pinch_begin(void *data);
 void set_mark(void *data);
 void actually_set_mark(const xkb_keysym_t sym);
 void go_to_mark(void *data);

src/action.c Modified

@@ -188,13 +188,28 @@
 }
 
 
-void zoom_mouse(void *data) {
+void zoom_scroll(void *data) {
     struct motion motion = *(struct motion*)data;
     double dz = - motion.dx - motion.dy;
     zoom(&dz);
 }
 
 
+static double zoom_pinch_initial;
+
+
+void zoom_pinch(void *data) {
+    double scale = *(double*)data;
+    double dz = 100 * scale * zoom_pinch_initial / wimp.current_desk->zoom - 100;
+    zoom(&dz);
+}
+
+
+void zoom_pinch_begin(void *data) {
+    zoom_pinch_initial = wimp.current_desk->zoom;
+}
+
+
 void set_mark(void *data) {
     struct mark *mark = calloc(1, sizeof(struct mark));
     struct desk *desk = wimp.current_desk;