~ruther/dwl

34521ea43bc7e9b65fd3c6decfadcff7db59d950 — Devin J. Pohly 3 years ago 5dfd7cf + c6f96d5
Merge branch 'main' into wlroots-next
2 files changed, 62 insertions(+), 49 deletions(-)

M README.md
M dwl.c
M README.md => README.md +1 -1
@@ 38,7 38,7 @@ Feature *non-goals* for the main codebase include:

## Building dwl

dwl has only two dependencies: wlroots-git and wayland-protocols. Simply install these and run `make`.
dwl has only two dependencies: wlroots-git and wayland-protocols. Simply install these (and their `-devel` versions if your distro has separate development packages) and run `make`.

To enable XWayland, you should also install xorg-xwayland and uncomment its flag in `config.mk`.


M dwl.c => dwl.c +61 -48
@@ 259,6 259,7 @@ static void pointerfocus(Client *c, struct wlr_surface *surface,
		double sx, double sy, uint32_t time);
static void printstatus(void);
static void quit(const Arg *arg);
static void quitsignal(int signo);
static void render(struct wlr_surface *surface, int sx, int sy, void *data);
static void renderclients(Monitor *m, struct timespec *now);
static void renderlayer(struct wl_list *layer_surfaces, struct timespec *now);


@@ 842,11 843,13 @@ createmon(struct wl_listener *listener, void *data)
	LISTEN(&wlr_output->events.frame, &m->frame, rendermon);
	LISTEN(&wlr_output->events.destroy, &m->destroy, cleanupmon);

	wl_list_insert(&mons, &m->link);
	wlr_output_enable(wlr_output, 1);
	if (!wlr_output_commit(wlr_output))
		return;

	wl_list_insert(&mons, &m->link);
	printstatus();

	/* Adds this to the output layout in the order it was configured in.
	 *
	 * The output layout utility automatically adds a wl_output global to the


@@ 1577,6 1580,12 @@ quit(const Arg *arg)
}

void
quitsignal(int signo)
{
	quit(NULL);
}

void
render(struct wlr_surface *surface, int sx, int sy, void *data)
{
	/* This function is called for every surface that needs to be rendered. */


@@ 1724,38 1733,42 @@ rendermon(struct wl_listener *listener, void *data)
		}
	}

	/* wlr_output_attach_render makes the OpenGL context current. */
	if (!wlr_output_attach_render(m->wlr_output, NULL))
		return;
	/* HACK: This loop is the simplest way to handle ephemeral pageflip
	 * failures but probably not the best. Revisit if damage tracking is
	 * added. */
	do {
		/* wlr_output_attach_render makes the OpenGL context current. */
		if (!wlr_output_attach_render(m->wlr_output, NULL))
			return;

	if (render) {
		/* Begin the renderer (calls glViewport and some other GL sanity checks) */
		wlr_renderer_begin(drw, m->wlr_output->width, m->wlr_output->height);
		wlr_renderer_clear(drw, rootcolor);
		if (render) {
			/* Begin the renderer (calls glViewport and some other GL sanity checks) */
			wlr_renderer_begin(drw, m->wlr_output->width, m->wlr_output->height);
			wlr_renderer_clear(drw, rootcolor);

		renderlayer(&m->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], &now);
		renderlayer(&m->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], &now);
		renderclients(m, &now);
			renderlayer(&m->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], &now);
			renderlayer(&m->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], &now);
			renderclients(m, &now);
#ifdef XWAYLAND
		renderindependents(m->wlr_output, &now);
			renderindependents(m->wlr_output, &now);
#endif
		renderlayer(&m->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], &now);
		renderlayer(&m->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], &now);

		/* Hardware cursors are rendered by the GPU on a separate plane, and can be
		 * moved around without re-rendering what's beneath them - which is more
		 * efficient. However, not all hardware supports hardware cursors. For this
		 * reason, wlroots provides a software fallback, which we ask it to render
		 * here. wlr_cursor handles configuring hardware vs software cursors for you,
		 * and this function is a no-op when hardware cursors are in use. */
		wlr_output_render_software_cursors(m->wlr_output, NULL);

		/* Conclude rendering and swap the buffers, showing the final frame
		 * on-screen. */
		wlr_renderer_end(drw);
	}
			renderlayer(&m->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], &now);
			renderlayer(&m->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], &now);

			/* Hardware cursors are rendered by the GPU on a separate plane, and can be
			 * moved around without re-rendering what's beneath them - which is more
			 * efficient. However, not all hardware supports hardware cursors. For this
			 * reason, wlroots provides a software fallback, which we ask it to render
			 * here. wlr_cursor handles configuring hardware vs software cursors for you,
			 * and this function is a no-op when hardware cursors are in use. */
			wlr_output_render_software_cursors(m->wlr_output, NULL);

			/* Conclude rendering and swap the buffers, showing the final frame
			 * on-screen. */
			wlr_renderer_end(drw);
		}

	wlr_output_commit(m->wlr_output);
	} while (!wlr_output_commit(m->wlr_output));
}

void


@@ 1786,27 1799,9 @@ run(char *startup_cmd)
	const char *socket = wl_display_add_socket_auto(dpy);
	if (!socket)
		BARF("startup: display_add_socket_auto");

	/* Start the backend. This will enumerate outputs and inputs, become the DRM
	 * master, etc */
	if (!wlr_backend_start(backend))
		BARF("startup: backend_start");

	/* Now that outputs are initialized, choose initial selmon based on
	 * cursor position, and set default cursor image */
	selmon = xytomon(cursor->x, cursor->y);

	/* TODO hack to get cursor to display in its initial location (100, 100)
	 * instead of (0, 0) and then jumping.  still may not be fully
	 * initialized, as the image/coordinates are not transformed for the
	 * monitor when displayed here */
	wlr_cursor_warp_closest(cursor, NULL, cursor->x, cursor->y);
	wlr_xcursor_manager_set_cursor_image(cursor_mgr, "left_ptr", cursor);

	/* Set the WAYLAND_DISPLAY environment variable to our socket and run the
	 * startup command if requested. */
	setenv("WAYLAND_DISPLAY", socket, 1);

	/* Now that the socket exists, run the startup command */
	if (startup_cmd) {
		int piperw[2];
		pipe(piperw);


@@ 1825,6 1820,22 @@ run(char *startup_cmd)
	/* If nobody is reading the status output, don't terminate */
	signal(SIGPIPE, SIG_IGN);

	/* Start the backend. This will enumerate outputs and inputs, become the DRM
	 * master, etc */
	if (!wlr_backend_start(backend))
		BARF("startup: backend_start");

	/* Now that outputs are initialized, choose initial selmon based on
	 * cursor position, and set default cursor image */
	selmon = xytomon(cursor->x, cursor->y);

	/* TODO hack to get cursor to display in its initial location (100, 100)
	 * instead of (0, 0) and then jumping.  still may not be fully
	 * initialized, as the image/coordinates are not transformed for the
	 * monitor when displayed here */
	wlr_cursor_warp_closest(cursor, NULL, cursor->x, cursor->y);
	wlr_xcursor_manager_set_cursor_image(cursor_mgr, "left_ptr", cursor);

	/* 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


@@ 1961,8 1972,10 @@ setup(void)
	 * clients from the Unix socket, manging Wayland globals, and so on. */
	dpy = wl_display_create();

	/* clean up child processes immediately */
	/* Set up signal handlers */
	sigchld(0);
	signal(SIGINT, quitsignal);
	signal(SIGTERM, quitsignal);

	/* The backend is a wlroots feature which abstracts the underlying input and
	 * output hardware. The autocreate option will choose the most suitable

Do not follow this link