|  |  |  | @ -135,15 +135,25 @@ static struct sway_container *container_at_coords( | 
			
		
	
		
			
				
					|  |  |  |  | 	return output->swayc; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec, | 
			
		
	
		
			
				
					|  |  |  |  | 		bool allow_refocusing) { | 
			
		
	
		
			
				
					|  |  |  |  | void cursor_send_pointer_motion(struct sway_cursor *cursor, | 
			
		
	
		
			
				
					|  |  |  |  | 		double delta_x, double delta_y, uint32_t time_msec, bool allow_refocusing) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_container *prev_c = NULL; | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlr_surface *surface = NULL; | 
			
		
	
		
			
				
					|  |  |  |  | 	double sx, sy; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (delta_x != 0 || delta_y != 0) { | 
			
		
	
		
			
				
					|  |  |  |  | 		// Use the motion delta to find the container the pointer was previously
 | 
			
		
	
		
			
				
					|  |  |  |  | 		// over.
 | 
			
		
	
		
			
				
					|  |  |  |  | 		prev_c = container_at_coords(cursor->seat, | 
			
		
	
		
			
				
					|  |  |  |  | 			cursor->cursor->x - delta_x, cursor->cursor->y - delta_y, | 
			
		
	
		
			
				
					|  |  |  |  | 			&surface, &sx, &sy); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (time_msec == 0) { | 
			
		
	
		
			
				
					|  |  |  |  | 		time_msec = get_current_time_msec(); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlr_seat *seat = cursor->seat->wlr_seat; | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlr_surface *surface = NULL; | 
			
		
	
		
			
				
					|  |  |  |  | 	double sx, sy; | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_container *c = container_at_coords(cursor->seat, | 
			
		
	
		
			
				
					|  |  |  |  | 			cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy); | 
			
		
	
		
			
				
					|  |  |  |  | 	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, | 
			
		
	
		
			
				
					|  |  |  |  | 				seat_set_focus_warp(cursor->seat, c, false); | 
			
		
	
		
			
				
					|  |  |  |  | 			} | 
			
		
	
		
			
				
					|  |  |  |  | 		} else if (c->type == C_VIEW) { | 
			
		
	
		
			
				
					|  |  |  |  | 			// Don't switch focus on title mouseover for
 | 
			
		
	
		
			
				
					|  |  |  |  | 			// stacked and tabbed layouts
 | 
			
		
	
		
			
				
					|  |  |  |  | 			// If pointed container is in nested containers which are
 | 
			
		
	
		
			
				
					|  |  |  |  | 			// inside tabbed/stacked layout we should skip them
 | 
			
		
	
		
			
				
					|  |  |  |  | 			bool do_mouse_focus = true; | 
			
		
	
		
			
				
					|  |  |  |  | 			bool is_visible = view_is_visible(c->sway_view); | 
			
		
	
		
			
				
					|  |  |  |  | 			struct sway_container *p = c->parent; | 
			
		
	
		
			
				
					|  |  |  |  | 			while (p) { | 
			
		
	
		
			
				
					|  |  |  |  | 				if ((p->layout == L_TABBED || p->layout == L_STACKED) | 
			
		
	
		
			
				
					|  |  |  |  | 					&& !is_visible) { | 
			
		
	
		
			
				
					|  |  |  |  | 					do_mouse_focus = false; | 
			
		
	
		
			
				
					|  |  |  |  | 					break; | 
			
		
	
		
			
				
					|  |  |  |  | 			// Don't switch focus unless we have moved from one container to another.
 | 
			
		
	
		
			
				
					|  |  |  |  | 			if (c && prev_c && c == prev_c) { | 
			
		
	
		
			
				
					|  |  |  |  | 				do_mouse_focus = false; | 
			
		
	
		
			
				
					|  |  |  |  | 			} | 
			
		
	
		
			
				
					|  |  |  |  | 			// Skip check if we already know not to focus.
 | 
			
		
	
		
			
				
					|  |  |  |  | 			if (do_mouse_focus) { | 
			
		
	
		
			
				
					|  |  |  |  | 				// Don't switch focus on title mouseover for
 | 
			
		
	
		
			
				
					|  |  |  |  | 				// stacked and tabbed layouts
 | 
			
		
	
		
			
				
					|  |  |  |  | 				// If pointed container is in nested containers which are
 | 
			
		
	
		
			
				
					|  |  |  |  | 				// inside tabbed/stacked layout we should skip them
 | 
			
		
	
		
			
				
					|  |  |  |  | 				bool is_visible = view_is_visible(c->sway_view); | 
			
		
	
		
			
				
					|  |  |  |  | 				while (p) { | 
			
		
	
		
			
				
					|  |  |  |  | 					if ((p->layout == L_TABBED || p->layout == L_STACKED) | 
			
		
	
		
			
				
					|  |  |  |  | 							&& !is_visible) { | 
			
		
	
		
			
				
					|  |  |  |  | 						do_mouse_focus = false; | 
			
		
	
		
			
				
					|  |  |  |  | 						break; | 
			
		
	
		
			
				
					|  |  |  |  | 					} | 
			
		
	
		
			
				
					|  |  |  |  | 					p = p->parent; | 
			
		
	
		
			
				
					|  |  |  |  | 				} | 
			
		
	
		
			
				
					|  |  |  |  | 				p = p->parent; | 
			
		
	
		
			
				
					|  |  |  |  | 			} | 
			
		
	
		
			
				
					|  |  |  |  | 			if (!do_mouse_focus) { | 
			
		
	
		
			
				
					|  |  |  |  | 				struct sway_container *next_focus = seat_get_focus_inactive( | 
			
		
	
	
		
			
				
					|  |  |  | @ -221,7 +238,8 @@ static void handle_cursor_motion(struct wl_listener *listener, void *data) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlr_event_pointer_motion *event = data; | 
			
		
	
		
			
				
					|  |  |  |  | 	wlr_cursor_move(cursor->cursor, event->device, | 
			
		
	
		
			
				
					|  |  |  |  | 		event->delta_x, event->delta_y); | 
			
		
	
		
			
				
					|  |  |  |  | 	cursor_send_pointer_motion(cursor, event->time_msec, true); | 
			
		
	
		
			
				
					|  |  |  |  | 	cursor_send_pointer_motion(cursor, event->delta_x, event->delta_y, | 
			
		
	
		
			
				
					|  |  |  |  | 			event->time_msec, true); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void handle_cursor_motion_absolute( | 
			
		
	
	
		
			
				
					|  |  |  | @ -231,7 +249,7 @@ static void handle_cursor_motion_absolute( | 
			
		
	
		
			
				
					|  |  |  |  | 	wlr_idle_notify_activity(cursor->seat->input->server->idle, cursor->seat->wlr_seat); | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlr_event_pointer_motion_absolute *event = data; | 
			
		
	
		
			
				
					|  |  |  |  | 	wlr_cursor_warp_absolute(cursor->cursor, event->device, event->x, event->y); | 
			
		
	
		
			
				
					|  |  |  |  | 	cursor_send_pointer_motion(cursor, event->time_msec, true); | 
			
		
	
		
			
				
					|  |  |  |  | 	cursor_send_pointer_motion(cursor, 0, 0, event->time_msec, true); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | void dispatch_cursor_button(struct sway_cursor *cursor, | 
			
		
	
	
		
			
				
					|  |  |  | @ -401,7 +419,7 @@ static void handle_tool_axis(struct wl_listener *listener, void *data) { | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	wlr_cursor_warp_absolute(cursor->cursor, event->device, x, y); | 
			
		
	
		
			
				
					|  |  |  |  | 	cursor_send_pointer_motion(cursor, event->time_msec, true); | 
			
		
	
		
			
				
					|  |  |  |  | 	cursor_send_pointer_motion(cursor, 0, 0, event->time_msec, true); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void handle_tool_tip(struct wl_listener *listener, void *data) { | 
			
		
	
	
		
			
				
					|  |  |  | 
 |