From fe3c6c929be467b3e1ec860c94c9524a6686bd61 Mon Sep 17 00:00:00 2001
From: Tony Crisci <tony@dubstepdish.com>
Date: Tue, 10 Oct 2017 10:00:09 -0400
Subject: wl-shell: popup input handling

---
 rootston/desktop.c  | 21 +++++++++++++++++++++
 rootston/wl_shell.c | 37 +++++++++++++++++++++++++++++++++++++
 2 files changed, 58 insertions(+)

(limited to 'rootston')

diff --git a/rootston/desktop.c b/rootston/desktop.c
index bef0fad4..d5cac575 100644
--- a/rootston/desktop.c
+++ b/rootston/desktop.c
@@ -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,
diff --git a/rootston/wl_shell.c b/rootston/wl_shell.c
index 34f53c7a..a629575b 100644
--- a/rootston/wl_shell.c
+++ b/rootston/wl_shell.c
@@ -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;
+}
-- 
cgit v1.2.3