diff options
-rw-r--r-- | sway/input/cursor.c | 78 |
1 files changed, 66 insertions, 12 deletions
diff --git a/sway/input/cursor.c b/sway/input/cursor.c index d814e08e..b498a517 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c | |||
@@ -9,8 +9,10 @@ | |||
9 | #include "list.h" | 9 | #include "list.h" |
10 | #include "log.h" | 10 | #include "log.h" |
11 | #include "sway/input/cursor.h" | 11 | #include "sway/input/cursor.h" |
12 | #include "sway/layers.h" | ||
12 | #include "sway/output.h" | 13 | #include "sway/output.h" |
13 | #include "sway/tree/view.h" | 14 | #include "sway/tree/view.h" |
15 | #include "wlr-layer-shell-unstable-v1-protocol.h" | ||
14 | 16 | ||
15 | static void cursor_update_position(struct sway_cursor *cursor) { | 17 | static void cursor_update_position(struct sway_cursor *cursor) { |
16 | double x = cursor->cursor->x; | 18 | double x = cursor->cursor->x; |
@@ -20,9 +22,35 @@ static void cursor_update_position(struct sway_cursor *cursor) { | |||
20 | cursor->y = y; | 22 | cursor->y = y; |
21 | } | 23 | } |
22 | 24 | ||
25 | static struct wlr_surface *layer_surface_at(struct sway_output *output, | ||
26 | struct wl_list *layer, double ox, double oy, double *sx, double *sy) { | ||
27 | struct sway_layer_surface *sway_layer; | ||
28 | wl_list_for_each_reverse(sway_layer, layer, link) { | ||
29 | struct wlr_surface *wlr_surface = | ||
30 | sway_layer->layer_surface->surface; | ||
31 | double _sx = ox - sway_layer->geo.x; | ||
32 | double _sy = oy - sway_layer->geo.y; | ||
33 | struct wlr_box box = { | ||
34 | .x = sway_layer->geo.x, | ||
35 | .y = sway_layer->geo.y, | ||
36 | .width = wlr_surface->current->width, | ||
37 | .height = wlr_surface->current->height, | ||
38 | }; | ||
39 | // TODO: Test popups/subsurfaces | ||
40 | if (wlr_box_contains_point(&box, ox, oy) && | ||
41 | pixman_region32_contains_point( | ||
42 | &wlr_surface->current->input, _sx, _sy, NULL)) { | ||
43 | *sx = _sx; | ||
44 | *sy = _sy; | ||
45 | return wlr_surface; | ||
46 | } | ||
47 | } | ||
48 | return NULL; | ||
49 | } | ||
50 | |||
23 | /** | 51 | /** |
24 | * Returns the container at the cursor's position. If the container is a view, | 52 | * Returns the container at the cursor's position. If there is a surface at that |
25 | * stores the surface at the cursor's position in `*surface`. | 53 | * location, it is stored in **surface (it may not be a view). |
26 | */ | 54 | */ |
27 | static struct sway_container *container_at_cursor(struct sway_cursor *cursor, | 55 | static struct sway_container *container_at_cursor(struct sway_cursor *cursor, |
28 | struct wlr_surface **surface, double *sx, double *sy) { | 56 | struct wlr_surface **surface, double *sx, double *sy) { |
@@ -57,20 +85,47 @@ static struct sway_container *container_at_cursor(struct sway_cursor *cursor, | |||
57 | return NULL; | 85 | return NULL; |
58 | } | 86 | } |
59 | struct sway_output *output = wlr_output->data; | 87 | struct sway_output *output = wlr_output->data; |
88 | double ox = cursor->x, oy = cursor->y; | ||
89 | wlr_output_layout_output_coords(output_layout, wlr_output, &ox, &oy); | ||
60 | 90 | ||
61 | // find the focused workspace on the output for this seat | 91 | // find the focused workspace on the output for this seat |
62 | struct sway_container *workspace_cont = | 92 | struct sway_container *ws = |
63 | sway_seat_get_focus_inactive(cursor->seat, output->swayc); | 93 | sway_seat_get_focus_inactive(cursor->seat, output->swayc); |
64 | if (workspace_cont != NULL && workspace_cont->type != C_WORKSPACE) { | 94 | if (ws && ws->type != C_WORKSPACE) { |
65 | workspace_cont = container_parent(workspace_cont, C_WORKSPACE); | 95 | ws = container_parent(ws, C_WORKSPACE); |
66 | } | 96 | } |
67 | if (workspace_cont == NULL) { | 97 | if (!ws) { |
68 | return output->swayc; | 98 | return output->swayc; |
69 | } | 99 | } |
70 | 100 | ||
71 | struct sway_container *view_cont = container_at(workspace_cont, | 101 | if ((*surface = layer_surface_at(output, |
72 | cursor->x, cursor->y, surface, sx, sy); | 102 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], |
73 | return view_cont != NULL ? view_cont : workspace_cont; | 103 | ox, oy, sx, sy))) { |
104 | return ws; | ||
105 | } | ||
106 | if ((*surface = layer_surface_at(output, | ||
107 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], | ||
108 | ox, oy, sx, sy))) { | ||
109 | return ws; | ||
110 | } | ||
111 | |||
112 | struct sway_container *c; | ||
113 | if ((c = container_at(ws, cursor->x, cursor->y, surface, sx, sy))) { | ||
114 | return c; | ||
115 | } | ||
116 | |||
117 | if ((*surface = layer_surface_at(output, | ||
118 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], | ||
119 | ox, oy, sx, sy))) { | ||
120 | return ws; | ||
121 | } | ||
122 | if ((*surface = layer_surface_at(output, | ||
123 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], | ||
124 | ox, oy, sx, sy))) { | ||
125 | return ws; | ||
126 | } | ||
127 | |||
128 | return NULL; | ||
74 | } | 129 | } |
75 | 130 | ||
76 | static void cursor_send_pointer_motion(struct sway_cursor *cursor, | 131 | static void cursor_send_pointer_motion(struct sway_cursor *cursor, |
@@ -78,8 +133,7 @@ static void cursor_send_pointer_motion(struct sway_cursor *cursor, | |||
78 | struct wlr_seat *seat = cursor->seat->wlr_seat; | 133 | struct wlr_seat *seat = cursor->seat->wlr_seat; |
79 | struct wlr_surface *surface = NULL; | 134 | struct wlr_surface *surface = NULL; |
80 | double sx, sy; | 135 | double sx, sy; |
81 | struct sway_container *cont = | 136 | container_at_cursor(cursor, &surface, &sx, &sy); |
82 | container_at_cursor(cursor, &surface, &sx, &sy); | ||
83 | 137 | ||
84 | // reset cursor if switching between clients | 138 | // reset cursor if switching between clients |
85 | struct wl_client *client = NULL; | 139 | struct wl_client *client = NULL; |
@@ -93,7 +147,7 @@ static void cursor_send_pointer_motion(struct sway_cursor *cursor, | |||
93 | } | 147 | } |
94 | 148 | ||
95 | // send pointer enter/leave | 149 | // send pointer enter/leave |
96 | if (cont != NULL && surface != NULL) { | 150 | if (surface != NULL) { |
97 | wlr_seat_pointer_notify_enter(seat, surface, sx, sy); | 151 | wlr_seat_pointer_notify_enter(seat, surface, sx, sy); |
98 | wlr_seat_pointer_notify_motion(seat, time, sx, sy); | 152 | wlr_seat_pointer_notify_motion(seat, time, sx, sy); |
99 | } else { | 153 | } else { |