Merge branch 'hotfix' into feature/continuous-integration

This commit is contained in:
project-repo 2023-12-09 14:24:37 +01:00
commit a65f15babf
63 changed files with 454 additions and 228 deletions

82
Bugs.md
View file

@ -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.

View file

@ -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)

100
Hashes.md
View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -26,8 +26,8 @@
#include <wlr/types/wlr_data_device.h>
#include <wlr/types/wlr_export_dmabuf_v1.h>
#include <wlr/types/wlr_gamma_control_v1.h>
#include <wlr/types/wlr_idle.h>
#include <wlr/types/wlr_idle_inhibit_v1.h>
#include <wlr/types/wlr_idle_notify_v1.h>
#include <wlr/types/wlr_output_layout.h>
#include <wlr/types/wlr_presentation_time.h>
#include <wlr/types/wlr_primary_selection_v1.h>
@ -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);

View file

@ -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

View file

@ -25,10 +25,9 @@
#include <wlr/types/wlr_data_device.h>
#include <wlr/types/wlr_export_dmabuf_v1.h>
#include <wlr/types/wlr_gamma_control_v1.h>
#include <wlr/types/wlr_idle.h>
#include <wlr/types/wlr_idle_inhibit_v1.h>
#include <wlr/types/wlr_idle_notify_v1.h>
#include <wlr/types/wlr_keyboard_group.h>
#include <wlr/types/wlr_output_damage.h>
#include <wlr/types/wlr_output_layout.h>
#include <wlr/types/wlr_presentation_time.h>
#include <wlr/types/wlr_primary_selection_v1.h>
@ -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;

View file

@ -2,8 +2,8 @@
// SPDX-License-Identifier: MIT
#include <wayland-server-core.h>
#include <wlr/types/wlr_idle.h>
#include <wlr/types/wlr_idle_inhibit_v1.h>
#include <wlr/types/wlr_idle_notify_v1.h>
#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

View file

@ -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;
}

View file

@ -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;
}

View file

@ -11,7 +11,6 @@
#include <wlr/backend/session.h>
#include <wlr/types/wlr_cursor.h>
#include <wlr/types/wlr_keyboard_group.h>
#include <wlr/types/wlr_output_damage.h>
#include <wlr/types/wlr_output_layout.h>
#include <wlr/types/wlr_scene.h>
#include <wlr/types/wlr_xcursor_manager.h>
@ -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;

View file

@ -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) \

View file

@ -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 <message>*
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 <message>.
See *cagebreak-socket(7)* for more details.
*definekey <mode> <key> <command>*
Bind <key> to execute <command> if pressed in <mode> -
*definekey* is a more general version of *bind*.

View file

@ -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

View file

@ -1,4 +1,4 @@
cagebreak(1) "VERSION 2.1.1" "Cagebreak Manual"
cagebreak(1) "Version 2.2.3" "Cagebreak Manual"
# NAME

View file

@ -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')

View file

@ -12,7 +12,6 @@
#include <wlr/render/allocator.h>
#include <wlr/render/drm_format_set.h>
#include <wlr/render/wlr_renderer.h>
#include <wlr/types/wlr_output_damage.h>
#include <wlr/types/wlr_output_layout.h>
#include <wlr/types/wlr_scene.h>
#include <wlr/util/log.h>

View file

@ -15,9 +15,9 @@
#include <wlr/backend/x11.h>
#endif
#include <wlr/types/wlr_compositor.h>
#include <wlr/types/wlr_cursor.h>
#include <wlr/types/wlr_data_device.h>
#include <wlr/types/wlr_output.h>
#include <wlr/types/wlr_output_damage.h>
#include <wlr/types/wlr_output_layout.h>
#include <wlr/types/wlr_scene.h>
#include <wlr/types/wlr_xcursor_manager.h>
@ -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}",

View file

@ -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;

View file

@ -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) {

View file

@ -1,2 +1,2 @@
2.1.1
2023-04-17
2.2.3
2023-12-05

View file

@ -1,2 +1,2 @@
2.1.1
2023-04-17
2.2.3
2023-12-05

View file

@ -1,2 +1,2 @@
2.1.1
2023-04-17
2.2.3
2023-12-05

View file

@ -1,2 +1,2 @@
2.1.1
2023-04-17
2.2.3
2023-12-05

View file

@ -0,0 +1,2 @@
2.2.3
2023-12-05

View file

@ -1,2 +1,2 @@
2.1.1
2023-04-17
2.2.3
2023-12-05

View file

@ -1,2 +1,2 @@
2.1.1
2023-04-17
2.2.3
2023-12-05

View file

@ -1,2 +0,0 @@
2.1.1
2023-04-17

View file

@ -1,2 +1,2 @@
2.1.1
2023-04-17
2.2.3
2023-12-05

View file

@ -1,2 +1,2 @@
2.1.1
2023-04-17
2.2.3
2023-12-05

View file

@ -1,2 +1,2 @@
2.1.1
2023-04-17
2.2.3
2023-12-05

View file

@ -0,0 +1,2 @@
2.2.3
2023-12-05

0
scripts/install-development-environment Executable file → Normal file
View file

View file

@ -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

49
seat.c
View file

@ -14,7 +14,7 @@
#include <wlr/types/wlr_compositor.h>
#include <wlr/types/wlr_cursor.h>
#include <wlr/types/wlr_data_device.h>
#include <wlr/types/wlr_idle.h>
#include <wlr/types/wlr_idle_notify_v1.h>
#include <wlr/types/wlr_keyboard_group.h>
#include <wlr/types/wlr_primary_selection.h>
#include <wlr/types/wlr_scene.h>
@ -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;
}

View file

@ -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;

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -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"

1
view.c
View file

@ -8,7 +8,6 @@
#include <wayland-server-core.h>
#include <wlr/types/wlr_compositor.h>
#include <wlr/types/wlr_output.h>
#include <wlr/types/wlr_output_damage.h>
#include <wlr/types/wlr_output_layout.h>
#include <wlr/types/wlr_scene.h>
#include <wlr/util/box.h>

4
view.h
View file

@ -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;

View file

@ -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;

View file

@ -6,7 +6,6 @@
#include <X11/Xutil.h>
#include <stdbool.h>
#include <wayland-server-core.h>
#include <wlr/types/wlr_output_damage.h>
#include <wlr/types/wlr_output_layout.h>
#include <wlr/util/box.h>
#include <wlr/util/log.h>
@ -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 =

View file

@ -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;
};