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 }