mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	wlr_cursor: handle layout changes
Add the layout `destroy` and `change` events. When a layout is destroyed, detach is from the wlr_cursor. When a layout is changed, warp the cursor to the closest layout boundary.
This commit is contained in:
		
							parent
							
								
									6089967e07
								
							
						
					
					
						commit
						57c18c38bb
					
				
					 3 changed files with 66 additions and 1 deletions
				
			
		| 
						 | 
					@ -9,6 +9,11 @@ struct wlr_output_layout_state;
 | 
				
			||||||
struct wlr_output_layout {
 | 
					struct wlr_output_layout {
 | 
				
			||||||
	struct wl_list outputs;
 | 
						struct wl_list outputs;
 | 
				
			||||||
	struct wlr_output_layout_state *state;
 | 
						struct wlr_output_layout_state *state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct {
 | 
				
			||||||
 | 
							struct wl_signal change;
 | 
				
			||||||
 | 
							struct wl_signal destroy;
 | 
				
			||||||
 | 
						} events;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wlr_output_layout_output_state;
 | 
					struct wlr_output_layout_output_state;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,11 +34,15 @@ struct wlr_cursor_device {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wlr_cursor_state {
 | 
					struct wlr_cursor_state {
 | 
				
			||||||
 | 
						struct wlr_cursor *cursor;
 | 
				
			||||||
	struct wl_list devices;
 | 
						struct wl_list devices;
 | 
				
			||||||
	struct wlr_output_layout *layout;
 | 
						struct wlr_output_layout *layout;
 | 
				
			||||||
	struct wlr_xcursor *xcursor;
 | 
						struct wlr_xcursor *xcursor;
 | 
				
			||||||
	struct wlr_output *mapped_output;
 | 
						struct wlr_output *mapped_output;
 | 
				
			||||||
	struct wlr_box *mapped_box;
 | 
						struct wlr_box *mapped_box;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wl_listener layout_change;
 | 
				
			||||||
 | 
						struct wl_listener layout_destroy;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wlr_cursor *wlr_cursor_create() {
 | 
					struct wlr_cursor *wlr_cursor_create() {
 | 
				
