Merge branch 'main' of /home/mahesh/git/furnish/dwl_20240217
This commit is contained in:
		
							
								
								
									
										62
									
								
								.gitea/issue_template/bug_report.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								.gitea/issue_template/bug_report.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | ||||
| 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 | ||||
							
								
								
									
										9
									
								
								.gitea/issue_template/enhancement-idea.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								.gitea/issue_template/enhancement-idea.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| name: Enhancement idea | ||||
| about: Suggest a feature or improvement | ||||
| title: | ||||
| labels: | ||||
|     - 'Kind/Feature' | ||||
| body: | ||||
|     - type: textarea | ||||
|       attributes: | ||||
|           label: Description | ||||
							
								
								
									
										22
									
								
								.github/ISSUE_TEMPLATE/bug_report.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										22
									
								
								.github/ISSUE_TEMPLATE/bug_report.md
									
									
									
									
										vendored
									
									
								
							| @@ -1,22 +0,0 @@ | ||||
| --- | ||||
| name: Bug report | ||||
| about: Something in dwl isn't working correctly | ||||
| title: '' | ||||
| labels: 'A: bug' | ||||
| assignees: '' | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## Info | ||||
| dwl's commit: | ||||
| wlroots version: | ||||
| ## Description | ||||
| <!-- | ||||
| Only report bugs that can be reproduced on the main line | ||||
| Report patch issues to their respective authors | ||||
| If the patch author doesn't respond within a reasonable time, email me: | ||||
|  | ||||
| Leonardo Hernández Hernández <leohdz172@protonmail.com> | ||||
|  | ||||
| but note that I'm NOT making any promises | ||||
| --> | ||||
							
								
								
									
										10
									
								
								.github/ISSUE_TEMPLATE/enhancement-idea.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								.github/ISSUE_TEMPLATE/enhancement-idea.md
									
									
									
									
										vendored
									
									
								
							| @@ -1,10 +0,0 @@ | ||||
| --- | ||||
| name: Enhancement idea | ||||
| about: Suggest a feature or improvement | ||||
| title: '' | ||||
| labels: 'A: enhancement' | ||||
| assignees: '' | ||||
|  | ||||
| --- | ||||
|  | ||||
|  | ||||
							
								
								
									
										110
									
								
								CHANGELOG.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								CHANGELOG.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,110 @@ | ||||
