diff options
-rw-r--r-- | include/bar/bar.h | 3 | ||||
-rw-r--r-- | include/bar/ipc.h | 6 | ||||
-rw-r--r-- | include/bar/render.h | 5 | ||||
-rw-r--r-- | include/client/window.h | 6 | ||||
-rw-r--r-- | include/extensions.h | 4 | ||||
-rw-r--r-- | sway/extensions.c | 1 | ||||
-rw-r--r-- | sway/handlers.c | 126 | ||||
-rw-r--r-- | swaybar/bar.c | 34 | ||||
-rw-r--r-- | swaybar/ipc.c | 9 | ||||
-rw-r--r-- | swaybar/render.c | 34 | ||||
-rw-r--r-- | swaybg/main.c | 1 | ||||
-rw-r--r-- | wayland/window.c | 4 |
12 files changed, 158 insertions, 75 deletions
diff --git a/include/bar/bar.h b/include/bar/bar.h index c20efc55..a3c511d9 100644 --- a/include/bar/bar.h +++ b/include/bar/bar.h | |||
@@ -32,6 +32,9 @@ struct workspace { | |||
32 | bool urgent; | 32 | bool urgent; |
33 | }; | 33 | }; |
34 | 34 | ||
35 | /** Global bar state */ | ||
36 | extern struct bar swaybar; | ||
37 | |||
35 | /** | 38 | /** |
36 | * Setup bar. | 39 | * Setup bar. |
37 | */ | 40 | */ |
diff --git a/include/bar/ipc.h b/include/bar/ipc.h index 741c067b..c11931d0 100644 --- a/include/bar/ipc.h +++ b/include/bar/ipc.h | |||
@@ -13,5 +13,11 @@ void ipc_bar_init(struct bar *bar, const char *bar_id); | |||
13 | */ | 13 | */ |
14 | bool handle_ipc_event(struct bar *bar); | 14 | bool handle_ipc_event(struct bar *bar); |
15 | 15 | ||
16 | |||
17 | /** | ||
18 | * Send workspace command to sway | ||
19 | */ | ||
20 | void ipc_send_workspace_command(const char *workspace_name); | ||
21 | |||
16 | #endif /* _SWAYBAR_IPC_H */ | 22 | #endif /* _SWAYBAR_IPC_H */ |
17 | 23 | ||
diff --git a/include/bar/render.h b/include/bar/render.h index 931a1cdd..114f43f4 100644 --- a/include/bar/render.h +++ b/include/bar/render.h | |||
@@ -14,4 +14,9 @@ void render(struct output *output, struct config *config, struct status_line *li | |||
14 | */ | 14 | */ |
15 | void set_window_height(struct window *window, int height); | 15 | void set_window_height(struct window *window, int height); |
16 | 16 | ||
17 | /** | ||
18 | * Compute the size of a workspace name | ||
19 | */ | ||
20 | void workspace_button_size(struct window *window, const char *workspace_name, int *width, int *height); | ||
21 | |||
17 | #endif /* _SWAYBAR_RENDER_H */ | 22 | #endif /* _SWAYBAR_RENDER_H */ |
diff --git a/include/client/window.h b/include/client/window.h index 7be4fff3..55a12225 100644 --- a/include/client/window.h +++ b/include/client/window.h | |||
@@ -28,10 +28,10 @@ struct cursor { | |||
28 | }; | 28 | }; |
29 | 29 | ||
30 | struct pointer_input { | 30 | struct pointer_input { |
31 | wl_fixed_t last_x; | 31 | int last_x; |
32 | wl_fixed_t last_y; | 32 | int last_y; |
33 | 33 | ||
34 | void (*notify)(struct window *window, wl_fixed_t x, wl_fixed_t y, uint32_t button); | 34 | void (*notify)(struct window *window, int x, int y, uint32_t button); |
35 | }; | 35 | }; |
36 | 36 | ||
37 | struct window { | 37 | struct window { |
diff --git a/include/extensions.h b/include/extensions.h index 7c508b5e..d26e95c1 100644 --- a/include/extensions.h +++ b/include/extensions.h | |||
@@ -11,8 +11,6 @@ struct background_config { | |||
11 | wlc_resource surface; | 11 | wlc_resource surface; |
12 | // we need the wl_resource of the surface in the destructor | 12 | // we need the wl_resource of the surface in the destructor |
13 | struct wl_resource *wl_surface_res; | 13 | struct wl_resource *wl_surface_res; |
14 | // used to determine if client is a background | ||
15 | struct wl_client *client; | ||
16 | }; | 14 | }; |
17 | 15 | ||
18 | struct panel_config { | 16 | struct panel_config { |
@@ -25,6 +23,8 @@ struct panel_config { | |||
25 | enum desktop_shell_panel_position panel_position; | 23 | enum desktop_shell_panel_position panel_position; |
26 | // used to determine if client is a panel | 24 | // used to determine if client is a panel |
27 | struct wl_client *client; | 25 | struct wl_client *client; |
26 | // wlc handle for this panel's surface, not set until panel is created | ||
27 | wlc_handle handle; | ||
28 | }; | 28 | }; |
29 | 29 | ||
30 | struct desktop_shell_state { | 30 | struct desktop_shell_state { |
diff --git a/sway/extensions.c b/sway/extensions.c index 1fe15ac5..ab425fa7 100644 --- a/sway/extensions.c +++ b/sway/extensions.c | |||
@@ -73,7 +73,6 @@ static void set_background(struct wl_client *client, struct wl_resource *resourc | |||
73 | } | 73 | } |
74 | sway_log(L_DEBUG, "Setting surface %p as background for output %d", surface, (int)output); | 74 | sway_log(L_DEBUG, "Setting surface %p as background for output %d", surface, (int)output); |
75 | struct background_config *config = malloc(sizeof(struct background_config)); | 75 | struct background_config *config = malloc(sizeof(struct background_config)); |
76 | config->client = client; | ||
77 | config->output = output; | 76 | config->output = output; |
78 | config->surface = wlc_resource_from_wl_surface_resource(surface); | 77 | config->surface = wlc_resource_from_wl_surface_resource(surface); |
79 | config->wl_surface_res = surface; | 78 | config->wl_surface_res = surface; |
diff --git a/sway/handlers.c b/sway/handlers.c index 4336b6c7..a7a87564 100644 --- a/sway/handlers.c +++ b/sway/handlers.c | |||
@@ -33,6 +33,66 @@ | |||
33 | // Event handled by sway and should not be sent to client | 33 | // Event handled by sway and should not be sent to client |
34 | #define EVENT_HANDLED true | 34 | #define EVENT_HANDLED true |
35 | 35 | ||
36 | static struct panel_config *if_panel_find_config(struct wl_client *client) { | ||
37 | int i; | ||
38 | for (i = 0; i < desktop_shell.panels->length; i++) { | ||
39 | struct panel_config *config = desktop_shell.panels->items[i]; | ||
40 | if (config->client == client) { | ||
41 | return config; | ||
42 | } | ||
43 | } | ||
44 | return NULL; | ||
45 | } | ||
46 | |||
47 | static struct wlc_geometry compute_panel_geometry(struct panel_config *config) { | ||
48 | const struct wlc_size resolution = *wlc_output_get_resolution(config->output); | ||
49 | const struct wlc_geometry *old = wlc_view_get_geometry(config->handle); | ||
50 | struct wlc_geometry new; | ||
51 | |||
52 | switch (config->panel_position) { | ||
53 | case DESKTOP_SHELL_PANEL_POSITION_TOP: | ||
54 | new.origin.x = 0; | ||
55 | new.origin.y = 0; | ||
56 | new.size.w = resolution.w; | ||
57 | new.size.h = old->size.h; | ||
58 | break; | ||
59 | case DESKTOP_SHELL_PANEL_POSITION_BOTTOM: | ||
60 | new.origin.x = 0; | ||
61 | new.origin.y = resolution.h - old->size.h; | ||
62 | new.size.w = resolution.w; | ||
63 | new.size.h = old->size.h; | ||
64 | break; | ||
65 | case DESKTOP_SHELL_PANEL_POSITION_LEFT: | ||
66 | new.origin.x = 0; | ||
67 | new.origin.y = 0; | ||
68 | new.size.w = old->size.w; | ||
69 | new.size.h = resolution.h; | ||
70 | break; | ||
71 | case DESKTOP_SHELL_PANEL_POSITION_RIGHT: | ||
72 | new.origin.x = resolution.w - old->size.w; | ||
73 | new.origin.y = 0; | ||
74 | new.size.w = old->size.w; | ||
75 | new.size.h = resolution.h; | ||
76 | break; | ||
77 | } | ||
78 | |||
79 | return new; | ||
80 | } | ||
81 | |||
82 | static void update_panel_geometry(struct panel_config *config) { | ||
83 | struct wlc_geometry geometry = compute_panel_geometry(config); | ||
84 | wlc_view_set_geometry(config->handle, 0, &geometry); | ||
85 | } | ||
86 | |||
87 | static void update_panel_geometries(wlc_handle output) { | ||
88 | for (int i = 0; i < desktop_shell.panels->length; i++) { | ||
89 | struct panel_config *config = desktop_shell.panels->items[i]; | ||
90 | if (config->output == output) { | ||
91 | update_panel_geometry(config); | ||
92 | } | ||
93 | } | ||
94 | } | ||
95 | |||
36 | /* Handles */ | 96 | /* Handles */ |
37 | 97 | ||
38 | static bool handle_input_created(struct libinput_device *device) { | 98 | static bool handle_input_created(struct libinput_device *device) { |
@@ -119,32 +179,6 @@ static void handle_output_pre_render(wlc_handle output) { | |||
119 | break; | 179 | break; |
120 | } | 180 | } |
121 | } | 181 | } |
122 | |||
123 | for (i = 0; i < desktop_shell.panels->length; ++i) { | ||
124 | struct panel_config *config = desktop_shell.panels->items[i]; | ||
125 | if (config->output == output) { | ||
126 | struct wlc_size size = *wlc_surface_get_size(config->surface); | ||
127 | struct wlc_geometry geo = { | ||
128 | .size = size | ||
129 | }; | ||
130 | switch (config->panel_position) { | ||
131 | case DESKTOP_SHELL_PANEL_POSITION_TOP: | ||
132 | geo.origin = (struct wlc_point){ 0, 0 }; | ||
133 | break; | ||
134 | case DESKTOP_SHELL_PANEL_POSITION_BOTTOM: | ||
135 | geo.origin = (struct wlc_point){ 0, resolution.h - size.h }; | ||
136 | break; | ||
137 | case DESKTOP_SHELL_PANEL_POSITION_LEFT: | ||
138 | geo.origin = (struct wlc_point){ 0, 0 }; | ||
139 | break; | ||
140 | case DESKTOP_SHELL_PANEL_POSITION_RIGHT: | ||
141 | geo.origin = (struct wlc_point){ resolution.w - size.w, 0 }; | ||
142 | break; | ||
143 | } | ||
144 | wlc_surface_render(config->surface, &geo); | ||
145 | break; | ||
146 | } | ||
147 | } | ||
148 | } | 182 | } |
149 | 183 | ||
150 | static void handle_output_post_render(wlc_handle output) { | 184 | static void handle_output_post_render(wlc_handle output) { |
@@ -158,10 +192,16 @@ static void handle_view_pre_render(wlc_handle view) { | |||
158 | 192 | ||
159 | static void handle_output_resolution_change(wlc_handle output, const struct wlc_size *from, const struct wlc_size *to) { | 193 | static void handle_output_resolution_change(wlc_handle output, const struct wlc_size *from, const struct wlc_size *to) { |
160 | sway_log(L_DEBUG, "Output %u resolution changed to %d x %d", (unsigned int)output, to->w, to->h); | 194 | sway_log(L_DEBUG, "Output %u resolution changed to %d x %d", (unsigned int)output, to->w, to->h); |
195 | |||
161 | swayc_t *c = swayc_by_handle(output); | 196 | swayc_t *c = swayc_by_handle(output); |
162 | if (!c) return; | 197 | if (!c) { |
198 | return; | ||
199 | } | ||
163 | c->width = to->w; | 200 | c->width = to->w; |
164 | c->height = to->h; | 201 | c->height = to->h; |
202 | |||
203 | update_panel_geometries(output); | ||
204 | |||
165 | arrange_windows(&root_container, -1, -1); | 205 | arrange_windows(&root_container, -1, -1); |
166 | } | 206 | } |
167 | 207 | ||
@@ -176,28 +216,6 @@ static void handle_output_focused(wlc_handle output, bool focus) { | |||
176 | } | 216 | } |
177 | } | 217 | } |
178 | 218 | ||
179 | static bool client_is_background(struct wl_client *client) { | ||
180 | int i; | ||
181 | for (i = 0; i < desktop_shell.backgrounds->length; i++) { | ||
182 | struct background_config *config = desktop_shell.backgrounds->items[i]; | ||
183 | if (config->client == client) { | ||
184 | return true; | ||
185 | } | ||
186 | } | ||
187 | return false; | ||
188 | } | ||
189 | |||
190 | static bool client_is_panel(struct wl_client *client) { | ||
191 | int i; | ||
192 | for (i = 0; i < desktop_shell.panels->length; i++) { | ||
193 | struct panel_config *config = desktop_shell.panels->items[i]; | ||
194 | if (config->client == client) { | ||
195 | return true; | ||
196 | } | ||
197 | } | ||
198 | return false; | ||
199 | } | ||
200 | |||
201 | static void ws_cleanup() { | 219 | static void ws_cleanup() { |
202 | swayc_t *op, *ws; | 220 | swayc_t *op, *ws; |
203 | int i = 0, j; | 221 | int i = 0, j; |
@@ -228,8 +246,14 @@ static bool handle_view_created(wlc_handle handle) { | |||
228 | bool return_to_workspace = false; | 246 | bool return_to_workspace = false; |
229 | struct wl_client *client = wlc_view_get_wl_client(handle); | 247 | struct wl_client *client = wlc_view_get_wl_client(handle); |
230 | pid_t pid; | 248 | pid_t pid; |
231 | 249 | struct panel_config *panel_config = NULL; | |
232 | if (client_is_background(client) || client_is_panel(client)) { | 250 | |
251 | panel_config = if_panel_find_config(client); | ||
252 | if (panel_config) { | ||
253 | panel_config->handle = handle; | ||
254 | update_panel_geometry(panel_config); | ||
255 | wlc_view_set_mask(handle, VISIBLE); | ||
256 | wlc_view_set_output(handle, panel_config->output); | ||
233 | return true; | 257 | return true; |
234 | } | 258 | } |
235 | 259 | ||
diff --git a/swaybar/bar.c b/swaybar/bar.c index 6d858f92..4f8063ac 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c | |||
@@ -58,6 +58,37 @@ struct output *new_output(const char *name) { | |||
58 | return output; | 58 | return output; |
59 | } | 59 | } |
60 | 60 | ||
61 | static void mouse_button_notify(struct window *window, int x, int y, uint32_t button) { | ||
62 | sway_log(L_DEBUG, "Mouse button %d clicked at %d %d\n", button, x, y); | ||
63 | |||
64 | struct output *clicked_output = NULL; | ||
65 | for (int i = 0; i < swaybar.outputs->length; i++) { | ||
66 | struct output *output = swaybar.outputs->items[i]; | ||
67 | if (window == output->window) { | ||
68 | clicked_output = output; | ||
69 | break; | ||
70 | } | ||
71 | } | ||
72 | |||
73 | if (!sway_assert(clicked_output != NULL, "Got pointer event for non-existing output")) { | ||
74 | return; | ||
75 | } | ||
76 | |||
77 | double button_x = 0.5; | ||
78 | for (int i = 0; i < clicked_output->workspaces->length; i++) { | ||
79 | struct workspace *workspace = clicked_output->workspaces->items[i]; | ||
80 | int button_width, button_height; | ||
81 | |||
82 | workspace_button_size(window, workspace->name, &button_width, &button_height); | ||
83 | |||
84 | button_x += button_width; | ||
85 | if (x <= button_x) { | ||
86 | ipc_send_workspace_command(workspace->name); | ||
87 | break; | ||
88 | } | ||
89 | } | ||
90 | } | ||
91 | |||
61 | void bar_setup(struct bar *bar, const char *socket_path, const char *bar_id) { | 92 | void bar_setup(struct bar *bar, const char *socket_path, const char *bar_id) { |
62 | /* initialize bar with default values */ | 93 | /* initialize bar with default values */ |
63 | bar_init(bar); | 94 | bar_init(bar); |
@@ -92,6 +123,9 @@ void bar_setup(struct bar *bar, const char *socket_path, const char *bar_id) { | |||
92 | /* set font */ | 123 | /* set font */ |
93 | bar_output->window->font = bar->config->font; | 124 | bar_output->window->font = bar->config->font; |
94 | 125 | ||
126 | /* set font */ | ||
127 | bar_output->window->pointer_input.notify = mouse_button_notify; | ||
128 | |||
95 | /* set window height */ | 129 | /* set window height */ |
96 | set_window_height(bar_output->window, bar->config->height); | 130 | set_window_height(bar_output->window, bar->config->height); |
97 | } | 131 | } |
diff --git a/swaybar/ipc.c b/swaybar/ipc.c index dacee4c2..15f40508 100644 --- a/swaybar/ipc.c +++ b/swaybar/ipc.c | |||
@@ -7,6 +7,15 @@ | |||
7 | #include "bar/config.h" | 7 | #include "bar/config.h" |
8 | #include "bar/ipc.h" | 8 | #include "bar/ipc.h" |
9 | 9 | ||
10 | void ipc_send_workspace_command(const char *workspace_name) { | ||
11 | uint32_t size = strlen("workspace ") + strlen(workspace_name) + 1; | ||
12 | |||
13 | char command[size]; | ||
14 | sprintf(command, "workspace %s", workspace_name); | ||
15 | |||
16 | ipc_single_command(swaybar.ipc_socketfd, IPC_COMMAND, command, &size); | ||
17 | } | ||
18 | |||
10 | static void ipc_parse_config(struct config *config, const char *payload) { | 19 | static void ipc_parse_config(struct config *config, const char *payload) { |
11 | json_object *bar_config = json_tokener_parse(payload); | 20 | json_object *bar_config = json_tokener_parse(payload); |
12 | json_object *tray_output, *mode, *hidden_bar, *position, *status_command; | 21 | json_object *tray_output, *mode, *hidden_bar, *position, *status_command; |
diff --git a/swaybar/render.c b/swaybar/render.c index 273bd4f0..cea36f52 100644 --- a/swaybar/render.c +++ b/swaybar/render.c | |||
@@ -172,7 +172,7 @@ static void render_block(struct window *window, struct config *config, struct st | |||
172 | 172 | ||
173 | } | 173 | } |
174 | 174 | ||
175 | static char *handle_workspace_number(bool strip_num, const char *ws_name) { | 175 | static const char *strip_workspace_name(bool strip_num, const char *ws_name) { |
176 | bool strip = false; | 176 | bool strip = false; |
177 | int i; | 177 | int i; |
178 | 178 | ||
@@ -190,18 +190,23 @@ static char *handle_workspace_number(bool strip_num, const char *ws_name) { | |||
190 | } | 190 | } |
191 | 191 | ||
192 | if (strip) { | 192 | if (strip) { |
193 | return strdup(ws_name + i); | 193 | return ws_name + i; |
194 | } | 194 | } |
195 | 195 | ||
196 | return strdup(ws_name); | 196 | return ws_name; |
197 | } | ||
198 | |||
199 | void workspace_button_size(struct window *window, const char *workspace_name, int *width, int *height) { | ||
200 | const char *stripped_name = strip_workspace_name(swaybar.config->strip_workspace_numbers, workspace_name); | ||
201 | |||
202 | get_text_size(window->cairo, window->font, width, height, false, "%s", stripped_name); | ||
203 | *width += 2 * ws_horizontal_padding; | ||
204 | *height += 2 * ws_vertical_padding; | ||
197 | } | 205 | } |
198 | 206 | ||
199 | static void render_workspace_button(struct window *window, struct config *config, struct workspace *ws, double *x) { | 207 | static void render_workspace_button(struct window *window, struct config *config, struct workspace *ws, double *x) { |
200 | // strip workspace numbers if required | 208 | const char *stripped_name = strip_workspace_name(config->strip_workspace_numbers, ws->name); |
201 | char *name = handle_workspace_number(config->strip_workspace_numbers, ws->name); | ||
202 | 209 | ||
203 | int width, height; | ||
204 | get_text_size(window->cairo, window->font, &width, &height, false, "%s", name); | ||
205 | struct box_colors box_colors; | 210 | struct box_colors box_colors; |
206 | if (ws->urgent) { | 211 | if (ws->urgent) { |
207 | box_colors = config->colors.urgent_workspace; | 212 | box_colors = config->colors.urgent_workspace; |
@@ -213,26 +218,25 @@ static void render_workspace_button(struct window *window, struct config *config | |||
213 | box_colors = config->colors.inactive_workspace; | 218 | box_colors = config->colors.inactive_workspace; |
214 | } | 219 | } |
215 | 220 | ||
221 | int width, height; | ||
222 | workspace_button_size(window, stripped_name, &width, &height); | ||
223 | |||
216 | // background | 224 | // background |
217 | cairo_set_source_u32(window->cairo, box_colors.background); | 225 | cairo_set_source_u32(window->cairo, box_colors.background); |
218 | cairo_rectangle(window->cairo, *x, 1.5, width + ws_horizontal_padding * 2 - 1, | 226 | cairo_rectangle(window->cairo, *x, 1.5, width - 1, height); |
219 | height + ws_vertical_padding * 2); | ||
220 | cairo_fill(window->cairo); | 227 | cairo_fill(window->cairo); |
221 | 228 | ||
222 | // border | 229 | // border |
223 | cairo_set_source_u32(window->cairo, box_colors.border); | 230 | cairo_set_source_u32(window->cairo, box_colors.border); |
224 | cairo_rectangle(window->cairo, *x, 1.5, width + ws_horizontal_padding * 2 - 1, | 231 | cairo_rectangle(window->cairo, *x, 1.5, width - 1, height); |
225 | height + ws_vertical_padding * 2); | ||
226 | cairo_stroke(window->cairo); | 232 | cairo_stroke(window->cairo); |
227 | 233 | ||
228 | // text | 234 | // text |
229 | cairo_set_source_u32(window->cairo, box_colors.text); | 235 | cairo_set_source_u32(window->cairo, box_colors.text); |
230 | cairo_move_to(window->cairo, (int)*x + ws_horizontal_padding, margin); | 236 | cairo_move_to(window->cairo, (int)*x + ws_horizontal_padding, margin); |
231 | pango_printf(window->cairo, window->font, false, "%s", name); | 237 | pango_printf(window->cairo, window->font, false, "%s", stripped_name); |
232 | |||
233 | *x += width + ws_horizontal_padding * 2 + ws_spacing; | ||
234 | 238 | ||
235 | free(name); | 239 | *x += width + ws_spacing; |
236 | } | 240 | } |
237 | 241 | ||
238 | static void render_binding_mode_indicator(struct window *window, struct config *config, double pos) { | 242 | static void render_binding_mode_indicator(struct window *window, struct config *config, double pos) { |
diff --git a/swaybg/main.c b/swaybg/main.c index 4e0cc4b3..fbd0d16b 100644 --- a/swaybg/main.c +++ b/swaybg/main.c | |||
@@ -54,7 +54,6 @@ int main(int argc, const char **argv) { | |||
54 | sway_abort("Failed to create surfaces."); | 54 | sway_abort("Failed to create surfaces."); |
55 | } | 55 | } |
56 | desktop_shell_set_background(registry->desktop_shell, output->output, window->surface); | 56 | desktop_shell_set_background(registry->desktop_shell, output->output, window->surface); |
57 | window_make_shell(window); | ||
58 | list_add(surfaces, window); | 57 | list_add(surfaces, window); |
59 | 58 | ||
60 | #ifdef WITH_GDK_PIXBUF | 59 | #ifdef WITH_GDK_PIXBUF |
diff --git a/wayland/window.c b/wayland/window.c index e055e244..9b6e5b00 100644 --- a/wayland/window.c +++ b/wayland/window.c | |||
@@ -32,8 +32,8 @@ static void pointer_handle_motion(void *data, struct wl_pointer *pointer, | |||
32 | uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w) { | 32 | uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w) { |
33 | struct window *window = data; | 33 | struct window *window = data; |
34 | 34 | ||
35 | window->pointer_input.last_x = sx_w; | 35 | window->pointer_input.last_x = wl_fixed_to_int(sx_w); |
36 | window->pointer_input.last_y = sy_w; | 36 | window->pointer_input.last_y = wl_fixed_to_int(sy_w); |
37 | } | 37 | } |
38 | 38 | ||
39 | static void pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial, | 39 | static void pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial, |