wl-shell: popup input handling
This commit is contained in:
		
							parent
							
								
									d4c065e59b
								
							
						
					
					
						commit
						fe3c6c929b
					
				|  | @ -125,4 +125,13 @@ void wlr_wl_shell_surface_configure(struct wlr_wl_shell_surface *surface, | ||||||
| void wlr_wl_shell_surface_popup_done(struct wlr_wl_shell_surface *surface); | void wlr_wl_shell_surface_popup_done(struct wlr_wl_shell_surface *surface); | ||||||
| bool wlr_wl_shell_surface_is_transient(struct wlr_wl_shell_surface *surface); | bool wlr_wl_shell_surface_is_transient(struct wlr_wl_shell_surface *surface); | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * Find a popup within this surface at the surface-local coordinates. Returns | ||||||
|  |  * the popup and coordinates in the topmost surface coordinate system or NULL if | ||||||
|  |  * no popup is found at that location. | ||||||
|  |  */ | ||||||
|  | struct wlr_wl_shell_surface *wlr_wl_shell_surface_popup_at( | ||||||
|  | 		struct wlr_wl_shell_surface *surface, double sx, double sy, | ||||||
|  | 		double *popup_sx, double *popup_sy); | ||||||
|  | 
 | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | @ -103,6 +103,12 @@ struct roots_view *view_at(struct roots_desktop *desktop, double lx, double ly, | ||||||
| 	for (int i = desktop->views->length - 1; i >= 0; --i) { | 	for (int i = desktop->views->length - 1; i >= 0; --i) { | ||||||
| 		struct roots_view *view = desktop->views->items[i]; | 		struct roots_view *view = desktop->views->items[i]; | ||||||
| 
 | 
 | ||||||
|  | 		if (view->type == ROOTS_WL_SHELL_VIEW && | ||||||
|  | 				view->wl_shell_surface->state == | ||||||
|  | 				WLR_WL_SHELL_SURFACE_STATE_POPUP) { | ||||||
|  | 			continue; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		double view_sx = lx - view->x; | 		double view_sx = lx - view->x; | ||||||
| 		double view_sy = ly - view->y; | 		double view_sy = ly - view->y; | ||||||
| 
 | 
 | ||||||
|  | @ -138,6 +144,21 @@ struct roots_view *view_at(struct roots_desktop *desktop, double lx, double ly, | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		if (view->type == ROOTS_WL_SHELL_VIEW) { | ||||||
|  | 			// TODO: test if this works with rotated views
 | ||||||
|  | 			double popup_sx, popup_sy; | ||||||
|  | 			struct wlr_wl_shell_surface *popup = | ||||||
|  | 				wlr_wl_shell_surface_popup_at(view->wl_shell_surface, | ||||||
|  | 					view_sx, view_sy, &popup_sx, &popup_sy); | ||||||
|  | 
 | ||||||
|  | 			if (popup) { | ||||||
|  | 				*sx = view_sx - popup_sx; | ||||||
|  | 				*sy = view_sy - popup_sy; | ||||||
|  | 				*surface = popup->surface; | ||||||
|  | 				return view; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		double sub_x, sub_y; | 		double sub_x, sub_y; | ||||||
| 		struct wlr_subsurface *subsurface = | 		struct wlr_subsurface *subsurface = | ||||||
| 			wlr_surface_subsurface_at(view->wlr_surface, | 			wlr_surface_subsurface_at(view->wlr_surface, | ||||||
|  |  | ||||||
|  | @ -138,3 +138,40 @@ void handle_wl_shell_surface(struct wl_listener *listener, void *data) { | ||||||
| 	roots_surface->view = view; | 	roots_surface->view = view; | ||||||
| 	list_add(desktop->views, view); | 	list_add(desktop->views, view); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | struct wlr_wl_shell_surface *wlr_wl_shell_surface_popup_at( | ||||||
|  | 		struct wlr_wl_shell_surface *surface, double sx, double sy, | ||||||
|  | 		double *popup_sx, double *popup_sy) { | ||||||
|  | 	struct wlr_wl_shell_surface *popup; | ||||||
|  | 	wl_list_for_each(popup, &surface->children, child_link) { | ||||||
|  | 		double _popup_sx = popup->transient_state->x; | ||||||
|  | 		double _popup_sy = popup->transient_state->y; | ||||||
|  | 		int popup_width = | ||||||
|  | 			popup->surface->current->buffer_width; | ||||||
|  | 		int popup_height = | ||||||
|  | 			popup->surface->current->buffer_height; | ||||||
|  | 
 | ||||||
|  | 		struct wlr_wl_shell_surface *_popup = | ||||||
|  | 			wlr_wl_shell_surface_popup_at(popup, | ||||||
|  | 				popup->transient_state->x, | ||||||
|  | 				popup->transient_state->y, | ||||||
|  | 				popup_sx, popup_sy); | ||||||
|  | 		if (_popup) { | ||||||
|  | 			*popup_sx = sx + _popup_sx; | ||||||
|  | 			*popup_sy = sy + _popup_sy; | ||||||
|  | 			return _popup; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if ((sx > _popup_sx && sx < _popup_sx + popup_width) && | ||||||
|  | 				(sy > _popup_sy && sy < _popup_sy + popup_height)) { | ||||||
|  | 			if (pixman_region32_contains_point(&popup->surface->current->input, | ||||||
|  | 						sx - _popup_sx, sy - _popup_sy, NULL)) { | ||||||
|  | 				*popup_sx = _popup_sx; | ||||||
|  | 				*popup_sy = _popup_sy; | ||||||
|  | 				return popup; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return NULL; | ||||||
|  | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue