mirror of
https://codeberg.org/dwl/dwl.git
synced 2026-06-21 06:32:40 +00:00
Compare commits
63 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 31d8a67eda | |||
| b04c73be3d | |||
| 8cdb997126 | |||
| 90a12c90a0 | |||
| e082292606 | |||
| deb48ff48b | |||
| c70db2d06a | |||
| e98719f552 | |||
| af12e777f2 | |||
| 8e03bce621 | |||
| 87fc3a58ab | |||
| 0eff78d6c2 | |||
| c6d97f1db7 | |||
| 829dec6598 | |||
| ff70337c16 | |||
| 7cc6c640e2 | |||
| 72e0a560d9 | |||
| 2aa391361c | |||
| 549335ae54 | |||
| 097b4a30f5 | |||
| c1578bc14d | |||
| 9b84940e37 | |||
| 79ad72413d | |||
| 74fce9d918 | |||
| 553ba5b7c8 | |||
| 4ae6d0f387 | |||
| 2ef5abfb72 | |||
| 8076b47cc6 | |||
| 3a77f02919 | |||
| d26ddfc7fd | |||
| 671a9b450b | |||
| 583f471cfe | |||
| 8bce3b1583 | |||
| c008bf2a7d | |||
| c990dbd441 | |||
| d969289baf | |||
| 50b6630f3d | |||
| 14641560b0 | |||
| 7b42232ad1 | |||
| a5a0674f6a | |||
| 4dfa45659a | |||
| b91017e713 | |||
| 70da04a714 | |||
| 2623a96ebf | |||
| 52e0d00942 | |||
| 7018b9b65c | |||
| 48ec914f43 | |||
| 40449fa64f | |||
| ecbc2c61db | |||
| 8870ba0bb8 | |||
| 5de68ba713 | |||
| 2f8736b986 | |||
| 3c11ad9aa6 | |||
| 06d9230a96 | |||
| 22bd75226b | |||
| 063736f898 | |||
| d5a741c9b4 | |||
| 5d8084daa7 | |||
| 07d56c6d7b | |||
| e0d310fd84 | |||
| 3a4b7d104f | |||
| d071a899f3 | |||
| a48ce99e6a |
@@ -1,64 +1,69 @@
|
|||||||
|
.POSIX:
|
||||||
|
.SUFFIXES:
|
||||||
|
|
||||||
include config.mk
|
include config.mk
|
||||||
|
|
||||||
CFLAGS += -I. -DWLR_USE_UNSTABLE -std=c99 -pedantic
|
# flags for compiling
|
||||||
|
DWLCPPFLAGS = -I. -DWLR_USE_UNSTABLE -DVERSION=\"$(VERSION)\"
|
||||||
|
|
||||||
WAYLAND_PROTOCOLS=$(shell pkg-config --variable=pkgdatadir wayland-protocols)
|
# Wayland utils
|
||||||
WAYLAND_SCANNER=$(shell pkg-config --variable=wayland_scanner wayland-scanner)
|
WAYLAND_PROTOCOLS = `pkg-config --variable=pkgdatadir wayland-protocols`
|
||||||
|
WAYLAND_SCANNER = `pkg-config --variable=wayland_scanner wayland-scanner`
|
||||||
|
|
||||||
PKGS = wlroots wayland-server xcb xkbcommon libinput
|
# CFLAGS / LDFLAGS
|
||||||
CFLAGS += $(foreach p,$(PKGS),$(shell pkg-config --cflags $(p)))
|
PKGS = wlroots wayland-server xkbcommon libinput $(XLIBS)
|
||||||
LDLIBS += $(foreach p,$(PKGS),$(shell pkg-config --libs $(p)))
|
DWLCFLAGS = `pkg-config --cflags $(PKGS)` $(DWLCPPFLAGS) $(CFLAGS) $(XWAYLAND)
|
||||||
|
LDLIBS = `pkg-config --libs $(PKGS)` $(LIBS)
|
||||||
|
|
||||||
all: dwl
|
# build rules
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f dwl *.o *-protocol.h *-protocol.c
|
|
||||||
|
|
||||||
install: dwl
|
|
||||||
install -Dm755 dwl $(DESTDIR)$(PREFIX)/bin/dwl
|
|
||||||
install -Dm644 dwl.1 $(DESTDIR)$(MANDIR)/man1/dwl.1
|
|
||||||
|
|
||||||
uninstall:
|
|
||||||
rm -f $(DESTDIR)$(PREFIX)/bin/dwl $(DESTDIR)$(MANDIR)/man1/dwl.1
|
|
||||||
|
|
||||||
.PHONY: all clean install uninstall
|
|
||||||
|
|
||||||
# wayland-scanner is a tool which generates C headers and rigging for Wayland
|
# 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
|
# 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.
|
# to your build system yourself and provide them in the include path.
|
||||||
|
all: dwl
|
||||||
|
dwl: dwl.o util.o
|
||||||
|
$(CC) dwl.o util.o $(LDLIBS) $(LDFLAGS) $(DWLCFLAGS) -o $@
|
||||||
|
dwl.o: dwl.c config.mk config.h client.h xdg-shell-protocol.h wlr-layer-shell-unstable-v1-protocol.h idle-protocol.h
|
||||||
|
util.o: util.c util.h
|
||||||
|
|
||||||
|
# wayland scanner rules to generate .h / .c files
|
||||||
xdg-shell-protocol.h:
|
xdg-shell-protocol.h:
|
||||||
$(WAYLAND_SCANNER) server-header \
|
$(WAYLAND_SCANNER) server-header \
|
||||||
$(WAYLAND_PROTOCOLS)/stable/xdg-shell/xdg-shell.xml $@
|
$(WAYLAND_PROTOCOLS)/stable/xdg-shell/xdg-shell.xml $@
|
||||||
|
|
||||||
xdg-shell-protocol.c:
|
|
||||||
$(WAYLAND_SCANNER) private-code \
|
|
||||||
$(WAYLAND_PROTOCOLS)/stable/xdg-shell/xdg-shell.xml $@
|
|
||||||
|
|
||||||
xdg-shell-protocol.o: xdg-shell-protocol.h
|
|
||||||
|
|
||||||
wlr-layer-shell-unstable-v1-protocol.h:
|
wlr-layer-shell-unstable-v1-protocol.h:
|
||||||
$(WAYLAND_SCANNER) server-header \
|
$(WAYLAND_SCANNER) server-header \
|
||||||
protocols/wlr-layer-shell-unstable-v1.xml $@
|
protocols/wlr-layer-shell-unstable-v1.xml $@
|
||||||
|
|
||||||
wlr-layer-shell-unstable-v1-protocol.c:
|
|
||||||
$(WAYLAND_SCANNER) private-code \
|
|
||||||
protocols/wlr-layer-shell-unstable-v1.xml $@
|
|
||||||
|
|
||||||
wlr-layer-shell-unstable-v1-protocol.o: wlr-layer-shell-unstable-v1-protocol.h
|
|
||||||
|
|
||||||
idle-protocol.h:
|
idle-protocol.h:
|
||||||
$(WAYLAND_SCANNER) server-header \
|
$(WAYLAND_SCANNER) server-header \
|
||||||
protocols/idle.xml $@
|
protocols/idle.xml $@
|
||||||
|
|
||||||
idle-protocol.c:
|
config.h:
|
||||||
$(WAYLAND_SCANNER) private-code \
|
|
||||||
protocols/idle.xml $@
|
|
||||||
|
|
||||||
idle-protocol.o: idle-protocol.h
|
|
||||||
|
|
||||||
config.h: | config.def.h
|
|
||||||
cp config.def.h $@
|
cp config.def.h $@
|
||||||
|
clean:
|
||||||
|
rm -f dwl *.o *-protocol.h
|
||||||
|
|
||||||
dwl.o: config.mk config.h client.h xdg-shell-protocol.h wlr-layer-shell-unstable-v1-protocol.h idle-protocol.h util.h
|
# distribution archive
|
||||||
|
dist: clean
|
||||||
|
mkdir -p dwl-$(VERSION)
|
||||||
|
cp -R LICENSE* Makefile README.md generate-version.sh client.h\
|
||||||
|
config.def.h config.mk protocols dwl.1 dwl.c util.c util.h\
|
||||||
|
dwl-$(VERSION)
|
||||||
|
echo "echo $(VERSION)" > dwl-$(VERSION)/generate-version.sh
|
||||||
|
tar -caf dwl-$(VERSION).tar.gz dwl-$(VERSION)
|
||||||
|
rm -rf dwl-$(VERSION)
|
||||||
|
|
||||||
dwl: xdg-shell-protocol.o wlr-layer-shell-unstable-v1-protocol.o idle-protocol.o util.o
|
# install rules
|
||||||
|
|
||||||
|
install: dwl
|
||||||
|
mkdir -p $(DESTDIR)$(PREFIX)/bin
|
||||||
|
cp -f dwl $(DESTDIR)$(PREFIX)/bin
|
||||||
|
chmod 755 $(DESTDIR)$(PREFIX)/bin/dwl
|
||||||
|
mkdir -p $(DESTDIR)$(MANDIR)/man1
|
||||||
|
cp -f dwl.1 $(DESTDIR)$(MANDIR)/man1
|
||||||
|
chmod 644 $(DESTDIR)$(MANDIR)/man1/dwl.1
|
||||||
|
uninstall:
|
||||||
|
rm -f $(DESTDIR)$(PREFIX)/bin/dwl $(DESTDIR)$(MANDIR)/man1/dwl.1
|
||||||
|
|
||||||
|
.SUFFIXES: .c .o
|
||||||
|
.c.o:
|
||||||
|
$(CC) $(CPPFLAGS) $(DWLCFLAGS) -c $<
|
||||||
|
|||||||
@@ -37,7 +37,9 @@ Feature *non-goals* for the main codebase include:
|
|||||||
|
|
||||||
## Building dwl
|
## Building dwl
|
||||||
|
|
||||||
dwl has only two dependencies: wlroots and wayland-protocols. Simply install these (and their `-devel` versions if your distro has separate development packages) and run `make`. If you wish to build against a Git version of wlroots, check out the [wlroots-next branch](https://github.com/djpohly/dwl/tree/wlroots-next).
|
dwl has only two dependencies: `wlroots` and `wayland-protocols`.
|
||||||
|
|
||||||
|
Simply install these (and their `-devel` versions if your distro has separate development packages) and run `make`. If you wish to build against a Git version of wlroots, check out the [wlroots-next branch](https://github.com/djpohly/dwl/tree/wlroots-next).
|
||||||
|
|
||||||
To enable XWayland, you should also install xorg-xwayland and uncomment its flag in `config.mk`.
|
To enable XWayland, you should also install xorg-xwayland and uncomment its flag in `config.mk`.
|
||||||
|
|
||||||
@@ -71,6 +73,14 @@ If your startup command is a shell script, you can achieve the same inside the s
|
|||||||
|
|
||||||
exec <&-
|
exec <&-
|
||||||
|
|
||||||
|
Existing dwl-specific status bars and dwl-specific scripts for other status bars include:
|
||||||
|
- [somebar](https://sr.ht/~raphi/somebar/) status bar designed for dwl
|
||||||
|
- [dtaobarv2.sh](https://cdn.discordapp.com/attachments/792078050024095745/862428883423723560/dtaobarv2.sh) for use with [dtao](https://github.com/djpohly/dtao) (See "Pinned Messages" on the "customizations" channel of the [dwl Discord server](https://discord.gg/jJxZnrGPWN) for details.)
|
||||||
|
- [dwlbar.sh](https://cdn.discordapp.com/attachments/792078050024095745/810926218529472592/dwlbar.sh) for use with [waybar](https://github.com/Alexays/Waybar) (See "Pinned Messages" on the "customizations" channel of the [dwl Discord server](https://discord.gg/jJxZnrGPWN) for details.)
|
||||||
|
- [waybar-dwl](https://codeberg.org/fauxmight/waybar-dwl.git) for use with [waybar](https://github.com/Alexays/Waybar)
|
||||||
|
- [dwl-tags.sh](https://codeberg.org/novakane/yambar/src/branch/master/examples/scripts/dwl-tags.sh) for use with [yambar](https://codeberg.org/dnkl/yambar)
|
||||||
|
- [waybar-dwl.sh](https://gitee.com/guyuming76/personal/tree/dwl/gentoo/waybar-dwl) for use with [waybar](https://github.com/Alexays/Waybar) (ACCESS TO THIS SCRIPT REQUIRES gitee.com LOGIN!)
|
||||||
|
|
||||||
## Replacements for X applications
|
## Replacements for X applications
|
||||||
|
|
||||||
You can find a [list of Wayland applications on the sway wiki](https://github.com/swaywm/sway/wiki/i3-Migration-Guide).
|
You can find a [list of Wayland applications on the sway wiki](https://github.com/swaywm/sway/wiki/i3-Migration-Guide).
|
||||||
|
|||||||
@@ -26,20 +26,42 @@ client_surface(Client *c)
|
|||||||
return c->surface.xdg->surface;
|
return c->surface.xdg->surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline Client *
|
||||||
|
client_from_wlr_surface(struct wlr_surface *s)
|
||||||
|
{
|
||||||
|
struct wlr_xdg_surface *surface;
|
||||||
|
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
struct wlr_xwayland_surface *xsurface;
|
||||||
|
if (s && wlr_surface_is_xwayland_surface(s)
|
||||||
|
&& (xsurface = wlr_xwayland_surface_from_wlr_surface(s)))
|
||||||
|
return xsurface->data;
|
||||||
|
#endif
|
||||||
|
if (s && wlr_surface_is_xdg_surface(s)
|
||||||
|
&& (surface = wlr_xdg_surface_from_wlr_surface(s))
|
||||||
|
&& surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL)
|
||||||
|
return surface->data;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* The others */
|
/* The others */
|
||||||
static inline void
|
static inline void
|
||||||
client_activate_surface(struct wlr_surface *s, int activated)
|
client_activate_surface(struct wlr_surface *s, int activated)
|
||||||
{
|
{
|
||||||
|
struct wlr_xdg_surface *surface;
|
||||||
#ifdef XWAYLAND
|
#ifdef XWAYLAND
|
||||||
if (wlr_surface_is_xwayland_surface(s)) {
|
struct wlr_xwayland_surface *xsurface;
|
||||||
wlr_xwayland_surface_activate(
|
if (wlr_surface_is_xwayland_surface(s)
|
||||||
wlr_xwayland_surface_from_wlr_surface(s), activated);
|
&& (xsurface = wlr_xwayland_surface_from_wlr_surface(s))) {
|
||||||
|
wlr_xwayland_surface_activate(xsurface, activated);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (wlr_surface_is_xdg_surface(s))
|
if (wlr_surface_is_xdg_surface(s)
|
||||||
wlr_xdg_toplevel_set_activated(
|
&& (surface = wlr_xdg_surface_from_wlr_surface(s))
|
||||||
wlr_xdg_surface_from_wlr_surface(s), activated);
|
&& surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL)
|
||||||
|
wlr_xdg_toplevel_set_activated(surface, activated);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
@@ -78,6 +100,32 @@ client_get_geometry(Client *c, struct wlr_box *geom)
|
|||||||
wlr_xdg_surface_get_geometry(c->surface.xdg, geom);
|
wlr_xdg_surface_get_geometry(c->surface.xdg, geom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
client_get_size_hints(Client *c, struct wlr_box *max, struct wlr_box *min)
|
||||||
|
{
|
||||||
|
struct wlr_xdg_toplevel *toplevel;
|
||||||
|
struct wlr_xdg_toplevel_state *state;
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
if (client_is_x11(c)) {
|
||||||
|
struct wlr_xwayland_surface_size_hints *size_hints;
|
||||||
|
size_hints = c->surface.xwayland->size_hints;
|
||||||
|
if (size_hints) {
|
||||||
|
max->width = size_hints->max_width;
|
||||||
|
max->height = size_hints->max_height;
|
||||||
|
min->width = size_hints->min_width;
|
||||||
|
min->height = size_hints->min_height;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
toplevel = c->surface.xdg->toplevel;
|
||||||
|
state = &toplevel->current;
|
||||||
|
max->width = state->max_width;
|
||||||
|
max->height = state->max_height;
|
||||||
|
min->width = state->min_width;
|
||||||
|
min->height = state->min_height;
|
||||||
|
}
|
||||||
|
|
||||||
static inline const char *
|
static inline const char *
|
||||||
client_get_title(Client *c)
|
client_get_title(Client *c)
|
||||||
{
|
{
|
||||||
@@ -88,42 +136,48 @@ client_get_title(Client *c)
|
|||||||
return c->surface.xdg->toplevel->title;
|
return c->surface.xdg->toplevel->title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline Client *
|
||||||
|
client_get_parent(Client *c)
|
||||||
|
{
|
||||||
|
Client *p;
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
if (client_is_x11(c) && c->surface.xwayland->parent)
|
||||||
|
return client_from_wlr_surface(c->surface.xwayland->parent->surface);
|
||||||
|
#endif
|
||||||
|
if (c->surface.xdg->toplevel->parent)
|
||||||
|
return client_from_wlr_surface(c->surface.xdg->toplevel->parent->surface);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
client_is_float_type(Client *c)
|
client_is_float_type(Client *c)
|
||||||
{
|
{
|
||||||
struct wlr_xdg_toplevel *toplevel;
|
struct wlr_box min = {0}, max = {0};
|
||||||
struct wlr_xdg_toplevel_state state;
|
client_get_size_hints(c, &max, &min);
|
||||||
|
|
||||||
#ifdef XWAYLAND
|
#ifdef XWAYLAND
|
||||||
if (client_is_x11(c)) {
|
if (client_is_x11(c)) {
|
||||||
struct wlr_xwayland_surface *surface = c->surface.xwayland;
|
struct wlr_xwayland_surface *surface = c->surface.xwayland;
|
||||||
struct wlr_xwayland_surface_size_hints *size_hints;
|
|
||||||
if (surface->modal)
|
if (surface->modal)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
for (size_t i = 0; i < surface->window_type_len; i++)
|
for (size_t i = 0; i < surface->window_type_len; i++)
|
||||||
if (surface->window_type[i] == netatom[NetWMWindowTypeDialog] ||
|
if (surface->window_type[i] == netatom[NetWMWindowTypeDialog]
|
||||||
surface->window_type[i] == netatom[NetWMWindowTypeSplash] ||
|
|| surface->window_type[i] == netatom[NetWMWindowTypeSplash]
|
||||||
surface->window_type[i] == netatom[NetWMWindowTypeToolbar] ||
|
|| surface->window_type[i] == netatom[NetWMWindowTypeToolbar]
|
||||||
surface->window_type[i] == netatom[NetWMWindowTypeUtility])
|
|| surface->window_type[i] == netatom[NetWMWindowTypeUtility])
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
size_hints = surface->size_hints;
|
return ((min.width > 0 || min.height > 0 || max.width > 0 || max.height > 0)
|
||||||
if (size_hints && size_hints->min_width > 0 && size_hints->min_height > 0
|
&& (min.width == max.width || min.height == max.height))
|
||||||
&& (size_hints->max_width == size_hints->min_width ||
|
|| c->surface.xwayland->parent;
|
||||||
size_hints->max_height == size_hints->min_height))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
toplevel = c->surface.xdg->toplevel;
|
return ((min.width > 0 || min.height > 0 || max.width > 0 || max.height > 0)
|
||||||
state = toplevel->current;
|
&& (min.width == max.width || min.height == max.height))
|
||||||
return (state.min_width != 0 && state.min_height != 0
|
|| c->surface.xdg->toplevel->parent;
|
||||||
&& (state.min_width == state.max_width
|
|
||||||
|| state.min_height == state.max_height))
|
|
||||||
|| toplevel->parent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
@@ -204,34 +258,27 @@ client_surface_at(Client *c, double cx, double cy, double *sx, double *sy)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
client_min_size(Client *c, int *width, int *height)
|
client_restack_surface(Client *c)
|
||||||
{
|
{
|
||||||
struct wlr_xdg_toplevel *toplevel;
|
|
||||||
struct wlr_xdg_toplevel_state *state;
|
|
||||||
#ifdef XWAYLAND
|
#ifdef XWAYLAND
|
||||||
if (client_is_x11(c)) {
|
if (client_is_x11(c))
|
||||||
struct wlr_xwayland_surface_size_hints *size_hints;
|
wlr_xwayland_surface_restack(c->surface.xwayland, NULL,
|
||||||
size_hints = c->surface.xwayland->size_hints;
|
XCB_STACK_MODE_ABOVE);
|
||||||
*width = size_hints->min_width;
|
|
||||||
*height = size_hints->min_height;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
toplevel = c->surface.xdg->toplevel;
|
return;
|
||||||
state = &toplevel->current;
|
|
||||||
*width = state->min_width;
|
|
||||||
*height = state->min_height;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Client *
|
static inline void *
|
||||||
client_from_popup(struct wlr_xdg_popup *popup)
|
toplevel_from_popup(struct wlr_xdg_popup *popup)
|
||||||
{
|
{
|
||||||
struct wlr_xdg_surface *surface = popup->base;
|
struct wlr_xdg_surface *surface = popup->base;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
switch (surface->role) {
|
switch (surface->role) {
|
||||||
case WLR_XDG_SURFACE_ROLE_POPUP:
|
case WLR_XDG_SURFACE_ROLE_POPUP:
|
||||||
if (!wlr_surface_is_xdg_surface(surface->popup->parent))
|
if (wlr_surface_is_layer_surface(surface->popup->parent))
|
||||||
|
return wlr_layer_surface_v1_from_wlr_surface(surface->popup->parent)->data;
|
||||||
|
else if (!wlr_surface_is_xdg_surface(surface->popup->parent))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
surface = wlr_xdg_surface_from_wlr_surface(surface->popup->parent);
|
surface = wlr_xdg_surface_from_wlr_surface(surface->popup->parent);
|
||||||
|
|||||||
+53
-18
@@ -5,6 +5,8 @@ static const int lockfullscreen = 1; /* 1 will force focus on the fullscree
|
|||||||
static const float rootcolor[] = {0.3, 0.3, 0.3, 1.0};
|
static const float rootcolor[] = {0.3, 0.3, 0.3, 1.0};
|
||||||
static const float bordercolor[] = {0.5, 0.5, 0.5, 1.0};
|
static const float bordercolor[] = {0.5, 0.5, 0.5, 1.0};
|
||||||
static const float focuscolor[] = {1.0, 0.0, 0.0, 1.0};
|
static const float focuscolor[] = {1.0, 0.0, 0.0, 1.0};
|
||||||
|
/* To conform the xdg-protocol, set the alpha to zero to restore the old behavior */
|
||||||
|
static const float fullscreen_bg[] = {0.1, 0.1, 0.1, 1.0};
|
||||||
|
|
||||||
/* tagging */
|
/* tagging */
|
||||||
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
|
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
|
||||||
@@ -41,7 +43,7 @@ static const struct xkb_rule_names xkb_rules = {
|
|||||||
/* example:
|
/* example:
|
||||||
.options = "ctrl:nocaps",
|
.options = "ctrl:nocaps",
|
||||||
*/
|
*/
|
||||||
.options = "",
|
.options = NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int repeat_rate = 25;
|
static const int repeat_rate = 25;
|
||||||
@@ -49,15 +51,48 @@ static const int repeat_delay = 600;
|
|||||||
|
|
||||||
/* Trackpad */
|
/* Trackpad */
|
||||||
static const int tap_to_click = 1;
|
static const int tap_to_click = 1;
|
||||||
|
static const int tap_and_drag = 1;
|
||||||
|
static const int drag_lock = 1;
|
||||||
static const int natural_scrolling = 0;
|
static const int natural_scrolling = 0;
|
||||||
|
static const int disable_while_typing = 1;
|
||||||
|
static const int left_handed = 0;
|
||||||
|
static const int middle_button_emulation = 0;
|
||||||
|
/* You can choose between:
|
||||||
|
LIBINPUT_CONFIG_SCROLL_NO_SCROLL
|
||||||
|
LIBINPUT_CONFIG_SCROLL_2FG
|
||||||
|
LIBINPUT_CONFIG_SCROLL_EDGE
|
||||||
|
LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN
|
||||||
|
*/
|
||||||
|
static const enum libinput_config_scroll_method scroll_method = LIBINPUT_CONFIG_SCROLL_2FG;
|
||||||
|
|
||||||
|
/* You can choose between:
|
||||||
|
LIBINPUT_CONFIG_CLICK_METHOD_NONE
|
||||||
|
LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS
|
||||||
|
LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER
|
||||||
|
*/
|
||||||
|
static const enum libinput_config_click_method click_method = LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS;
|
||||||
|
|
||||||
|
/* You can choose between:
|
||||||
|
LIBINPUT_CONFIG_SEND_EVENTS_ENABLED
|
||||||
|
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED
|
||||||
|
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE
|
||||||
|
*/
|
||||||
|
static const uint32_t send_events_mode = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
|
||||||
|
|
||||||
|
/* You can choose between:
|
||||||
|
LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT
|
||||||
|
LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE
|
||||||
|
*/
|
||||||
|
static const enum libinput_config_accel_profile accel_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE;
|
||||||
|
static const double accel_speed = 0.0;
|
||||||
|
|
||||||
/* If you want to use the windows key change this to WLR_MODIFIER_LOGO */
|
/* If you want to use the windows key change this to WLR_MODIFIER_LOGO */
|
||||||
#define MODKEY WLR_MODIFIER_ALT
|
#define MODKEY WLR_MODIFIER_ALT
|
||||||
#define TAGKEYS(KEY,SKEY,TAG) \
|
#define TAGKEYS(KEY,TAG) \
|
||||||
{ MODKEY, KEY, view, {.ui = 1 << TAG} }, \
|
{ MODKEY, KEY, view, {.ui = 1 << TAG} }, \
|
||||||
{ MODKEY|WLR_MODIFIER_CTRL, KEY, toggleview, {.ui = 1 << TAG} }, \
|
{ MODKEY|WLR_MODIFIER_CTRL, KEY, toggleview, {.ui = 1 << TAG} }, \
|
||||||
{ MODKEY|WLR_MODIFIER_SHIFT, SKEY, tag, {.ui = 1 << TAG} }, \
|
{ MODKEY|WLR_MODIFIER_SHIFT, KEY, tag, {.ui = 1 << TAG} }, \
|
||||||
{ MODKEY|WLR_MODIFIER_CTRL|WLR_MODIFIER_SHIFT,SKEY,toggletag, {.ui = 1 << TAG} }
|
{ MODKEY|WLR_MODIFIER_CTRL|WLR_MODIFIER_SHIFT,KEY,toggletag, {.ui = 1 << TAG} }
|
||||||
|
|
||||||
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
|
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
|
||||||
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
|
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
|
||||||
@@ -79,7 +114,7 @@ static const Key keys[] = {
|
|||||||
{ MODKEY, XKB_KEY_l, setmfact, {.f = +0.05} },
|
{ MODKEY, XKB_KEY_l, setmfact, {.f = +0.05} },
|
||||||
{ MODKEY, XKB_KEY_Return, zoom, {0} },
|
{ MODKEY, XKB_KEY_Return, zoom, {0} },
|
||||||
{ MODKEY, XKB_KEY_Tab, view, {0} },
|
{ MODKEY, XKB_KEY_Tab, view, {0} },
|
||||||
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_C, killclient, {0} },
|
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_c, killclient, {0} },
|
||||||
{ MODKEY, XKB_KEY_t, setlayout, {.v = &layouts[0]} },
|
{ MODKEY, XKB_KEY_t, setlayout, {.v = &layouts[0]} },
|
||||||
{ MODKEY, XKB_KEY_f, setlayout, {.v = &layouts[1]} },
|
{ MODKEY, XKB_KEY_f, setlayout, {.v = &layouts[1]} },
|
||||||
{ MODKEY, XKB_KEY_m, setlayout, {.v = &layouts[2]} },
|
{ MODKEY, XKB_KEY_m, setlayout, {.v = &layouts[2]} },
|
||||||
@@ -87,21 +122,21 @@ static const Key keys[] = {
|
|||||||
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} },
|
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} },
|
||||||
{ MODKEY, XKB_KEY_e, togglefullscreen, {0} },
|
{ MODKEY, XKB_KEY_e, togglefullscreen, {0} },
|
||||||
{ MODKEY, XKB_KEY_0, view, {.ui = ~0} },
|
{ MODKEY, XKB_KEY_0, view, {.ui = ~0} },
|
||||||
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_parenright, tag, {.ui = ~0} },
|
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_0, tag, {.ui = ~0} },
|
||||||
{ MODKEY, XKB_KEY_comma, focusmon, {.i = WLR_DIRECTION_LEFT} },
|
{ MODKEY, XKB_KEY_comma, focusmon, {.i = WLR_DIRECTION_LEFT} },
|
||||||
{ MODKEY, XKB_KEY_period, focusmon, {.i = WLR_DIRECTION_RIGHT} },
|
{ MODKEY, XKB_KEY_period, focusmon, {.i = WLR_DIRECTION_RIGHT} },
|
||||||
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_less, tagmon, {.i = WLR_DIRECTION_LEFT} },
|
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_comma, tagmon, {.i = WLR_DIRECTION_LEFT} },
|
||||||
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_greater, tagmon, {.i = WLR_DIRECTION_RIGHT} },
|
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_period, tagmon, {.i = WLR_DIRECTION_RIGHT} },
|
||||||
TAGKEYS( XKB_KEY_1, XKB_KEY_exclam, 0),
|
TAGKEYS( XKB_KEY_1, 0),
|
||||||
TAGKEYS( XKB_KEY_2, XKB_KEY_at, 1),
|
TAGKEYS( XKB_KEY_2, 1),
|
||||||
TAGKEYS( XKB_KEY_3, XKB_KEY_numbersign, 2),
|
TAGKEYS( XKB_KEY_3, 2),
|
||||||
TAGKEYS( XKB_KEY_4, XKB_KEY_dollar, 3),
|
TAGKEYS( XKB_KEY_4, 3),
|
||||||
TAGKEYS( XKB_KEY_5, XKB_KEY_percent, 4),
|
TAGKEYS( XKB_KEY_5, 4),
|
||||||
TAGKEYS( XKB_KEY_6, XKB_KEY_asciicircum, 5),
|
TAGKEYS( XKB_KEY_6, 5),
|
||||||
TAGKEYS( XKB_KEY_7, XKB_KEY_ampersand, 6),
|
TAGKEYS( XKB_KEY_7, 6),
|
||||||
TAGKEYS( XKB_KEY_8, XKB_KEY_asterisk, 7),
|
TAGKEYS( XKB_KEY_8, 7),
|
||||||
TAGKEYS( XKB_KEY_9, XKB_KEY_parenleft, 8),
|
TAGKEYS( XKB_KEY_9, 8),
|
||||||
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Q, quit, {0} },
|
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_q, quit, {0} },
|
||||||
|
|
||||||
/* Ctrl-Alt-Backspace and Ctrl-Alt-Fx used to be handled by X server */
|
/* Ctrl-Alt-Backspace and Ctrl-Alt-Fx used to be handled by X server */
|
||||||
{ WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_Terminate_Server, quit, {0} },
|
{ WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_Terminate_Server, quit, {0} },
|
||||||
|
|||||||
@@ -1,9 +1,15 @@
|
|||||||
|
_VERSION = 0.3.1
|
||||||
|
VERSION = `./generate-version.sh $(_VERSION)`
|
||||||
|
|
||||||
# paths
|
# paths
|
||||||
PREFIX = /usr/local
|
PREFIX = /usr/local
|
||||||
MANDIR = $(PREFIX)/share/man
|
MANDIR = $(PREFIX)/share/man
|
||||||
|
|
||||||
# Default compile flags (overridable by environment)
|
# Compile flags that can be used
|
||||||
CFLAGS ?= -g -Wall -Wextra -Werror -Wno-unused-parameter -Wno-sign-compare -Wno-unused-function -Wno-unused-variable -Wno-unused-result -Wdeclaration-after-statement
|
#CFLAGS = -pedantic -Wall -Wextra -Werror -Wno-unused-parameter -Wno-sign-compare -Wno-unused-function -Wno-unused-variable -Wno-unused-result -Wdeclaration-after-statement
|
||||||
|
|
||||||
|
XWAYLAND =
|
||||||
|
XLIBS =
|
||||||
# Uncomment to build XWayland support
|
# Uncomment to build XWayland support
|
||||||
#CFLAGS += -DXWAYLAND
|
#XWAYLAND = -DXWAYLAND
|
||||||
|
#XLIBS = xcb
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
.Nd dwm for Wayland
|
.Nd dwm for Wayland
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm
|
.Nm
|
||||||
.Op Fl s Ar command
|
.Op Fl v
|
||||||
|
.Op Fl s Ar startup command
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
.Nm
|
.Nm
|
||||||
is a Wayland compositor based on wlroots.
|
is a Wayland compositor based on wlroots.
|
||||||
@@ -15,6 +16,12 @@ It is intended to fill the same space in the Wayland world that
|
|||||||
does for X11.
|
does for X11.
|
||||||
.Pp
|
.Pp
|
||||||
When given the
|
When given the
|
||||||
|
.Fl v
|
||||||
|
option,
|
||||||
|
.Nm
|
||||||
|
writes its name and version to standard error and exits unsuccessfully.
|
||||||
|
.Pp
|
||||||
|
When given the
|
||||||
.Fl s
|
.Fl s
|
||||||
option,
|
option,
|
||||||
.Nm
|
.Nm
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#define _POSIX_C_SOURCE 200809L
|
#define _POSIX_C_SOURCE 200809L
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <libinput.h>
|
#include <libinput.h>
|
||||||
|
#include <limits.h>
|
||||||
#include <linux/input-event-codes.h>
|
#include <linux/input-event-codes.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -90,11 +91,14 @@ typedef struct {
|
|||||||
|
|
||||||
typedef struct Monitor Monitor;
|
typedef struct Monitor Monitor;
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* Must be first */
|
/* Must keep these three elements in this order */
|
||||||
unsigned int type; /* XDGShell or X11* */
|
unsigned int type; /* XDGShell or X11* */
|
||||||
|
struct wlr_box geom; /* layout-relative, includes border */
|
||||||
|
Monitor *mon;
|
||||||
struct wlr_scene_node *scene;
|
struct wlr_scene_node *scene;
|
||||||
struct wlr_scene_rect *border[4]; /* top, bottom, left, right */
|
struct wlr_scene_rect *border[4]; /* top, bottom, left, right */
|
||||||
struct wlr_scene_node *scene_surface;
|
struct wlr_scene_node *scene_surface;
|
||||||
|
struct wlr_scene_rect *fullscreen_bg; /* See setfullscreen() for info */
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
struct wl_list flink;
|
struct wl_list flink;
|
||||||
union {
|
union {
|
||||||
@@ -107,11 +111,11 @@ typedef struct {
|
|||||||
struct wl_listener destroy;
|
struct wl_listener destroy;
|
||||||
struct wl_listener set_title;
|
struct wl_listener set_title;
|
||||||
struct wl_listener fullscreen;
|
struct wl_listener fullscreen;
|
||||||
struct wlr_box geom, prev; /* layout-relative, includes border */
|
struct wlr_box prev; /* layout-relative, includes border */
|
||||||
Monitor *mon;
|
|
||||||
#ifdef XWAYLAND
|
#ifdef XWAYLAND
|
||||||
struct wl_listener activate;
|
struct wl_listener activate;
|
||||||
struct wl_listener configure;
|
struct wl_listener configure;
|
||||||
|
struct wl_listener set_hints;
|
||||||
#endif
|
#endif
|
||||||
int bw;
|
int bw;
|
||||||
unsigned int tags;
|
unsigned int tags;
|
||||||
@@ -145,19 +149,19 @@ typedef struct {
|
|||||||
} Keyboard;
|
} Keyboard;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* Must be first */
|
/* Must keep these three elements in this order */
|
||||||
unsigned int type; /* LayerShell */
|
unsigned int type; /* LayerShell */
|
||||||
int mapped;
|
struct wlr_box geom;
|
||||||
|
Monitor *mon;
|
||||||
struct wlr_scene_node *scene;
|
struct wlr_scene_node *scene;
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
|
int mapped;
|
||||||
struct wlr_layer_surface_v1 *layer_surface;
|
struct wlr_layer_surface_v1 *layer_surface;
|
||||||
|
|
||||||
struct wl_listener destroy;
|
struct wl_listener destroy;
|
||||||
struct wl_listener map;
|
struct wl_listener map;
|
||||||
struct wl_listener unmap;
|
struct wl_listener unmap;
|
||||||
struct wl_listener surface_commit;
|
struct wl_listener surface_commit;
|
||||||
|
|
||||||
struct wlr_box geo;
|
|
||||||
} LayerSurface;
|
} LayerSurface;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -259,7 +263,7 @@ static void quit(const Arg *arg);
|
|||||||
static void quitsignal(int signo);
|
static void quitsignal(int signo);
|
||||||
static void rendermon(struct wl_listener *listener, void *data);
|
static void rendermon(struct wl_listener *listener, void *data);
|
||||||
static void requeststartdrag(struct wl_listener *listener, void *data);
|
static void requeststartdrag(struct wl_listener *listener, void *data);
|
||||||
static void resize(Client *c, int x, int y, int w, int h, int interact);
|
static void resize(Client *c, struct wlr_box geo, int interact);
|
||||||
static void run(char *startup_cmd);
|
static void run(char *startup_cmd);
|
||||||
static Client *selclient(void);
|
static Client *selclient(void);
|
||||||
static void setcursor(struct wl_listener *listener, void *data);
|
static void setcursor(struct wl_listener *listener, void *data);
|
||||||
@@ -281,7 +285,6 @@ static void togglefloating(const Arg *arg);
|
|||||||
static void togglefullscreen(const Arg *arg);
|
static void togglefullscreen(const Arg *arg);
|
||||||
static void toggletag(const Arg *arg);
|
static void toggletag(const Arg *arg);
|
||||||
static void toggleview(const Arg *arg);
|
static void toggleview(const Arg *arg);
|
||||||
static void unmaplayersurface(LayerSurface *layersurface);
|
|
||||||
static void unmaplayersurfacenotify(struct wl_listener *listener, void *data);
|
static void unmaplayersurfacenotify(struct wl_listener *listener, void *data);
|
||||||
static void unmapnotify(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 updatemons(struct wl_listener *listener, void *data);
|
||||||
@@ -296,6 +299,8 @@ static void zoom(const Arg *arg);
|
|||||||
|
|
||||||
/* variables */
|
/* variables */
|
||||||
static const char broken[] = "broken";
|
static const char broken[] = "broken";
|
||||||
|
static pid_t child_pid = -1;
|
||||||
|
static struct wlr_surface *exclusive_focus;
|
||||||
static struct wl_display *dpy;
|
static struct wl_display *dpy;
|
||||||
static struct wlr_backend *backend;
|
static struct wlr_backend *backend;
|
||||||
static struct wlr_scene *scene;
|
static struct wlr_scene *scene;
|
||||||
@@ -358,6 +363,7 @@ static void activatex11(struct wl_listener *listener, void *data);
|
|||||||
static void configurex11(struct wl_listener *listener, void *data);
|
static void configurex11(struct wl_listener *listener, void *data);
|
||||||
static void createnotifyx11(struct wl_listener *listener, void *data);
|
static void createnotifyx11(struct wl_listener *listener, void *data);
|
||||||
static Atom getatom(xcb_connection_t *xc, const char *name);
|
static Atom getatom(xcb_connection_t *xc, const char *name);
|
||||||
|
static void sethints(struct wl_listener *listener, void *data);
|
||||||
static void xwaylandready(struct wl_listener *listener, void *data);
|
static void xwaylandready(struct wl_listener *listener, void *data);
|
||||||
static struct wl_listener new_xwayland_surface = {.notify = createnotifyx11};
|
static struct wl_listener new_xwayland_surface = {.notify = createnotifyx11};
|
||||||
static struct wl_listener xwayland_ready = {.notify = xwaylandready};
|
static struct wl_listener xwayland_ready = {.notify = xwaylandready};
|
||||||
@@ -378,9 +384,15 @@ struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
|
|||||||
void
|
void
|
||||||
applybounds(Client *c, struct wlr_box *bbox)
|
applybounds(Client *c, struct wlr_box *bbox)
|
||||||
{
|
{
|
||||||
/* set minimum possible */
|
struct wlr_box min = {0}, max = {0};
|
||||||
c->geom.width = MAX(1, c->geom.width);
|
client_get_size_hints(c, &max, &min);
|
||||||
c->geom.height = MAX(1, c->geom.height);
|
/* try to set size hints */
|
||||||
|
c->geom.width = MAX(min.width + (2 * c->bw), c->geom.width);
|
||||||
|
c->geom.height = MAX(min.height + (2 * c->bw), c->geom.height);
|
||||||
|
if (max.width > 0 && !(2 * c->bw > INT_MAX - max.width)) // Checks for overflow
|
||||||
|
c->geom.width = MIN(max.width + (2 * c->bw), c->geom.width);
|
||||||
|
if (max.height > 0 && !(2 * c->bw > INT_MAX - max.height)) // Checks for overflow
|
||||||
|
c->geom.height = MIN(max.height + (2 * c->bw), c->geom.height);
|
||||||
|
|
||||||
if (c->geom.x >= bbox->x + bbox->width)
|
if (c->geom.x >= bbox->x + bbox->width)
|
||||||
c->geom.x = bbox->x + bbox->width - c->geom.width;
|
c->geom.x = bbox->x + bbox->width - c->geom.width;
|
||||||
@@ -486,7 +498,7 @@ arrange(Monitor *m)
|
|||||||
|
|
||||||
if (m->lt[m->sellt]->arrange)
|
if (m->lt[m->sellt]->arrange)
|
||||||
m->lt[m->sellt]->arrange(m);
|
m->lt[m->sellt]->arrange(m);
|
||||||
/* TODO recheck pointer focus here... or in resize()? */
|
motionnotify(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -556,7 +568,7 @@ arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area, int
|
|||||||
wlr_layer_surface_v1_destroy(wlr_layer_surface);
|
wlr_layer_surface_v1_destroy(wlr_layer_surface);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
layersurface->geo = box;
|
layersurface->geom = box;
|
||||||
|
|
||||||
if (state->exclusive_zone > 0)
|
if (state->exclusive_zone > 0)
|
||||||
applyexclusive(usable_area, state->anchor, state->exclusive_zone,
|
applyexclusive(usable_area, state->anchor, state->exclusive_zone,
|
||||||
@@ -600,8 +612,12 @@ arrangelayers(Monitor *m)
|
|||||||
layersurface->layer_surface->mapped) {
|
layersurface->layer_surface->mapped) {
|
||||||
/* Deactivate the focused client. */
|
/* Deactivate the focused client. */
|
||||||
focusclient(NULL, 0);
|
focusclient(NULL, 0);
|
||||||
wlr_seat_keyboard_notify_enter(seat, layersurface->layer_surface->surface,
|
exclusive_focus = layersurface->layer_surface->surface;
|
||||||
|
if (kb)
|
||||||
|
wlr_seat_keyboard_notify_enter(seat, exclusive_focus,
|
||||||
kb->keycodes, kb->num_keycodes, &kb->modifiers);
|
kb->keycodes, kb->num_keycodes, &kb->modifiers);
|
||||||
|
else
|
||||||
|
wlr_seat_keyboard_notify_enter(seat, exclusive_focus, NULL, 0, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -641,7 +657,7 @@ buttonpress(struct wl_listener *listener, void *data)
|
|||||||
focusclient(c, 1);
|
focusclient(c, 1);
|
||||||
|
|
||||||
keyboard = wlr_seat_get_keyboard(seat);
|
keyboard = wlr_seat_get_keyboard(seat);
|
||||||
mods = wlr_keyboard_get_modifiers(keyboard);
|
mods = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0;
|
||||||
for (b = buttons; b < END(buttons); b++) {
|
for (b = buttons; b < END(buttons); b++) {
|
||||||
if (CLEANMASK(mods) == CLEANMASK(b->mod) &&
|
if (CLEANMASK(mods) == CLEANMASK(b->mod) &&
|
||||||
event->button == b->button && b->func) {
|
event->button == b->button && b->func) {
|
||||||
@@ -682,7 +698,10 @@ cleanup(void)
|
|||||||
wlr_xwayland_destroy(xwayland);
|
wlr_xwayland_destroy(xwayland);
|
||||||
#endif
|
#endif
|
||||||
wl_display_destroy_clients(dpy);
|
wl_display_destroy_clients(dpy);
|
||||||
|
if (child_pid > 0) {
|
||||||
|
kill(child_pid, SIGTERM);
|
||||||
|
waitpid(child_pid, NULL, 0);
|
||||||
|
}
|
||||||
wlr_backend_destroy(backend);
|
wlr_backend_destroy(backend);
|
||||||
wlr_xcursor_manager_destroy(cursor_mgr);
|
wlr_xcursor_manager_destroy(cursor_mgr);
|
||||||
wlr_cursor_destroy(cursor);
|
wlr_cursor_destroy(cursor);
|
||||||
@@ -735,11 +754,12 @@ closemon(Monitor *m)
|
|||||||
|
|
||||||
wl_list_for_each(c, &clients, link) {
|
wl_list_for_each(c, &clients, link) {
|
||||||
if (c->isfloating && c->geom.x > m->m.width)
|
if (c->isfloating && c->geom.x > m->m.width)
|
||||||
resize(c, c->geom.x - m->w.width, c->geom.y,
|
resize(c, (struct wlr_box){.x = c->geom.x - m->w.width, .y = c->geom.y,
|
||||||
c->geom.width, c->geom.height, 0);
|
.width = c->geom.width, .height = c->geom.height}, 0);
|
||||||
if (c->mon == m)
|
if (c->mon == m)
|
||||||
setmon(c, selmon, c->tags);
|
setmon(c, selmon, c->tags);
|
||||||
}
|
}
|
||||||
|
printstatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -748,14 +768,13 @@ commitlayersurfacenotify(struct wl_listener *listener, void *data)
|
|||||||
LayerSurface *layersurface = wl_container_of(listener, layersurface, surface_commit);
|
LayerSurface *layersurface = wl_container_of(listener, layersurface, surface_commit);
|
||||||
struct wlr_layer_surface_v1 *wlr_layer_surface = layersurface->layer_surface;
|
struct wlr_layer_surface_v1 *wlr_layer_surface = layersurface->layer_surface;
|
||||||
struct wlr_output *wlr_output = wlr_layer_surface->output;
|
struct wlr_output *wlr_output = wlr_layer_surface->output;
|
||||||
Monitor *m;
|
|
||||||
|
if (!wlr_output || !(layersurface->mon = wlr_output->data))
|
||||||
|
return;
|
||||||
|
|
||||||
wlr_scene_node_reparent(layersurface->scene,
|
wlr_scene_node_reparent(layersurface->scene,
|
||||||
layers[wlr_layer_surface->current.layer]);
|
layers[wlr_layer_surface->current.layer]);
|
||||||
|
|
||||||
if (!wlr_output || !(m = wlr_output->data))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (wlr_layer_surface->current.committed == 0
|
if (wlr_layer_surface->current.committed == 0
|
||||||
&& layersurface->mapped == wlr_layer_surface->mapped)
|
&& layersurface->mapped == wlr_layer_surface->mapped)
|
||||||
return;
|
return;
|
||||||
@@ -764,19 +783,27 @@ commitlayersurfacenotify(struct wl_listener *listener, void *data)
|
|||||||
|
|
||||||
if (layers[wlr_layer_surface->current.layer] != layersurface->scene) {
|
if (layers[wlr_layer_surface->current.layer] != layersurface->scene) {
|
||||||
wl_list_remove(&layersurface->link);
|
wl_list_remove(&layersurface->link);
|
||||||
wl_list_insert(&m->layers[wlr_layer_surface->current.layer],
|
wl_list_insert(&layersurface->mon->layers[wlr_layer_surface->current.layer],
|
||||||
&layersurface->link);
|
&layersurface->link);
|
||||||
}
|
}
|
||||||
arrangelayers(m);
|
arrangelayers(layersurface->mon);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
commitnotify(struct wl_listener *listener, void *data)
|
commitnotify(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
Client *c = wl_container_of(listener, c, commit);
|
Client *c = wl_container_of(listener, c, commit);
|
||||||
|
struct wlr_box box;
|
||||||
|
client_get_geometry(c, &box);
|
||||||
|
|
||||||
|
if (c->mon && !wlr_box_empty(&box) && (box.width != c->geom.width - 2 * c->bw
|
||||||
|
|| box.height != c->geom.height - 2 * c->bw))
|
||||||
|
arrange(c->mon);
|
||||||
|
|
||||||
/* mark a pending resize as completed */
|
/* mark a pending resize as completed */
|
||||||
if (c->resize && c->resize <= c->surface.xdg->current.configure_serial)
|
if (c->resize && (c->resize <= c->surface.xdg->current.configure_serial
|
||||||
|
|| (c->surface.xdg->current.geometry.width == c->surface.xdg->pending.geometry.width
|
||||||
|
&& c->surface.xdg->current.geometry.height == c->surface.xdg->pending.geometry.height)))
|
||||||
c->resize = 0;
|
c->resize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -823,7 +850,6 @@ createlayersurface(struct wl_listener *listener, void *data)
|
|||||||
{
|
{
|
||||||
struct wlr_layer_surface_v1 *wlr_layer_surface = data;
|
struct wlr_layer_surface_v1 *wlr_layer_surface = data;
|
||||||
LayerSurface *layersurface;
|
LayerSurface *layersurface;
|
||||||
Monitor *m;
|
|
||||||
struct wlr_layer_surface_v1_state old_state;
|
struct wlr_layer_surface_v1_state old_state;
|
||||||
|
|
||||||
if (!wlr_layer_surface->output) {
|
if (!wlr_layer_surface->output) {
|
||||||
@@ -843,14 +869,14 @@ createlayersurface(struct wl_listener *listener, void *data)
|
|||||||
|
|
||||||
layersurface->layer_surface = wlr_layer_surface;
|
layersurface->layer_surface = wlr_layer_surface;
|
||||||
wlr_layer_surface->data = layersurface;
|
wlr_layer_surface->data = layersurface;
|
||||||
m = wlr_layer_surface->output->data;
|
layersurface->mon = wlr_layer_surface->output->data;
|
||||||
|
|
||||||
layersurface->scene = wlr_layer_surface->surface->data =
|
layersurface->scene = wlr_layer_surface->surface->data =
|
||||||
wlr_scene_subsurface_tree_create(layers[wlr_layer_surface->pending.layer],
|
wlr_scene_subsurface_tree_create(layers[wlr_layer_surface->pending.layer],
|
||||||
wlr_layer_surface->surface);
|
wlr_layer_surface->surface);
|
||||||
layersurface->scene->data = layersurface;
|
layersurface->scene->data = layersurface;
|
||||||
|
|
||||||
wl_list_insert(&m->layers[wlr_layer_surface->pending.layer],
|
wl_list_insert(&layersurface->mon->layers[wlr_layer_surface->pending.layer],
|
||||||
&layersurface->link);
|
&layersurface->link);
|
||||||
|
|
||||||
/* Temporarily set the layer's current state to pending
|
/* Temporarily set the layer's current state to pending
|
||||||
@@ -858,7 +884,7 @@ createlayersurface(struct wl_listener *listener, void *data)
|
|||||||
*/
|
*/
|
||||||
old_state = wlr_layer_surface->current;
|
old_state = wlr_layer_surface->current;
|
||||||
wlr_layer_surface->current = wlr_layer_surface->pending;
|
wlr_layer_surface->current = wlr_layer_surface->pending;
|
||||||
arrangelayers(m);
|
arrangelayers(layersurface->mon);
|
||||||
wlr_layer_surface->current = old_state;
|
wlr_layer_surface->current = old_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -941,11 +967,16 @@ createnotify(struct wl_listener *listener, void *data)
|
|||||||
|
|
||||||
if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) {
|
if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) {
|
||||||
struct wlr_box box;
|
struct wlr_box box;
|
||||||
|
LayerSurface *l;
|
||||||
|
void *toplevel = toplevel_from_popup(xdg_surface->popup);
|
||||||
xdg_surface->surface->data = wlr_scene_xdg_surface_create(
|
xdg_surface->surface->data = wlr_scene_xdg_surface_create(
|
||||||
xdg_surface->popup->parent->data, xdg_surface);
|
xdg_surface->popup->parent->data, xdg_surface);
|
||||||
if (!(c = client_from_popup(xdg_surface->popup)) || !c->mon)
|
if (wlr_surface_is_layer_surface(xdg_surface->popup->parent) && (l = toplevel)
|
||||||
|
&& l->layer_surface->current.layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP)
|
||||||
|
wlr_scene_node_reparent(xdg_surface->surface->data, layers[LyrTop]);
|
||||||
|
if (!(c = toplevel) || !c->mon)
|
||||||
return;
|
return;
|
||||||
box = c->mon->m;
|
box = c->type == LayerShell ? c->mon->m : c->mon->w;
|
||||||
box.x -= c->geom.x;
|
box.x -= c->geom.x;
|
||||||
box.y -= c->geom.y;
|
box.y -= c->geom.y;
|
||||||
wlr_xdg_popup_unconstrain_from_box(xdg_surface->popup, &box);
|
wlr_xdg_popup_unconstrain_from_box(xdg_surface->popup, &box);
|
||||||
@@ -958,14 +989,12 @@ createnotify(struct wl_listener *listener, void *data)
|
|||||||
c->surface.xdg = xdg_surface;
|
c->surface.xdg = xdg_surface;
|
||||||
c->bw = borderpx;
|
c->bw = borderpx;
|
||||||
|
|
||||||
LISTEN(&xdg_surface->surface->events.commit, &c->commit, commitnotify);
|
|
||||||
LISTEN(&xdg_surface->events.map, &c->map, mapnotify);
|
LISTEN(&xdg_surface->events.map, &c->map, mapnotify);
|
||||||
LISTEN(&xdg_surface->events.unmap, &c->unmap, unmapnotify);
|
LISTEN(&xdg_surface->events.unmap, &c->unmap, unmapnotify);
|
||||||
LISTEN(&xdg_surface->events.destroy, &c->destroy, destroynotify);
|
LISTEN(&xdg_surface->events.destroy, &c->destroy, destroynotify);
|
||||||
LISTEN(&xdg_surface->toplevel->events.set_title, &c->set_title, updatetitle);
|
LISTEN(&xdg_surface->toplevel->events.set_title, &c->set_title, updatetitle);
|
||||||
LISTEN(&xdg_surface->toplevel->events.request_fullscreen, &c->fullscreen,
|
LISTEN(&xdg_surface->toplevel->events.request_fullscreen, &c->fullscreen,
|
||||||
fullscreennotify);
|
fullscreennotify);
|
||||||
c->isfullscreen = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -975,17 +1004,39 @@ createpointer(struct wlr_input_device *device)
|
|||||||
struct libinput_device *libinput_device = (struct libinput_device*)
|
struct libinput_device *libinput_device = (struct libinput_device*)
|
||||||
wlr_libinput_get_device_handle(device);
|
wlr_libinput_get_device_handle(device);
|
||||||
|
|
||||||
if (tap_to_click && libinput_device_config_tap_get_finger_count(libinput_device))
|
if (libinput_device_config_tap_get_finger_count(libinput_device)) {
|
||||||
libinput_device_config_tap_set_enabled(libinput_device, LIBINPUT_CONFIG_TAP_ENABLED);
|
libinput_device_config_tap_set_enabled(libinput_device, tap_to_click);
|
||||||
|
libinput_device_config_tap_set_drag_enabled(libinput_device, tap_and_drag);
|
||||||
|
libinput_device_config_tap_set_drag_lock_enabled(libinput_device, drag_lock);
|
||||||
|
}
|
||||||
|
|
||||||
if (libinput_device_config_scroll_has_natural_scroll(libinput_device))
|
if (libinput_device_config_scroll_has_natural_scroll(libinput_device))
|
||||||
libinput_device_config_scroll_set_natural_scroll_enabled(libinput_device, natural_scrolling);
|
libinput_device_config_scroll_set_natural_scroll_enabled(libinput_device, natural_scrolling);
|
||||||
|
|
||||||
|
if (libinput_device_config_dwt_is_available(libinput_device))
|
||||||
|
libinput_device_config_dwt_set_enabled(libinput_device, disable_while_typing);
|
||||||
|
|
||||||
|
if (libinput_device_config_left_handed_is_available(libinput_device))
|
||||||
|
libinput_device_config_left_handed_set(libinput_device, left_handed);
|
||||||
|
|
||||||
|
if (libinput_device_config_middle_emulation_is_available(libinput_device))
|
||||||
|
libinput_device_config_middle_emulation_set_enabled(libinput_device, middle_button_emulation);
|
||||||
|
|
||||||
|
if (libinput_device_config_scroll_get_methods(libinput_device) != LIBINPUT_CONFIG_SCROLL_NO_SCROLL)
|
||||||
|
libinput_device_config_scroll_set_method (libinput_device, scroll_method);
|
||||||
|
|
||||||
|
if (libinput_device_config_click_get_methods(libinput_device) != LIBINPUT_CONFIG_CLICK_METHOD_NONE)
|
||||||
|
libinput_device_config_click_set_method (libinput_device, click_method);
|
||||||
|
|
||||||
|
if (libinput_device_config_send_events_get_modes(libinput_device))
|
||||||
|
libinput_device_config_send_events_set_mode(libinput_device, send_events_mode);
|
||||||
|
|
||||||
|
if (libinput_device_config_accel_is_available(libinput_device)) {
|
||||||
|
libinput_device_config_accel_set_profile(libinput_device, accel_profile);
|
||||||
|
libinput_device_config_accel_set_speed(libinput_device, accel_speed);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We don't do anything special with pointers. All of our pointer handling
|
|
||||||
* is proxied through wlr_cursor. On another compositor, you might take this
|
|
||||||
* opportunity to do libinput configuration on the device to set
|
|
||||||
* acceleration, etc. */
|
|
||||||
wlr_cursor_attach_input_device(cursor, device);
|
wlr_cursor_attach_input_device(cursor, device);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1013,17 +1064,15 @@ destroylayersurfacenotify(struct wl_listener *listener, void *data)
|
|||||||
{
|
{
|
||||||
LayerSurface *layersurface = wl_container_of(listener, layersurface, destroy);
|
LayerSurface *layersurface = wl_container_of(listener, layersurface, destroy);
|
||||||
|
|
||||||
if (layersurface->layer_surface->mapped)
|
|
||||||
unmaplayersurface(layersurface);
|
|
||||||
wl_list_remove(&layersurface->link);
|
wl_list_remove(&layersurface->link);
|
||||||
wl_list_remove(&layersurface->destroy.link);
|
wl_list_remove(&layersurface->destroy.link);
|
||||||
wl_list_remove(&layersurface->map.link);
|
wl_list_remove(&layersurface->map.link);
|
||||||
wl_list_remove(&layersurface->unmap.link);
|
wl_list_remove(&layersurface->unmap.link);
|
||||||
wl_list_remove(&layersurface->surface_commit.link);
|
wl_list_remove(&layersurface->surface_commit.link);
|
||||||
|
wlr_scene_node_destroy(layersurface->scene);
|
||||||
if (layersurface->layer_surface->output) {
|
if (layersurface->layer_surface->output) {
|
||||||
Monitor *m = layersurface->layer_surface->output->data;
|
if ((layersurface->mon = layersurface->layer_surface->output->data))
|
||||||
if (m)
|
arrangelayers(layersurface->mon);
|
||||||
arrangelayers(m);
|
|
||||||
layersurface->layer_surface->output = NULL;
|
layersurface->layer_surface->output = NULL;
|
||||||
}
|
}
|
||||||
free(layersurface);
|
free(layersurface);
|
||||||
@@ -1042,10 +1091,10 @@ destroynotify(struct wl_listener *listener, void *data)
|
|||||||
#ifdef XWAYLAND
|
#ifdef XWAYLAND
|
||||||
if (c->type != XDGShell) {
|
if (c->type != XDGShell) {
|
||||||
wl_list_remove(&c->configure.link);
|
wl_list_remove(&c->configure.link);
|
||||||
|
wl_list_remove(&c->set_hints.link);
|
||||||
wl_list_remove(&c->activate.link);
|
wl_list_remove(&c->activate.link);
|
||||||
} else
|
}
|
||||||
#endif
|
#endif
|
||||||
wl_list_remove(&c->commit.link);
|
|
||||||
free(c);
|
free(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1079,6 +1128,9 @@ focusclient(Client *c, int lift)
|
|||||||
struct wlr_surface *old = seat->keyboard_state.focused_surface;
|
struct wlr_surface *old = seat->keyboard_state.focused_surface;
|
||||||
struct wlr_keyboard *kb;
|
struct wlr_keyboard *kb;
|
||||||
int i;
|
int i;
|
||||||
|
/* Do not focus clients if a layer surface is focused */
|
||||||
|
if (exclusive_focus)
|
||||||
|
return;
|
||||||
|
|
||||||
/* Raise client in stacking order if requested */
|
/* Raise client in stacking order if requested */
|
||||||
if (c && lift)
|
if (c && lift)
|
||||||
@@ -1093,6 +1145,7 @@ focusclient(Client *c, int lift)
|
|||||||
wl_list_insert(&fstack, &c->flink);
|
wl_list_insert(&fstack, &c->flink);
|
||||||
selmon = c->mon;
|
selmon = c->mon;
|
||||||
c->isurgent = 0;
|
c->isurgent = 0;
|
||||||
|
client_restack_surface(c);
|
||||||
|
|
||||||
for (i = 0; i < 4; i++)
|
for (i = 0; i < 4; i++)
|
||||||
wlr_scene_rect_set_color(c->border[i], focuscolor);
|
wlr_scene_rect_set_color(c->border[i], focuscolor);
|
||||||
@@ -1116,8 +1169,7 @@ focusclient(Client *c, int lift)
|
|||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
Client *w;
|
Client *w;
|
||||||
struct wlr_scene_node *node = old->data;
|
if ((w = client_from_wlr_surface(old)))
|
||||||
if ((w = node->data))
|
|
||||||
for (i = 0; i < 4; i++)
|
for (i = 0; i < 4; i++)
|
||||||
wlr_scene_rect_set_color(w->border[i], bordercolor);
|
wlr_scene_rect_set_color(w->border[i], bordercolor);
|
||||||
|
|
||||||
@@ -1136,8 +1188,11 @@ focusclient(Client *c, int lift)
|
|||||||
|
|
||||||
/* Have a client, so focus its top-level wlr_surface */
|
/* Have a client, so focus its top-level wlr_surface */
|
||||||
kb = wlr_seat_get_keyboard(seat);
|
kb = wlr_seat_get_keyboard(seat);
|
||||||
|
if (kb)
|
||||||
wlr_seat_keyboard_notify_enter(seat, client_surface(c),
|
wlr_seat_keyboard_notify_enter(seat, client_surface(c),
|
||||||
kb->keycodes, kb->num_keycodes, &kb->modifiers);
|
kb->keycodes, kb->num_keycodes, &kb->modifiers);
|
||||||
|
else
|
||||||
|
wlr_seat_keyboard_notify_enter(seat, client_surface(c), NULL, 0, NULL);
|
||||||
|
|
||||||
/* Activate the new client */
|
/* Activate the new client */
|
||||||
client_activate_surface(client_surface(c), 1);
|
client_activate_surface(client_surface(c), 1);
|
||||||
@@ -1271,8 +1326,10 @@ keypress(struct wl_listener *listener, void *data)
|
|||||||
uint32_t keycode = event->keycode + 8;
|
uint32_t keycode = event->keycode + 8;
|
||||||
/* Get a list of keysyms based on the keymap for this keyboard */
|
/* Get a list of keysyms based on the keymap for this keyboard */
|
||||||
const xkb_keysym_t *syms;
|
const xkb_keysym_t *syms;
|
||||||
int nsyms = xkb_state_key_get_syms(
|
xkb_layout_index_t layout_index = xkb_state_key_get_layout(
|
||||||
kb->device->keyboard->xkb_state, keycode, &syms);
|
kb->device->keyboard->xkb_state, keycode);
|
||||||
|
int nsyms = xkb_keymap_key_get_syms_by_level(kb->device->keyboard->keymap,
|
||||||
|
keycode, layout_index, 0, &syms);
|
||||||
|
|
||||||
int handled = 0;
|
int handled = 0;
|
||||||
uint32_t mods = wlr_keyboard_get_modifiers(kb->device->keyboard);
|
uint32_t mods = wlr_keyboard_get_modifiers(kb->device->keyboard);
|
||||||
@@ -1324,8 +1381,9 @@ void
|
|||||||
maplayersurfacenotify(struct wl_listener *listener, void *data)
|
maplayersurfacenotify(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
LayerSurface *layersurface = wl_container_of(listener, layersurface, map);
|
LayerSurface *layersurface = wl_container_of(listener, layersurface, map);
|
||||||
|
layersurface->mon = layersurface->layer_surface->output->data;
|
||||||
wlr_surface_send_enter(layersurface->layer_surface->surface,
|
wlr_surface_send_enter(layersurface->layer_surface->surface,
|
||||||
layersurface->layer_surface->output);
|
layersurface->mon->wlr_output);
|
||||||
motionnotify(0);
|
motionnotify(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1333,15 +1391,23 @@ void
|
|||||||
mapnotify(struct wl_listener *listener, void *data)
|
mapnotify(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
/* Called when the surface is mapped, or ready to display on-screen. */
|
/* Called when the surface is mapped, or ready to display on-screen. */
|
||||||
Client *c = wl_container_of(listener, c, map);
|
Client *p, *c = wl_container_of(listener, c, map);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Create scene tree for this client and its border */
|
/* Create scene tree for this client and its border */
|
||||||
c->scene = &wlr_scene_tree_create(layers[LyrTile])->node;
|
c->scene = &wlr_scene_tree_create(layers[LyrTile])->node;
|
||||||
c->scene_surface = client_surface(c)->data = c->type == XDGShell
|
c->scene_surface = c->type == XDGShell
|
||||||
? wlr_scene_xdg_surface_create(c->scene, c->surface.xdg)
|
? wlr_scene_xdg_surface_create(c->scene, c->surface.xdg)
|
||||||
: wlr_scene_subsurface_tree_create(c->scene, client_surface(c));
|
: wlr_scene_subsurface_tree_create(c->scene, client_surface(c));
|
||||||
c->scene_surface->data = c;
|
if (client_surface(c)) {
|
||||||
|
client_surface(c)->data = c->scene;
|
||||||
|
/* Ideally we should do this in createnotify{,x11} but at that moment
|
||||||
|
* wlr_xwayland_surface doesn't have wlr_surface yet
|
||||||
|
*/
|
||||||
|
LISTEN(&client_surface(c)->events.commit, &c->commit, commitnotify);
|
||||||
|
|
||||||
|
}
|
||||||
|
c->scene->data = c->scene_surface->data = c;
|
||||||
|
|
||||||
if (client_is_unmanaged(c)) {
|
if (client_is_unmanaged(c)) {
|
||||||
client_get_geometry(c, &c->geom);
|
client_get_geometry(c, &c->geom);
|
||||||
@@ -1356,7 +1422,6 @@ mapnotify(struct wl_listener *listener, void *data)
|
|||||||
c->border[i] = wlr_scene_rect_create(c->scene, 0, 0, bordercolor);
|
c->border[i] = wlr_scene_rect_create(c->scene, 0, 0, bordercolor);
|
||||||
c->border[i]->node.data = c;
|
c->border[i]->node.data = c;
|
||||||
wlr_scene_rect_set_color(c->border[i], bordercolor);
|
wlr_scene_rect_set_color(c->border[i], bordercolor);
|
||||||
wlr_scene_node_lower_to_bottom(&c->border[i]->node);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize client geometry with room for border */
|
/* Initialize client geometry with room for border */
|
||||||
@@ -1370,7 +1435,14 @@ mapnotify(struct wl_listener *listener, void *data)
|
|||||||
wl_list_insert(&fstack, &c->flink);
|
wl_list_insert(&fstack, &c->flink);
|
||||||
|
|
||||||
/* Set initial monitor, tags, floating status, and focus */
|
/* Set initial monitor, tags, floating status, and focus */
|
||||||
|
if ((p = client_get_parent(c))) {
|
||||||
|
/* Set the same monitor and tags than its parent */
|
||||||
|
c->isfloating = 1;
|
||||||
|
wlr_scene_node_reparent(c->scene, layers[LyrFloat]);
|
||||||
|
setmon(c, p->mon, p->tags);
|
||||||
|
} else {
|
||||||
applyrules(c);
|
applyrules(c);
|
||||||
|
}
|
||||||
printstatus();
|
printstatus();
|
||||||
|
|
||||||
if (c->isfullscreen)
|
if (c->isfullscreen)
|
||||||
@@ -1387,8 +1459,9 @@ monocle(Monitor *m)
|
|||||||
wl_list_for_each(c, &clients, link) {
|
wl_list_for_each(c, &clients, link) {
|
||||||
if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen)
|
if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen)
|
||||||
continue;
|
continue;
|
||||||
resize(c, m->w.x, m->w.y, m->w.width, m->w.height, 0);
|
resize(c, m->w, 0);
|
||||||
}
|
}
|
||||||
|
focusclient(focustop(m), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -1428,13 +1501,12 @@ motionnotify(uint32_t time)
|
|||||||
/* If we are currently grabbing the mouse, handle and return */
|
/* If we are currently grabbing the mouse, handle and return */
|
||||||
if (cursor_mode == CurMove) {
|
if (cursor_mode == CurMove) {
|
||||||
/* Move the grabbed client to the new position. */
|
/* Move the grabbed client to the new position. */
|
||||||
resize(grabc, cursor->x - grabcx, cursor->y - grabcy,
|
resize(grabc, (struct wlr_box){.x = cursor->x - grabcx, .y = cursor->y - grabcy,
|
||||||
grabc->geom.width, grabc->geom.height, 1);
|
.width = grabc->geom.width, .height = grabc->geom.height}, 1);
|
||||||
return;
|
return;
|
||||||
} else if (cursor_mode == CurResize) {
|
} else if (cursor_mode == CurResize) {
|
||||||
resize(grabc, grabc->geom.x, grabc->geom.y,
|
resize(grabc, (struct wlr_box){.x = grabc->geom.x, .y = grabc->geom.y,
|
||||||
cursor->x - grabc->geom.x,
|
.width = cursor->x - grabc->geom.x, .height = cursor->y - grabc->geom.y}, 1);
|
||||||
cursor->y - grabc->geom.y, 1);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1617,7 +1689,6 @@ printstatus(void)
|
|||||||
sel, urg);
|
sel, urg);
|
||||||
printf("%s layout %s\n", m->wlr_output->name, m->lt[m->sellt]->symbol);
|
printf("%s layout %s\n", m->wlr_output->name, m->lt[m->sellt]->symbol);
|
||||||
}
|
}
|
||||||
fflush(stdout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -1678,15 +1749,10 @@ requeststartdrag(struct wl_listener *listener, void *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
resize(Client *c, int x, int y, int w, int h, int interact)
|
resize(Client *c, struct wlr_box geo, int interact)
|
||||||
{
|
{
|
||||||
int min_width = 0, min_height = 0;
|
|
||||||
struct wlr_box *bbox = interact ? &sgeom : &c->mon->w;
|
struct wlr_box *bbox = interact ? &sgeom : &c->mon->w;
|
||||||
client_min_size(c, &min_width, &min_height);
|
c->geom = geo;
|
||||||
c->geom.x = x;
|
|
||||||
c->geom.y = y;
|
|
||||||
c->geom.width = MAX(min_width + 2 * c->bw, w);
|
|
||||||
c->geom.height = MAX(min_height + 2 * c->bw, h);
|
|
||||||
applybounds(c, bbox);
|
applybounds(c, bbox);
|
||||||
|
|
||||||
/* Update scene-graph, including borders */
|
/* Update scene-graph, including borders */
|
||||||
@@ -1708,8 +1774,6 @@ resize(Client *c, int x, int y, int w, int h, int interact)
|
|||||||
void
|
void
|
||||||
run(char *startup_cmd)
|
run(char *startup_cmd)
|
||||||
{
|
{
|
||||||
pid_t startup_pid = -1;
|
|
||||||
|
|
||||||
/* Add a Unix socket to the Wayland display. */
|
/* Add a Unix socket to the Wayland display. */
|
||||||
const char *socket = wl_display_add_socket_auto(dpy);
|
const char *socket = wl_display_add_socket_auto(dpy);
|
||||||
if (!socket)
|
if (!socket)
|
||||||
@@ -1721,9 +1785,9 @@ run(char *startup_cmd)
|
|||||||
int piperw[2];
|
int piperw[2];
|
||||||
if (pipe(piperw) < 0)
|
if (pipe(piperw) < 0)
|
||||||
die("startup: pipe:");
|
die("startup: pipe:");
|
||||||
if ((startup_pid = fork()) < 0)
|
if ((child_pid = fork()) < 0)
|
||||||
die("startup: fork:");
|
die("startup: fork:");
|
||||||
if (startup_pid == 0) {
|
if (child_pid == 0) {
|
||||||
dup2(piperw[0], STDIN_FILENO);
|
dup2(piperw[0], STDIN_FILENO);
|
||||||
close(piperw[0]);
|
close(piperw[0]);
|
||||||
close(piperw[1]);
|
close(piperw[1]);
|
||||||
@@ -1759,11 +1823,6 @@ run(char *startup_cmd)
|
|||||||
* loop configuration to listen to libinput events, DRM events, generate
|
* loop configuration to listen to libinput events, DRM events, generate
|
||||||
* frame events at the refresh rate, and so on. */
|
* frame events at the refresh rate, and so on. */
|
||||||
wl_display_run(dpy);
|
wl_display_run(dpy);
|
||||||
|
|
||||||
if (startup_cmd) {
|
|
||||||
kill(startup_pid, SIGTERM);
|
|
||||||
waitpid(startup_pid, NULL, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Client *
|
Client *
|
||||||
@@ -1812,11 +1871,29 @@ setfullscreen(Client *c, int fullscreen)
|
|||||||
|
|
||||||
if (fullscreen) {
|
if (fullscreen) {
|
||||||
c->prev = c->geom;
|
c->prev = c->geom;
|
||||||
resize(c, c->mon->m.x, c->mon->m.y, c->mon->m.width, c->mon->m.height, 0);
|
resize(c, c->mon->m, 0);
|
||||||
|
/* The xdg-protocol specifies:
|
||||||
|
*
|
||||||
|
* If the fullscreened surface is not opaque, the compositor must make
|
||||||
|
* sure that other screen content not part of the same surface tree (made
|
||||||
|
* up of subsurfaces, popups or similarly coupled surfaces) are not
|
||||||
|
* visible below the fullscreened surface.
|
||||||
|
*
|
||||||
|
* For brevity we set a black background for all clients
|
||||||
|
*/
|
||||||
|
if (!c->fullscreen_bg) {
|
||||||
|
c->fullscreen_bg = wlr_scene_rect_create(c->scene,
|
||||||
|
c->geom.width, c->geom.height, fullscreen_bg);
|
||||||
|
wlr_scene_node_lower_to_bottom(&c->fullscreen_bg->node);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* restore previous size instead of arrange for floating windows since
|
/* restore previous size instead of arrange for floating windows since
|
||||||
* client positions are set by the user and cannot be recalculated */
|
* client positions are set by the user and cannot be recalculated */
|
||||||
resize(c, c->prev.x, c->prev.y, c->prev.width, c->prev.height, 0);
|
resize(c, c->prev, 0);
|
||||||
|
if (c->fullscreen_bg) {
|
||||||
|
wlr_scene_node_destroy(&c->fullscreen_bg->node);
|
||||||
|
c->fullscreen_bg = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
arrange(c->mon);
|
arrange(c->mon);
|
||||||
printstatus();
|
printstatus();
|
||||||
@@ -1865,7 +1942,7 @@ setmon(Client *c, Monitor *m, unsigned int newtags)
|
|||||||
}
|
}
|
||||||
if (m) {
|
if (m) {
|
||||||
/* Make sure window actually overlaps with the monitor */
|
/* Make sure window actually overlaps with the monitor */
|
||||||
resize(c, c->geom.x, c->geom.y, c->geom.width, c->geom.height, 0);
|
resize(c, c->geom, 0);
|
||||||
wlr_surface_send_enter(client_surface(c), m->wlr_output);
|
wlr_surface_send_enter(client_surface(c), m->wlr_output);
|
||||||
c->tags = newtags ? newtags : m->tagset[m->seltags]; /* assign tags of target monitor */
|
c->tags = newtags ? newtags : m->tagset[m->seltags]; /* assign tags of target monitor */
|
||||||
arrange(m);
|
arrange(m);
|
||||||
@@ -1898,6 +1975,9 @@ setsel(struct wl_listener *listener, void *data)
|
|||||||
void
|
void
|
||||||
setup(void)
|
setup(void)
|
||||||
{
|
{
|
||||||
|
/* Force line-buffered stdout */
|
||||||
|
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||||
|
|
||||||
/* The Wayland display is managed by libwayland. It handles accepting
|
/* The Wayland display is managed by libwayland. It handles accepting
|
||||||
* clients from the Unix socket, manging Wayland globals, and so on. */
|
* clients from the Unix socket, manging Wayland globals, and so on. */
|
||||||
dpy = wl_display_create();
|
dpy = wl_display_create();
|
||||||
@@ -2075,10 +2155,12 @@ sigchld(int unused)
|
|||||||
* but the Xwayland implementation in wlroots currently prevents us from
|
* but the Xwayland implementation in wlroots currently prevents us from
|
||||||
* setting our own disposition for SIGCHLD.
|
* setting our own disposition for SIGCHLD.
|
||||||
*/
|
*/
|
||||||
|
pid_t pid;
|
||||||
if (signal(SIGCHLD, sigchld) == SIG_ERR)
|
if (signal(SIGCHLD, sigchld) == SIG_ERR)
|
||||||
die("can't install SIGCHLD handler:");
|
die("can't install SIGCHLD handler:");
|
||||||
while (0 < waitpid(-1, NULL, WNOHANG))
|
while (0 < (pid = waitpid(-1, NULL, WNOHANG)))
|
||||||
;
|
if (pid == child_pid)
|
||||||
|
child_pid = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -2129,7 +2211,7 @@ tagmon(const Arg *arg)
|
|||||||
void
|
void
|
||||||
tile(Monitor *m)
|
tile(Monitor *m)
|
||||||
{
|
{
|
||||||
unsigned int i, n = 0, h, mw, my, ty;
|
unsigned int i, n = 0, mw, my, ty;
|
||||||
Client *c;
|
Client *c;
|
||||||
|
|
||||||
wl_list_for_each(c, &clients, link)
|
wl_list_for_each(c, &clients, link)
|
||||||
@@ -2147,12 +2229,12 @@ tile(Monitor *m)
|
|||||||
if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen)
|
if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen)
|
||||||
continue;
|
continue;
|
||||||
if (i < m->nmaster) {
|
if (i < m->nmaster) {
|
||||||
h = (m->w.height - my) / (MIN(n, m->nmaster) - i);
|
resize(c, (struct wlr_box){.x = m->w.x, .y = m->w.y + my, .width = mw,
|
||||||
resize(c, m->w.x, m->w.y + my, mw, h, 0);
|
.height = (m->w.height - my) / (MIN(n, m->nmaster) - i)}, 0);
|
||||||
my += c->geom.height;
|
my += c->geom.height;
|
||||||
} else {
|
} else {
|
||||||
h = (m->w.height - ty) / (n - i);
|
resize(c, (struct wlr_box){.x = m->w.x + mw, .y = m->w.y + ty,
|
||||||
resize(c, m->w.x + mw, m->w.y + ty, m->w.width - mw, h, 0);
|
.width = m->w.width - mw, .height = (m->w.height - ty) / (n - i)}, 0);
|
||||||
ty += c->geom.height;
|
ty += c->geom.height;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
@@ -2206,22 +2288,20 @@ toggleview(const Arg *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
unmaplayersurface(LayerSurface *layersurface)
|
unmaplayersurfacenotify(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
layersurface->layer_surface->mapped = 0;
|
LayerSurface *layersurface = wl_container_of(listener, layersurface, unmap);
|
||||||
|
|
||||||
|
layersurface->layer_surface->mapped = (layersurface->mapped = 0);
|
||||||
|
wlr_scene_node_set_enabled(layersurface->scene, 0);
|
||||||
|
if (layersurface->layer_surface->surface == exclusive_focus)
|
||||||
|
exclusive_focus = NULL;
|
||||||
if (layersurface->layer_surface->surface ==
|
if (layersurface->layer_surface->surface ==
|
||||||
seat->keyboard_state.focused_surface)
|
seat->keyboard_state.focused_surface)
|
||||||
focusclient(selclient(), 1);
|
focusclient(selclient(), 1);
|
||||||
motionnotify(0);
|
motionnotify(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
unmaplayersurfacenotify(struct wl_listener *listener, void *data)
|
|
||||||
{
|
|
||||||
LayerSurface *layersurface = wl_container_of(listener, layersurface, unmap);
|
|
||||||
unmaplayersurface(layersurface);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
unmapnotify(struct wl_listener *listener, void *data)
|
unmapnotify(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
@@ -2243,6 +2323,7 @@ unmapnotify(struct wl_listener *listener, void *data)
|
|||||||
wl_list_remove(&c->link);
|
wl_list_remove(&c->link);
|
||||||
setmon(c, NULL, 0);
|
setmon(c, NULL, 0);
|
||||||
wl_list_remove(&c->flink);
|
wl_list_remove(&c->flink);
|
||||||
|
wl_list_remove(&c->commit.link);
|
||||||
wlr_scene_node_destroy(c->scene);
|
wlr_scene_node_destroy(c->scene);
|
||||||
printstatus();
|
printstatus();
|
||||||
}
|
}
|
||||||
@@ -2297,11 +2378,7 @@ void
|
|||||||
urgent(struct wl_listener *listener, void *data)
|
urgent(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct wlr_xdg_activation_v1_request_activate_event *event = data;
|
struct wlr_xdg_activation_v1_request_activate_event *event = data;
|
||||||
Client *c;
|
Client *c = client_from_wlr_surface(event->surface);
|
||||||
|
|
||||||
if (!wlr_surface_is_xdg_surface(event->surface))
|
|
||||||
return;
|
|
||||||
c = wlr_xdg_surface_from_wlr_surface(event->surface)->data;
|
|
||||||
if (c != selclient()) {
|
if (c != selclient()) {
|
||||||
c->isurgent = 1;
|
c->isurgent = 1;
|
||||||
printstatus();
|
printstatus();
|
||||||
@@ -2344,11 +2421,11 @@ xytonode(double x, double y, struct wlr_surface **psurface,
|
|||||||
struct wlr_surface *surface = NULL;
|
struct wlr_surface *surface = NULL;
|
||||||
Client *c = NULL;
|
Client *c = NULL;
|
||||||
LayerSurface *l = NULL;
|
LayerSurface *l = NULL;
|
||||||
int i;
|
const int *layer;
|
||||||
int focus_order[] = { LyrOverlay, LyrTop, LyrFloat, LyrTile, LyrBottom, LyrBg };
|
int focus_order[] = { LyrOverlay, LyrTop, LyrFloat, LyrTile, LyrBottom, LyrBg };
|
||||||
|
|
||||||
for (i = 0; i < LENGTH(focus_order); i++) {
|
for (layer = focus_order; layer < END(focus_order); layer++) {
|
||||||
if ((node = wlr_scene_node_at(layers[focus_order[i]], x, y, nx, ny))) {
|
if ((node = wlr_scene_node_at(layers[*layer], x, y, nx, ny))) {
|
||||||
if (node->type == WLR_SCENE_NODE_SURFACE)
|
if (node->type == WLR_SCENE_NODE_SURFACE)
|
||||||
surface = wlr_scene_surface_from_node(node)->surface;
|
surface = wlr_scene_surface_from_node(node)->surface;
|
||||||
/* Walk the tree to find a node that knows the client */
|
/* Walk the tree to find a node that knows the client */
|
||||||
@@ -2435,7 +2512,6 @@ createnotifyx11(struct wl_listener *listener, void *data)
|
|||||||
c->surface.xwayland = xwayland_surface;
|
c->surface.xwayland = xwayland_surface;
|
||||||
c->type = xwayland_surface->override_redirect ? X11Unmanaged : X11Managed;
|
c->type = xwayland_surface->override_redirect ? X11Unmanaged : X11Managed;
|
||||||
c->bw = borderpx;
|
c->bw = borderpx;
|
||||||
c->isfullscreen = 0;
|
|
||||||
|
|
||||||
/* Listen to the various events it can emit */
|
/* Listen to the various events it can emit */
|
||||||
LISTEN(&xwayland_surface->events.map, &c->map, mapnotify);
|
LISTEN(&xwayland_surface->events.map, &c->map, mapnotify);
|
||||||
@@ -2443,6 +2519,7 @@ createnotifyx11(struct wl_listener *listener, void *data)
|
|||||||
LISTEN(&xwayland_surface->events.request_activate, &c->activate, activatex11);
|
LISTEN(&xwayland_surface->events.request_activate, &c->activate, activatex11);
|
||||||
LISTEN(&xwayland_surface->events.request_configure, &c->configure,
|
LISTEN(&xwayland_surface->events.request_configure, &c->configure,
|
||||||
configurex11);
|
configurex11);
|
||||||
|
LISTEN(&xwayland_surface->events.set_hints, &c->set_hints, sethints);
|
||||||
LISTEN(&xwayland_surface->events.set_title, &c->set_title, updatetitle);
|
LISTEN(&xwayland_surface->events.set_title, &c->set_title, updatetitle);
|
||||||
LISTEN(&xwayland_surface->events.destroy, &c->destroy, destroynotify);
|
LISTEN(&xwayland_surface->events.destroy, &c->destroy, destroynotify);
|
||||||
LISTEN(&xwayland_surface->events.request_fullscreen, &c->fullscreen,
|
LISTEN(&xwayland_surface->events.request_fullscreen, &c->fullscreen,
|
||||||
@@ -2462,6 +2539,16 @@ getatom(xcb_connection_t *xc, const char *name)
|
|||||||
return atom;
|
return atom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sethints(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
Client *c = wl_container_of(listener, c, set_hints);
|
||||||
|
if (c != selclient()) {
|
||||||
|
c->isurgent = c->surface.xwayland->hints_urgency;
|
||||||
|
printstatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xwaylandready(struct wl_listener *listener, void *data)
|
xwaylandready(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
@@ -2500,9 +2587,11 @@ main(int argc, char *argv[])
|
|||||||
char *startup_cmd = NULL;
|
char *startup_cmd = NULL;
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
while ((c = getopt(argc, argv, "s:h")) != -1) {
|
while ((c = getopt(argc, argv, "s:hv")) != -1) {
|
||||||
if (c == 's')
|
if (c == 's')
|
||||||
startup_cmd = optarg;
|
startup_cmd = optarg;
|
||||||
|
else if (c == 'v')
|
||||||
|
die("dwl " VERSION);
|
||||||
else
|
else
|
||||||
goto usage;
|
goto usage;
|
||||||
}
|
}
|
||||||
@@ -2518,5 +2607,5 @@ main(int argc, char *argv[])
|
|||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|
||||||
usage:
|
usage:
|
||||||
die("Usage: %s [-s startup command]", argv[0]);
|
die("Usage: %s [-v] [-s startup command]", argv[0]);
|
||||||
}
|
}
|
||||||
|
|||||||
Executable
+13
@@ -0,0 +1,13 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
if git tag --contains HEAD | grep -q $1; then
|
||||||
|
echo $1
|
||||||
|
else
|
||||||
|
branch="$(git rev-parse --abbrev-ref HEAD)"
|
||||||
|
commit="$(git rev-parse --short HEAD)"
|
||||||
|
if [ "${branch}" != "main" ]; then
|
||||||
|
echo $1-$branch-$commit
|
||||||
|
else
|
||||||
|
echo $1-$commit
|
||||||
|
fi
|
||||||
|
fi
|
||||||
Reference in New Issue
Block a user