aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDrew DeVault <sir@cmpwn.com>2017-09-05 20:55:27 +0900
committerGitHub <noreply@github.com>2017-09-05 20:55:27 +0900
commitc5a2014a2ff3e22086c0d911f3bf771c5d5fb112 (patch)
tree905cc9e62ed24dbc2675097357ee44cf99eb550d
parent6089967e070f382ca33854c8dd9560a9b6c4af6f (diff)
parent6904ed8bd95b3c6c9454086db0f5734cfff66ff3 (diff)
Merge pull request #133 from acrisci/feature/wlr-cursor-layout-changes
wlr_cursor: automatically handle layout changes
-rw-r--r--examples/pointer.c8
-rw-r--r--include/wlr/types/wlr_output_layout.h5
-rw-r--r--types/wlr_cursor.c52
-rw-r--r--types/wlr_output_layout.c10
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) {