| # Changelog | ||||
|  | ||||
| * [Unreleased](#unreleased) | ||||
| * [0.5](#0.5) | ||||
|  | ||||
|  | ||||
| ## Unreleased | ||||
| ### Added | ||||
| ### Changed | ||||
| ### Deprecated | ||||
| ### Removed | ||||
| ### Fixed | ||||
| ### Security | ||||
| ### Contributors | ||||
|  | ||||
|  | ||||
| ## 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 | ||||
							
								
								
									
										34
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								Makefile
									
									
									
									
									
								
							| @@ -5,8 +5,8 @@ include config.mk | ||||
|  | ||||
| # flags for compiling | ||||
| DWLCPPFLAGS = -I. -DWLR_USE_UNSTABLE -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XWAYLAND) | ||||
| DWLDEVCFLAGS = -pedantic -Wall -Wextra -Wdeclaration-after-statement -Wno-unused-parameter -Wno-sign-compare -Wshadow -Wunused-macros\ | ||||
| 	-Werror=strict-prototypes -Werror=implicit -Werror=return-type -Werror=incompatible-pointer-types | ||||
| DWLDEVCFLAGS = -g -pedantic -Wall -Wextra -Wdeclaration-after-statement -Wno-unused-parameter -Wshadow -Wunused-macros\ | ||||
| 	-Werror=strict-prototypes -Werror=implicit -Werror=return-type -Werror=incompatible-pointer-types -Wfloat-conversion | ||||
|  | ||||
| # CFLAGS / LDFLAGS | ||||
| PKGS      = wlroots wayland-server xkbcommon libinput $(XLIBS) | ||||
| @@ -14,10 +14,11 @@ DWLCFLAGS = `$(PKG_CONFIG) --cflags $(PKGS)` $(DWLCPPFLAGS) $(DWLDEVCFLAGS) $(CF | ||||
| LDLIBS    = `$(PKG_CONFIG) --libs $(PKGS)` $(LIBS) | ||||
|  | ||||
| all: dwl | ||||
| dwl: dwl.o util.o net-tapesoftware-dwl-wm-unstable-v1-protocol.o | ||||
| 	$(CC) dwl.o util.o net-tapesoftware-dwl-wm-unstable-v1-protocol.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 net-tapesoftware-dwl-wm-unstable-v1-protocol.h | ||||
| dwl: dwl.o util.o dwl-ipc-unstable-v2-protocol.o | ||||
| 	$(CC) dwl.o util.o dwl-ipc-unstable-v2-protocol.o $(LDLIBS) $(LDFLAGS) $(DWLCFLAGS) -o $@ | ||||
| dwl.o: dwl.c config.mk config.h client.h cursor-shape-v1-protocol.h xdg-shell-protocol.h wlr-layer-shell-unstable-v1-protocol.h dwl-ipc-unstable-v2-protocol.h | ||||
| util.o: util.c util.h | ||||
| dwl-ipc-unstable-v2-protocol.o: dwl-ipc-unstable-v2-protocol.h | ||||
|  | ||||
| # 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 | ||||
| @@ -31,15 +32,15 @@ xdg-shell-protocol.h: | ||||
| wlr-layer-shell-unstable-v1-protocol.h: | ||||
| 	$(WAYLAND_SCANNER) server-header \ | ||||
| 		protocols/wlr-layer-shell-unstable-v1.xml $@ | ||||
|  | ||||
| # install rules | ||||
| net-tapesoftware-dwl-wm-unstable-v1-protocol.h: protocols/net-tapesoftware-dwl-wm-unstable-v1.xml | ||||
| cursor-shape-v1-protocol.h: | ||||
| 	$(WAYLAND_SCANNER) server-header \ | ||||
| 		protocols/net-tapesoftware-dwl-wm-unstable-v1.xml $@ | ||||
| net-tapesoftware-dwl-wm-unstable-v1-protocol.c: protocols/net-tapesoftware-dwl-wm-unstable-v1.xml | ||||
| 		$(WAYLAND_PROTOCOLS)/staging/cursor-shape/cursor-shape-v1.xml $@ | ||||
| dwl-ipc-unstable-v2-protocol.h: | ||||
| 	$(WAYLAND_SCANNER) server-header \ | ||||
| 		protocols/dwl-ipc-unstable-v2.xml $@ | ||||
| dwl-ipc-unstable-v2-protocol.c: | ||||
| 	$(WAYLAND_SCANNER) private-code \ | ||||
| 		protocols/net-tapesoftware-dwl-wm-unstable-v1.xml $@ | ||||
| net-tapesoftware-dwl-wm-unstable-v1-protocol.o: net-tapesoftware-dwl-wm-unstable-v1-protocol.h | ||||
| 		protocols/dwl-ipc-unstable-v2.xml $@ | ||||
|  | ||||
| config.h: | ||||
| 	cp config.def.h $@ | ||||
| @@ -48,8 +49,8 @@ clean: | ||||
|  | ||||
| dist: clean | ||||
| 	mkdir -p dwl-$(VERSION) | ||||
| 	cp -R LICENSE* Makefile README.md client.h config.def.h\ | ||||
| 		config.mk protocols dwl.1 dwl.c util.c util.h\ | ||||
| 	cp -R LICENSE* Makefile CHANGELOG.md README.md client.h config.def.h\ | ||||
| 		config.mk protocols dwl.1 dwl.c util.c util.h dwl.desktop\ | ||||
| 		dwl-$(VERSION) | ||||
| 	tar -caf dwl-$(VERSION).tar.gz dwl-$(VERSION) | ||||
| 	rm -rf dwl-$(VERSION) | ||||
| @@ -61,8 +62,11 @@ install: dwl | ||||
| 	mkdir -p $(DESTDIR)$(MANDIR)/man1 | ||||
| 	cp -f dwl.1 $(DESTDIR)$(MANDIR)/man1 | ||||
| 	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: | ||||
| 	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 | ||||
| .c.o: | ||||
|   | ||||
							
								
								
									
										56
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										56
									
								
								README.md
									
									
									
									
									
								
							| @@ -1,15 +1,15 @@ | ||||
| # dwl - dwm for Wayland | ||||
|  | ||||
| Join us on our [Discord server] or at [#dwl] on irc.libera.chat. | ||||
| Join us on our IRC channel: [#dwl on Libera Chat]   | ||||
| Or on our [Discord server]. | ||||
|  | ||||
| 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, | ||||
| primarily in terms of philosophy, and secondarily in terms of functionality. | ||||
| primarily in terms of functionality, and secondarily in terms of philosophy. | ||||
| Like dwm, dwl is: | ||||
|  | ||||
| - Easy to understand, hack on, and extend with patches | ||||
| - 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 | ||||
|  | ||||
| dwl is not meant to provide every feature under the sun. Instead, like dwm, it | ||||
| @@ -26,19 +26,25 @@ given the base on which it is built. Implemented default features are: | ||||
|   monitoring | ||||
| - Provide information to external status bars via stdout/stdin | ||||
| - Urgency hints via xdg-activate protocol | ||||
| - Support screen lockers via input-inhibitor 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://github.com/djpohly/dwl/pull/235) | ||||
|   https://codeberg.org/dwl/dwl/pulls/235) | ||||
|  | ||||
| Feature *non-goals* for the main codebase include: | ||||
|  | ||||
| @@ -49,14 +55,28 @@ Feature *non-goals* for the main codebase include: | ||||
|  | ||||
| ## Building dwl | ||||
|  | ||||
| dwl has only two dependencies: `wlroots` and `wayland-protocols`.  | ||||
| dwl has the following dependencies: | ||||
| ``` | ||||
| libinput | ||||
| wayland | ||||
| wlroots (compiled with the libinput backend) | ||||
| xkbcommon | ||||
| wayland-protocols (compile-time only) | ||||
| pkg-config (compile-time only) | ||||
| ``` | ||||
| If you enable X11 support: | ||||
| ``` | ||||
| libxcb | ||||
| libxcb-wm | ||||
| wlroots (compiled with X11 support) | ||||
| Xwayland (runtime only) | ||||
| ``` | ||||
|  | ||||
| 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`. | ||||
| To enable XWayland, you should uncomment its flags in `config.mk`. | ||||
|  | ||||
| ## Configuration | ||||
|  | ||||
| @@ -66,7 +86,7 @@ Wayland without restarting the entire display server, so any changes will take | ||||
| effect the next time dwl is executed. | ||||
|  | ||||
| As in the dwm community, we encourage users to share patches they have created. | ||||
| Check out the [patches page on our wiki]! | ||||
| Check out the dwl [patches repository] and [patches wiki]! | ||||
|  | ||||
| ## Running dwl | ||||
|  | ||||
| @@ -82,6 +102,7 @@ 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 | ||||
| decoration initially; these are instead clients that can be run within | ||||
| the Wayland session. | ||||
| Do note that the background color is black. | ||||
|  | ||||
| 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 | ||||
| @@ -89,7 +110,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 | ||||
| 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 | ||||
| a user service manager like [s6], [anopa], [runit], or [`systemd --user`]. | ||||
| a user service manager like [s6], [anopa], [runit], [dinit], or [`systemd --user`]. | ||||
|  | ||||
| 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 | ||||
| @@ -105,7 +126,7 @@ automatically, you will need to configure it prior to launching `dwl`, e.g.: | ||||
|  | ||||
| ### Status information | ||||
|  | ||||
| Information about selected layouts, current window title, and | ||||
| Information about selected layouts, current window title, app-id, and | ||||
| 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 | ||||
| populate an external status bar with a script that parses the information. | ||||
| @@ -136,6 +157,7 @@ possible. | ||||
| Many thanks to suckless.org and the dwm developers and community for the | ||||
| 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 | ||||
| - Guido Cella for the layer-shell protocol implementation, patch maintenance, | ||||
|   and for helping to keep the project running | ||||
| @@ -143,15 +165,17 @@ inspiration, and to the various contributors to the project, including: | ||||
|  | ||||
|  | ||||
| [Discord server]: https://discord.gg/jJxZnrGPWN | ||||
| [#dwl]: https://web.libera.chat/?channels=#dwl | ||||
| [#dwl on Libera Chat]: https://web.libera.chat/?channels=#dwl | ||||
| [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 | ||||
| [wlroots-next branch]: https://codeberg.org/dwl/dwl/src/branch/wlroots-next | ||||
| [patches repository]: https://codeberg.org/dwl/dwl-patches | ||||
| [patches wiki]: https://codeberg.org/dwl/dwl-patches/wiki | ||||
| [s6]: https://skarnet.org/software/s6/ | ||||
| [anopa]: https://jjacky.com/anopa/ | ||||
| [runit]: http://smarden.org/runit/faq.html#userservices | ||||
| [dinit]: https://davmac.org/projects/dinit/ | ||||
| [`systemd --user`]: https://wiki.archlinux.org/title/Systemd/User | ||||
| [wiki]: https://github.com/djpohly/dwl/wiki#compatible-status-bars | ||||
| [wiki]: https://codeberg.org/dwl/dwl/wiki/Home#compatible-status-bars | ||||
| [list of useful resources on our wiki]: | ||||
|     https://github.com/djpohly/dwl/wiki#migrating-from-x | ||||
|     https://codeberg.org/dwl/dwl/wiki/Home#migrating-from-x | ||||
|   | ||||
							
								
								
									
										345
									
								
								client.h
									
									
									
									
									
								
							
							
						
						
									
										345
									
								
								client.h
									
									
									
									
									
								
							| @@ -10,70 +10,9 @@ static inline int | ||||
| client_is_x11(Client *c) | ||||
| { | ||||
| #ifdef XWAYLAND | ||||
| 	return c->type == X11Managed || c->type == X11Unmanaged; | ||||
| #else | ||||
| 	return c->type == X11; | ||||
| #endif | ||||
| 	return 0; | ||||
| #endif | ||||
| } | ||||
|  | ||||
| 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; | ||||
|  | ||||
| 	if (s && wlr_surface_is_subsurface(s)) | ||||
| 		return client_from_wlr_surface(wlr_surface_get_root_surface(s)); | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| static inline Client * | ||||
| client_get_parent(Client *c) | ||||
| { | ||||
| #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 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 struct wlr_surface * | ||||
| @@ -86,34 +25,100 @@ client_surface(Client *c) | ||||
| 	return c->surface.xdg->surface; | ||||
| } | ||||
|  | ||||
| static inline int | ||||
| toplevel_from_wlr_surface(struct wlr_surface *s, Client **pc, LayerSurface **pl) | ||||
| { | ||||
| 	struct wlr_xdg_surface *xdg_surface, *tmp_xdg_surface; | ||||
| 	struct wlr_surface *root_surface; | ||||
| 	struct wlr_layer_surface_v1 *layer_surface; | ||||
| 	Client *c = NULL; | ||||
| 	LayerSurface *l = NULL; | ||||
| 	int type = -1; | ||||
| #ifdef XWAYLAND | ||||
| 	struct wlr_xwayland_surface *xsurface; | ||||
| #endif | ||||
|  | ||||
| 	if (!s) | ||||
| 		return -1; | ||||
| 	root_surface = wlr_surface_get_root_surface(s); | ||||
|  | ||||
| #ifdef XWAYLAND | ||||
| 	if ((xsurface = wlr_xwayland_surface_try_from_wlr_surface(root_surface))) { | ||||
| 		c = xsurface->data; | ||||
| 		type = c->type; | ||||
| 		goto end; | ||||
| 	} | ||||
| #endif | ||||
|  | ||||
| 	if ((layer_surface = wlr_layer_surface_v1_try_from_wlr_surface(root_surface))) { | ||||
| 		l = layer_surface->data; | ||||
| 		type = LayerShell; | ||||
| 		goto end; | ||||
| 	} | ||||
|  | ||||
| 	xdg_surface = wlr_xdg_surface_try_from_wlr_surface(root_surface); | ||||
| 	while (xdg_surface) { | ||||
| 		tmp_xdg_surface = NULL; | ||||
| 		switch (xdg_surface->role) { | ||||
| 		case WLR_XDG_SURFACE_ROLE_POPUP: | ||||
| 			if (!xdg_surface->popup || !xdg_surface->popup->parent) | ||||
| 				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; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| end: | ||||
| 	if (pl) | ||||
| 		*pl = l; | ||||
| 	if (pc) | ||||
| 		*pc = c; | ||||
| 	return type; | ||||
| } | ||||
|  | ||||
| /* The others */ | ||||
| static inline void | ||||
| client_activate_surface(struct wlr_surface *s, int activated) | ||||
| { | ||||
| 	struct wlr_xdg_surface *surface; | ||||
| 	struct wlr_xdg_toplevel *toplevel; | ||||
| #ifdef XWAYLAND | ||||
| 	struct wlr_xwayland_surface *xsurface; | ||||
| 	if (wlr_surface_is_xwayland_surface(s) | ||||
| 			&& (xsurface = wlr_xwayland_surface_from_wlr_surface(s))) { | ||||
| 	if ((xsurface = wlr_xwayland_surface_try_from_wlr_surface(s))) { | ||||
| 		wlr_xwayland_surface_activate(xsurface, activated); | ||||
| 		return; | ||||
| 	} | ||||
| #endif | ||||
| 	if (wlr_surface_is_xdg_surface(s) | ||||
| 			&& (surface = wlr_xdg_surface_from_wlr_surface(s)) | ||||
| 			&& surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL) | ||||
| 		wlr_xdg_toplevel_set_activated(surface, activated); | ||||
| 	if ((toplevel = wlr_xdg_toplevel_try_from_wlr_surface(s))) | ||||
| 		wlr_xdg_toplevel_set_activated(toplevel, activated); | ||||
| } | ||||
|  | ||||
| static inline void | ||||
| client_for_each_surface(Client *c, wlr_surface_iterator_func_t fn, void *data) | ||||
| static inline uint32_t | ||||
| client_set_bounds(Client *c, int32_t width, int32_t height) | ||||
| { | ||||
| 	wlr_surface_for_each_surface(client_surface(c), fn, data); | ||||
| #ifdef XWAYLAND | ||||
| 	if (client_is_x11(c)) | ||||
| 		return; | ||||
| 		return 0; | ||||
| #endif | ||||
| 	wlr_xdg_surface_for_each_popup_surface(c->surface.xdg, fn, data); | ||||
| 	if (wl_resource_get_version(c->surface.xdg->toplevel->resource) >= | ||||
| 			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 0; | ||||
| } | ||||
|  | ||||
| static inline const char * | ||||
| @@ -126,6 +131,27 @@ client_get_appid(Client *c) | ||||
| 	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 | ||||
| client_get_geometry(Client *c, struct wlr_box *geom) | ||||
| { | ||||
| @@ -141,6 +167,34 @@ client_get_geometry(Client *c, struct wlr_box *geom) | ||||
| 	wlr_xdg_surface_get_geometry(c->surface.xdg, geom); | ||||
| } | ||||
|  | ||||
| static inline Client * | ||||
| client_get_parent(Client *c) | ||||
| { | ||||
| 	Client *p = NULL; | ||||
| #ifdef XWAYLAND | ||||
|     if (client_is_x11(c)) { | ||||
|         if (c->surface.xwayland->parent) | ||||
|             toplevel_from_wlr_surface(c->surface.xwayland->parent->surface, &p, NULL); | ||||
|         return p; | ||||
|     } | ||||
| #endif | ||||
| 	if (c->surface.xdg->toplevel->parent) | ||||
| 		toplevel_from_wlr_surface(c->surface.xdg->toplevel->parent->base->surface, &p, NULL); | ||||
| 	return p; | ||||
| } | ||||
|  | ||||
| static inline int | ||||
| 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 * | ||||
| client_get_title(Client *c) | ||||
| { | ||||
| @@ -151,47 +205,88 @@ client_get_title(Client *c) | ||||
| 	return c->surface.xdg->toplevel->title; | ||||
| } | ||||
|  | ||||
|  | ||||
| static inline int | ||||
| client_is_float_type(Client *c) | ||||
| { | ||||
| 	struct wlr_box min = {0}, max = {0}; | ||||
| 	client_get_size_hints(c, &max, &min); | ||||
| 	struct wlr_xdg_toplevel *toplevel; | ||||
| 	struct wlr_xdg_toplevel_state state; | ||||
|  | ||||
| #ifdef XWAYLAND | ||||
| 	if (client_is_x11(c)) { | ||||
| 		struct wlr_xwayland_surface *surface = c->surface.xwayland; | ||||
| 		xcb_size_hints_t *size_hints = surface->size_hints; | ||||
| 		size_t i; | ||||
| 		if (surface->modal) | ||||
| 			return 1; | ||||
|  | ||||
| 		for (size_t i = 0; i < surface->window_type_len; i++) | ||||
| 		for (i = 0; i < surface->window_type_len; i++) | ||||
| 			if (surface->window_type[i] == netatom[NetWMWindowTypeDialog] | ||||
| 					|| surface->window_type[i] == netatom[NetWMWindowTypeSplash] | ||||
| 					|| surface->window_type[i] == netatom[NetWMWindowTypeToolbar] | ||||
| 					|| surface->window_type[i] == netatom[NetWMWindowTypeUtility]) | ||||
| 				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 | ||||
| 	return ((min.width > 0 || min.height > 0 || max.width > 0 || max.height > 0) | ||||
| 		&& (min.width == max.width || min.height == max.height)) | ||||
| 		|| client_get_parent(c); | ||||
|  | ||||
| 	toplevel = c->surface.xdg->toplevel; | ||||
| 	state = toplevel->current; | ||||
| 	return toplevel->parent || (state.min_width != 0 && state.min_height != 0 | ||||
| 		&& (state.min_width == state.max_width | ||||
| 			|| state.min_height == state.max_height)); | ||||
| } | ||||
|  | ||||
| static inline int | ||||
| client_is_mapped(Client *c) | ||||
| client_is_rendered_on_mon(Client *c, Monitor *m) | ||||
| { | ||||
| 	/* This is needed for when you don't want to check formal assignment, | ||||
| 	 * but rather actual displaying of the pixels. | ||||
| 	 * Usually VISIBLEON suffices and is also faster. */ | ||||
| 	struct wlr_surface_output *s; | ||||
| 	int unused_lx, unused_ly; | ||||
| 	if (!wlr_scene_node_coords(&c->scene->node, &unused_lx, &unused_ly)) | ||||
| 		return 0; | ||||
| 	wl_list_for_each(s, &client_surface(c)->current_outputs, link) | ||||
| 		if (s->output == m->wlr_output) | ||||
| 			return 1; | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static inline int | ||||
| client_is_stopped(Client *c) | ||||
| { | ||||
| 	int pid; | ||||
| 	siginfo_t in = {0}; | ||||
| #ifdef XWAYLAND | ||||
| 	if (client_is_x11(c)) | ||||
| 		return c->surface.xwayland->mapped; | ||||
| 		return 0; | ||||
| #endif | ||||
| 	return c->surface.xdg->mapped; | ||||
|  | ||||
| 	wl_client_get_credentials(c->surface.xdg->client->client, &pid, NULL, NULL); | ||||
| 	if (waitid(P_PID, pid, &in, WNOHANG|WCONTINUED|WSTOPPED|WNOWAIT) < 0) { | ||||
| 		/* This process is not our child process, while is very unluckely that | ||||
| 		 * it is stopped, in order to do not skip frames assume that it is. */ | ||||
| 		if (errno == ECHILD) | ||||
| 			return 1; | ||||
| 	} else if (in.si_pid) { | ||||
| 		if (in.si_code == CLD_STOPPED || in.si_code == CLD_TRAPPED) | ||||
| 			return 1; | ||||
| 		if (in.si_code == CLD_CONTINUED) | ||||
| 			return 0; | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static inline int | ||||
| client_is_unmanaged(Client *c) | ||||
| { | ||||
| #ifdef XWAYLAND | ||||
| 	return c->type == X11Unmanaged; | ||||
| 	if (client_is_x11(c)) | ||||
| 		return c->surface.xwayland->override_redirect; | ||||
| #endif | ||||
| 	return 0; | ||||
| } | ||||
| @@ -226,7 +321,15 @@ client_send_close(Client *c) | ||||
| 		return; | ||||
| 	} | ||||
| #endif | ||||
| 	wlr_xdg_toplevel_send_close(c->surface.xdg); | ||||
| 	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 | ||||
| @@ -238,7 +341,7 @@ client_set_fullscreen(Client *c, int fullscreen) | ||||
| 		return; | ||||
| 	} | ||||
| #endif | ||||
| 	wlr_xdg_toplevel_set_fullscreen(c->surface.xdg, fullscreen); | ||||
| 	wlr_xdg_toplevel_set_fullscreen(c->surface.xdg->toplevel, fullscreen); | ||||
| } | ||||
|  | ||||
| static inline uint32_t | ||||
| @@ -251,7 +354,10 @@ client_set_size(Client *c, uint32_t width, uint32_t height) | ||||
| 		return 0; | ||||
| 	} | ||||
| #endif | ||||
| 	return wlr_xdg_toplevel_set_size(c->surface.xdg, width, height); | ||||
| 	if ((int32_t)width == c->surface.xdg->toplevel->current.width | ||||
| 			&& (int32_t)height == c->surface.xdg->toplevel->current.height) | ||||
| 		return 0; | ||||
| 	return wlr_xdg_toplevel_set_size(c->surface.xdg->toplevel, (int32_t)width, (int32_t)height); | ||||
| } | ||||
|  | ||||
| static inline void | ||||
| @@ -261,18 +367,25 @@ client_set_tiled(Client *c, uint32_t edges) | ||||
| 	if (client_is_x11(c)) | ||||
| 		return; | ||||
| #endif | ||||
| 	wlr_xdg_toplevel_set_tiled(c->surface.xdg, edges); | ||||
| 	if (wl_resource_get_version(c->surface.xdg->toplevel->resource) | ||||
| 			>= 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 struct wlr_surface * | ||||
| client_surface_at(Client *c, double cx, double cy, double *sx, double *sy) | ||||
| static inline void | ||||
| client_set_suspended(Client *c, int suspended) | ||||
| { | ||||
| #ifdef XWAYLAND | ||||
| 	if (client_is_x11(c)) | ||||
| 		return wlr_surface_surface_at(c->surface.xwayland->surface, | ||||
| 				cx, cy, sx, sy); | ||||
| 	if (client_is_x11(c)) { | ||||
| 		wlr_xwayland_surface_set_withdrawn(c->surface.xwayland, suspended); | ||||
| 		return; | ||||
| 	} | ||||
| #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 | ||||
| @@ -295,43 +408,3 @@ client_wants_fullscreen(Client *c) | ||||
| #endif | ||||
| 	return c->surface.xdg->toplevel->requested.fullscreen; | ||||
| } | ||||
|  | ||||
| static inline void * | ||||
| toplevel_from_popup(struct wlr_xdg_popup *popup) | ||||
| { | ||||
| 	struct wlr_xdg_surface *surface = popup->base; | ||||
|  | ||||
| 	while (1) { | ||||
| 		switch (surface->role) { | ||||
| 		case WLR_XDG_SURFACE_ROLE_POPUP: | ||||
| 			if (!surface->popup->parent) | ||||
| 				return NULL; | ||||
| 			else 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; | ||||
|  | ||||
| 			surface = wlr_xdg_surface_from_wlr_surface(surface->popup->parent); | ||||
| 			break; | ||||
| 		case WLR_XDG_SURFACE_ROLE_TOPLEVEL: | ||||
| 				return surface->data; | ||||
| 		case WLR_XDG_SURFACE_ROLE_NONE: | ||||
| 			return NULL; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static inline void * | ||||
| toplevel_from_wlr_layer_surface(struct wlr_surface *s) | ||||
| { | ||||
| 	Client *c; | ||||
| 	struct wlr_layer_surface_v1 *wlr_layer_surface; | ||||
|  | ||||
| 	if ((c = client_from_wlr_surface(s))) | ||||
| 		return c; | ||||
| 	else if (s && wlr_surface_is_layer_surface(s) | ||||
| 			&& (wlr_layer_surface = wlr_layer_surface_v1_from_wlr_surface(s))) | ||||
| 		return wlr_layer_surface->data; | ||||
|  | ||||
| 	return NULL; | ||||
| } | ||||
|   | ||||
							
								
								
									
										52
									
								
								config.def.h
									
									
									
									
									
								
							
							
						
						
									
										52
									
								
								config.def.h
									
									
									
									
									
								
							| @@ -1,15 +1,24 @@ | ||||
| /* 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 */ | ||||
| static const int sloppyfocus        = 1;  /* focus follows mouse */ | ||||
| static const unsigned int borderpx  = 1;  /* border pixel of windows */ | ||||
| static const int lockfullscreen     = 1;  /* 1 will force focus on the fullscreen window */ | ||||
| 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 focuscolor[]     = {1.0, 0.0, 0.0, 1.0}; | ||||
| 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 unsigned int borderpx         = 1;  /* border pixel of windows */ | ||||
| static const float rootcolor[]             = COLOR(0x222222ff); | ||||
| static const float bordercolor[]           = COLOR(0x444444ff); | ||||
| static const float focuscolor[]            = COLOR(0x005577ff); | ||||
| static const float urgentcolor[]           = COLOR(0xff0000ff); | ||||
| /* 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}; | ||||
| static const float fullscreen_bg[]         = {0.1f, 0.1f, 0.1f, 1.0f}; /* You can also use glsl colors */ | ||||
|  | ||||
| /* tagging */ | ||||
| static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; | ||||
| /* tagging - TAGCOUNT must be no greater than 31 */ | ||||
| #define TAGCOUNT (9) | ||||
|  | ||||
| /* logging */ | ||||
| static int log_level = WLR_ERROR; | ||||
|  | ||||
| static const Rule rules[] = { | ||||
| 	/* app_id     title       tags mask     isfloating   monitor */ | ||||
| @@ -28,13 +37,14 @@ static const Layout layouts[] = { | ||||
| }; | ||||
|  | ||||
| /* monitors */ | ||||
| /* NOTE: ALWAYS add a fallback rule, even if you are completely sure it won't be used */ | ||||
| static const MonitorRule monrules[] = { | ||||
| 	/* name       mfact nmaster scale layout       rotate/reflect */ | ||||
| 	/* name       mfact  nmaster scale layout       rotate/reflect                x    y */ | ||||
| 	/* example of a HiDPI laptop monitor: | ||||
| 	{ "eDP-1",    0.5,  1,      2,    &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL }, | ||||
| 	{ "eDP-1",    0.5f,  1,      2,    &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL,   -1,  -1 }, | ||||
| 	*/ | ||||
| 	/* defaults */ | ||||
| 	{ NULL,       0.55, 1,      1,    &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL }, | ||||
| 	{ NULL,       0.55f, 1,      1,    &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL,   -1,  -1 }, | ||||
| }; | ||||
|  | ||||
| /* keyboard */ | ||||
| @@ -66,9 +76,9 @@ 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  | ||||
| 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; | ||||
|  | ||||
| @@ -85,6 +95,11 @@ 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; | ||||
| /* You can choose between: | ||||
| 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 | ||||
| */ | ||||
| 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 */ | ||||
| #define MODKEY WLR_MODIFIER_ALT | ||||
| @@ -111,8 +126,8 @@ static const Key keys[] = { | ||||
| 	{ MODKEY,                    XKB_KEY_k,          focusstack,     {.i = -1} }, | ||||
| 	{ MODKEY,                    XKB_KEY_i,          incnmaster,     {.i = +1} }, | ||||
| 	{ MODKEY,                    XKB_KEY_d,          incnmaster,     {.i = -1} }, | ||||
| 	{ MODKEY,                    XKB_KEY_h,          setmfact,       {.f = -0.05} }, | ||||
| 	{ MODKEY,                    XKB_KEY_l,          setmfact,       {.f = +0.05} }, | ||||
| 	{ MODKEY,                    XKB_KEY_h,          setmfact,       {.f = -0.05f} }, | ||||
| 	{ MODKEY,                    XKB_KEY_l,          setmfact,       {.f = +0.05f} }, | ||||
| 	{ MODKEY,                    XKB_KEY_Return,     zoom,           {0} }, | ||||
| 	{ MODKEY,                    XKB_KEY_Tab,        view,           {0} }, | ||||
| 	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_C,          killclient,     {0} }, | ||||
| @@ -141,6 +156,9 @@ static const Key keys[] = { | ||||
|  | ||||
| 	/* 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} }, | ||||
| 	/* 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)} } | ||||
| 	CHVT(1), CHVT(2), CHVT(3), CHVT(4), CHVT(5), CHVT(6), | ||||
| 	CHVT(7), CHVT(8), CHVT(9), CHVT(10), CHVT(11), CHVT(12), | ||||
|   | ||||
| @@ -1,14 +1,15 @@ | ||||
| _VERSION = 0.3.1-dev | ||||
| VERSION  = `git describe --long --tags --dirty 2>/dev/null || echo $(_VERSION)` | ||||
| _VERSION = 0.5 | ||||
| VERSION  = `git describe --tags --dirty 2>/dev/null || echo $(_VERSION)` | ||||
|  | ||||
| PKG_CONFIG = pkg-config | ||||
|  | ||||
| # paths | ||||
| PREFIX = /usr/local | ||||
| MANDIR = $(PREFIX)/share/man | ||||
| DATADIR = $(PREFIX)/share | ||||
|  | ||||
| XWAYLAND = | ||||
| XLIBS = | ||||
| # Uncomment to build XWayland support | ||||
| #XWAYLAND = -DXWAYLAND | ||||
| #XLIBS = xcb | ||||
| #XLIBS = xcb xcb-icccm | ||||
|   | ||||
							
								
								
									
										13
									
								
								dwl.1
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								dwl.1
									
									
									
									
									
								
							| @@ -7,6 +7,7 @@ | ||||
| .Sh SYNOPSIS | ||||
| .Nm | ||||
| .Op Fl v | ||||
| .Op Fl d | ||||
| .Op Fl s Ar startup command | ||||
| .Sh DESCRIPTION | ||||
| .Nm | ||||
| @@ -22,6 +23,12 @@ option, | ||||
| writes its name and version to standard error and exits unsuccessfully. | ||||
| .Pp | ||||
| When given the | ||||
| .Fl d | ||||
| option, | ||||
| .Nm | ||||
| enables full wlroots logging, including debug information. | ||||
| .Pp | ||||
| When given the | ||||
| .Fl s | ||||
| option, | ||||
| .Nm | ||||
| @@ -51,7 +58,7 @@ Spawn | ||||
| .Nm bemenu-run . | ||||
| .It Mod-Shift-Return | ||||
| Spawn | ||||
| .Nm alacritty . | ||||
| .Nm foot . | ||||
| .It Mod-[jk] | ||||
| Move focus down/up the stack. | ||||
| .It Mod-[id] | ||||
| @@ -101,7 +108,7 @@ These environment variables are used by | ||||
| A directory where temporary user files, such as the Wayland socket, | ||||
| are stored. | ||||
| .It Ev XDG_CONFIG_DIR | ||||
| A directory containung configuration of various programs and | ||||
| A directory containing configuration of various programs and | ||||
| libraries, including libxkbcommon. | ||||
| .It Ev DISPLAY , WAYLAND_DISPLAY , WAYLAND_SOCKET | ||||
| Tell how to connect to an underlying X11 or Wayland server. | ||||
| @@ -135,7 +142,7 @@ Start | ||||
| with s6 in the background: | ||||
| .Dl dwl -s 's6-svscan <&-' | ||||
| .Sh SEE ALSO | ||||
| .Xr alacritty 1 , | ||||
| .Xr foot 1 , | ||||
| .Xr bemenu 1 , | ||||
| .Xr dwm 1 , | ||||
| .Xr xkeyboard-config 7 | ||||
|   | ||||
							
								
								
									
										5
									
								
								dwl.desktop
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								dwl.desktop
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| [Desktop Entry] | ||||
| Name=dwl | ||||
| Comment=dwm for Wayland | ||||
| Exec=dwl | ||||
| Type=Application | ||||
							
								
								
									
										575
									
								
								ipc-v2-fixed.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										575
									
								
								ipc-v2-fixed.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,575 @@ | ||||
| diff --git a/Makefile b/Makefile | ||||
| index 5320e42..c13557c 100644 | ||||
| --- a/Makefile | ||||
| +++ b/Makefile | ||||
| @@ -14,10 +14,11 @@ DWLCFLAGS = `$(PKG_CONFIG) --cflags $(PKGS)` $(DWLCPPFLAGS) $(DWLDEVCFLAGS) $(CF | ||||
|  LDLIBS    = `$(PKG_CONFIG) --libs $(PKGS)` $(LIBS) | ||||
|   | ||||
|  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 | ||||
| +dwl: dwl.o util.o dwl-ipc-unstable-v2-protocol.o | ||||
| +	$(CC) dwl.o util.o dwl-ipc-unstable-v2-protocol.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 dwl-ipc-unstable-v2-protocol.h | ||||
|  util.o: util.c util.h | ||||
| +dwl-ipc-unstable-v2-protocol.o: dwl-ipc-unstable-v2-protocol.h | ||||
|   | ||||
|  # 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 | ||||
| @@ -31,6 +32,12 @@ xdg-shell-protocol.h: | ||||
|  wlr-layer-shell-unstable-v1-protocol.h: | ||||
|  	$(WAYLAND_SCANNER) server-header \ | ||||
|  		protocols/wlr-layer-shell-unstable-v1.xml $@ | ||||
| +dwl-ipc-unstable-v2-protocol.h: | ||||
| +	$(WAYLAND_SCANNER) server-header \ | ||||
| +		protocols/dwl-ipc-unstable-v2.xml $@ | ||||
| +dwl-ipc-unstable-v2-protocol.c: | ||||
| +	$(WAYLAND_SCANNER) private-code \ | ||||
| +		protocols/dwl-ipc-unstable-v2.xml $@ | ||||
|   | ||||
|  config.h: | ||||
|  	cp config.def.h $@ | ||||
| diff --git a/config.def.h b/config.def.h | ||||
| index 4e30885..f285840 100644 | ||||
| --- a/config.def.h | ||||
| +++ b/config.def.h | ||||
| @@ -120,6 +120,7 @@ static const Key keys[] = { | ||||
|  	/* modifier                  key                 function        argument */ | ||||
|  	{ MODKEY,                    XKB_KEY_p,          spawn,          {.v = menucmd} }, | ||||
|  	{ 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_k,          focusstack,     {.i = -1} }, | ||||
|  	{ MODKEY,                    XKB_KEY_i,          incnmaster,     {.i = +1} }, | ||||
| diff --git a/dwl.c b/dwl.c | ||||
| index a7d41b0..e507e31 100644 | ||||
| --- a/dwl.c | ||||
| +++ b/dwl.c | ||||
| @@ -58,6 +58,7 @@ | ||||
|  #include <xcb/xcb_icccm.h> | ||||
|  #endif | ||||
|   | ||||
| +#include "dwl-ipc-unstable-v2-protocol.h" | ||||
|  #include "util.h" | ||||
|   | ||||
|  /* macros */ | ||||
| @@ -128,6 +129,12 @@ typedef struct { | ||||
|  	uint32_t resize; /* configure serial of a pending resize */ | ||||
|  } Client; | ||||
|   | ||||
| +typedef struct { | ||||
| +	struct wl_list link; | ||||
| +	struct wl_resource *resource; | ||||
| +	Monitor *mon; | ||||
| +} DwlIpcOutput; | ||||
| + | ||||
|  typedef struct { | ||||
|  	uint32_t mod; | ||||
|  	xkb_keysym_t keysym; | ||||
| @@ -174,6 +181,7 @@ typedef struct { | ||||
|   | ||||
|  struct Monitor { | ||||
|  	struct wl_list link; | ||||
| +	struct wl_list dwl_ipc_outputs; | ||||
|  	struct wlr_output *wlr_output; | ||||
|  	struct wlr_scene_output *scene_output; | ||||
|  	struct wlr_scene_rect *fullscreen_bg; /* See createmon() for info */ | ||||
| @@ -255,6 +263,17 @@ static void destroynotify(struct wl_listener *listener, void *data); | ||||
|  static void destroysessionlock(struct wl_listener *listener, void *data); | ||||
|  static void destroysessionmgr(struct wl_listener *listener, void *data); | ||||
|  static Monitor *dirtomon(enum wlr_direction dir); | ||||
| +static void dwl_ipc_manager_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id); | ||||
| +static void dwl_ipc_manager_destroy(struct wl_resource *resource); | ||||
| +static void dwl_ipc_manager_get_output(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *output); | ||||
| +static void dwl_ipc_manager_release(struct wl_client *client, struct wl_resource *resource); | ||||
| +static void dwl_ipc_output_destroy(struct wl_resource *resource); | ||||
| +static void dwl_ipc_output_printstatus(Monitor *monitor); | ||||
| +static void dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output); | ||||
| +static void dwl_ipc_output_set_client_tags(struct wl_client *client, struct wl_resource *resource, uint32_t and_tags, uint32_t xor_tags); | ||||
| +static void dwl_ipc_output_set_layout(struct wl_client *client, struct wl_resource *resource, uint32_t index); | ||||
| +static void dwl_ipc_output_set_tags(struct wl_client *client, struct wl_resource *resource, uint32_t tagmask, uint32_t toggle_tagset); | ||||
| +static void dwl_ipc_output_release(struct wl_client *client, struct wl_resource *resource); | ||||
|  static void focusclient(Client *c, int lift); | ||||
|  static void focusmon(const Arg *arg); | ||||
|  static void focusstack(const Arg *arg); | ||||
| @@ -302,6 +321,7 @@ static void startdrag(struct wl_listener *listener, void *data); | ||||
|  static void tag(const Arg *arg); | ||||
|  static void tagmon(const Arg *arg); | ||||
|  static void tile(Monitor *m); | ||||
| +static void togglebar(const Arg *arg); | ||||
|  static void togglefloating(const Arg *arg); | ||||
|  static void togglefullscreen(const Arg *arg); | ||||
|  static void toggletag(const Arg *arg); | ||||
| @@ -374,6 +394,8 @@ static struct wl_listener cursor_frame = {.notify = cursorframe}; | ||||
|  static struct wl_listener cursor_motion = {.notify = motionrelative}; | ||||
|  static struct wl_listener cursor_motion_absolute = {.notify = motionabsolute}; | ||||
|  static struct wl_listener drag_icon_destroy = {.notify = destroydragicon}; | ||||
| +static struct zdwl_ipc_manager_v2_interface dwl_manager_implementation = {.release = dwl_ipc_manager_release, .get_output = dwl_ipc_manager_get_output}; | ||||
| +static struct zdwl_ipc_output_v2_interface dwl_output_implementation = {.release = dwl_ipc_output_release, .set_tags = dwl_ipc_output_set_tags, .set_layout = dwl_ipc_output_set_layout, .set_client_tags = dwl_ipc_output_set_client_tags}; | ||||
|  static struct wl_listener idle_inhibitor_create = {.notify = createidleinhibitor}; | ||||
|  static struct wl_listener idle_inhibitor_destroy = {.notify = destroyidleinhibitor}; | ||||
|  static struct wl_listener layout_change = {.notify = updatemons}; | ||||
| @@ -691,6 +713,9 @@ cleanupmon(struct wl_listener *listener, void *data) | ||||
|  	LayerSurface *l, *tmp; | ||||
|  	int i; | ||||
|   | ||||
| +	DwlIpcOutput *ipc_output, *ipc_output_tmp; | ||||
| +	wl_list_for_each_safe(ipc_output, ipc_output_tmp, &m->dwl_ipc_outputs, link) | ||||
| +		wl_resource_destroy(ipc_output->resource); | ||||
|  	for (i = 0; i <= ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY; i++) | ||||
|  		wl_list_for_each_safe(l, tmp, &m->layers[i], link) | ||||
|  			wlr_layer_surface_v1_destroy(l->layer_surface); | ||||
| @@ -902,6 +927,7 @@ createmon(struct wl_listener *listener, void *data) | ||||
|  	Monitor *m = wlr_output->data = ecalloc(1, sizeof(*m)); | ||||
|  	m->wlr_output = wlr_output; | ||||
|   | ||||
| +	wl_list_init(&m->dwl_ipc_outputs); | ||||
|  	wlr_output_init_render(wlr_output, alloc, drw); | ||||
|   | ||||
|  	/* Initialize monitor state using configured rules */ | ||||
| @@ -1195,6 +1221,190 @@ dirtomon(enum wlr_direction dir) | ||||
|  	return selmon; | ||||
|  } | ||||
|   | ||||
| +void | ||||
| +dwl_ipc_manager_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id) | ||||
| +{ | ||||
| +	struct wl_resource *manager_resource = wl_resource_create(client, &zdwl_ipc_manager_v2_interface, version, id); | ||||
| +	if (!manager_resource) { | ||||
| +		wl_client_post_no_memory(client); | ||||
| +		return; | ||||
| +	} | ||||
| +	wl_resource_set_implementation(manager_resource, &dwl_manager_implementation, NULL, dwl_ipc_manager_destroy); | ||||
| + | ||||
| +	zdwl_ipc_manager_v2_send_tags(manager_resource, TAGCOUNT); | ||||
| + | ||||
| +	for (int i = 0; i < LENGTH(layouts); i++) | ||||
| +		zdwl_ipc_manager_v2_send_layout(manager_resource, layouts[i].symbol); | ||||
| +} | ||||
| + | ||||
| +void | ||||
| +dwl_ipc_manager_destroy(struct wl_resource *resource) | ||||
| +{ | ||||
| +	/* No state to destroy */ | ||||
| +} | ||||
| + | ||||
| +void | ||||
| +dwl_ipc_manager_get_output(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *output) | ||||
| +{ | ||||
| +	DwlIpcOutput *ipc_output; | ||||
| +	Monitor *monitor = wlr_output_from_resource(output)->data; | ||||
| +	struct wl_resource *output_resource = wl_resource_create(client, &zdwl_ipc_output_v2_interface, wl_resource_get_version(resource), id); | ||||
| +	if (!output_resource) | ||||
| +		return; | ||||
| + | ||||
| +	ipc_output = ecalloc(1, sizeof(*ipc_output)); | ||||
| +	ipc_output->resource = output_resource; | ||||
| +	ipc_output->mon = monitor; | ||||
| +	wl_resource_set_implementation(output_resource, &dwl_output_implementation, ipc_output, dwl_ipc_output_destroy); | ||||
| +	wl_list_insert(&monitor->dwl_ipc_outputs, &ipc_output->link); | ||||
| +	dwl_ipc_output_printstatus_to(ipc_output); | ||||
| +} | ||||
| + | ||||
| +void | ||||
| +dwl_ipc_manager_release(struct wl_client *client, struct wl_resource *resource) | ||||
| +{ | ||||
| +	wl_resource_destroy(resource); | ||||
| +} | ||||
| + | ||||
| +static void | ||||
| +dwl_ipc_output_destroy(struct wl_resource *resource) | ||||
| +{ | ||||
| +	DwlIpcOutput *ipc_output = wl_resource_get_user_data(resource); | ||||
| +	wl_list_remove(&ipc_output->link); | ||||
| +	free(ipc_output); | ||||
| +} | ||||
| + | ||||
| +void | ||||
| +dwl_ipc_output_printstatus(Monitor *monitor) | ||||
| +{ | ||||
| +	DwlIpcOutput *ipc_output; | ||||
| +	wl_list_for_each(ipc_output, &monitor->dwl_ipc_outputs, link) | ||||
| +		dwl_ipc_output_printstatus_to(ipc_output); | ||||
| +} | ||||
| + | ||||
| +void | ||||
| +dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output) | ||||
| +{ | ||||
| +	Monitor *monitor = ipc_output->mon; | ||||
| +	Client *c, *focused; | ||||
| +	int tagmask, state, numclients, focused_client, tag; | ||||
| +	const char *title, *appid; | ||||
| +	focused = focustop(monitor); | ||||
| +	zdwl_ipc_output_v2_send_active(ipc_output->resource, monitor == selmon); | ||||
| + | ||||
| +	for (tag = 0 ; tag < TAGCOUNT; tag++) { | ||||
| +		numclients = state = focused_client = 0; | ||||
| +		tagmask = 1 << tag; | ||||
| +		if ((tagmask & monitor->tagset[monitor->seltags]) != 0) | ||||
| +			state |= ZDWL_IPC_OUTPUT_V2_TAG_STATE_ACTIVE; | ||||
| + | ||||
| +		wl_list_for_each(c, &clients, link) { | ||||
| +			if (c->mon != monitor) | ||||
| +				continue; | ||||
| +			if (!(c->tags & tagmask)) | ||||
| +				continue; | ||||
| +			if (c == focused) | ||||
| +				focused_client = 1; | ||||
| +			if (c->isurgent) | ||||
| +				state |= ZDWL_IPC_OUTPUT_V2_TAG_STATE_URGENT; | ||||
| + | ||||
| +			numclients++; | ||||
| +		} | ||||
| +		zdwl_ipc_output_v2_send_tag(ipc_output->resource, tag, state, numclients, focused_client); | ||||
| +	} | ||||
| +	title = focused ? client_get_title(focused) : ""; | ||||
| +	appid = focused ? client_get_appid(focused) : ""; | ||||
| + | ||||
| +	zdwl_ipc_output_v2_send_layout(ipc_output->resource, monitor->lt[monitor->sellt] - layouts); | ||||
| +	zdwl_ipc_output_v2_send_title(ipc_output->resource, title ? title : broken); | ||||
| +	zdwl_ipc_output_v2_send_appid(ipc_output->resource, appid ? appid : broken); | ||||
| +	zdwl_ipc_output_v2_send_layout_symbol(ipc_output->resource, monitor->ltsymbol); | ||||
| +	if (wl_resource_get_version(ipc_output->resource) >= ZDWL_IPC_OUTPUT_V2_FULLSCREEN_SINCE_VERSION) { | ||||
| +		zdwl_ipc_output_v2_send_fullscreen(ipc_output->resource, focused ? focused->isfullscreen : 0); | ||||
| +	} | ||||
| +	if (wl_resource_get_version(ipc_output->resource) >= ZDWL_IPC_OUTPUT_V2_FLOATING_SINCE_VERSION) { | ||||
| +		zdwl_ipc_output_v2_send_floating(ipc_output->resource, focused ? focused->isfloating : 0); | ||||
| +	} | ||||
| +	zdwl_ipc_output_v2_send_frame(ipc_output->resource); | ||||
| +} | ||||
| + | ||||
| +void | ||||
| +dwl_ipc_output_set_client_tags(struct wl_client *client, struct wl_resource *resource, uint32_t and_tags, uint32_t xor_tags) | ||||
| +{ | ||||
| +	DwlIpcOutput *ipc_output; | ||||
| +	Monitor *monitor; | ||||
| +	Client *selected_client; | ||||
| +	unsigned int newtags = 0; | ||||
| + | ||||
| +	ipc_output = wl_resource_get_user_data(resource); | ||||
| +	if (!ipc_output) | ||||
| +		return; | ||||
| + | ||||
| +	monitor = ipc_output->mon; | ||||
| +	selected_client = focustop(monitor); | ||||
| +	if (!selected_client) | ||||
| +		return; | ||||
| + | ||||
| +	newtags = (selected_client->tags & and_tags) ^ xor_tags; | ||||
| +	if (!newtags) | ||||
| +		return; | ||||
| + | ||||
| +	selected_client->tags = newtags; | ||||
| +	focusclient(focustop(selmon), 1); | ||||
| +	arrange(selmon); | ||||
| +	printstatus(); | ||||
| +} | ||||
| + | ||||
| +void | ||||
| +dwl_ipc_output_set_layout(struct wl_client *client, struct wl_resource *resource, uint32_t index) | ||||
| +{ | ||||
| +	DwlIpcOutput *ipc_output; | ||||
| +	Monitor *monitor; | ||||
| + | ||||
| +	ipc_output = wl_resource_get_user_data(resource); | ||||
| +	if (!ipc_output) | ||||
| +		return; | ||||
| + | ||||
| +	monitor = ipc_output->mon; | ||||
| +	if (index >= LENGTH(layouts)) | ||||
| +		return; | ||||
| +	if (index != monitor->lt[monitor->sellt] - layouts) | ||||
| +		monitor->sellt ^= 1; | ||||
| + | ||||
| +	monitor->lt[monitor->sellt] = &layouts[index]; | ||||
| +	arrange(monitor); | ||||
| +	printstatus(); | ||||
| +} | ||||
| + | ||||
| +void | ||||
| +dwl_ipc_output_set_tags(struct wl_client *client, struct wl_resource *resource, uint32_t tagmask, uint32_t toggle_tagset) | ||||
| +{ | ||||
| +	DwlIpcOutput *ipc_output; | ||||
| +	Monitor *monitor; | ||||
| +	unsigned int newtags = tagmask & TAGMASK; | ||||
| + | ||||
| +	ipc_output = wl_resource_get_user_data(resource); | ||||
| +	if (!ipc_output) | ||||
| +		return; | ||||
| +	monitor = ipc_output->mon; | ||||
| + | ||||
| +	if (!newtags || newtags == monitor->tagset[monitor->seltags]) | ||||
| +		return; | ||||
| +	if (toggle_tagset) | ||||
| +		monitor->seltags ^= 1; | ||||
| + | ||||
| +	monitor->tagset[monitor->seltags] = newtags; | ||||
| +	focusclient(focustop(monitor), 1); | ||||
| +	arrange(monitor); | ||||
| +	printstatus(); | ||||
| +} | ||||
| + | ||||
| +void | ||||
| +dwl_ipc_output_release(struct wl_client *client, struct wl_resource *resource) | ||||
| +{ | ||||
| +	wl_resource_destroy(resource); | ||||
| +} | ||||
| + | ||||
|  void | ||||
|  focusclient(Client *c, int lift) | ||||
|  { | ||||
| @@ -1846,41 +2056,9 @@ void | ||||
|  printstatus(void) | ||||
|  { | ||||
|  	Monitor *m = NULL; | ||||
| -	Client *c; | ||||
| -	uint32_t occ, urg, sel; | ||||
| -	const char *appid, *title; | ||||
|   | ||||
| -	wl_list_for_each(m, &mons, link) { | ||||
| -		occ = urg = 0; | ||||
| -		wl_list_for_each(c, &clients, link) { | ||||
| -			if (c->mon != m) | ||||
| -				continue; | ||||
| -			occ |= c->tags; | ||||
| -			if (c->isurgent) | ||||
| -				urg |= c->tags; | ||||
| -		} | ||||
| -		if ((c = focustop(m))) { | ||||
| -			title = client_get_title(c); | ||||
| -			appid = client_get_appid(c); | ||||
| -			printf("%s title %s\n", m->wlr_output->name, title ? title : broken); | ||||
| -			printf("%s appid %s\n", m->wlr_output->name, appid ? appid : broken); | ||||
| -			printf("%s fullscreen %u\n", m->wlr_output->name, c->isfullscreen); | ||||
| -			printf("%s floating %u\n", m->wlr_output->name, c->isfloating); | ||||
| -			sel = c->tags; | ||||
| -		} else { | ||||
| -			printf("%s title \n", m->wlr_output->name); | ||||
| -			printf("%s appid \n", m->wlr_output->name); | ||||
| -			printf("%s fullscreen \n", m->wlr_output->name); | ||||
| -			printf("%s floating \n", m->wlr_output->name); | ||||
| -			sel = 0; | ||||
| -		} | ||||
| - | ||||
| -		printf("%s selmon %u\n", m->wlr_output->name, m == selmon); | ||||
| -		printf("%s tags %u %u %u %u\n", m->wlr_output->name, occ, m->tagset[m->seltags], | ||||
| -				sel, urg); | ||||
| -		printf("%s layout %s\n", m->wlr_output->name, m->ltsymbol); | ||||
| -	} | ||||
| -	fflush(stdout); | ||||
| +	wl_list_for_each(m, &mons, link) | ||||
| +		dwl_ipc_output_printstatus(m); | ||||
|  } | ||||
|   | ||||
|  void | ||||
| @@ -2295,6 +2473,7 @@ setup(void) | ||||
|  	wl_signal_add(&output_mgr->events.test, &output_mgr_test); | ||||
|   | ||||
|  	wlr_scene_set_presentation(scene, wlr_presentation_create(dpy, backend)); | ||||
| +	wl_global_create(dpy, &zdwl_ipc_manager_v2_interface, 2, NULL, dwl_ipc_manager_bind); | ||||
|   | ||||
|  #ifdef XWAYLAND | ||||
|  	/* | ||||
| @@ -2389,6 +2568,13 @@ tile(Monitor *m) | ||||
|  	} | ||||
|  } | ||||
|   | ||||
| +void | ||||
| +togglebar(const Arg *arg) { | ||||
| +	DwlIpcOutput *ipc_output; | ||||
| +	wl_list_for_each(ipc_output, &selmon->dwl_ipc_outputs, link) | ||||
| +		zdwl_ipc_output_v2_send_toggle_visibility(ipc_output->resource); | ||||
| +} | ||||
| + | ||||
|  void | ||||
|  togglefloating(const Arg *arg) | ||||
|  { | ||||
| diff --git a/protocols/dwl-ipc-unstable-v2.xml b/protocols/dwl-ipc-unstable-v2.xml | ||||
| new file mode 100644 | ||||
| index 0000000..0a6e7e5 | ||||
| --- /dev/null | ||||
| +++ b/protocols/dwl-ipc-unstable-v2.xml | ||||
| @@ -0,0 +1,181 @@ | ||||
| +<?xml version="1.0" encoding="utf-8"?> | ||||
| +<!-- | ||||
| +This is largely ripped from somebar's ipc patchset; just with some personal modifications. | ||||
| +I would probably just submit raphi's patchset but I don't think that would be polite. | ||||
| +--> | ||||
| +<protocol name="dwl_ipc_unstable_v2"> | ||||
| +  <description summary="inter-proccess-communication about dwl's state"> | ||||
| +      This protocol allows clients to update and get updates from dwl. | ||||
| + | ||||
| +      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="zdwl_ipc_manager_v2" version="2"> | ||||
| +    <description summary="manage dwl state"> | ||||
| +      This interface is exposed as a global in wl_registry. | ||||
| + | ||||
| +      Clients can use this interface to get a dwl_ipc_output. | ||||
| +      After binding the client will recieve the dwl_ipc_manager.tags and dwl_ipc_manager.layout events. | ||||
| +      The dwl_ipc_manager.tags and dwl_ipc_manager.layout events expose tags and layouts to the client. | ||||
| +    </description> | ||||
| + | ||||
| +    <request name="release" type="destructor"> | ||||
| +      <description summary="release dwl_ipc_manager"> | ||||
| +        Indicates that the client will not the dwl_ipc_manager object anymore. | ||||
| +        Objects created through this instance are not affected. | ||||
| +      </description> | ||||
| +    </request> | ||||
| + | ||||
| +    <request name="get_output"> | ||||
| +      <description summary="get a dwl_ipc_outout for a wl_output"> | ||||
| +        Get a dwl_ipc_outout for the specified wl_output. | ||||
| +      </description> | ||||
| +      <arg name="id" type="new_id" interface="zdwl_ipc_output_v2"/> | ||||
| +      <arg name="output" type="object" interface="wl_output"/> | ||||
| +    </request> | ||||
| + | ||||
| +    <event name="tags"> | ||||
| +      <description summary="Announces tag amount"> | ||||
| +        This event is sent after binding. | ||||
| +        A roundtrip after binding guarantees the client recieved all tags. | ||||
| +      </description> | ||||
| +      <arg name="amount" type="uint"/> | ||||
| +    </event> | ||||
| + | ||||
| +    <event name="layout"> | ||||
| +      <description summary="Announces a layout"> | ||||
| +        This event is sent after binding. | ||||
| +        A roundtrip after binding guarantees the client recieved all layouts. | ||||
| +      </description> | ||||
| +      <arg name="name" type="string"/> | ||||
| +    </event> | ||||
| +  </interface> | ||||
| + | ||||
| +  <interface name="zdwl_ipc_output_v2" version="2"> | ||||
| +    <description summary="control dwl output"> | ||||
| +      Observe and control a dwl output. | ||||
| + | ||||
| +      Events are double-buffered: | ||||
| +      Clients should cache events and redraw when a dwl_ipc_output.frame event is sent. | ||||
| + | ||||
| +      Request are not double-buffered: | ||||
| +      The compositor will update immediately upon request. | ||||
| +    </description> | ||||
| + | ||||
| +    <enum name="tag_state"> | ||||
| +      <entry name="none" value="0" summary="no state"/> | ||||
| +      <entry name="active" value="1" summary="tag is active"/> | ||||
| +      <entry name="urgent" value="2" summary="tag has at least one urgent client"/> | ||||
| +    </enum> | ||||
| + | ||||
| +    <request name="release" type="destructor"> | ||||
| +      <description summary="release dwl_ipc_outout"> | ||||
| +        Indicates to that the client no longer needs this dwl_ipc_output. | ||||
| +      </description> | ||||
| +    </request> | ||||
| + | ||||
| +    <event name="toggle_visibility"> | ||||
| +      <description summary="Toggle client visibilty"> | ||||
| +        Indicates the client should hide or show themselves. | ||||
| +        If the client is visible then hide, if hidden then show. | ||||
| +      </description> | ||||
| +    </event> | ||||
| + | ||||
| +    <event name="active"> | ||||
| +      <description summary="Update the selected output."> | ||||
| +        Indicates if the output is active. Zero is invalid, nonzero is valid. | ||||
| +      </description> | ||||
| +      <arg name="active" type="uint"/> | ||||
| +    </event> | ||||
| + | ||||
| +    <event name="tag"> | ||||
| +      <description summary="Update the state of a tag."> | ||||
| +        Indicates that a tag has been updated. | ||||
| +      </description> | ||||
| +      <arg name="tag" type="uint" summary="Index of the tag"/> | ||||
| +      <arg name="state" type="uint" enum="tag_state" summary="The state of the tag."/> | ||||
| +      <arg name="clients" type="uint" summary="The number of clients in the tag."/> | ||||
| +      <arg name="focused" type="uint" summary="If there is a focused client. Nonzero being valid, zero being invalid."/> | ||||
| +    </event> | ||||
| + | ||||
| +    <event name="layout"> | ||||
| +      <description summary="Update the layout."> | ||||
| +        Indicates a new layout is selected. | ||||
| +      </description> | ||||
| +      <arg name="layout" type="uint" summary="Index of the layout."/> | ||||
| +    </event> | ||||
| + | ||||
| +    <event name="title"> | ||||
| +      <description summary="Update the title."> | ||||
| +        Indicates the title has changed. | ||||
| +      </description> | ||||
| +      <arg name="title" type="string" summary="The new title name."/> | ||||
| +    </event> | ||||
| + | ||||
| +    <event name="appid" since="1"> | ||||
| +      <description summary="Update the appid."> | ||||
| +        Indicates the appid has changed. | ||||
| +      </description> | ||||
| +      <arg name="appid" type="string" summary="The new appid."/> | ||||
| +    </event> | ||||
| + | ||||
| +    <event name="layout_symbol" since="1"> | ||||
| +      <description summary="Update the current layout symbol"> | ||||
| +          Indicates the layout has changed. Since layout symbols are dynamic. | ||||
| +          As opposed to the zdwl_ipc_manager.layout event, this should take precendence when displaying. | ||||
| +          You can ignore the zdwl_ipc_output.layout event. | ||||
| +      </description> | ||||
| +      <arg name="layout" type="string" summary="The new layout"/> | ||||
| +    </event> | ||||
| + | ||||
| +    <event name="frame"> | ||||
| +      <description summary="The update sequence is done."> | ||||
| +        Indicates that a sequence of status updates have finished and the client should redraw. | ||||
| +      </description> | ||||
| +    </event> | ||||
| + | ||||
| +    <request name="set_tags"> | ||||
| +      <description summary="Set the active tags of this output"/> | ||||
| +      <arg name="tagmask" type="uint" summary="bitmask of the tags that should be set."/> | ||||
| +      <arg name="toggle_tagset" type="uint" summary="toggle the selected tagset, zero for invalid, nonzero for valid."/> | ||||
| +    </request> | ||||
| + | ||||
| +    <request name="set_client_tags"> | ||||
| +      <description summary="Set the tags of the focused client."> | ||||
| +        The tags are updated as follows: | ||||
| +        new_tags = (current_tags AND and_tags) XOR xor_tags | ||||
| +      </description> | ||||
| +      <arg name="and_tags" type="uint"/> | ||||
| +      <arg name="xor_tags" type="uint"/> | ||||
| +    </request> | ||||
| + | ||||
| +    <request name="set_layout"> | ||||
| +      <description summary="Set the layout of this output"/> | ||||
| +      <arg name="index" type="uint" summary="index of a layout recieved by dwl_ipc_manager.layout"/> | ||||
| +    </request> | ||||
| + | ||||
| +    <!-- Version 2 --> | ||||
| +    <event name="fullscreen" since="2"> | ||||
| +      <description summary="Update fullscreen status"> | ||||
| +          Indicates if the selected client on this output is fullscreen. | ||||
| +      </description> | ||||
| +      <arg name="is_fullscreen" type="uint" summary="If the selected client is fullscreen. Nonzero is valid, zero invalid"/> | ||||
| +    </event> | ||||
| + | ||||
| +    <event name="floating" since="2"> | ||||
| +      <description summary="Update the floating status"> | ||||
| +          Indicates if the selected client on this output is floating. | ||||
| +      </description> | ||||
| +      <arg name="is_floating" type="uint" summary="If the selected client is floating. Nonzero is valid, zero invalid"/> | ||||
| +    </event> | ||||
| +  </interface> | ||||
| +</protocol> | ||||
|  | ||||
							
								
								
									
										181
									
								
								protocols/dwl-ipc-unstable-v2.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										181
									
								
								protocols/dwl-ipc-unstable-v2.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,181 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <!-- | ||||
| This is largely ripped from somebar's ipc patchset; just with some personal modifications. | ||||
| I would probably just submit raphi's patchset but I don't think that would be polite. | ||||
| --> | ||||
| <protocol name="dwl_ipc_unstable_v2"> | ||||
|   <description summary="inter-proccess-communication about dwl's state"> | ||||
|       This protocol allows clients to update and get updates from dwl. | ||||
|  | ||||
|       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="zdwl_ipc_manager_v2" version="2"> | ||||
|     <description summary="manage dwl state"> | ||||
|       This interface is exposed as a global in wl_registry. | ||||
|  | ||||
|       Clients can use this interface to get a dwl_ipc_output. | ||||
|       After binding the client will recieve the dwl_ipc_manager.tags and dwl_ipc_manager.layout events. | ||||
|       The dwl_ipc_manager.tags and dwl_ipc_manager.layout events expose tags and layouts to the client. | ||||
|     </description> | ||||
|  | ||||
|     <request name="release" type="destructor"> | ||||
|       <description summary="release dwl_ipc_manager"> | ||||
|         Indicates that the client will not the dwl_ipc_manager object anymore. | ||||
|         Objects created through this instance are not affected. | ||||
|       </description> | ||||
|     </request> | ||||
|  | ||||
|     <request name="get_output"> | ||||
|       <description summary="get a dwl_ipc_outout for a wl_output"> | ||||
|         Get a dwl_ipc_outout for the specified wl_output. | ||||
|       </description> | ||||
|       <arg name="id" type="new_id" interface="zdwl_ipc_output_v2"/> | ||||
|       <arg name="output" type="object" interface="wl_output"/> | ||||
|     </request> | ||||
|  | ||||
|     <event name="tags"> | ||||
|       <description summary="Announces tag amount"> | ||||
|         This event is sent after binding. | ||||
|         A roundtrip after binding guarantees the client recieved all tags. | ||||
|       </description> | ||||
|       <arg name="amount" type="uint"/> | ||||
|     </event> | ||||
|  | ||||
|     <event name="layout"> | ||||
|       <description summary="Announces a layout"> | ||||
|         This event is sent after binding. | ||||
|         A roundtrip after binding guarantees the client recieved all layouts. | ||||
|       </description> | ||||
|       <arg name="name" type="string"/> | ||||
|     </event> | ||||
|   </interface> | ||||
|  | ||||
|   <interface name="zdwl_ipc_output_v2" version="2"> | ||||
|     <description summary="control dwl output"> | ||||
|       Observe and control a dwl output. | ||||
|  | ||||
|       Events are double-buffered: | ||||
|       Clients should cache events and redraw when a dwl_ipc_output.frame event is sent. | ||||
|  | ||||
|       Request are not double-buffered: | ||||
|       The compositor will update immediately upon request. | ||||
|     </description> | ||||
|  | ||||
|     <enum name="tag_state"> | ||||
|       <entry name="none" value="0" summary="no state"/> | ||||
|       <entry name="active" value="1" summary="tag is active"/> | ||||
|       <entry name="urgent" value="2" summary="tag has at least one urgent client"/> | ||||
|     </enum> | ||||
|  | ||||
|     <request name="release" type="destructor"> | ||||
|       <description summary="release dwl_ipc_outout"> | ||||
|         Indicates to that the client no longer needs this dwl_ipc_output. | ||||
|       </description> | ||||
|     </request> | ||||
|  | ||||
|     <event name="toggle_visibility"> | ||||
|       <description summary="Toggle client visibilty"> | ||||
|         Indicates the client should hide or show themselves. | ||||
|         If the client is visible then hide, if hidden then show. | ||||
|       </description> | ||||
|     </event> | ||||
|  | ||||
|     <event name="active"> | ||||
|       <description summary="Update the selected output."> | ||||
|         Indicates if the output is active. Zero is invalid, nonzero is valid. | ||||
|       </description> | ||||
|       <arg name="active" type="uint"/> | ||||
|     </event> | ||||
|  | ||||
|     <event name="tag"> | ||||
|       <description summary="Update the state of a tag."> | ||||
|         Indicates that a tag has been updated. | ||||
|       </description> | ||||
|       <arg name="tag" type="uint" summary="Index of the tag"/> | ||||
|       <arg name="state" type="uint" enum="tag_state" summary="The state of the tag."/> | ||||
|       <arg name="clients" type="uint" summary="The number of clients in the tag."/> | ||||
|       <arg name="focused" type="uint" summary="If there is a focused client. Nonzero being valid, zero being invalid."/> | ||||
|     </event> | ||||
|  | ||||
|     <event name="layout"> | ||||
|       <description summary="Update the layout."> | ||||
|         Indicates a new layout is selected. | ||||
|       </description> | ||||
|       <arg name="layout" type="uint" summary="Index of the layout."/> | ||||
|     </event> | ||||
|  | ||||
|     <event name="title"> | ||||
|       <description summary="Update the title."> | ||||
|         Indicates the title has changed. | ||||
|       </description> | ||||
|       <arg name="title" type="string" summary="The new title name."/> | ||||
|     </event> | ||||
|  | ||||
|     <event name="appid" since="1"> | ||||
|       <description summary="Update the appid."> | ||||
|         Indicates the appid has changed. | ||||
|       </description> | ||||
|       <arg name="appid" type="string" summary="The new appid."/> | ||||
|     </event> | ||||
|  | ||||
|     <event name="layout_symbol" since="1"> | ||||
|       <description summary="Update the current layout symbol"> | ||||
|           Indicates the layout has changed. Since layout symbols are dynamic. | ||||
|           As opposed to the zdwl_ipc_manager.layout event, this should take precendence when displaying. | ||||
|           You can ignore the zdwl_ipc_output.layout event. | ||||
|       </description> | ||||
|       <arg name="layout" type="string" summary="The new layout"/> | ||||
|     </event> | ||||
|  | ||||
|     <event name="frame"> | ||||
|       <description summary="The update sequence is done."> | ||||
|         Indicates that a sequence of status updates have finished and the client should redraw. | ||||
|       </description> | ||||
|     </event> | ||||
|  | ||||
|     <request name="set_tags"> | ||||
|       <description summary="Set the active tags of this output"/> | ||||
|       <arg name="tagmask" type="uint" summary="bitmask of the tags that should be set."/> | ||||
|       <arg name="toggle_tagset" type="uint" summary="toggle the selected tagset, zero for invalid, nonzero for valid."/> | ||||
|     </request> | ||||
|  | ||||
|     <request name="set_client_tags"> | ||||
|       <description summary="Set the tags of the focused client."> | ||||
|         The tags are updated as follows: | ||||
|         new_tags = (current_tags AND and_tags) XOR xor_tags | ||||
|       </description> | ||||
|       <arg name="and_tags" type="uint"/> | ||||
|       <arg name="xor_tags" type="uint"/> | ||||
|     </request> | ||||
|  | ||||
|     <request name="set_layout"> | ||||
|       <description summary="Set the layout of this output"/> | ||||
|       <arg name="index" type="uint" summary="index of a layout recieved by dwl_ipc_manager.layout"/> | ||||
|     </request> | ||||
|  | ||||
|     <!-- Version 2 --> | ||||
|     <event name="fullscreen" since="2"> | ||||
|       <description summary="Update fullscreen status"> | ||||
|           Indicates if the selected client on this output is fullscreen. | ||||
|       </description> | ||||
|       <arg name="is_fullscreen" type="uint" summary="If the selected client is fullscreen. Nonzero is valid, zero invalid"/> | ||||
|     </event> | ||||
|  | ||||
|     <event name="floating" since="2"> | ||||
|       <description summary="Update the floating status"> | ||||
|           Indicates if the selected client on this output is floating. | ||||
|       </description> | ||||
|       <arg name="is_floating" type="uint" summary="If the selected client is floating. Nonzero is valid, zero invalid"/> | ||||
|     </event> | ||||
|   </interface> | ||||
| </protocol> | ||||
		Reference in New Issue
	
	Block a user