rofi 2.0.0
display.c
Go to the documentation of this file.
1
24
25#define G_LOG_DOMAIN "Wayland"
26#pragma GCC diagnostic ignored "-Wunused-variable"
27#pragma GCC diagnostic ignored "-Wunused-parameter"
28
29#include <config.h>
30#include <errno.h>
31#include <fcntl.h>
32#include <locale.h>
33#include <math.h>
34#include <stdint.h>
35#include <sys/mman.h>
36#include <sys/types.h>
37#include <unistd.h>
38
39#include <cairo.h>
40#include <glib.h>
41#include <glib/gstdio.h>
42#include <wayland-client.h>
43#include <wayland-cursor.h>
44#include <xkbcommon/xkbcommon-compose.h>
45#include <xkbcommon/xkbcommon.h>
46
47#include <libgwater-wayland.h>
48
49#include <nkutils-bindings.h>
50
51#include <rofi.h>
52
53#include "input-codes.h"
54#include "keyb.h"
55#include "rofi-types.h"
56#include "settings.h"
57#include "view.h"
58
59#include "display-internal.h"
60#include "display.h"
61#include "wayland-internal.h"
62
63#ifdef HAVE_WAYLAND_CURSOR_SHAPE
64#include "cursor-shape-v1-protocol.h"
65#endif
66#include "keyboard-shortcuts-inhibit-unstable-v1-protocol.h"
67#include "primary-selection-unstable-v1-protocol.h"
68#include "wlr-layer-shell-unstable-v1-protocol.h"
69
70#define wayland_output_get_dpi(output, scale, dimension) \
71 ((output)->current.physical_##dimension > 0 && (scale) > 0 \
72 ? round((double)(output)->current.dimension * 25.4 / (scale) / \
73 (output)->current.physical_##dimension) \
74 : 0)
75
77typedef struct {
79 uint32_t global_name;
80 struct wl_output *output;
81 gchar *name;
82 struct {
83 int32_t x;
84 int32_t y;
85 int32_t width;
86 int32_t height;
87 int32_t physical_width; /* mm */
88 int32_t physical_height; /* mm */
89 int32_t scale;
90 int32_t transform;
91 } current, pending;
93
94typedef struct {
96 struct wl_buffer *buffer;
97 uint8_t *data;
98 gboolean released;
100
110
111static gboolean wayland_display_late_setup(void);
112
115static const cairo_user_data_key_t wayland_cairo_surface_user_data;
116
118 if (!self->to_free) {
119 return;
120 }
121
122 size_t i, count = 0;
123 for (i = 0; i < wayland->buffer_count; ++i) {
124 if ((self->buffers[i].released) && (self->buffers[i].buffer != NULL)) {
125 wl_buffer_destroy(self->buffers[i].buffer);
126 self->buffers[i].buffer = NULL;
127 }
128 if (self->buffers[i].buffer == NULL) {
129 ++count;
130 }
131 }
132
133 if (count < wayland->buffer_count) {
134 return;
135 }
136
137 munmap(self->data, self->size);
138 g_free(self);
139}
140
141static void wayland_buffer_release(void *data, struct wl_buffer *buffer) {
142 wayland_buffer_pool *self = data;
143
144 size_t i;
145 for (i = 0; i < wayland->buffer_count; ++i) {
146 if (self->buffers[i].buffer == buffer) {
147 self->buffers[i].released = TRUE;
148 }
149 }
150
152}
153
154static const struct wl_buffer_listener wayland_buffer_listener = {
156
158 struct wl_shm_pool *wl_pool;
159 struct wl_buffer *buffer;
160 int fd;
161 uint8_t *data;
162 width *= wayland->scale;
163 height *= wayland->scale;
164 int32_t stride;
165 size_t size;
166 size_t pool_size;
167
168 stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
169 if (stride < 0) {
170 g_warning("cairo stride width calculation failure");
171 return NULL;
172 }
173 size = (size_t)stride * height;
174 pool_size = size * wayland->buffer_count;
175
176 gchar filename[PATH_MAX];
177 g_snprintf(filename, PATH_MAX, "%s/rofi-wayland-surface",
178 g_get_user_runtime_dir());
179 fd = g_open(filename, O_CREAT | O_RDWR, 0);
180 g_unlink(filename);
181 if (fd < 0) {
182 g_warning("creating a buffer file for %zu B failed: %s", pool_size,
183 g_strerror(errno));
184 return NULL;
185 }
186 if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) {
187 g_close(fd, NULL);
188 return NULL;
189 }
190 if (ftruncate(fd, pool_size) < 0) {
191 g_close(fd, NULL);
192 return NULL;
193 }
194
195 data = mmap(NULL, pool_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
196 if (data == MAP_FAILED) {
197 g_warning("mmap of size %zu failed: %s", pool_size, g_strerror(errno));
198 close(fd);
199 return NULL;
200 }
201
203 pool = g_new0(wayland_buffer_pool, 1);
204
205 pool->width = width;
206 pool->height = height;
207
208 pool->buffers = g_new0(wayland_buffer, wayland->buffer_count);
209
210 wl_pool = wl_shm_create_pool(wayland->shm, fd, pool_size);
211 size_t i;
212 for (i = 0; i < wayland->buffer_count; ++i) {
213 pool->buffers[i].pool = pool;
214 pool->buffers[i].buffer = wl_shm_pool_create_buffer(
215 wl_pool, size * i, width, height, stride, WL_SHM_FORMAT_ARGB8888);
216 pool->buffers[i].data = data + size * i;
217 pool->buffers[i].released = TRUE;
218 wl_buffer_add_listener(pool->buffers[i].buffer, &wayland_buffer_listener,
219 pool);
220 }
221 wl_shm_pool_destroy(wl_pool);
222 close(fd);
223
224 return pool;
225}
226
228 if (self == NULL) {
229 return;
230 }
231 self->to_free = TRUE;
233}
234
235static void wayland_surface_protocol_enter(void *data,
236 struct wl_surface *wl_surface,
237 struct wl_output *wl_output) {
238 wayland_output *output;
239
240 output = g_hash_table_lookup(wayland->outputs, wl_output);
241 if (output == NULL) {
242 return;
243 }
244
245 if (config.dpi == 0 || config.dpi == 1) {
246 // DPI auto-detect requested.
247 config.dpi = wayland_output_get_dpi(output, output->current.scale, height);
248 g_debug("Auto-detected DPI: %d", config.dpi);
249 }
250
251 wl_surface_set_buffer_scale(wl_surface, output->current.scale);
252
253 if (wayland->scale != output->current.scale) {
254 wayland->scale = output->current.scale;
255
256 // create new buffers with the correct scaled size
258
260 if (state != NULL) {
261 rofi_view_set_size(state, -1, -1);
262 }
263 }
264}
265
266static void wayland_surface_protocol_leave(void *data,
267 struct wl_surface *wl_surface,
268 struct wl_output *wl_output) {}
269
270static const struct wl_surface_listener wayland_surface_interface = {
273};
274
275static void wayland_frame_callback(void *data, struct wl_callback *callback,
276 uint32_t time);
277
278static const struct wl_callback_listener wayland_frame_wl_callback_listener = {
280};
281
282cairo_surface_t *
284 wayland_buffer *buffer = NULL;
285 size_t i;
286 for (i = 0; (buffer == NULL) && (i < wayland->buffer_count); ++i) {
287 buffer = pool->buffers + i;
288 if (!buffer->released) {
289 buffer = NULL;
290 }
291 }
292 if (buffer == NULL) {
293 return NULL;
294 }
295
296 cairo_surface_t *surface;
297
298 surface = cairo_image_surface_create_for_data(
299 buffer->data, CAIRO_FORMAT_ARGB32, pool->width, pool->height,
300 cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, pool->width));
301 cairo_surface_set_user_data(surface, &wayland_cairo_surface_user_data, buffer,
302 NULL);
303 return surface;
304}
305
306void display_surface_commit(cairo_surface_t *surface) {
307 if (surface == NULL || wayland->surface == NULL) {
308 return;
309 }
310
311 wayland_buffer *buffer =
312 cairo_surface_get_user_data(surface, &wayland_cairo_surface_user_data);
313 wayland_buffer_pool *pool = buffer->pool;
314
315 cairo_surface_destroy(surface);
316
317 wl_surface_damage(wayland->surface, 0, 0, pool->width, pool->height);
318 wl_surface_attach(wayland->surface, buffer->buffer, 0, 0);
319 // FIXME: hidpi
320 wl_surface_set_buffer_scale(wayland->surface, wayland->scale);
321 buffer->released = FALSE;
322
323 wl_surface_commit(wayland->surface);
324}
325
326static void wayland_frame_callback(void *data, struct wl_callback *callback,
327 uint32_t timestamp) {
328 if (wayland->frame_cb != NULL) {
329 wl_callback_destroy(wayland->frame_cb);
330 wayland->frame_cb = NULL;
332 }
333 if (wayland->surface != NULL) {
334 wayland->frame_cb = wl_surface_frame(wayland->surface);
335 wl_callback_add_listener(wayland->frame_cb,
337 }
338}
339
340static void wayland_keyboard_keymap(void *data, struct wl_keyboard *keyboard,
341 enum wl_keyboard_keymap_format format,
342 int32_t fd, uint32_t size) {
343 if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
344 close(fd);
345 return;
346 }
347
348 char *str = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
349 if (str == MAP_FAILED) {
350 close(fd);
351 return;
352 }
353
354 struct xkb_keymap *keymap = xkb_keymap_new_from_string(
355 nk_bindings_seat_get_context(wayland->bindings_seat), str,
356 XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
357 if (keymap == NULL) {
358 fprintf(stderr, "Failed to get Keymap for current keyboard device.\n");
359 return;
360 }
361 struct xkb_state *state = xkb_state_new(keymap);
362 if (state == NULL) {
363 fprintf(stderr,
364 "Failed to get state object for current keyboard device.\n");
365 return;
366 }
367
368 nk_bindings_seat_update_keymap(wayland->bindings_seat, keymap, state);
369}
370
371static void wayland_keyboard_enter(void *data, struct wl_keyboard *keyboard,
372 uint32_t serial, struct wl_surface *surface,
373 struct wl_array *keys) {
374 wayland_seat *self = data;
375
376 wayland->last_seat = self;
377 self->serial = serial;
378
379 uint32_t *key, *kend;
380 for (key = keys->data, kend = key + keys->size / sizeof(*key); key < kend;
381 ++key) {
382 nk_bindings_seat_handle_key(wayland->bindings_seat, NULL, *key + 8,
383 NK_BINDINGS_KEY_STATE_PRESSED);
384 }
385}
386
387static void wayland_keyboard_leave(void *data, struct wl_keyboard *keyboard,
388 uint32_t serial,
389 struct wl_surface *surface) {
390 wayland_seat *self = data;
391 // TODO?
392}
393
394static gboolean wayland_key_repeat(void *data) {
395 wayland_seat *self = data;
396
397 if (self->repeat.key == 0) {
398 self->repeat.source = NULL;
399 return G_SOURCE_REMOVE;
400 }
401
402 char *text = nk_bindings_seat_handle_key(wayland->bindings_seat, NULL,
403 self->repeat.key,
404 NK_BINDINGS_KEY_STATE_PRESS);
405
407 if (state == NULL) {
408 return G_SOURCE_REMOVE;
409 }
410
411 if (text != NULL) {
412 rofi_view_handle_text(state, text);
413 }
414
416
417 return G_SOURCE_CONTINUE;
418}
419
420static gboolean wayland_key_repeat_delay(void *data) {
421 wayland_seat *self = data;
422
423 if (self->repeat.key == 0) {
424 return FALSE;
425 }
426
427 char *text = nk_bindings_seat_handle_key(wayland->bindings_seat, NULL,
428 self->repeat.key,
429 NK_BINDINGS_KEY_STATE_PRESS);
430
432 if (state == NULL) {
433 return G_SOURCE_REMOVE;
434 }
435
436 if (text != NULL) {
437 rofi_view_handle_text(state, text);
438 }
439
440 guint repeat_wait_ms = 30;
441 if (self->repeat.rate != 0) {
442 repeat_wait_ms = 1000 / self->repeat.rate;
443 }
444 guint source_id = g_timeout_add(repeat_wait_ms, wayland_key_repeat, data);
445 self->repeat.source = g_main_context_find_source_by_id(NULL, source_id);
446
448
449 return G_SOURCE_REMOVE;
450}
451
452static void wayland_keyboard_key(void *data, struct wl_keyboard *keyboard,
453 uint32_t serial, uint32_t time, uint32_t key,
454 enum wl_keyboard_key_state kstate) {
456 wayland_seat *self = data;
457
458 wayland->last_seat = self;
459 self->serial = serial;
460
461 xkb_keycode_t keycode = key + 8;
462 if (kstate == WL_KEYBOARD_KEY_STATE_RELEASED) {
463 if (keycode == self->repeat.key) {
464 self->repeat.key = 0;
465 if (self->repeat.source != NULL) {
466 g_source_destroy(self->repeat.source);
467 self->repeat.source = NULL;
468 }
469 }
470 nk_bindings_seat_handle_key(wayland->bindings_seat, NULL, keycode,
471 NK_BINDINGS_KEY_STATE_RELEASE);
472 } else if (kstate == WL_KEYBOARD_KEY_STATE_PRESSED) {
473 gchar *text = nk_bindings_seat_handle_key(
474 wayland->bindings_seat, NULL, keycode, NK_BINDINGS_KEY_STATE_PRESS);
475
476 if (self->repeat.source != NULL) {
477 g_source_destroy(self->repeat.source);
478 self->repeat.source = NULL;
479 }
480
481 if (state != NULL) {
482 if (text != NULL) {
483 rofi_view_handle_text(state, text);
484 }
485 self->repeat.key = keycode;
486 guint source_id =
487 g_timeout_add(self->repeat.delay, wayland_key_repeat_delay, data);
488 self->repeat.source = g_main_context_find_source_by_id(NULL, source_id);
489 }
490 }
491
492 if (state != NULL) {
494 }
495}
496
497static void wayland_keyboard_modifiers(void *data, struct wl_keyboard *keyboard,
498 uint32_t serial, uint32_t mods_depressed,
499 uint32_t mods_latched,
500 uint32_t mods_locked, uint32_t group) {
501 wayland_seat *self = data;
502 nk_bindings_seat_update_mask(wayland->bindings_seat, NULL, mods_depressed,
503 mods_latched, mods_locked, 0, 0, group);
504
506 if (state != NULL) {
508 }
509}
510
511static void wayland_keyboard_repeat_info(void *data,
512 struct wl_keyboard *keyboard,
513 int32_t rate, int32_t delay) {
514 wayland_seat *self = data;
515 self->repeat.key = 0;
516 self->repeat.rate = rate;
517 self->repeat.delay = delay;
518 if (self->repeat.source != NULL) {
519 g_source_destroy(self->repeat.source);
520 self->repeat.source = NULL;
521 }
522}
523
524static const struct wl_keyboard_listener wayland_keyboard_listener = {
525 .keymap = wayland_keyboard_keymap,
526 .enter = wayland_keyboard_enter,
527 .leave = wayland_keyboard_leave,
529 .modifiers = wayland_keyboard_modifiers,
530 .repeat_info = wayland_keyboard_repeat_info,
531};
532
533static gboolean wayland_cursor_reload_theme(guint scale);
534
535static void wayland_cursor_set_image(int i) {
536 struct wl_buffer *buffer;
537 struct wl_cursor_image *image;
538 image = wayland->cursor.cursor->images[i];
539
540 wayland->cursor.image = image;
541 buffer = wl_cursor_image_get_buffer(wayland->cursor.image);
542 wl_surface_set_buffer_scale(wayland->cursor.surface, wayland->scale);
543 wl_surface_attach(wayland->cursor.surface, buffer, 0, 0);
544 wl_surface_damage(wayland->cursor.surface, 0, 0, wayland->cursor.image->width,
545 wayland->cursor.image->height);
546 wl_surface_commit(wayland->cursor.surface);
547}
548
549static void wayland_cursor_frame_callback(void *data,
550 struct wl_callback *callback,
551 uint32_t time);
552
553static const struct wl_callback_listener
557
558static void wayland_cursor_frame_callback(void *data,
559 struct wl_callback *callback,
560 uint32_t time) {
561 int i;
562
563 if (wayland->cursor.frame_cb != NULL) {
564 wl_callback_destroy(wayland->cursor.frame_cb);
565 }
566 wayland->cursor.frame_cb = wl_surface_frame(wayland->cursor.surface);
567 wl_callback_add_listener(wayland->cursor.frame_cb,
569
570 i = wl_cursor_frame(wayland->cursor.cursor, time);
572}
573
576
577 if (state == NULL) {
578 return;
579 }
580
581 if (self->motion.x > -1 || self->motion.y > -1) {
582 rofi_view_handle_mouse_motion(state, self->motion.x, self->motion.y,
583 config.hover_select);
584 self->motion.x = -1;
585 self->motion.y = -1;
586 }
587
588 NkBindingsMouseButton button = -1;
589 switch (self->button.button) {
590 case BTN_LEFT:
591 button = NK_BINDINGS_MOUSE_BUTTON_PRIMARY;
592 break;
593 case BTN_RIGHT:
594 button = NK_BINDINGS_MOUSE_BUTTON_SECONDARY;
595 break;
596 case BTN_MIDDLE:
597 button = NK_BINDINGS_MOUSE_BUTTON_MIDDLE;
598 break;
599 }
600
601 if (self->button.button > 0) {
602 if (self->button.pressed) {
603 rofi_view_handle_mouse_motion(state, self->button.x, self->button.y,
604 FALSE);
605 nk_bindings_seat_handle_button(wayland->bindings_seat, NULL, button,
606 NK_BINDINGS_BUTTON_STATE_PRESS,
607 self->button.time);
608 } else {
609 nk_bindings_seat_handle_button(wayland->bindings_seat, NULL, button,
610 NK_BINDINGS_BUTTON_STATE_RELEASE,
611 self->button.time);
612 }
613 self->button.button = 0;
614 }
615
616 if (self->axis_source == WL_POINTER_AXIS_SOURCE_FINGER ||
617 self->axis_source == WL_POINTER_AXIS_SOURCE_CONTINUOUS) {
618 self->wheel.vertical += 20 * self->wheel_continuous.vertical;
619 self->wheel.horizontal += 20 * self->wheel_continuous.horizontal;
620 }
621
622 if (abs(self->wheel.vertical) >= 120) {
623 gint v120 = self->wheel.vertical;
624 nk_bindings_seat_handle_scroll(wayland->bindings_seat, NULL,
625 NK_BINDINGS_SCROLL_AXIS_VERTICAL,
626 v120 / 120);
627 if (v120 > 0) {
628 self->wheel.vertical = v120 % 120;
629 } else {
630 self->wheel.vertical = -((-v120) % 120);
631 }
632 }
633
634 if (abs(self->wheel.horizontal) >= 120) {
635 gint v120 = self->wheel.horizontal;
636 nk_bindings_seat_handle_scroll(wayland->bindings_seat, NULL,
637 NK_BINDINGS_SCROLL_AXIS_HORIZONTAL,
638 v120 / 120);
639 if (v120 > 0) {
640 self->wheel.horizontal = v120 % 120;
641 } else {
642 self->wheel.horizontal = -((-v120) % 120);
643 }
644 }
645
646 self->axis_source = 0;
647 self->wheel_continuous.vertical = 0;
649
651}
652
653static struct wl_cursor *
654rofi_cursor_type_to_wl_cursor(struct wl_cursor_theme *theme,
655 RofiCursorType type) {
656 static const char *const default_names[] = {
657 "default", "left_ptr", "top_left_arrow", "left-arrow", NULL};
658 static const char *const pointer_names[] = {"pointer", "hand1", NULL};
659 static const char *const text_names[] = {"text", "xterm", NULL};
660
661 const char *const *name;
662 struct wl_cursor *cursor = NULL;
663
664 switch (type) {
666 name = pointer_names;
667 break;
668 case ROFI_CURSOR_TEXT:
669 name = text_names;
670 break;
671 default:
672 name = default_names;
673 break;
674 }
675 for (; cursor == NULL && *name != NULL; ++name) {
676 cursor = wl_cursor_theme_get_cursor(theme, *name);
677 }
678 return cursor;
679}
680
681#ifdef HAVE_WAYLAND_CURSOR_SHAPE
682static enum wp_cursor_shape_device_v1_shape
683rofi_cursor_type_to_wp_cursor_shape(RofiCursorType type) {
684 switch (type) {
686 return WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_POINTER;
687 case ROFI_CURSOR_TEXT:
688 return WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_TEXT;
689 default:
690 return WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_DEFAULT;
691 }
692}
693#endif
694
696#ifdef HAVE_WAYLAND_CURSOR_SHAPE
697 if (seat->cursor_shape_device != NULL) {
698 wp_cursor_shape_device_v1_set_shape(
699 seat->cursor_shape_device, seat->pointer_serial,
700 rofi_cursor_type_to_wp_cursor_shape(wayland->cursor.type));
701 return;
702 } else if (wayland->cursor.theme == NULL) {
703 // cursor-shape-v1 is available, but the seat haven't seen a pointer yet
704 return;
705 }
706#endif
707
708 if (wayland->cursor.surface == NULL) {
709 wayland->cursor.surface = wl_compositor_create_surface(wayland->compositor);
710 }
711
712 if (wayland->cursor.cursor->image_count < 2) {
714 } else {
715 wayland_cursor_frame_callback(wayland, wayland->cursor.frame_cb, 0);
716 }
717
718 wl_pointer_set_cursor(
719 seat->pointer, seat->pointer_serial, wayland->cursor.surface,
720 wayland->cursor.image->hotspot_x / wayland->cursor.scale,
721 wayland->cursor.image->hotspot_y / wayland->cursor.scale);
722}
723
724static void wayland_pointer_enter(void *data, struct wl_pointer *pointer,
725 uint32_t serial, struct wl_surface *surface,
726 wl_fixed_t x, wl_fixed_t y) {
727 wayland_seat *self = data;
728
729 self->pointer_serial = serial;
730
731#ifdef HAVE_WAYLAND_CURSOR_SHAPE
732 if (wayland->cursor_shape_manager != NULL) {
733 if (self->cursor_shape_device == NULL) {
734 self->cursor_shape_device = wp_cursor_shape_manager_v1_get_pointer(
735 wayland->cursor_shape_manager, pointer);
736 }
737 } else
738#endif
740 return;
741 }
742
744}
745
747 wayland_seat *seat;
748 GHashTableIter iter;
749 struct wl_cursor *cursor;
750
751 if (wayland->cursor.type == type) {
752 return;
753 }
754 wayland->cursor.type = type;
755
756#ifdef HAVE_WAYLAND_CURSOR_SHAPE
757 if (wayland->cursor_shape_manager == NULL)
758#endif
759 {
760 if (wayland->cursor.theme == NULL) {
761 return;
762 }
763
764 cursor = rofi_cursor_type_to_wl_cursor(wayland->cursor.theme, type);
765 if (cursor == NULL) {
766 g_info("Failed to load cursor type %d", type);
767 return;
768 }
769 wayland->cursor.cursor = cursor;
770 }
771
772 g_hash_table_iter_init(&iter, wayland->seats);
773 while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&seat)) {
774 if (seat->pointer != NULL) {
776 }
777 }
778}
779
780static void wayland_pointer_leave(void *data, struct wl_pointer *pointer,
781 uint32_t serial, struct wl_surface *surface) {
782 wayland_seat *self = data;
783
784 if (wayland->cursor.frame_cb != NULL) {
785 wl_callback_destroy(wayland->cursor.frame_cb);
786 wayland->cursor.frame_cb = NULL;
787 }
788}
789
790static void wayland_pointer_motion(void *data, struct wl_pointer *pointer,
791 uint32_t time, wl_fixed_t x, wl_fixed_t y) {
792 wayland_seat *self = data;
793
794 self->button.x = wl_fixed_to_int(x);
795 self->button.y = wl_fixed_to_int(y);
796 self->motion.x = wl_fixed_to_int(x);
797 self->motion.y = wl_fixed_to_int(y);
798 self->motion.time = time;
799}
800
801static void wayland_pointer_button(void *data, struct wl_pointer *pointer,
802 uint32_t serial, uint32_t time,
803 uint32_t button,
804 enum wl_pointer_button_state state) {
805 wayland_seat *self = data;
806
807 wayland->last_seat = self;
808 self->serial = serial;
809
810 self->button.time = time;
811 self->button.pressed = (state == WL_POINTER_BUTTON_STATE_PRESSED);
812 self->button.button = button;
813}
814
815static void wayland_pointer_axis(void *data, struct wl_pointer *pointer,
816 uint32_t time, enum wl_pointer_axis axis,
817 wl_fixed_t value) {
818 wayland_seat *self = data;
819
820 switch (axis) {
821 case WL_POINTER_AXIS_VERTICAL_SCROLL:
822 self->wheel_continuous.vertical += wl_fixed_to_double(value);
823 break;
824 case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
825 self->wheel_continuous.horizontal += wl_fixed_to_double(value);
826 break;
827 }
828}
829
830static void wayland_pointer_frame(void *data, struct wl_pointer *pointer) {
831 wayland_seat *self = data;
833}
834
835static void
836wayland_pointer_axis_source(void *data, struct wl_pointer *pointer,
837 enum wl_pointer_axis_source axis_source) {
838
839 wayland_seat *self = data;
840 self->axis_source = axis_source;
841}
842
843static void wayland_pointer_axis_stop(void *data, struct wl_pointer *pointer,
844 uint32_t time,
845 enum wl_pointer_axis axis) {}
846
847static void wayland_pointer_axis_discrete(void *data,
848 struct wl_pointer *pointer,
849 enum wl_pointer_axis axis,
850 int32_t discrete) {
851 wayland_seat *self = data;
852
853 // values are multiplied by 120 for compatibility with the
854 // new high-resolution events
855 switch (axis) {
856 case WL_POINTER_AXIS_VERTICAL_SCROLL:
857 self->wheel.vertical += discrete * 120;
858 break;
859 case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
860 self->wheel.horizontal += discrete * 120;
861 break;
862 }
863}
864
865#ifdef WL_POINTER_AXIS_VALUE120_SINCE_VERSION
866static void wayland_pointer_axis120(void *data, struct wl_pointer *wl_pointer,
867 enum wl_pointer_axis axis,
868 int32_t value120) {
869 wayland_seat *self = data;
870
871 switch (axis) {
872 case WL_POINTER_AXIS_VERTICAL_SCROLL:
873 self->wheel.vertical += value120;
874 break;
875 case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
876 self->wheel.horizontal += value120;
877 break;
878 }
879}
880#endif
881
882static const struct wl_pointer_listener wayland_pointer_listener = {
883 .enter = wayland_pointer_enter,
884 .leave = wayland_pointer_leave,
885 .motion = wayland_pointer_motion,
886 .button = wayland_pointer_button,
887 .axis = wayland_pointer_axis,
888 .frame = wayland_pointer_frame,
889 .axis_source = wayland_pointer_axis_source,
890 .axis_stop = wayland_pointer_axis_stop,
891#ifdef WL_POINTER_AXIS_VALUE120_SINCE_VERSION
892 .axis_value120 = wayland_pointer_axis120,
893#endif
894 .axis_discrete = wayland_pointer_axis_discrete,
895};
896
898 if (self->keyboard == NULL) {
899 return;
900 }
901
902 wl_keyboard_release(self->keyboard);
903
904 self->repeat.key = 0;
905 if (self->repeat.source != NULL) {
906 g_source_destroy(self->repeat.source);
907 self->repeat.source = NULL;
908 }
909
910 self->keyboard = NULL;
911}
912
913#define CLIPBOARD_READ_INCREMENT 1024
914
922
923static gboolean clipboard_read_glib_callback(GIOChannel *channel,
924 GIOCondition condition,
925 gpointer opaque) {
926 struct clipboard_read_info *info = opaque;
927 gsize read;
928
929 GIOStatus status =
930 g_io_channel_read_chars(channel, info->buffer + info->size,
931 CLIPBOARD_READ_INCREMENT, &read, NULL);
932 switch (status) {
933 case G_IO_STATUS_AGAIN:
934 return TRUE;
935
936 case G_IO_STATUS_NORMAL: {
937 info->size += read;
938 info->buffer =
939 g_realloc(info->buffer, info->size + CLIPBOARD_READ_INCREMENT);
940 if (!info->buffer) {
941 g_io_channel_shutdown(channel, FALSE, NULL);
942 g_io_channel_unref(channel);
943 close(info->fd);
944 g_free(info);
945 return FALSE;
946 }
947 return TRUE;
948 }
949
950 default:
951 info->buffer[info->size] = '\0';
952 if (status == G_IO_STATUS_EOF) {
953 info->callback(info->buffer, info->user_data);
954 } else { // G_IO_STATUS_ERROR
955 g_warning("Could not read data from clipboard");
956 g_free(info->buffer);
957 }
958 g_io_channel_shutdown(channel, FALSE, NULL);
959 g_io_channel_unref(channel);
960 close(info->fd);
961 g_free(info);
962 return FALSE;
963 }
964}
965
967 void *user_data) {
968 GIOChannel *channel = g_io_channel_unix_new(fd);
969
970 struct clipboard_read_info *info = g_malloc(sizeof *info);
971 if (info == NULL) {
972 g_io_channel_unref(channel);
973 close(fd);
974 return FALSE;
975 }
976
977 info->fd = fd;
978 info->size = 0;
979 info->callback = callback;
980 info->user_data = user_data;
981 info->buffer = g_malloc(CLIPBOARD_READ_INCREMENT);
982
983 if (info->buffer == NULL) {
984 g_io_channel_unref(channel);
985 close(info->fd);
986 g_free(info);
987 return FALSE;
988 }
989
990 g_io_add_watch(channel, G_IO_IN | G_IO_HUP | G_IO_ERR,
992
993 return TRUE;
994}
995
996static void data_offer_handle_offer(void *data, struct wl_data_offer *offer,
997 const char *mime_type) {}
998
1000 void *data, struct wl_data_offer *wl_data_offer, uint32_t source_actions) {}
1001
1002static void data_offer_handle_action(void *data,
1003 struct wl_data_offer *wl_data_offer,
1004 uint32_t dnd_action) {}
1005
1006static const struct wl_data_offer_listener data_offer_listener = {
1007 .offer = data_offer_handle_offer,
1008 .source_actions = data_offer_handle_source_actions,
1009 .action = data_offer_handle_action,
1010};
1011
1012static void data_device_handle_data_offer(void *data,
1013 struct wl_data_device *data_device,
1014 struct wl_data_offer *offer) {
1015 wl_data_offer_add_listener(offer, &data_offer_listener, NULL);
1016}
1017
1018static void data_device_handle_enter(void *data,
1019 struct wl_data_device *wl_data_device,
1020 uint32_t serial,
1021 struct wl_surface *surface, wl_fixed_t x,
1022 wl_fixed_t y, struct wl_data_offer *id) {}
1023
1024static void data_device_handle_leave(void *data,
1025 struct wl_data_device *wl_data_device) {}
1026
1027static void data_device_handle_motion(void *data,
1028 struct wl_data_device *wl_data_device,
1029 uint32_t time, wl_fixed_t x,
1030 wl_fixed_t y) {}
1031
1032static void data_device_handle_drop(void *data,
1033 struct wl_data_device *wl_data_device) {}
1034
1036 void *offer) {
1037 clipboard_data *clipboard = &wayland->clipboards[cb_type];
1038
1039 if (clipboard->offer != NULL) {
1040 if (cb_type == CLIPBOARD_DEFAULT) {
1041 wl_data_offer_destroy(clipboard->offer);
1042 } else {
1043 zwp_primary_selection_offer_v1_destroy(clipboard->offer);
1044 }
1045 }
1046 clipboard->offer = offer;
1047}
1048
1049static void data_device_handle_selection(void *data,
1050 struct wl_data_device *data_device,
1051 struct wl_data_offer *offer) {
1053}
1054
1055static const struct wl_data_device_listener data_device_listener = {
1056 .data_offer = data_device_handle_data_offer,
1057 .enter = data_device_handle_enter,
1058 .leave = data_device_handle_leave,
1059 .motion = data_device_handle_motion,
1061 .selection = data_device_handle_selection,
1062};
1063
1064static void
1066 struct zwp_primary_selection_offer_v1 *offer,
1067 const char *mime_type) {}
1068
1069static const struct zwp_primary_selection_offer_v1_listener
1073
1075 void *data, struct zwp_primary_selection_device_v1 *data_device,
1076 struct zwp_primary_selection_offer_v1 *offer) {
1077 zwp_primary_selection_offer_v1_add_listener(
1078 offer, &primary_selection_offer_listener, NULL);
1079}
1080
1082 void *data, struct zwp_primary_selection_device_v1 *data_device,
1083 struct zwp_primary_selection_offer_v1 *offer) {
1085}
1086
1087static const struct zwp_primary_selection_device_v1_listener
1092
1094 if (self->pointer == NULL) {
1095 return;
1096 }
1097
1098#ifdef HAVE_WAYLAND_CURSOR_SHAPE
1099 if (self->cursor_shape_device != NULL) {
1100 wp_cursor_shape_device_v1_destroy(self->cursor_shape_device);
1101 self->cursor_shape_device = NULL;
1102 }
1103#endif
1104
1105 wl_pointer_release(self->pointer);
1106
1107 self->pointer = NULL;
1108}
1109
1113
1114 wl_seat_release(self->seat);
1115
1116 g_hash_table_remove(wayland->seats, self->seat);
1117
1118 g_free(self);
1119}
1120
1121static void wayland_seat_capabilities(void *data, struct wl_seat *seat,
1122 uint32_t capabilities) {
1123 wayland_seat *self = data;
1124
1125 if ((capabilities & WL_SEAT_CAPABILITY_KEYBOARD) &&
1126 (self->keyboard == NULL)) {
1127 self->keyboard = wl_seat_get_keyboard(self->seat);
1128 wl_keyboard_add_listener(self->keyboard, &wayland_keyboard_listener, self);
1129 } else if ((!(capabilities & WL_SEAT_CAPABILITY_POINTER)) &&
1130 (self->keyboard != NULL)) {
1132 }
1133
1134 if ((capabilities & WL_SEAT_CAPABILITY_POINTER) && (self->pointer == NULL)) {
1135 self->pointer = wl_seat_get_pointer(self->seat);
1136 wl_pointer_add_listener(self->pointer, &wayland_pointer_listener, self);
1137 } else if ((!(capabilities & WL_SEAT_CAPABILITY_POINTER)) &&
1138 (self->pointer != NULL)) {
1140 }
1141
1142 if (wayland->data_device_manager != NULL) {
1143 self->data_device = wl_data_device_manager_get_data_device(
1144 wayland->data_device_manager, seat);
1145 wl_data_device_add_listener(self->data_device, &data_device_listener, NULL);
1146 }
1147
1148 if (wayland->primary_selection_device_manager != NULL) {
1150 zwp_primary_selection_device_manager_v1_get_device(
1151 wayland->primary_selection_device_manager, seat);
1152 zwp_primary_selection_device_v1_add_listener(
1154 NULL);
1155 }
1156}
1157
1158static void wayland_seat_name(void *data, struct wl_seat *seat,
1159 const char *name) {
1160 wayland_seat *self = data;
1161
1162 if (self->name != NULL) {
1163 g_hash_table_remove(wayland->seats_by_name, self->name);
1164 }
1165 self->name = g_strdup(name);
1166 g_hash_table_insert(wayland->seats_by_name, self->name, self);
1167}
1168
1169static const struct wl_seat_listener wayland_seat_listener = {
1170 .capabilities = wayland_seat_capabilities,
1171 .name = wayland_seat_name,
1172};
1173
1175 g_debug("Output release: %s", self->name);
1176
1177 if (wl_output_get_version(self->output) >= WL_OUTPUT_RELEASE_SINCE_VERSION) {
1178 wl_output_release(self->output);
1179 } else {
1180 wl_output_destroy(self->output);
1181 }
1182
1183 g_hash_table_remove(wayland->outputs, self->output);
1184
1185 g_free(self->name);
1186 g_free(self);
1187}
1188
1189static wayland_output *wayland_output_by_name(const char *name) {
1190#ifdef WL_OUTPUT_NAME_SINCE_VERSION
1191 GHashTableIter iter;
1192 wayland_output *output;
1193
1194 g_debug("Monitor lookup by name : %s", name);
1195
1196 g_hash_table_iter_init(&iter, wayland->outputs);
1197 while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&output)) {
1198 if (g_strcmp0(output->name, name) == 0) {
1199 return output;
1200 }
1201 }
1202#endif
1203 g_debug("Monitor lookup by name failed: %s", name);
1204
1205 return NULL;
1206}
1208 double retv = -1.0;
1209 if ( wayland == 0 ) {
1210 return -1.0;
1211 }
1212 gsize noutputs = g_hash_table_size(wayland->outputs);
1213 if ( noutputs == 1) {
1214 GHashTableIter iter;
1215 wayland_output *output;
1216 g_hash_table_iter_init(&iter, wayland->outputs);
1217 if (g_hash_table_iter_next(&iter, NULL, (gpointer *)&output)) {
1218 return wayland_output_get_dpi(output, output->current.scale, height);
1219 }
1220 } else if (noutputs > 1 && config.monitor != NULL ) {
1221 wayland_output *output = wayland_output_by_name(config.monitor);
1222 if (output != NULL) {
1223 return wayland_output_get_dpi(output, output->current.scale, height);
1224 }
1225 }
1226 return retv;
1227}
1228
1229static void wayland_output_done(void *data, struct wl_output *output) {
1230 wayland_output *self = data;
1231
1232 self->current = self->pending;
1233
1234 g_debug("Output %s: %" PRIi32 "x%" PRIi32 " (%" PRIi32 "x%" PRIi32 "mm)"
1235 " position %" PRIi32 "x%" PRIi32 " scale %" PRIi32
1236 " transform %" PRIi32,
1237 self->name ? self->name : "Unknown", self->current.width,
1238 self->current.height, self->current.physical_width,
1239 self->current.physical_height, self->current.x, self->current.y,
1240 self->current.scale, self->current.transform);
1241}
1242
1243static void wayland_output_geometry(void *data, struct wl_output *output,
1244 int32_t x, int32_t y, int32_t width,
1245 int32_t height, int32_t subpixel,
1246 const char *make, const char *model,
1247 int32_t transform) {
1248 wayland_output *self = data;
1249
1250 self->pending.x = x;
1251 self->pending.y = y;
1252 self->pending.physical_width = width;
1253 self->pending.physical_height = height;
1254 self->pending.transform = transform;
1255}
1256
1257static void wayland_output_mode(void *data, struct wl_output *output,
1258 enum wl_output_mode flags, int32_t width,
1259 int32_t height, int32_t refresh) {
1260 if (flags & WL_OUTPUT_MODE_CURRENT) {
1261 wayland_output *self = data;
1262 self->pending.width = width;
1263 self->pending.height = height;
1264 }
1265}
1266
1267static void wayland_output_scale(void *data, struct wl_output *output,
1268 int32_t scale) {
1269 wayland_output *self = data;
1270
1271 self->pending.scale = scale;
1272}
1273
1274#ifdef WL_OUTPUT_NAME_SINCE_VERSION
1275static void wayland_output_name(void *data, struct wl_output *output,
1276 const char *name) {
1277 wayland_output *self = data;
1278
1279 g_free(self->name);
1280 self->name = g_strdup(name);
1281}
1282#endif
1283
1284#ifdef WL_OUTPUT_DESCRIPTION_SINCE_VERSION
1285static void wayland_output_description(void *data, struct wl_output *output,
1286 const char *name) {}
1287#endif
1288
1289static const struct wl_output_listener wayland_output_listener = {
1290 .geometry = wayland_output_geometry,
1291 .mode = wayland_output_mode,
1292 .scale = wayland_output_scale,
1293 .done = wayland_output_done,
1294#ifdef WL_OUTPUT_NAME_SINCE_VERSION
1295 .name = wayland_output_name,
1296#endif
1297#ifdef WL_OUTPUT_DESCRIPTION_SINCE_VERSION
1298 .description = wayland_output_description,
1299#endif
1300};
1301
1302static void wayland_registry_handle_global(void *data,
1303 struct wl_registry *registry,
1304 uint32_t name, const char *interface,
1305 uint32_t version) {
1306 g_debug("wayland registry: interface %s", interface);
1307
1308 if (g_strcmp0(interface, wl_compositor_interface.name) == 0) {
1309 wayland->global_names[WAYLAND_GLOBAL_COMPOSITOR] = name;
1310 wayland->compositor =
1311 wl_registry_bind(registry, name, &wl_compositor_interface,
1312 MIN(version, WL_COMPOSITOR_INTERFACE_VERSION));
1313 } else if (g_strcmp0(interface, zwlr_layer_shell_v1_interface.name) == 0) {
1314 wayland->global_names[WAYLAND_GLOBAL_LAYER_SHELL] = name;
1315 wayland->layer_shell =
1316 wl_registry_bind(registry, name, &zwlr_layer_shell_v1_interface,
1317 MIN(version, WL_LAYER_SHELL_INTERFACE_VERSION));
1318 } else if (g_strcmp0(
1319 interface,
1320 zwp_keyboard_shortcuts_inhibit_manager_v1_interface.name) ==
1321 0) {
1323 wayland->kb_shortcuts_inhibit_manager = wl_registry_bind(
1324 registry, name, &zwp_keyboard_shortcuts_inhibit_manager_v1_interface,
1326 } else if (g_strcmp0(interface, wl_shm_interface.name) == 0) {
1327 wayland->global_names[WAYLAND_GLOBAL_SHM] = name;
1328 wayland->shm = wl_registry_bind(registry, name, &wl_shm_interface,
1329 MIN(version, WL_SHM_INTERFACE_VERSION));
1330 } else if (g_strcmp0(interface, wl_seat_interface.name) == 0) {
1331 if (version < WL_SEAT_INTERFACE_MIN_VERSION) {
1332 g_error("Minimum version of wayland seat interface is %u, got %u",
1334 return;
1335 }
1336 version = MIN(version, WL_SEAT_INTERFACE_MAX_VERSION);
1337
1338 wayland_seat *seat = g_new0(wayland_seat, 1);
1339 seat->context = wayland;
1340 seat->global_name = name;
1341 seat->seat = wl_registry_bind(registry, name, &wl_seat_interface, version);
1342 g_hash_table_insert(wayland->seats, seat->seat, seat);
1343
1344 wl_seat_add_listener(seat->seat, &wayland_seat_listener, seat);
1345 } else if (g_strcmp0(interface, wl_output_interface.name) == 0) {
1346 if (version < WL_OUTPUT_INTERFACE_MIN_VERSION) {
1347 g_error("Minimum version of wayland output interface is %u, got %u",
1349 return;
1350 }
1351 version = MIN(version, WL_OUTPUT_INTERFACE_MAX_VERSION);
1352
1353 wayland_output *output = g_new0(wayland_output, 1);
1354 output->context = wayland;
1355 output->global_name = name;
1356 output->output =
1357 wl_registry_bind(registry, name, &wl_output_interface, version);
1358 output->pending.scale = 1;
1359 output->current = output->pending;
1360
1361 g_hash_table_insert(wayland->outputs, output->output, output);
1362
1363 wl_output_add_listener(output->output, &wayland_output_listener, output);
1364 } else if (strcmp(interface, wl_data_device_manager_interface.name) == 0) {
1365 wayland->data_device_manager =
1366 wl_registry_bind(registry, name, &wl_data_device_manager_interface, 3);
1367 } else if (strcmp(interface,
1368 zwp_primary_selection_device_manager_v1_interface.name) ==
1369 0) {
1370 wayland->primary_selection_device_manager = wl_registry_bind(
1371 registry, name, &zwp_primary_selection_device_manager_v1_interface, 1);
1372 }
1373#ifdef HAVE_WAYLAND_CURSOR_SHAPE
1374 else if (strcmp(interface, wp_cursor_shape_manager_v1_interface.name) == 0) {
1375 wayland->global_names[WAYLAND_GLOBAL_CURSOR_SHAPE] = name;
1376 wayland->cursor_shape_manager = wl_registry_bind(
1377 registry, name, &wp_cursor_shape_manager_v1_interface, 1);
1378 }
1379#endif
1380}
1381
1383 struct wl_registry *registry,
1384 uint32_t name) {
1386 for (i = 0; i < _WAYLAND_GLOBAL_SIZE; ++i) {
1387 if (wayland->global_names[i] != name) {
1388 continue;
1389 }
1390 wayland->global_names[i] = 0;
1391
1392 switch (i) {
1394 wl_compositor_destroy(wayland->compositor);
1395 wayland->compositor = NULL;
1396 break;
1398#ifdef HAVE_WAYLAND_CURSOR_SHAPE
1399 wp_cursor_shape_manager_v1_destroy(wayland->cursor_shape_manager);
1400 wayland->cursor_shape_manager = NULL;
1401#endif
1402 break;
1404 zwlr_layer_shell_v1_destroy(wayland->layer_shell);
1405 wayland->layer_shell = NULL;
1406 break;
1408 zwp_keyboard_shortcuts_inhibit_manager_v1_destroy(
1409 wayland->kb_shortcuts_inhibit_manager);
1410 wayland->kb_shortcuts_inhibit_manager = NULL;
1411 break;
1412 case WAYLAND_GLOBAL_SHM:
1413 wl_shm_destroy(wayland->shm);
1414 wayland->shm = NULL;
1415 break;
1417 g_assert_not_reached();
1418 }
1419 return;
1420 }
1421 if ((wayland->cursor.theme != NULL) &&
1422 ((wayland->compositor == NULL) || (wayland->shm == NULL))) {
1423 if (wayland->cursor.frame_cb != NULL) {
1424 wl_callback_destroy(wayland->cursor.frame_cb);
1425 wayland->cursor.frame_cb = NULL;
1426 }
1427
1428 wl_surface_destroy(wayland->cursor.surface);
1429 wl_cursor_theme_destroy(wayland->cursor.theme);
1430 wayland->cursor.surface = NULL;
1431 wayland->cursor.image = NULL;
1432 wayland->cursor.cursor = NULL;
1433 wayland->cursor.theme = NULL;
1434 wayland->cursor.scale = 0;
1435 }
1436
1437 GHashTableIter iter;
1438
1439 wayland_seat *seat;
1440 g_hash_table_iter_init(&iter, wayland->seats);
1441 while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&seat)) {
1442 if (seat->global_name != name) {
1443 continue;
1444 }
1445
1446 g_hash_table_iter_remove(&iter);
1448 return;
1449 }
1450
1451 wayland_output *output;
1452 g_hash_table_iter_init(&iter, wayland->outputs);
1453 while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&output)) {
1454 if (output->global_name != name) {
1455 continue;
1456 }
1457
1458 g_hash_table_iter_remove(&iter);
1459 wayland_output_release(output);
1460 return;
1461 }
1462}
1463
1464static const struct wl_registry_listener wayland_registry_listener = {
1467};
1468
1470 void *data, struct zwlr_layer_surface_v1 *surface, uint32_t serial,
1471 uint32_t width, uint32_t height) {
1472 wayland->layer_width = width;
1473 wayland->layer_height = height;
1474 zwlr_layer_surface_v1_ack_configure(surface, serial);
1475}
1476
1477static void wayland_surface_destroy(void) {
1478 if (wayland->wlr_surface != NULL) {
1479 zwlr_layer_surface_v1_destroy(wayland->wlr_surface);
1480 wayland->wlr_surface = NULL;
1481 }
1482 if (wayland->surface != NULL) {
1483 wl_surface_destroy(wayland->surface);
1484 wayland->surface = NULL;
1485 }
1486}
1487
1488static void
1490 struct zwlr_layer_surface_v1 *surface) {
1491 g_debug("Layer shell surface closed");
1492
1494
1495 // In this case, we recreate the layer shell surface the best we can and
1496 // re-initialize everything:
1497
1498 // recreate layer shell
1500
1501 // create new buffers with the correct scaled size
1503
1505 if (state != NULL) {
1506 rofi_view_set_size(state, -1, -1);
1507 }
1508}
1509
1510static const struct zwlr_layer_surface_v1_listener
1515
1516static gboolean wayland_error(gpointer user_data) {
1517 g_main_loop_quit(wayland->main_loop);
1518 return G_SOURCE_REMOVE;
1519}
1520
1521static gboolean wayland_cursor_reload_theme(guint scale) {
1522 if (wayland->cursor.theme != NULL) {
1523 if (wayland->cursor.scale == scale)
1524 return TRUE;
1525
1526 wl_cursor_theme_destroy(wayland->cursor.theme);
1527 wayland->cursor.theme = NULL;
1528 wayland->cursor.cursor = NULL;
1529 }
1530
1531 guint64 cursor_size = 24;
1532 char *env_cursor_size = (char *)g_getenv("XCURSOR_SIZE");
1533 if (env_cursor_size && strlen(env_cursor_size) > 0) {
1534 guint64 size = g_ascii_strtoull(env_cursor_size, NULL, 10);
1535 if (0 < size && size < G_MAXUINT64) {
1536 cursor_size = size;
1537 }
1538 }
1539 cursor_size *= scale;
1540
1541 wayland->cursor.theme = wl_cursor_theme_load(wayland->cursor.theme_name,
1542 cursor_size, wayland->shm);
1543 if (wayland->cursor.theme != NULL) {
1544 wayland->cursor.cursor = rofi_cursor_type_to_wl_cursor(
1545 wayland->cursor.theme, wayland->cursor.type);
1546 if (wayland->cursor.cursor == NULL) {
1547 wl_cursor_theme_destroy(wayland->cursor.theme);
1548 wayland->cursor.theme = NULL;
1549 return FALSE;
1550 } else {
1551 wayland->cursor.scale = scale;
1552 return TRUE;
1553 }
1554 }
1555 return FALSE;
1556}
1557
1558static gboolean wayland_display_setup(GMainLoop *main_loop,
1559 NkBindings *bindings) {
1560 wayland->main_loop = main_loop;
1561
1562 char *display = (char *)g_getenv("WAYLAND_DISPLAY");
1563 wayland->main_loop_source = g_water_wayland_source_new(NULL, display);
1564 if (wayland->main_loop_source == NULL) {
1565 g_warning("Could not connect to the Wayland compositor");
1566 return FALSE;
1567 }
1568
1569 g_water_wayland_source_set_error_callback(wayland->main_loop_source,
1570 wayland_error, NULL, NULL);
1571
1572 wayland->buffer_count = 3;
1573 wayland->cursor.type = ROFI_CURSOR_DEFAULT;
1574 wayland->scale = 1;
1575
1576 wayland->outputs = g_hash_table_new(g_direct_hash, g_direct_equal);
1577 wayland->seats = g_hash_table_new(g_direct_hash, g_direct_equal);
1578 wayland->seats_by_name =
1579 g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
1580
1581 wayland->display =
1582 g_water_wayland_source_get_display(wayland->main_loop_source);
1583 wayland->registry = wl_display_get_registry(wayland->display);
1584 wl_registry_add_listener(wayland->registry, &wayland_registry_listener, NULL);
1585 wl_display_roundtrip(wayland->display);
1586
1587 if (wayland->compositor == NULL || wayland->shm == NULL ||
1588 g_hash_table_size(wayland->outputs) == 0 ||
1589 g_hash_table_size(wayland->seats) == 0) {
1590 g_error("Could not connect to wayland compositor");
1591 return FALSE;
1592 }
1593 if (wayland->layer_shell == NULL) {
1594 g_error("Rofi on wayland requires support for the layer shell protocol");
1595 return FALSE;
1596 }
1597
1598 wayland->bindings_seat = nk_bindings_seat_new(bindings, XKB_CONTEXT_NO_FLAGS);
1599
1600 // Wait for output information
1601 wl_display_roundtrip(wayland->display);
1602
1603 return TRUE;
1604}
1605
1606static gboolean wayland_display_late_setup(void) {
1607 wayland_output *output = wayland_output_by_name(config.monitor);
1608
1609 struct wl_output *wlo = NULL;
1610 if (output != NULL) {
1611 wlo = output->output;
1612 }
1613 wayland->surface = wl_compositor_create_surface(wayland->compositor);
1614 wayland->wlr_surface = zwlr_layer_shell_v1_get_layer_surface(
1615 wayland->layer_shell, wayland->surface, wlo,
1616 ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY, "rofi");
1617
1618 // Set size zero and anchor on all corners to get the usable screen size
1619 // see https://github.com/swaywm/wlroots/pull/2422
1620 zwlr_layer_surface_v1_set_anchor(wayland->wlr_surface,
1621 ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP |
1622 ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM |
1623 ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT |
1624 ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT);
1625 zwlr_layer_surface_v1_set_size(wayland->wlr_surface, 0, 0);
1626 zwlr_layer_surface_v1_set_keyboard_interactivity(wayland->wlr_surface, 1);
1627 zwlr_layer_surface_v1_add_listener(
1628 wayland->wlr_surface, &wayland_layer_shell_surface_listener, NULL);
1629
1630 if (config.global_kb && wayland->kb_shortcuts_inhibit_manager) {
1631 g_debug("inhibit shortcuts from compositor");
1632 GHashTableIter iter;
1633 wayland_seat *seat;
1634 g_hash_table_iter_init(&iter, wayland->seats);
1635 while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&seat)) {
1636 // we don't need to keep track of these, they will get inactive when the
1637 // surface is destroyed
1638 zwp_keyboard_shortcuts_inhibit_manager_v1_inhibit_shortcuts(
1639 wayland->kb_shortcuts_inhibit_manager, wayland->surface, seat->seat);
1640 }
1641 }
1642
1643 wl_surface_add_listener(wayland->surface, &wayland_surface_interface,
1644 wayland);
1645 wl_surface_commit(wayland->surface);
1646 wl_display_roundtrip(wayland->display);
1647 wayland_frame_callback(wayland, wayland->frame_cb, 0);
1648
1649 return TRUE;
1650}
1651
1652gboolean display_get_surface_dimensions(int *width, int *height) {
1653 if (wayland->layer_width != 0) {
1654 if (width != NULL) {
1655 *width = wayland->layer_width;
1656 }
1657 if (height != NULL) {
1658 *height = wayland->layer_height;
1659 }
1660 return TRUE;
1661 }
1662 return FALSE;
1663}
1664
1665void display_set_surface_dimensions(int width, int height, int x_margin,
1666 int y_margin, int loc) {
1667
1668 wayland->layer_width = width;
1669 wayland->layer_height = height;
1670 zwlr_layer_surface_v1_set_size(wayland->wlr_surface, width, height);
1671
1672 uint32_t wlr_anchor = 0;
1673 switch (loc) {
1674 case WL_NORTH_WEST:
1675 wlr_anchor =
1676 ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP;
1677 break;
1678 case WL_NORTH:
1679 wlr_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP;
1680 break;
1681 case WL_NORTH_EAST:
1682 wlr_anchor =
1683 ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP;
1684 break;
1685 case WL_EAST:
1686 wlr_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
1687 break;
1688 case WL_SOUTH_EAST:
1689 wlr_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT |
1690 ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
1691 break;
1692 case WL_SOUTH:
1693 wlr_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
1694 break;
1695 case WL_SOUTH_WEST:
1696 wlr_anchor =
1697 ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
1698 break;
1699 case WL_WEST:
1700 wlr_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT;
1701 break;
1702 case WL_CENTER:
1703 default:
1704 break;
1705 }
1706
1707 if (height == 0) {
1708 wlr_anchor |=
1709 ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM | ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP;
1710 }
1711 if (width == 0) {
1712 wlr_anchor |=
1713 ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
1714 }
1715
1716 zwlr_layer_surface_v1_set_anchor(wayland->wlr_surface, wlr_anchor);
1717
1718 // NOTE: Setting margin for edges we are not anchored to has no effect, so
1719 // we can safely set contradictory margins (e.g. top vs bottom) - at most
1720 // one of the margins on a given axis will have effect. This also means that
1721 // margin has no effect if the window is centered. :(
1722 zwlr_layer_surface_v1_set_margin(wayland->wlr_surface, y_margin, -x_margin,
1723 -y_margin, x_margin);
1724}
1725
1727 if (wayland->main_loop_source == NULL) {
1728 return;
1729 }
1730
1732 wl_display_flush(wayland->display);
1733}
1734
1735static void wayland_display_cleanup(void) {
1736 if (wayland->main_loop_source == NULL) {
1737 return;
1738 }
1739
1740 nk_bindings_seat_free(wayland->bindings_seat);
1741 g_hash_table_unref(wayland->seats_by_name);
1742 g_hash_table_unref(wayland->seats);
1743 g_hash_table_unref(wayland->outputs);
1744 wl_registry_destroy(wayland->registry);
1745 wl_display_flush(wayland->display);
1746 g_water_wayland_source_free(wayland->main_loop_source);
1747}
1748
1750 int is_term = isatty(fileno(stdout));
1751 GHashTableIter iter;
1752 wayland_output *output;
1753
1754 g_hash_table_iter_init(&iter, wayland->outputs);
1755 printf("Monitor layout:\n");
1756 while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&output)) {
1757 printf("%s ID%s: %" PRIu32, is_term ? color_bold : "",
1758 is_term ? color_reset : "", output->global_name);
1759 printf("\n");
1760 printf("%s name%s: %s\n", is_term ? color_bold : "",
1761 is_term ? color_reset : "", output->name);
1762 printf("%s scale%s: %" PRIi32 "\n", is_term ? color_bold : "",
1763 is_term ? color_reset : "", output->current.scale);
1764 printf("%s position%s: %" PRIi32 ",%" PRIi32 "\n",
1765 is_term ? color_bold : "", is_term ? color_reset : "",
1766 output->current.x, output->current.y);
1767 printf("%s size%s: %" PRIi32 ",%" PRIi32 "\n",
1768 is_term ? color_bold : "", is_term ? color_reset : "",
1769 output->current.width, output->current.height);
1770
1771 if (output->current.physical_width > 0 &&
1772 output->current.physical_height > 0) {
1773 printf("%s size%s: %" PRIi32 "mm,%" PRIi32
1774 "mm dpi: %.0f,%.0f\n",
1775 is_term ? color_bold : "", is_term ? color_reset : "",
1777 wayland_output_get_dpi(output, output->current.scale, width),
1778 wayland_output_get_dpi(output, output->current.scale, height));
1779 }
1780 printf("\n");
1781 }
1782}
1783
1784static void
1786 GSpawnChildSetupFunc *child_setup,
1787 gpointer *user_data) {}
1788
1790 // TODO: do something?
1791 return FALSE;
1792}
1793
1794static void wayland_display_set_input_focus(guint w) {}
1795
1797
1798static const struct _view_proxy *wayland_display_view_proxy(void) {
1799 return wayland_view_proxy;
1800}
1801
1802static guint wayland_display_scale(void) { return wayland->scale; }
1803
1804static void wayland_get_clipboard_data(int cb_type, ClipboardCb callback,
1805 void *user_data) {
1806 clipboard_data *clipboard = &wayland->clipboards[cb_type];
1807
1808 if (clipboard->offer == NULL) {
1809 return;
1810 }
1811
1812 int fds[2];
1813 if (pipe(fds) < 0) {
1814 return;
1815 }
1816
1817 if (cb_type == CLIPBOARD_DEFAULT) {
1818 wl_data_offer_receive(clipboard->offer, "text/plain", fds[1]);
1819 } else {
1820 zwp_primary_selection_offer_v1_receive(clipboard->offer, "text/plain",
1821 fds[1]);
1822 }
1823 close(fds[1]);
1824
1825 clipboard_read_data(fds[0], callback, user_data);
1826}
1827
1829 if (!wayland->wlr_surface) {
1830 return;
1831 }
1832 zwlr_layer_surface_v1_set_exclusive_zone(wayland->wlr_surface, -1);
1833 zwlr_layer_surface_v1_set_size(wayland->wlr_surface, 0, 0);
1834 wl_surface_commit(wayland->surface);
1835 wl_display_roundtrip(wayland->display);
1836
1838}
1839
1841 .setup = wayland_display_setup,
1842 .late_setup = wayland_display_late_setup,
1843 .early_cleanup = wayland_display_early_cleanup,
1844 .cleanup = wayland_display_cleanup,
1845 .dump_monitor_layout = wayland_display_dump_monitor_layout,
1846 .startup_notification = wayland_display_startup_notification,
1847 .monitor_active = wayland_display_monitor_active,
1848 .set_input_focus = wayland_display_set_input_focus,
1849 .revert_input_focus = wayland_display_revert_input_focus,
1850 .scale = wayland_display_scale,
1851 .get_clipboard_data = wayland_get_clipboard_data,
1852 .set_fullscreen_mode = wayland_set_fullscreen_mode,
1853
1855};
1856
struct _display_proxy display_proxy
clipboard_type
Definition display.h:125
@ CLIPBOARD_DEFAULT
Definition display.h:126
@ CLIPBOARD_PRIMARY
Definition display.h:127
struct _workarea workarea
void(* ClipboardCb)(char *clipboard_data, void *user_data)
Definition display.h:130
@ WL_SOUTH_EAST
Definition rofi-types.h:249
@ WL_CENTER
Definition rofi-types.h:235
@ WL_NORTH_WEST
Definition rofi-types.h:245
@ WL_SOUTH
Definition rofi-types.h:241
@ WL_NORTH_EAST
Definition rofi-types.h:247
@ WL_WEST
Definition rofi-types.h:243
@ WL_NORTH
Definition rofi-types.h:237
@ WL_EAST
Definition rofi-types.h:239
@ WL_SOUTH_WEST
Definition rofi-types.h:251
#define color_reset
Definition rofi.h:114
#define color_bold
Definition rofi.h:116
RofiViewState * rofi_view_get_active(void)
Definition view.c:299
void rofi_view_handle_text(RofiViewState *state, char *text)
Definition view.c:1401
void rofi_view_handle_mouse_motion(RofiViewState *state, gint x, gint y, gboolean find_mouse_target)
Definition view.c:1435
void rofi_view_frame_callback(void)
Definition view.c:2127
void rofi_view_maybe_update(RofiViewState *state)
Definition view.c:1495
void rofi_view_set_size(RofiViewState *state, gint width, gint height)
Definition view.c:2169
void rofi_view_pool_refresh(void)
Definition view.c:2179
#define BTN_LEFT
Definition input-codes.h:33
#define BTN_MIDDLE
Definition input-codes.h:41
#define BTN_RIGHT
Definition input-codes.h:37
RofiCursorType
Definition rofi-types.h:147
@ ROFI_CURSOR_POINTER
Definition rofi-types.h:149
@ ROFI_CURSOR_TEXT
Definition rofi-types.h:150
@ ROFI_CURSOR_DEFAULT
Definition rofi-types.h:148
NkBindings * bindings
Definition rofi.c:136
GMainLoop * main_loop
Definition rofi.c:142
Settings config
wayland_buffer * buffers
Definition display.c:108
wayland_stuff * context
Definition display.c:102
wayland_stuff * context
widget_motion_event motion
struct zwp_primary_selection_device_v1 * primary_selection_device
struct wl_data_device * data_device
uint32_t pointer_serial
enum wl_pointer_axis_source axis_source
xkb_keycode_t key
struct _wayland_seat::@343227211112372105005173305133123375230264171047 repeat
struct _wayland_seat::@313335272333100233226263113233303355264201246036 wheel_continuous
struct wl_pointer * pointer
struct wl_keyboard * keyboard
struct _wayland_seat::@304276237306320361362211175300054320337005042177 wheel
widget_button_event button
struct wl_seat * seat
ClipboardCb callback
Definition display.c:919
wayland_buffer_pool * pool
Definition display.c:95
gboolean released
Definition display.c:98
uint8_t * data
Definition display.c:97
struct wl_buffer * buffer
Definition display.c:96
struct wayland_output::@126201033072136362231003373230312354065355150332 pending
wayland_stuff * context
Definition display.c:78
struct wayland_output::@126201033072136362231003373230312354065355150332 current
int32_t width
Definition display.c:85
int32_t x
Definition display.c:83
int32_t physical_width
Definition display.c:87
gchar * name
Definition display.c:81
int32_t height
Definition display.c:86
int32_t scale
Definition display.c:89
uint32_t global_name
Definition display.c:79
int32_t physical_height
Definition display.c:88
struct wl_output * output
Definition display.c:80
int32_t y
Definition display.c:84
int32_t transform
Definition display.c:90
#define WL_LAYER_SHELL_INTERFACE_VERSION
struct _wayland_seat wayland_seat
#define WL_KEYBOARD_SHORTCUTS_INHIBITOR_INTERFACE_VERSION
#define WL_SHM_INTERFACE_VERSION
#define WL_SEAT_INTERFACE_MAX_VERSION
wayland_global_name
@ WAYLAND_GLOBAL_CURSOR_SHAPE
@ WAYLAND_GLOBAL_LAYER_SHELL
@ WAYLAND_GLOBAL_KEYBOARD_SHORTCUTS_INHIBITOR
@ WAYLAND_GLOBAL_COMPOSITOR
@ WAYLAND_GLOBAL_SHM
@ _WAYLAND_GLOBAL_SIZE
#define WL_SEAT_INTERFACE_MIN_VERSION
#define WL_OUTPUT_INTERFACE_MIN_VERSION
#define WL_OUTPUT_INTERFACE_MAX_VERSION
#define WL_COMPOSITOR_INTERFACE_VERSION
static void data_offer_handle_action(void *data, struct wl_data_offer *wl_data_offer, uint32_t dnd_action)
Definition display.c:1002
static void wayland_registry_handle_global_remove(void *data, struct wl_registry *registry, uint32_t name)
Definition display.c:1382
static gboolean wayland_key_repeat_delay(void *data)
Definition display.c:420
static void wayland_pointer_axis(void *data, struct wl_pointer *pointer, uint32_t time, enum wl_pointer_axis axis, wl_fixed_t value)
Definition display.c:815
static void clipboard_handle_selection(enum clipboard_type cb_type, void *offer)
Definition display.c:1035
static void wayland_layer_shell_surface_closed(void *data, struct zwlr_layer_surface_v1 *surface)
Definition display.c:1489
static void wayland_display_dump_monitor_layout(void)
Definition display.c:1749
static const struct wl_buffer_listener wayland_buffer_listener
Definition display.c:154
static void wayland_display_set_input_focus(guint w)
Definition display.c:1794
static void data_offer_handle_source_actions(void *data, struct wl_data_offer *wl_data_offer, uint32_t source_actions)
Definition display.c:999
static const struct zwlr_layer_surface_v1_listener wayland_layer_shell_surface_listener
Definition display.c:1511
static void wayland_seat_capabilities(void *data, struct wl_seat *seat, uint32_t capabilities)
Definition display.c:1121
static void wayland_display_revert_input_focus(void)
Definition display.c:1796
static const struct wl_registry_listener wayland_registry_listener
Definition display.c:1464
static void wayland_seat_name(void *data, struct wl_seat *seat, const char *name)
Definition display.c:1158
static void wayland_buffer_release(void *data, struct wl_buffer *buffer)
Definition display.c:141
static const struct wl_data_device_listener data_device_listener
Definition display.c:1055
static void wayland_pointer_send_events(wayland_seat *self)
Definition display.c:574
static void wayland_get_clipboard_data(int cb_type, ClipboardCb callback, void *user_data)
Definition display.c:1804
static const struct wl_keyboard_listener wayland_keyboard_listener
Definition display.c:524
static void wayland_surface_destroy(void)
Definition display.c:1477
static void wayland_pointer_axis_stop(void *data, struct wl_pointer *pointer, uint32_t time, enum wl_pointer_axis axis)
Definition display.c:843
static void wayland_output_scale(void *data, struct wl_output *output, int32_t scale)
Definition display.c:1267
double wayland_get_dpi_estimation(void)
Definition display.c:1207
static void wayland_output_done(void *data, struct wl_output *output)
Definition display.c:1229
void display_surface_commit(cairo_surface_t *surface)
Definition display.c:306
wayland_stuff * wayland
Definition display.c:114
static void wayland_display_early_cleanup(void)
Definition display.c:1726
static void data_device_handle_drop(void *data, struct wl_data_device *wl_data_device)
Definition display.c:1032
#define CLIPBOARD_READ_INCREMENT
Definition display.c:913
static const struct wl_callback_listener wayland_frame_wl_callback_listener
Definition display.c:278
static gboolean clipboard_read_data(int fd, ClipboardCb callback, void *user_data)
Definition display.c:966
static wayland_stuff wayland_
Definition display.c:113
static void wayland_pointer_axis_discrete(void *data, struct wl_pointer *pointer, enum wl_pointer_axis axis, int32_t discrete)
Definition display.c:847
static void wayland_keyboard_key(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key, enum wl_keyboard_key_state kstate)
Definition display.c:452
static wayland_output * wayland_output_by_name(const char *name)
Definition display.c:1189
static void wayland_keyboard_modifiers(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group)
Definition display.c:497
static void wayland_display_startup_notification(RofiHelperExecuteContext *context, GSpawnChildSetupFunc *child_setup, gpointer *user_data)
Definition display.c:1785
cairo_surface_t * display_buffer_pool_get_next_buffer(wayland_buffer_pool *pool)
Definition display.c:283
static void primary_selection_device_handle_selection(void *data, struct zwp_primary_selection_device_v1 *data_device, struct zwp_primary_selection_offer_v1 *offer)
Definition display.c:1081
static void data_device_handle_selection(void *data, struct wl_data_device *data_device, struct wl_data_offer *offer)
Definition display.c:1049
static const struct wl_data_offer_listener data_offer_listener
Definition display.c:1006
gboolean display_get_surface_dimensions(int *width, int *height)
Definition display.c:1652
static void wayland_pointer_axis_source(void *data, struct wl_pointer *pointer, enum wl_pointer_axis_source axis_source)
Definition display.c:836
static void data_device_handle_leave(void *data, struct wl_data_device *wl_data_device)
Definition display.c:1024
void wayland_display_set_cursor_type(RofiCursorType type)
Definition display.c:746
static gboolean wayland_key_repeat(void *data)
Definition display.c:394
static guint wayland_display_scale(void)
Definition display.c:1802
static gboolean wayland_display_late_setup(void)
Definition display.c:1606
static void wayland_layer_shell_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface, uint32_t serial, uint32_t width, uint32_t height)
Definition display.c:1469
static gboolean wayland_cursor_reload_theme(guint scale)
Definition display.c:1521
static void wayland_output_release(wayland_output *self)
Definition display.c:1174
static void data_device_handle_motion(void *data, struct wl_data_device *wl_data_device, uint32_t time, wl_fixed_t x, wl_fixed_t y)
Definition display.c:1027
static void wayland_seat_release(wayland_seat *self)
Definition display.c:1110
static void wayland_buffer_cleanup(wayland_buffer_pool *self)
Definition display.c:117
static void wayland_keyboard_keymap(void *data, struct wl_keyboard *keyboard, enum wl_keyboard_keymap_format format, int32_t fd, uint32_t size)
Definition display.c:340
static void wayland_surface_protocol_enter(void *data, struct wl_surface *wl_surface, struct wl_output *wl_output)
Definition display.c:235
static const cairo_user_data_key_t wayland_cairo_surface_user_data
Definition display.c:115
static void data_device_handle_data_offer(void *data, struct wl_data_device *data_device, struct wl_data_offer *offer)
Definition display.c:1012
static void wayland_registry_handle_global(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version)
Definition display.c:1302
static void wayland_pointer_button(void *data, struct wl_pointer *pointer, uint32_t serial, uint32_t time, uint32_t button, enum wl_pointer_button_state state)
Definition display.c:801
static const struct wl_pointer_listener wayland_pointer_listener
Definition display.c:882
static display_proxy display_
Definition display.c:1840
static void wayland_cursor_set_image(int i)
Definition display.c:535
static void wayland_cursor_update_for_seat(wayland_seat *seat)
Definition display.c:695
static void wayland_output_geometry(void *data, struct wl_output *output, int32_t x, int32_t y, int32_t width, int32_t height, int32_t subpixel, const char *make, const char *model, int32_t transform)
Definition display.c:1243
static struct wl_cursor * rofi_cursor_type_to_wl_cursor(struct wl_cursor_theme *theme, RofiCursorType type)
Definition display.c:654
static void wayland_keyboard_leave(void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface)
Definition display.c:387
static void primary_selection_device_handle_data_offer(void *data, struct zwp_primary_selection_device_v1 *data_device, struct zwp_primary_selection_offer_v1 *offer)
Definition display.c:1074
static void primary_selection_handle_offer(void *data, struct zwp_primary_selection_offer_v1 *offer, const char *mime_type)
Definition display.c:1065
void display_buffer_pool_free(wayland_buffer_pool *self)
Definition display.c:227
static void wayland_display_cleanup(void)
Definition display.c:1735
static void wayland_pointer_release(wayland_seat *self)
Definition display.c:1093
#define wayland_output_get_dpi(output, scale, dimension)
Definition display.c:70
static gboolean wayland_display_setup(GMainLoop *main_loop, NkBindings *bindings)
Definition display.c:1558
static void wayland_frame_callback(void *data, struct wl_callback *callback, uint32_t time)
Definition display.c:326
static void data_device_handle_enter(void *data, struct wl_data_device *wl_data_device, uint32_t serial, struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y, struct wl_data_offer *id)
Definition display.c:1018
static const struct zwp_primary_selection_device_v1_listener primary_selection_device_listener
Definition display.c:1088
static const struct wl_callback_listener wayland_cursor_frame_wl_callback_listener
Definition display.c:554
static void wayland_keyboard_release(wayland_seat *self)
Definition display.c:897
static void wayland_set_fullscreen_mode(void)
Definition display.c:1828
struct _display_buffer_pool wayland_buffer_pool
Definition display.c:76
static void wayland_pointer_frame(void *data, struct wl_pointer *pointer)
Definition display.c:830
static const struct _view_proxy * wayland_display_view_proxy(void)
Definition display.c:1798
static void wayland_keyboard_repeat_info(void *data, struct wl_keyboard *keyboard, int32_t rate, int32_t delay)
Definition display.c:511
static const struct wl_output_listener wayland_output_listener
Definition display.c:1289
static const struct wl_surface_listener wayland_surface_interface
Definition display.c:270
static gboolean wayland_error(gpointer user_data)
Definition display.c:1516
static const struct wl_seat_listener wayland_seat_listener
Definition display.c:1169
static void wayland_keyboard_enter(void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface, struct wl_array *keys)
Definition display.c:371
static void wayland_cursor_frame_callback(void *data, struct wl_callback *callback, uint32_t time)
Definition display.c:558
static void wayland_pointer_leave(void *data, struct wl_pointer *pointer, uint32_t serial, struct wl_surface *surface)
Definition display.c:780
static const struct zwp_primary_selection_offer_v1_listener primary_selection_offer_listener
Definition display.c:1070
static void wayland_output_mode(void *data, struct wl_output *output, enum wl_output_mode flags, int32_t width, int32_t height, int32_t refresh)
Definition display.c:1257
static void data_offer_handle_offer(void *data, struct wl_data_offer *offer, const char *mime_type)
Definition display.c:996
void display_set_surface_dimensions(int width, int height, int x_margin, int y_margin, int loc)
Definition display.c:1665
static gboolean clipboard_read_glib_callback(GIOChannel *channel, GIOCondition condition, gpointer opaque)
Definition display.c:923
wayland_buffer_pool * display_buffer_pool_new(gint width, gint height)
Definition display.c:157
display_proxy *const wayland_proxy
Definition display.c:1857
static void wayland_pointer_enter(void *data, struct wl_pointer *pointer, uint32_t serial, struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y)
Definition display.c:724
static void wayland_pointer_motion(void *data, struct wl_pointer *pointer, uint32_t time, wl_fixed_t x, wl_fixed_t y)
Definition display.c:790
static int wayland_display_monitor_active(workarea *mon)
Definition display.c:1789
static void wayland_surface_protocol_leave(void *data, struct wl_surface *wl_surface, struct wl_output *wl_output)
Definition display.c:266
const view_proxy * wayland_view_proxy
Definition view.c:442
MenuFlags flags
Definition view.c:72
unsigned long long count
Definition view.c:76
GTimer * time
Definition view.c:159
workarea mon
Definition view.c:117