commit 7cd1fe7

shrub  ·  2025-12-15 21:55:21 +0000 UTC
parent e4bb1fc
z-ordering
compositor.c : click to raise window to top. uses internal helpers to
find the window under the pointer and raise it on button press.
1 files changed,  +97, -16
+97, -16
  1@@ -63,10 +63,12 @@ struct target {
  2 };
  3 
  4 static bool handle_motion(struct pointer_handler *handler, uint32_t time, wl_fixed_t x, wl_fixed_t y);
  5+static bool handle_button(struct pointer_handler *handler, uint32_t time, struct button *button, uint32_t state);
  6 static void perform_update(void *data);
  7 
  8 static struct pointer_handler pointer_handler = {
  9 	.motion = handle_motion,
 10+	.button = handle_button,
 11 };
 12 
 13 static struct {
 14@@ -523,6 +525,78 @@ static const struct view_impl view_impl = {
 15 	.move = move,
 16 };
 17 
 18+static struct compositor_view *
 19+view_at(int32_t x, int32_t y)
 20+{
 21+	struct compositor_view *view;
 22+	struct swc_rectangle *geom;
 23+
 24+	wl_list_for_each (view, &compositor.views, link) {
 25+		if (!view->visible)
 26+			continue;
 27+
 28+		geom = &view->base.geometry;
 29+		if (!rectangle_contains_point(geom, x, y))
 30+			continue;
 31+
 32+		if (pixman_region32_contains_point(&view->surface->state.input,
 33+		                                   x - geom->x, y - geom->y, NULL))
 34+		{
 35+			return view;
 36+		}
 37+	}
 38+
 39+	return NULL;
 40+}
 41+
 42+static struct compositor_view *
 43+window_view(struct compositor_view *view)
 44+{
 45+	while (view && !view->window && view->parent && view->parent != view)
 46+		view = view->parent;
 47+	return (view && view->window) ? view : NULL;
 48+}
 49+
 50+static void
 51+raise_window(struct compositor_view *view)
 52+{
 53+	struct compositor_view *other, *top_window;
 54+	struct wl_list *insert_after;
 55+	uint32_t screens;
 56+
 57+	view = window_view(view);
 58+	if (!view || !view->visible)
 59+		return;
 60+
 61+	top_window = NULL;
 62+	insert_after = &compositor.views;
 63+	wl_list_for_each (other, &compositor.views, link) {
 64+		if (!other->visible)
 65+			continue;
 66+
 67+		if (other->window) {
 68+			top_window = other;
 69+			break;
 70+		}
 71+		insert_after = &other->link;
 72+	}
 73+
 74+	if (view == top_window)
 75+		return;
 76+
 77+	screens = view->base.screens;
 78+
 79+	wl_list_remove(&view->link);
 80+	wl_list_insert(insert_after, &view->link);
 81+
 82+	view->border.damaged = true;
 83+	pixman_region32_union_rect(&compositor.damage, &compositor.damage,
 84+	                           view->extents.x1, view->extents.y1,
 85+	                           (uint32_t)(view->extents.x2 - view->extents.x1),
 86+	                           (uint32_t)(view->extents.y2 - view->extents.y1));
 87+	schedule_updates(screens);
 88+}
 89+
 90 struct compositor_view *
 91 compositor_create_view(struct surface *surface)
 92 {
 93@@ -575,7 +649,7 @@ compositor_view(struct view *view)
 94 void
 95 compositor_view_set_parent(struct compositor_view *view, struct compositor_view *parent)
 96 {
 97-	view->parent = view;
 98+	view->parent = parent;
 99 
100 	if (parent->visible)
101 		compositor_view_show(view);
102@@ -789,28 +863,35 @@ perform_update(void *data)
103 bool
104 handle_motion(struct pointer_handler *handler, uint32_t time, wl_fixed_t fx, wl_fixed_t fy)
105 {
106-	struct compositor_view *view;
107-	bool found = false;
108 	int32_t x = wl_fixed_to_int(fx), y = wl_fixed_to_int(fy);
109-	struct swc_rectangle *geom;
110 
111 	/* If buttons are pressed, don't change pointer focus. */
112 	if (swc.seat->pointer->buttons.size > 0)
113 		return false;
114 
115-	wl_list_for_each (view, &compositor.views, link) {
116-		if (!view->visible)
117-			continue;
118-		geom = &view->base.geometry;
119-		if (rectangle_contains_point(geom, x, y)) {
120-			if (pixman_region32_contains_point(&view->surface->state.input, x - geom->x, y - geom->y, NULL)) {
121-				found = true;
122-				break;
123-			}
124-		}
125-	}
126+	struct compositor_view *view = view_at(x, y);
127+
128+	pointer_set_focus(swc.seat->pointer, view);
129+
130+	return false;
131+}
132+
133+static bool
134+handle_button(struct pointer_handler *handler, uint32_t time, struct button *button, uint32_t state)
135+{
136+	(void)handler;
137+	(void)time;
138+	(void)button;
139+
140+	if (state != WL_POINTER_BUTTON_STATE_PRESSED)
141+		return false;
142+
143+	int32_t x = wl_fixed_to_int(swc.seat->pointer->x);
144+	int32_t y = wl_fixed_to_int(swc.seat->pointer->y);
145+	struct compositor_view *view = view_at(x, y);
146 
147-	pointer_set_focus(swc.seat->pointer, found ? view : NULL);
148+	pointer_set_focus(swc.seat->pointer, view);
149+	raise_window(view);
150 
151 	return false;
152 }