|  |  | @ -10,6 +10,7 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  | #include <dev/evdev/input-event-codes.h> |  |  |  | #include <dev/evdev/input-event-codes.h> | 
			
		
	
		
		
			
				
					
					|  |  |  | #endif |  |  |  | #endif | 
			
		
	
		
		
			
				
					
					|  |  |  | #include "rootston/cursor.h" |  |  |  | #include "rootston/cursor.h" | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | #include "rootston/desktop.h" | 
			
		
	
		
		
			
				
					
					|  |  |  | #include "rootston/xcursor.h" |  |  |  | #include "rootston/xcursor.h" | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | struct roots_cursor *roots_cursor_create(struct roots_seat *seat) { |  |  |  | struct roots_cursor *roots_cursor_create(struct roots_seat *seat) { | 
			
		
	
	
		
		
			
				
					|  |  | @ -98,51 +99,56 @@ static void seat_view_deco_button(struct roots_seat_view *view, double sx, | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | static void roots_cursor_update_position(struct roots_cursor *cursor, |  |  |  | static void roots_passthrough_cursor(struct roots_cursor *cursor, | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 		uint32_t time) { |  |  |  | 		uint32_t time) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct roots_desktop *desktop = cursor->seat->input->server->desktop; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct roots_seat *seat = cursor->seat; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct roots_view *view; |  |  |  | 	struct roots_view *view; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct wlr_surface *surface = NULL; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	double sx, sy; |  |  |  | 	double sx, sy; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	switch (cursor->mode) { |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	case ROOTS_CURSOR_PASSTHROUGH: |  |  |  | 	struct roots_seat *seat = cursor->seat; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		view = desktop_view_at(desktop, cursor->cursor->x, cursor->cursor->y, |  |  |  | 	struct roots_desktop *desktop = seat->input->server->desktop; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			&surface, &sx, &sy); |  |  |  | 	struct wlr_surface *surface = desktop_surface_at(desktop, | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			cursor->cursor->x, cursor->cursor->y, &sx, &sy, &view); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (!surface && cursor->cursor_client) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			cursor->default_xcursor, cursor->cursor); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		cursor->cursor_client = NULL; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (view) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		struct roots_seat_view *seat_view = |  |  |  | 		struct roots_seat_view *seat_view = | 
			
		
	
		
		
			
				
					
					|  |  |  | 			roots_seat_view_from_view(seat, view); |  |  |  | 			roots_seat_view_from_view(seat, view); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		if (cursor->pointer_view && (surface || seat_view != cursor->pointer_view)) { |  |  |  | 		if (cursor->pointer_view && (surface || | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 					seat_view != cursor->pointer_view)) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 			seat_view_deco_leave(cursor->pointer_view); |  |  |  | 			seat_view_deco_leave(cursor->pointer_view); | 
			
		
	
		
		
			
				
					
					|  |  |  | 			cursor->pointer_view = NULL; |  |  |  | 			cursor->pointer_view = NULL; | 
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  | 		} | 
			
		
	
		
		
			
				
					
					|  |  |  | 		bool set_compositor_cursor = !view && !surface && cursor->cursor_client; |  |  |  | 		if (!surface) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		if (view && surface) { |  |  |  | 			cursor->pointer_view = seat_view; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			struct wl_client *view_client = |  |  |  | 			seat_view_deco_motion(seat_view, sx, sy); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 				wl_resource_get_client(view->wlr_surface->resource); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 			set_compositor_cursor = view_client != cursor->cursor_client; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		if (set_compositor_cursor) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 			wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 				cursor->default_xcursor, cursor->cursor); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 			cursor->cursor_client = NULL; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		if (view && !surface) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 			if (seat_view) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 				cursor->pointer_view = seat_view; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 				seat_view_deco_motion(seat_view, sx, sy); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 			} |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		} if (view && surface) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 			// motion over a view surface
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 			wlr_seat_pointer_notify_enter(seat->seat, surface, sx, sy); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 			wlr_seat_pointer_notify_motion(seat->seat, time, sx, sy); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		} else { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 			wlr_seat_pointer_clear_focus(seat->seat); |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  | 		} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 		struct roots_drag_icon *drag_icon; |  |  |  | 	if (surface) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		wl_list_for_each(drag_icon, &seat->drag_icons, link) { |  |  |  | 		wlr_seat_pointer_notify_enter(seat->seat, surface, sx, sy); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			roots_drag_icon_update_position(drag_icon); |  |  |  | 		wlr_seat_pointer_notify_motion(seat->seat, time, sx, sy); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  | 	} else { | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		wlr_seat_pointer_clear_focus(seat->seat); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	struct roots_drag_icon *drag_icon; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	wl_list_for_each(drag_icon, &seat->drag_icons, link) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		roots_drag_icon_update_position(drag_icon); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | static void roots_cursor_update_position( | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		struct roots_cursor *cursor, uint32_t time) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	struct roots_seat *seat = cursor->seat; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	struct roots_view *view; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	switch (cursor->mode) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	case ROOTS_CURSOR_PASSTHROUGH: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		roots_passthrough_cursor(cursor, time); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		break; |  |  |  | 		break; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	case ROOTS_CURSOR_MOVE: |  |  |  | 	case ROOTS_CURSOR_MOVE: | 
			
		
	
		
		
			
				
					
					|  |  |  | 		view = roots_seat_get_focus(seat); |  |  |  | 		view = roots_seat_get_focus(seat); | 
			
		
	
	
		
		
			
				
					|  |  | @ -180,15 +186,9 @@ static void roots_cursor_update_position(struct roots_cursor *cursor, | 
			
		
	
		
		
			
				
					
					|  |  |  | 			} else if (cursor->resize_edges & WLR_EDGE_RIGHT) { |  |  |  | 			} else if (cursor->resize_edges & WLR_EDGE_RIGHT) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 				width += dx; |  |  |  | 				width += dx; | 
			
		
	
		
		
			
				
					
					|  |  |  | 			} |  |  |  | 			} | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 			view_move_resize(view, x, y, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			if (width < 1) { |  |  |  | 					width < 1 ? 1 : width, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 				width = 1; |  |  |  | 					height < 1 ? 1 : height); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			} |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 			if (height < 1) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 				height = 1; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 			} |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 			view_move_resize(view, x, y, width, height); |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  | 		} | 
			
		
	
		
		
			
				
					
					|  |  |  | 		break; |  |  |  | 		break; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	case ROOTS_CURSOR_ROTATE: |  |  |  | 	case ROOTS_CURSOR_ROTATE: | 
			
		
	
	
		
		
			
				
					|  |  | @ -214,15 +214,15 @@ static void roots_cursor_press_button(struct roots_cursor *cursor, | 
			
		
	
		
		
			
				
					
					|  |  |  | 		uint32_t state, double lx, double ly) { |  |  |  | 		uint32_t state, double lx, double ly) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct roots_seat *seat = cursor->seat; |  |  |  | 	struct roots_seat *seat = cursor->seat; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct roots_desktop *desktop = seat->input->server->desktop; |  |  |  | 	struct roots_desktop *desktop = seat->input->server->desktop; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	bool is_touch = device->type == WLR_INPUT_DEVICE_TOUCH; |  |  |  | 	bool is_touch = device->type == WLR_INPUT_DEVICE_TOUCH; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct wlr_surface *surface = NULL; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	double sx, sy; |  |  |  | 	double sx, sy; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct roots_view *view = |  |  |  | 	struct roots_view *view; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		desktop_view_at(desktop, lx, ly, &surface, &sx, &sy); |  |  |  | 	struct wlr_surface *surface = desktop_surface_at(desktop, | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			lx, ly, &sx, &sy, &view); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (state == WLR_BUTTON_PRESSED && |  |  |  | 	if (state == WLR_BUTTON_PRESSED && view && | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			view && |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 			roots_seat_has_meta_pressed(seat)) { |  |  |  | 			roots_seat_has_meta_pressed(seat)) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		roots_seat_set_focus(seat, view); |  |  |  | 		roots_seat_set_focus(seat, view); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -250,11 +250,9 @@ static void roots_cursor_press_button(struct roots_cursor *cursor, | 
			
		
	
		
		
			
				
					
					|  |  |  | 			break; |  |  |  | 			break; | 
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  | 		} | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} else { |  |  |  | 	} else { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 		if (view && !surface && cursor->pointer_view) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		if (view && !surface) { |  |  |  | 			seat_view_deco_button(cursor->pointer_view, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			if (cursor->pointer_view) { |  |  |  | 					sx, sy, button, state); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 				seat_view_deco_button(cursor->pointer_view, sx, sy, button, state); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 			} |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  | 		} | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 		if (state == WLR_BUTTON_RELEASED && |  |  |  | 		if (state == WLR_BUTTON_RELEASED && | 
			
		
	
	
		
		
			
				
					|  |  | @ -308,7 +306,6 @@ void roots_cursor_handle_axis(struct roots_cursor *cursor, | 
			
		
	
		
		
			
				
					
					|  |  |  | void roots_cursor_handle_touch_down(struct roots_cursor *cursor, |  |  |  | void roots_cursor_handle_touch_down(struct roots_cursor *cursor, | 
			
		
	
		
		
			
				
					
					|  |  |  | 		struct wlr_event_touch_down *event) { |  |  |  | 		struct wlr_event_touch_down *event) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct roots_desktop *desktop = cursor->seat->input->server->desktop; |  |  |  | 	struct roots_desktop *desktop = cursor->seat->input->server->desktop; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct wlr_surface *surface = NULL; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	double lx, ly; |  |  |  | 	double lx, ly; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	bool result = wlr_cursor_absolute_to_layout_coords(cursor->cursor, |  |  |  | 	bool result = wlr_cursor_absolute_to_layout_coords(cursor->cursor, | 
			
		
	
		
		
			
				
					
					|  |  |  | 			event->device, event->x, event->y, &lx, &ly); |  |  |  | 			event->device, event->x, event->y, &lx, &ly); | 
			
		
	
	
		
		
			
				
					|  |  | @ -316,7 +313,8 @@ void roots_cursor_handle_touch_down(struct roots_cursor *cursor, | 
			
		
	
		
		
			
				
					
					|  |  |  | 		return; |  |  |  | 		return; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  | 	double sx, sy; |  |  |  | 	double sx, sy; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	desktop_view_at(desktop, lx, ly, &surface, &sx, &sy); |  |  |  | 	struct wlr_surface *surface = desktop_surface_at( | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			desktop, lx, ly, &sx, &sy, NULL); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	uint32_t serial = 0; |  |  |  | 	uint32_t serial = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (surface) { |  |  |  | 	if (surface) { | 
			
		
	
	
		
		
			
				
					|  |  | @ -359,17 +357,16 @@ void roots_cursor_handle_touch_motion(struct roots_cursor *cursor, | 
			
		
	
		
		
			
				
					
					|  |  |  | 		return; |  |  |  | 		return; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct wlr_surface *surface = NULL; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	double lx, ly; |  |  |  | 	double lx, ly; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	bool result = |  |  |  | 	bool result = wlr_cursor_absolute_to_layout_coords(cursor->cursor, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		wlr_cursor_absolute_to_layout_coords(cursor->cursor, |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 			event->device, event->x, event->y, &lx, &ly); |  |  |  | 			event->device, event->x, event->y, &lx, &ly); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (!result) { |  |  |  | 	if (!result) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		return; |  |  |  | 		return; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	double sx, sy; |  |  |  | 	double sx, sy; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	desktop_view_at(desktop, lx, ly, &surface, &sx, &sy); |  |  |  | 	struct wlr_surface *surface = desktop_surface_at( | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			desktop, lx, ly, &sx, &sy, NULL); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (surface) { |  |  |  | 	if (surface) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		wlr_seat_touch_point_focus(cursor->seat->seat, surface, |  |  |  | 		wlr_seat_touch_point_focus(cursor->seat->seat, surface, | 
			
		
	
	
		
		
			
				
					|  |  | 
 |