diff options
| author | Drew DeVault <sir@cmpwn.com> | 2017-09-05 20:55:27 +0900 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-09-05 20:55:27 +0900 | 
| commit | c5a2014a2ff3e22086c0d911f3bf771c5d5fb112 (patch) | |
| tree | 905cc9e62ed24dbc2675097357ee44cf99eb550d | |
| parent | 6089967e070f382ca33854c8dd9560a9b6c4af6f (diff) | |
| parent | 6904ed8bd95b3c6c9454086db0f5734cfff66ff3 (diff) | |
| download | wlroots-c5a2014a2ff3e22086c0d911f3bf771c5d5fb112.tar.xz | |
Merge pull request #133 from acrisci/feature/wlr-cursor-layout-changes
wlr_cursor: automatically handle layout changes
| -rw-r--r-- | examples/pointer.c | 8 | ||||
| -rw-r--r-- | include/wlr/types/wlr_output_layout.h | 5 | ||||
| -rw-r--r-- | types/wlr_cursor.c | 52 | ||||
| -rw-r--r-- | types/wlr_output_layout.c | 10 | 
4 files changed, 70 insertions, 5 deletions
diff --git a/examples/pointer.c b/examples/pointer.c index fe0e2cee..1eb0f923 100644 --- a/examples/pointer.c +++ b/examples/pointer.c @@ -151,15 +151,15 @@ static void handle_output_add(struct output_state *ostate) {  	configure_devices(sample); -	// TODO move to wlr_cursor +	// TODO the cursor must be set depending on which surface it is displayed +	// over which should happen in the compositor.  	if (!wlr_output_set_cursor(wlr_output, image->buffer,  			image->width, image->width, image->height)) {  		wlr_log(L_DEBUG, "Failed to set hardware cursor");  		return;  	} -	if (!wlr_output_move_cursor(wlr_output, 0, 0)) { -		wlr_log(L_DEBUG, "Failed to move hardware cursor"); -	} + +	wlr_cursor_warp(sample->cursor, NULL, sample->cursor->x, sample->cursor->y);  }  static void handle_output_remove(struct output_state *ostate) { diff --git a/include/wlr/types/wlr_output_layout.h b/include/wlr/types/wlr_output_layout.h index 78127f19..9cccd53c 100644 --- a/include/wlr/types/wlr_output_layout.h +++ b/include/wlr/types/wlr_output_layout.h @@ -9,6 +9,11 @@ struct wlr_output_layout_state;  struct wlr_output_layout {  	struct wl_list outputs;  	struct wlr_output_layout_state *state; + +	struct { +		struct wl_signal change; +		struct wl_signal destroy; +	} events;  };  struct wlr_output_layout_output_state; diff --git a/types/wlr_cursor.c b/types/wlr_cursor.c index 476af619..8751e5c3 100644 --- a/types/wlr_cursor.c +++ b/types/wlr_cursor.c @@ -34,11 +34,15 @@ struct wlr_cursor_device {  };  struct wlr_cursor_state { +	struct wlr_cursor *cursor;  	struct wl_list devices;  	struct wlr_output_layout *layout;  	struct wlr_xcursor *xcursor;  	struct wlr_output *mapped_output;  	struct wlr_box *mapped_box; + +	struct wl_listener layout_change; +	struct wl_listener layout_destroy;  };  struct wlr_cursor *wlr_cursor_create() { @@ -55,6 +59,7 @@ struct wlr_cursor *wlr_cursor_create() {  		return NULL;  	} +	cur->state->cursor = cur;  	cur->state->mapped_output = NULL;  	wl_list_init(&cur->state->devices); @@ -83,7 +88,20 @@ struct wlr_cursor *wlr_cursor_create() {  	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) { +	wlr_cursor_detach_output_layout(cur); +  	struct wlr_cursor_device *device, *device_tmp = NULL;  	wl_list_for_each_safe(device, device_tmp, &cur->state->devices, 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,  		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;  } diff --git a/types/wlr_output_layout.c b/types/wlr_output_layout.c index b189bd46..97fc8a68 100644 --- a/types/wlr_output_layout.c +++ b/types/wlr_output_layout.c @@ -28,6 +28,10 @@ struct wlr_output_layout *wlr_output_layout_init() {  	layout->state = calloc(1, sizeof(struct wlr_output_layout_state));  	layout->state->_box = calloc(1, sizeof(struct wlr_box));  	wl_list_init(&layout->outputs); + +	wl_signal_init(&layout->events.change); +	wl_signal_init(&layout->events.destroy); +  	return layout;  } @@ -46,6 +50,8 @@ void wlr_output_layout_destroy(struct wlr_output_layout *layout) {  		return;  	} +	wl_signal_emit(&layout->events.destroy, layout); +  	struct wlr_output_layout_output *_output, *temp = NULL;  	wl_list_for_each_safe(_output, temp, &layout->outputs, link) {  		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 - * configured outputs. + * configured outputs and emit the `changed` event.   *   * Auto configured outputs are placed to the right of the north east corner of   * 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;  		max_x += box->width;  	} + +	wl_signal_emit(&layout->events.change, layout);  }  static void handle_output_resolution(struct wl_listener *listener, void *data) {  | 
