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); | ||||
| 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 | ||||
|  |  | |||
|  | @ -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) { | ||||
| 		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_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; | ||||
| 		struct wlr_subsurface *subsurface = | ||||
| 			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; | ||||
| 	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