From 6a7560fae05147ac5a1ac0dd3474670f1bd6c871 Mon Sep 17 00:00:00 2001
From: Tony Crisci <tony@dubstepdish.com>
Date: Wed, 11 Oct 2017 15:48:40 -0400
Subject: wlr-data-device interface

---
 include/rootston/server.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'include/rootston')

diff --git a/include/rootston/server.h b/include/rootston/server.h
index a4eacb7f..8fc6530e 100644
--- a/include/rootston/server.h
+++ b/include/rootston/server.h
@@ -3,7 +3,7 @@
 #include <wayland-server.h>
 #include <wlr/backend.h>
 #include <wlr/backend/session.h>
-#include <wlr/types/wlr_data_device_manager.h>
+#include <wlr/types/wlr_data_device.h>
 #include <wlr/render.h>
 #ifdef HAS_XWAYLAND
 #include <wlr/xwayland.h>
-- 
cgit v1.2.3


From df0a8d3abe6a7a8cd010e07f078c0e92ea2fb516 Mon Sep 17 00:00:00 2001
From: Tony Crisci <tony@dubstepdish.com>
Date: Sun, 15 Oct 2017 11:06:03 -0400
Subject: wlr-data-device: drag icons

---
 include/rootston/input.h            | 11 +++++++++
 include/wlr/types/wlr_data_device.h |  3 +++
 rootston/cursor.c                   | 49 +++++++++++++++++++++++++++++++++++++
 rootston/input.c                    |  2 ++
 rootston/main.c                     |  4 +--
 rootston/output.c                   | 15 ++++++++++++
 types/wlr_data_device.c             |  8 +++---
 types/wlr_surface.c                 |  2 ++
 8 files changed, 89 insertions(+), 5 deletions(-)

(limited to 'include/rootston')

diff --git a/include/rootston/input.h b/include/rootston/input.h
index fbabbdb6..8b4fc3b3 100644
--- a/include/rootston/input.h
+++ b/include/rootston/input.h
@@ -70,6 +70,15 @@ struct roots_input_event {
 	struct wlr_input_device *device;
 };
 
+struct roots_drag_icon {
+	struct wlr_surface *surface;
+	struct wl_list link; // roots_input::drag_icons
+	bool mapped;
+
+	struct wl_listener surface_destroy;
+	struct wl_listener surface_commit;
+};
+
 struct roots_input {
 	struct roots_config *config;
 	struct roots_server *server;
@@ -80,6 +89,7 @@ struct roots_input {
 	struct wlr_xcursor *xcursor;
 	struct wlr_seat *wl_seat;
 	struct roots_view *client_cursor_view;
+	struct wl_list drag_icons;
 
 	enum roots_cursor_mode mode;
 	struct roots_view *active_view, *last_active_view;
@@ -107,6 +117,7 @@ struct roots_input {
 	struct wl_listener cursor_tool_axis;
 	struct wl_listener cursor_tool_tip;
 
+	struct wl_listener pointer_grab_begin;
 	struct wl_listener pointer_grab_end;
 
 	struct wl_listener request_set_cursor;
diff --git a/include/wlr/types/wlr_data_device.h b/include/wlr/types/wlr_data_device.h
index cb867741..6c5dc097 100644
--- a/include/wlr/types/wlr_data_device.h
+++ b/include/wlr/types/wlr_data_device.h
@@ -4,6 +4,9 @@
 #include <wayland-server.h>
 #include <wlr/types/wlr_seat.h>
 
+extern const struct
+wlr_pointer_grab_interface wlr_data_device_pointer_drag_interface;
+
 struct wlr_data_device_manager {
 	struct wl_global *global;
 };
diff --git a/rootston/cursor.c b/rootston/cursor.c
index 8790934c..19f015aa 100644
--- a/rootston/cursor.c
+++ b/rootston/cursor.c
@@ -1,8 +1,10 @@
 #define _XOPEN_SOURCE 700
+#include <stdlib.h>
 #include <stdbool.h>
 #include <stdint.h>
 #include <string.h>
 #include <math.h>
+#include <assert.h>
 #ifdef __linux__
 #include <linux/input-event-codes.h>
 #elif __FreeBSD__
@@ -11,6 +13,7 @@
 #include <wayland-server.h>
 #include <wlr/types/wlr_cursor.h>
 #include <wlr/util/log.h>
+#include <wlr/types/wlr_data_device.h>
 #include "rootston/config.h"
 #include "rootston/input.h"
 #include "rootston/desktop.h"
@@ -289,6 +292,49 @@ static void handle_tool_tip(struct wl_listener *listener, void *data) {
 			(uint32_t)(event->time_usec / 1000), BTN_LEFT, event->state);
 }
 
+static void handle_drag_icon_destroy(struct wl_listener *listener, void *data) {
+	struct roots_drag_icon *drag_icon =
+		wl_container_of(listener, drag_icon, surface_destroy);
+	wl_list_remove(&drag_icon->link);
+	wl_list_remove(&drag_icon->surface_destroy.link);
+	wl_list_remove(&drag_icon->surface_commit.link);
+	free(drag_icon);
+}
+
+static void handle_drag_icon_commit(struct wl_listener *listener, void *data) {
+	struct roots_drag_icon *drag_icon =
+		wl_container_of(listener, drag_icon, surface_commit);
+	// TODO the spec hints at rules that can determine whether the drag icon is
+	// mapped here, but it is not completely clear so we need to test more
+	// toolkits to see how we should interpret the surface state here.
+	drag_icon->mapped = drag_icon->surface->texture->valid;
+}
+
+static void handle_pointer_grab_begin(struct wl_listener *listener,
+		void *data) {
+	struct roots_input *input =
+		wl_container_of(listener, input, pointer_grab_begin);
+	struct wlr_seat_pointer_grab *grab = data;
+
+	if (grab->interface == &wlr_data_device_pointer_drag_interface) {
+		struct wlr_drag *drag = grab->data;
+		if (drag->icon) {
+			struct roots_drag_icon *drag_icon =
+				calloc(1, sizeof(struct roots_drag_icon));
+			drag_icon->surface = drag->icon;
+			wl_list_insert(&input->drag_icons, &drag_icon->link);
+
+			wl_signal_add(&drag->icon->events.destroy,
+				&drag_icon->surface_destroy);
+			drag_icon->surface_destroy.notify = handle_drag_icon_destroy;
+
+			wl_signal_add(&drag->icon->events.commit,
+				&drag_icon->surface_commit);
+			drag_icon->surface_commit.notify = handle_drag_icon_commit;
+		}
+	}
+}
+
 static void handle_pointer_grab_end(struct wl_listener *listener, void *data) {
 	struct roots_input *input =
 		wl_container_of(listener, input, pointer_grab_end);
@@ -358,6 +404,9 @@ void cursor_initialize(struct roots_input *input) {
 	wl_signal_add(&input->wl_seat->events.pointer_grab_end, &input->pointer_grab_end);
 	input->pointer_grab_end.notify = handle_pointer_grab_end;
 
+	wl_signal_add(&input->wl_seat->events.pointer_grab_begin, &input->pointer_grab_begin);
+	input->pointer_grab_begin.notify = handle_pointer_grab_begin;
+
 	wl_list_init(&input->request_set_cursor.link);
 	wl_signal_add(&input->wl_seat->events.request_set_cursor,
 		&input->request_set_cursor);
diff --git a/rootston/input.c b/rootston/input.c
index 86a87e24..f08b735a 100644
--- a/rootston/input.c
+++ b/rootston/input.c
@@ -110,6 +110,8 @@ struct roots_input *input_create(struct roots_server *server,
 	cursor_load_config(config, input->cursor,
 		input, server->desktop);
 
+	wl_list_init(&input->drag_icons);
+
 	return input;
 }
 
diff --git a/rootston/main.c b/rootston/main.c
index 81343dfc..f262a30f 100644
--- a/rootston/main.c
+++ b/rootston/main.c
@@ -19,11 +19,11 @@ int main(int argc, char **argv) {
 	assert(server.backend = wlr_backend_autocreate(server.wl_display));
 
 	assert(server.renderer = wlr_gles2_renderer_create(server.backend));
+	server.data_device_manager =
+		wlr_data_device_manager_create(server.wl_display);
 	wl_display_init_shm(server.wl_display);
 	server.desktop = desktop_create(&server, server.config);
 	server.input = input_create(&server, server.config);
-	server.data_device_manager =
-		wlr_data_device_manager_create(server.wl_display);
 
 	const char *socket = wl_display_add_socket_auto(server.wl_display);
 	if (!socket) {
diff --git a/rootston/output.c b/rootston/output.c
index 39a90fe3..b431cbc3 100644
--- a/rootston/output.c
+++ b/rootston/output.c
@@ -150,6 +150,21 @@ static void output_frame_notify(struct wl_listener *listener, void *data) {
 		render_view(view, desktop, wlr_output, &now);
 	}
 
+	struct roots_drag_icon *drag_icon = NULL;
+	wl_list_for_each(drag_icon, &server->input->drag_icons, link) {
+		if (!drag_icon->mapped) {
+			continue;
+		}
+
+		struct wlr_surface *icon = drag_icon->surface;
+		struct wlr_cursor *cursor = server->input->cursor;
+		// TODO should also use the hotspot to determine the location, but
+		// hotspot is broken right now.
+		double icon_x = cursor->x - icon->current->sx;
+		double icon_y = cursor->y - icon->current->sy;
+		render_surface(icon, desktop, wlr_output, &now, icon_x, icon_y, 0);
+	}
+
 	wlr_renderer_end(server->renderer);
 	wlr_output_swap_buffers(wlr_output);
 
diff --git a/types/wlr_data_device.c b/types/wlr_data_device.c
index e9c0aa10..5c6d5717 100644
--- a/types/wlr_data_device.c
+++ b/types/wlr_data_device.c
@@ -495,7 +495,8 @@ static void pointer_drag_cancel(struct wlr_seat_pointer_grab *grab) {
 	wlr_drag_end(drag);
 }
 
-static const struct wlr_pointer_grab_interface pointer_drag_interface = {
+const struct
+wlr_pointer_grab_interface wlr_data_device_pointer_drag_interface = {
 	.enter = pointer_drag_enter,
 	.motion = pointer_drag_motion,
 	.button = pointer_drag_button,
@@ -521,7 +522,8 @@ static bool seat_handle_start_drag(struct wlr_seat_handle *handle,
 		return false;
 	}
 
-	if (drag->icon) {
+	if (icon) {
+		drag->icon = icon;
 		drag->icon_destroy.notify = drag_handle_icon_destroy;
 		wl_signal_add(&icon->events.destroy, &drag->icon_destroy);
 		drag->icon = icon;
@@ -535,7 +537,7 @@ static bool seat_handle_start_drag(struct wlr_seat_handle *handle,
 
 	drag->handle = handle;
 	drag->pointer_grab.data = drag;
-	drag->pointer_grab.interface = &pointer_drag_interface;
+	drag->pointer_grab.interface = &wlr_data_device_pointer_drag_interface;
 
 	wlr_seat_pointer_clear_focus(handle->wlr_seat);
 
diff --git a/types/wlr_surface.c b/types/wlr_surface.c
index 9e38d701..6e56d6aa 100644
--- a/types/wlr_surface.c
+++ b/types/wlr_surface.c
@@ -269,6 +269,8 @@ static void wlr_surface_move_state(struct wlr_surface *surface, struct wlr_surfa
 		wlr_surface_state_release_buffer(state);
 		wlr_surface_state_set_buffer(state, next->buffer);
 		wlr_surface_state_reset_buffer(next);
+		state->sx = next->sx;
+		state->sy = next->sy;
 		update_size = true;
 	}
 	if (update_size) {
-- 
cgit v1.2.3


From c00a94ca76cfc81353b78174e88539f17e9db7e0 Mon Sep 17 00:00:00 2001
From: Tony Crisci <tony@dubstepdish.com>
Date: Tue, 17 Oct 2017 17:21:11 -0400
Subject: data-device: fix drag icon position

---
 include/rootston/input.h | 3 +++
 rootston/cursor.c        | 3 +++
 rootston/output.c        | 6 ++----
 3 files changed, 8 insertions(+), 4 deletions(-)

(limited to 'include/rootston')

diff --git a/include/rootston/input.h b/include/rootston/input.h
index 40aea80a..357991ee 100644
--- a/include/rootston/input.h
+++ b/include/rootston/input.h
@@ -75,6 +75,9 @@ struct roots_drag_icon {
 	struct wl_list link; // roots_input::drag_icons
 	bool mapped;
 
+	int32_t sx;
+	int32_t sy;
+
 	struct wl_listener surface_destroy;
 	struct wl_listener surface_commit;
 };
diff --git a/rootston/cursor.c b/rootston/cursor.c
index bd988a41..6b509640 100644
--- a/rootston/cursor.c
+++ b/rootston/cursor.c
@@ -313,6 +313,9 @@ static void handle_drag_icon_commit(struct wl_listener *listener, void *data) {
 	// TODO the spec hints at rules that can determine whether the drag icon is
 	// mapped here, but it is not completely clear so we need to test more
 	// toolkits to see how we should interpret the surface state here.
+	drag_icon->sx += drag_icon->surface->current->sx;
+	drag_icon->sy += drag_icon->surface->current->sy;
+
 	drag_icon->mapped = drag_icon->surface->texture->valid;
 }
 
diff --git a/rootston/output.c b/rootston/output.c
index b431cbc3..f50306a3 100644
--- a/rootston/output.c
+++ b/rootston/output.c
@@ -158,10 +158,8 @@ static void output_frame_notify(struct wl_listener *listener, void *data) {
 
 		struct wlr_surface *icon = drag_icon->surface;
 		struct wlr_cursor *cursor = server->input->cursor;
-		// TODO should also use the hotspot to determine the location, but
-		// hotspot is broken right now.
-		double icon_x = cursor->x - icon->current->sx;
-		double icon_y = cursor->y - icon->current->sy;
+		double icon_x = cursor->x + drag_icon->sx;
+		double icon_y = cursor->y + drag_icon->sy;
 		render_surface(icon, desktop, wlr_output, &now, icon_x, icon_y, 0);
 	}
 
-- 
cgit v1.2.3


From 6fcac087fe1d7b7fa3cd0628a6b7818d26222678 Mon Sep 17 00:00:00 2001
From: Tony Crisci <tony@dubstepdish.com>
Date: Sat, 21 Oct 2017 09:59:35 -0400
Subject: rootston: remove mostly unused mapped icon param

---
 include/rootston/input.h | 1 -
 rootston/cursor.c        | 2 --
 rootston/output.c        | 4 ----
 3 files changed, 7 deletions(-)

(limited to 'include/rootston')

diff --git a/include/rootston/input.h b/include/rootston/input.h
index aacb3016..33750d7b 100644
--- a/include/rootston/input.h
+++ b/include/rootston/input.h
@@ -67,7 +67,6 @@ struct roots_input_event {
 struct roots_drag_icon {
 	struct wlr_surface *surface;
 	struct wl_list link; // roots_input::drag_icons
-	bool mapped;
 
 	int32_t sx;
 	int32_t sy;
diff --git a/rootston/cursor.c b/rootston/cursor.c
index 83581101..200a6d37 100644
--- a/rootston/cursor.c
+++ b/rootston/cursor.c
@@ -374,8 +374,6 @@ static void handle_drag_icon_commit(struct wl_listener *listener, void *data) {
 	// toolkits to see how we should interpret the surface state here.
 	drag_icon->sx += drag_icon->surface->current->sx;
 	drag_icon->sy += drag_icon->surface->current->sy;
-
-	drag_icon->mapped = drag_icon->surface->texture->valid;
 }
 
 static void handle_pointer_grab_begin(struct wl_listener *listener,
diff --git a/rootston/output.c b/rootston/output.c
index fce14fea..f560061d 100644
--- a/rootston/output.c
+++ b/rootston/output.c
@@ -152,10 +152,6 @@ static void output_frame_notify(struct wl_listener *listener, void *data) {
 
 	struct roots_drag_icon *drag_icon = NULL;
 	wl_list_for_each(drag_icon, &server->input->drag_icons, link) {
-		if (!drag_icon->mapped) {
-			continue;
-		}
-
 		struct wlr_surface *icon = drag_icon->surface;
 		struct wlr_cursor *cursor = server->input->cursor;
 		double icon_x = cursor->x + drag_icon->sx;
-- 
cgit v1.2.3