aboutsummaryrefslogtreecommitdiffstats
path: root/sway/input/cursor.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/input/cursor.c')
-rw-r--r--sway/input/cursor.c54
1 files changed, 36 insertions, 18 deletions
diff --git a/sway/input/cursor.c b/sway/input/cursor.c
index 1cf432f3..cc8d344f 100644
--- a/sway/input/cursor.c
+++ b/sway/input/cursor.c
@@ -135,15 +135,25 @@ static struct sway_container *container_at_coords(
135 return output->swayc; 135 return output->swayc;
136} 136}
137 137
138void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec, 138void cursor_send_pointer_motion(struct sway_cursor *cursor,
139 bool allow_refocusing) { 139 double delta_x, double delta_y, uint32_t time_msec, bool allow_refocusing) {
140 struct sway_container *prev_c = NULL;
141 struct wlr_surface *surface = NULL;
142 double sx, sy;
143
144 if (delta_x != 0 || delta_y != 0) {
145 // Use the motion delta to find the container the pointer was previously
146 // over.
147 prev_c = container_at_coords(cursor->seat,
148 cursor->cursor->x - delta_x, cursor->cursor->y - delta_y,
149 &surface, &sx, &sy);
150 }
151
140 if (time_msec == 0) { 152 if (time_msec == 0) {
141 time_msec = get_current_time_msec(); 153 time_msec = get_current_time_msec();
142 } 154 }
143 155
144 struct wlr_seat *seat = cursor->seat->wlr_seat; 156 struct wlr_seat *seat = cursor->seat->wlr_seat;
145 struct wlr_surface *surface = NULL;
146 double sx, sy;
147 struct sway_container *c = container_at_coords(cursor->seat, 157 struct sway_container *c = container_at_coords(cursor->seat,
148 cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy); 158 cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
149 if (c && config->focus_follows_mouse && allow_refocusing) { 159 if (c && config->focus_follows_mouse && allow_refocusing) {
@@ -162,20 +172,27 @@ void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec,
162 seat_set_focus_warp(cursor->seat, c, false); 172 seat_set_focus_warp(cursor->seat, c, false);
163 } 173 }
164 } else if (c->type == C_VIEW) { 174 } else if (c->type == C_VIEW) {
165 // Don't switch focus on title mouseover for
166 // stacked and tabbed layouts
167 // If pointed container is in nested containers which are
168 // inside tabbed/stacked layout we should skip them
169 bool do_mouse_focus = true; 175 bool do_mouse_focus = true;
170 bool is_visible = view_is_visible(c->sway_view);
171 struct sway_container *p = c->parent; 176 struct sway_container *p = c->parent;
172 while (p) { 177 // Don't switch focus unless we have moved from one container to another.
173 if ((p->layout == L_TABBED || p->layout == L_STACKED) 178 if (c && prev_c && c == prev_c) {
174 && !is_visible) { 179 do_mouse_focus = false;
175 do_mouse_focus = false; 180 }
176 break; 181 // Skip check if we already know not to focus.
182 if (do_mouse_focus) {
183 // Don't switch focus on title mouseover for
184 // stacked and tabbed layouts
185 // If pointed container is in nested containers which are
186 // inside tabbed/stacked layout we should skip them
187 bool is_visible = view_is_visible(c->sway_view);
188 while (p) {
189 if ((p->layout == L_TABBED || p->layout == L_STACKED)
190 && !is_visible) {
191 do_mouse_focus = false;
192 break;
193 }
194 p = p->parent;
177 } 195 }
178 p = p->parent;
179 } 196 }
180 if (!do_mouse_focus) { 197 if (!do_mouse_focus) {
181 struct sway_container *next_focus = seat_get_focus_inactive( 198 struct sway_container *next_focus = seat_get_focus_inactive(
@@ -221,7 +238,8 @@ static void handle_cursor_motion(struct wl_listener *listener, void *data) {
221 struct wlr_event_pointer_motion *event = data; 238 struct wlr_event_pointer_motion *event = data;
222 wlr_cursor_move(cursor->cursor, event->device, 239 wlr_cursor_move(cursor->cursor, event->device,
223 event->delta_x, event->delta_y); 240 event->delta_x, event->delta_y);
224 cursor_send_pointer_motion(cursor, event->time_msec, true); 241 cursor_send_pointer_motion(cursor, event->delta_x, event->delta_y,
242 event->time_msec, true);
225} 243}
226 244
227static void handle_cursor_motion_absolute( 245static void handle_cursor_motion_absolute(
@@ -231,7 +249,7 @@ static void handle_cursor_motion_absolute(
231 wlr_idle_notify_activity(cursor->seat->input->server->idle, cursor->seat->wlr_seat); 249 wlr_idle_notify_activity(cursor->seat->input->server->idle, cursor->seat->wlr_seat);
232 struct wlr_event_pointer_motion_absolute *event = data; 250 struct wlr_event_pointer_motion_absolute *event = data;
233 wlr_cursor_warp_absolute(cursor->cursor, event->device, event->x, event->y); 251 wlr_cursor_warp_absolute(cursor->cursor, event->device, event->x, event->y);
234 cursor_send_pointer_motion(cursor, event->time_msec, true); 252 cursor_send_pointer_motion(cursor, 0, 0, event->time_msec, true);
235} 253}
236 254
237void dispatch_cursor_button(struct sway_cursor *cursor, 255void dispatch_cursor_button(struct sway_cursor *cursor,
@@ -401,7 +419,7 @@ static void handle_tool_axis(struct wl_listener *listener, void *data) {
401 } 419 }
402 420
403 wlr_cursor_warp_absolute(cursor->cursor, event->device, x, y); 421 wlr_cursor_warp_absolute(cursor->cursor, event->device, x, y);
404 cursor_send_pointer_motion(cursor, event->time_msec, true); 422 cursor_send_pointer_motion(cursor, 0, 0, event->time_msec, true);
405} 423}
406 424
407static void handle_tool_tip(struct wl_listener *listener, void *data) { 425static void handle_tool_tip(struct wl_listener *listener, void *data) {