			||||||
| 
						 | 
					@ -55,6 +59,7 @@ struct wlr_cursor *wlr_cursor_create() {
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cur->state->cursor = cur;
 | 
				
			||||||
	cur->state->mapped_output = NULL;
 | 
						cur->state->mapped_output = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_list_init(&cur->state->devices);
 | 
						wl_list_init(&cur->state->devices);
 | 
				
			||||||
| 
						 | 
					@ -83,7 +88,20 @@ struct wlr_cursor *wlr_cursor_create() {
 | 
				
			||||||
	return cur;
 | 
						return cur;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void wlr_cursor_detach_output_layout(struct wlr_cursor *cur) {
 | 
				
			||||||
 | 
						if (!cur->state->layout) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_list_remove(&cur->state->layout_destroy.link);
 | 
				
			||||||
 | 
						wl_list_remove(&cur->state->layout_change.link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cur->state->layout = NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void wlr_cursor_destroy(struct wlr_cursor *cur) {
 | 
					void wlr_cursor_destroy(struct wlr_cursor *cur) {
 | 
				
			||||||
 | 
						wlr_cursor_detach_output_layout(cur);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_cursor_device *device, *device_tmp = NULL;
 | 
						struct wlr_cursor_device *device, *device_tmp = NULL;
 | 
				
			||||||
	wl_list_for_each_safe(device, device_tmp, &cur->state->devices, link) {
 | 
						wl_list_for_each_safe(device, device_tmp, &cur->state->devices, link) {
 | 
				
			||||||
		wl_list_remove(&device->link);
 | 
							wl_list_remove(&device->link);
 | 
				
			||||||
| 
						 | 
					@ -430,8 +448,42 @@ void wlr_cursor_detach_input_device(struct wlr_cursor *cur,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void handle_layout_destroy(struct wl_listener *listener, void *data) {
 | 
				
			||||||
 | 
						struct wlr_cursor_state *state =
 | 
				
			||||||
 | 
							wl_container_of(listener, state, layout_change);
 | 
				
			||||||
 | 
						wlr_cursor_detach_output_layout(state->cursor);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void handle_layout_change(struct wl_listener *listener, void *data) {
 | 
				
			||||||
 | 
						struct wlr_cursor_state *state =
 | 
				
			||||||
 | 
							wl_container_of(listener, state, layout_change);
 | 
				
			||||||
 | 
						struct wlr_output_layout *layout = data;
 | 
				
			||||||
 | 
						if (!wlr_output_layout_contains_point(layout, NULL, state->cursor->x,
 | 
				
			||||||
 | 
								state->cursor->y)) {
 | 
				
			||||||
 | 
							// the output we were on has gone away so go to the closest boundary
 | 
				
			||||||
 | 
							// point
 | 
				
			||||||
 | 
							double x, y;
 | 
				
			||||||
 | 
							wlr_output_layout_closest_point(layout, NULL, state->cursor->x,
 | 
				
			||||||
 | 
								state->cursor->y, &x, &y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							wlr_cursor_warp_unchecked(state->cursor, x, y);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void wlr_cursor_attach_output_layout(struct wlr_cursor *cur,
 | 
					void wlr_cursor_attach_output_layout(struct wlr_cursor *cur,
 | 
				
			||||||
		struct wlr_output_layout *l) {
 | 
							struct wlr_output_layout *l) {
 | 
				
			||||||
 | 
						wlr_cursor_detach_output_layout(cur);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (l == NULL) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_signal_add(&l->events.change, &cur->state->layout_change);
 | 
				
			||||||
 | 
						cur->state->layout_change.notify = handle_layout_change;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_signal_add(&l->events.destroy, &cur->state->layout_destroy);
 | 
				
			||||||
 | 
						cur->state->layout_destroy.notify = handle_layout_destroy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cur->state->layout = l;
 | 
						cur->state->layout = l;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,6 +28,10 @@ struct wlr_output_layout *wlr_output_layout_init() {
 | 
				
			||||||
	layout->state = calloc(1, sizeof(struct wlr_output_layout_state));
 | 
						layout->state = calloc(1, sizeof(struct wlr_output_layout_state));
 | 
				
			||||||
	layout->state->_box = calloc(1, sizeof(struct wlr_box));
 | 
						layout->state->_box = calloc(1, sizeof(struct wlr_box));
 | 
				
			||||||
	wl_list_init(&layout->outputs);
 | 
						wl_list_init(&layout->outputs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_signal_init(&layout->events.change);
 | 
				
			||||||
 | 
						wl_signal_init(&layout->events.destroy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return layout;
 | 
						return layout;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -46,6 +50,8 @@ void wlr_output_layout_destroy(struct wlr_output_layout *layout) {
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_signal_emit(&layout->events.destroy, layout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_output_layout_output *_output, *temp = NULL;
 | 
						struct wlr_output_layout_output *_output, *temp = NULL;
 | 
				
			||||||
	wl_list_for_each_safe(_output, temp, &layout->outputs, link) {
 | 
						wl_list_for_each_safe(_output, temp, &layout->outputs, link) {
 | 
				
			||||||
		wlr_output_layout_output_destroy(_output);
 | 
							wlr_output_layout_output_destroy(_output);
 | 
				
			||||||
| 
						 | 
					@ -69,7 +75,7 @@ static struct wlr_box *wlr_output_layout_output_get_box(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * This must be called whenever the layout changes to reconfigure the auto
 | 
					 * This must be called whenever the layout changes to reconfigure the auto
 | 
				
			||||||
 * configured outputs.
 | 
					 * configured outputs and emit the `changed` event.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Auto configured outputs are placed to the right of the north east corner of
 | 
					 * Auto configured outputs are placed to the right of the north east corner of
 | 
				
			||||||
 * the rightmost output in the layout in a horizontal line.
 | 
					 * the rightmost output in the layout in a horizontal line.
 | 
				
			||||||
| 
						 | 
					@ -108,6 +114,8 @@ static void wlr_output_layout_reconfigure(struct wlr_output_layout *layout) {
 | 
				
			||||||
		l_output->y = max_x_y;
 | 
							l_output->y = max_x_y;
 | 
				
			||||||
		max_x += box->width;
 | 
							max_x += box->width;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_signal_emit(&layout->events.change, layout);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void handle_output_resolution(struct wl_listener *listener, void *data) {
 | 
					static void handle_output_resolution(struct wl_listener *listener, void *data) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue