6XZIQSMIVP2GZ5S3UCKEVNDSLTHSQEVSXLV4UIFF3G3SRCGJPXYAC ZOOCZQBGZ4PCOU54EPPUPWNOIFWCM5RMZ4EFL2WFR7LFJTAMHZGAC S7RXJJZG4IEIVLPHEWFT5M2T3SRRO5US5SYBPXSYSWJJLXAKNNPAC D425ND7AT3F7QJ3CCSESMVDOC3J5C5P32M5SJDBHECZJXLHNQ2FAC 7B74AT3BXYB7PVW4F6SGQNPMHOU5TEV5TZ54CG6VSQI46XSEKWXQC J6OSBEBQXZR5JZ5TOCCUPELBPUVEQULGCXURXLPY7WFYTDEQOU2AC 7XCGFU3GX4TQXZBOU7GFAQ62EEOTVRNWFYQGI3XULFPSUKDZ2EYAC O5JVMDEEKP334BAYMJ6HHXROW4X4WC24JHCYZTKJRQE5UGYXV7YQC Z53RRSEGCT3PGEZNNSAREB3WVYOHCTDXXPNAKOWWGCEYW4G2QC4QC E7UO6NRGXFDMBU3BSJYRDNOA3Y7VHD7NWPHI5PHCPHQF6ZNOPZLQC }voidrun(char *startup_cmd){pid_t startup_pid = -1;/* Add a Unix socket to the Wayland display. */const char *socket = wl_display_add_socket_auto(wl_display);if (!socket) {wlr_backend_destroy(backend);exit(1);}/* Start the backend. This will enumerate outputs and inputs, become the DRM* master, etc */if (!wlr_backend_start(backend)) {wlr_backend_destroy(backend);wl_display_destroy(wl_display);exit(1);}/* Set the WAYLAND_DISPLAY environment variable to our socket and run the* startup command if requested. */setenv("WAYLAND_DISPLAY", socket, true);if (startup_cmd) {startup_pid = fork();if (startup_pid < 0) {perror("startup: fork");wl_display_destroy(wl_display);exit(1);}if (startup_pid == 0) {execl("/bin/sh", "/bin/sh", "-c", startup_cmd, (void *)NULL);perror("startup: execl");wl_display_destroy(wl_display);exit(1);}}/* Run the Wayland event loop. This does not return until you exit the* compositor. Starting the backend rigged up all of the necessary event* loop configuration to listen to libinput events, DRM events, generate* frame events at the refresh rate, and so on. */wlr_log(WLR_INFO, "Running Wayland compositor on WAYLAND_DISPLAY=%s",socket);wl_display_run(wl_display);if (startup_cmd) {kill(startup_pid, SIGTERM);waitpid(startup_pid, NULL, 0);}
if (fork() == 0) {setsid();execvp(((char **)arg->v)[0], (char **)arg->v);fprintf(stderr, "dwl: execvp %s", ((char **)arg->v)[0]);perror(" failed");exit(EXIT_FAILURE);}}voidunmapnotify(struct wl_listener *listener, void *data){/* Called when the surface is unmapped, and should no longer be shown. */Client *c = wl_container_of(listener, c, unmap);c->mapped = false;}Client *xytoclient(double lx, double ly,struct wlr_surface **surface, double *sx, double *sy){/* This iterates over all of our surfaces and attempts to find one under the* cursor. This relies on clients being ordered from top-to-bottom. */Client *c;wl_list_for_each(c, &clients, link) {if (xytosurface(c, lx, ly, surface, sx, sy)) {return c;}}return NULL;}boolxytosurface(Client *c, double lx, double ly,struct wlr_surface **surface, double *sx, double *sy){/** XDG toplevels may have nested surfaces, such as popup windows for context* menus or tooltips. This function tests if any of those are underneath the* coordinates lx and ly (in output Layout Coordinates). If so, it sets the* surface pointer to that wlr_surface and the sx and sy coordinates to the* coordinates relative to that surface's top-left corner.*/double client_sx = lx - c->x;double client_sy = ly - c->y;struct wlr_surface_state *state = &c->xdg_surface->surface->current;double _sx, _sy;struct wlr_surface *_surface = NULL;_surface = wlr_xdg_surface_surface_at(c->xdg_surface, client_sx, client_sy, &_sx, &_sy);if (_surface != NULL) {*sx = _sx;*sy = _sy;*surface = _surface;return true;}return false;}intmain(int argc, char *argv[]){wlr_log_init(WLR_DEBUG, NULL);char *startup_cmd = NULL;pid_t startup_pid = -1;int c;while ((c = getopt(argc, argv, "s:h")) != -1) {switch (c) {case 's':startup_cmd = optarg;break;default:printf("Usage: %s [-s startup command]\n", argv[0]);return 0;}}if (optind < argc) {printf("Usage: %s [-s startup command]\n", argv[0]);return 0;}/* The Wayland display is managed by libwayland. It handles accepting* clients from the Unix socket, manging Wayland globals, and so on. */wl_display = wl_display_create();
/* Add a Unix socket to the Wayland display. */const char *socket = wl_display_add_socket_auto(wl_display);if (!socket) {wlr_backend_destroy(backend);return 1;
voidspawn(const Arg *arg){if (fork() == 0) {setsid();execvp(((char **)arg->v)[0], (char **)arg->v);fprintf(stderr, "dwl: execvp %s", ((char **)arg->v)[0]);perror(" failed");exit(EXIT_FAILURE);
/* Start the backend. This will enumerate outputs and inputs, become the DRM* master, etc */if (!wlr_backend_start(backend)) {wlr_backend_destroy(backend);wl_display_destroy(wl_display);return 1;}
voidunmapnotify(struct wl_listener *listener, void *data){/* Called when the surface is unmapped, and should no longer be shown. */Client *c = wl_container_of(listener, c, unmap);c->mapped = false;}
/* Set the WAYLAND_DISPLAY environment variable to our socket and run the* startup command if requested. */setenv("WAYLAND_DISPLAY", socket, true);if (startup_cmd) {startup_pid = fork();if (startup_pid < 0) {perror("startup: fork");wl_display_destroy(wl_display);return 1;}if (startup_pid == 0) {execl("/bin/sh", "/bin/sh", "-c", startup_cmd, (void *)NULL);perror("startup: execl");wl_display_destroy(wl_display);return 1;
Client *xytoclient(double lx, double ly,struct wlr_surface **surface, double *sx, double *sy){/* This iterates over all of our surfaces and attempts to find one under the* cursor. This relies on clients being ordered from top-to-bottom. */Client *c;wl_list_for_each(c, &clients, link) {if (xytosurface(c, lx, ly, surface, sx, sy)) {return c;
/* Run the Wayland event loop. This does not return until you exit the* compositor. Starting the backend rigged up all of the necessary event* loop configuration to listen to libinput events, DRM events, generate* frame events at the refresh rate, and so on. */wlr_log(WLR_INFO, "Running Wayland compositor on WAYLAND_DISPLAY=%s",socket);wl_display_run(wl_display);
return NULL;}boolxytosurface(Client *c, double lx, double ly,struct wlr_surface **surface, double *sx, double *sy){/** XDG toplevels may have nested surfaces, such as popup windows for context* menus or tooltips. This function tests if any of those are underneath the* coordinates lx and ly (in output Layout Coordinates). If so, it sets the* surface pointer to that wlr_surface and the sx and sy coordinates to the* coordinates relative to that surface's top-left corner.*/double client_sx = lx - c->x;double client_sy = ly - c->y;struct wlr_surface_state *state = &c->xdg_surface->surface->current;double _sx, _sy;struct wlr_surface *_surface = NULL;_surface = wlr_xdg_surface_surface_at(c->xdg_surface, client_sx, client_sy, &_sx, &_sy);if (_surface != NULL) {*sx = _sx;*sy = _sy;*surface = _surface;return true;}return false;}intmain(int argc, char *argv[]){wlr_log_init(WLR_DEBUG, NULL);char *startup_cmd = NULL;
if (startup_cmd) {kill(startup_pid, SIGTERM);waitpid(startup_pid, NULL, 0);
int c;while ((c = getopt(argc, argv, "s:h")) != -1) {switch (c) {case 's':startup_cmd = optarg;break;default:printf("Usage: %s [-s startup command]\n", argv[0]);return 0;}}if (optind < argc) {printf("Usage: %s [-s startup command]\n", argv[0]);return 0;