diff --git a/Bugs.md b/Bugs.md index d8a33a1..be04464 100644 --- a/Bugs.md +++ b/Bugs.md @@ -1170,3 +1170,85 @@ leading to a termination of cagebreak. * Fixed: 2.1.0 Prior to release 2.1.0 `meson install` did not work perfectly. + +## Issue 60 + + * github issue number: N/A + * Fixed: 2.1.2 + +In the `merge_output_configs` function, when copying the properties of +one config to another, the `angles` element of an input structure was +being copied to the `status` element of the resultant structure. + +## Issue 61 + + * github issue number: N/A + * Fixed: 2.1.2 + +The script introduced with 2.1.1 `scripts/install-development-environment` had some +missing dependencies. This has been resolved and tested with bare arch containers. + +## Issue 62 + + * github issue number: #46 + * Fixed: 2.2.0 + +When the readable flag of the IPC socket was set with 0 readable bytes +available, cagebreak entered an infinite loop which caused high CPU +usage before the first event was sent over the IPC socket. + +## Issue 63 + + * github issue number: N/A + * Fixed: 2.2.0 + +A file path in the environment-variables unit test was wrongly set, +causing this test to fail. + +## Issue 64 + + * github issue number: N/A + * Fixed: 2.2.0 + +Cagebreak did not update the pointer focus when focussing the +background. This means that the first pointer event after focussing the +background was sent to the previously focussed window. + +Steps to reproduce: + + * Open an application and hover the mouse over a clickable area. + * Switch to an empty desktop using a keybinding without moving the + mouse. + * Click the mouse without moving it. + * Observe that the element in the previously focussed window was + clicked. + +## Issue 65 + + * github issue number: N/A + * Fixed: 2.2.1 + +Up until cagebreak 2.2.0, the configuration for the calibration matrix of +a libinput device was not propagated correctly when internally copying +the configuration. This meant that effectively, the calibration matrix +configuration was a NoOp. Starting with version 2.2.1, the calibration +matrix can be set as documented. + +Thanks to Oliver Friedmann for providing a pull request. + +## Issue 66 + + * github issue number: #65 + * Fixed 2.2.3 + +In Cagebreak 2.2.2 the compatible wlroots versions were wrongly specified. +To stop this from reoccurring, we have added a check to our release checks. + +## Issue 67 + + * github issue number: #66 + * Fixed 2.2.3 + +In Cagebreak 2.2.2 dual monitors were mirrored instead of extended, changing +established behaviour. + diff --git a/Changelog.md b/Changelog.md index c33e179..b9f7461 100644 --- a/Changelog.md +++ b/Changelog.md @@ -119,3 +119,10 @@ Changelog: * Add miniscule test suite * Adjust Cagebreak to wlroots 0.16.2 * New GPG Keys + +## Release 2.2.0 + + * Add custom events + * Fix Issue 62 (#46 Github) + * Fix Issue 63 (environment variables test) + * Fix Issue 64 (pointer focus bug) diff --git a/Hashes.md b/Hashes.md index e5da651..867692b 100644 --- a/Hashes.md +++ b/Hashes.md @@ -1,5 +1,105 @@ # Hashes +2.2.3 cagebreak + + * sha 256: 265a9d09622272ca6ea79ddcdbdc6003704106814eb05a2b7547a77a982263de + * sha 512: 757f837a7e6ddd71fed88c4e1aab5cab9d4d07e8b76f280eed9afa35a2eaee23c0553299fe49a0139c754179d0df68c1303725f1f909921d078516e14ba3f21f + +2.2.3 cagebreak.1 + + * sha 256: 275698641476efa40fc1b33a8025e6dbba3ec931fbaf0a627c0748dad987ed4d + * sha 512: 617891ded06657e31daefee84a03191ad6e03892118f1790a5ebaa6e847c4d18d4b6849edc00841bd68abc9e0e0a111153efe102db02ce3d408c903b0d045927 + +2.2.3 cagebreak-config.5 + + * sha 256: 5967e9131d1ee16ffa046a732911c902e41f2e18f3170d11a47b9be596b4978a + * sha 512: 6d3c5fbb2b95a75d7c5a8ed8b5922cfcc4135857b389652572c5d9c211c6da9cf8ef0b5dc0e8eaa540c6b1c2dd215f512df2ef49ce80c34e8e5ad170bfb7134e + +2.2.3 cagebreak-socket.7 + + * sha 256: cb1bde8a6fb2a1fa2b7b8db7fdef9b933cd471ca604e15d1dd9133859fa6eea3 + * sha 512: 1d99672cb7ac7323790d47986d206bf8c392698db0cd52978963deb6e85118c6822e2d45c7fa66e8636e95214f8893d963a3157ca24239d2fd2d78b1e26f11e7 + +2.2.2 cagebreak + + * sha 256: 98e0dfe870a7242fdf7c6fb1a5c520cfe7d1154b3f139560da6cb86b2430b2a0 + * sha 512: c335f8f6e226203e797e232caead74db9b1e7f24d5edf80dd99a0c00c5f4e81351a5ddcad4f601a12618ebed5c62be547462c4f06ae4ccb6a622a869ee8741ec + +2.2.2 cagebreak.1 + + * sha 256: c655fff018377b5ee541854ee428559ba4c5080d44f87247fe608f18651b0764 + * sha 512: 7cbef17cbe3c59cde21466d6c76e1a34ffce748d2d9011a77bd7703f605b737e344cabaad1e3a599316321481524cb860b2533ab6bef2e7714c00b2641fe962c + +2.2.2 cagebreak-config.5 + + * sha 256: b799e0252d7224befc92bdd143d00dc3f42a38e39f510f3ace575b03f293a788 + * sha 512: 3778db9ff07429efb74b4b07476193844698e07ea91a742aac078391ba38fb07987dc61ba312c30b6eb04ad2d847ee552826e7a09be8dc572be5626c27059df3 + +2.2.2 cagebreak-socket.7 + + * sha 256: dd10359fd1840909bb817858668e67bdd433f367b0ed199328e4b29c99529322 + * sha 512: 67f8c39864472c9b2396946a943ce249297b1b9fc5e452a4051f0512fd61b4a22906e1a16aee1c2bf6cacb3b9cd7a11da19c5d760c192020402008eab379eee1 + +2.2.1 cagebreak + + * sha 256: 96469a78eeaddf9476c82e0ab8a0e35a95b3119bf83633a54feb8f3f5780df2f + * sha 512: 41135e9d81c79519a1db4955c742f50a375c4e4db80b51a02d618eb1520452c059a3df48013d11f17410a590ac43634da606daf6e95d0987af19284964bbcb5e + +2.2.1 cagebreak.1 + + * sha 256: 458259b066def0571b7604f4a87105f0ce608106abd7946e4697aa5ec5028ccf + * sha 512: aeed13e27e78ea8b30ee21f6ef41725f2808f484f0a3e6125cf70c601705954eb4a4a67ba9d6898ff994a79c20a0213557332d7f06a42098084aff3fe47ca21a + +2.2.1 cagebreak-config.5 + + * sha 256: 4ec5a18fae8d1170ff9d67126133a12ca7b1f7adae318d77f6fca8092c138761 + * sha 512: 9b35fde46191979dee5839873eaab4a673256f75dce533df141f43f7d8282381e1e3820d1cf97403c50846b1f4ddf1924271e961d519029ed58e76e31aef4c04 + +2.2.1 cagebreak-socket.7 + + * sha 256: 51911ee02637261e46164d861c4327ec338904221795a03895684582c361ef81 + * sha 512: db848faefbf5f1eff6d4f0ad1fc4e2169beb7fd0ada620b39fe64a319376e4c7e672c48a3e446943af40d23055467b001b8e1c38b4b72648258b6f7b14c1034d + +2.2.0 cagebreak + + * sha 256: 67660297290a18b7822a818d1d43343e4e6f4dc27427ed9099ff803f218aa9b4 + * sha 512: 9837e3901b2b10453db2663f5a3da6ec2393610c82984cbabe1c64a6d575e32b492cd3326a6fbb91faa912d14c58dfd1160168280b66417ce7f7f2306c5a501c + +2.2.0 cagebreak.1 + + * sha 256: 79caf055cb1c75f3751863718728cca5ea6231891d21b4364c877d5e4888e727 + * sha 512: 843e15e51f01ed25d0630eee8b6e12ebcc68934da49d6fb66e86f6a46d512145d9be22081b0c2b5f0356c2d0e15b9f13170f7ba1d34d5fba69c7e05a069db337 + +2.2.0 cagebreak-config.5 + + * sha 256: 7047333f5600d3b05caf04caf9910da1468efe49c1418ca3fcdc6163bade9e89 + * sha 512: 35203d3959594fe5130a561c440bf85a978384bc874fcce773bb02fa5c637ccc375f1b0ce1ad05603266dcdefed2570815363bc2c8ef81df7ff7be865de2cac5 + +2.2.0 cagebreak-socket.7 + + * sha 256: bf9bd35a17ab78cb93f0f5209daef27908bf02d0e31ae627ae05fabab162c984 + * sha 512: 023fb99c3a2c47543ae2870f19e8fd6fd8069834dc4fbeee93e890333b4ac24b4613d0e8dfd2bdffb2d5dc7f907868410b0c61f2e1346c76498955e15d0f3b89 + +2.1.2 cagebreak + + * sha 256: 7d07864a837ee577a52b2727bfbfe8834fe599712144f0685f458d508717e451 + * sha 512: 9429bace89affdd9f7e83f48168c1e119d1531a5eb9a320299924e469c0e43052e93580aee6ba5f4c2b878e5b85ec5fc4cf172940cb4c1d950329c175898b647 + +2.1.2 cagebreak.1 + + * sha 256: aec69b06cc8dd4328027a04a12847c91b6a176537cce7a6c2d68a4f004cdd47c + * sha 512: 1d6e882a1fa8bec84df189cd32a1ac8953fb61d0241b04296ecb8caadfc55733947037b3810ba28b73e2a32bc30dfd68794dd173220e1f8af8ba9d3d02abe19e + +2.1.2 cagebreak-config.5 + + * sha 256: 36e11b9d4437485a9671e72b3f6cc5669fb6a5b67b60198ee310efd6f3f3b093 + * sha 512: 8378924d81c2c35ddfeace15debafb0407fbbe76513f7a488815a1421ff1c49d7aa7f21812573043004a8fd4e481242fd6970be270fac8007771623ed8d92208 + +2.1.2 cagebreak-socket.7 + + * sha 256: 346f8e203210a1542ca31980628095dbfb267764e3c2228457dc5b0b43850fda + * sha 512: 84e40072c71a38449ec6a5409445458405009010ee47d3e26ba13f6fd13f0291e1c3b38f5e84ba5521b14955bd97ab6d1c636b72a093b6322d0879f98218ab7f + 2.1.1 cagebreak * sha 256: 8632e7e49637e5a3e7ab425a05fbd63d71cf6025143c89d196f309dbf4efdd57 diff --git a/README.md b/README.md index aca03a6..1ca4ce5 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Cagebreak: A Wayland Tiling Compositor -[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/6532/badge)](https://bestpractices.coreinfrastructure.org/projects/6532) [![Packaging status](https://repology.org/badge/tiny-repos/cagebreak.svg)](https://repology.org/project/cagebreak/versions) [![AUR package](https://repology.org/badge/version-for-repo/aur/cagebreak.svg?minversion=2.1.1)](https://repology.org/project/cagebreak/versions) +[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/6532/badge)](https://bestpractices.coreinfrastructure.org/projects/6532) [![Packaging status](https://repology.org/badge/tiny-repos/cagebreak.svg)](https://repology.org/project/cagebreak/versions) [![AUR package](https://repology.org/badge/version-for-repo/aur/cagebreak.svg?minversion=2.2.3)](https://repology.org/project/cagebreak/versions) ## Quick Introduction @@ -9,25 +9,21 @@ based on [Cage](https://github.com/Hjdskes/cage) and inspired by [ratpoison](htt ### Purpose -The goal of this project is to provide a successor to ratpoison for Wayland. +This project provides a successor to ratpoison for Wayland. However, this is no reimplementation of ratpoison. #### New Features, Bugs and Contact Information -Should you want to know if a feature will be implemented, file a bug or -get in touch, [open an issue](https://github.com/project-repo/cagebreak/issues/new) +You can [open an issue](https://github.com/project-repo/cagebreak/issues/new) or write an e-mail (See [SECURITY.md](SECURITY.md) for details.). -The Roadmap section outlines what is planned for the future. +The Roadmap section outlines our plans. #### Compatibility & Development Distribution Cagebreak supports [Arch Linux](https://archlinux.org/) and uses the libraries -(and software versions) as they are obtained through [pacman](https://wiki.archlinux.org/title/Pacman) -at the time of release. Any other use is out of scope. - -Most other setups probably work with a bit of luck. We -make no guarantees. +and versions from extra and core at the time of release. +Most other setups work with a bit of luck. ### Quick Installation @@ -42,17 +38,12 @@ details on getting started and the documentation for everything else. ### Documentation - * the rest of this file - * the man pages: - * [cagebreak](man/cagebreak.1.md) - * [configuration](man/cagebreak-config.5.md) - * [socket](man/cagebreak-socket.7.md) - * the [FAQ](FAQ.md) - * [SECURITY.md](SECURITY.md) + * the man pages: [cagebreak](man/cagebreak.1.md), [configuration](man/cagebreak-config.5.md) & [socket](man/cagebreak-socket.7.md) + * the [README](README.md), [FAQ](FAQ.md) & [SECURITY.md](SECURITY.md) #### What's new? -See the [Changelog](Changelog.md). +Check the [Changelog](Changelog.md). ### Uninstallation @@ -60,9 +51,9 @@ See the [Changelog](Changelog.md). ### Contributing - * Just [open an issue](https://github.com/project-repo/cagebreak/issues/new) and state your idea. - We will consider the proposal and get back to you. - * Don't open a pull request. We might not accept your code and + * [Open an issue](https://github.com/project-repo/cagebreak/issues/new) and state your idea. + We will get back to you. + * Ask before you open a pull request. We might not accept your code and it would be sad to waste the effort. * Respect the [Code of Conduct](CODE_OF_CONDUCT.md) (To date, we never had to intervene - Keep it that way!) @@ -208,16 +199,16 @@ as a source of inspiration and explanations for certain particularities. ## Contributing * Read this document. - * Just [open an issue](https://github.com/project-repo/cagebreak/issues/new) and state your feature request. - We will consider the proposal and get back to you. - * Don't open a pull request without asking first. We might not accept your + * [Open an issue](https://github.com/project-repo/cagebreak/issues/new) and state your feature request. + We will get back to you. + * Ask before opening a pull request. We might not accept your code and it would be sad to waste the effort. * Respect the [Code of Conduct](CODE_OF_CONDUCT.md) (To date, we never had to intervene - Please keep it that way!) ### Good First Contributions - * Reviewing the project is always welcome. + * Reviews are always welcome. * Read the code. * Read the documentation. * Test whether the documentation matches the code. @@ -225,12 +216,12 @@ as a source of inspiration and explanations for certain particularities. * Compile the code. * Ideas on improving the testing and quality assurance are particularly welcome. - * If you want, you can share your cagebreak scripts and we might include them - in the repository provided you agree to release them under MIT and we agree - with the use case and coding style. - * Iff you are happy with Cagebreak and use Arch Linux, you may vote for + * You can share your cagebreak scripts and we might include them with Cagebreak + provided you agree to release them under MIT and we agree with the + use case and coding style. + * If you are happy with Cagebreak under Arch Linux, you may vote for [Cagebreak in the AUR](https://aur.archlinux.org/packages/cagebreak). - * The points above still apply. + * The points from the Contributing section above still apply. ### Philosophy @@ -582,8 +573,8 @@ by at least one of the above collection. We registered project-repo.co and added mail addresses after release `1.3.0`. -We now have a mail address and its key is signed by signing keys. See Security -Bugs for details. +We now have a mail address and its key is signed by signing keys. See [SECURITY.md](SECURITY.md) +for details. The full public keys can be found in `keys/` along with any revocation certificates. @@ -633,14 +624,17 @@ The release procedure outlines the process for a release to occur. * [ ] Synchronize any socket changes to cagebreak-socket man page * [ ] Document fixed bugs in Bugs.md * [ ] Include issue discussion from github, where applicable + * [ ] `meson compile adjust-epoch -C build` * [ ] Commit changes * [ ] `git push origin development` * [ ] Testing * [ ] Manual testing * [ ] `meson compile fuzz -C build` for at least one hour + * [ ] Adjust Hashes.md - Use `meson compile output-hashes -C build` to add Hashes or aid in repro check + * [ ] Commit changes + * [ ] `git push origin development` * [ ] Complete release-non-auto-checks - * [ ] Use `meson compile output-hashes -C build` to add Hashes or aid in repro check - * [ ] `meson compile create-signatures -C build` + * [ ] `meson compile create-sigs -C build` * [ ] Commit and push signatures, hashes and non-auto-check files * [ ] `meson test -C build` passes everything except some release tests * [ ] `git add` relevant files @@ -660,6 +654,7 @@ The release procedure outlines the process for a release to occur. * [ ] `git merge master` * [ ] `git push --tags origin hotfix` * [ ] Upload archives and signatures as release assets + * [ ] Delete feature branches if appropriate * [ ] Manage package release ## Roadmap @@ -743,6 +738,10 @@ see [SECURITY.md](SECURITY.md). * Oliver Friedmann * [Add output scaling](https://github.com/project-repo/cagebreak/pull/34), released in 2.0.0 with slight modifications + * [Fix: calibration matrix](https://github.com/project-repo/cagebreak/pull/49), + released in 2.2.1 with slight modifications + * Tom Greig + * Fix bug in merge_output_configs in 2.1.2 ## License diff --git a/SECURITY.md b/SECURITY.md index 2f33197..a55a2b4 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -51,11 +51,10 @@ public key or provide the fingerprint and directions to obtain the key. ## Threat Model -Cagebreak is a wayland compositor run by the user of the system -and thus has access to whichever resources this user has access to. -Cagebreak can restrict other programs in no way, because this would hamper -usability (consider a web browser unable to write a downloaded file to disk -for instance). +Cagebreak is a wayland compositor run by a user and has access to +the resources the user has access to. +Cagebreak cannot restrict other programs (consider a web browser +unable to write a downloaded file for instance). There is no transmission of information by cagebreak other than to the screens, ipc and potentially other documented local channels. @@ -63,38 +62,36 @@ screens, ipc and potentially other documented local channels. ### STRIDE Threat List This is not a thorough analysis, just an overview of the ways in which cagebreak -has (no) attack surface. Please reference the man pages for details but especially -the -e and --bs options. +has (no) attack surface. Please reference the man pages (especially options -e and --bs ). #### Spoofing -Not applicable - Using Cagebreak already requires a login as a user. +Not applicable - Cagebreak is executed after user login. #### Tampering -Not applicable - Cagebreak must allow system manipulation for user software. +Not applicable - Cagebreak allows system manipulation for user software. #### Repudiation Not applicable - There are no prohibited operations (See Tampering above.). -While cagebreak does send events over documented channels there is no logging -activated by default, though, of course, this can be changed by the user -by logging socket output (if enabled) for example. +Cagebreak sends events over documented channels. There is no logging +activated by default - this can be changed by logging the socket (if enabled) for example. #### Information Disclosure -Not applicable - Information disclosure over documented channels is a feature -and any software run by the user may exfiltrate any data the user has access to. +Not applicable - Information disclosure over documented channels is a feature. +Any user software may exfiltrate any data the user has access to. #### Denial of Service -Not applicable - Cagebreak offers functionality to terminate itself, which is -available to all user software over the socket if the socket is enabled. +Not applicable - Cagebreak offers functionality to terminate itself. This is +available to user software over the socket (if enabled). #### Elevation of Privilege -Software may gain arbitrary code execution rights if it has access to the -Cagebreak socket. Privilege escalation to root is unlikely since privileges +Software may gain arbitrary code execution if it has access to the +socket (if enabled). Privilege escalation to root is unlikely since privileges are dropped before any user input is accepted. ## GPG Keys of the Cagebreak Repository diff --git a/cagebreak.c b/cagebreak.c index 4437331..66afdf3 100644 --- a/cagebreak.c +++ b/cagebreak.c @@ -26,8 +26,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -368,7 +368,7 @@ main(int argc, char *argv[]) { wl_event_loop_add_signal(event_loop, SIGPIPE, handle_signal, &server); server.event_loop = event_loop; - backend = wlr_backend_autocreate(server.wl_display); + backend = wlr_backend_autocreate(server.wl_display, &server.session); if(!backend) { wlr_log(WLR_ERROR, "Unable to create the wlroots backend"); ret = 1; @@ -428,9 +428,10 @@ main(int argc, char *argv[]) { ret = 1; goto end; } - wlr_scene_attach_output_layout(server.scene, server.output_layout); + server.scene_output_layout = + wlr_scene_attach_output_layout(server.scene, server.output_layout); - compositor = wlr_compositor_create(server.wl_display, server.renderer); + compositor = wlr_compositor_create(server.wl_display, 6, server.renderer); if(!compositor) { wlr_log(WLR_ERROR, "Unable to create the wlroots compositor"); ret = 1; @@ -474,14 +475,8 @@ main(int argc, char *argv[]) { goto end; } - server.idle = wlr_idle_create(server.wl_display); - if(!server.idle) { - wlr_log(WLR_ERROR, "Unable to create the idle tracker"); - ret = 1; - goto end; - } - server.idle_inhibit_v1 = wlr_idle_inhibit_v1_create(server.wl_display); + server.idle = wlr_idle_notifier_v1_create(server.wl_display); if(!server.idle_inhibit_v1) { wlr_log(WLR_ERROR, "Cannot create the idle inhibitor"); ret = 1; @@ -687,6 +682,12 @@ main(int argc, char *argv[]) { wl_display_run(server.wl_display); +#if CG_HAS_XWAYLAND + if(server.xwayland != NULL) { + wlr_xwayland_destroy(server.xwayland); + } +#endif + wl_display_destroy_clients(server.wl_display); end: @@ -734,11 +735,6 @@ end: if(server.seat != NULL) { seat_destroy(server.seat); } -#if CG_HAS_XWAYLAND - if(server.xwayland != NULL) { - wlr_xwayland_destroy(server.xwayland); - } -#endif if(sigint_source != NULL) { wl_event_source_remove(sigint_source); diff --git a/example_scripts/focus_follows_cursor.sh b/example_scripts/focus_follows_cursor.sh deleted file mode 100644 index e47bf88..0000000 --- a/example_scripts/focus_follows_cursor.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -# Copyright 2023, project-repo and the cagebreak contributors -# SPDX-License-Identifier: MIT - -# This script uses the cagebreak socket to modify the compositor's behaviour in -# such a way that the currently focussed tile follows the cursor, i.e. that the -# currently focussed tile is always the one within which the cursor is located. - -# Start up the ipc link -source "$(dirname "${BASH_SOURCE[0]}")/cb_script_header.sh" - -while IFS= read -r -d $'\0' event -do - # Remove the cg-ipc header - event="${event:6}" - if [[ "$(echo "${event}" | jq ".event_name")" = "\"cursor_switch_tile\"" ]] - then - new_tile="$(echo "${event}"|jq -r ".new_tile")" - new_output_id="$(echo "${event}"|jq -r ".new_output_id")" - # Send the new tile to focus to cagebreak - echo -e "screen ${new_output_id}\nfocus_tile ${new_tile}" >&3 - fi -done <&4 diff --git a/fuzz/fuzz-lib.c b/fuzz/fuzz-lib.c index d331880..650d8a8 100644 --- a/fuzz/fuzz-lib.c +++ b/fuzz/fuzz-lib.c @@ -25,10 +25,9 @@ #include #include #include -#include #include +#include #include -#include #include #include #include @@ -271,9 +270,10 @@ LLVMFuzzerInitialize(int *argc, char ***argv) { ret = 1; goto end; } - wlr_scene_attach_output_layout(server.scene, server.output_layout); + server.scene_output_layout = + wlr_scene_attach_output_layout(server.scene, server.output_layout); - compositor = wlr_compositor_create(server.wl_display, server.renderer); + compositor = wlr_compositor_create(server.wl_display, 5, server.renderer); if(!compositor) { wlr_log(WLR_ERROR, "Unable to create the wlroots compositor"); ret = 1; @@ -310,7 +310,7 @@ LLVMFuzzerInitialize(int *argc, char ***argv) { goto end; } - server.idle = wlr_idle_create(server.wl_display); + server.idle = wlr_idle_notifier_v1_create(server.wl_display); if(!server.idle) { wlr_log(WLR_ERROR, "Unable to create the idle tracker"); ret = 1; diff --git a/idle_inhibit_v1.c b/idle_inhibit_v1.c index b4f91f9..019d47b 100644 --- a/idle_inhibit_v1.c +++ b/idle_inhibit_v1.c @@ -2,8 +2,8 @@ // SPDX-License-Identifier: MIT #include -#include #include +#include #include "idle_inhibit_v1.h" #include "server.h" @@ -24,7 +24,7 @@ idle_inhibit_v1_check_active(struct cg_server *server) { /* As of right now, this does not check whether the inhibitor * is visible or not.*/ bool inhibited = !wl_list_empty(&server->inhibitors); - wlr_idle_set_enabled(server->idle, NULL, !inhibited); + wlr_idle_notifier_v1_set_inhibited(server->idle, inhibited); } #if CG_HAS_FANALYZE #pragma GCC diagnostic pop diff --git a/input_manager.c b/input_manager.c index cfde2c9..fcdd684 100644 --- a/input_manager.c +++ b/input_manager.c @@ -229,6 +229,11 @@ input_manager_merge_input_configs(struct cg_input_config *cfg1, } else { out_cfg->repeat_rate = cfg1->repeat_rate; } + if(cfg1->calibration_matrix.configured == false) { + out_cfg->calibration_matrix = cfg2->calibration_matrix; + } else { + out_cfg->calibration_matrix = cfg1->calibration_matrix; + } return out_cfg; } diff --git a/ipc_server.c b/ipc_server.c index ced183a..05614b3 100644 --- a/ipc_server.c +++ b/ipc_server.c @@ -127,10 +127,6 @@ ipc_client_handle_writable(int client_fd, uint32_t mask, void *data) { return 0; } - if(client->write_buffer_len <= 0) { - return 0; - } - if(fcntl(client->fd, F_GETFD) == -1) { return 0; } diff --git a/keybinding.c b/keybinding.c index 44ccffb..6da0cc6 100644 --- a/keybinding.c +++ b/keybinding.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -96,6 +95,12 @@ keybinding_free(struct keybinding *keybinding, bool recursive) { if(keybinding->data.c != NULL) { free(keybinding->data.c); } + break; + case KEYBINDING_SEND_CUSTOM_EVENT: + if(keybinding->data.c != NULL) { + free(keybinding->data.c); + } + break; default: break; } @@ -500,11 +505,10 @@ keybinding_workspace_fullscreen(struct cg_server *server) { // Switch to a differerent virtual terminal static int -keybinding_switch_vt(struct wlr_backend *backend, unsigned int vt) { - if(wlr_backend_is_multi(backend)) { - struct wlr_session *session = wlr_backend_get_session(backend); - if(session) { - wlr_session_change_vt(session, vt); +keybinding_switch_vt(struct cg_server *server, unsigned int vt) { + if(wlr_backend_is_multi(server->backend)) { + if(server->session) { + wlr_session_change_vt(server->session, vt); } return 0; } @@ -1245,6 +1249,12 @@ keybinding_display_message(struct cg_server *server, char *msg) { message_printf(server->curr_output, "%s", msg); } +void +keybinding_send_custom_event(struct cg_server *server, char *msg) { + ipc_send_event(server, + "{\"event_name\":\"custom_event\",\"message\":\"%s\"}", msg); +} + void keybinding_move_view_to_cycle_output(struct cg_server *server, bool reverse) { if(wl_list_length(&server->outputs) <= 1) { @@ -1615,11 +1625,11 @@ void set_cursor(bool enabled, struct cg_seat *seat) { if(enabled == true) { seat->enable_cursor = true; - wlr_xcursor_manager_set_cursor_image(seat->xcursor_manager, - DEFAULT_XCURSOR, seat->cursor); + wlr_cursor_set_xcursor(seat->cursor, seat->xcursor_manager, + DEFAULT_XCURSOR); } else { seat->enable_cursor = false; - wlr_cursor_set_image(seat->cursor, NULL, 0, 0, 0, 0, 0, 0); + wlr_cursor_unset_image(seat->cursor); } } @@ -1633,7 +1643,7 @@ run_action(enum keybinding_action action, struct cg_server *server, server->running = false; break; case KEYBINDING_CHANGE_TTY: - return keybinding_switch_vt(server->backend, data.u); + return keybinding_switch_vt(server, data.u); case KEYBINDING_CURSOR: set_cursor(data.i, server->seat); break; @@ -1676,9 +1686,9 @@ run_action(enum keybinding_action action, struct cg_server *server, if(data.u != server->seat->default_mode) { wlr_seat_pointer_notify_clear_focus(server->seat->seat); if(server->seat->enable_cursor == true) { - wlr_xcursor_manager_set_cursor_image( - server->seat->xcursor_manager, "dot_box_mask", - server->seat->cursor); + wlr_cursor_set_xcursor(server->seat->cursor, + server->seat->xcursor_manager, + "dot_box_mask"); } } server->seat->mode = data.u; @@ -1706,6 +1716,9 @@ run_action(enum keybinding_action action, struct cg_server *server, case KEYBINDING_DISPLAY_MESSAGE: keybinding_display_message(server, data.c); break; + case KEYBINDING_SEND_CUSTOM_EVENT: + keybinding_send_custom_event(server, data.c); + break; case KEYBINDING_RESIZE_TILE_HORIZONTAL: resize_tile(server, data.i, 0); break; diff --git a/keybinding.h b/keybinding.h index 6d6cf87..a5958f0 100644 --- a/keybinding.h +++ b/keybinding.h @@ -63,6 +63,7 @@ struct cg_server; KEYBINDING(KEYBINDING_SHOW_TIME, time) \ KEYBINDING(KEYBINDING_SHOW_INFO, show_info) \ KEYBINDING(KEYBINDING_DISPLAY_MESSAGE, message) \ + KEYBINDING(KEYBINDING_SEND_CUSTOM_EVENT, custom_event) \ KEYBINDING(KEYBINDING_CURSOR, cursor) \ \ KEYBINDING(KEYBINDING_SWAP_LEFT, exchangeleft) \ diff --git a/man/cagebreak-config.5.md b/man/cagebreak-config.5.md index bb04547..d5b4969 100644 --- a/man/cagebreak-config.5.md +++ b/man/cagebreak-config.5.md @@ -1,4 +1,4 @@ -cagebreak-config(5) "VERSION 2.1.1" "Cagebreak Manual" +cagebreak-config(5) "Version 2.2.3" "Cagebreak Manual" # NAME @@ -81,9 +81,17 @@ configure_message display_time 4 *cursor [enable|disable]* Enable or disable cursor + This simply hides the cursor. Pointing and clicking is still possible. +*custom_event * + Send a custom event to the IPC socket + + This sends an event of type "custom_event" to all programs + listening to the IPC socket along with the string . + See *cagebreak-socket(7)* for more details. + *definekey * Bind to execute if pressed in - *definekey* is a more general version of *bind*. diff --git a/man/cagebreak-socket.7.md b/man/cagebreak-socket.7.md index 19b7370..19365d6 100644 --- a/man/cagebreak-socket.7.md +++ b/man/cagebreak-socket.7.md @@ -1,4 +1,4 @@ -cagebreak-socket(7) "VERSION 2.1.1" "Cagebreak Manual" +cagebreak-socket(7) "Version 2.2.3" "Cagebreak Manual" # NAME @@ -113,6 +113,17 @@ cg-ipc{"event_name":"configure_output","output":"eDP-1","output_id":1} cg-ipc{"event_name":"cursor_switch_tile","old_output":"eDP-1","old_output_id":1,"old_tile":2,"new_output":"eDP-1","new_output_id":1,"new_tile":3} ``` +*custom_event* + - Trigger: Cagebreak receives the *custom_event* command, either in the config file or via the IPC socket (see *cagebreak-config(5)*). + - JSON + - event_name: "custom_event" + - message: The message passed to the *custom_event* command + +``` +custom_event Hello World! +cg-ipc{"event_name":"custom_event","message":"Hello World!"} +``` + *cycle_outputs* - Trigger: *nextscreen* and *prevscreen* commands - JSON diff --git a/man/cagebreak.1.md b/man/cagebreak.1.md index fdc2da1..bdd469f 100644 --- a/man/cagebreak.1.md +++ b/man/cagebreak.1.md @@ -1,4 +1,4 @@ -cagebreak(1) "VERSION 2.1.1" "Cagebreak Manual" +cagebreak(1) "Version 2.2.3" "Cagebreak Manual" # NAME diff --git a/meson.build b/meson.build index 26b0746..aeb3346 100644 --- a/meson.build +++ b/meson.build @@ -3,7 +3,7 @@ project( 'cagebreak', 'c', -version : '2.1.1', +version : '2.2.3', license : 'MIT', default_options : ['c_std=c11', 'warning_level=3'] ) @@ -55,7 +55,7 @@ if is_freebsd ) endif -wlroots = dependency('wlroots', version: ['>=0.16.1', '< 0.17.0']) +wlroots = dependency('wlroots', version: ['>=0.17.0', '< 0.18.0']) wayland_protos = dependency('wayland-protocols', version: '>=1.14') wayland_server = dependency('wayland-server') wayland_cursor = dependency('wayland-cursor') @@ -204,15 +204,15 @@ reproducible_build_versions = { 'wayland_server': '1.19.0', 'wayland_client': '1.22.0', 'wayland_cursor': '1.22.0', - 'wlroots': '0.16.2', - 'xkbcommon': '1.5.0', + 'wlroots': '0.17.0', + 'xkbcommon': '1.6.0', 'fontconfig': '2.14.2', - 'libinput': '1.23.0', - 'libevdev': '1.13.0', - 'libudev': '253', - 'pango': '1.50.14', - 'cairo': '1.17.8', - 'pangocairo': '1.50.14', + 'libinput': '1.24.0', + 'libevdev': '1.13.1', + 'libudev': '254', + 'pango': '1.51.0', + 'cairo': '1.18.0', + 'pangocairo': '1.51.0', 'math': '-1' } @@ -238,7 +238,7 @@ foreach name, dep : cagebreak_dependencies_dict endforeach reproducible_build_compiler = 'gcc' -reproducible_build_compiler_version = '12.2.1' +reproducible_build_compiler_version = '13.2.1' if cc.get_id() != reproducible_build_compiler warning('The compiler "' + cc.get_id() + '" differs from the one used to generate to binary specified in Hashes.md (' + reproducible_build_compiler + ').') @@ -260,7 +260,7 @@ install_data('LICENSE', install_dir : '/usr/share/licenses/' + meson.project_nam if get_option('man-pages') scdoc = find_program('scdoc') - secssinceepoch = 1681758922 + secssinceepoch = 1701768836 shcommand = 'export SOURCE_DATE_EPOCH=' + secssinceepoch.to_string() + ' ; @0@ < @INPUT@'.format(scdoc.path()) sh = find_program('sh') mandir1 = join_paths(get_option('mandir'), 'man1') diff --git a/message.c b/message.c index 74b1d0a..d74b8cf 100644 --- a/message.c +++ b/message.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include diff --git a/output.c b/output.c index b8fc627..0a482f0 100644 --- a/output.c +++ b/output.c @@ -15,9 +15,9 @@ #include #endif #include +#include #include #include -#include #include #include #include @@ -42,7 +42,7 @@ void output_clear(struct cg_output *output) { struct cg_server *server = output->server; - wlr_output_layout_remove(server->output_layout, output->wlr_output); + wlr_scene_output_destroy(output->scene_output); if(server->running && server->curr_output == output && wl_list_length(&server->outputs) > 1) { @@ -118,7 +118,6 @@ output_destroy(struct cg_output *output) { int outp_num = output_get_num(output); wl_list_remove(&output->destroy.link); - wl_list_remove(&output->mode.link); wl_list_remove(&output->commit.link); wl_list_remove(&output->frame.link); @@ -166,7 +165,7 @@ handle_output_frame(struct wl_listener *listener, void *data) { if(scene_output == NULL) { return; } - wlr_scene_output_commit(scene_output); + wlr_scene_output_commit(scene_output, NULL); struct timespec now = {0}; clock_gettime(CLOCK_MONOTONIC, &now); @@ -283,15 +282,20 @@ output_apply_config(struct cg_server *server, struct cg_output *output, wlr_output_commit(wlr_output); return; } - wlr_output_layout_add(server->output_layout, wlr_output, config->pos.x, - config->pos.y); + struct wlr_output_layout_output *lo = wlr_output_layout_add( + server->output_layout, wlr_output, config->pos.x, config->pos.y); + wlr_scene_output_layout_add_output(server->scene_output_layout, lo, + output->scene_output); /* Since the size of the output may have changed, we * reinitialize all workspaces with a fullscreen layout */ for(unsigned int i = 0; i < output->server->nws; ++i) { output_make_workspace_fullscreen(output, i); } } else { - wlr_output_layout_add_auto(server->output_layout, wlr_output); + struct wlr_output_layout_output *lo = + wlr_output_layout_add_auto(server->output_layout, wlr_output); + wlr_scene_output_layout_add_output(server->scene_output_layout, lo, + output->scene_output); struct wlr_output_mode *preferred_mode = wlr_output_preferred_mode(wlr_output); @@ -399,7 +403,7 @@ merge_output_configs(struct cg_output_config *cfg1, out_cfg->scale = cfg1->scale; } if(cfg1->angle == out_cfg->angle) { - out_cfg->status = cfg2->angle; + out_cfg->angle = cfg2->angle; } else { out_cfg->angle = cfg1->angle; } @@ -439,8 +443,9 @@ handle_output_commit(struct wl_listener *listener, void *data) { return; } - if(event->committed & - (WLR_OUTPUT_STATE_TRANSFORM | WLR_OUTPUT_STATE_SCALE)) { + if(event->state->committed & + (WLR_OUTPUT_STATE_TRANSFORM | WLR_OUTPUT_STATE_SCALE | + WLR_OUTPUT_STATE_MODE)) { struct cg_view *view; wl_list_for_each( view, &output->workspaces[output->curr_workspace]->views, link) { @@ -451,23 +456,6 @@ handle_output_commit(struct wl_listener *listener, void *data) { } } -static void -handle_output_mode(struct wl_listener *listener, void *data) { - struct cg_output *output = wl_container_of(listener, output, mode); - - if(!output->wlr_output->enabled || output->workspaces == NULL) { - return; - } - - struct cg_view *view; - wl_list_for_each(view, &output->workspaces[output->curr_workspace]->views, - link) { - if(view_is_visible(view)) { - view_maximize(view, view->tile); - } - } -} - void output_make_workspace_fullscreen(struct cg_output *output, int ws) { struct cg_server *server = output->server; @@ -517,6 +505,7 @@ handle_new_output(struct wl_listener *listener, void *data) { } struct cg_output *output = calloc(1, sizeof(struct cg_output)); + output->scene_output = wlr_scene_output_create(server->scene, wlr_output); if(!output) { wlr_log(WLR_ERROR, "Failed to allocate output"); return; @@ -568,8 +557,8 @@ handle_new_output(struct wl_listener *listener, void *data) { if(server->curr_output == NULL) { server->curr_output = output; } - wlr_xcursor_manager_set_cursor_image(server->seat->xcursor_manager, - DEFAULT_XCURSOR, server->seat->cursor); + wlr_cursor_set_xcursor(server->seat->cursor, server->seat->xcursor_manager, + DEFAULT_XCURSOR); wlr_cursor_warp(server->seat->cursor, NULL, 0, 0); output->destroy.notify = handle_output_destroy; @@ -578,8 +567,7 @@ handle_new_output(struct wl_listener *listener, void *data) { wl_signal_add(&wlr_output->events.frame, &output->frame); output->commit.notify = handle_output_commit; wl_signal_add(&wlr_output->events.commit, &output->commit); - output->mode.notify = handle_output_mode; - wl_signal_add(&wlr_output->events.mode, &output->mode); + ipc_send_event(server, "{\"event_name\":\"new_output\",\"output\":\"%s\",\"output_" "id\":%d,\"priority\":%d}", diff --git a/output.h b/output.h index 90cd615..c1d4853 100644 --- a/output.h +++ b/output.h @@ -16,8 +16,8 @@ struct cg_output { struct cg_server *server; struct wlr_output *wlr_output; struct wlr_scene_rect *bg; + struct wlr_scene_output *scene_output; - struct wl_listener mode; struct wl_listener commit; struct wl_listener destroy; struct wl_listener frame; diff --git a/parse.c b/parse.c index 68767c6..c163b3a 100644 --- a/parse.c +++ b/parse.c @@ -811,6 +811,15 @@ parse_command(struct cg_server *server, struct keybinding *keybinding, return -1; } keybinding->data.c = strdup(saveptr); + } else if(strcmp(action, "custom_event") == 0) { + keybinding->action = KEYBINDING_SEND_CUSTOM_EVENT; + if(saveptr == NULL) { + *errstr = + log_error("Not enough paramaters to \"custom_event\". Expected " + "string to send."); + return -1; + } + keybinding->data.c = strdup(saveptr); } else if(strcmp(action, "time") == 0) { keybinding->action = KEYBINDING_SHOW_TIME; } else if(strcmp(action, "nextscreen") == 0) { diff --git a/release-non-auto-checks/Bugs.md b/release-non-auto-checks/Bugs.md index aa7d21e..16e03cd 100644 --- a/release-non-auto-checks/Bugs.md +++ b/release-non-auto-checks/Bugs.md @@ -1,2 +1,2 @@ -2.1.1 -2023-04-17 +2.2.3 +2023-12-05 diff --git a/release-non-auto-checks/FAQ.md b/release-non-auto-checks/FAQ.md index aa7d21e..16e03cd 100644 --- a/release-non-auto-checks/FAQ.md +++ b/release-non-auto-checks/FAQ.md @@ -1,2 +1,2 @@ -2.1.1 -2023-04-17 +2.2.3 +2023-12-05 diff --git a/release-non-auto-checks/SECURITY.md b/release-non-auto-checks/SECURITY.md index aa7d21e..16e03cd 100644 --- a/release-non-auto-checks/SECURITY.md +++ b/release-non-auto-checks/SECURITY.md @@ -1,2 +1,2 @@ -2.1.1 -2023-04-17 +2.2.3 +2023-12-05 diff --git a/release-non-auto-checks/WLR_XDG_VERSION b/release-non-auto-checks/WLR_XDG_VERSION index aa7d21e..16e03cd 100644 --- a/release-non-auto-checks/WLR_XDG_VERSION +++ b/release-non-auto-checks/WLR_XDG_VERSION @@ -1,2 +1,2 @@ -2.1.1 -2023-04-17 +2.2.3 +2023-12-05 diff --git a/release-non-auto-checks/acknowledge-contributors b/release-non-auto-checks/acknowledge-contributors new file mode 100644 index 0000000..16e03cd --- /dev/null +++ b/release-non-auto-checks/acknowledge-contributors @@ -0,0 +1,2 @@ +2.2.3 +2023-12-05 diff --git a/release-non-auto-checks/changelog-major-minor b/release-non-auto-checks/changelog-major-minor index aa7d21e..16e03cd 100644 --- a/release-non-auto-checks/changelog-major-minor +++ b/release-non-auto-checks/changelog-major-minor @@ -1,2 +1,2 @@ -2.1.1 -2023-04-17 +2.2.3 +2023-12-05 diff --git a/release-non-auto-checks/internal-wiki b/release-non-auto-checks/internal-wiki index aa7d21e..16e03cd 100644 --- a/release-non-auto-checks/internal-wiki +++ b/release-non-auto-checks/internal-wiki @@ -1,2 +1,2 @@ -2.1.1 -2023-04-17 +2.2.3 +2023-12-05 diff --git a/release-non-auto-checks/meson-epoch b/release-non-auto-checks/meson-epoch deleted file mode 100644 index aa7d21e..0000000 --- a/release-non-auto-checks/meson-epoch +++ /dev/null @@ -1,2 +0,0 @@ -2.1.1 -2023-04-17 diff --git a/release-non-auto-checks/release-note b/release-non-auto-checks/release-note index aa7d21e..16e03cd 100644 --- a/release-non-auto-checks/release-note +++ b/release-non-auto-checks/release-note @@ -1,2 +1,2 @@ -2.1.1 -2023-04-17 +2.2.3 +2023-12-05 diff --git a/release-non-auto-checks/reproducibility-checked b/release-non-auto-checks/reproducibility-checked index aa7d21e..16e03cd 100644 --- a/release-non-auto-checks/reproducibility-checked +++ b/release-non-auto-checks/reproducibility-checked @@ -1,2 +1,2 @@ -2.1.1 -2023-04-17 +2.2.3 +2023-12-05 diff --git a/release-non-auto-checks/security-to-man-page-info-transfer b/release-non-auto-checks/security-to-man-page-info-transfer index aa7d21e..16e03cd 100644 --- a/release-non-auto-checks/security-to-man-page-info-transfer +++ b/release-non-auto-checks/security-to-man-page-info-transfer @@ -1,2 +1,2 @@ -2.1.1 -2023-04-17 +2.2.3 +2023-12-05 diff --git a/release-non-auto-checks/version-restrictions b/release-non-auto-checks/version-restrictions new file mode 100644 index 0000000..16e03cd --- /dev/null +++ b/release-non-auto-checks/version-restrictions @@ -0,0 +1,2 @@ +2.2.3 +2023-12-05 diff --git a/scripts/install-development-environment b/scripts/install-development-environment old mode 100755 new mode 100644 diff --git a/scripts/set-version b/scripts/set-version index c4506cb..3ee035c 100755 --- a/scripts/set-version +++ b/scripts/set-version @@ -15,6 +15,6 @@ version="${1}" sed -i -e "s/minversion\=[0-9]*\.[0-9]*.[0-9]*/minversion=$version/" README.md -sed -i -e "s/Version [0-9]*\.[0-9]*.[0-9]*/VERSION $version/" man/cagebreak.1.md -sed -i -e "s/Version [0-9]*\.[0-9]*.[0-9]*/VERSION $version/" man/cagebreak-config.5.md -sed -i -e "s/Version [0-9]*\.[0-9]*.[0-9]*/VERSION $version/" man/cagebreak-socket.7.md +sed -i -e "s/Version [0-9]*\.[0-9]*.[0-9]*/Version $version/" man/cagebreak.1.md +sed -i -e "s/Version [0-9]*\.[0-9]*.[0-9]*/Version $version/" man/cagebreak-config.5.md +sed -i -e "s/Version [0-9]*\.[0-9]*.[0-9]*/Version $version/" man/cagebreak-socket.7.md diff --git a/seat.c b/seat.c index cd085be..80206e9 100644 --- a/seat.c +++ b/seat.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include @@ -59,10 +59,10 @@ update_capabilities(const struct cg_seat *seat) { /* Hide cursor if the seat doesn't have pointer capability. */ if(((caps & WL_SEAT_CAPABILITY_POINTER) == 0) || seat->enable_cursor == false) { - wlr_cursor_set_image(seat->cursor, NULL, 0, 0, 0, 0, 0, 0); + wlr_cursor_unset_image(seat->cursor); } else { - wlr_xcursor_manager_set_cursor_image(seat->xcursor_manager, - DEFAULT_XCURSOR, seat->cursor); + wlr_cursor_set_xcursor(seat->cursor, seat->xcursor_manager, + DEFAULT_XCURSOR); } } @@ -169,7 +169,7 @@ handle_modifier_event(struct wlr_input_device *device, struct cg_seat *seat) { wlr_seat_set_keyboard(seat->seat, keyboard); wlr_seat_keyboard_notify_modifiers(seat->seat, &keyboard->modifiers); - wlr_idle_notify_activity(seat->server->idle, seat->seat); + wlr_idle_notifier_v1_notify_activity(seat->server->idle, seat->seat); } void @@ -205,12 +205,11 @@ handle_command_key_bindings(struct cg_server *server, xkb_keysym_t sym, &server->scene->tree.node, server->seat->cursor->x, server->seat->cursor->y, &sx, &sy); if(server->seat->enable_cursor) { - wlr_xcursor_manager_set_cursor_image(server->seat->xcursor_manager, - "left_ptr", - server->seat->cursor); + wlr_cursor_set_xcursor(server->seat->cursor, + server->seat->xcursor_manager, "left_ptr"); if(node && node->type == WLR_SCENE_NODE_BUFFER) { struct wlr_scene_surface *scene_surface = - wlr_scene_surface_from_buffer( + wlr_scene_surface_try_from_buffer( wlr_scene_buffer_from_node(node)); if(scene_surface != NULL) { surface = scene_surface->surface; @@ -239,7 +238,7 @@ handle_command_key_bindings(struct cg_server *server, xkb_keysym_t sym, } message_clear(group->seat->server->curr_output); run_action((*keybinding)->action, server, (*keybinding)->data); - wlr_idle_notify_activity(server->idle, server->seat->seat); + wlr_idle_notifier_v1_notify_activity(server->idle, server->seat->seat); return true; } else if(mode != 0) { run_action(KEYBINDING_NOOP, server, (union keybinding_params){NULL}); @@ -312,7 +311,7 @@ handle_key_event(struct cg_keyboard_group *group, struct cg_seat *seat, event->keycode, event->state); } - wlr_idle_notify_activity(seat->server->idle, seat->seat); + wlr_idle_notifier_v1_notify_activity(seat->server->idle, seat->seat); } static void @@ -589,7 +588,7 @@ handle_touch_down(struct wl_listener *listener, void *data) { uint32_t serial = 0; if(node && node->type == WLR_SCENE_NODE_BUFFER) { struct wlr_scene_surface *scene_surface = - wlr_scene_surface_from_buffer(wlr_scene_buffer_from_node(node)); + wlr_scene_surface_try_from_buffer(wlr_scene_buffer_from_node(node)); if(scene_surface != NULL) { serial = wlr_seat_touch_notify_down( seat->seat, scene_surface->surface, event->time_msec, @@ -603,7 +602,7 @@ handle_touch_down(struct wl_listener *listener, void *data) { seat->touch_ly = ly; } - wlr_idle_notify_activity(seat->server->idle, seat->seat); + wlr_idle_notifier_v1_notify_activity(seat->server->idle, seat->seat); } static void @@ -616,7 +615,7 @@ handle_touch_up(struct wl_listener *listener, void *data) { } wlr_seat_touch_notify_up(seat->seat, event->time_msec, event->touch_id); - wlr_idle_notify_activity(seat->server->idle, seat->seat); + wlr_idle_notifier_v1_notify_activity(seat->server->idle, seat->seat); } static void @@ -638,7 +637,7 @@ handle_touch_motion(struct wl_listener *listener, void *data) { if(node && node->type == WLR_SCENE_NODE_BUFFER) { struct wlr_scene_surface *scene_surface = - wlr_scene_surface_from_buffer(wlr_scene_buffer_from_node(node)); + wlr_scene_surface_try_from_buffer(wlr_scene_buffer_from_node(node)); if(scene_surface != NULL) { wlr_seat_touch_point_focus(seat->seat, scene_surface->surface, @@ -657,7 +656,7 @@ handle_touch_motion(struct wl_listener *listener, void *data) { seat->touch_ly = ly; } - wlr_idle_notify_activity(seat->server->idle, seat->seat); + wlr_idle_notifier_v1_notify_activity(seat->server->idle, seat->seat); } static void @@ -665,7 +664,7 @@ handle_cursor_frame(struct wl_listener *listener, void *_data) { struct cg_seat *seat = wl_container_of(listener, seat, cursor_frame); wlr_seat_pointer_notify_frame(seat->seat); - wlr_idle_notify_activity(seat->server->idle, seat->seat); + wlr_idle_notifier_v1_notify_activity(seat->server->idle, seat->seat); } static void @@ -676,7 +675,7 @@ handle_cursor_axis(struct wl_listener *listener, void *data) { wlr_seat_pointer_notify_axis(seat->seat, event->time_msec, event->orientation, event->delta, event->delta_discrete, event->source); - wlr_idle_notify_activity(seat->server->idle, seat->seat); + wlr_idle_notifier_v1_notify_activity(seat->server->idle, seat->seat); } static void @@ -686,7 +685,7 @@ handle_cursor_button(struct wl_listener *listener, void *data) { wlr_seat_pointer_notify_button(seat->seat, event->time_msec, event->button, event->state); - wlr_idle_notify_activity(seat->server->idle, seat->seat); + wlr_idle_notifier_v1_notify_activity(seat->server->idle, seat->seat); } static void @@ -701,7 +700,7 @@ process_cursor_motion(struct cg_seat *seat, uint32_t time) { if(node && node->type == WLR_SCENE_NODE_BUFFER) { struct wlr_scene_surface *scene_surface = - wlr_scene_surface_from_buffer(wlr_scene_buffer_from_node(node)); + wlr_scene_surface_try_from_buffer(wlr_scene_buffer_from_node(node)); if(scene_surface != NULL) { surface = scene_surface->surface; if(surface != NULL) { @@ -722,7 +721,7 @@ process_cursor_motion(struct cg_seat *seat, uint32_t time) { drag_icon_update_position(drag_icon); } - wlr_idle_notify_activity(seat->server->idle, seat->seat); + wlr_idle_notifier_v1_notify_activity(seat->server->idle, seat->seat); /* Check if cursor switched tile */ struct wlr_output *c_outp = wlr_output_layout_output_at( @@ -749,7 +748,8 @@ process_cursor_motion(struct cg_seat *seat, uint32_t time) { break; } } - if(seat->cursor_tile != NULL && seat->cursor_tile != c_tile) { + if(seat->cursor_tile != NULL && seat->cursor_tile != c_tile && + seat->server->running) { ipc_send_event(seat->server, "{\"event_name\":\"cursor_switch_tile\",\"old_output\":" "\"%s\",\"old_output_id\":%d," @@ -772,7 +772,7 @@ handle_cursor_motion_absolute(struct wl_listener *listener, void *data) { wlr_cursor_warp_absolute(seat->cursor, &event->pointer->base, event->x, event->y); process_cursor_motion(seat, event->time_msec); - wlr_idle_notify_activity(seat->server->idle, seat->seat); + wlr_idle_notifier_v1_notify_activity(seat->server->idle, seat->seat); } static void @@ -783,7 +783,7 @@ handle_cursor_motion(struct wl_listener *listener, void *data) { wlr_cursor_move(seat->cursor, &event->pointer->base, event->delta_x, event->delta_y); process_cursor_motion(seat, event->time_msec); - wlr_idle_notify_activity(seat->server->idle, seat->seat); + wlr_idle_notifier_v1_notify_activity(seat->server->idle, seat->seat); } static void @@ -1043,6 +1043,7 @@ seat_set_focus(struct cg_seat *seat, struct cg_view *view) { view_activate(prev_view, false); } wlr_seat_keyboard_clear_focus(wlr_seat); + process_cursor_motion(seat, -1); return; } diff --git a/server.h b/server.h index 9f6eca6..0c067ec 100644 --- a/server.h +++ b/server.h @@ -26,17 +26,19 @@ struct cg_server { struct cg_seat *seat; struct cg_input_manager *input; struct wlr_backend *backend; - struct wlr_idle *idle; + struct wlr_idle_notifier_v1 *idle; struct wlr_idle_inhibit_manager_v1 *idle_inhibit_v1; struct wl_listener new_idle_inhibitor_v1; struct wl_list inhibitors; struct wlr_output_layout *output_layout; + struct wlr_scene_output_layout *scene_output_layout; struct wl_list disabled_outputs; struct wl_list outputs; struct cg_output *curr_output; struct wl_listener new_output; struct wl_list output_priorities; + struct wlr_session *session; struct wlr_renderer *renderer; struct wlr_allocator *allocator; diff --git a/signatures/2.1.1-cagebreak-config.5.sig b/signatures/2.1.1-cagebreak-config.5.sig new file mode 100644 index 0000000..e25e49c Binary files /dev/null and b/signatures/2.1.1-cagebreak-config.5.sig differ diff --git a/signatures/2.1.1-cagebreak-socket.7.sig b/signatures/2.1.1-cagebreak-socket.7.sig new file mode 100644 index 0000000..6b1a6a5 Binary files /dev/null and b/signatures/2.1.1-cagebreak-socket.7.sig differ diff --git a/signatures/2.1.1-cagebreak.1.sig b/signatures/2.1.1-cagebreak.1.sig new file mode 100644 index 0000000..7674f52 Binary files /dev/null and b/signatures/2.1.1-cagebreak.1.sig differ diff --git a/signatures/2.1.1-cagebreak.sig b/signatures/2.1.1-cagebreak.sig new file mode 100644 index 0000000..c71037f Binary files /dev/null and b/signatures/2.1.1-cagebreak.sig differ diff --git a/signatures/2.1.2-cagebreak-config.5.sig b/signatures/2.1.2-cagebreak-config.5.sig new file mode 100644 index 0000000..93f0f2b Binary files /dev/null and b/signatures/2.1.2-cagebreak-config.5.sig differ diff --git a/signatures/2.1.2-cagebreak-socket.7.sig b/signatures/2.1.2-cagebreak-socket.7.sig new file mode 100644 index 0000000..6797b53 Binary files /dev/null and b/signatures/2.1.2-cagebreak-socket.7.sig differ diff --git a/signatures/2.1.2-cagebreak.1.sig b/signatures/2.1.2-cagebreak.1.sig new file mode 100644 index 0000000..feaa1b9 Binary files /dev/null and b/signatures/2.1.2-cagebreak.1.sig differ diff --git a/signatures/2.1.2-cagebreak.sig b/signatures/2.1.2-cagebreak.sig new file mode 100644 index 0000000..4e3a176 Binary files /dev/null and b/signatures/2.1.2-cagebreak.sig differ diff --git a/signatures/2.2.1-cagebreak-config.5.sig b/signatures/2.2.1-cagebreak-config.5.sig new file mode 100644 index 0000000..4a959e1 Binary files /dev/null and b/signatures/2.2.1-cagebreak-config.5.sig differ diff --git a/signatures/2.2.1-cagebreak-socket.7.sig b/signatures/2.2.1-cagebreak-socket.7.sig new file mode 100644 index 0000000..c2006c1 Binary files /dev/null and b/signatures/2.2.1-cagebreak-socket.7.sig differ diff --git a/signatures/2.2.1-cagebreak.1.sig b/signatures/2.2.1-cagebreak.1.sig new file mode 100644 index 0000000..cdbd781 Binary files /dev/null and b/signatures/2.2.1-cagebreak.1.sig differ diff --git a/signatures/2.2.1-cagebreak.sig b/signatures/2.2.1-cagebreak.sig new file mode 100644 index 0000000..f24848b Binary files /dev/null and b/signatures/2.2.1-cagebreak.sig differ diff --git a/signatures/2.2.2-cagebreak-config.5.sig b/signatures/2.2.2-cagebreak-config.5.sig new file mode 100644 index 0000000..811fe37 Binary files /dev/null and b/signatures/2.2.2-cagebreak-config.5.sig differ diff --git a/signatures/2.2.2-cagebreak-socket.7.sig b/signatures/2.2.2-cagebreak-socket.7.sig new file mode 100644 index 0000000..e46522f Binary files /dev/null and b/signatures/2.2.2-cagebreak-socket.7.sig differ diff --git a/signatures/2.2.2-cagebreak.1.sig b/signatures/2.2.2-cagebreak.1.sig new file mode 100644 index 0000000..36b2c99 Binary files /dev/null and b/signatures/2.2.2-cagebreak.1.sig differ diff --git a/signatures/2.2.2-cagebreak.sig b/signatures/2.2.2-cagebreak.sig new file mode 100644 index 0000000..ca4ae14 Binary files /dev/null and b/signatures/2.2.2-cagebreak.sig differ diff --git a/signatures/cagebreak-config.5.sig b/signatures/cagebreak-config.5.sig index e25e49c..6d7f6c1 100644 Binary files a/signatures/cagebreak-config.5.sig and b/signatures/cagebreak-config.5.sig differ diff --git a/signatures/cagebreak-socket.7.sig b/signatures/cagebreak-socket.7.sig index 6b1a6a5..5e37733 100644 Binary files a/signatures/cagebreak-socket.7.sig and b/signatures/cagebreak-socket.7.sig differ diff --git a/signatures/cagebreak.1.sig b/signatures/cagebreak.1.sig index 7674f52..14ac7ab 100644 Binary files a/signatures/cagebreak.1.sig and b/signatures/cagebreak.1.sig differ diff --git a/signatures/cagebreak.sig b/signatures/cagebreak.sig index c71037f..b061305 100644 Binary files a/signatures/cagebreak.sig and b/signatures/cagebreak.sig differ diff --git a/test/environment-variables b/test/environment-variables index f1c9fac..a3753b5 100644 --- a/test/environment-variables +++ b/test/environment-variables @@ -22,7 +22,7 @@ cp "${MESONCURRENTCONFIGDIR}/test/testing-configurations/config" "${testdir}/env sed -i "s|CONFIGPATH|$testdir\/envvars\/socket|g" "${testdir}/envvars/config" (WLR_BACKENDS=headless ./cagebreak -e -c "${testdir}/envvars/config") sync -[[ ! $(cat "${testdir}/socket") = "${oldsocket}" ]] || RESULT=1 +[[ $(cat "${testdir}/envvars/socket") != "${oldsocket}" ]] || RESULT=1 # XDG_CONFIG_HOME cp "${MESONCURRENTCONFIGDIR}/test/testing-configurations/env-var-config" "${testdir}/cagebreak/config" diff --git a/view.c b/view.c index 99e2e7c..69ee5fe 100644 --- a/view.c +++ b/view.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include diff --git a/view.h b/view.h index a3b61ed..b9ec0a1 100644 --- a/view.h +++ b/view.h @@ -28,6 +28,10 @@ struct cg_view { struct cg_tile *tile; struct wlr_scene_tree *scene_tree; + struct wl_listener destroy; + struct wl_listener unmap; + struct wl_listener map; + /* The view has a position in output coordinates. */ int ox, oy; diff --git a/xdg_shell.c b/xdg_shell.c index afa3352..79f322f 100644 --- a/xdg_shell.c +++ b/xdg_shell.c @@ -23,12 +23,14 @@ static struct cg_view * popup_get_view(struct wlr_xdg_popup *popup) { while(true) { - if(popup->parent == NULL || - !wlr_surface_is_xdg_surface(popup->parent)) { + if(popup->parent == NULL) { return NULL; } struct wlr_xdg_surface *xdg_surface = - wlr_xdg_surface_from_wlr_surface(popup->parent); + wlr_xdg_surface_try_from_wlr_surface(popup->parent); + if(xdg_surface == NULL) { + return NULL; + } switch(xdg_surface->role) { case WLR_XDG_SURFACE_ROLE_TOPLEVEL: return xdg_surface->data; @@ -244,9 +246,10 @@ handle_xdg_shell_surface_new(struct wl_listener *listener, void *data) { xdg_shell_view->xdg_surface = xdg_surface; xdg_shell_view->map.notify = handle_xdg_shell_surface_map; - wl_signal_add(&xdg_surface->events.map, &xdg_shell_view->map); + wl_signal_add(&xdg_surface->surface->events.map, &xdg_shell_view->map); xdg_shell_view->unmap.notify = handle_xdg_shell_surface_unmap; - wl_signal_add(&xdg_surface->events.unmap, &xdg_shell_view->unmap); + wl_signal_add(&xdg_surface->surface->events.unmap, + &xdg_shell_view->unmap); xdg_shell_view->destroy.notify = handle_xdg_shell_surface_destroy; wl_signal_add(&xdg_surface->events.destroy, &xdg_shell_view->destroy); xdg_shell_view->request_fullscreen.notify = @@ -265,7 +268,10 @@ handle_xdg_shell_surface_new(struct wl_listener *listener, void *data) { struct wlr_scene_tree *parent_scene_tree = NULL; struct wlr_xdg_surface *parent = - wlr_xdg_surface_from_wlr_surface(popup->parent); + wlr_xdg_surface_try_from_wlr_surface(popup->parent); + if(parent == NULL) { + return; + } switch(parent->role) { case WLR_XDG_SURFACE_ROLE_TOPLEVEL:; parent_scene_tree = view->scene_tree; diff --git a/xwayland.c b/xwayland.c index ece9e5a..21cc2ba 100644 --- a/xwayland.c +++ b/xwayland.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include @@ -42,8 +41,12 @@ xwayland_view_should_manage(const struct cg_view *view) { static pid_t get_pid(const struct cg_view *view) { struct wlr_xwayland_surface *surf = - wlr_xwayland_surface_from_wlr_surface(view->wlr_surface); - return surf->pid; + wlr_xwayland_surface_try_from_wlr_surface(view->wlr_surface); + if(surf == NULL) { + return -1; + } else { + return surf->pid; + } } static char * @@ -154,8 +157,6 @@ handle_xwayland_surface_destroy(struct wl_listener *listener, void *_data) { wl_container_of(listener, xwayland_view, destroy); struct cg_view *view = &xwayland_view->view; - wl_list_remove(&xwayland_view->map.link); - wl_list_remove(&xwayland_view->unmap.link); wl_list_remove(&xwayland_view->destroy.link); wl_list_remove(&xwayland_view->request_fullscreen.link); xwayland_view->xwayland_surface = NULL; @@ -173,6 +174,25 @@ static const struct cg_view_impl xwayland_view_impl = { .destroy = destroy, }; +static void +handle_xwayland_surface_associate(struct wl_listener *listener, void *data) { + struct cg_xwayland_view *xwayland_view = + wl_container_of(listener, xwayland_view, associate); + struct wlr_xwayland_surface *xsurface = xwayland_view->xwayland_surface; + wl_signal_add(&xsurface->surface->events.unmap, &xwayland_view->unmap); + xwayland_view->unmap.notify = handle_xwayland_surface_unmap; + wl_signal_add(&xsurface->surface->events.map, &xwayland_view->map); + xwayland_view->map.notify = handle_xwayland_surface_map; +} + +static void +handle_xwayland_surface_dissociate(struct wl_listener *listener, void *data) { + struct cg_xwayland_view *xwayland_view = + wl_container_of(listener, xwayland_view, dissociate); + wl_list_remove(&xwayland_view->map.link); + wl_list_remove(&xwayland_view->unmap.link); +} + void handle_xwayland_surface_new(struct wl_listener *listener, void *data) { struct cg_server *server = @@ -190,10 +210,12 @@ handle_xwayland_surface_new(struct wl_listener *listener, void *data) { server); xwayland_view->xwayland_surface = xwayland_surface; - xwayland_view->map.notify = handle_xwayland_surface_map; - wl_signal_add(&xwayland_surface->events.map, &xwayland_view->map); - xwayland_view->unmap.notify = handle_xwayland_surface_unmap; - wl_signal_add(&xwayland_surface->events.unmap, &xwayland_view->unmap); + xwayland_view->associate.notify = handle_xwayland_surface_associate; + wl_signal_add(&xwayland_surface->events.associate, + &xwayland_view->associate); + xwayland_view->dissociate.notify = handle_xwayland_surface_dissociate; + wl_signal_add(&xwayland_surface->events.dissociate, + &xwayland_view->dissociate); xwayland_view->destroy.notify = handle_xwayland_surface_destroy; wl_signal_add(&xwayland_surface->events.destroy, &xwayland_view->destroy); xwayland_view->request_fullscreen.notify = diff --git a/xwayland.h b/xwayland.h index 71a0b7a..79c265a 100644 --- a/xwayland.h +++ b/xwayland.h @@ -13,6 +13,8 @@ struct cg_xwayland_view { struct wl_listener destroy; struct wl_listener unmap; struct wl_listener map; + struct wl_listener associate; + struct wl_listener dissociate; struct wl_listener request_fullscreen; };