mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	Implement xdg request_move in reference compositor
This commit is contained in:
		
							parent
							
								
									8cb49f4d68
								
							
						
					
					
						commit
						7ae5268679
					
				
					 1 changed files with 89 additions and 24 deletions
				
			
		| 
						 | 
					@ -35,6 +35,37 @@
 | 
				
			||||||
// TODO: move to common header?
 | 
					// TODO: move to common header?
 | 
				
			||||||
int os_create_anonymous_file(off_t size);
 | 
					int os_create_anonymous_file(off_t size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct sample_state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct example_xdg_surface_v6 {
 | 
				
			||||||
 | 
						struct wlr_xdg_surface_v6 *surface;
 | 
				
			||||||
 | 
						struct sample_state *sample;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// position of the wlr_surface in the layout
 | 
				
			||||||
 | 
						struct {
 | 
				
			||||||
 | 
							int lx;
 | 
				
			||||||
 | 
							int ly;
 | 
				
			||||||
 | 
						} position;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wl_listener destroy_listener;
 | 
				
			||||||
 | 
						struct wl_listener ping_timeout_listener;
 | 
				
			||||||
 | 
						struct wl_listener request_minimize_listener;
 | 
				
			||||||
 | 
						struct wl_listener request_move_listener;
 | 
				
			||||||
 | 
						struct wl_listener request_resize_listener;
 | 
				
			||||||
 | 
						struct wl_listener request_show_window_menu_listener;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct input_event_cache {
 | 
				
			||||||
 | 
						uint32_t serial;
 | 
				
			||||||
 | 
						struct wlr_cursor *cursor;
 | 
				
			||||||
 | 
						struct wlr_input_device *device;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct motion_context {
 | 
				
			||||||
 | 
						struct example_xdg_surface_v6 *surface;
 | 
				
			||||||
 | 
						int off_x, off_y;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct sample_state {
 | 
					struct sample_state {
 | 
				
			||||||
	struct wlr_renderer *renderer;
 | 
						struct wlr_renderer *renderer;
 | 
				
			||||||
	struct compositor_state *compositor;
 | 
						struct compositor_state *compositor;
 | 
				
			||||||
| 
						 | 
					@ -51,11 +82,17 @@ struct sample_state {
 | 
				
			||||||
	size_t keymap_size;
 | 
						size_t keymap_size;
 | 
				
			||||||
	uint32_t serial;
 | 
						uint32_t serial;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct motion_context motion_context;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct example_config *config;
 | 
						struct example_config *config;
 | 
				
			||||||
	struct wlr_output_layout *layout;
 | 
						struct wlr_output_layout *layout;
 | 
				
			||||||
	struct wlr_cursor *cursor;
 | 
						struct wlr_cursor *cursor;
 | 
				
			||||||
	struct wlr_xcursor *xcursor;
 | 
						struct wlr_xcursor *xcursor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Ring buffer
 | 
				
			||||||
 | 
						int input_cache_idx;
 | 
				
			||||||
 | 
						struct input_event_cache input_cache[16];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wl_listener cursor_motion;
 | 
						struct wl_listener cursor_motion;
 | 
				
			||||||
	struct wl_listener cursor_motion_absolute;
 | 
						struct wl_listener cursor_motion_absolute;
 | 
				
			||||||
	struct wl_listener cursor_button;
 | 
						struct wl_listener cursor_button;
 | 
				
			||||||
| 
						 | 
					@ -70,23 +107,6 @@ struct sample_state {
 | 
				
			||||||
	struct wlr_xdg_surface_v6 *focused_surface;
 | 
						struct wlr_xdg_surface_v6 *focused_surface;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct example_xdg_surface_v6 {
 | 
					 | 
				
			||||||
	struct wlr_xdg_surface_v6 *surface;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// position of the wlr_surface in the layout
 | 
					 | 
				
			||||||
	struct {
 | 
					 | 
				
			||||||
		int lx;
 | 
					 | 
				
			||||||
		int ly;
 | 
					 | 
				
			||||||
	} position;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct wl_listener destroy_listener;
 | 
					 | 
				
			||||||
	struct wl_listener ping_timeout_listener;
 | 
					 | 
				
			||||||
	struct wl_listener request_minimize_listener;
 | 
					 | 
				
			||||||
	struct wl_listener request_move_listener;
 | 
					 | 
				
			||||||
	struct wl_listener request_resize_listener;
 | 
					 | 
				
			||||||
	struct wl_listener request_show_window_menu_listener;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void example_set_focused_surface(struct sample_state *sample,
 | 
					static void example_set_focused_surface(struct sample_state *sample,
 | 
				
			||||||
		struct wlr_xdg_surface_v6 *surface) {
 | 
							struct wlr_xdg_surface_v6 *surface) {
 | 
				
			||||||
	if (sample->focused_surface == surface) {
 | 
						if (sample->focused_surface == surface) {
 | 
				
			||||||
| 
						 | 
					@ -159,10 +179,27 @@ static void handle_xdg_surface_v6_destroy(struct wl_listener *listener,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void handle_xdg_surface_v6_request_move(struct wl_listener *listener,
 | 
					static void handle_xdg_surface_v6_request_move(struct wl_listener *listener,
 | 
				
			||||||
		void *data) {
 | 
							void *data) {
 | 
				
			||||||
	struct example_xdg_surface_v6 *example_surface =
 | 
						struct example_xdg_surface_v6 *esurface =
 | 
				
			||||||
		wl_container_of(listener, example_surface, request_move_listener);
 | 
							wl_container_of(listener, esurface, request_move_listener);
 | 
				
			||||||
	struct wlr_xdg_toplevel_v6_move_event *e = data;
 | 
						struct wlr_xdg_toplevel_v6_move_event *e = data;
 | 
				
			||||||
	wlr_log(L_DEBUG, "TODO: surface requested move: %s", e->surface->title);
 | 
						struct sample_state *sample = esurface->sample;
 | 
				
			||||||
 | 
						struct input_event_cache *event;
 | 
				
			||||||
 | 
						for (size_t i = 0;
 | 
				
			||||||
 | 
								i < sizeof(sample->input_cache) / sizeof(sample->input_cache[0]);
 | 
				
			||||||
 | 
								++i) {
 | 
				
			||||||
 | 
							if (sample->input_cache[i].cursor
 | 
				
			||||||
 | 
									&& sample->input_cache[i].serial == e->serial) {
 | 
				
			||||||
 | 
								event = &sample->input_cache[i];
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (!event || sample->motion_context.surface) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						sample->motion_context.surface = esurface;
 | 
				
			||||||
 | 
						sample->motion_context.off_x = sample->cursor->x - esurface->position.lx;
 | 
				
			||||||
 | 
						sample->motion_context.off_y = sample->cursor->y - esurface->position.ly;
 | 
				
			||||||
 | 
						wlr_seat_pointer_clear_focus(sample->wl_seat);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void handle_xdg_surface_v6_request_resize(struct wl_listener *listener,
 | 
					static void handle_xdg_surface_v6_request_resize(struct wl_listener *listener,
 | 
				
			||||||
| 
						 | 
					@ -193,6 +230,8 @@ static void handle_xdg_surface_v6_request_minimize(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void handle_new_xdg_surface_v6(struct wl_listener *listener,
 | 
					static void handle_new_xdg_surface_v6(struct wl_listener *listener,
 | 
				
			||||||
		void *data) {
 | 
							void *data) {
 | 
				
			||||||
 | 
						struct sample_state *sample_state =
 | 
				
			||||||
 | 
							wl_container_of(listener, sample_state, new_xdg_surface_v6);
 | 
				
			||||||
	struct wlr_xdg_surface_v6 *surface = data;
 | 
						struct wlr_xdg_surface_v6 *surface = data;
 | 
				
			||||||
	wlr_log(L_DEBUG, "new xdg surface: title=%s, app_id=%s",
 | 
						wlr_log(L_DEBUG, "new xdg surface: title=%s, app_id=%s",
 | 
				
			||||||
		surface->title, surface->app_id);
 | 
							surface->title, surface->app_id);
 | 
				
			||||||
| 
						 | 
					@ -205,6 +244,7 @@ static void handle_new_xdg_surface_v6(struct wl_listener *listener,
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						esurface->sample = sample_state;
 | 
				
			||||||
	esurface->surface = surface;
 | 
						esurface->surface = surface;
 | 
				
			||||||
	// TODO sensible default position
 | 
						// TODO sensible default position
 | 
				
			||||||
	esurface->position.lx = 300;
 | 
						esurface->position.lx = 300;
 | 
				
			||||||
| 
						 | 
					@ -374,8 +414,16 @@ static struct wlr_xdg_surface_v6 *example_xdg_surface_at(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void update_pointer_position(struct sample_state *sample,
 | 
					static void update_pointer_position(struct sample_state *sample,
 | 
				
			||||||
		uint32_t time_sec) {
 | 
							uint32_t time_sec) {
 | 
				
			||||||
	struct wlr_xdg_surface_v6 *surface =
 | 
						if (sample->motion_context.surface) {
 | 
				
			||||||
		example_xdg_surface_at(sample, sample->cursor->x, sample->cursor->y);
 | 
							struct example_xdg_surface_v6 *surface;
 | 
				
			||||||
 | 
							surface = sample->motion_context.surface;
 | 
				
			||||||
 | 
							surface->position.lx = sample->cursor->x - sample->motion_context.off_x;
 | 
				
			||||||
 | 
							surface->position.ly = sample->cursor->y - sample->motion_context.off_y;
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wlr_xdg_surface_v6 *surface = example_xdg_surface_at(sample,
 | 
				
			||||||
 | 
								sample->cursor->x, sample->cursor->y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (surface) {
 | 
						if (surface) {
 | 
				
			||||||
		struct example_xdg_surface_v6 *esurface = surface->data;
 | 
							struct example_xdg_surface_v6 *esurface = surface->data;
 | 
				
			||||||
| 
						 | 
					@ -425,13 +473,30 @@ static void handle_cursor_axis(struct wl_listener *listener, void *data) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void handle_cursor_button(struct wl_listener *listener, void *data) {
 | 
					static void handle_cursor_button(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	struct sample_state *sample =
 | 
						struct sample_state *sample =
 | 
				
			||||||
	wl_container_of(listener, sample, cursor_button);
 | 
							wl_container_of(listener, sample, cursor_button);
 | 
				
			||||||
	struct wlr_event_pointer_button *event = data;
 | 
						struct wlr_event_pointer_button *event = data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_xdg_surface_v6 *surface =
 | 
						struct wlr_xdg_surface_v6 *surface =
 | 
				
			||||||
		example_xdg_surface_at(sample, sample->cursor->x, sample->cursor->y);
 | 
							example_xdg_surface_at(sample, sample->cursor->x, sample->cursor->y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	example_set_focused_surface(sample, surface);
 | 
						int i;
 | 
				
			||||||
 | 
						switch (event->state) {
 | 
				
			||||||
 | 
						case WLR_BUTTON_RELEASED:
 | 
				
			||||||
 | 
							if (sample->motion_context.surface) {
 | 
				
			||||||
 | 
								sample->motion_context.surface = NULL;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case WLR_BUTTON_PRESSED:
 | 
				
			||||||
 | 
							i = sample->input_cache_idx;
 | 
				
			||||||
 | 
							// TODO: serials should probably be based on time_usec
 | 
				
			||||||
 | 
							sample->input_cache[i].serial = event->time_sec;
 | 
				
			||||||
 | 
							sample->input_cache[i].cursor = sample->cursor;
 | 
				
			||||||
 | 
							sample->input_cache[i].device = event->device;
 | 
				
			||||||
 | 
							sample->input_cache_idx = (i + 1)
 | 
				
			||||||
 | 
								% (sizeof(sample->input_cache) / sizeof(sample->input_cache[0]));
 | 
				
			||||||
 | 
							example_set_focused_surface(sample, surface);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wlr_seat_pointer_send_button(sample->wl_seat, event->time_sec,
 | 
						wlr_seat_pointer_send_button(sample->wl_seat, event->time_sec,
 | 
				
			||||||
		event->button, event->state);
 | 
							event->button, event->state);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue