diff options
| author | Raghuram Subramani <raghus2247@gmail.com> | 2024-03-09 19:15:15 +0530 |
|---|---|---|
| committer | Raghuram Subramani <raghus2247@gmail.com> | 2024-03-09 19:15:15 +0530 |
| commit | e4abf501157bbca7978ffa35d53283117755859d (patch) | |
| tree | 53886b30b39e74fdfee242275a90141a423fbfe4 | |
| parent | baac62e103c5ea317801f89056dd44479cb6b3db (diff) | |
reset
Diffstat (limited to '')
| -rw-r--r-- | .gitea/issue_template/bug_report.yml | 62 | ||||
| -rw-r--r-- | .gitea/issue_template/enhancement-idea.yml | 9 | ||||
| -rw-r--r-- | LICENSE.dwm | 39 | ||||
| -rw-r--r-- | LICENSE.sway | 19 | ||||
| -rw-r--r-- | LICENSE.tinywl | 127 | ||||
| -rw-r--r-- | Makefile | 25 | ||||
| -rw-r--r-- | README.md | 5 | ||||
| -rw-r--r-- | client.h | 19 | ||||
| -rw-r--r-- | config.def.h | 63 | ||||
| -rw-r--r-- | dwl.c | 680 | ||||
| -rw-r--r-- | patches/attachbottom.patch | 26 | ||||
| -rw-r--r-- | patches/autostart.patch | 147 | ||||
| -rw-r--r-- | patches/ipc-v2-fixed-wlroots17.patch | 593 | ||||
| -rw-r--r-- | patches/naturalscrolltrackpad.patch | 27 | ||||
| -rw-r--r-- | patches/pertag.patch | 167 | ||||
| -rw-r--r-- | patches/smartborders.patch | 203 | ||||
| -rw-r--r-- | patches/wayland-ipc.patch | 498 | ||||
| -rw-r--r-- | protocols/dwl-ipc-unstable-v2.xml | 181 | ||||
| -rw-r--r-- | protocols/net-tapesoftware-dwl-wm-unstable-v1.xml | 164 |
19 files changed, 313 insertions, 2741 deletions
diff --git a/.gitea/issue_template/bug_report.yml b/.gitea/issue_template/bug_report.yml deleted file mode 100644 index 77ce108..0000000 --- a/.gitea/issue_template/bug_report.yml +++ /dev/null @@ -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 diff --git a/.gitea/issue_template/enhancement-idea.yml b/.gitea/issue_template/enhancement-idea.yml deleted file mode 100644 index be1bbf2..0000000 --- a/.gitea/issue_template/enhancement-idea.yml +++ /dev/null @@ -1,9 +0,0 @@ -name: Enhancement idea -about: Suggest a feature or improvement -title: -labels: - - 'Kind/Feature' -body: - - type: textarea - attributes: - label: Description diff --git a/LICENSE.dwm b/LICENSE.dwm new file mode 100644 index 0000000..507e4dc --- /dev/null +++ b/LICENSE.dwm @@ -0,0 +1,39 @@ +Portions of dwl based on dwm code are used under the following license: + +MIT/X Consortium License + +© 2006-2019 Anselm R Garbe <anselm@garbe.ca> +© 2006-2009 Jukka Salmi <jukka at salmi dot ch> +© 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com> +© 2007-2011 Peter Hartlich <sgkkr at hartlich dot com> +© 2007-2009 Szabolcs Nagy <nszabolcs at gmail dot com> +© 2007-2009 Christof Musik <christof at sendfax dot de> +© 2007-2009 Premysl Hruby <dfenze at gmail dot com> +© 2007-2008 Enno Gottox Boland <gottox at s01 dot de> +© 2008 Martin Hurton <martin dot hurton at gmail dot com> +© 2008 Neale Pickett <neale dot woozle dot org> +© 2009 Mate Nagy <mnagy at port70 dot net> +© 2010-2016 Hiltjo Posthuma <hiltjo@codemadness.org> +© 2010-2012 Connor Lane Smith <cls@lubutu.com> +© 2011 Christoph Lohmann <20h@r-36.net> +© 2015-2016 Quentin Rameau <quinq@fifth.space> +© 2015-2016 Eric Pruitt <eric.pruitt@gmail.com> +© 2016-2017 Markus Teich <markus.teich@stusta.mhn.de> + +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. diff --git a/LICENSE.sway b/LICENSE.sway new file mode 100644 index 0000000..3e0cacc --- /dev/null +++ b/LICENSE.sway @@ -0,0 +1,19 @@ +Copyright (c) 2016-2017 Drew DeVault + +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. diff --git a/LICENSE.tinywl b/LICENSE.tinywl new file mode 100644 index 0000000..7023690 --- /dev/null +++ b/LICENSE.tinywl @@ -0,0 +1,127 @@ +dwl is originally based on TinyWL, which is used under the following license: + +This work is licensed under CC0, which effectively puts it in the public domain. + +--- + +Creative Commons Legal Code + +CC0 1.0 Universal + + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS + PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM + THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED + HEREUNDER. + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator +and subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for +the purpose of contributing to a commons of creative, cultural and +scientific works ("Commons") that the public can reliably and without fear +of later claims of infringement build upon, modify, incorporate in other +works, reuse and redistribute as freely as possible in any form whatsoever +and for any purposes, including without limitation commercial purposes. +These owners may contribute to the Commons to promote the ideal of a free +culture and the further production of creative, cultural and scientific +works, or to gain reputation or greater distribution for their Work in +part through the use and efforts of others. + +For these and/or other purposes and motivations, and without any +expectation of additional consideration or compensation, the person +associating CC0 with a Work (the "Affirmer"), to the extent that he or she +is an owner of Copyright and Related Rights in the Work, voluntarily +elects to apply CC0 to the Work and publicly distribute the Work under its +terms, with knowledge of his or her Copyright and Related Rights in the +Work and the meaning and intended legal effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not +limited to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + ii. moral rights retained by the original author(s) and/or performer(s); +iii. publicity and privacy rights pertaining to a person's image or + likeness depicted in a Work; + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + v. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation + thereof, including any amended or successor version of such + directive); and +vii. other similar, equivalent or corresponding rights throughout the + world based on applicable law or treaty, and any national + implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention +of, applicable law, Affirmer hereby overtly, fully, permanently, +irrevocably and unconditionally waives, abandons, and surrenders all of +Affirmer's Copyright and Related Rights and associated claims and causes +of action, whether now known or unknown (including existing as well as +future claims and causes of action), in the Work (i) in all territories +worldwide, (ii) for the maximum duration provided by applicable law or +treaty (including future time extensions), (iii) in any current or future +medium and for any number of copies, and (iv) for any purpose whatsoever, +including without limitation commercial, advertising or promotional +purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each +member of the public at large and to the detriment of Affirmer's heirs and +successors, fully intending that such Waiver shall not be subject to +revocation, rescission, cancellation, termination, or any other legal or +equitable action to disrupt the quiet enjoyment of the Work by the public +as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason +be judged legally invalid or ineffective under applicable law, then the +Waiver shall be preserved to the maximum extent permitted taking into +account Affirmer's express Statement of Purpose. In addition, to the +extent the Waiver is so judged Affirmer hereby grants to each affected +person a royalty-free, non transferable, non sublicensable, non exclusive, +irrevocable and unconditional license to exercise Affirmer's Copyright and +Related Rights in the Work (i) in all territories worldwide, (ii) for the +maximum duration provided by applicable law or treaty (including future +time extensions), (iii) in any current or future medium and for any number +of copies, and (iv) for any purpose whatsoever, including without +limitation commercial, advertising or promotional purposes (the +"License"). The License shall be deemed effective as of the date CC0 was +applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder +of the License, and in such case Affirmer hereby affirms that he or she +will not (i) exercise any of his or her remaining Copyright and Related +Rights in the Work or (ii) assert any associated claims and causes of +action with respect to the Work, in either case contrary to Affirmer's +express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + b. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, + statutory or otherwise, including without limitation warranties of + title, merchantability, fitness for a particular purpose, non + infringement, or the absence of latent or other defects, accuracy, or + the present or absence of errors, whether or not discoverable, all to + the greatest extent permissible under applicable law. + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person's Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the + Work. + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. @@ -14,14 +14,11 @@ DWLCFLAGS = `$(PKG_CONFIG) --cflags $(PKGS)` $(DWLCPPFLAGS) $(DWLDEVCFLAGS) $(CF LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` $(LIBS) all: dwl -dwl: dwl.o util.o dwl-ipc-unstable-v2-protocol.o - $(CC) dwl.o util.o dwl-ipc-unstable-v2-protocol.o net-tapesoftware-dwl-wm-unstable-v1-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 net-tapesoftware-dwl-wm-unstable-v1-protocol.o - +dwl: dwl.o util.o + $(CC) dwl.o util.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 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 # to your build system yourself and provide them in the include path. @@ -37,25 +34,11 @@ wlr-layer-shell-unstable-v1-protocol.h: cursor-shape-v1-protocol.h: $(WAYLAND_SCANNER) server-header \ $(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/dwl-ipc-unstable-v2.xml $@ - -net-tapesoftware-dwl-wm-unstable-v1-protocol.h: protocols/net-tapesoftware-dwl-wm-unstable-v1.xml - $(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_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 config.h: cp config.def.h $@ clean: - rm -f dwl *.o *-protocol.h *.rej *.orig config.h + rm -f dwl *.o *-protocol.h dist: clean mkdir -p dwl-$(VERSION) @@ -86,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 @@ -169,7 +169,8 @@ inspiration, and to the various contributors to the project, including: [Wayland]: https://wayland.freedesktop.org/ [wlroots]: https://gitlab.freedesktop.org/wlroots/wlroots/ [wlroots-next branch]: https://codeberg.org/dwl/dwl/src/branch/wlroots-next -[patches page on our wiki]: https://codeberg.org/dwl/dwl/wiki/Patches +[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 @@ -172,14 +172,29 @@ client_get_parent(Client *c) { Client *p = NULL; #ifdef XWAYLAND - if (client_is_x11(c) && c->surface.xwayland->parent) - toplevel_from_wlr_surface(c->surface.xwayland->parent->surface, &p, NULL); + 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) { diff --git a/config.def.h b/config.def.h index ac696d2..9009517 100644 --- a/config.def.h +++ b/config.def.h @@ -6,12 +6,11 @@ /* appearance */ 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 smartborders = 1; -static const unsigned int borderpx = 2; /* border pixel of windows */ -static const float rootcolor[] = COLOR(0x272727ff); -static const float bordercolor[] = COLOR(0x272727ff); -static const float focuscolor[] = COLOR(0xf2f0faff); -static const float urgentcolor[] = COLOR(0xf2f0faff); +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.1f, 0.1f, 0.1f, 1.0f}; /* You can also use glsl colors */ @@ -21,27 +20,19 @@ static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You ca /* logging */ static int log_level = WLR_ERROR; -/* Autostart */ -static const char *const autostart[] = { - "wbg", "/home/compromyse/Pictures/wallpaper.jpg", NULL, - "way-displays", NULL, - "waybar", NULL, - "dunst", NULL, - "swayidle", "before-sleep", "swaylock", "lock", "swaylock", NULL, - NULL -}; - - static const Rule rules[] = { /* app_id title tags mask isfloating monitor */ - { NULL, NULL, NULL, 0, -1 }, + /* examples: + { "Gimp", NULL, 0, 1, -1 }, + */ + { "firefox", NULL, 1 << 8, 0, -1 }, }; /* layout(s) */ static const Layout layouts[] = { /* symbol arrange function */ { "[]=", tile }, - { "><>", NULL }, + { "><>", NULL }, /* no layout function means floating behavior */ { "[M]", monocle }, }; @@ -72,11 +63,10 @@ static const int repeat_delay = 600; static const int tap_to_click = 1; static const int tap_and_drag = 1; static const int drag_lock = 1; -static const int natural_scrolling = 1; +static const int natural_scrolling = 0; static const int disable_while_typing = 1; static const int left_handed = 0; -static const int middle_button_emulation = 1; - +static const int middle_button_emulation = 0; /* You can choose between: LIBINPUT_CONFIG_SCROLL_NO_SCROLL LIBINPUT_CONFIG_SCROLL_2FG @@ -90,7 +80,7 @@ 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_CLICKFINGER; +static const enum libinput_config_click_method click_method = LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS; /* You can choose between: LIBINPUT_CONFIG_SEND_EVENTS_ENABLED @@ -105,7 +95,6 @@ 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 @@ -113,7 +102,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; /* 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) \ { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ @@ -125,16 +114,14 @@ static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TA #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } /* commands */ -static const char *termcmd[] = { "alacritty", NULL }; -static const char *menucmd[] = { "fuzzel", NULL }; -static const char *lockcmd[] = { "swaylock", NULL }; +static const char *termcmd[] = { "foot", NULL }; +static const char *menucmd[] = { "bemenu-run", NULL }; static const Key keys[] = { /* Note that Shift changes certain key codes: c -> C, 2 -> at, etc. */ /* modifier key function argument */ - { MODKEY, XKB_KEY_space, spawn, {.v = menucmd} }, + { MODKEY, XKB_KEY_p, spawn, {.v = menucmd} }, { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Return, spawn, {.v = termcmd} }, - { MODKEY, XKB_KEY_x, spawn, {.v = lockcmd} }, { MODKEY, XKB_KEY_j, focusstack, {.i = +1} }, { MODKEY, XKB_KEY_k, focusstack, {.i = -1} }, { MODKEY, XKB_KEY_i, incnmaster, {.i = +1} }, @@ -143,17 +130,19 @@ static const Key keys[] = { { 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_Q, killclient, {0} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_C, killclient, {0} }, { MODKEY, XKB_KEY_t, setlayout, {.v = &layouts[0]} }, - { MODKEY, XKB_KEY_f, setlayout, {.v = &layouts[2]} }, - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_F, togglefloating, {0} }, - { MODKEY, XKB_KEY_e, togglefullscreen, {0} }, + { MODKEY, XKB_KEY_f, setlayout, {.v = &layouts[1]} }, + { MODKEY, XKB_KEY_m, setlayout, {.v = &layouts[2]} }, + { MODKEY, XKB_KEY_space, setlayout, {0} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} }, + { MODKEY, XKB_KEY_e, togglefullscreen, {0} }, { MODKEY, XKB_KEY_0, view, {.ui = ~0} }, { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_parenright, tag, {.ui = ~0} }, { MODKEY, XKB_KEY_comma, focusmon, {.i = WLR_DIRECTION_LEFT} }, { MODKEY, XKB_KEY_period, focusmon, {.i = WLR_DIRECTION_RIGHT} }, - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_H, tagmon, {.i = WLR_DIRECTION_LEFT} }, - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_L, tagmon, {.i = WLR_DIRECTION_RIGHT} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_less, tagmon, {.i = WLR_DIRECTION_LEFT} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_greater, tagmon, {.i = WLR_DIRECTION_RIGHT} }, TAGKEYS( XKB_KEY_1, XKB_KEY_exclam, 0), TAGKEYS( XKB_KEY_2, XKB_KEY_at, 1), TAGKEYS( XKB_KEY_3, XKB_KEY_numbersign, 2), @@ -163,7 +152,7 @@ static const Key keys[] = { TAGKEYS( XKB_KEY_7, XKB_KEY_ampersand, 6), TAGKEYS( XKB_KEY_8, XKB_KEY_asterisk, 7), TAGKEYS( XKB_KEY_9, XKB_KEY_parenleft, 8), - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_B, quit, {0} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Q, quit, {0} }, /* Ctrl-Alt-Backspace and Ctrl-Alt-Fx used to be handled by X server */ { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_Terminate_Server, quit, {0} }, @@ -55,14 +55,12 @@ #include <wlr/types/wlr_xdg_shell.h> #include <wlr/util/log.h> #include <xkbcommon/xkbcommon.h> -#include "net-tapesoftware-dwl-wm-unstable-v1-protocol.h" #ifdef XWAYLAND #include <wlr/xwayland.h> #include <xcb/xcb.h> #include <xcb/xcb_icccm.h> #endif -#include "dwl-ipc-unstable-v2-protocol.h" #include "util.h" /* macros */ @@ -100,7 +98,6 @@ typedef struct { const Arg arg; } Button; -typedef struct Pertag Pertag; typedef struct Monitor Monitor; typedef struct { /* Must keep these three elements in this order */ @@ -142,12 +139,6 @@ typedef struct { } Client; typedef struct { - struct wl_list link; - struct wl_resource *resource; - Monitor *mon; -} DwlIpcOutput; - -typedef struct { uint32_t mod; xkb_keysym_t keysym; void (*func)(const Arg *); @@ -190,15 +181,8 @@ typedef struct { void (*arrange)(Monitor *); } Layout; -typedef struct { - struct wl_list link; - struct wl_resource *resource; - struct Monitor *monitor; -} DwlWmMonitor; - 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 */ @@ -210,9 +194,7 @@ struct Monitor { struct wlr_box m; /* monitor area, layout-relative */ struct wlr_box w; /* window area, layout-relative */ struct wl_list layers[4]; /* LayerSurface.link */ - struct wl_list dwl_wm_monitor_link; const Layout *lt[2]; - Pertag *pertag; unsigned int seltags; unsigned int sellt; uint32_t tagset[2]; @@ -256,7 +238,6 @@ static void arrange(Monitor *m); static void arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area, int exclusive); static void arrangelayers(Monitor *m); -static void autostartexec(void); static void axisnotify(struct wl_listener *listener, void *data); static void buttonpress(struct wl_listener *listener, void *data); static void chvt(const Arg *arg); @@ -285,17 +266,6 @@ 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); @@ -329,7 +299,7 @@ static void rendermon(struct wl_listener *listener, void *data); static void requestdecorationmode(struct wl_listener *listener, void *data); static void requeststartdrag(struct wl_listener *listener, void *data); static void requestmonstate(struct wl_listener *listener, void *data); -static void resize(Client *c, struct wlr_box geo, int interact, int draw_borders); +static void resize(Client *c, struct wlr_box geo, int interact); static void run(char *startup_cmd); static void setcursor(struct wl_listener *listener, void *data); static void setcursorshape(struct wl_listener *listener, void *data); @@ -365,10 +335,6 @@ static void xytonode(double x, double y, struct wlr_surface **psurface, Client **pc, LayerSurface **pl, double *nx, double *ny); static void zoom(const Arg *arg); -static void dwl_wm_bind(struct wl_client *client, void *data, - uint32_t version, uint32_t id); -static void dwl_wm_printstatus(Monitor *monitor); - /* variables */ static const char broken[] = "broken"; static pid_t child_pid = -1; @@ -408,8 +374,6 @@ static struct wlr_session_lock_manager_v1 *session_lock_mgr; static struct wlr_scene_rect *locked_bg; static struct wlr_session_lock_v1 *cur_lock; static struct wl_listener lock_listener = {.notify = locksession}; -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 wlr_seat *seat; static KeyboardGroup kb_group = {0}; @@ -443,24 +407,13 @@ static xcb_atom_t netatom[NetLast]; /* attempt to encapsulate suck into one file */ #include "client.h" -static pid_t *autostart_pids; -static size_t autostart_len; - -struct Pertag { - unsigned int curtag, prevtag; /* current and previous tag */ - int nmasters[TAGCOUNT + 1]; /* number of windows in master area */ - float mfacts[TAGCOUNT + 1]; /* mfacts per tag */ - unsigned int sellts[TAGCOUNT + 1]; /* selected layouts */ - const Layout *ltidxs[TAGCOUNT + 1][2]; /* matrix of tags and layouts indexes */ -}; - /* function implementations */ void applybounds(Client *c, struct wlr_box *bbox) { /* set minimum possible */ - c->geom.width = MAX(1, c->geom.width); - c->geom.height = MAX(1, c->geom.height); + c->geom.width = MAX(1 + 2 * (int)c->bw, c->geom.width); + c->geom.height = MAX(1 + 2 * (int)c->bw, c->geom.height); if (c->geom.x >= bbox->x + bbox->width) c->geom.x = bbox->x + bbox->width - c->geom.width; @@ -500,7 +453,6 @@ applyrules(Client *c) } } } - wlr_scene_node_reparent(&c->scene->node, layers[c->isfloating ? LyrFloat : LyrTile]); setmon(c, mon, newtags); } @@ -590,27 +542,6 @@ arrangelayers(Monitor *m) } void -autostartexec(void) { - const char *const *p; - size_t i = 0; - - /* count entries */ - for (p = autostart; *p; autostart_len++, p++) - while (*++p); - - autostart_pids = calloc(autostart_len, sizeof(pid_t)); - for (p = autostart; *p; i++, p++) { - if ((autostart_pids[i] = fork()) == 0) { - setsid(); - execvp(*p, (char *const *)p); - die("dwl: execvp %s:", *p); - } - /* skip arguments */ - while (*++p); - } -} - -void axisnotify(struct wl_listener *listener, void *data) { /* This event is forwarded by the cursor when a pointer emits an axis event, @@ -707,21 +638,11 @@ checkidleinhibitor(struct wlr_surface *exclude) void cleanup(void) { - size_t i; #ifdef XWAYLAND wlr_xwayland_destroy(xwayland); xwayland = NULL; #endif wl_display_destroy_clients(dpy); - - /* kill child processes */ - for (i = 0; i < autostart_len; i++) { - if (0 < autostart_pids[i]) { - kill(autostart_pids[i], SIGTERM); - waitpid(autostart_pids[i], NULL, 0); - } - } - if (child_pid > 0) { kill(child_pid, SIGTERM); waitpid(child_pid, NULL, 0); @@ -743,14 +664,9 @@ void cleanupmon(struct wl_listener *listener, void *data) { Monitor *m = wl_container_of(listener, m, destroy); - DwlWmMonitor *mon, *montmp; LayerSurface *l, *tmp; size_t 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); - /* m->layers[i] are intentionally not unlinked */ for (i = 0; i < LENGTH(m->layers); i++) { wl_list_for_each_safe(l, tmp, &m->layers[i], link) @@ -763,19 +679,13 @@ cleanupmon(struct wl_listener *listener, void *data) wl_list_remove(&m->request_state.link); m->wlr_output->data = NULL; wlr_output_layout_remove(output_layout, m->wlr_output); - wl_list_for_each_safe(mon, montmp, &m->dwl_wm_monitor_link, link) { - wl_resource_set_user_data(mon->resource, NULL); - free(mon); - } wlr_scene_output_destroy(m->scene_output); - free(m->pertag); closemon(m); wlr_scene_node_destroy(&m->fullscreen_bg->node); free(m); } - void closemon(Monitor *m) { @@ -794,7 +704,7 @@ closemon(Monitor *m) wl_list_for_each(c, &clients, link) { if (c->isfloating && c->geom.x > m->m.width) resize(c, (struct wlr_box){.x = c->geom.x - m->w.width, .y = c->geom.y, - .width = c->geom.width, .height = c->geom.height}, 0, 1); + .width = c->geom.width, .height = c->geom.height}, 0); if (c->mon == m) setmon(c, selmon, c->tags); } @@ -829,12 +739,8 @@ commitnotify(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, commit); - if (client_surface(c)->mapped) { - if (c->mon && c->mon->lt[c->mon->sellt]->arrange && !c->isfullscreen && !c->isfloating) - c->mon->lt[c->mon->sellt]->arrange(c->mon); - else - resize(c, c->geom, (c->isfloating && !c->isfullscreen), (c->isfloating && !c->isfullscreen)); - } + if (client_surface(c)->mapped && c->mon) + resize(c, c->geom, (c->isfloating && !c->isfullscreen)); /* mark a pending resize as completed */ if (c->resize && c->resize <= c->surface.xdg->current.configure_serial) @@ -946,7 +852,6 @@ createmon(struct wl_listener *listener, void *data) size_t i; struct wlr_output_state state; Monitor *m; - wl_list_init(&m->dwl_wm_monitor_link); if (!wlr_output_init_render(wlr_output, alloc, drw)) return; @@ -954,8 +859,6 @@ createmon(struct wl_listener *listener, void *data) m = wlr_output->data = ecalloc(1, sizeof(*m)); m->wlr_output = wlr_output; - wl_list_init(&m->dwl_ipc_outputs); - for (i = 0; i < LENGTH(m->layers); i++) wl_list_init(&m->layers[i]); @@ -968,7 +871,8 @@ createmon(struct wl_listener *listener, void *data) m->m.y = r->y; m->mfact = r->mfact; m->nmaster = r->nmaster; - m->lt[0] = m->lt[1] = r->lt; + m->lt[0] = r->lt; + m->lt[1] = &layouts[LENGTH(layouts) > 1 && r->lt != &layouts[1]]; strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, LENGTH(m->ltsymbol)); wlr_output_state_set_scale(&state, r->scale); wlr_output_state_set_transform(&state, r->rr); @@ -994,18 +898,6 @@ createmon(struct wl_listener *listener, void *data) wl_list_insert(&mons, &m->link); printstatus(); - m->pertag = calloc(1, sizeof(Pertag)); - m->pertag->curtag = m->pertag->prevtag = 1; - - for (i = 0; i <= TAGCOUNT; i++) { - m->pertag->nmasters[i] = m->nmaster; - m->pertag->mfacts[i] = m->mfact; - - m->pertag->ltidxs[i][0] = m->lt[0]; - m->pertag->ltidxs[i][1] = m->lt[1]; - m->pertag->sellts[i] = m->sellt; - } - /* The xdg-protocol specifies: * * If the fullscreened surface is not opaque, the compositor must make @@ -1091,10 +983,11 @@ createpointer(struct wlr_pointer *pointer) libinput_device_config_tap_set_drag_enabled(device, tap_and_drag); libinput_device_config_tap_set_drag_lock_enabled(device, drag_lock); libinput_device_config_tap_set_button_map(device, button_map); - if (libinput_device_config_scroll_has_natural_scroll(device)) - libinput_device_config_scroll_set_natural_scroll_enabled(device, natural_scrolling); } + if (libinput_device_config_scroll_has_natural_scroll(device)) + libinput_device_config_scroll_set_natural_scroll_enabled(device, natural_scrolling); + if (libinput_device_config_dwt_is_available(device)) libinput_device_config_dwt_set_enabled(device, disable_while_typing); @@ -1273,191 +1166,6 @@ dirtomon(enum wlr_direction dir) } 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) { struct wlr_surface *old = seat->keyboard_state.focused_surface; @@ -1549,7 +1257,7 @@ focusstack(const Arg *arg) { /* Focus the next or previous client (in tiling order) on selmon */ Client *c, *sel = focustop(selmon); - if (!sel || sel->isfullscreen) + if (!sel || (sel->isfullscreen && !client_has_children(sel))) return; if (arg->i > 0) { wl_list_for_each(c, &sel->link, link) { @@ -1595,31 +1303,18 @@ void handlesig(int signo) { if (signo == SIGCHLD) { +#ifdef XWAYLAND siginfo_t in; /* wlroots expects to reap the XWayland process itself, so we * use WNOWAIT to keep the child waitable until we know it's not * XWayland. */ while (!waitid(P_ALL, 0, &in, WEXITED|WNOHANG|WNOWAIT) && in.si_pid -#ifdef XWAYLAND - && (!xwayland || in.si_pid != xwayland->server->pid) -#endif - ) { - pid_t *p, *lim; + && (!xwayland || in.si_pid != xwayland->server->pid)) waitpid(in.si_pid, NULL, 0); - if (in.si_pid == child_pid) - child_pid = -1; - if (!(p = autostart_pids)) - continue; - lim = &p[autostart_len]; - - for (; p < lim; p++) { - if (*p == in.si_pid) { - *p = -1; - break; - } - } - } +#else + while (waitpid(-1, NULL, WNOHANG) > 0); +#endif } else if (signo == SIGINT || signo == SIGTERM) { quit(NULL); } @@ -1630,7 +1325,7 @@ incnmaster(const Arg *arg) { if (!arg || !selmon) return; - selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag] = MAX(selmon->nmaster + arg->i, 0); + selmon->nmaster = MAX(selmon->nmaster + arg->i, 0); arrange(selmon); } @@ -1802,7 +1497,8 @@ void mapnotify(struct wl_listener *listener, void *data) { /* Called when the surface is mapped, or ready to display on-screen. */ - Client *p, *w, *c = wl_container_of(listener, c, map); + Client *p = NULL; + Client *w, *c = wl_container_of(listener, c, map); Monitor *m; int i; @@ -1841,21 +1537,15 @@ mapnotify(struct wl_listener *listener, void *data) c->geom.height += 2 * c->bw; /* Insert this client into client lists. */ - if (clients.prev) - // tile at the bottom - wl_list_insert(clients.prev, &c->link); - else - wl_list_insert(&clients, &c->link); + wl_list_insert(&clients, &c->link); wl_list_insert(&fstack, &c->flink); /* Set initial monitor, tags, floating status, and focus: * we always consider floating, clients that have parent and thus * we set the same tags and monitor than its parent, if not * try to apply rules for them */ - /* TODO: https://github.com/djpohly/dwl/pull/334#issuecomment-1330166324 */ - if (c->type == XDGShell && (p = client_get_parent(c))) { + if ((p = client_get_parent(c))) { c->isfloating = 1; - wlr_scene_node_reparent(&c->scene->node, layers[LyrFloat]); setmon(c, p->mon, p->tags); } else { applyrules(c); @@ -1865,7 +1555,7 @@ mapnotify(struct wl_listener *listener, void *data) unset_fullscreen: m = c->mon ? c->mon : xytomon(c->geom.x, c->geom.y); wl_list_for_each(w, &clients, link) { - if (w != c && w->isfullscreen && m == w->mon && (w->tags & c->tags)) + if (w != c && w != p && w->isfullscreen && m == w->mon && (w->tags & c->tags)) setfullscreen(w, 0); } } @@ -1896,7 +1586,7 @@ monocle(Monitor *m) wl_list_for_each(c, &clients, link) { if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen) continue; - resize(c, m->w, 0, !smartborders); + resize(c, m->w, 0); n++; } if (n) @@ -1943,11 +1633,11 @@ motionnotify(uint32_t time) if (cursor_mode == CurMove) { /* Move the grabbed client to the new position. */ resize(grabc, (struct wlr_box){.x = ROUND(cursor->x) - grabcx, .y = ROUND(cursor->y) - grabcy, - .width = grabc->geom.width, .height = grabc->geom.height}, 1, 1); + .width = grabc->geom.width, .height = grabc->geom.height}, 1); return; } else if (cursor_mode == CurResize) { resize(grabc, (struct wlr_box){.x = grabc->geom.x, .y = grabc->geom.y, - .width = ROUND(cursor->x) - grabc->geom.x, .height = ROUND(cursor->y) - grabc->geom.y}, 1, 1); + .width = ROUND(cursor->x) - grabc->geom.x, .height = ROUND(cursor->y) - grabc->geom.y}, 1); return; } @@ -2117,9 +1807,41 @@ void printstatus(void) { Monitor *m = NULL; - wl_list_for_each(m, &mons, link) - dwl_ipc_output_printstatus(m); - dwl_wm_printstatus(m); + 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 %d\n", m->wlr_output->name, c->isfullscreen); + printf("%s floating %d\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 %"PRIu32" %"PRIu32" %"PRIu32" %"PRIu32"\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); } void @@ -2209,13 +1931,12 @@ requestmonstate(struct wl_listener *listener, void *data) } void -resize(Client *c, struct wlr_box geo, int interact, int draw_borders) +resize(Client *c, struct wlr_box geo, int interact) { struct wlr_box *bbox = interact ? &sgeom : &c->mon->w; struct wlr_box clip; client_set_bounds(c, geo.width, geo.height); c->geom = geo; - c->bw = draw_borders ? borderpx : 0; applybounds(c, bbox); /* Update scene-graph, including borders */ @@ -2251,7 +1972,6 @@ run(char *startup_cmd) die("startup: backend_start"); /* Now that the socket exists and the backend is started, run the startup command */ - autostartexec(); if (startup_cmd) { int piperw[2]; if (pipe(piperw) < 0) @@ -2326,13 +2046,13 @@ setcursorshape(struct wl_listener *listener, void *data) void setfloating(Client *c, int floating) { + Client *p = client_get_parent(c); c->isfloating = floating; if (!c->mon) return; - wlr_scene_node_reparent(&c->scene->node, layers[c->isfullscreen - ? LyrFS : c->isfloating ? LyrFloat : LyrTile]); - if (c->isfloating && !c->bw) - resize(c, c->mon->m, 0, 1); + wlr_scene_node_reparent(&c->scene->node, layers[c->isfullscreen || + (p && p->isfullscreen) ? LyrFS + : c->isfloating ? LyrFloat : LyrTile]); arrange(c->mon); printstatus(); } @@ -2350,11 +2070,11 @@ setfullscreen(Client *c, int fullscreen) if (fullscreen) { c->prev = c->geom; - resize(c, c->mon->m, 0, 0); + resize(c, c->mon->m, 0); } else { /* restore previous size instead of arrange for floating windows since * client positions are set by the user and cannot be recalculated */ - resize(c, c->prev, 0, 1); + resize(c, c->prev, 0); } arrange(c->mon); printstatus(); @@ -2377,16 +2097,10 @@ setlayout(const Arg *arg) if (!selmon) return; if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) - selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag] ^= 1; + selmon->sellt ^= 1; if (arg && arg->v) - selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt] = (Layout *)arg->v; + selmon->lt[selmon->sellt] = (Layout *)arg->v; strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, LENGTH(selmon->ltsymbol)); - if (!selmon->lt[selmon->sellt]->arrange) { - /* floating layout, draw borders around all clients */ - Client *c; - wl_list_for_each(c, &clients, link) - resize(c, c->mon->m, 0, 1); - } arrange(selmon); printstatus(); } @@ -2402,7 +2116,7 @@ setmfact(const Arg *arg) f = arg->f < 1.0f ? arg->f + selmon->mfact : arg->f - 1.0f; if (f < 0.1 || f > 0.9) return; - selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag] = f; + selmon->mfact = f; arrange(selmon); } @@ -2421,7 +2135,7 @@ setmon(Client *c, Monitor *m, uint32_t newtags) arrange(oldmon); if (m) { /* Make sure window actually overlaps with the monitor */ - resize(c, c->geom, 0, 1); + resize(c, c->geom, 0); c->tags = newtags ? newtags : m->tagset[m->seltags]; /* assign tags of target monitor */ setfullscreen(c, c->isfullscreen); /* This will call arrange(c->mon) */ setfloating(c, c->isfloating); @@ -2685,8 +2399,6 @@ setup(void) LISTEN_STATIC(&output_mgr->events.test, outputmgrtest); wlr_scene_set_presentation(scene, wlr_presentation_create(dpy, backend)); - wl_global_create(dpy, &znet_tapesoftware_dwl_wm_v1_interface, 1, NULL, dwl_wm_bind); - wl_global_create(dpy, &zdwl_ipc_manager_v2_interface, 2, NULL, dwl_ipc_manager_bind); /* Make sure XWayland clients don't connect to the parent X server, * e.g when running in the x11 backend or the wayland backend and the @@ -2754,7 +2466,7 @@ tagmon(const Arg *arg) void tile(Monitor *m) { - unsigned int mw, my, ty, draw_borders = 1; + unsigned int mw, my, ty; int i, n = 0; Client *c; @@ -2764,9 +2476,6 @@ tile(Monitor *m) if (n == 0) return; - if (n == smartborders) - draw_borders = 0; - if (n > m->nmaster) mw = m->nmaster ? ROUND(m->w.width * m->mfact) : 0; else @@ -2777,11 +2486,11 @@ tile(Monitor *m) continue; if (i < m->nmaster) { resize(c, (struct wlr_box){.x = m->w.x, .y = m->w.y + my, .width = mw, - .height = (m->w.height - my) / (MIN(n, m->nmaster) - i)}, 0, draw_borders); + .height = (m->w.height - my) / (MIN(n, m->nmaster) - i)}, 0); my += c->geom.height; } else { resize(c, (struct wlr_box){.x = m->w.x + mw, .y = m->w.y + ty, - .width = m->w.width - mw, .height = (m->w.height - ty) / (n - i)}, 0, draw_borders); + .width = m->w.width - mw, .height = (m->w.height - ty) / (n - i)}, 0); ty += c->geom.height; } i++; @@ -2826,27 +2535,6 @@ toggleview(const Arg *arg) if (!(newtagset = selmon ? selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK) : 0)) return; - size_t i; - - if (newtagset == ~0) { - selmon->pertag->prevtag = selmon->pertag->curtag; - selmon->pertag->curtag = 0; - } - - /* test if the user did not select the same tag */ - if (!(newtagset & 1 << (selmon->pertag->curtag - 1))) { - selmon->pertag->prevtag = selmon->pertag->curtag; - for (i = 0; !(newtagset & 1 << i); i++) ; - selmon->pertag->curtag = i + 1; - } - - /* apply settings for this view */ - selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag]; - selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag]; - selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; - selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; - selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; - selmon->tagset[selmon->seltags] = newtagset; focusclient(focustop(selmon), 1); arrange(selmon); @@ -2971,7 +2659,7 @@ updatemons(struct wl_listener *listener, void *data) arrange(m); /* make sure fullscreen clients have the right size */ if ((c = focustop(m)) && c->isfullscreen) - resize(c, m->m, 0, 0); + resize(c, m->m, 0); /* Try to re-set the gamma LUT when updating monitors, * it's only really needed when enabling a disabled output, but meh. */ @@ -3031,33 +2719,11 @@ urgent(struct wl_listener *listener, void *data) void view(const Arg *arg) { - size_t i, tmptag; - if (!selmon || (arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) return; selmon->seltags ^= 1; /* toggle sel tagset */ - if (arg->ui & TAGMASK) { + if (arg->ui & TAGMASK) selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; - selmon->pertag->prevtag = selmon->pertag->curtag; - - if (arg->ui == ~0) - selmon->pertag->curtag = 0; - else { - for (i = 0; !(arg->ui & 1 << i); i++) ; - selmon->pertag->curtag = i + 1; - } - } else { - tmptag = selmon->pertag->prevtag; - selmon->pertag->prevtag = selmon->pertag->curtag; - selmon->pertag->curtag = tmptag; - } - - selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag]; - selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag]; - selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; - selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; - selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; - focusclient(focustop(selmon), 1); arrange(selmon); printstatus(); @@ -3190,7 +2856,7 @@ configurex11(struct wl_listener *listener, void *data) } if (c->isfloating || client_is_unmanaged(c)) resize(c, (struct wlr_box){.x = event->x, .y = event->y, - .width = event->width, .height = event->height}, 0, 1); + .width = event->width, .height = event->height}, 0); else arrange(c->mon); } @@ -3316,193 +2982,3 @@ main(int argc, char *argv[]) usage: die("Usage: %s [-v] [-d] [-s startup command]", argv[0]); } - -/* dwl_wm_monitor_v1 */ -static void -dwl_wm_monitor_handle_release(struct wl_client *client, struct wl_resource *resource) -{ - wl_resource_destroy(resource); -} - -static void -dwl_wm_monitor_handle_destroy(struct wl_resource *resource) -{ - DwlWmMonitor *mon = wl_resource_get_user_data(resource); - if (mon) { - wl_list_remove(&mon->link); - free(mon); - } -} - -static void -dwl_wm_printstatus_to(Monitor *m, const DwlWmMonitor *mon) -{ - Client *c, *focused; - int tagmask, state, numclients, focused_client; - focused = focustop(m); - znet_tapesoftware_dwl_wm_monitor_v1_send_selected(mon->resource, m == selmon); - - for (int tag = 0; tag<LENGTH(tags); tag++) { - numclients = state = 0; - focused_client = -1; - tagmask = 1 << tag; - if ((tagmask & m->tagset[m->seltags]) != 0) - state = state | ZNET_TAPESOFTWARE_DWL_WM_MONITOR_V1_TAG_STATE_ACTIVE; - wl_list_for_each(c, &clients, link) { - if (c->mon != m) - continue; - if (!(c->tags & tagmask)) - continue; - if (c == focused) - focused_client = numclients; - numclients++; - if (c->isurgent) - state = state | ZNET_TAPESOFTWARE_DWL_WM_MONITOR_V1_TAG_STATE_URGENT; - } - znet_tapesoftware_dwl_wm_monitor_v1_send_tag(mon->resource, - tag, state, numclients, focused_client); - } - znet_tapesoftware_dwl_wm_monitor_v1_send_layout(mon->resource, m->lt[m->sellt] - layouts); - znet_tapesoftware_dwl_wm_monitor_v1_send_title(mon->resource, - focused ? client_get_title(focused) : ""); - znet_tapesoftware_dwl_wm_monitor_v1_send_frame(mon->resource); -} - -static void -dwl_wm_printstatus(Monitor *m) -{ - DwlWmMonitor *mon; - wl_list_for_each(mon, &m->dwl_wm_monitor_link, link) { - dwl_wm_printstatus_to(m, mon); - } -} - -static void -dwl_wm_monitor_handle_set_tags(struct wl_client *client, struct wl_resource *resource, - uint32_t t, uint32_t toggle_tagset) -{ - DwlWmMonitor *mon; - Monitor *m; - mon = wl_resource_get_user_data(resource); - if (!mon) - return; - m = mon->monitor; - if ((t & TAGMASK) == m->tagset[m->seltags]) - return; - if (toggle_tagset) - m->seltags ^= 1; - if (t & TAGMASK) - m->tagset[m->seltags] = t & TAGMASK; - - focusclient(focustop(m), 1); - arrange(m); - printstatus(); -} - -static void -dwl_wm_monitor_handle_set_layout(struct wl_client *client, struct wl_resource *resource, - uint32_t layout) -{ - DwlWmMonitor *mon; - Monitor *m; - mon = wl_resource_get_user_data(resource); - if (!mon) - return; - m = mon->monitor; - if (layout >= LENGTH(layouts)) - return; - if (layout != m->lt[m->sellt] - layouts) - m->sellt ^= 1; - - m->lt[m->sellt] = &layouts[layout]; - arrange(m); - printstatus(); -} - -static void -dwl_wm_monitor_handle_set_client_tags(struct wl_client *client, struct wl_resource *resource, - uint32_t and, uint32_t xor) -{ - DwlWmMonitor *mon; - Client *sel; - unsigned int newtags; - mon = wl_resource_get_user_data(resource); - if (!mon) - return; - sel = focustop(mon->monitor); - if (!sel) - return; - newtags = (sel->tags & and) ^ xor; - if (newtags) { - sel->tags = newtags; - focusclient(focustop(selmon), 1); - arrange(selmon); - printstatus(); - } -} - -static const struct znet_tapesoftware_dwl_wm_monitor_v1_interface dwl_wm_monitor_implementation = { - .release = dwl_wm_monitor_handle_release, - .set_tags = dwl_wm_monitor_handle_set_tags, - .set_layout = dwl_wm_monitor_handle_set_layout, - .set_client_tags = dwl_wm_monitor_handle_set_client_tags, -}; - -/* dwl_wm_v1 */ -static void -dwl_wm_handle_release(struct wl_client *client, struct wl_resource *resource) -{ - wl_resource_destroy(resource); -} - -static void -dwl_wm_handle_get_monitor(struct wl_client *client, struct wl_resource *resource, - uint32_t id, struct wl_resource *output) -{ - DwlWmMonitor *dwl_wm_monitor; - struct wlr_output *wlr_output = wlr_output_from_resource(output); - struct Monitor *m = wlr_output->data; - struct wl_resource *dwlOutputResource = wl_resource_create(client, - &znet_tapesoftware_dwl_wm_monitor_v1_interface, wl_resource_get_version(resource), id); - if (!resource) { - wl_client_post_no_memory(client); - return; - } - dwl_wm_monitor = calloc(1, sizeof(DwlWmMonitor)); - dwl_wm_monitor->resource = dwlOutputResource; - dwl_wm_monitor->monitor = m; - wl_resource_set_implementation(dwlOutputResource, &dwl_wm_monitor_implementation, - dwl_wm_monitor, dwl_wm_monitor_handle_destroy); - wl_list_insert(&m->dwl_wm_monitor_link, &dwl_wm_monitor->link); - dwl_wm_printstatus_to(m, dwl_wm_monitor); -} - -static void -dwl_wm_handle_destroy(struct wl_resource *resource) -{ - /* no state to destroy */ -} - -static const struct znet_tapesoftware_dwl_wm_v1_interface dwl_wm_implementation = { - .release = dwl_wm_handle_release, - .get_monitor = dwl_wm_handle_get_monitor, -}; - -static void -dwl_wm_bind(struct wl_client *client, void *data, - uint32_t version, uint32_t id) -{ - struct wl_resource *resource = wl_resource_create(client, - &znet_tapesoftware_dwl_wm_v1_interface, version, id); - if (!resource) { - wl_client_post_no_memory(client); - return; - } - - wl_resource_set_implementation(resource, &dwl_wm_implementation, NULL, dwl_wm_handle_destroy); - - for (int i = 0; i < LENGTH(tags); i++) - znet_tapesoftware_dwl_wm_v1_send_tag(resource, tags[i]); - for (int i = 0; i < LENGTH(layouts); i++) - znet_tapesoftware_dwl_wm_v1_send_layout(resource, layouts[i].symbol); -} diff --git a/patches/attachbottom.patch b/patches/attachbottom.patch deleted file mode 100644 index 7c0ad52..0000000 --- a/patches/attachbottom.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 396531c8e7905cb226be0a4c3cddc60726fa2794 Mon Sep 17 00:00:00 2001 -From: Dmitry Zakharchenko <dmitz@disroot.org> -Date: Tue, 3 Jan 2023 20:01:34 +0200 -Subject: [PATCH] attachbottom: sync with 0.4 - ---- - dwl.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/dwl.c b/dwl.c -index 19bb6ce34..7f940c45f 100644 ---- a/dwl.c -+++ b/dwl.c -@@ -1511,7 +1511,11 @@ mapnotify(struct wl_listener *listener, void *data) - c->geom.height += 2 * c->bw; - - /* Insert this client into client lists. */ -- wl_list_insert(&clients, &c->link); -+ if (clients.prev) -+ // tile at the bottom -+ wl_list_insert(clients.prev, &c->link); -+ else -+ wl_list_insert(&clients, &c->link); - wl_list_insert(&fstack, &c->flink); - - /* Set initial monitor, tags, floating status, and focus: diff --git a/patches/autostart.patch b/patches/autostart.patch deleted file mode 100644 index 9efed3e..0000000 --- a/patches/autostart.patch +++ /dev/null @@ -1,147 +0,0 @@ -From 44044d45a32d4a0091422f4c803a4ddd98b7f7a9 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= - <leohdz172@proton.me> -Date: Sat, 8 Jul 2023 17:11:36 -0600 -Subject: [PATCH] port autostart patch from dwm - -https://dwm.suckless.org/patches/cool_autostart/ ---- - config.def.h | 7 +++++++ - dwl.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++----- - 2 files changed, 61 insertions(+), 5 deletions(-) - -diff --git a/config.def.h b/config.def.h -index db0babc..2b6a5ad 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -19,6 +19,13 @@ static const float fullscreen_bg[] = {0.1, 0.1, 0.1, 1.0}; /* You can al - /* logging */ - static int log_level = WLR_ERROR; - -+/* Autostart */ -+static const char *const autostart[] = { -+ "wbg", "/path/to/your/image", NULL, -+ NULL /* terminate */ -+}; -+ -+ - static const Rule rules[] = { - /* app_id title tags mask isfloating monitor */ - /* examples: -diff --git a/dwl.c b/dwl.c -index 6a96179..d387c06 100644 ---- a/dwl.c -+++ b/dwl.c -@@ -233,6 +233,7 @@ static void arrange(Monitor *m); - static void arrangelayer(Monitor *m, struct wl_list *list, - struct wlr_box *usable_area, int exclusive); - static void arrangelayers(Monitor *m); -+static void autostartexec(void); - static void axisnotify(struct wl_listener *listener, void *data); - static void buttonpress(struct wl_listener *listener, void *data); - static void chvt(const Arg *arg); -@@ -396,6 +397,9 @@ static xcb_atom_t netatom[NetLast]; - /* attempt to encapsulate suck into one file */ - #include "client.h" - -+static pid_t *autostart_pids; -+static size_t autostart_len; -+ - /* function implementations */ - void - applybounds(Client *c, struct wlr_box *bbox) -@@ -529,6 +533,27 @@ arrangelayers(Monitor *m) - } - } - -+void -+autostartexec(void) { -+ const char *const *p; -+ size_t i = 0; -+ -+ /* count entries */ -+ for (p = autostart; *p; autostart_len++, p++) -+ while (*++p); -+ -+ autostart_pids = calloc(autostart_len, sizeof(pid_t)); -+ for (p = autostart; *p; i++, p++) { -+ if ((autostart_pids[i] = fork()) == 0) { -+ setsid(); -+ execvp(*p, (char *const *)p); -+ die("dwl: execvp %s:", *p); -+ } -+ /* skip arguments */ -+ while (*++p); -+ } -+} -+ - void - axisnotify(struct wl_listener *listener, void *data) - { -@@ -624,11 +649,21 @@ checkidleinhibitor(struct wlr_surface *exclude) - void - cleanup(void) - { -+ size_t i; - #ifdef XWAYLAND - wlr_xwayland_destroy(xwayland); - xwayland = NULL; - #endif - wl_display_destroy_clients(dpy); -+ -+ /* kill child processes */ -+ for (i = 0; i < autostart_len; i++) { -+ if (0 < autostart_pids[i]) { -+ kill(autostart_pids[i], SIGTERM); -+ waitpid(autostart_pids[i], NULL, 0); -+ } -+ } -+ - if (child_pid > 0) { - kill(child_pid, SIGTERM); - waitpid(child_pid, NULL, 0); -@@ -1306,18 +1341,31 @@ void - handlesig(int signo) - { - if (signo == SIGCHLD) { --#ifdef XWAYLAND - siginfo_t in; - /* wlroots expects to reap the XWayland process itself, so we - * use WNOWAIT to keep the child waitable until we know it's not - * XWayland. - */ - while (!waitid(P_ALL, 0, &in, WEXITED|WNOHANG|WNOWAIT) && in.si_pid -- && (!xwayland || in.si_pid != xwayland->server->pid)) -- waitpid(in.si_pid, NULL, 0); --#else -- while (waitpid(-1, NULL, WNOHANG) > 0); -+#ifdef XWAYLAND -+ && (!xwayland || in.si_pid != xwayland->server->pid) - #endif -+ ) { -+ pid_t *p, *lim; -+ waitpid(in.si_pid, NULL, 0); -+ if (in.si_pid == child_pid) -+ child_pid = -1; -+ if (!(p = autostart_pids)) -+ continue; -+ lim = &p[autostart_len]; -+ -+ for (; p < lim; p++) { -+ if (*p == in.si_pid) { -+ *p = -1; -+ break; -+ } -+ } -+ } - } else if (signo == SIGINT || signo == SIGTERM) { - quit(NULL); - } -@@ -1973,6 +2021,7 @@ run(char *startup_cmd) - die("startup: backend_start"); - - /* Now that the socket exists and the backend is started, run the startup command */ -+ autostartexec(); - if (startup_cmd) { - int piperw[2]; - if (pipe(piperw) < 0) diff --git a/patches/ipc-v2-fixed-wlroots17.patch b/patches/ipc-v2-fixed-wlroots17.patch deleted file mode 100644 index 692f8d2..0000000 --- a/patches/ipc-v2-fixed-wlroots17.patch +++ /dev/null @@ -1,593 +0,0 @@ -commit 49cfa08b1e1864f8830cb2a56ee6464c8497cc4f -Author: Nicola Ferru Aka NFVblog <ask.nfvblog@outlook.it> -Date: Wed Nov 29 22:56:27 2023 +0100 - - ipc-v2-wlroots-0.17 - -diff --git a/Makefile b/Makefile -index 6cde460..8b1ec23 100644 ---- a/Makefile -+++ b/Makefile -@@ -14,11 +14,14 @@ 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 cursor-shape-v1-protocol.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 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 - # to your build system yourself and provide them in the include path. -@@ -34,6 +37,12 @@ wlr-layer-shell-unstable-v1-protocol.h: - cursor-shape-v1-protocol.h: - $(WAYLAND_SCANNER) server-header \ - $(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/dwl-ipc-unstable-v2.xml $@ - - config.h: - cp config.def.h $@ -diff --git a/config.def.h b/config.def.h -index db0babc..501e6af 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -129,6 +129,7 @@ static const Key keys[] = { - { MODKEY, XKB_KEY_Return, zoom, {0} }, - { MODKEY, XKB_KEY_Tab, view, {0} }, - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_C, killclient, {0} }, -+ { MODKEY, XKB_KEY_b, togglebar, {0}}, - { MODKEY, XKB_KEY_t, setlayout, {.v = &layouts[0]} }, - { MODKEY, XKB_KEY_f, setlayout, {.v = &layouts[1]} }, - { MODKEY, XKB_KEY_m, setlayout, {.v = &layouts[2]} }, -diff --git a/dwl.c b/dwl.c -index ef27a1d..20b8c9d 100644 ---- a/dwl.c -+++ b/dwl.c -@@ -59,6 +59,7 @@ - #include <xcb/xcb_icccm.h> - #endif - -+#include "dwl-ipc-unstable-v2-protocol.h" - #include "util.h" - - /* macros */ -@@ -132,6 +133,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; -@@ -178,6 +185,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 */ -@@ -261,6 +269,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); -@@ -310,6 +329,7 @@ static void spawn(const Arg *arg); - static void startdrag(struct wl_listener *listener, void *data); - static void tag(const Arg *arg); - static void tagmon(const Arg *arg); -+static void togglebar(const Arg *arg); - static void tile(Monitor *m); - static void togglefloating(const Arg *arg); - static void togglefullscreen(const Arg *arg); -@@ -365,6 +385,8 @@ static struct wlr_session_lock_manager_v1 *session_lock_mgr; - static struct wlr_scene_rect *locked_bg; - static struct wlr_session_lock_v1 *cur_lock; - static struct wl_listener lock_listener = {.notify = locksession}; -+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 wlr_seat *seat; - static struct wl_list keyboards; -@@ -661,6 +683,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); -@@ -677,6 +702,7 @@ cleanupmon(struct wl_listener *listener, void *data) - free(m); - } - -+ - void - closemon(Monitor *m) - { -@@ -875,6 +901,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 */ -@@ -1170,6 +1197,191 @@ 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) - { -@@ -1818,41 +2030,8 @@ 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 -@@ -2343,6 +2522,7 @@ setup(void) - LISTEN_STATIC(&output_mgr->events.test, outputmgrtest); - - 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 - /* -@@ -2437,6 +2617,14 @@ 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> diff --git a/patches/naturalscrolltrackpad.patch b/patches/naturalscrolltrackpad.patch deleted file mode 100644 index 5cd3742..0000000 --- a/patches/naturalscrolltrackpad.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 8b523453aefdc9d2920c8f9a52de009da251fbb0 Mon Sep 17 00:00:00 2001 -From: neuromagus <neuromagus@mail.ru> -Date: Sun, 7 Jan 2024 05:11:24 +0300 -Subject: [PATCH] apply patch naturalscrolltrackpad - ---- - dwl.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - -diff --git a/dwl.c b/dwl.c -index 4d19357..26f394b 100644 ---- a/dwl.c -+++ b/dwl.c -@@ -974,11 +974,10 @@ createpointer(struct wlr_pointer *pointer) - libinput_device_config_tap_set_drag_enabled(device, tap_and_drag); - libinput_device_config_tap_set_drag_lock_enabled(device, drag_lock); - libinput_device_config_tap_set_button_map(device, button_map); -+ if (libinput_device_config_scroll_has_natural_scroll(device)) -+ libinput_device_config_scroll_set_natural_scroll_enabled(device, natural_scrolling); - } - -- if (libinput_device_config_scroll_has_natural_scroll(device)) -- libinput_device_config_scroll_set_natural_scroll_enabled(device, natural_scrolling); -- - if (libinput_device_config_dwt_is_available(device)) - libinput_device_config_dwt_set_enabled(device, disable_while_typing); - diff --git a/patches/pertag.patch b/patches/pertag.patch deleted file mode 100644 index a0c66d8..0000000 --- a/patches/pertag.patch +++ /dev/null @@ -1,167 +0,0 @@ -From 8750e1255f6c8b799165186cd6cfdfa7af3ee56d Mon Sep 17 00:00:00 2001 -From: mortezadadgar <mortezadadgar97@gmail.com> -Date: Sat, 26 Aug 2023 20:37:22 +0330 -Subject: [PATCH] Applied pertag - ---- - dwl.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---- - 1 file changed, 70 insertions(+), 5 deletions(-) - -diff --git a/dwl.c b/dwl.c -index 4ff5c37f7..6c104bbb0 100644 ---- a/dwl.c -+++ b/dwl.c -@@ -94,6 +94,7 @@ typedef struct { - const Arg arg; - } Button; - -+typedef struct Pertag Pertag; - typedef struct Monitor Monitor; - typedef struct { - /* Must keep these three elements in this order */ -@@ -185,6 +186,7 @@ struct Monitor { - struct wlr_box w; /* window area, layout-relative */ - struct wl_list layers[4]; /* LayerSurface::link */ - const Layout *lt[2]; -+ Pertag *pertag; - unsigned int seltags; - unsigned int sellt; - uint32_t tagset[2]; -@@ -413,6 +415,14 @@ static Atom netatom[NetLast]; - /* attempt to encapsulate suck into one file */ - #include "client.h" - -+struct Pertag { -+ unsigned int curtag, prevtag; /* current and previous tag */ -+ int nmasters[TAGCOUNT + 1]; /* number of windows in master area */ -+ float mfacts[TAGCOUNT + 1]; /* mfacts per tag */ -+ unsigned int sellts[TAGCOUNT + 1]; /* selected layouts */ -+ const Layout *ltidxs[TAGCOUNT + 1][2]; /* matrix of tags and layouts indexes */ -+}; -+ - /* function implementations */ - void - applybounds(Client *c, struct wlr_box *bbox) -@@ -703,6 +713,7 @@ cleanupmon(struct wl_listener *listener, void *data) - wlr_scene_output_destroy(m->scene_output); - wlr_scene_node_destroy(&m->fullscreen_bg->node); - -+ free(m->pertag); - closemon(m); - free(m); - } -@@ -944,6 +955,18 @@ createmon(struct wl_listener *listener, void *data) - wl_list_insert(&mons, &m->link); - printstatus(); - -+ m->pertag = calloc(1, sizeof(Pertag)); -+ m->pertag->curtag = m->pertag->prevtag = 1; -+ -+ for (i = 0; i <= TAGCOUNT; i++) { -+ m->pertag->nmasters[i] = m->nmaster; -+ m->pertag->mfacts[i] = m->mfact; -+ -+ m->pertag->ltidxs[i][0] = m->lt[0]; -+ m->pertag->ltidxs[i][1] = m->lt[1]; -+ m->pertag->sellts[i] = m->sellt; -+ } -+ - /* The xdg-protocol specifies: - * - * If the fullscreened surface is not opaque, the compositor must make -@@ -1355,7 +1378,7 @@ incnmaster(const Arg *arg) - { - if (!arg || !selmon) - return; -- selmon->nmaster = MAX(selmon->nmaster + arg->i, 0); -+ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag] = MAX(selmon->nmaster + arg->i, 0); - arrange(selmon); - } - -@@ -2060,9 +2083,9 @@ setlayout(const Arg *arg) - if (!selmon) - return; - if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) -- selmon->sellt ^= 1; -+ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag] ^= 1; - if (arg && arg->v) -- selmon->lt[selmon->sellt] = (Layout *)arg->v; -+ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt] = (Layout *)arg->v; - strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, LENGTH(selmon->ltsymbol)); - arrange(selmon); - printstatus(); -@@ -2079,7 +2102,7 @@ setmfact(const Arg *arg) - f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; - if (f < 0.1 || f > 0.9) - return; -- selmon->mfact = f; -+ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag] = f; - arrange(selmon); - } - -@@ -2423,10 +2446,30 @@ void - toggleview(const Arg *arg) - { - uint32_t newtagset = selmon ? selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK) : 0; -+ size_t i; - - if (!newtagset) - return; - -+ if (newtagset == ~0) { -+ selmon->pertag->prevtag = selmon->pertag->curtag; -+ selmon->pertag->curtag = 0; -+ } -+ -+ /* test if the user did not select the same tag */ -+ if (!(newtagset & 1 << (selmon->pertag->curtag - 1))) { -+ selmon->pertag->prevtag = selmon->pertag->curtag; -+ for (i = 0; !(newtagset & 1 << i); i++) ; -+ selmon->pertag->curtag = i + 1; -+ } -+ -+ /* apply settings for this view */ -+ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag]; -+ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag]; -+ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; -+ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; -+ selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; -+ - selmon->tagset[selmon->seltags] = newtagset; - focusclient(focustop(selmon), 1); - arrange(selmon); -@@ -2596,11 +2639,33 @@ urgent(struct wl_listener *listener, void *data) - void - view(const Arg *arg) - { -+ size_t i, tmptag; -+ - if (!selmon || (arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) - return; - selmon->seltags ^= 1; /* toggle sel tagset */ -- if (arg->ui & TAGMASK) -+ if (arg->ui & TAGMASK) { - selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; -+ selmon->pertag->prevtag = selmon->pertag->curtag; -+ -+ if (arg->ui == ~0) -+ selmon->pertag->curtag = 0; -+ else { -+ for (i = 0; !(arg->ui & 1 << i); i++) ; -+ selmon->pertag->curtag = i + 1; -+ } -+ } else { -+ tmptag = selmon->pertag->prevtag; -+ selmon->pertag->prevtag = selmon->pertag->curtag; -+ selmon->pertag->curtag = tmptag; -+ } -+ -+ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag]; -+ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag]; -+ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; -+ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; -+ selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; -+ - focusclient(focustop(selmon), 1); - arrange(selmon); - printstatus(); diff --git a/patches/smartborders.patch b/patches/smartborders.patch deleted file mode 100644 index 98dafe3..0000000 --- a/patches/smartborders.patch +++ /dev/null @@ -1,203 +0,0 @@ -From c7120b651b1a6f1ae3277088d4de9af9686c71ae Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= - <leohdz172@protonmail.com> -Date: Tue, 16 Aug 2022 15:28:00 -0500 -Subject: [PATCH] don't draw borders if there is only one window -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Co-authored-by: A Frederick Christensen <dwl@ivories.org> -Co-authored-by: Andrey Proskurin <andreyproskurin@protonmail.com> -Signed-off-by: Leonardo Hernández Hernández <leohdz172@proton.me> ---- - config.def.h | 1 + - dwl.c | 48 ++++++++++++++++++++++++++++++++---------------- - 2 files changed, 33 insertions(+), 16 deletions(-) - -diff --git a/config.def.h b/config.def.h -index a8ed61d..f07cf07 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -6,6 +6,7 @@ - /* appearance */ - 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 smartborders = 1; - static const unsigned int borderpx = 1; /* border pixel of windows */ - static const float rootcolor[] = COLOR(0x222222ff); - static const float bordercolor[] = COLOR(0x444444ff); -diff --git a/dwl.c b/dwl.c -index 10d5a5b..903afc6 100644 ---- a/dwl.c -+++ b/dwl.c -@@ -297,7 +297,7 @@ static void rendermon(struct wl_listener *listener, void *data); - static void requestdecorationmode(struct wl_listener *listener, void *data); - static void requeststartdrag(struct wl_listener *listener, void *data); - static void requestmonstate(struct wl_listener *listener, void *data); --static void resize(Client *c, struct wlr_box geo, int interact); -+static void resize(Client *c, struct wlr_box geo, int interact, int draw_borders); - static void run(char *startup_cmd); - static void setcursor(struct wl_listener *listener, void *data); - static void setcursorshape(struct wl_listener *listener, void *data); -@@ -696,7 +696,7 @@ closemon(Monitor *m) - wl_list_for_each(c, &clients, link) { - if (c->isfloating && c->geom.x > m->m.width) - resize(c, (struct wlr_box){.x = c->geom.x - m->w.width, .y = c->geom.y, -- .width = c->geom.width, .height = c->geom.height}, 0); -+ .width = c->geom.width, .height = c->geom.height}, 0, 1); - if (c->mon == m) - setmon(c, selmon, c->tags); - } -@@ -731,8 +731,12 @@ commitnotify(struct wl_listener *listener, void *data) - { - Client *c = wl_container_of(listener, c, commit); - -- if (client_surface(c)->mapped) -- resize(c, c->geom, (c->isfloating && !c->isfullscreen)); -+ if (client_surface(c)->mapped) { -+ if (c->mon && c->mon->lt[c->mon->sellt]->arrange && !c->isfullscreen && !c->isfloating) -+ c->mon->lt[c->mon->sellt]->arrange(c->mon); -+ else -+ resize(c, c->geom, (c->isfloating && !c->isfullscreen), (c->isfloating && !c->isfullscreen)); -+ } - - /* mark a pending resize as completed */ - if (c->resize && c->resize <= c->surface.xdg->current.configure_serial) -@@ -1579,7 +1583,7 @@ monocle(Monitor *m) - wl_list_for_each(c, &clients, link) { - if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen) - continue; -- resize(c, m->w, 0); -+ resize(c, m->w, 0, !smartborders); - n++; - } - if (n) -@@ -1626,11 +1630,11 @@ motionnotify(uint32_t time) - if (cursor_mode == CurMove) { - /* Move the grabbed client to the new position. */ - resize(grabc, (struct wlr_box){.x = cursor->x - grabcx, .y = cursor->y - grabcy, -- .width = grabc->geom.width, .height = grabc->geom.height}, 1); -+ .width = grabc->geom.width, .height = grabc->geom.height}, 1, 1); - return; - } else if (cursor_mode == CurResize) { - resize(grabc, (struct wlr_box){.x = grabc->geom.x, .y = grabc->geom.y, -- .width = cursor->x - grabc->geom.x, .height = cursor->y - grabc->geom.y}, 1); -+ .width = cursor->x - grabc->geom.x, .height = cursor->y - grabc->geom.y}, 1, 1); - return; - } - -@@ -1924,12 +1928,13 @@ requestmonstate(struct wl_listener *listener, void *data) - } - - void --resize(Client *c, struct wlr_box geo, int interact) -+resize(Client *c, struct wlr_box geo, int interact, int draw_borders) - { - struct wlr_box *bbox = interact ? &sgeom : &c->mon->w; - struct wlr_box clip; - client_set_bounds(c, geo.width, geo.height); - c->geom = geo; -+ c->bw = draw_borders ? borderpx : 0; - applybounds(c, bbox); - - /* Update scene-graph, including borders */ -@@ -2044,6 +2049,8 @@ setfloating(Client *c, int floating) - return; - wlr_scene_node_reparent(&c->scene->node, layers[c->isfullscreen - ? LyrFS : c->isfloating ? LyrFloat : LyrTile]); -+ if (c->isfloating && !c->bw) -+ resize(c, c->mon->m, 0, 1); - arrange(c->mon); - printstatus(); - } -@@ -2061,11 +2068,11 @@ setfullscreen(Client *c, int fullscreen) - - if (fullscreen) { - c->prev = c->geom; -- resize(c, c->mon->m, 0); -+ resize(c, c->mon->m, 0, 0); - } else { - /* restore previous size instead of arrange for floating windows since - * client positions are set by the user and cannot be recalculated */ -- resize(c, c->prev, 0); -+ resize(c, c->prev, 0, 1); - } - arrange(c->mon); - printstatus(); -@@ -2090,6 +2097,12 @@ setlayout(const Arg *arg) - if (arg && arg->v) - selmon->lt[selmon->sellt] = (Layout *)arg->v; - strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, LENGTH(selmon->ltsymbol)); -+ if (!selmon->lt[selmon->sellt]->arrange) { -+ /* floating layout, draw borders around all clients */ -+ Client *c; -+ wl_list_for_each(c, &clients, link) -+ resize(c, c->mon->m, 0, 1); -+ } - arrange(selmon); - printstatus(); - } -@@ -2124,7 +2137,7 @@ setmon(Client *c, Monitor *m, uint32_t newtags) - arrange(oldmon); - if (m) { - /* Make sure window actually overlaps with the monitor */ -- resize(c, c->geom, 0); -+ resize(c, c->geom, 0, 1); - c->tags = newtags ? newtags : m->tagset[m->seltags]; /* assign tags of target monitor */ - setfullscreen(c, c->isfullscreen); /* This will call arrange(c->mon) */ - setfloating(c, c->isfloating); -@@ -2452,7 +2465,7 @@ tagmon(const Arg *arg) - void - tile(Monitor *m) - { -- unsigned int i, n = 0, mw, my, ty; -+ unsigned int i, n = 0, mw, my, ty, draw_borders = 1; - Client *c; - - wl_list_for_each(c, &clients, link) -@@ -2461,6 +2474,9 @@ tile(Monitor *m) - if (n == 0) - return; - -+ if (n == smartborders) -+ draw_borders = 0; -+ - if (n > m->nmaster) - mw = m->nmaster ? m->w.width * m->mfact : 0; - else -@@ -2471,11 +2487,11 @@ tile(Monitor *m) - continue; - if (i < m->nmaster) { - resize(c, (struct wlr_box){.x = m->w.x, .y = m->w.y + my, .width = mw, -- .height = (m->w.height - my) / (MIN(n, m->nmaster) - i)}, 0); -+ .height = (m->w.height - my) / (MIN(n, m->nmaster) - i)}, 0, draw_borders); - my += c->geom.height; - } else { - resize(c, (struct wlr_box){.x = m->w.x + mw, .y = m->w.y + ty, -- .width = m->w.width - mw, .height = (m->w.height - ty) / (n - i)}, 0); -+ .width = m->w.width - mw, .height = (m->w.height - ty) / (n - i)}, 0, draw_borders); - ty += c->geom.height; - } - i++; -@@ -2644,7 +2660,7 @@ updatemons(struct wl_listener *listener, void *data) - arrange(m); - /* make sure fullscreen clients have the right size */ - if ((c = focustop(m)) && c->isfullscreen) -- resize(c, m->m, 0); -+ resize(c, m->m, 0, 0); - - /* Try to re-set the gamma LUT when updating monitors, - * it's only really needed when enabling a disabled output, but meh. */ -@@ -2826,7 +2842,7 @@ configurex11(struct wl_listener *listener, void *data) - return; - if (c->isfloating || client_is_unmanaged(c)) - resize(c, (struct wlr_box){.x = event->x, .y = event->y, -- .width = event->width, .height = event->height}, 0); -+ .width = event->width, .height = event->height}, 0, 1); - else - arrange(c->mon); - } --- -2.43.0 - diff --git a/patches/wayland-ipc.patch b/patches/wayland-ipc.patch deleted file mode 100644 index 5283eaa..0000000 --- a/patches/wayland-ipc.patch +++ /dev/null @@ -1,498 +0,0 @@ -Add wayland protocol extenion for controlling dwl - -This adds a wayland protocol extension that allows clients to observe and control the window management state. - -Supported features: - * observing/updating active tags and layout - * observing the selected output and client - * updating the tags of the selected client - -This patch adds the .xml file and feeds it into wayland-scanner. - -Co-authored-by: Palanix <palanixyt@gmail.com> -diff --git a/Makefile b/Makefile -index ccca079..d72dea8 100644 ---- a/Makefile -+++ b/Makefile -@@ -14,9 +14,9 @@ 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 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.o - util.o: util.c util.h - - # wayland-scanner is a tool which generates C headers and rigging for Wayland -@@ -32,6 +32,14 @@ wlr-layer-shell-unstable-v1-protocol.h: - $(WAYLAND_SCANNER) server-header \ - protocols/wlr-layer-shell-unstable-v1.xml $@ - -+net-tapesoftware-dwl-wm-unstable-v1-protocol.h: protocols/net-tapesoftware-dwl-wm-unstable-v1.xml -+ $(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_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 -+ - config.h: - cp config.def.h $@ - clean: -diff --git a/dwl.c b/dwl.c -index 8043bf9..f2977fc 100644 ---- a/dwl.c -+++ b/dwl.c -@@ -52,6 +52,7 @@ - #include <wlr/types/wlr_xdg_shell.h> - #include <wlr/util/log.h> - #include <xkbcommon/xkbcommon.h> -+#include "net-tapesoftware-dwl-wm-unstable-v1-protocol.h" - #ifdef XWAYLAND - #include <wlr/xwayland.h> - #include <X11/Xlib.h> -@@ -172,6 +173,12 @@ typedef struct { - void (*arrange)(Monitor *); - } Layout; - -+typedef struct { -+ struct wl_list link; -+ struct wl_resource *resource; -+ struct Monitor *monitor; -+} DwlWmMonitor; -+ - struct Monitor { - struct wl_list link; - struct wlr_output *wlr_output; -@@ -184,6 +191,7 @@ struct Monitor { - struct wlr_box m; /* monitor area, layout-relative */ - struct wlr_box w; /* window area, layout-relative */ - struct wl_list layers[4]; /* LayerSurface::link */ -+ struct wl_list dwl_wm_monitor_link; - const Layout *lt[2]; - unsigned int seltags; - unsigned int sellt; -@@ -318,6 +326,10 @@ static struct wlr_scene_node *xytonode(double x, double y, struct wlr_surface ** - Client **pc, LayerSurface **pl, double *nx, double *ny); - static void zoom(const Arg *arg); - -+static void dwl_wm_bind(struct wl_client *client, void *data, -+ uint32_t version, uint32_t id); -+static void dwl_wm_printstatus(Monitor *monitor); -+ - /* variables */ - static const char broken[] = "broken"; - static const char *cursor_image = "left_ptr"; -@@ -685,6 +697,7 @@ void - cleanupmon(struct wl_listener *listener, void *data) - { - Monitor *m = wl_container_of(listener, m, destroy); -+ DwlWmMonitor *mon, *montmp; - LayerSurface *l, *tmp; - int i; - -@@ -697,6 +710,10 @@ cleanupmon(struct wl_listener *listener, void *data) - wl_list_remove(&m->link); - m->wlr_output->data = NULL; - wlr_output_layout_remove(output_layout, m->wlr_output); -+ wl_list_for_each_safe(mon, montmp, &m->dwl_wm_monitor_link, link) { -+ wl_resource_set_user_data(mon->resource, NULL); -+ free(mon); -+ } - wlr_scene_output_destroy(m->scene_output); - wlr_scene_node_destroy(&m->fullscreen_bg->node); - -@@ -903,6 +920,7 @@ createmon(struct wl_listener *listener, void *data) - const MonitorRule *r; - size_t i; - Monitor *m = wlr_output->data = ecalloc(1, sizeof(*m)); -+ wl_list_init(&m->dwl_wm_monitor_link); - m->wlr_output = wlr_output; - - wlr_output_init_render(wlr_output, alloc, drw); -@@ -1852,6 +1870,7 @@ printstatus(void) - 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->lt[m->sellt]->symbol); -+ dwl_wm_printstatus(m); - } - fflush(stdout); - } -@@ -2289,6 +2308,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, &znet_tapesoftware_dwl_wm_v1_interface, 1, NULL, dwl_wm_bind); - - #ifdef XWAYLAND - /* -@@ -2828,3 +2848,193 @@ main(int argc, char *argv[]) - usage: - die("Usage: %s [-v] [-s startup command]", argv[0]); - } -+ -+/* dwl_wm_monitor_v1 */ -+static void -+dwl_wm_monitor_handle_release(struct wl_client *client, struct wl_resource *resource) -+{ -+ wl_resource_destroy(resource); -+} -+ -+static void -+dwl_wm_monitor_handle_destroy(struct wl_resource *resource) -+{ -+ DwlWmMonitor *mon = wl_resource_get_user_data(resource); -+ if (mon) { -+ wl_list_remove(&mon->link); -+ free(mon); -+ } -+} -+ -+static void -+dwl_wm_printstatus_to(Monitor *m, const DwlWmMonitor *mon) -+{ -+ Client *c, *focused; -+ int tagmask, state, numclients, focused_client; -+ focused = focustop(m); -+ znet_tapesoftware_dwl_wm_monitor_v1_send_selected(mon->resource, m == selmon); -+ -+ for (int tag = 0; tag<LENGTH(tags); tag++) { -+ numclients = state = 0; -+ focused_client = -1; -+ tagmask = 1 << tag; -+ if ((tagmask & m->tagset[m->seltags]) != 0) -+ state = state | ZNET_TAPESOFTWARE_DWL_WM_MONITOR_V1_TAG_STATE_ACTIVE; -+ wl_list_for_each(c, &clients, link) { -+ if (c->mon != m) -+ continue; -+ if (!(c->tags & tagmask)) -+ continue; -+ if (c == focused) -+ focused_client = numclients; -+ numclients++; -+ if (c->isurgent) -+ state = state | ZNET_TAPESOFTWARE_DWL_WM_MONITOR_V1_TAG_STATE_URGENT; -+ } -+ znet_tapesoftware_dwl_wm_monitor_v1_send_tag(mon->resource, -+ tag, state, numclients, focused_client); -+ } -+ znet_tapesoftware_dwl_wm_monitor_v1_send_layout(mon->resource, m->lt[m->sellt] - layouts); -+ znet_tapesoftware_dwl_wm_monitor_v1_send_title(mon->resource, -+ focused ? client_get_title(focused) : ""); -+ znet_tapesoftware_dwl_wm_monitor_v1_send_frame(mon->resource); -+} -+ -+static void -+dwl_wm_printstatus(Monitor *m) -+{ -+ DwlWmMonitor *mon; -+ wl_list_for_each(mon, &m->dwl_wm_monitor_link, link) { -+ dwl_wm_printstatus_to(m, mon); -+ } -+} -+ -+static void -+dwl_wm_monitor_handle_set_tags(struct wl_client *client, struct wl_resource *resource, -+ uint32_t t, uint32_t toggle_tagset) -+{ -+ DwlWmMonitor *mon; -+ Monitor *m; -+ mon = wl_resource_get_user_data(resource); -+ if (!mon) -+ return; -+ m = mon->monitor; -+ if ((t & TAGMASK) == m->tagset[m->seltags]) -+ return; -+ if (toggle_tagset) -+ m->seltags ^= 1; -+ if (t & TAGMASK) -+ m->tagset[m->seltags] = t & TAGMASK; -+ -+ focusclient(focustop(m), 1); -+ arrange(m); -+ printstatus(); -+} -+ -+static void -+dwl_wm_monitor_handle_set_layout(struct wl_client *client, struct wl_resource *resource, -+ uint32_t layout) -+{ -+ DwlWmMonitor *mon; -+ Monitor *m; -+ mon = wl_resource_get_user_data(resource); -+ if (!mon) -+ return; -+ m = mon->monitor; -+ if (layout >= LENGTH(layouts)) -+ return; -+ if (layout != m->lt[m->sellt] - layouts) -+ m->sellt ^= 1; -+ -+ m->lt[m->sellt] = &layouts[layout]; -+ arrange(m); -+ printstatus(); -+} -+ -+static void -+dwl_wm_monitor_handle_set_client_tags(struct wl_client *client, struct wl_resource *resource, -+ uint32_t and, uint32_t xor) -+{ -+ DwlWmMonitor *mon; -+ Client *sel; -+ unsigned int newtags; -+ mon = wl_resource_get_user_data(resource); -+ if (!mon) -+ return; -+ sel = focustop(mon->monitor); -+ if (!sel) -+ return; -+ newtags = (sel->tags & and) ^ xor; -+ if (newtags) { -+ sel->tags = newtags; -+ focusclient(focustop(selmon), 1); -+ arrange(selmon); -+ printstatus(); -+ } -+} -+ -+static const struct znet_tapesoftware_dwl_wm_monitor_v1_interface dwl_wm_monitor_implementation = { -+ .release = dwl_wm_monitor_handle_release, -+ .set_tags = dwl_wm_monitor_handle_set_tags, -+ .set_layout = dwl_wm_monitor_handle_set_layout, -+ .set_client_tags = dwl_wm_monitor_handle_set_client_tags, -+}; -+ -+/* dwl_wm_v1 */ -+static void -+dwl_wm_handle_release(struct wl_client *client, struct wl_resource *resource) -+{ -+ wl_resource_destroy(resource); -+} -+ -+static void -+dwl_wm_handle_get_monitor(struct wl_client *client, struct wl_resource *resource, -+ uint32_t id, struct wl_resource *output) -+{ -+ DwlWmMonitor *dwl_wm_monitor; -+ struct wlr_output *wlr_output = wlr_output_from_resource(output); -+ struct Monitor *m = wlr_output->data; -+ struct wl_resource *dwlOutputResource = wl_resource_create(client, -+ &znet_tapesoftware_dwl_wm_monitor_v1_interface, wl_resource_get_version(resource), id); -+ if (!resource) { -+ wl_client_post_no_memory(client); -+ return; -+ } -+ dwl_wm_monitor = calloc(1, sizeof(DwlWmMonitor)); -+ dwl_wm_monitor->resource = dwlOutputResource; -+ dwl_wm_monitor->monitor = m; -+ wl_resource_set_implementation(dwlOutputResource, &dwl_wm_monitor_implementation, -+ dwl_wm_monitor, dwl_wm_monitor_handle_destroy); -+ wl_list_insert(&m->dwl_wm_monitor_link, &dwl_wm_monitor->link); -+ dwl_wm_printstatus_to(m, dwl_wm_monitor); -+} -+ -+static void -+dwl_wm_handle_destroy(struct wl_resource *resource) -+{ -+ /* no state to destroy */ -+} -+ -+static const struct znet_tapesoftware_dwl_wm_v1_interface dwl_wm_implementation = { -+ .release = dwl_wm_handle_release, -+ .get_monitor = dwl_wm_handle_get_monitor, -+}; -+ -+static void -+dwl_wm_bind(struct wl_client *client, void *data, -+ uint32_t version, uint32_t id) -+{ -+ struct wl_resource *resource = wl_resource_create(client, -+ &znet_tapesoftware_dwl_wm_v1_interface, version, id); -+ if (!resource) { -+ wl_client_post_no_memory(client); -+ return; -+ } -+ -+ wl_resource_set_implementation(resource, &dwl_wm_implementation, NULL, dwl_wm_handle_destroy); -+ -+ for (int i = 0; i < LENGTH(tags); i++) -+ znet_tapesoftware_dwl_wm_v1_send_tag(resource, tags[i]); -+ for (int i = 0; i < LENGTH(layouts); i++) -+ znet_tapesoftware_dwl_wm_v1_send_layout(resource, layouts[i].symbol); -+} -diff --git a/protocols/net-tapesoftware-dwl-wm-unstable-v1.xml b/protocols/net-tapesoftware-dwl-wm-unstable-v1.xml -new file mode 100644 -index 0000000..4fe5b73 ---- /dev/null -+++ b/protocols/net-tapesoftware-dwl-wm-unstable-v1.xml -@@ -0,0 +1,164 @@ -+<?xml version="1.0" encoding="UTF-8"?> -+<protocol name="net_tapesoftware_dwl_wm_unstable_v1"> -+ <copyright> -+ Copyright (c) 2021 Raphael Robatsch -+ -+ 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> -+ -+ <interface name="znet_tapesoftware_dwl_wm_v1" version="1"> -+ <description summary="control the dwl state"> -+ This interface is exposed as a global in the wl_registry. -+ -+ Clients can use this protocol to receive updates of the window manager -+ state (active tags, active layout, and focused window). -+ Clients can also control this state. -+ -+ After binding, the client will receive the available tags and layouts -+ with the 'tag' and 'layout' events. These can be used in subsequent -+ dwl_wm_monitor_v1.set_tags/set_layout requests, and to interpret the -+ dwl_wm_monitor_v1.layout/tag events. -+ </description> -+ -+ <request name="release" type="destructor"> -+ <description summary="release dwl_wm"> -+ This request indicates that the client will not use the dwl_wm -+ object any more. Objects that have been created through this instance -+ are not affected. -+ </description> -+ </request> -+ -+ <request name="get_monitor"> -+ <description summary="gets a dwl monitor from an output"> -+ Gets a dwl monitor for the specified output. The window manager -+ state on the output can be controlled using the monitor. -+ </description> -+ <arg name="id" type="new_id" interface="znet_tapesoftware_dwl_wm_monitor_v1" /> -+ <arg name="output" type="object" interface="wl_output" /> -+ </request> -+ -+ <event name="tag"> -+ <description summary="announces the presence of a tag"> -+ This event is sent immediately after binding. -+ A roundtrip after binding guarantees that the client has received all tags. -+ </description> -+ <arg name="name" type="string"/> -+ </event> -+ -+ <event name="layout"> -+ <description summary="announces the presence of a layout"> -+ This event is sent immediately after binding. -+ A roundtrip after binding guarantees that the client has received all layouts. -+ </description> -+ <arg name="name" type="string"/> -+ </event> -+ </interface> -+ -+ <interface name="znet_tapesoftware_dwl_wm_monitor_v1" version="1"> -+ <description summary="control one monitor"> -+ Observes and controls one monitor. -+ -+ Events are double-buffered: Clients should cache all events and only -+ redraw themselves once the 'frame' event is sent. -+ -+ Requests are not double-buffered: The compositor will update itself -+ immediately. -+ </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_monitor"> -+ This request indicates that the client is done with this dwl_monitor. -+ All further requests are ignored. -+ </description> -+ </request> -+ -+ <event name="selected"> -+ <description summary="updates the selected state of the monitor"> -+ If 'selected' is nonzero, this monitor is the currently selected one. -+ </description> -+ <arg name="selected" type="uint"/> -+ </event> -+ -+ <event name="tag"> -+ <description summary="updates the state of one tag"> -+ Announces the update of a tag. num_clients and focused_client can be -+ used to draw client indicators. -+ </description> -+ <arg name="tag" type="uint" summary="index of a tag received by the dwl_wm_v1.tag event." /> -+ <arg name="state" type="uint" enum="tag_state"/> -+ <arg name="num_clients" type="uint" summary="number of clients on this tag"/> -+ <arg name="focused_client" type="int" summary="out of num_clients. -1 if there is no focused client"/> -+ </event> -+ -+ <event name="layout"> -+ <description summary="updates the selected layout"> -+ Announces the update of the selected layout. -+ </description> -+ <arg name="layout" type="uint" summary="index of a layout received by the dwl_wm_v1.layout event."/> -+ </event> -+ -+ <event name="title"> -+ <description summary="updates the focused client"> -+ Announces the update of the selected client. -+ </description> -+ <arg name="title" type="string"/> -+ </event> -+ -+ <event name="frame"> -+ <description summary="end of status update sequence"> -+ Sent after all other events belonging to the status update has been sent. -+ Clients should redraw themselves now. -+ </description> -+ </event> -+ -+ <request name="set_tags"> -+ <description summary="sets the active tags on this monitor."> -+ Changes are applied immediately. -+ </description> -+ <arg name="tagmask" type="uint" summary="bitmask of the tags that should be set."/> -+ <arg name="toggle_tagset" type="uint"/> -+ </request> -+ -+ <request name="set_client_tags"> -+ <description summary="updates the tags of the focused client."> -+ tags are updated as follows: -+ new_tags = (current_tags AND and_tags) XOR xor_tags -+ -+ Changes are applied immediately. -+ </description> -+ <arg name="and_tags" type="uint"/> -+ <arg name="xor_tags" type="uint"/> -+ </request> -+ -+ <request name="set_layout"> -+ <description summary="sets the active layout on this monitor."> -+ Changes are applied immediately. -+ </description> -+ <arg name="layout" type="uint" summary="index of a layout received by the dwl_wm_v1.layout event."/> -+ </request> -+ </interface> -+</protocol> --- -2.39.1 - diff --git a/protocols/dwl-ipc-unstable-v2.xml b/protocols/dwl-ipc-unstable-v2.xml deleted file mode 100644 index 0a6e7e5..0000000 --- a/protocols/dwl-ipc-unstable-v2.xml +++ /dev/null @@ -1,181 +0,0 @@ -<?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> diff --git a/protocols/net-tapesoftware-dwl-wm-unstable-v1.xml b/protocols/net-tapesoftware-dwl-wm-unstable-v1.xml deleted file mode 100644 index 4fe5b73..0000000 --- a/protocols/net-tapesoftware-dwl-wm-unstable-v1.xml +++ /dev/null @@ -1,164 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<protocol name="net_tapesoftware_dwl_wm_unstable_v1"> - <copyright> - Copyright (c) 2021 Raphael Robatsch - - 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> - - <interface name="znet_tapesoftware_dwl_wm_v1" version="1"> - <description summary="control the dwl state"> - This interface is exposed as a global in the wl_registry. - - Clients can use this protocol to receive updates of the window manager - state (active tags, active layout, and focused window). - Clients can also control this state. - - After binding, the client will receive the available tags and layouts - with the 'tag' and 'layout' events. These can be used in subsequent - dwl_wm_monitor_v1.set_tags/set_layout requests, and to interpret the - dwl_wm_monitor_v1.layout/tag events. - </description> - - <request name="release" type="destructor"> - <description summary="release dwl_wm"> - This request indicates that the client will not use the dwl_wm - object any more. Objects that have been created through this instance - are not affected. - </description> - </request> - - <request name="get_monitor"> - <description summary="gets a dwl monitor from an output"> - Gets a dwl monitor for the specified output. The window manager - state on the output can be controlled using the monitor. - </description> - <arg name="id" type="new_id" interface="znet_tapesoftware_dwl_wm_monitor_v1" /> - <arg name="output" type="object" interface="wl_output" /> - </request> - - <event name="tag"> - <description summary="announces the presence of a tag"> - This event is sent immediately after binding. - A roundtrip after binding guarantees that the client has received all tags. - </description> - <arg name="name" type="string"/> - </event> - - <event name="layout"> - <description summary="announces the presence of a layout"> - This event is sent immediately after binding. - A roundtrip after binding guarantees that the client has received all layouts. - </description> - <arg name="name" type="string"/> - </event> - </interface> - - <interface name="znet_tapesoftware_dwl_wm_monitor_v1" version="1"> - <description summary="control one monitor"> - Observes and controls one monitor. - - Events are double-buffered: Clients should cache all events and only - redraw themselves once the 'frame' event is sent. - - Requests are not double-buffered: The compositor will update itself - immediately. - </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_monitor"> - This request indicates that the client is done with this dwl_monitor. - All further requests are ignored. - </description> - </request> - - <event name="selected"> - <description summary="updates the selected state of the monitor"> - If 'selected' is nonzero, this monitor is the currently selected one. - </description> - <arg name="selected" type="uint"/> - </event> - - <event name="tag"> - <description summary="updates the state of one tag"> - Announces the update of a tag. num_clients and focused_client can be - used to draw client indicators. - </description> - <arg name="tag" type="uint" summary="index of a tag received by the dwl_wm_v1.tag event." /> - <arg name="state" type="uint" enum="tag_state"/> - <arg name="num_clients" type="uint" summary="number of clients on this tag"/> - <arg name="focused_client" type="int" summary="out of num_clients. -1 if there is no focused client"/> - </event> - - <event name="layout"> - <description summary="updates the selected layout"> - Announces the update of the selected layout. - </description> - <arg name="layout" type="uint" summary="index of a layout received by the dwl_wm_v1.layout event."/> - </event> - - <event name="title"> - <description summary="updates the focused client"> - Announces the update of the selected client. - </description> - <arg name="title" type="string"/> - </event> - - <event name="frame"> - <description summary="end of status update sequence"> - Sent after all other events belonging to the status update has been sent. - Clients should redraw themselves now. - </description> - </event> - - <request name="set_tags"> - <description summary="sets the active tags on this monitor."> - Changes are applied immediately. - </description> - <arg name="tagmask" type="uint" summary="bitmask of the tags that should be set."/> - <arg name="toggle_tagset" type="uint"/> - </request> - - <request name="set_client_tags"> - <description summary="updates the tags of the focused client."> - tags are updated as follows: - new_tags = (current_tags AND and_tags) XOR xor_tags - - Changes are applied immediately. - </description> - <arg name="and_tags" type="uint"/> - <arg name="xor_tags" type="uint"/> - </request> - - <request name="set_layout"> - <description summary="sets the active layout on this monitor."> - Changes are applied immediately. - </description> - <arg name="layout" type="uint" summary="index of a layout received by the dwl_wm_v1.layout event."/> - </request> - </interface> -</protocol> |
