forked from mirror/dwl
Compare commits
10 commits
Author | SHA1 | Date | |
---|---|---|---|
|
7c3c5ffcc2 | ||
|
81c8ebf677 | ||
|
a89872f02e | ||
|
a41d817979 | ||
|
a4e4fd3d25 | ||
|
0259e9a8ab | ||
|
04079a0946 | ||
|
daf5ee475f | ||
|
156a13d9f9 | ||
|
dcb7a4d910 |
25 changed files with 1032 additions and 3789 deletions
|
@ -1,62 +0,0 @@
|
||||||
name: Bug Report
|
|
||||||
about: Something in dwl isn't working correctly
|
|
||||||
title:
|
|
||||||
labels:
|
|
||||||
- 'Kind/Bug'
|
|
||||||
body:
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: |
|
|
||||||
- Only report bugs that can be reproduced on the main (or wlroots-next) branch without patches.
|
|
||||||
- Proprietary graphics drivers, including nvidia, are not supported. Please use the open source equivalents, such as nouveau, if you would like to use dwl.
|
|
||||||
- Report patch issues to their respective authors.
|
|
||||||
|
|
||||||
- type: input
|
|
||||||
id: dwl_version
|
|
||||||
attributes:
|
|
||||||
label: 'dwl version:'
|
|
||||||
placeholder: '`dwl -v`'
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: input
|
|
||||||
id: wlroots_version
|
|
||||||
attributes:
|
|
||||||
label: 'wlroots version:'
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: input
|
|
||||||
id: distro
|
|
||||||
attributes:
|
|
||||||
label: What distro (and version) are you using?
|
|
||||||
validations:
|
|
||||||
required: false
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Description
|
|
||||||
value: |
|
|
||||||
The steps you took to reproduce the problem.
|
|
||||||
validations:
|
|
||||||
required: false
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
id: debug_log
|
|
||||||
attributes:
|
|
||||||
label: Debug Log
|
|
||||||
value: |
|
|
||||||
Run `dwl -d 2> ~/dwl.log` from a TTY and attach the **full** (do not truncate it) file here, or upload it to a pastebin.
|
|
||||||
Please try to keep the reproduction as brief as possible and exit dwl.
|
|
||||||
validations:
|
|
||||||
required: false
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
id: backtrace
|
|
||||||
attributes:
|
|
||||||
label: Stack Trace
|
|
||||||
value: |
|
|
||||||
- Only required if dwl crashes.
|
|
||||||
- If the lines mentioning dwl or wlroots have `??`. Please compile both dwl and wlroots from source (enabling debug symbols) and try to reproduce.
|
|
||||||
validations:
|
|
||||||
required: false
|
|
|
@ -1,9 +0,0 @@
|
||||||
name: Enhancement idea
|
|
||||||
about: Suggest a feature or improvement
|
|
||||||
title:
|
|
||||||
labels:
|
|
||||||
- 'Kind/Feature'
|
|
||||||
body:
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Description
|
|
17
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
17
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Something in dwl isn't working correctly
|
||||||
|
title: ''
|
||||||
|
labels: 'A: bug'
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Info
|
||||||
|
dwl version:
|
||||||
|
wlroots version:
|
||||||
|
## Description
|
||||||
|
<!--
|
||||||
|
Only report bugs that can be reproduced on the main line
|
||||||
|
Report patch issues to their respective authors
|
||||||
|
-->
|
10
.github/ISSUE_TEMPLATE/enhancement-idea.md
vendored
Normal file
10
.github/ISSUE_TEMPLATE/enhancement-idea.md
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
---
|
||||||
|
name: Enhancement idea
|
||||||
|
about: Suggest a feature or improvement
|
||||||
|
title: ''
|
||||||
|
labels: 'A: enhancement'
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
1
.mailmap
1
.mailmap
|
@ -1 +0,0 @@
|
||||||
Lennart Jablonka <humm@ljabl.com> <hummsmith42@gmail.com>
|
|
214
CHANGELOG.md
214
CHANGELOG.md
|
@ -1,214 +0,0 @@
|
||||||
# Changelog
|
|
||||||
|
|
||||||
* [Unreleased](#unreleased)
|
|
||||||
* [0.7](#0.7)
|
|
||||||
* [0.6](#0.6)
|
|
||||||
* [0.5](#0.5)
|
|
||||||
|
|
||||||
|
|
||||||
## Unreleased
|
|
||||||
### Added
|
|
||||||
### Changed
|
|
||||||
### Deprecated
|
|
||||||
### Removed
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
* Crash when a client is created while all outputs are disabled.
|
|
||||||
|
|
||||||
### Security
|
|
||||||
### Contributors
|
|
||||||
|
|
||||||
|
|
||||||
## 0.7
|
|
||||||
|
|
||||||
See also [0.6](#0.6) release notes. 0.7 builds against wlroots 0.18.x.
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
* Add support for the alpha-modifier-v1 protocol ([wlroots!4616][wlroots!4616]).
|
|
||||||
* dwl now will survive GPU resets ([#601][601]).
|
|
||||||
|
|
||||||
[wlroots!4616]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4616
|
|
||||||
[601]: https://codeberg.org/dwl/dwl/issues/601
|
|
||||||
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
* Crash when re-mapping unmapped clients.
|
|
||||||
|
|
||||||
|
|
||||||
### Contributors
|
|
||||||
|
|
||||||
Guido Cella
|
|
||||||
Lennart Jablonka
|
|
||||||
|
|
||||||
|
|
||||||
## 0.6
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
* Add `rootcolor` to change the default background color ([#544][544]).
|
|
||||||
* Implement the wlr-virtual-pointer-unstable-v1 protocol ([#574][574]).
|
|
||||||
* Implement the pointer-constraints and relative-pointer protocols ([#317][317])
|
|
||||||
* Implement the wlr-output-power-management protocol ([#599][599])
|
|
||||||
|
|
||||||
[544]: https://codeberg.org/dwl/dwl/pulls/544
|
|
||||||
[574]: https://codeberg.org/dwl/dwl/pulls/574
|
|
||||||
[317]: https://codeberg.org/dwl/dwl/issues/317
|
|
||||||
[599]: https://codeberg.org/dwl/dwl/issues/559
|
|
||||||
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
* Keyboards are now managed through keyboard groups ([#549][549]).
|
|
||||||
* Only the first matched keybinding is executed.
|
|
||||||
* Allow toggling the layout before selecting a different one ([#570][570]).
|
|
||||||
* Fullscreen clients are now rendered above wlr_layer_surfaces in the top layer
|
|
||||||
([#609][609]).
|
|
||||||
* The default menu was changed from `bemenu-run` to `wmenu-run` ([#553][553]).
|
|
||||||
* The option `sloppyfocus` now replicates the dwm behavior ([#599][599]).
|
|
||||||
* Allow configure position of monitors with negative values. (-1, -1) is
|
|
||||||
used to auto-configure them ([#635][635]).
|
|
||||||
* dwl now kills the entire process group of `startup_cmd`
|
|
||||||
* The O_NONBLOCK flag is set for stdout.
|
|
||||||
|
|
||||||
[549]: https://codeberg.org/dwl/dwl/pulls/549
|
|
||||||
[570]: https://codeberg.org/dwl/dwl/pulls/570
|
|
||||||
[609]: https://codeberg.org/dwl/dwl/pulls/609
|
|
||||||
[553]: https://codeberg.org/dwl/dwl/issues/553
|
|
||||||
[599]: https://codeberg.org/dwl/dwl/pulls/599
|
|
||||||
[635]: https://codeberg.org/dwl/dwl/pulls/635
|
|
||||||
|
|
||||||
|
|
||||||
### Removed
|
|
||||||
|
|
||||||
* The SLOC limit is now removed ([#497][497]).
|
|
||||||
|
|
||||||
[497]: https://codeberg.org/dwl/dwl/pulls/497
|
|
||||||
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
* Clients not having the correct border color when mapping.
|
|
||||||
* Compliance with the xdg-decoration-unstable-v1 ([#546][546]).
|
|
||||||
* dwl no longer sends negative values in xdg_toplevel.configure events.
|
|
||||||
* Crashes with disabled monitors ([#472][472]).
|
|
||||||
|
|
||||||
[546]: https://codeberg.org/dwl/dwl/pulls/546
|
|
||||||
[472]: https://codeberg.org/dwl/dwl/issues/472
|
|
||||||
|
|
||||||
|
|
||||||
### Contributors
|
|
||||||
|
|
||||||
Ben Jargowsky
|
|
||||||
Benjamin Chausse
|
|
||||||
David Donahue
|
|
||||||
Devin J. Pohly
|
|
||||||
Dima Krasner
|
|
||||||
Emil Miler
|
|
||||||
Forrest Bushstone
|
|
||||||
Guido Cella
|
|
||||||
Peter Hofmann
|
|
||||||
Rutherther
|
|
||||||
Squibid
|
|
||||||
choc
|
|
||||||
fictitiousexistence
|
|
||||||
korei999
|
|
||||||
sewn
|
|
||||||
thanatos
|
|
||||||
|
|
||||||
|
|
||||||
## 0.5
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
* Allow configure x and y position of outputs ([#301][301])
|
|
||||||
* Implement repeatable keybindings ([#368][368])
|
|
||||||
* Print app id in printstatus() output ([#381][381])
|
|
||||||
* Display client count in monocle symbol ([#387][387])
|
|
||||||
* Export XCURSOR_SIZE to fix apps using an older version of Qt ([#425][425])
|
|
||||||
* Support for wp-fractional-scale-v1 (through wlr_scene: [wlroots!3511][wlroots!3511])
|
|
||||||
* dwl now sends `wl_surface.preferred_buffer_scale` (through wlr_scene: [wlroots!4269][wlroots!4269])
|
|
||||||
* Add support for xdg-shell v6 ([#465][465])
|
|
||||||
* Add support for wp-cursor-shape-v1 ([#444][444])
|
|
||||||
* Add desktop file ([#484][484])
|
|
||||||
* Add macro to easily configure colors ([#466][466])
|
|
||||||
* Color of urgent clients are now red ([#494][494])
|
|
||||||
* New flag `-d` and option `log_level` to change the wlroots debug level
|
|
||||||
* Add CHANGELOG.md ([#501][501])
|
|
||||||
|
|
||||||
[301]: https://github.com/djpohly/dwl/pull/301
|
|
||||||
[368]: https://github.com/djpohly/dwl/pull/368
|
|
||||||
[381]: https://github.com/djpohly/dwl/pull/381
|
|
||||||
[387]: https://github.com/djpohly/dwl/issues/387
|
|
||||||
[425]: https://github.com/djpohly/dwl/pull/425
|
|
||||||
[wlroots!4269]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4269
|
|
||||||
[wlroots!3511]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3511
|
|
||||||
[465]: https://github.com/djpohly/dwl/pull/465
|
|
||||||
[444]: https://github.com/djpohly/dwl/pull/444
|
|
||||||
[484]: https://github.com/djpohly/dwl/pull/484
|
|
||||||
[466]: https://github.com/djpohly/dwl/issues/466
|
|
||||||
[494]: https://github.com/djpohly/dwl/pull/494
|
|
||||||
[501]: https://github.com/djpohly/dwl/pull/501
|
|
||||||
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
* Replace `tags` with `TAGCOUNT` in config.def.h ([#403][403])
|
|
||||||
* Pop ups are now destroyed when focusing another client ([#408][408])
|
|
||||||
* dwl does not longer respect size hints, instead clip windows if they are
|
|
||||||
larger than they should be ([#455][455])
|
|
||||||
* The version of wlr-layer-shell-unstable-v1 was lowered to 3 (from 4)
|
|
||||||
* Use the same border color as dwm ([#494][494])
|
|
||||||
|
|
||||||
[403]: https://github.com/djpohly/dwl/pull/403
|
|
||||||
[408]: https://github.com/djpohly/dwl/pull/409
|
|
||||||
[455]: https://github.com/djpohly/dwl/pull/455
|
|
||||||
[494]: https://github.com/djpohly/dwl/pull/494
|
|
||||||
|
|
||||||
|
|
||||||
### Removed
|
|
||||||
|
|
||||||
* Remove unused `rootcolor` option ([#401][401])
|
|
||||||
* Remove support for wlr-input-inhibitor-unstable-v1 ([#430][430])
|
|
||||||
* Remove support for KDE idle protocol ([#431][431])
|
|
||||||
|
|
||||||
[401]: https://github.com/djpohly/dwl/pull/401
|
|
||||||
[430]: https://github.com/djpohly/dwl/pull/430
|
|
||||||
[431]: https://github.com/djpohly/dwl/pull/431
|
|
||||||
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
* Fix crash when creating a layer surface with all outputs disabled
|
|
||||||
([#421][421])
|
|
||||||
* Fix other clients being shown as focused if the focused client have pop ups
|
|
||||||
open ([#408][408])
|
|
||||||
* Resize fullscreen clients when updating monitor mode
|
|
||||||
* dwl no longer crash at exit like sometimes did
|
|
||||||
* Fullscreen background appearing above clients ([#487][487])
|
|
||||||
* Fix a segfault when user provides invalid xkb_rules ([#518][518])
|
|
||||||
|
|
||||||
[421]: https://github.com/djpohly/dwl/pull/421
|
|
||||||
[408]: https://github.com/djpohly/dwl/issues/408
|
|
||||||
[487]: https://github.com/djpohly/dwl/issues/487
|
|
||||||
[518]: https://github.com/djpohly/dwl/pull/518
|
|
||||||
|
|
||||||
|
|
||||||
### Contributors
|
|
||||||
|
|
||||||
* A Frederick Christensen
|
|
||||||
* Angelo Antony
|
|
||||||
* Ben Collerson
|
|
||||||
* Devin J. Pohly
|
|
||||||
* Forrest Bushstone
|
|
||||||
* gan-of-culture
|
|
||||||
* godalming123
|
|
||||||
* Job79
|
|
||||||
* link2xt
|
|
||||||
* Micah Gorrell
|
|
||||||
* Nikita Ivanov
|
|
||||||
* Palanix
|
|
||||||
* pino-desktop
|
|
||||||
* Weiseguy
|
|
||||||
* Yves Zoundi
|
|
47
Makefile
47
Makefile
|
@ -4,24 +4,19 @@
|
||||||
include config.mk
|
include config.mk
|
||||||
|
|
||||||
# flags for compiling
|
# flags for compiling
|
||||||
DWLCPPFLAGS = -I. -DWLR_USE_UNSTABLE -D_POSIX_C_SOURCE=200809L \
|
DWLCPPFLAGS = -I. -DWLR_USE_UNSTABLE -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XWAYLAND)
|
||||||
-DVERSION=\"$(VERSION)\" $(XWAYLAND)
|
DWLDEVCFLAGS = -pedantic -Wall -Wextra -Wdeclaration-after-statement -Wno-unused-parameter -Wno-sign-compare -Wshadow -Wunused-macros\
|
||||||
DWLDEVCFLAGS = -g -pedantic -Wall -Wextra -Wdeclaration-after-statement \
|
-Werror=strict-prototypes -Werror=implicit -Werror=return-type -Werror=incompatible-pointer-types
|
||||||
-Wno-unused-parameter -Wshadow -Wunused-macros -Werror=strict-prototypes \
|
|
||||||
-Werror=implicit -Werror=return-type -Werror=incompatible-pointer-types \
|
|
||||||
-Wfloat-conversion
|
|
||||||
|
|
||||||
# CFLAGS / LDFLAGS
|
# CFLAGS / LDFLAGS
|
||||||
PKGS = wlroots-0.18 wayland-server xkbcommon libinput pixman-1 fcft $(XLIBS)
|
PKGS = wlroots wayland-server xkbcommon libinput $(XLIBS)
|
||||||
DWLCFLAGS = `$(PKG_CONFIG) --cflags $(PKGS)` $(DWLCPPFLAGS) $(DWLDEVCFLAGS) $(CFLAGS)
|
DWLCFLAGS = `$(PKG_CONFIG) --cflags $(PKGS)` $(DWLCPPFLAGS) $(DWLDEVCFLAGS) $(CFLAGS)
|
||||||
LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` -lm $(LIBS)
|
LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` $(LIBS)
|
||||||
|
|
||||||
all: dwl
|
all: dwl
|
||||||
dwl: dwl.o util.o
|
dwl: dwl.o util.o
|
||||||
$(CC) dwl.o util.o $(DWLCFLAGS) $(LDFLAGS) $(LDLIBS) -o $@
|
$(CC) dwl.o util.o $(LDLIBS) $(LDFLAGS) $(DWLCFLAGS) -o $@
|
||||||
dwl.o: dwl.c client.h config.h config.mk cursor-shape-v1-protocol.h \
|
dwl.o: dwl.c push.c config.mk config.h client.h xdg-shell-protocol.h wlr-layer-shell-unstable-v1-protocol.h
|
||||||
pointer-constraints-unstable-v1-protocol.h wlr-layer-shell-unstable-v1-protocol.h \
|
|
||||||
wlr-output-power-management-unstable-v1-protocol.h xdg-shell-protocol.h
|
|
||||||
util.o: util.c util.h
|
util.o: util.c util.h
|
||||||
|
|
||||||
# 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
|
||||||
|
@ -30,32 +25,22 @@ util.o: util.c util.h
|
||||||
WAYLAND_SCANNER = `$(PKG_CONFIG) --variable=wayland_scanner wayland-scanner`
|
WAYLAND_SCANNER = `$(PKG_CONFIG) --variable=wayland_scanner wayland-scanner`
|
||||||
WAYLAND_PROTOCOLS = `$(PKG_CONFIG) --variable=pkgdatadir wayland-protocols`
|
WAYLAND_PROTOCOLS = `$(PKG_CONFIG) --variable=pkgdatadir wayland-protocols`
|
||||||
|
|
||||||
cursor-shape-v1-protocol.h:
|
|
||||||
$(WAYLAND_SCANNER) enum-header \
|
|
||||||
$(WAYLAND_PROTOCOLS)/staging/cursor-shape/cursor-shape-v1.xml $@
|
|
||||||
pointer-constraints-unstable-v1-protocol.h:
|
|
||||||
$(WAYLAND_SCANNER) enum-header \
|
|
||||||
$(WAYLAND_PROTOCOLS)/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml $@
|
|
||||||
wlr-layer-shell-unstable-v1-protocol.h:
|
|
||||||
$(WAYLAND_SCANNER) enum-header \
|
|
||||||
protocols/wlr-layer-shell-unstable-v1.xml $@
|
|
||||||
wlr-output-power-management-unstable-v1-protocol.h:
|
|
||||||
$(WAYLAND_SCANNER) server-header \
|
|
||||||
protocols/wlr-output-power-management-unstable-v1.xml $@
|
|
||||||
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 $@
|
||||||
|
wlr-layer-shell-unstable-v1-protocol.h:
|
||||||
|
$(WAYLAND_SCANNER) server-header \
|
||||||
|
protocols/wlr-layer-shell-unstable-v1.xml $@
|
||||||
|
|
||||||
config.h:
|
config.h:
|
||||||
cp config.def.h $@
|
cp config.def.h $@
|
||||||
clean:
|
clean:
|
||||||
rm -f dwl *.o *-protocol.h
|
rm -f dwl *.o *-protocol.h
|
||||||
rm -f result result-man
|
|
||||||
|
|
||||||
dist: clean
|
dist: clean
|
||||||
mkdir -p dwl-$(VERSION)
|
mkdir -p dwl-$(VERSION)
|
||||||
cp -R LICENSE* Makefile CHANGELOG.md README.md client.h config.def.h \
|
cp -R LICENSE* Makefile README.md client.h config.def.h\
|
||||||
config.mk protocols dwl.1 dwl.c util.c util.h dwl.desktop \
|
config.mk protocols dwl.1 dwl.c util.c util.h\
|
||||||
dwl-$(VERSION)
|
dwl-$(VERSION)
|
||||||
tar -caf dwl-$(VERSION).tar.gz dwl-$(VERSION)
|
tar -caf dwl-$(VERSION).tar.gz dwl-$(VERSION)
|
||||||
rm -rf dwl-$(VERSION)
|
rm -rf dwl-$(VERSION)
|
||||||
|
@ -67,13 +52,9 @@ install: dwl
|
||||||
mkdir -p $(DESTDIR)$(MANDIR)/man1
|
mkdir -p $(DESTDIR)$(MANDIR)/man1
|
||||||
cp -f dwl.1 $(DESTDIR)$(MANDIR)/man1
|
cp -f dwl.1 $(DESTDIR)$(MANDIR)/man1
|
||||||
chmod 644 $(DESTDIR)$(MANDIR)/man1/dwl.1
|
chmod 644 $(DESTDIR)$(MANDIR)/man1/dwl.1
|
||||||
mkdir -p $(DESTDIR)$(DATADIR)/wayland-sessions
|
|
||||||
cp -f dwl.desktop $(DESTDIR)$(DATADIR)/wayland-sessions/dwl.desktop
|
|
||||||
chmod 644 $(DESTDIR)$(DATADIR)/wayland-sessions/dwl.desktop
|
|
||||||
uninstall:
|
uninstall:
|
||||||
rm -f $(DESTDIR)$(PREFIX)/bin/dwl $(DESTDIR)$(MANDIR)/man1/dwl.1 \
|
rm -f $(DESTDIR)$(PREFIX)/bin/dwl $(DESTDIR)$(MANDIR)/man1/dwl.1
|
||||||
$(DESTDIR)$(DATADIR)/wayland-sessions/dwl.desktop
|
|
||||||
|
|
||||||
.SUFFIXES: .c .o
|
.SUFFIXES: .c .o
|
||||||
.c.o:
|
.c.o:
|
||||||
$(CC) $(CPPFLAGS) $(DWLCFLAGS) -o $@ -c $<
|
$(CC) $(CPPFLAGS) $(DWLCFLAGS) -c $<
|
||||||
|
|
184
README.md
184
README.md
|
@ -1,57 +1,62 @@
|
||||||
# dwl - dwm for Wayland
|
# dwl - dwm for Wayland
|
||||||
|
|
||||||
Join us on our IRC channel: [#dwl on Libera Chat]
|
Join us on our [Discord server] or at [#dwl] on irc.libera.chat.
|
||||||
Or on our [Discord server].
|
|
||||||
|
|
||||||
dwl is a compact, hackable compositor for [Wayland] based on [wlroots]. It is
|
dwl is a compact, hackable compositor for [Wayland] based on [wlroots]. It is
|
||||||
intended to fill the same space in the Wayland world that dwm does in X11,
|
intended to fill the same space in the Wayland world that dwm does in X11,
|
||||||
primarily in terms of functionality, and secondarily in terms of
|
primarily in terms of philosophy, and secondarily in terms of functionality.
|
||||||
philosophy. Like dwm, dwl is:
|
Like dwm, dwl is:
|
||||||
|
|
||||||
- Easy to understand, hack on, and extend with patches
|
- Easy to understand, hack on, and extend with patches
|
||||||
- One C source file (or a very small number) configurable via `config.h`
|
- One C source file (or a very small number) configurable via `config.h`
|
||||||
|
- Limited to 2200 SLOC to promote hackability
|
||||||
- Tied to as few external dependencies as possible
|
- Tied to as few external dependencies as possible
|
||||||
|
|
||||||
## Getting Started:
|
dwl is not meant to provide every feature under the sun. Instead, like dwm, it
|
||||||
|
sticks to features which are necessary, simple, and straightforward to implement
|
||||||
|
given the base on which it is built. Implemented default features are:
|
||||||
|
|
||||||
### **dwl branch 0.7 and releases based upon 0.7 build against [wlroots] 0.18**
|
- 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
|
||||||
|
- Idle-inhibit protocol which lets applications such as mpv disable idle
|
||||||
|
monitoring
|
||||||
|
- Provide information to external status bars via stdout/stdin
|
||||||
|
- Urgency hints via xdg-activate protocol
|
||||||
|
- Support screen lockers via input-inhibitor protocol
|
||||||
|
- Various Wayland protocols
|
||||||
|
- XWayland support as provided by wlroots (can be enabled in `config.mk`)
|
||||||
|
- Zero flickering - Wayland users naturally expect that "every frame is perfect"
|
||||||
|
- Layer shell popups (used by Waybar)
|
||||||
|
- Damage tracking provided by scenegraph API
|
||||||
|
|
||||||
### Latest semi-stable [release]
|
Features under consideration (possibly as patches) are:
|
||||||
This is probably where you want to start. This builds against the dependent
|
|
||||||
packages' versions currently shipping in major distributions. If your
|
|
||||||
distribution's wlroots version is older, use an earlier dwl [release] or [0.x
|
|
||||||
branch].
|
|
||||||
|
|
||||||
### Development branch [main]
|
- Protocols made trivial by wlroots
|
||||||
Active development progresses on the `main` branch. The `main` branch is built
|
- Implement the text-input and input-method protocols to support IME once ibus
|
||||||
against a late (and often changing) git commit of wlroots. While the adventurous
|
implements input-method v2 (see https://github.com/ibus/ibus/pull/2256 and
|
||||||
are welcome to use `main`, it is a rocky road. Using `main` requires that the
|
https://github.com/djpohly/dwl/pull/235)
|
||||||
user be willing to chase git commits of wlroots. Testing development pull
|
|
||||||
requests may involve merging unmerged pull requests in [wlroots]' git repository
|
|
||||||
and/or git commits of wayland.
|
|
||||||
|
|
||||||
### Building dwl
|
|
||||||
dwl has the following dependencies:
|
|
||||||
- libinput
|
|
||||||
- wayland
|
|
||||||
- wlroots (compiled with the libinput backend)
|
|
||||||
- xkbcommon
|
|
||||||
- wayland-protocols (compile-time only)
|
|
||||||
- pkg-config (compile-time only)
|
|
||||||
|
|
||||||
dwl has the following additional dependencies if XWayland support is enabled:
|
Feature *non-goals* for the main codebase include:
|
||||||
- libxcb
|
|
||||||
- libxcb-wm
|
|
||||||
- wlroots (compiled with X11 support)
|
|
||||||
- Xwayland (runtime only)
|
|
||||||
|
|
||||||
Install these (and their `-devel` versions if your distro has separate
|
- Client-side decoration (any more than is necessary to tell the clients not to)
|
||||||
development packages) and run `make`. If you wish to build against a released
|
- Client-initiated window management, such as move, resize, and close, which can
|
||||||
version of wlroots (*you probably do*), use a [release] or a [0.x branch]. If
|
be done through the compositor
|
||||||
you want to use the unstable development `main` branch, you need to use the git
|
- Animations and visual effects
|
||||||
version of [wlroots].
|
|
||||||
|
|
||||||
To enable XWayland, you should uncomment its flags in `config.mk`.
|
## 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].
|
||||||
|
|
||||||
|
To enable XWayland, you should also install xorg-xwayland and uncomment its flag
|
||||||
|
in `config.mk`.
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
|
@ -60,24 +65,23 @@ manner as dwm. There is no way to separately restart the window manager in
|
||||||
Wayland without restarting the entire display server, so any changes will take
|
Wayland without restarting the entire display server, so any changes will take
|
||||||
effect the next time dwl is executed.
|
effect the next time dwl is executed.
|
||||||
|
|
||||||
As in the dwm community, we encourage users to share patches they have
|
As in the dwm community, we encourage users to share patches they have created.
|
||||||
created. Check out the [dwl-patches] repository!
|
Check out the [patches page on our wiki]!
|
||||||
|
|
||||||
## Running dwl
|
## Running dwl
|
||||||
|
|
||||||
dwl can be run on any of the backends supported by wlroots. This means you can
|
dwl can be run on any of the backends supported by wlroots. This means you can
|
||||||
run it as a separate window inside either an X11 or Wayland session, as well as
|
run it as a separate window inside either an X11 or Wayland session, as well
|
||||||
directly from a VT console. Depending on your distro's setup, you may need to
|
as directly from a VT console. Depending on your distro's setup, you may need
|
||||||
add your user to the `video` and `input` groups before you can run dwl on a
|
to add your user to the `video` and `input` groups before you can run dwl on
|
||||||
VT. If you are using `elogind` or `systemd-logind` you need to install polkit;
|
a VT. If you are using `elogind` or `systemd-logind` you need to install
|
||||||
otherwise you need to add yourself in the `seat` group and enable/start the
|
polkit; otherwise you need to add yourself in the `seat` group and
|
||||||
seatd daemon.
|
enable/start the seatd daemon.
|
||||||
|
|
||||||
When dwl is run with no arguments, it will launch the server and begin handling
|
When dwl is run with no arguments, it will launch the server and begin handling
|
||||||
any shortcuts configured in `config.h`. There is no status bar or other
|
any shortcuts configured in `config.h`. There is no status bar or other
|
||||||
decoration initially; these are instead clients that can be run within the
|
decoration initially; these are instead clients that can be run within
|
||||||
Wayland session. Do note that the default background color is black. This can be
|
the Wayland session.
|
||||||
modified in `config.h`.
|
|
||||||
|
|
||||||
If you would like to run a script or command automatically at startup, you can
|
If you would like to run a script or command automatically at startup, you can
|
||||||
specify the command using the `-s` option. This command will be executed as a
|
specify the command using the `-s` option. This command will be executed as a
|
||||||
|
@ -85,8 +89,7 @@ shell command using `/bin/sh -c`. It serves a similar function to `.xinitrc`,
|
||||||
but differs in that the display server will not shut down when this process
|
but differs in that the display server will not shut down when this process
|
||||||
terminates. Instead, dwl will send this process a SIGTERM at shutdown and wait
|
terminates. Instead, dwl will send this process a SIGTERM at shutdown and wait
|
||||||
for it to terminate (if it hasn't already). This makes it ideal for execing into
|
for it to terminate (if it hasn't already). This makes it ideal for execing into
|
||||||
a user service manager like [s6], [anopa], [runit], [dinit], or [`systemd
|
a user service manager like [s6], [anopa], [runit], or [`systemd --user`].
|
||||||
--user`].
|
|
||||||
|
|
||||||
Note: The `-s` command is run as a *child process* of dwl, which means that it
|
Note: The `-s` command is run as a *child process* of dwl, which means that it
|
||||||
does not have the ability to affect the environment of dwl or of any processes
|
does not have the ability to affect the environment of dwl or of any processes
|
||||||
|
@ -102,13 +105,13 @@ automatically, you will need to configure it prior to launching `dwl`, e.g.:
|
||||||
|
|
||||||
### Status information
|
### Status information
|
||||||
|
|
||||||
Information about selected layouts, current window title, app-id, and
|
Information about selected layouts, current window title, and
|
||||||
selected/occupied/urgent tags is written to the stdin of the `-s` command (see
|
selected/occupied/urgent tags is written to the stdin of the `-s` command (see
|
||||||
the `printstatus()` function for details). This information can be used to
|
the `printstatus()` function for details). This information can be used to
|
||||||
populate an external status bar with a script that parses the
|
populate an external status bar with a script that parses the information.
|
||||||
information. Failing to read this information will cause dwl to block, so if you
|
Failing to read this information will cause dwl to block, so if you do want to
|
||||||
do want to run a startup command that does not consume the status information,
|
run a startup command that does not consume the status information, you can
|
||||||
you can close standard input with the `<&-` shell redirection, for example:
|
close standard input with the `<&-` shell redirection, for example:
|
||||||
|
|
||||||
dwl -s 'foot --server <&-'
|
dwl -s 'foot --server <&-'
|
||||||
|
|
||||||
|
@ -123,49 +126,6 @@ To get a list of status bars that work with dwl consult our [wiki].
|
||||||
|
|
||||||
You can find a [list of useful resources on our wiki].
|
You can find a [list of useful resources on our wiki].
|
||||||
|
|
||||||
## Background
|
|
||||||
|
|
||||||
dwl is not meant to provide every feature under the sun. Instead, like dwm, it
|
|
||||||
sticks to features which are necessary, simple, and straightforward to implement
|
|
||||||
given the base on which it is built. Implemented default features are:
|
|
||||||
|
|
||||||
- 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
|
|
||||||
- Idle-inhibit protocol which lets applications such as mpv disable idle
|
|
||||||
monitoring
|
|
||||||
- Provide information to external status bars via stdout/stdin
|
|
||||||
- Urgency hints via xdg-activate protocol
|
|
||||||
- Support screen lockers via ext-session-lock-v1 protocol
|
|
||||||
- Various Wayland protocols
|
|
||||||
- XWayland support as provided by wlroots (can be enabled in `config.mk`)
|
|
||||||
- Zero flickering - Wayland users naturally expect that "every frame is perfect"
|
|
||||||
- Layer shell popups (used by Waybar)
|
|
||||||
- Damage tracking provided by scenegraph API
|
|
||||||
|
|
||||||
Given the Wayland architecture, dwl has to implement features from dwm **and**
|
|
||||||
the xorg-server. Because of this, it is impossible to maintain the original
|
|
||||||
project goal of 2000 SLOC and have a reasonably complete compositor with
|
|
||||||
features comparable to dwm. However, this does not mean that the code will grow
|
|
||||||
indiscriminately. We will try to keep the code as small as possible.
|
|
||||||
|
|
||||||
Features under consideration (possibly as patches) are:
|
|
||||||
|
|
||||||
- Protocols made trivial by wlroots
|
|
||||||
- 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://codeberg.org/dwl/dwl/pulls/235)
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
## Acknowledgements
|
## Acknowledgements
|
||||||
|
|
||||||
dwl began by extending the TinyWL example provided (CC0) by the sway/wlroots
|
dwl began by extending the TinyWL example provided (CC0) by the sway/wlroots
|
||||||
|
@ -176,26 +136,22 @@ possible.
|
||||||
Many thanks to suckless.org and the dwm developers and community for the
|
Many thanks to suckless.org and the dwm developers and community for the
|
||||||
inspiration, and to the various contributors to the project, including:
|
inspiration, and to the various contributors to the project, including:
|
||||||
|
|
||||||
- **Devin J. Pohly for creating and nurturing the fledgling project**
|
|
||||||
- Alexander Courtis for the XWayland implementation
|
- Alexander Courtis for the XWayland implementation
|
||||||
- Guido Cella for the layer-shell protocol implementation, patch maintenance,
|
- Guido Cella for the layer-shell protocol implementation, patch maintenance,
|
||||||
and for helping to keep the project running
|
and for helping to keep the project running
|
||||||
- Stivvo for output management and fullscreen support, and patch maintenance
|
- Stivvo for output management and fullscreen support, and patch maintenance
|
||||||
|
|
||||||
|
|
||||||
[`systemd --user`]: https://wiki.archlinux.org/title/Systemd/User
|
|
||||||
[#dwl on Libera Chat]: https://web.libera.chat/?channels=#dwl
|
|
||||||
[0.7-rc1]: https://codeberg.org/dwl/dwl/releases/tag/v0.7-rc1
|
|
||||||
[0.x branch]: https://codeberg.org/dwl/dwl/branches
|
|
||||||
[anopa]: https://jjacky.com/anopa/
|
|
||||||
[dinit]: https://davmac.org/projects/dinit/
|
|
||||||
[dwl-patches]: https://codeberg.org/dwl/dwl-patches
|
|
||||||
[list of useful resources on our wiki]: https://codeberg.org/dwl/dwl/wiki/Home#migrating-from-x
|
|
||||||
[main]: https://codeberg.org/dwl/dwl/src/branch/main
|
|
||||||
[release]: https://codeberg.org/dwl/dwl/releases
|
|
||||||
[runit]: http://smarden.org/runit/faq.html#userservices
|
|
||||||
[s6]: https://skarnet.org/software/s6/
|
|
||||||
[wlroots]: https://gitlab.freedesktop.org/wlroots/wlroots/
|
|
||||||
[wiki]: https://codeberg.org/dwl/dwl/wiki/Home#compatible-status-bars
|
|
||||||
[Discord server]: https://discord.gg/jJxZnrGPWN
|
[Discord server]: https://discord.gg/jJxZnrGPWN
|
||||||
|
[#dwl]: https://web.libera.chat/?channels=#dwl
|
||||||
[Wayland]: https://wayland.freedesktop.org/
|
[Wayland]: https://wayland.freedesktop.org/
|
||||||
|
[wlroots]: https://gitlab.freedesktop.org/wlroots/wlroots/
|
||||||
|
[wlroots-next branch]: https://github.com/djpohly/dwl/tree/wlroots-next
|
||||||
|
[patches page on our wiki]: https://github.com/djpohly/dwl/wiki/Patches
|
||||||
|
[s6]: https://skarnet.org/software/s6/
|
||||||
|
[anopa]: https://jjacky.com/anopa/
|
||||||
|
[runit]: http://smarden.org/runit/faq.html#userservices
|
||||||
|
[`systemd --user`]: https://wiki.archlinux.org/title/Systemd/User
|
||||||
|
[wiki]: https://github.com/djpohly/dwl/wiki#compatible-status-bars
|
||||||
|
[list of useful resources on our wiki]:
|
||||||
|
https://github.com/djpohly/dwl/wiki#migrating-from-x
|
||||||
|
|
216
client.h
216
client.h
|
@ -10,9 +10,35 @@ static inline int
|
||||||
client_is_x11(Client *c)
|
client_is_x11(Client *c)
|
||||||
{
|
{
|
||||||
#ifdef XWAYLAND
|
#ifdef XWAYLAND
|
||||||
return c->type == X11;
|
return c->type == X11Managed || c->type == X11Unmanaged;
|
||||||
#endif
|
#else
|
||||||
return 0;
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
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)) {
|
||||||
|
xcb_size_hints_t *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 struct wlr_surface *
|
static inline struct wlr_surface *
|
||||||
|
@ -28,7 +54,7 @@ client_surface(Client *c)
|
||||||
static inline int
|
static inline int
|
||||||
toplevel_from_wlr_surface(struct wlr_surface *s, Client **pc, LayerSurface **pl)
|
toplevel_from_wlr_surface(struct wlr_surface *s, Client **pc, LayerSurface **pl)
|
||||||
{
|
{
|
||||||
struct wlr_xdg_surface *xdg_surface, *tmp_xdg_surface;
|
struct wlr_xdg_surface *xdg_surface;
|
||||||
struct wlr_surface *root_surface;
|
struct wlr_surface *root_surface;
|
||||||
struct wlr_layer_surface_v1 *layer_surface;
|
struct wlr_layer_surface_v1 *layer_surface;
|
||||||
Client *c = NULL;
|
Client *c = NULL;
|
||||||
|
@ -39,44 +65,44 @@ toplevel_from_wlr_surface(struct wlr_surface *s, Client **pc, LayerSurface **pl)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!s)
|
if (!s)
|
||||||
return -1;
|
return type;
|
||||||
root_surface = wlr_surface_get_root_surface(s);
|
root_surface = wlr_surface_get_root_surface(s);
|
||||||
|
|
||||||
#ifdef XWAYLAND
|
#ifdef XWAYLAND
|
||||||
if ((xsurface = wlr_xwayland_surface_try_from_wlr_surface(root_surface))) {
|
if (wlr_surface_is_xwayland_surface(root_surface)
|
||||||
|
&& (xsurface = wlr_xwayland_surface_from_wlr_surface(root_surface))) {
|
||||||
c = xsurface->data;
|
c = xsurface->data;
|
||||||
type = c->type;
|
type = c->type;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((layer_surface = wlr_layer_surface_v1_try_from_wlr_surface(root_surface))) {
|
if (wlr_surface_is_layer_surface(root_surface)
|
||||||
|
&& (layer_surface = wlr_layer_surface_v1_from_wlr_surface(root_surface))) {
|
||||||
l = layer_surface->data;
|
l = layer_surface->data;
|
||||||
type = LayerShell;
|
type = LayerShell;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
xdg_surface = wlr_xdg_surface_try_from_wlr_surface(root_surface);
|
if (wlr_surface_is_xdg_surface(root_surface)
|
||||||
while (xdg_surface) {
|
&& (xdg_surface = wlr_xdg_surface_from_wlr_surface(root_surface))) {
|
||||||
tmp_xdg_surface = NULL;
|
while (1) {
|
||||||
switch (xdg_surface->role) {
|
switch (xdg_surface->role) {
|
||||||
case WLR_XDG_SURFACE_ROLE_POPUP:
|
case WLR_XDG_SURFACE_ROLE_POPUP:
|
||||||
if (!xdg_surface->popup || !xdg_surface->popup->parent)
|
if (!xdg_surface->popup->parent)
|
||||||
|
return -1;
|
||||||
|
else if (!wlr_surface_is_xdg_surface(xdg_surface->popup->parent))
|
||||||
|
return toplevel_from_wlr_surface(xdg_surface->popup->parent, pc, pl);
|
||||||
|
|
||||||
|
xdg_surface = wlr_xdg_surface_from_wlr_surface(xdg_surface->popup->parent);
|
||||||
|
break;
|
||||||
|
case WLR_XDG_SURFACE_ROLE_TOPLEVEL:
|
||||||
|
c = xdg_surface->data;
|
||||||
|
type = c->type;
|
||||||
|
goto end;
|
||||||
|
case WLR_XDG_SURFACE_ROLE_NONE:
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
tmp_xdg_surface = wlr_xdg_surface_try_from_wlr_surface(xdg_surface->popup->parent);
|
|
||||||
|
|
||||||
if (!tmp_xdg_surface)
|
|
||||||
return toplevel_from_wlr_surface(xdg_surface->popup->parent, pc, pl);
|
|
||||||
|
|
||||||
xdg_surface = tmp_xdg_surface;
|
|
||||||
break;
|
|
||||||
case WLR_XDG_SURFACE_ROLE_TOPLEVEL:
|
|
||||||
c = xdg_surface->data;
|
|
||||||
type = c->type;
|
|
||||||
goto end;
|
|
||||||
case WLR_XDG_SURFACE_ROLE_NONE:
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,16 +118,19 @@ end:
|
||||||
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_toplevel *toplevel;
|
struct wlr_xdg_surface *surface;
|
||||||
#ifdef XWAYLAND
|
#ifdef XWAYLAND
|
||||||
struct wlr_xwayland_surface *xsurface;
|
struct wlr_xwayland_surface *xsurface;
|
||||||
if ((xsurface = wlr_xwayland_surface_try_from_wlr_surface(s))) {
|
if (wlr_surface_is_xwayland_surface(s)
|
||||||
|
&& (xsurface = wlr_xwayland_surface_from_wlr_surface(s))) {
|
||||||
wlr_xwayland_surface_activate(xsurface, activated);
|
wlr_xwayland_surface_activate(xsurface, activated);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if ((toplevel = wlr_xdg_toplevel_try_from_wlr_surface(s)))
|
if (wlr_surface_is_xdg_surface(s)
|
||||||
wlr_xdg_toplevel_set_activated(toplevel, activated);
|
&& (surface = wlr_xdg_surface_from_wlr_surface(s))
|
||||||
|
&& surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL)
|
||||||
|
wlr_xdg_toplevel_set_activated(surface->toplevel, activated);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t
|
static inline uint32_t
|
||||||
|
@ -111,16 +140,23 @@ client_set_bounds(Client *c, int32_t width, int32_t height)
|
||||||
if (client_is_x11(c))
|
if (client_is_x11(c))
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
if (wl_resource_get_version(c->surface.xdg->toplevel->resource) >=
|
if (c->surface.xdg->client->shell->version >=
|
||||||
XDG_TOPLEVEL_CONFIGURE_BOUNDS_SINCE_VERSION && width >= 0 && height >= 0
|
XDG_TOPLEVEL_CONFIGURE_BOUNDS_SINCE_VERSION && width >= 0 && height >= 0)
|
||||||
&& (c->bounds.width != width || c->bounds.height != height)) {
|
|
||||||
c->bounds.width = width;
|
|
||||||
c->bounds.height = height;
|
|
||||||
return wlr_xdg_toplevel_set_bounds(c->surface.xdg->toplevel, width, height);
|
return wlr_xdg_toplevel_set_bounds(c->surface.xdg->toplevel, width, height);
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
client_for_each_surface(Client *c, wlr_surface_iterator_func_t fn, void *data)
|
||||||
|
{
|
||||||
|
wlr_surface_for_each_surface(client_surface(c), fn, data);
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
if (client_is_x11(c))
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
wlr_xdg_surface_for_each_popup_surface(c->surface.xdg, fn, data);
|
||||||
|
}
|
||||||
|
|
||||||
static inline const char *
|
static inline const char *
|
||||||
client_get_appid(Client *c)
|
client_get_appid(Client *c)
|
||||||
{
|
{
|
||||||
|
@ -131,27 +167,6 @@ client_get_appid(Client *c)
|
||||||
return c->surface.xdg->toplevel->app_id;
|
return c->surface.xdg->toplevel->app_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
|
||||||
client_get_clip(Client *c, struct wlr_box *clip)
|
|
||||||
{
|
|
||||||
struct wlr_box xdg_geom = {0};
|
|
||||||
*clip = (struct wlr_box){
|
|
||||||
.x = 0,
|
|
||||||
.y = 0,
|
|
||||||
.width = c->geom.width - c->bw,
|
|
||||||
.height = c->geom.height - c->bw,
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef XWAYLAND
|
|
||||||
if (client_is_x11(c))
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
wlr_xdg_surface_get_geometry(c->surface.xdg, &xdg_geom);
|
|
||||||
clip->x = xdg_geom.x;
|
|
||||||
clip->y = xdg_geom.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
client_get_geometry(Client *c, struct wlr_box *geom)
|
client_get_geometry(Client *c, struct wlr_box *geom)
|
||||||
{
|
{
|
||||||
|
@ -172,27 +187,13 @@ client_get_parent(Client *c)
|
||||||
{
|
{
|
||||||
Client *p = NULL;
|
Client *p = NULL;
|
||||||
#ifdef XWAYLAND
|
#ifdef XWAYLAND
|
||||||
if (client_is_x11(c)) {
|
if (client_is_x11(c) && c->surface.xwayland->parent)
|
||||||
if (c->surface.xwayland->parent)
|
toplevel_from_wlr_surface(c->surface.xwayland->parent->surface, &p, NULL);
|
||||||
toplevel_from_wlr_surface(c->surface.xwayland->parent->surface, &p, NULL);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
if (c->surface.xdg->toplevel->parent)
|
if (c->surface.xdg->toplevel->parent)
|
||||||
toplevel_from_wlr_surface(c->surface.xdg->toplevel->parent->base->surface, &p, NULL);
|
toplevel_from_wlr_surface(c->surface.xdg->toplevel->parent->base->surface, &p, NULL);
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int
|
return p;
|
||||||
client_has_children(Client *c)
|
|
||||||
{
|
|
||||||
#ifdef XWAYLAND
|
|
||||||
if (client_is_x11(c))
|
|
||||||
return !wl_list_empty(&c->surface.xwayland->children);
|
|
||||||
#endif
|
|
||||||
/* surface.xdg->link is never empty because it always contains at least the
|
|
||||||
* surface itself. */
|
|
||||||
return wl_list_length(&c->surface.xdg->link) > 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline const char *
|
static inline const char *
|
||||||
|
@ -208,35 +209,35 @@ client_get_title(Client *c)
|
||||||
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;
|
||||||
xcb_size_hints_t *size_hints = surface->size_hints;
|
|
||||||
size_t i;
|
|
||||||
if (surface->modal)
|
if (surface->modal)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
for (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;
|
||||||
|
|
||||||
return size_hints && size_hints->min_width > 0 && size_hints->min_height > 0
|
|
||||||
&& (size_hints->max_width == size_hints->min_width
|
|
||||||
|| size_hints->max_height == size_hints->min_height);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
return ((min.width > 0 || min.height > 0 || max.width > 0 || max.height > 0)
|
||||||
|
&& (min.width == max.width || min.height == max.height));
|
||||||
|
}
|
||||||
|
|
||||||
toplevel = c->surface.xdg->toplevel;
|
static inline int
|
||||||
state = toplevel->current;
|
client_is_mapped(Client *c)
|
||||||
return toplevel->parent || (state.min_width != 0 && state.min_height != 0
|
{
|
||||||
&& (state.min_width == state.max_width
|
#ifdef XWAYLAND
|
||||||
|| state.min_height == state.max_height));
|
if (client_is_x11(c))
|
||||||
|
return c->surface.xwayland->mapped;
|
||||||
|
#endif
|
||||||
|
return c->surface.xdg->mapped;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
|
@ -246,8 +247,7 @@ client_is_rendered_on_mon(Client *c, Monitor *m)
|
||||||
* but rather actual displaying of the pixels.
|
* but rather actual displaying of the pixels.
|
||||||
* Usually VISIBLEON suffices and is also faster. */
|
* Usually VISIBLEON suffices and is also faster. */
|
||||||
struct wlr_surface_output *s;
|
struct wlr_surface_output *s;
|
||||||
int unused_lx, unused_ly;
|
if (!c->scene->node.enabled)
|
||||||
if (!wlr_scene_node_coords(&c->scene->node, &unused_lx, &unused_ly))
|
|
||||||
return 0;
|
return 0;
|
||||||
wl_list_for_each(s, &client_surface(c)->current_outputs, link)
|
wl_list_for_each(s, &client_surface(c)->current_outputs, link)
|
||||||
if (s->output == m->wlr_output)
|
if (s->output == m->wlr_output)
|
||||||
|
@ -285,8 +285,7 @@ static inline int
|
||||||
client_is_unmanaged(Client *c)
|
client_is_unmanaged(Client *c)
|
||||||
{
|
{
|
||||||
#ifdef XWAYLAND
|
#ifdef XWAYLAND
|
||||||
if (client_is_x11(c))
|
return c->type == X11Unmanaged;
|
||||||
return c->surface.xwayland->override_redirect;
|
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -324,14 +323,6 @@ client_send_close(Client *c)
|
||||||
wlr_xdg_toplevel_send_close(c->surface.xdg->toplevel);
|
wlr_xdg_toplevel_send_close(c->surface.xdg->toplevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
|
||||||
client_set_border_color(Client *c, const float color[static 4])
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < 4; i++)
|
|
||||||
wlr_scene_rect_set_color(c->border[i], color);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
client_set_fullscreen(Client *c, int fullscreen)
|
client_set_fullscreen(Client *c, int fullscreen)
|
||||||
{
|
{
|
||||||
|
@ -350,14 +341,14 @@ client_set_size(Client *c, uint32_t width, uint32_t height)
|
||||||
#ifdef XWAYLAND
|
#ifdef XWAYLAND
|
||||||
if (client_is_x11(c)) {
|
if (client_is_x11(c)) {
|
||||||
wlr_xwayland_surface_configure(c->surface.xwayland,
|
wlr_xwayland_surface_configure(c->surface.xwayland,
|
||||||
c->geom.x + c->bw, c->geom.y + c->bw, width, height);
|
c->geom.x, c->geom.y, width, height);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if ((int32_t)width == c->surface.xdg->toplevel->current.width
|
if (width == c->surface.xdg->toplevel->current.width
|
||||||
&& (int32_t)height == c->surface.xdg->toplevel->current.height)
|
&& height ==c->surface.xdg->toplevel->current.height)
|
||||||
return 0;
|
return 0;
|
||||||
return wlr_xdg_toplevel_set_size(c->surface.xdg->toplevel, (int32_t)width, (int32_t)height);
|
return wlr_xdg_toplevel_set_size(c->surface.xdg->toplevel, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
@ -367,23 +358,18 @@ client_set_tiled(Client *c, uint32_t edges)
|
||||||
if (client_is_x11(c))
|
if (client_is_x11(c))
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
if (wl_resource_get_version(c->surface.xdg->toplevel->resource)
|
wlr_xdg_toplevel_set_tiled(c->surface.xdg->toplevel, edges);
|
||||||
>= XDG_TOPLEVEL_STATE_TILED_RIGHT_SINCE_VERSION) {
|
|
||||||
wlr_xdg_toplevel_set_tiled(c->surface.xdg->toplevel, edges);
|
|
||||||
} else {
|
|
||||||
wlr_xdg_toplevel_set_maximized(c->surface.xdg->toplevel, edges != WLR_EDGE_NONE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline struct wlr_surface *
|
||||||
client_set_suspended(Client *c, int suspended)
|
client_surface_at(Client *c, double cx, double cy, double *sx, double *sy)
|
||||||
{
|
{
|
||||||
#ifdef XWAYLAND
|
#ifdef XWAYLAND
|
||||||
if (client_is_x11(c))
|
if (client_is_x11(c))
|
||||||
return;
|
return wlr_surface_surface_at(c->surface.xwayland->surface,
|
||||||
|
cx, cy, sx, sy);
|
||||||
#endif
|
#endif
|
||||||
|
return wlr_xdg_surface_surface_at(c->surface.xdg, cx, cy, sx, sy);
|
||||||
wlr_xdg_toplevel_set_suspended(c->surface.xdg->toplevel, suspended);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
[]
|
|
80
config.def.h
80
config.def.h
|
@ -1,37 +1,21 @@
|
||||||
/* Taken from https://github.com/djpohly/dwl/issues/466 */
|
|
||||||
#define COLOR(hex) { ((hex >> 24) & 0xFF) / 255.0f, \
|
|
||||||
((hex >> 16) & 0xFF) / 255.0f, \
|
|
||||||
((hex >> 8) & 0xFF) / 255.0f, \
|
|
||||||
(hex & 0xFF) / 255.0f }
|
|
||||||
/* appearance */
|
/* appearance */
|
||||||
static const int sloppyfocus = 1; /* focus follows mouse */
|
static const int sloppyfocus = 1; /* focus follows mouse */
|
||||||
static const int bypass_surface_visibility = 0; /* 1 means idle inhibitors will disable idle tracking even if it's surface isn't visible */
|
static const int bypass_surface_visibility = 0; /* 1 means idle inhibitors will disable idle tracking even if it's surface isn't visible */
|
||||||
static const unsigned int borderpx = 1; /* border pixel of windows */
|
static const unsigned int borderpx = 1; /* border pixel of windows */
|
||||||
static const int showbar = 1; /* 0 means no bar */
|
static const float bordercolor[] = {0.5, 0.5, 0.5, 1.0};
|
||||||
static const int topbar = 1; /* 0 means bottom bar */
|
static const float focuscolor[] = {1.0, 0.0, 0.0, 1.0};
|
||||||
static const char *fonts[] = {"monospace:size=10"};
|
/* To conform the xdg-protocol, set the alpha to zero to restore the old behavior */
|
||||||
static const float rootcolor[] = COLOR(0x000000ff);
|
static const float fullscreen_bg[] = {0.1, 0.1, 0.1, 1.0};
|
||||||
/* This conforms to the xdg-protocol. Set the alpha to zero to restore the old behavior */
|
|
||||||
static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You can also use glsl colors */
|
|
||||||
static uint32_t colors[][3] = {
|
|
||||||
/* fg bg border */
|
|
||||||
[SchemeNorm] = { 0xbbbbbbff, 0x222222ff, 0x444444ff },
|
|
||||||
[SchemeSel] = { 0xeeeeeeff, 0x005577ff, 0x005577ff },
|
|
||||||
[SchemeUrg] = { 0, 0, 0x770000ff },
|
|
||||||
};
|
|
||||||
|
|
||||||
/* tagging - TAGCOUNT must be no greater than 31 */
|
/* tagging - tagcount must be no greater than 31 */
|
||||||
static char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
|
static const int tagcount = 9;
|
||||||
|
|
||||||
/* logging */
|
|
||||||
static int log_level = WLR_ERROR;
|
|
||||||
|
|
||||||
/* NOTE: ALWAYS keep a rule declared even if you don't use rules (e.g leave at least one example) */
|
|
||||||
static const Rule rules[] = {
|
static const Rule rules[] = {
|
||||||
/* app_id title tags mask isfloating monitor */
|
/* app_id title tags mask isfloating monitor */
|
||||||
/* examples: */
|
/* examples:
|
||||||
{ "Gimp_EXAMPLE", NULL, 0, 1, -1 }, /* Start on currently visible tags floating, not tiled */
|
{ "Gimp", NULL, 0, 1, -1 },
|
||||||
{ "discord", NULL, 1 << 1, 0, 1 }, /* Start on ONLY tag "9" */
|
*/
|
||||||
|
{ "firefox", NULL, 1 << 8, 0, -1 },
|
||||||
};
|
};
|
||||||
|
|
||||||
/* layout(s) */
|
/* layout(s) */
|
||||||
|
@ -43,20 +27,13 @@ static const Layout layouts[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* monitors */
|
/* monitors */
|
||||||
/* (x=-1, y=-1) is reserved as an "autoconfigure" monitor position indicator
|
|
||||||
* WARNING: negative values other than (-1, -1) cause problems with Xwayland clients
|
|
||||||
* https://gitlab.freedesktop.org/xorg/xserver/-/issues/899
|
|
||||||
*/
|
|
||||||
/* NOTE: ALWAYS add a fallback rule, even if you are completely sure it won't be used */
|
|
||||||
static const MonitorRule monrules[] = {
|
static const MonitorRule monrules[] = {
|
||||||
/* name mfact nmaster scale layout rotate/reflect x y */
|
/* name mfact nmaster scale layout rotate/reflect x y */
|
||||||
/* example of a HiDPI laptop monitor:
|
/* example of a HiDPI laptop monitor:
|
||||||
{ "eDP-1", 0.5f, 1, 2, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 },
|
{ "eDP-1", 0.5, 1, 2, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 },
|
||||||
*/
|
*/
|
||||||
{ "HDMI-A-1", 0.5f, 1, 1, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, 0, 0 },
|
|
||||||
{ "DP-1", 0.5f, 1, 1, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, 1920, 0 },
|
|
||||||
/* defaults */
|
/* defaults */
|
||||||
{ NULL, 0.55f, 1, 1, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 },
|
{ NULL, 0.55, 1, 1, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 },
|
||||||
};
|
};
|
||||||
|
|
||||||
/* keyboard */
|
/* keyboard */
|
||||||
|
@ -107,7 +84,6 @@ LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE
|
||||||
*/
|
*/
|
||||||
static const enum libinput_config_accel_profile accel_profile = 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;
|
static const double accel_speed = 0.0;
|
||||||
|
|
||||||
/* You can choose between:
|
/* You can choose between:
|
||||||
LIBINPUT_CONFIG_TAP_MAP_LRM -- 1/2/3 finger tap maps to left/right/middle
|
LIBINPUT_CONFIG_TAP_MAP_LRM -- 1/2/3 finger tap maps to left/right/middle
|
||||||
LIBINPUT_CONFIG_TAP_MAP_LMR -- 1/2/3 finger tap maps to left/middle/right
|
LIBINPUT_CONFIG_TAP_MAP_LMR -- 1/2/3 finger tap maps to left/middle/right
|
||||||
|
@ -115,7 +91,7 @@ LIBINPUT_CONFIG_TAP_MAP_LMR -- 1/2/3 finger tap maps to left/middle/right
|
||||||
static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TAP_MAP_LRM;
|
static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TAP_MAP_LRM;
|
||||||
|
|
||||||
/* If you want to use the windows key for MODKEY, use WLR_MODIFIER_LOGO */
|
/* If you want to use the windows key for MODKEY, use WLR_MODIFIER_LOGO */
|
||||||
#define MODKEY WLR_MODIFIER_LOGO
|
#define MODKEY WLR_MODIFIER_ALT
|
||||||
|
|
||||||
#define TAGKEYS(KEY,SKEY,TAG) \
|
#define TAGKEYS(KEY,SKEY,TAG) \
|
||||||
{ MODKEY, KEY, view, {.ui = 1 << TAG} }, \
|
{ MODKEY, KEY, view, {.ui = 1 << TAG} }, \
|
||||||
|
@ -127,21 +103,20 @@ static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TA
|
||||||
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
|
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
|
||||||
|
|
||||||
/* commands */
|
/* commands */
|
||||||
static const char *termcmd[] = { "kitty", NULL };
|
static const char *termcmd[] = { "foot", NULL };
|
||||||
static const char *menucmd[] = { "wmenu-run", NULL };
|
static const char *menucmd[] = { "bemenu-run", NULL };
|
||||||
|
|
||||||
static const Key keys[] = {
|
static const Key keys[] = {
|
||||||
/* Note that Shift changes certain key codes: c -> C, 2 -> at, etc. */
|
/* Note that Shift changes certain key codes: c -> C, 2 -> at, etc. */
|
||||||
/* modifier key function argument */
|
/* modifier key function argument */
|
||||||
{ MODKEY, XKB_KEY_p, spawn, {.v = menucmd} },
|
{ MODKEY, XKB_KEY_p, spawn, {.v = menucmd} },
|
||||||
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Return, spawn, {.v = termcmd} },
|
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Return, spawn, {.v = termcmd} },
|
||||||
{ MODKEY, XKB_KEY_b, togglebar, {0} },
|
|
||||||
{ MODKEY, XKB_KEY_j, focusstack, {.i = +1} },
|
{ MODKEY, XKB_KEY_j, focusstack, {.i = +1} },
|
||||||
{ MODKEY, XKB_KEY_k, focusstack, {.i = -1} },
|
{ MODKEY, XKB_KEY_k, focusstack, {.i = -1} },
|
||||||
{ MODKEY, XKB_KEY_i, incnmaster, {.i = +1} },
|
{ MODKEY, XKB_KEY_i, incnmaster, {.i = +1} },
|
||||||
{ MODKEY, XKB_KEY_d, incnmaster, {.i = -1} },
|
{ MODKEY, XKB_KEY_d, incnmaster, {.i = -1} },
|
||||||
{ MODKEY, XKB_KEY_h, setmfact, {.f = -0.05f} },
|
{ MODKEY, XKB_KEY_h, setmfact, {.f = -0.05} },
|
||||||
{ MODKEY, XKB_KEY_l, setmfact, {.f = +0.05f} },
|
{ 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} },
|
||||||
|
@ -170,24 +145,13 @@ static const Key keys[] = {
|
||||||
|
|
||||||
/* 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} },
|
||||||
/* Ctrl-Alt-Fx is used to switch to another VT, if you don't know what a VT is
|
|
||||||
* do not remove them.
|
|
||||||
*/
|
|
||||||
#define CHVT(n) { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_XF86Switch_VT_##n, chvt, {.ui = (n)} }
|
#define CHVT(n) { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_XF86Switch_VT_##n, chvt, {.ui = (n)} }
|
||||||
CHVT(1), CHVT(2), CHVT(3), CHVT(4), CHVT(5), CHVT(6),
|
CHVT(1), CHVT(2), CHVT(3), CHVT(4), CHVT(5), CHVT(6),
|
||||||
CHVT(7), CHVT(8), CHVT(9), CHVT(10), CHVT(11), CHVT(12),
|
CHVT(7), CHVT(8), CHVT(9), CHVT(10), CHVT(11), CHVT(12),
|
||||||
};
|
};
|
||||||
|
|
||||||
static const Button buttons[] = {
|
static const Button buttons[] = {
|
||||||
{ ClkLtSymbol, 0, BTN_LEFT, setlayout, {.v = &layouts[0]} },
|
{ MODKEY, BTN_LEFT, moveresize, {.ui = CurMove} },
|
||||||
{ ClkLtSymbol, 0, BTN_RIGHT, setlayout, {.v = &layouts[2]} },
|
{ MODKEY, BTN_MIDDLE, togglefloating, {0} },
|
||||||
{ ClkTitle, 0, BTN_MIDDLE, zoom, {0} },
|
{ MODKEY, BTN_RIGHT, moveresize, {.ui = CurResize} },
|
||||||
{ ClkStatus, 0, BTN_MIDDLE, spawn, {.v = termcmd} },
|
|
||||||
{ ClkClient, MODKEY, BTN_LEFT, moveresize, {.ui = CurMove} },
|
|
||||||
{ ClkClient, MODKEY, BTN_MIDDLE, togglefloating, {0} },
|
|
||||||
{ ClkClient, MODKEY, BTN_RIGHT, moveresize, {.ui = CurResize} },
|
|
||||||
{ ClkTagBar, 0, BTN_LEFT, view, {0} },
|
|
||||||
{ ClkTagBar, 0, BTN_RIGHT, toggleview, {0} },
|
|
||||||
{ ClkTagBar, MODKEY, BTN_LEFT, tag, {0} },
|
|
||||||
{ ClkTagBar, MODKEY, BTN_RIGHT, toggletag, {0} },
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
_VERSION = 0.7
|
_VERSION = 0.4
|
||||||
VERSION = `git describe --tags --dirty 2>/dev/null || echo $(_VERSION)`
|
VERSION = `git describe --tags --dirty 2>/dev/null || echo $(_VERSION)`
|
||||||
|
|
||||||
PKG_CONFIG = pkg-config
|
PKG_CONFIG = pkg-config
|
||||||
|
@ -6,12 +6,9 @@ PKG_CONFIG = pkg-config
|
||||||
# paths
|
# paths
|
||||||
PREFIX = /usr/local
|
PREFIX = /usr/local
|
||||||
MANDIR = $(PREFIX)/share/man
|
MANDIR = $(PREFIX)/share/man
|
||||||
DATADIR = $(PREFIX)/share
|
|
||||||
|
|
||||||
XWAYLAND =
|
XWAYLAND =
|
||||||
XLIBS =
|
XLIBS =
|
||||||
# Uncomment to build XWayland support
|
# Uncomment to build XWayland support
|
||||||
#XWAYLAND = -DXWAYLAND
|
#XWAYLAND = -DXWAYLAND
|
||||||
#XLIBS = xcb xcb-icccm
|
#XLIBS = xcb xcb-icccm
|
||||||
|
|
||||||
CC = gcc
|
|
||||||
|
|
311
drwl.h
311
drwl.h
|
@ -1,311 +0,0 @@
|
||||||
/*
|
|
||||||
* drwl - https://codeberg.org/sewn/drwl
|
|
||||||
*
|
|
||||||
* Copyright (c) 2023-2024 sewn <sewn@disroot.org>
|
|
||||||
* Copyright (c) 2024 notchoc <notchoc@disroot.org>
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* The UTF-8 Decoder included is from Bjoern Hoehrmann:
|
|
||||||
* Copyright (c) 2008-2010 Bjoern Hoehrmann <bjoern@hoehrmann.de>
|
|
||||||
* See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details.
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <fcft/fcft.h>
|
|
||||||
#include <pixman-1/pixman.h>
|
|
||||||
|
|
||||||
enum { ColFg, ColBg, ColBorder }; /* colorscheme index */
|
|
||||||
|
|
||||||
typedef struct fcft_font Fnt;
|
|
||||||
typedef pixman_image_t Img;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
Img *image;
|
|
||||||
Fnt *font;
|
|
||||||
uint32_t *scheme;
|
|
||||||
} Drwl;
|
|
||||||
|
|
||||||
#define UTF8_ACCEPT 0
|
|
||||||
#define UTF8_REJECT 12
|
|
||||||
#define UTF8_INVALID 0xFFFD
|
|
||||||
|
|
||||||
static const uint8_t utf8d[] = {
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
|
|
||||||
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
|
||||||
8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
|
||||||
10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8,
|
|
||||||
|
|
||||||
0,12,24,36,60,96,84,12,12,12,48,72, 12,12,12,12,12,12,12,12,12,12,12,12,
|
|
||||||
12, 0,12,12,12,12,12, 0,12, 0,12,12, 12,24,12,12,12,12,12,24,12,24,12,12,
|
|
||||||
12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24,12,12,
|
|
||||||
12,12,12,12,12,12,12,36,12,36,12,12, 12,36,12,12,12,12,12,36,12,36,12,12,
|
|
||||||
12,36,12,12,12,12,12,12,12,12,12,12,
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline uint32_t
|
|
||||||
utf8decode(uint32_t *state, uint32_t *codep, uint8_t byte)
|
|
||||||
{
|
|
||||||
uint32_t type = utf8d[byte];
|
|
||||||
|
|
||||||
*codep = (*state != UTF8_ACCEPT) ?
|
|
||||||
(byte & 0x3fu) | (*codep << 6) :
|
|
||||||
(0xff >> type) & (byte);
|
|
||||||
|
|
||||||
*state = utf8d[256 + *state + type];
|
|
||||||
return *state;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
drwl_init(void)
|
|
||||||
{
|
|
||||||
fcft_set_scaling_filter(FCFT_SCALING_FILTER_LANCZOS3);
|
|
||||||
return fcft_init(FCFT_LOG_COLORIZE_AUTO, 0, FCFT_LOG_CLASS_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Drwl *
|
|
||||||
drwl_create(void)
|
|
||||||
{
|
|
||||||
Drwl *drwl;
|
|
||||||
|
|
||||||
if (!(drwl = calloc(1, sizeof(Drwl))))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return drwl;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
drwl_setfont(Drwl *drwl, Fnt *font)
|
|
||||||
{
|
|
||||||
if (drwl)
|
|
||||||
drwl->font = font;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
drwl_setimage(Drwl *drwl, Img *image)
|
|
||||||
{
|
|
||||||
if (drwl)
|
|
||||||
drwl->image = image;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Fnt *
|
|
||||||
drwl_font_create(Drwl *drwl, size_t count,
|
|
||||||
const char *names[static count], const char *attributes)
|
|
||||||
{
|
|
||||||
Fnt *font = fcft_from_name(count, names, attributes);
|
|
||||||
if (drwl)
|
|
||||||
drwl_setfont(drwl, font);
|
|
||||||
return font;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
drwl_font_destroy(Fnt *font)
|
|
||||||
{
|
|
||||||
fcft_destroy(font);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline pixman_color_t
|
|
||||||
convert_color(uint32_t clr)
|
|
||||||
{
|
|
||||||
return (pixman_color_t){
|
|
||||||
((clr >> 24) & 0xFF) * 0x101 * (clr & 0xFF) / 0xFF,
|
|
||||||
((clr >> 16) & 0xFF) * 0x101 * (clr & 0xFF) / 0xFF,
|
|
||||||
((clr >> 8) & 0xFF) * 0x101 * (clr & 0xFF) / 0xFF,
|
|
||||||
(clr & 0xFF) * 0x101
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
drwl_setscheme(Drwl *drwl, uint32_t *scm)
|
|
||||||
{
|
|
||||||
if (drwl)
|
|
||||||
drwl->scheme = scm;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Img *
|
|
||||||
drwl_image_create(Drwl *drwl, unsigned int w, unsigned int h, uint32_t *bits)
|
|
||||||
{
|
|
||||||
Img *image;
|
|
||||||
pixman_region32_t clip;
|
|
||||||
|
|
||||||
image = pixman_image_create_bits_no_clear(
|
|
||||||
PIXMAN_a8r8g8b8, w, h, bits, w * 4);
|
|
||||||
if (!image)
|
|
||||||
return NULL;
|
|
||||||
pixman_region32_init_rect(&clip, 0, 0, w, h);
|
|
||||||
pixman_image_set_clip_region32(image, &clip);
|
|
||||||
pixman_region32_fini(&clip);
|
|
||||||
|
|
||||||
if (drwl)
|
|
||||||
drwl_setimage(drwl, image);
|
|
||||||
return image;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
drwl_rect(Drwl *drwl,
|
|
||||||
int x, int y, unsigned int w, unsigned int h,
|
|
||||||
int filled, int invert)
|
|
||||||
{
|
|
||||||
pixman_color_t clr;
|
|
||||||
if (!drwl || !drwl->scheme || !drwl->image)
|
|
||||||
return;
|
|
||||||
|
|
||||||
clr = convert_color(drwl->scheme[invert ? ColBg : ColFg]);
|
|
||||||
if (filled)
|
|
||||||
pixman_image_fill_rectangles(PIXMAN_OP_SRC, drwl->image, &clr, 1,
|
|
||||||
&(pixman_rectangle16_t){x, y, w, h});
|
|
||||||
else
|
|
||||||
pixman_image_fill_rectangles(PIXMAN_OP_SRC, drwl->image, &clr, 4,
|
|
||||||
(pixman_rectangle16_t[4]){
|
|
||||||
{ x, y, w, 1 },
|
|
||||||
{ x, y + h - 1, w, 1 },
|
|
||||||
{ x, y, 1, h },
|
|
||||||
{ x + w - 1, y, 1, h }});
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
drwl_text(Drwl *drwl,
|
|
||||||
int x, int y, unsigned int w, unsigned int h,
|
|
||||||
unsigned int lpad, const char *text, int invert)
|
|
||||||
{
|
|
||||||
int ty;
|
|
||||||
int render = x || y || w || h;
|
|
||||||
long x_kern;
|
|
||||||
uint32_t cp = 0, last_cp = 0, state;
|
|
||||||
pixman_color_t clr;
|
|
||||||
pixman_image_t *fg_pix = NULL;
|
|
||||||
int noellipsis = 0;
|
|
||||||
const struct fcft_glyph *glyph, *eg = NULL;
|
|
||||||
int fcft_subpixel_mode = FCFT_SUBPIXEL_DEFAULT;
|
|
||||||
|
|
||||||
if (!drwl || (render && (!drwl->scheme || !w || !drwl->image)) || !text || !drwl->font)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!render) {
|
|
||||||
w = invert ? invert : ~invert;
|
|
||||||
} else {
|
|
||||||
clr = convert_color(drwl->scheme[invert ? ColBg : ColFg]);
|
|
||||||
fg_pix = pixman_image_create_solid_fill(&clr);
|
|
||||||
|
|
||||||
drwl_rect(drwl, x, y, w, h, 1, !invert);
|
|
||||||
|
|
||||||
x += lpad;
|
|
||||||
w -= lpad;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (render && (drwl->scheme[ColBg] & 0xFF) != 0xFF)
|
|
||||||
fcft_subpixel_mode = FCFT_SUBPIXEL_NONE;
|
|
||||||
|
|
||||||
if (render)
|
|
||||||
eg = fcft_rasterize_char_utf32(drwl->font, 0x2026 /* … */, fcft_subpixel_mode);
|
|
||||||
|
|
||||||
for (const char *p = text, *pp; pp = p, *p; p++) {
|
|
||||||
for (state = UTF8_ACCEPT; *p &&
|
|
||||||
utf8decode(&state, &cp, *p) > UTF8_REJECT; p++)
|
|
||||||
;
|
|
||||||
if (!*p || state == UTF8_REJECT) {
|
|
||||||
cp = UTF8_INVALID;
|
|
||||||
if (p > pp)
|
|
||||||
p--;
|
|
||||||
}
|
|
||||||
|
|
||||||
glyph = fcft_rasterize_char_utf32(drwl->font, cp, fcft_subpixel_mode);
|
|
||||||
if (!glyph)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
x_kern = 0;
|
|
||||||
if (last_cp)
|
|
||||||
fcft_kerning(drwl->font, last_cp, cp, &x_kern, NULL);
|
|
||||||
last_cp = cp;
|
|
||||||
|
|
||||||
ty = y + (h - drwl->font->height) / 2 + drwl->font->ascent;
|
|
||||||
|
|
||||||
if (render && !noellipsis && x_kern + glyph->advance.x + eg->advance.x > w &&
|
|
||||||
*(p + 1) != '\0') {
|
|
||||||
/* cannot fit ellipsis after current codepoint */
|
|
||||||
if (drwl_text(drwl, 0, 0, 0, 0, 0, pp, 0) + x_kern <= w) {
|
|
||||||
noellipsis = 1;
|
|
||||||
} else {
|
|
||||||
w -= eg->advance.x;
|
|
||||||
pixman_image_composite32(
|
|
||||||
PIXMAN_OP_OVER, fg_pix, eg->pix, drwl->image, 0, 0, 0, 0,
|
|
||||||
x + eg->x, ty - eg->y, eg->width, eg->height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((x_kern + glyph->advance.x) > w)
|
|
||||||
break;
|
|
||||||
|
|
||||||
x += x_kern;
|
|
||||||
|
|
||||||
if (render && pixman_image_get_format(glyph->pix) == PIXMAN_a8r8g8b8)
|
|
||||||
/* pre-rendered glyphs (eg. emoji) */
|
|
||||||
pixman_image_composite32(
|
|
||||||
PIXMAN_OP_OVER, glyph->pix, NULL, drwl->image, 0, 0, 0, 0,
|
|
||||||
x + glyph->x, ty - glyph->y, glyph->width, glyph->height);
|
|
||||||
else if (render)
|
|
||||||
pixman_image_composite32(
|
|
||||||
PIXMAN_OP_OVER, fg_pix, glyph->pix, drwl->image, 0, 0, 0, 0,
|
|
||||||
x + glyph->x, ty - glyph->y, glyph->width, glyph->height);
|
|
||||||
|
|
||||||
x += glyph->advance.x;
|
|
||||||
w -= glyph->advance.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (render)
|
|
||||||
pixman_image_unref(fg_pix);
|
|
||||||
|
|
||||||
return x + (render ? w : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned int
|
|
||||||
drwl_font_getwidth(Drwl *drwl, const char *text)
|
|
||||||
{
|
|
||||||
if (!drwl || !drwl->font || !text)
|
|
||||||
return 0;
|
|
||||||
return drwl_text(drwl, 0, 0, 0, 0, 0, text, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
drwl_image_destroy(Img *image)
|
|
||||||
{
|
|
||||||
pixman_image_unref(image);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
drwl_destroy(Drwl *drwl)
|
|
||||||
{
|
|
||||||
if (drwl->font)
|
|
||||||
drwl_font_destroy(drwl->font);
|
|
||||||
if (drwl->image)
|
|
||||||
drwl_image_destroy(drwl->image);
|
|
||||||
free(drwl);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
drwl_fini(void)
|
|
||||||
{
|
|
||||||
fcft_fini();
|
|
||||||
}
|
|
15
dwl.1
15
dwl.1
|
@ -7,7 +7,6 @@
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm
|
.Nm
|
||||||
.Op Fl v
|
.Op Fl v
|
||||||
.Op Fl d
|
|
||||||
.Op Fl s Ar startup command
|
.Op Fl s Ar startup command
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
.Nm
|
.Nm
|
||||||
|
@ -23,12 +22,6 @@ option,
|
||||||
writes its name and version to standard error and exits unsuccessfully.
|
writes its name and version to standard error and exits unsuccessfully.
|
||||||
.Pp
|
.Pp
|
||||||
When given the
|
When given the
|
||||||
.Fl d
|
|
||||||
option,
|
|
||||||
.Nm
|
|
||||||
enables full wlroots logging, including debug information.
|
|
||||||
.Pp
|
|
||||||
When given the
|
|
||||||
.Fl s
|
.Fl s
|
||||||
option,
|
option,
|
||||||
.Nm
|
.Nm
|
||||||
|
@ -55,7 +48,7 @@ Move window to a single tag.
|
||||||
Toggle tag for window.
|
Toggle tag for window.
|
||||||
.It Mod-p
|
.It Mod-p
|
||||||
Spawn
|
Spawn
|
||||||
.Nm wmenu-run .
|
.Nm bemenu-run .
|
||||||
.It Mod-Shift-Return
|
.It Mod-Shift-Return
|
||||||
Spawn
|
Spawn
|
||||||
.Nm foot .
|
.Nm foot .
|
||||||
|
@ -108,7 +101,7 @@ These environment variables are used by
|
||||||
A directory where temporary user files, such as the Wayland socket,
|
A directory where temporary user files, such as the Wayland socket,
|
||||||
are stored.
|
are stored.
|
||||||
.It Ev XDG_CONFIG_DIR
|
.It Ev XDG_CONFIG_DIR
|
||||||
A directory containing configuration of various programs and
|
A directory containung configuration of various programs and
|
||||||
libraries, including libxkbcommon.
|
libraries, including libxkbcommon.
|
||||||
.It Ev DISPLAY , WAYLAND_DISPLAY , WAYLAND_SOCKET
|
.It Ev DISPLAY , WAYLAND_DISPLAY , WAYLAND_SOCKET
|
||||||
Tell how to connect to an underlying X11 or Wayland server.
|
Tell how to connect to an underlying X11 or Wayland server.
|
||||||
|
@ -140,10 +133,10 @@ server.
|
||||||
Start
|
Start
|
||||||
.Nm
|
.Nm
|
||||||
with s6 in the background:
|
with s6 in the background:
|
||||||
.Dl dwl \-s \(aqs6\-svscan <&\-\(aq
|
.Dl dwl -s 's6-svscan <&-'
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr foot 1 ,
|
.Xr foot 1 ,
|
||||||
.Xr wmenu 1 ,
|
.Xr bemenu 1 ,
|
||||||
.Xr dwm 1 ,
|
.Xr dwm 1 ,
|
||||||
.Xr xkeyboard-config 7
|
.Xr xkeyboard-config 7
|
||||||
.Sh CAVEATS
|
.Sh CAVEATS
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
[Desktop Entry]
|
|
||||||
Name=dwl
|
|
||||||
Comment=dwm for Wayland
|
|
||||||
Exec=dwl
|
|
||||||
Type=Application
|
|
58
flake.lock
58
flake.lock
|
@ -1,58 +0,0 @@
|
||||||
{
|
|
||||||
"nodes": {
|
|
||||||
"flake-parts": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs-lib": "nixpkgs-lib"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1733312601,
|
|
||||||
"narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=",
|
|
||||||
"owner": "hercules-ci",
|
|
||||||
"repo": "flake-parts",
|
|
||||||
"rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "hercules-ci",
|
|
||||||
"repo": "flake-parts",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1733759999,
|
|
||||||
"narHash": "sha256-463SNPWmz46iLzJKRzO3Q2b0Aurff3U1n0nYItxq7jU=",
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "a73246e2eef4c6ed172979932bc80e1404ba2d56",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "NixOS",
|
|
||||||
"ref": "nixos-unstable",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs-lib": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1733096140,
|
|
||||||
"narHash": "sha256-1qRH7uAUsyQI7R1Uwl4T+XvdNv778H0Nb5njNrqvylY=",
|
|
||||||
"type": "tarball",
|
|
||||||
"url": "https://github.com/NixOS/nixpkgs/archive/5487e69da40cbd611ab2cadee0b4637225f7cfae.tar.gz"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"type": "tarball",
|
|
||||||
"url": "https://github.com/NixOS/nixpkgs/archive/5487e69da40cbd611ab2cadee0b4637225f7cfae.tar.gz"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": {
|
|
||||||
"inputs": {
|
|
||||||
"flake-parts": "flake-parts",
|
|
||||||
"nixpkgs": "nixpkgs"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": "root",
|
|
||||||
"version": 7
|
|
||||||
}
|
|
28
flake.nix
28
flake.nix
|
@ -1,28 +0,0 @@
|
||||||
{
|
|
||||||
description = "dwm for Wayland (requires dwl 0.7)";
|
|
||||||
|
|
||||||
inputs = {
|
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
|
||||||
flake-parts.url = "github:hercules-ci/flake-parts";
|
|
||||||
};
|
|
||||||
|
|
||||||
outputs = inputs@{ flake-parts, nixpkgs, ... }:
|
|
||||||
flake-parts.lib.mkFlake { inherit inputs; } {
|
|
||||||
imports = [
|
|
||||||
flake-parts.flakeModules.easyOverlay
|
|
||||||
];
|
|
||||||
systems = nixpkgs.lib.platforms.unix;
|
|
||||||
perSystem = { config, self', inputs', pkgs, system, ... }: {
|
|
||||||
overlayAttrs = {
|
|
||||||
zdwl = config.packages.default;
|
|
||||||
};
|
|
||||||
packages.default = pkgs.dwl.overrideAttrs (old: {
|
|
||||||
buildInputs = old.buildInputs ++ (with pkgs; [
|
|
||||||
fcft
|
|
||||||
libdrm.dev
|
|
||||||
]);
|
|
||||||
src = ./.;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,128 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<protocol name="wlr_output_power_management_unstable_v1">
|
|
||||||
<copyright>
|
|
||||||
Copyright © 2019 Purism SPC
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
copy of this software and associated documentation files (the "Software"),
|
|
||||||
to deal in the Software without restriction, including without limitation
|
|
||||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
Software is furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice (including the next
|
|
||||||
paragraph) shall be included in all copies or substantial portions of the
|
|
||||||
Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
</copyright>
|
|
||||||
|
|
||||||
<description summary="Control power management modes of outputs">
|
|
||||||
This protocol allows clients to control power management modes
|
|
||||||
of outputs that are currently part of the compositor space. The
|
|
||||||
intent is to allow special clients like desktop shells to power
|
|
||||||
down outputs when the system is idle.
|
|
||||||
|
|
||||||
To modify outputs not currently part of the compositor space see
|
|
||||||
wlr-output-management.
|
|
||||||
|
|
||||||
Warning! The protocol described in this file is experimental and
|
|
||||||
backward incompatible changes may be made. Backward compatible changes
|
|
||||||
may be added together with the corresponding interface version bump.
|
|
||||||
Backward incompatible changes are done by bumping the version number in
|
|
||||||
the protocol and interface names and resetting the interface version.
|
|
||||||
Once the protocol is to be declared stable, the 'z' prefix and the
|
|
||||||
version number in the protocol and interface names are removed and the
|
|
||||||
interface version number is reset.
|
|
||||||
</description>
|
|
||||||
|
|
||||||
<interface name="zwlr_output_power_manager_v1" version="1">
|
|
||||||
<description summary="manager to create per-output power management">
|
|
||||||
This interface is a manager that allows creating per-output power
|
|
||||||
management mode controls.
|
|
||||||
</description>
|
|
||||||
|
|
||||||
<request name="get_output_power">
|
|
||||||
<description summary="get a power management for an output">
|
|
||||||
Create a output power management mode control that can be used to
|
|
||||||
adjust the power management mode for a given output.
|
|
||||||
</description>
|
|
||||||
<arg name="id" type="new_id" interface="zwlr_output_power_v1"/>
|
|
||||||
<arg name="output" type="object" interface="wl_output"/>
|
|
||||||
</request>
|
|
||||||
|
|
||||||
<request name="destroy" type="destructor">
|
|
||||||
<description summary="destroy the manager">
|
|
||||||
All objects created by the manager will still remain valid, until their
|
|
||||||
appropriate destroy request has been called.
|
|
||||||
</description>
|
|
||||||
</request>
|
|
||||||
</interface>
|
|
||||||
|
|
||||||
<interface name="zwlr_output_power_v1" version="1">
|
|
||||||
<description summary="adjust power management mode for an output">
|
|
||||||
This object offers requests to set the power management mode of
|
|
||||||
an output.
|
|
||||||
</description>
|
|
||||||
|
|
||||||
<enum name="mode">
|
|
||||||
<entry name="off" value="0"
|
|
||||||
summary="Output is turned off."/>
|
|
||||||
<entry name="on" value="1"
|
|
||||||
summary="Output is turned on, no power saving"/>
|
|
||||||
</enum>
|
|
||||||
|
|
||||||
<enum name="error">
|
|
||||||
<entry name="invalid_mode" value="1" summary="inexistent power save mode"/>
|
|
||||||
</enum>
|
|
||||||
|
|
||||||
<request name="set_mode">
|
|
||||||
<description summary="Set an outputs power save mode">
|
|
||||||
Set an output's power save mode to the given mode. The mode change
|
|
||||||
is effective immediately. If the output does not support the given
|
|
||||||
mode a failed event is sent.
|
|
||||||
</description>
|
|
||||||
<arg name="mode" type="uint" enum="mode" summary="the power save mode to set"/>
|
|
||||||
</request>
|
|
||||||
|
|
||||||
<event name="mode">
|
|
||||||
<description summary="Report a power management mode change">
|
|
||||||
Report the power management mode change of an output.
|
|
||||||
|
|
||||||
The mode event is sent after an output changed its power
|
|
||||||
management mode. The reason can be a client using set_mode or the
|
|
||||||
compositor deciding to change an output's mode.
|
|
||||||
This event is also sent immediately when the object is created
|
|
||||||
so the client is informed about the current power management mode.
|
|
||||||
</description>
|
|
||||||
<arg name="mode" type="uint" enum="mode"
|
|
||||||
summary="the output's new power management mode"/>
|
|
||||||
</event>
|
|
||||||
|
|
||||||
<event name="failed">
|
|
||||||
<description summary="object no longer valid">
|
|
||||||
This event indicates that the output power management mode control
|
|
||||||
is no longer valid. This can happen for a number of reasons,
|
|
||||||
including:
|
|
||||||
- The output doesn't support power management
|
|
||||||
- Another client already has exclusive power management mode control
|
|
||||||
for this output
|
|
||||||
- The output disappeared
|
|
||||||
|
|
||||||
Upon receiving this event, the client should destroy this object.
|
|
||||||
</description>
|
|
||||||
</event>
|
|
||||||
|
|
||||||
<request name="destroy" type="destructor">
|
|
||||||
<description summary="destroy this power management">
|
|
||||||
Destroys the output power management mode control object.
|
|
||||||
</description>
|
|
||||||
</request>
|
|
||||||
</interface>
|
|
||||||
</protocol>
|
|
63
push.c
Normal file
63
push.c
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
static Client *
|
||||||
|
nexttiled(Client *sel) {
|
||||||
|
Client *c;
|
||||||
|
wl_list_for_each(c, &sel->link, link) {
|
||||||
|
if (&c->link == &clients)
|
||||||
|
break; /* don't wrap */
|
||||||
|
if (!c->isfloating && VISIBLEON(c, selmon))
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Client *
|
||||||
|
prevtiled(Client *sel) {
|
||||||
|
Client *c;
|
||||||
|
wl_list_for_each_reverse(c, &sel->link, link) {
|
||||||
|
if (&c->link == &clients)
|
||||||
|
break; /* don't wrap */
|
||||||
|
if (!c->isfloating && VISIBLEON(c, selmon))
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pushup(const Arg *arg) {
|
||||||
|
Client *sel = focustop(selmon);
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
if(!sel || sel->isfloating)
|
||||||
|
return;
|
||||||
|
if((c = prevtiled(sel))) {
|
||||||
|
/* attach before c */
|
||||||
|
wl_list_remove(&sel->link);
|
||||||
|
wl_list_insert(c->link.prev, &sel->link);
|
||||||
|
} else {
|
||||||
|
/* move to the end */
|
||||||
|
wl_list_remove(&sel->link);
|
||||||
|
wl_list_insert(clients.prev, &sel->link);
|
||||||
|
}
|
||||||
|
focusclient(sel, 1);
|
||||||
|
arrange(selmon);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pushdown(const Arg *arg) {
|
||||||
|
Client *sel = focustop(selmon);
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
if(!sel || sel->isfloating)
|
||||||
|
return;
|
||||||
|
if((c = nexttiled(sel))) {
|
||||||
|
/* attach after c */
|
||||||
|
wl_list_remove(&sel->link);
|
||||||
|
wl_list_insert(&c->link, &sel->link);
|
||||||
|
} else {
|
||||||
|
/* move to the front */
|
||||||
|
wl_list_remove(&sel->link);
|
||||||
|
wl_list_insert(&clients, &sel->link);
|
||||||
|
}
|
||||||
|
focusclient(sel, 1);
|
||||||
|
arrange(selmon);
|
||||||
|
}
|
4
push.h
Normal file
4
push.h
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
static Client *nexttiled(Client *sel);
|
||||||
|
static Client *prevtiled(Client *sel);
|
||||||
|
static void pushdown(const Arg *arg);
|
||||||
|
static void pushup(const Arg *arg);
|
|
@ -1,2 +0,0 @@
|
||||||
nix-shell -p bear --command fish
|
|
||||||
nix develop nixpkgs#dwl --command fish
|
|
16
util.c
16
util.c
|
@ -3,7 +3,6 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
@ -34,18 +33,3 @@ ecalloc(size_t nmemb, size_t size)
|
||||||
die("calloc:");
|
die("calloc:");
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
fd_set_nonblock(int fd) {
|
|
||||||
int flags = fcntl(fd, F_GETFL);
|
|
||||||
if (flags < 0) {
|
|
||||||
perror("fcntl(F_GETFL):");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
|
|
||||||
perror("fcntl(F_SETFL):");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
1
util.h
1
util.h
|
@ -2,4 +2,3 @@
|
||||||
|
|
||||||
void die(const char *fmt, ...);
|
void die(const char *fmt, ...);
|
||||||
void *ecalloc(size_t nmemb, size_t size);
|
void *ecalloc(size_t nmemb, size_t size);
|
||||||
int fd_set_nonblock(int fd);
|
|
||||||
|
|
Loading…
Reference in a new issue