aboutsummaryrefslogtreecommitdiffstats
path: root/sway/input/cursor.c
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2018-03-30 21:03:35 -0400
committerLibravatar Drew DeVault <sir@cmpwn.com>2018-03-30 21:03:35 -0400
commitf5470f33384713ce62c1628a550f3a52b16a6fe5 (patch)
tree8ef187ba7d9421b0a008e4318a7fb4919a74c07a /sway/input/cursor.c
parentMerge pull request #1660 from emersion/client-cursors (diff)
downloadsway-f5470f33384713ce62c1628a550f3a52b16a6fe5.tar.gz
sway-f5470f33384713ce62c1628a550f3a52b16a6fe5.tar.zst
sway-f5470f33384713ce62c1628a550f3a52b16a6fe5.zip
Pass pointer events to surface layers
Diffstat (limited to 'sway/input/cursor.c')
-rw-r--r--sway/input/cursor.c78
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
15static void cursor_update_position(struct sway_cursor *cursor) { 17static 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
25static 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 */
27static struct sway_container *container_at_cursor(struct sway_cursor *cursor, 55static 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
76static void cursor_send_pointer_motion(struct sway_cursor *cursor, 131static 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 {