diff options
| -rw-r--r-- | Makefile | 22 | ||||
| -rw-r--r-- | README.md | 9 | ||||
| -rw-r--r-- | client.h | 11 | ||||
| -rw-r--r-- | dwl.c | 29 | 
4 files changed, 52 insertions, 19 deletions
@@ -11,6 +11,17 @@ LDLIBS += $(foreach p,$(PKGS),$(shell pkg-config --libs $(p)))  all: dwl +clean: +	rm -f dwl *.o *-protocol.h *-protocol.c + +install: dwl +	install -D dwl $(PREFIX)/bin/dwl + +uninstall: +	rm -f $(PREFIX)/bin/dwl + +.PHONY: all clean install uninstall +  # wayland-scanner is a tool which generates C headers and rigging for Wayland  # protocols, which are specified in XML. wlroots requires you to rig these up  # to your build system yourself and provide them in the include path. @@ -47,15 +58,6 @@ idle-protocol.o: idle-protocol.h  config.h: | config.def.h  	cp config.def.h $@ -dwl.o: config.h client.h xdg-shell-protocol.h wlr-layer-shell-unstable-v1-protocol.h idle-protocol.h +dwl.o: config.mk config.h client.h xdg-shell-protocol.h wlr-layer-shell-unstable-v1-protocol.h idle-protocol.h  dwl: xdg-shell-protocol.o wlr-layer-shell-unstable-v1-protocol.o idle-protocol.o - -clean: -	rm -f dwl *.o *-protocol.h *-protocol.c - -install: dwl -	install -D dwl $(PREFIX)/bin/dwl - -.DEFAULT_GOAL=dwl -.PHONY: clean @@ -14,26 +14,27 @@ dwl is not meant to provide every feature under the sun. Instead, like dwm, it s  - Any features provided by dwm/Xlib: simple window borders, tags, keybindings, client rules, mouse move/resize. Providing a built-in status bar is an exception to this goal, to avoid dependencies on font rendering and/or drawing libraries when an external bar could work well.  - Configurable multi-monitor layout support, including position and rotation  - Configurable HiDPI/multi-DPI support +- Provide information to external status bars via stdout/stdin  - Various Wayland protocols -- XWayland support as provided by wlroots +- XWayland support as provided by wlroots (can be enabled in `config.mk`)  - Zero flickering - Wayland users naturally expect that "every frame is perfect"  Features under consideration (possibly as patches) are:  - Protocols made trivial by wlroots -- Provide information to external status bars via stdout or another file descriptor +- Implement urgent/focus-request once the xdg-activation protocol [hits wlroots](https://github.com/swaywm/wlroots/pull/2718)  - Implement the input-inhibitor protocol to support screen lockers  - Implement the idle-inhibit protocol which lets applications such as mpv disable idle monitoring  - Layer shell popups (used by Waybar)  - Basic yes/no damage tracking to avoid needless redraws  - More in-depth damage region tracking ([which may improve power usage](https://mozillagfx.wordpress.com/2019/10/22/dramatically-reduced-power-usage-in-firefox-70-on-macos-with-core-animation/))  - Implement the text-input and input-method protocols to support IME once ibus implements input-method v2 (see https://github.com/ibus/ibus/pull/2256 and https://github.com/djpohly/dwl/pull/12) -- Implement urgent/attention/focus-request once it's part of the xdg-shell protocol (https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/9) -Feature *non-goals* include: +Feature *non-goals* for the main codebase include:  - Client-side decoration (any more than is necessary to tell the clients not to)  - Client-initiated window management, such as move, resize, and close, which can be done through the compositor +- Animations and visual effects  ## Building dwl @@ -141,6 +141,17 @@ client_set_size(Client *c, uint32_t width, uint32_t height)  	return wlr_xdg_toplevel_set_size(c->surface.xdg, width, height);  } +static inline void +client_set_tiled(Client *c, uint32_t edges) +{ +#ifdef XWAYLAND +	if (client_is_x11(c)) +		return; +#endif +	wlr_xdg_toplevel_set_tiled(c->surface.xdg, WLR_EDGE_TOP | +			WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | WLR_EDGE_RIGHT); +} +  static inline struct wlr_surface *  client_surface(Client *c)  { @@ -96,6 +96,7 @@ typedef struct {  	struct wl_listener map;  	struct wl_listener unmap;  	struct wl_listener destroy; +	struct wl_listener set_title;  	struct wl_listener fullscreen;  	struct wlr_box geom;  /* layout-relative, includes border */  	Monitor *mon; @@ -288,6 +289,7 @@ static void unmaplayersurface(LayerSurface *layersurface);  static void unmaplayersurfacenotify(struct wl_listener *listener, void *data);  static void unmapnotify(struct wl_listener *listener, void *data);  static void updatemons(struct wl_listener *listener, void *data); +static void updatetitle(struct wl_listener *listener, void *data);  static void view(const Arg *arg);  static void virtualkeyboard(struct wl_listener *listener, void *data);  static Client *xytoclient(double x, double y); @@ -883,14 +885,11 @@ createnotify(struct wl_listener *listener, void *data)  	c->surface.xdg = xdg_surface;  	c->bw = borderpx; -	/* Tell the client not to try anything fancy */ -	wlr_xdg_toplevel_set_tiled(c->surface.xdg, WLR_EDGE_TOP | -			WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | WLR_EDGE_RIGHT); -  	LISTEN(&xdg_surface->surface->events.commit, &c->commit, commitnotify);  	LISTEN(&xdg_surface->events.map, &c->map, mapnotify);  	LISTEN(&xdg_surface->events.unmap, &c->unmap, unmapnotify);  	LISTEN(&xdg_surface->events.destroy, &c->destroy, destroynotify); +	LISTEN(&xdg_surface->toplevel->events.set_title, &c->set_title, updatetitle);  	LISTEN(&xdg_surface->toplevel->events.request_fullscreen, &c->fullscreen,  			fullscreennotify);  	c->isfullscreen = 0; @@ -994,6 +993,7 @@ destroynotify(struct wl_listener *listener, void *data)  	wl_list_remove(&c->map.link);  	wl_list_remove(&c->unmap.link);  	wl_list_remove(&c->destroy.link); +	wl_list_remove(&c->set_title.link);  	wl_list_remove(&c->fullscreen.link);  #ifdef XWAYLAND  	if (c->type == X11Managed) @@ -1304,6 +1304,9 @@ mapnotify(struct wl_listener *listener, void *data)  	c->geom.width += 2 * c->bw;  	c->geom.height += 2 * c->bw; +	/* Tell the client not to try anything fancy */ +	client_set_tiled(c, WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | WLR_EDGE_RIGHT); +  	/* Set initial monitor, tags, floating status, and focus */  	applyrules(c);  } @@ -1805,15 +1808,22 @@ run(char *startup_cmd)  	setenv("WAYLAND_DISPLAY", socket, 1);  	if (startup_cmd) { +		int piperw[2]; +		pipe(piperw);  		startup_pid = fork();  		if (startup_pid < 0)  			EBARF("startup: fork");  		if (startup_pid == 0) { -			dup2(STDERR_FILENO, STDOUT_FILENO); +			dup2(piperw[0], STDIN_FILENO); +			close(piperw[1]);  			execl("/bin/sh", "/bin/sh", "-c", startup_cmd, NULL);  			EBARF("startup: execl");  		} +		dup2(piperw[1], STDOUT_FILENO); +		close(piperw[0]);  	} +	/* If nobody is reading the status output, don't terminate */ +	signal(SIGPIPE, SIG_IGN);  	/* Run the Wayland event loop. This does not return until you exit the  	 * compositor. Starting the backend rigged up all of the necessary event @@ -2292,6 +2302,14 @@ updatemons(struct wl_listener *listener, void *data)  }  void +updatetitle(struct wl_listener *listener, void *data) +{ +	Client *c = wl_container_of(listener, c, set_title); +	if (c == focustop(c->mon)) +		printstatus(); +} + +void  view(const Arg *arg)  {  	if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) @@ -2427,6 +2445,7 @@ createnotifyx11(struct wl_listener *listener, void *data)  			activatex11);  	LISTEN(&xwayland_surface->events.request_configure, &c->configure,  			configurex11); +	LISTEN(&xwayland_surface->events.set_title, &c->set_title, updatetitle);  	LISTEN(&xwayland_surface->events.destroy, &c->destroy, destroynotify);  	LISTEN(&xwayland_surface->events.request_fullscreen, &c->fullscreen,  			fullscreennotify);  | 
