aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sway/container.h4
-rw-r--r--include/sway/input/cursor.h3
-rw-r--r--sway/desktop/output.c30
-rw-r--r--sway/input/cursor.c42
-rw-r--r--sway/tree/container.c60
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
8typedef struct sway_container swayc_t; 9typedef struct sway_container swayc_t;
@@ -136,4 +137,7 @@ swayc_t *destroy_view(swayc_t *view);
136 137
137swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types type); 138swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types type);
138 139
140swayc_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
6struct sway_cursor { 6struct 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
9static 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
20static 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
7static void handle_cursor_motion(struct wl_listener *listener, void *data) { 35static 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
17static void handle_cursor_motion_absolute(struct wl_listener *listener, 45static 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
25static void handle_cursor_button(struct wl_listener *listener, void *data) { 56static 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
173swayc_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}