diff options
-rw-r--r-- | include/sway/container.h | 4 | ||||
-rw-r--r-- | include/sway/input/cursor.h | 3 | ||||
-rw-r--r-- | sway/desktop/output.c | 30 | ||||
-rw-r--r-- | sway/input/cursor.c | 42 | ||||
-rw-r--r-- | sway/tree/container.c | 60 |
5 files changed, 126 insertions, 13 deletions
diff --git a/include/sway/container.h b/include/sway/container.h index 08a98ed9..0e1cc8a3 100644 --- a/include/sway/container.h +++ b/include/sway/container.h | |||
@@ -3,6 +3,7 @@ | |||
3 | #include <stdint.h> | 3 | #include <stdint.h> |
4 | #include <sys/types.h> | 4 | #include <sys/types.h> |
5 | #include <wlr/types/wlr_box.h> | 5 | #include <wlr/types/wlr_box.h> |
6 | #include <wlr/types/wlr_surface.h> | ||
6 | #include "list.h" | 7 | #include "list.h" |
7 | 8 | ||
8 | typedef struct sway_container swayc_t; | 9 | typedef struct sway_container swayc_t; |
@@ -136,4 +137,7 @@ swayc_t *destroy_view(swayc_t *view); | |||
136 | 137 | ||
137 | swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types type); | 138 | swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types type); |
138 | 139 | ||
140 | swayc_t *swayc_at(swayc_t *parent, double lx, double ly, | ||
141 | struct wlr_surface **surface, double *sx, double *sy); | ||
142 | |||
139 | #endif | 143 | #endif |
diff --git a/include/sway/input/cursor.h b/include/sway/input/cursor.h index aa873f46..cc529de6 100644 --- a/include/sway/input/cursor.h +++ b/include/sway/input/cursor.h | |||
@@ -4,9 +4,12 @@ | |||
4 | #include "sway/input/seat.h" | 4 | #include "sway/input/seat.h" |
5 | 5 | ||
6 | struct sway_cursor { | 6 | struct sway_cursor { |
7 | struct sway_seat *seat; | ||
7 | struct wlr_cursor *cursor; | 8 | struct wlr_cursor *cursor; |
8 | struct wlr_xcursor_manager *xcursor_manager; | 9 | struct wlr_xcursor_manager *xcursor_manager; |
9 | 10 | ||
11 | double x, y; | ||
12 | |||
10 | struct wl_listener motion; | 13 | struct wl_listener motion; |
11 | struct wl_listener motion_absolute; | 14 | struct wl_listener motion_absolute; |
12 | struct wl_listener button; | 15 | struct wl_listener button; |
diff --git a/sway/desktop/output.c b/sway/desktop/output.c index d2003834..0e7f7060 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c | |||
@@ -25,8 +25,8 @@ static void output_frame_view(swayc_t *view, void *data) { | |||
25 | } | 25 | } |
26 | // TODO | 26 | // TODO |
27 | // - Deal with wlr_output_layout | 27 | // - Deal with wlr_output_layout |
28 | int width = sway_view->width; | 28 | int width = sway_view->surface->current->width; |
29 | int height = sway_view->height; | 29 | int height = sway_view->surface->current->height; |
30 | int render_width = width * wlr_output->scale; | 30 | int render_width = width * wlr_output->scale; |
31 | int render_height = height * wlr_output->scale; | 31 | int render_height = height * wlr_output->scale; |
32 | double ox = view->x, oy = view->y; | 32 | double ox = view->x, oy = view->y; |
@@ -40,19 +40,33 @@ static void output_frame_view(swayc_t *view, void *data) { | |||
40 | // return; | 40 | // return; |
41 | //} | 41 | //} |
42 | 42 | ||
43 | // if the shell specifies window geometry, make the top left corner of the | ||
44 | // window in the top left corner of the container to avoid arbitrarily | ||
45 | // sized gaps based on the attached buffer size | ||
46 | int window_offset_x = 0; | ||
47 | int window_offset_y = 0; | ||
48 | |||
49 | if (view->sway_view->type == SWAY_XDG_SHELL_V6_VIEW) { | ||
50 | window_offset_x = view->sway_view->wlr_xdg_surface_v6->geometry->x; | ||
51 | window_offset_y = view->sway_view->wlr_xdg_surface_v6->geometry->y; | ||
52 | } | ||
53 | |||
43 | // TODO | 54 | // TODO |
44 | double rotation = 0; | 55 | double rotation = 0; |
45 | float matrix[16]; | 56 | float matrix[16]; |
46 | 57 | ||
47 | float translate_origin[16]; | 58 | float translate_origin[16]; |
48 | wlr_matrix_translate(&translate_origin, | 59 | wlr_matrix_translate(&translate_origin, |
49 | (int)ox + render_width / 2, (int)oy + render_height / 2, 0); | 60 | (int)ox + render_width / 2 - window_offset_x, |
61 | (int)oy + render_height / 2 - window_offset_y, | ||
62 | 0); | ||
50 | 63 | ||
51 | float rotate[16]; | 64 | float rotate[16]; |
52 | wlr_matrix_rotate(&rotate, rotation); | 65 | wlr_matrix_rotate(&rotate, rotation); |
53 | 66 | ||
54 | float translate_center[16]; | 67 | float translate_center[16]; |
55 | wlr_matrix_translate(&translate_center, -render_width / 2, | 68 | wlr_matrix_translate(&translate_center, |
69 | -render_width / 2, | ||
56 | -render_height / 2, 0); | 70 | -render_height / 2, 0); |
57 | 71 | ||
58 | float scale[16]; | 72 | float scale[16]; |
@@ -122,10 +136,10 @@ void output_add_notify(struct wl_listener *listener, void *data) { | |||
122 | output->resolution.notify = output_resolution_notify; | 136 | output->resolution.notify = output_resolution_notify; |
123 | wl_signal_add(&wlr_output->events.resolution, &output->resolution); | 137 | wl_signal_add(&wlr_output->events.resolution, &output->resolution); |
124 | 138 | ||
125 | for (int i = 0; i < server->input->seats->length; ++i) { | 139 | for (int i = 0; i < server->input->seats->length; ++i) { |
126 | struct sway_seat *seat = server->input->seats->items[i]; | 140 | struct sway_seat *seat = server->input->seats->items[i]; |
127 | sway_seat_configure_xcursor(seat); | 141 | sway_seat_configure_xcursor(seat); |
128 | } | 142 | } |
129 | 143 | ||
130 | arrange_windows(output->swayc, -1, -1); | 144 | arrange_windows(output->swayc, -1, -1); |
131 | } | 145 | } |
diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 4f0344be..059f907d 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c | |||
@@ -2,16 +2,44 @@ | |||
2 | #include <wlr/types/wlr_cursor.h> | 2 | #include <wlr/types/wlr_cursor.h> |
3 | #include <wlr/types/wlr_xcursor_manager.h> | 3 | #include <wlr/types/wlr_xcursor_manager.h> |
4 | #include "sway/input/cursor.h" | 4 | #include "sway/input/cursor.h" |
5 | #include "sway/view.h" | ||
6 | #include "list.h" | ||
5 | #include "log.h" | 7 | #include "log.h" |
6 | 8 | ||
9 | static void cursor_update_position(struct sway_cursor *cursor) { | ||
10 | double x = cursor->cursor->x; | ||
11 | double y = cursor->cursor->y; | ||
12 | |||
13 | wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, | ||
14 | "left_ptr", cursor->cursor); | ||
15 | |||
16 | cursor->x = x; | ||
17 | cursor->y = y; | ||
18 | } | ||
19 | |||
20 | static void cursor_send_pointer_motion(struct sway_cursor *cursor, | ||
21 | uint32_t time) { | ||
22 | struct wlr_seat *seat = cursor->seat->seat; | ||
23 | struct wlr_surface *surface = NULL; | ||
24 | double sx, sy; | ||
25 | swayc_t *swayc = | ||
26 | swayc_at(&root_container, cursor->x, cursor->y, &surface, &sx, &sy); | ||
27 | if (swayc) { | ||
28 | wlr_seat_pointer_enter(seat, surface, sx, sy); | ||
29 | wlr_seat_pointer_notify_motion(seat, time, sx, sy); | ||
30 | } else { | ||
31 | wlr_seat_pointer_clear_focus(seat); | ||
32 | } | ||
33 | } | ||
34 | |||
7 | static void handle_cursor_motion(struct wl_listener *listener, void *data) { | 35 | static void handle_cursor_motion(struct wl_listener *listener, void *data) { |
8 | struct sway_cursor *cursor = | 36 | struct sway_cursor *cursor = |
9 | wl_container_of(listener, cursor, motion); | 37 | wl_container_of(listener, cursor, motion); |
10 | struct wlr_event_pointer_motion *event = data; | 38 | struct wlr_event_pointer_motion *event = data; |
11 | sway_log(L_DEBUG, "TODO: handle cursor motion event: dx=%f, dy=%f", event->delta_x, event->delta_y); | 39 | wlr_cursor_move(cursor->cursor, event->device, |
12 | wlr_cursor_move(cursor->cursor, event->device, event->delta_x, event->delta_y); | 40 | event->delta_x, event->delta_y); |
13 | sway_log(L_DEBUG, "TODO: new x=%f, y=%f", cursor->cursor->x, cursor->cursor->y); | 41 | cursor_update_position(cursor); |
14 | wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, "left_ptr", cursor->cursor); | 42 | cursor_send_pointer_motion(cursor, event->time_msec); |
15 | } | 43 | } |
16 | 44 | ||
17 | static void handle_cursor_motion_absolute(struct wl_listener *listener, | 45 | static void handle_cursor_motion_absolute(struct wl_listener *listener, |
@@ -19,7 +47,10 @@ static void handle_cursor_motion_absolute(struct wl_listener *listener, | |||
19 | struct sway_cursor *cursor = | 47 | struct sway_cursor *cursor = |
20 | wl_container_of(listener, cursor, motion_absolute); | 48 | wl_container_of(listener, cursor, motion_absolute); |
21 | struct wlr_event_pointer_motion_absolute *event = data; | 49 | struct wlr_event_pointer_motion_absolute *event = data; |
22 | sway_log(L_DEBUG, "TODO: handle event: %p", event); | 50 | wlr_cursor_warp_absolute(cursor->cursor, event->device, |
51 | event->x_mm / event->width_mm, event->y_mm / event->height_mm); | ||
52 | cursor_update_position(cursor); | ||
53 | cursor_send_pointer_motion(cursor, event->time_msec); | ||
23 | } | 54 | } |
24 | 55 | ||
25 | static void handle_cursor_button(struct wl_listener *listener, void *data) { | 56 | static void handle_cursor_button(struct wl_listener *listener, void *data) { |
@@ -91,6 +122,7 @@ struct sway_cursor *sway_cursor_create(struct sway_seat *seat) { | |||
91 | return NULL; | 122 | return NULL; |
92 | } | 123 | } |
93 | 124 | ||
125 | cursor->seat = seat; | ||
94 | wlr_cursor_attach_output_layout(wlr_cursor, root_container.output_layout); | 126 | wlr_cursor_attach_output_layout(wlr_cursor, root_container.output_layout); |
95 | 127 | ||
96 | // input events | 128 | // input events |
diff --git a/sway/tree/container.c b/sway/tree/container.c index e205fbcf..321ef8b1 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c | |||
@@ -3,6 +3,7 @@ | |||
3 | #include <stdlib.h> | 3 | #include <stdlib.h> |
4 | #include <string.h> | 4 | #include <string.h> |
5 | #include <wlr/types/wlr_output_layout.h> | 5 | #include <wlr/types/wlr_output_layout.h> |
6 | #include <wlr/types/wlr_wl_shell.h> | ||
6 | #include "sway/container.h" | 7 | #include "sway/container.h" |
7 | #include "sway/layout.h" | 8 | #include "sway/layout.h" |
8 | #include "sway/output.h" | 9 | #include "sway/output.h" |
@@ -168,3 +169,62 @@ swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types type) { | |||
168 | } while (container && container->type != type); | 169 | } while (container && container->type != type); |
169 | return container; | 170 | return container; |
170 | } | 171 | } |
172 | |||
173 | swayc_t *swayc_at(swayc_t *parent, double lx, double ly, | ||
174 | struct wlr_surface **surface, double *sx, double *sy) { | ||
175 | list_t *queue = create_list(); | ||
176 | list_add(queue, parent); | ||
177 | |||
178 | swayc_t *swayc = NULL; | ||
179 | while (queue->length) { | ||
180 | swayc = queue->items[0]; | ||
181 | list_del(queue, 0); | ||
182 | if (swayc->type == C_VIEW) { | ||
183 | struct sway_view *sview = swayc->sway_view; | ||
184 | swayc_t *soutput = swayc_parent_by_type(swayc, C_OUTPUT); | ||
185 | struct wlr_box *output_box = | ||
186 | wlr_output_layout_get_box(root_container.output_layout, | ||
187 | soutput->sway_output->wlr_output); | ||
188 | double ox = lx - output_box->x; | ||
189 | double oy = ly - output_box->y; | ||
190 | double view_sx = ox - swayc->x; | ||
191 | double view_sy = oy - swayc->y; | ||
192 | int width = swayc->sway_view->surface->current->width; | ||
193 | int height = swayc->sway_view->surface->current->height; | ||
194 | |||
195 | // TODO popups and subsurfaces | ||
196 | switch (sview->type) { | ||
197 | case SWAY_WL_SHELL_VIEW: | ||
198 | break; | ||
199 | case SWAY_XDG_SHELL_V6_VIEW: | ||
200 | // the top left corner of the sway container is the | ||
201 | // coordinate of the top left corner of the window geometry | ||
202 | view_sx += sview->wlr_xdg_surface_v6->geometry->x; | ||
203 | view_sy += sview->wlr_xdg_surface_v6->geometry->y; | ||
204 | break; | ||
205 | case SWAY_XWAYLAND_VIEW: | ||
206 | break; | ||
207 | default: | ||
208 | break; | ||
209 | } | ||
210 | |||
211 | if (view_sx > 0 && view_sx < width && | ||
212 | view_sy > 0 && view_sy < height && | ||
213 | pixman_region32_contains_point( | ||
214 | &sview->surface->current->input, | ||
215 | view_sx, view_sy, NULL)) { | ||
216 | *sx = view_sx; | ||
217 | *sy = view_sy; | ||
218 | *surface = swayc->sway_view->surface; | ||
219 | list_free(queue); | ||
220 | return swayc; | ||
221 | } | ||
222 | } else { | ||
223 | list_cat(queue, swayc->children); | ||
224 | } | ||
225 | } | ||
226 | |||
227 | list_free(queue); | ||
228 | |||
229 | return NULL; | ||
230 | } | ||