aboutsummaryrefslogtreecommitdiffstats
path: root/swaynag/swaynag.c
diff options
context:
space:
mode:
authorLibravatar Brian Ashworth <bosrsf04@gmail.com>2018-07-30 01:02:50 -0400
committerLibravatar Brian Ashworth <bosrsf04@gmail.com>2018-08-01 22:47:54 -0400
commit0ef3988438c251c84251ef7a2723791856505065 (patch)
tree9b9273ad89656e1244b24ceb2a337387cdf939d6 /swaynag/swaynag.c
parentswaynag: allow more config options (diff)
downloadsway-0ef3988438c251c84251ef7a2723791856505065.tar.gz
sway-0ef3988438c251c84251ef7a2723791856505065.tar.zst
sway-0ef3988438c251c84251ef7a2723791856505065.zip
swaynag: fix hidpi
Diffstat (limited to 'swaynag/swaynag.c')
-rw-r--r--swaynag/swaynag.c120
1 files changed, 73 insertions, 47 deletions
diff --git a/swaynag/swaynag.c b/swaynag/swaynag.c
index e79cd879..22511529 100644
--- a/swaynag/swaynag.c
+++ b/swaynag/swaynag.c
@@ -85,12 +85,34 @@ static struct zwlr_layer_surface_v1_listener layer_surface_listener = {
85 .closed = layer_surface_closed, 85 .closed = layer_surface_closed,
86}; 86};
87 87
88static void surface_enter(void *data, struct wl_surface *surface,
89 struct wl_output *output) {
90 struct swaynag *swaynag = data;
91 struct swaynag_output *swaynag_output;
92 wl_list_for_each(swaynag_output, &swaynag->outputs, link) {
93 if (swaynag_output->wl_output == output) {
94 wlr_log(WLR_DEBUG, "Surface enter on output %s",
95 swaynag_output->name);
96 swaynag->output = swaynag_output;
97 swaynag->scale = swaynag->output->scale;
98 render_frame(swaynag);
99 break;
100 }
101 };
102}
103
104static struct wl_surface_listener surface_listener = {
105 .enter = surface_enter,
106 .leave = nop,
107};
108
88static void wl_pointer_enter(void *data, struct wl_pointer *wl_pointer, 109static void wl_pointer_enter(void *data, struct wl_pointer *wl_pointer,
89 uint32_t serial, struct wl_surface *surface, 110 uint32_t serial, struct wl_surface *surface,
90 wl_fixed_t surface_x, wl_fixed_t surface_y) { 111 wl_fixed_t surface_x, wl_fixed_t surface_y) {
91 struct swaynag *swaynag = data; 112 struct swaynag *swaynag = data;
92 struct swaynag_pointer *pointer = &swaynag->pointer; 113 struct swaynag_pointer *pointer = &swaynag->pointer;
93 wl_surface_set_buffer_scale(pointer->cursor_surface, swaynag->scale); 114 wl_surface_set_buffer_scale(pointer->cursor_surface,
115 swaynag->scale);
94 wl_surface_attach(pointer->cursor_surface, 116 wl_surface_attach(pointer->cursor_surface,
95 wl_cursor_image_get_buffer(pointer->cursor_image), 0, 0); 117 wl_cursor_image_get_buffer(pointer->cursor_image), 0, 0);
96 wl_pointer_set_cursor(wl_pointer, serial, pointer->cursor_surface, 118 wl_pointer_set_cursor(wl_pointer, serial, pointer->cursor_surface,
@@ -141,7 +163,8 @@ static void wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
141 } 163 }
142 164
143 struct swaynag_button button_down = swaynag->details.button_down; 165 struct swaynag_button button_down = swaynag->details.button_down;
144 int bot = swaynag->details.total_lines - swaynag->details.visible_lines; 166 int bot = swaynag->details.total_lines;
167 bot -= swaynag->details.visible_lines;
145 if (x >= button_down.x 168 if (x >= button_down.x
146 && y >= button_down.y 169 && y >= button_down.y
147 && x < button_down.x + button_down.width 170 && x < button_down.x + button_down.width
@@ -206,9 +229,12 @@ const struct wl_seat_listener seat_listener = {
206 229
207static void output_scale(void *data, struct wl_output *output, 230static void output_scale(void *data, struct wl_output *output,
208 int32_t factor) { 231 int32_t factor) {
209 struct swaynag *swaynag = data; 232 struct swaynag_output *swaynag_output = data;
210 swaynag->scale = factor; 233 swaynag_output->scale = factor;
211 render_frame(swaynag); 234 if (swaynag_output->swaynag->output == swaynag_output) {
235 swaynag_output->swaynag->scale = swaynag_output->scale;
236 render_frame(swaynag_output->swaynag);
237 }
212} 238}
213 239
214static struct wl_output_listener output_listener = { 240static struct wl_output_listener output_listener = {
@@ -218,33 +244,19 @@ static struct wl_output_listener output_listener = {
218 .scale = output_scale, 244 .scale = output_scale,
219}; 245};
220 246
221struct output_state {
222 struct wl_output *wl_output;
223 uint32_t wl_name;
224 struct zxdg_output_v1 *xdg_output;
225 struct swaynag *swaynag;
226};
227
228static void xdg_output_handle_name(void *data, 247static void xdg_output_handle_name(void *data,
229 struct zxdg_output_v1 *xdg_output, const char *name) { 248 struct zxdg_output_v1 *xdg_output, const char *name) {
230 struct output_state *state = data; 249 struct swaynag_output *swaynag_output = data;
231 char *outname = state->swaynag->output.name; 250 char *outname = swaynag_output->swaynag->type->output;
232 wlr_log(WLR_DEBUG, "Checking against output %s for %s", name, outname); 251 wlr_log(WLR_DEBUG, "Checking against output %s for %s", name, outname);
233 if (!state->swaynag->output.wl_output && outname && name 252 if (!swaynag_output->swaynag->output && outname && name
234 && strcmp(outname, name) == 0) { 253 && strcmp(outname, name) == 0) {
235 wlr_log(WLR_DEBUG, "Using output %s", name); 254 wlr_log(WLR_DEBUG, "Using output %s", name);
236 state->swaynag->output.wl_output = state->wl_output; 255 swaynag_output->swaynag->output = swaynag_output;
237 state->swaynag->output.wl_name = state->wl_name;
238 wl_output_add_listener(state->swaynag->output.wl_output,
239 &output_listener, state->swaynag);
240 wl_display_roundtrip(state->swaynag->display);
241 zxdg_output_v1_destroy(state->xdg_output);
242 } else {
243 zxdg_output_v1_destroy(state->xdg_output);
244 wl_output_destroy(state->wl_output);
245 } 256 }
246 state->swaynag->querying_outputs--; 257 swaynag_output->name = strdup(name);
247 free(state); 258 zxdg_output_v1_destroy(xdg_output);
259 swaynag_output->swaynag->querying_outputs--;
248} 260}
249 261
250static struct zxdg_output_v1_listener xdg_output_listener = { 262static struct zxdg_output_v1_listener xdg_output_listener = {
@@ -267,18 +279,24 @@ static void handle_global(void *data, struct wl_registry *registry,
267 } else if (strcmp(interface, wl_shm_interface.name) == 0) { 279 } else if (strcmp(interface, wl_shm_interface.name) == 0) {
268 swaynag->shm = wl_registry_bind(registry, name, &wl_shm_interface, 1); 280 swaynag->shm = wl_registry_bind(registry, name, &wl_shm_interface, 1);
269 } else if (strcmp(interface, wl_output_interface.name) == 0) { 281 } else if (strcmp(interface, wl_output_interface.name) == 0) {
270 if (!swaynag->output.wl_output && swaynag->xdg_output_manager) { 282 if (!swaynag->output && swaynag->xdg_output_manager) {
271 swaynag->querying_outputs++; 283 swaynag->querying_outputs++;
272 struct output_state *state = 284 struct swaynag_output *output =
273 calloc(1, sizeof(struct output_state)); 285 calloc(1, sizeof(struct swaynag_output));
274 state->swaynag = swaynag; 286 output->wl_output = wl_registry_bind(registry, name,
275 state->wl_output = wl_registry_bind(registry, name,
276 &wl_output_interface, 3); 287 &wl_output_interface, 3);
277 state->wl_name = name; 288 output->wl_name = name;
278 state->xdg_output = zxdg_output_manager_v1_get_xdg_output( 289 output->scale = 1;
279 swaynag->xdg_output_manager, state->wl_output); 290 output->swaynag = swaynag;
280 zxdg_output_v1_add_listener(state->xdg_output, 291 wl_list_insert(&swaynag->outputs, &output->link);
281 &xdg_output_listener, state); 292 wl_output_add_listener(output->wl_output,
293 &output_listener, output);
294
295 struct zxdg_output_v1 *xdg_output;
296 xdg_output = zxdg_output_manager_v1_get_xdg_output(
297 swaynag->xdg_output_manager, output->wl_output);
298 zxdg_output_v1_add_listener(xdg_output,
299 &xdg_output_listener, output);
282 } 300 }
283 } else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) { 301 } else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) {
284 swaynag->layer_shell = wl_registry_bind( 302 swaynag->layer_shell = wl_registry_bind(
@@ -294,7 +312,7 @@ static void handle_global(void *data, struct wl_registry *registry,
294static void handle_global_remove(void *data, struct wl_registry *registry, 312static void handle_global_remove(void *data, struct wl_registry *registry,
295 uint32_t name) { 313 uint32_t name) {
296 struct swaynag *swaynag = data; 314 struct swaynag *swaynag = data;
297 if (swaynag->output.wl_name == name) { 315 if (swaynag->output->wl_name == name) {
298 swaynag->run_display = false; 316 swaynag->run_display = false;
299 } 317 }
300} 318}
@@ -309,6 +327,7 @@ void swaynag_setup(struct swaynag *swaynag) {
309 assert(swaynag->display); 327 assert(swaynag->display);
310 328
311 swaynag->scale = 1; 329 swaynag->scale = 1;
330 wl_list_init(&swaynag->outputs);
312 331
313 struct wl_registry *registry = wl_display_get_registry(swaynag->display); 332 struct wl_registry *registry = wl_display_get_registry(swaynag->display);
314 wl_registry_add_listener(registry, &registry_listener, swaynag); 333 wl_registry_add_listener(registry, &registry_listener, swaynag);
@@ -319,16 +338,16 @@ void swaynag_setup(struct swaynag *swaynag) {
319 wl_display_roundtrip(swaynag->display); 338 wl_display_roundtrip(swaynag->display);
320 } 339 }
321 340
322 if (!swaynag->output.wl_output && swaynag->output.name) { 341 if (!swaynag->output && swaynag->type->output) {
323 wlr_log(WLR_ERROR, "Output '%s' not found", swaynag->output.name); 342 wlr_log(WLR_ERROR, "Output '%s' not found", swaynag->type->output);
324 swaynag_destroy(swaynag); 343 swaynag_destroy(swaynag);
325 exit(EXIT_FAILURE); 344 exit(EXIT_FAILURE);
326 } 345 }
327 346
328 struct swaynag_pointer *pointer = &swaynag->pointer; 347 struct swaynag_pointer *pointer = &swaynag->pointer;
329 int scale = swaynag->scale < 1 ? 1 : swaynag->scale; 348 int scale = swaynag->output ? swaynag->scale : 1;
330 pointer->cursor_theme = wl_cursor_theme_load( 349 pointer->cursor_theme = wl_cursor_theme_load(NULL, 24 * scale,
331 NULL, 24 * scale, swaynag->shm); 350 swaynag->shm);
332 assert(pointer->cursor_theme); 351 assert(pointer->cursor_theme);
333 struct wl_cursor *cursor = 352 struct wl_cursor *cursor =
334 wl_cursor_theme_get_cursor(pointer->cursor_theme, "left_ptr"); 353 wl_cursor_theme_get_cursor(pointer->cursor_theme, "left_ptr");
@@ -339,8 +358,11 @@ void swaynag_setup(struct swaynag *swaynag) {
339 358
340 swaynag->surface = wl_compositor_create_surface(swaynag->compositor); 359 swaynag->surface = wl_compositor_create_surface(swaynag->compositor);
341 assert(swaynag->surface); 360 assert(swaynag->surface);
361 wl_surface_add_listener(swaynag->surface, &surface_listener, swaynag);
362
342 swaynag->layer_surface = zwlr_layer_shell_v1_get_layer_surface( 363 swaynag->layer_surface = zwlr_layer_shell_v1_get_layer_surface(
343 swaynag->layer_shell, swaynag->surface, swaynag->output.wl_output, 364 swaynag->layer_shell, swaynag->surface,
365 swaynag->output ? swaynag->output->wl_output : NULL,
344 ZWLR_LAYER_SHELL_V1_LAYER_TOP, "swaynag"); 366 ZWLR_LAYER_SHELL_V1_LAYER_TOP, "swaynag");
345 assert(swaynag->layer_surface); 367 assert(swaynag->layer_surface);
346 zwlr_layer_surface_v1_add_listener(swaynag->layer_surface, 368 zwlr_layer_surface_v1_add_listener(swaynag->layer_surface,
@@ -388,10 +410,6 @@ void swaynag_destroy(struct swaynag *swaynag) {
388 wl_surface_destroy(swaynag->surface); 410 wl_surface_destroy(swaynag->surface);
389 } 411 }
390 412
391 if (swaynag->output.wl_output) {
392 wl_output_destroy(swaynag->output.wl_output);
393 }
394
395 if (&swaynag->buffers[0]) { 413 if (&swaynag->buffers[0]) {
396 destroy_buffer(&swaynag->buffers[0]); 414 destroy_buffer(&swaynag->buffers[0]);
397 } 415 }
@@ -400,6 +418,14 @@ void swaynag_destroy(struct swaynag *swaynag) {
400 destroy_buffer(&swaynag->buffers[1]); 418 destroy_buffer(&swaynag->buffers[1]);
401 } 419 }
402 420
421 struct swaynag_output *output, *temp;
422 wl_list_for_each_safe(output, temp, &swaynag->outputs, link) {
423 wl_output_destroy(output->wl_output);
424 free(output->name);
425 wl_list_remove(&output->link);
426 free(output);
427 };
428
403 if (swaynag->compositor) { 429 if (swaynag->compositor) {
404 wl_compositor_destroy(swaynag->compositor); 430 wl_compositor_destroy(swaynag->compositor);
405 } 431 }