diff options
author | Drew DeVault <sir@cmpwn.com> | 2018-03-30 18:49:18 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-03-30 18:49:18 -0400 |
commit | e6fa7a722e9329b1e61ff2977ae715da3c2d9c9b (patch) | |
tree | 65e272dbd50614ff343d1297aee99cb46a497d1a | |
parent | Set exclusive zone to -1 for swaybg (diff) | |
parent | Fix segfaults when focusing a workspace (diff) | |
download | sway-e6fa7a722e9329b1e61ff2977ae715da3c2d9c9b.tar.gz sway-e6fa7a722e9329b1e61ff2977ae715da3c2d9c9b.tar.zst sway-e6fa7a722e9329b1e61ff2977ae715da3c2d9c9b.zip |
Merge pull request #1669 from emersion/workspace-pointer-events
Fix pointer events for hidden workspaces
-rw-r--r-- | sway/input/cursor.c | 96 | ||||
-rw-r--r-- | sway/ipc-server.c | 2 |
2 files changed, 60 insertions, 38 deletions
diff --git a/sway/input/cursor.c b/sway/input/cursor.c index d57ac3e3..717d864b 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c | |||
@@ -6,10 +6,11 @@ | |||
6 | #endif | 6 | #endif |
7 | #include <wlr/types/wlr_cursor.h> | 7 | #include <wlr/types/wlr_cursor.h> |
8 | #include <wlr/types/wlr_xcursor_manager.h> | 8 | #include <wlr/types/wlr_xcursor_manager.h> |
9 | #include "sway/input/cursor.h" | ||
10 | #include "sway/tree/view.h" | ||
11 | #include "list.h" | 9 | #include "list.h" |
12 | #include "log.h" | 10 | #include "log.h" |
11 | #include "sway/input/cursor.h" | ||
12 | #include "sway/output.h" | ||
13 | #include "sway/tree/view.h" | ||
13 | 14 | ||
14 | static void cursor_update_position(struct sway_cursor *cursor) { | 15 | static void cursor_update_position(struct sway_cursor *cursor) { |
15 | double x = cursor->cursor->x; | 16 | double x = cursor->cursor->x; |
@@ -19,16 +20,16 @@ static void cursor_update_position(struct sway_cursor *cursor) { | |||
19 | cursor->y = y; | 20 | cursor->y = y; |
20 | } | 21 | } |
21 | 22 | ||
22 | static void cursor_send_pointer_motion(struct sway_cursor *cursor, | 23 | /** |
23 | uint32_t time) { | 24 | * Returns the container at the cursor's position. If the container is a view, |
24 | struct wlr_seat *seat = cursor->seat->wlr_seat; | 25 | * stores the surface at the cursor's position in `*surface`. |
25 | struct wlr_surface *surface = NULL; | 26 | */ |
26 | double sx, sy; | 27 | static struct sway_container *container_at_cursor(struct sway_cursor *cursor, |
27 | 28 | struct wlr_surface **surface, double *sx, double *sy) { | |
28 | // check for unmanaged views first | 29 | // check for unmanaged views first |
30 | struct wl_list *unmanaged = &root_container.sway_root->unmanaged_views; | ||
29 | struct sway_view *view; | 31 | struct sway_view *view; |
30 | wl_list_for_each_reverse(view, &root_container.sway_root->unmanaged_views, | 32 | wl_list_for_each_reverse(view, unmanaged, unmanaged_view_link) { |
31 | unmanaged_view_link) { | ||
32 | if (view->type == SWAY_XWAYLAND_VIEW) { | 33 | if (view->type == SWAY_XWAYLAND_VIEW) { |
33 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; | 34 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; |
34 | struct wlr_box box = { | 35 | struct wlr_box box = { |
@@ -39,19 +40,48 @@ static void cursor_send_pointer_motion(struct sway_cursor *cursor, | |||
39 | }; | 40 | }; |
40 | 41 | ||
41 | if (wlr_box_contains_point(&box, cursor->x, cursor->y)) { | 42 | if (wlr_box_contains_point(&box, cursor->x, cursor->y)) { |
42 | surface = xsurface->surface; | 43 | *surface = xsurface->surface; |
43 | sx = cursor->x - box.x; | 44 | *sx = cursor->x - box.x; |
44 | sy = cursor->y - box.y; | 45 | *sy = cursor->y - box.y; |
45 | wlr_seat_pointer_notify_enter(seat, surface, sx, sy); | 46 | return view->swayc; |
46 | wlr_seat_pointer_notify_motion(seat, time, sx, sy); | ||
47 | return; | ||
48 | } | 47 | } |
49 | } | 48 | } |
50 | } | 49 | } |
51 | 50 | ||
52 | struct sway_container *swayc = | 51 | // find the output the cursor is on |
53 | container_at(&root_container, cursor->x, cursor->y, &surface, &sx, &sy); | 52 | struct wlr_output_layout *output_layout = |
54 | if (swayc) { | 53 | root_container.sway_root->output_layout; |
54 | struct wlr_output *wlr_output = | ||
55 | wlr_output_layout_output_at(output_layout, cursor->x, cursor->y); | ||
56 | if (wlr_output == NULL) { | ||
57 | return NULL; | ||
58 | } | ||
59 | struct sway_output *output = wlr_output->data; | ||
60 | |||
61 | // find the focused workspace on the output for this seat | ||
62 | struct sway_container *workspace_cont = | ||
63 | sway_seat_get_focus_inactive(cursor->seat, output->swayc); | ||
64 | if (workspace_cont != NULL && workspace_cont->type != C_WORKSPACE) { | ||
65 | workspace_cont = container_parent(workspace_cont, C_WORKSPACE); | ||
66 | } | ||
67 | if (workspace_cont == NULL) { | ||
68 | return output->swayc; | ||
69 | } | ||
70 | |||
71 | struct sway_container *view_cont = container_at(workspace_cont, | ||
72 | cursor->x, cursor->y, surface, sx, sy); | ||
73 | return view_cont != NULL ? view_cont : workspace_cont; | ||
74 | } | ||
75 | |||
76 | static void cursor_send_pointer_motion(struct sway_cursor *cursor, | ||
77 | uint32_t time) { | ||
78 | struct wlr_seat *seat = cursor->seat->wlr_seat; | ||
79 | struct wlr_surface *surface = NULL; | ||
80 | double sx, sy; | ||
81 | struct sway_container *cont = | ||
82 | container_at_cursor(cursor, &surface, &sx, &sy); | ||
83 | |||
84 | if (cont != NULL && surface != NULL) { | ||
55 | wlr_seat_pointer_notify_enter(seat, surface, sx, sy); | 85 | wlr_seat_pointer_notify_enter(seat, surface, sx, sy); |
56 | wlr_seat_pointer_notify_motion(seat, time, sx, sy); | 86 | wlr_seat_pointer_notify_motion(seat, time, sx, sy); |
57 | } else { | 87 | } else { |
@@ -60,8 +90,7 @@ static void cursor_send_pointer_motion(struct sway_cursor *cursor, | |||
60 | } | 90 | } |
61 | 91 | ||
62 | static void handle_cursor_motion(struct wl_listener *listener, void *data) { | 92 | static void handle_cursor_motion(struct wl_listener *listener, void *data) { |
63 | struct sway_cursor *cursor = | 93 | struct sway_cursor *cursor = wl_container_of(listener, cursor, motion); |
64 | wl_container_of(listener, cursor, motion); | ||
65 | struct wlr_event_pointer_motion *event = data; | 94 | struct wlr_event_pointer_motion *event = data; |
66 | wlr_cursor_move(cursor->cursor, event->device, | 95 | wlr_cursor_move(cursor->cursor, event->device, |
67 | event->delta_x, event->delta_y); | 96 | event->delta_x, event->delta_y); |
@@ -80,17 +109,15 @@ static void handle_cursor_motion_absolute(struct wl_listener *listener, | |||
80 | } | 109 | } |
81 | 110 | ||
82 | static void handle_cursor_button(struct wl_listener *listener, void *data) { | 111 | static void handle_cursor_button(struct wl_listener *listener, void *data) { |
83 | struct sway_cursor *cursor = | 112 | struct sway_cursor *cursor = wl_container_of(listener, cursor, button); |
84 | wl_container_of(listener, cursor, button); | ||
85 | struct wlr_event_pointer_button *event = data; | 113 | struct wlr_event_pointer_button *event = data; |
86 | 114 | ||
87 | if (event->button == BTN_LEFT) { | 115 | if (event->button == BTN_LEFT) { |
88 | struct wlr_surface *surface = NULL; | 116 | struct wlr_surface *surface = NULL; |
89 | double sx, sy; | 117 | double sx, sy; |
90 | struct sway_container *swayc = | 118 | struct sway_container *cont = |
91 | container_at(&root_container, cursor->x, cursor->y, &surface, &sx, &sy); | 119 | container_at_cursor(cursor, &surface, &sx, &sy); |
92 | 120 | sway_seat_set_focus(cursor->seat, cont); | |
93 | sway_seat_set_focus(cursor->seat, swayc); | ||
94 | } | 121 | } |
95 | 122 | ||
96 | wlr_seat_pointer_notify_button(cursor->seat->wlr_seat, event->time_msec, | 123 | wlr_seat_pointer_notify_button(cursor->seat->wlr_seat, event->time_msec, |
@@ -98,23 +125,20 @@ static void handle_cursor_button(struct wl_listener *listener, void *data) { | |||
98 | } | 125 | } |
99 | 126 | ||
100 | static void handle_cursor_axis(struct wl_listener *listener, void *data) { | 127 | static void handle_cursor_axis(struct wl_listener *listener, void *data) { |
101 | struct sway_cursor *cursor = | 128 | struct sway_cursor *cursor = wl_container_of(listener, cursor, axis); |
102 | wl_container_of(listener, cursor, axis); | ||
103 | struct wlr_event_pointer_axis *event = data; | 129 | struct wlr_event_pointer_axis *event = data; |
104 | wlr_seat_pointer_notify_axis(cursor->seat->wlr_seat, event->time_msec, | 130 | wlr_seat_pointer_notify_axis(cursor->seat->wlr_seat, event->time_msec, |
105 | event->orientation, event->delta); | 131 | event->orientation, event->delta); |
106 | } | 132 | } |
107 | 133 | ||
108 | static void handle_touch_down(struct wl_listener *listener, void *data) { | 134 | static void handle_touch_down(struct wl_listener *listener, void *data) { |
109 | struct sway_cursor *cursor = | 135 | struct sway_cursor *cursor = wl_container_of(listener, cursor, touch_down); |
110 | wl_container_of(listener, cursor, touch_down); | ||
111 | struct wlr_event_touch_down *event = data; | 136 | struct wlr_event_touch_down *event = data; |
112 | wlr_log(L_DEBUG, "TODO: handle touch down event: %p", event); | 137 | wlr_log(L_DEBUG, "TODO: handle touch down event: %p", event); |
113 | } | 138 | } |
114 | 139 | ||
115 | static void handle_touch_up(struct wl_listener *listener, void *data) { | 140 | static void handle_touch_up(struct wl_listener *listener, void *data) { |
116 | struct sway_cursor *cursor = | 141 | struct sway_cursor *cursor = wl_container_of(listener, cursor, touch_up); |
117 | wl_container_of(listener, cursor, touch_up); | ||
118 | struct wlr_event_touch_up *event = data; | 142 | struct wlr_event_touch_up *event = data; |
119 | wlr_log(L_DEBUG, "TODO: handle touch up event: %p", event); | 143 | wlr_log(L_DEBUG, "TODO: handle touch up event: %p", event); |
120 | } | 144 | } |
@@ -127,15 +151,13 @@ static void handle_touch_motion(struct wl_listener *listener, void *data) { | |||
127 | } | 151 | } |
128 | 152 | ||
129 | static void handle_tool_axis(struct wl_listener *listener, void *data) { | 153 | static void handle_tool_axis(struct wl_listener *listener, void *data) { |
130 | struct sway_cursor *cursor = | 154 | struct sway_cursor *cursor = wl_container_of(listener, cursor, tool_axis); |
131 | wl_container_of(listener, cursor, tool_axis); | ||
132 | struct wlr_event_tablet_tool_axis *event = data; | 155 | struct wlr_event_tablet_tool_axis *event = data; |
133 | wlr_log(L_DEBUG, "TODO: handle tool axis event: %p", event); | 156 | wlr_log(L_DEBUG, "TODO: handle tool axis event: %p", event); |
134 | } | 157 | } |
135 | 158 | ||
136 | static void handle_tool_tip(struct wl_listener *listener, void *data) { | 159 | static void handle_tool_tip(struct wl_listener *listener, void *data) { |
137 | struct sway_cursor *cursor = | 160 | struct sway_cursor *cursor = wl_container_of(listener, cursor, tool_tip); |
138 | wl_container_of(listener, cursor, tool_tip); | ||
139 | struct wlr_event_tablet_tool_tip *event = data; | 161 | struct wlr_event_tablet_tool_tip *event = data; |
140 | wlr_log(L_DEBUG, "TODO: handle tool tip event: %p", event); | 162 | wlr_log(L_DEBUG, "TODO: handle tool tip event: %p", event); |
141 | } | 163 | } |
diff --git a/sway/ipc-server.c b/sway/ipc-server.c index f1854bcc..869f1ed0 100644 --- a/sway/ipc-server.c +++ b/sway/ipc-server.c | |||
@@ -390,7 +390,7 @@ static void ipc_get_workspaces_callback(struct sway_container *workspace, | |||
390 | struct sway_seat *seat = | 390 | struct sway_seat *seat = |
391 | sway_input_manager_get_default_seat(input_manager); | 391 | sway_input_manager_get_default_seat(input_manager); |
392 | struct sway_container *focused_ws = sway_seat_get_focus(seat); | 392 | struct sway_container *focused_ws = sway_seat_get_focus(seat); |
393 | if (focused_ws->type != C_WORKSPACE) { | 393 | if (focused_ws != NULL && focused_ws->type != C_WORKSPACE) { |
394 | focused_ws = container_parent(focused_ws, C_WORKSPACE); | 394 | focused_ws = container_parent(focused_ws, C_WORKSPACE); |
395 | } | 395 | } |
396 | bool focused = workspace == focused_ws; | 396 | bool focused = workspace == focused_ws; |