Release 2.2.2

- Adjust Cagebreak to wlroot 0.17
- Improve README & SECURITY.md
This commit is contained in:
project-repo 2023-12-04 12:22:24 +01:00
commit 61fb97b070
40 changed files with 205 additions and 189 deletions

View file

@ -1,5 +1,25 @@
# Hashes
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

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.2.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.2)](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

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

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

@ -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>
@ -506,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;
}
@ -1627,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);
}
}
@ -1645,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;
@ -1688,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;

View file

@ -1,4 +1,4 @@
cagebreak-config(5) "Version 2.2.1" "Cagebreak Manual"
cagebreak-config(5) "Version 2.2.2" "Cagebreak Manual"
# NAME

View file

@ -1,4 +1,4 @@
cagebreak-socket(7) "Version 2.2.1" "Cagebreak Manual"
cagebreak-socket(7) "Version 2.2.2" "Cagebreak Manual"
# NAME

View file

@ -1,4 +1,4 @@
cagebreak(1) "Version 2.2.1" "Cagebreak Manual"
cagebreak(1) "Version 2.2.2" "Cagebreak Manual"
# NAME

View file

@ -3,7 +3,7 @@
project(
'cagebreak',
'c',
version : '2.2.1',
version : '2.2.2',
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.16.1', '< 0.17.1'])
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',
'libinput': '1.24.0',
'libevdev': '1.13.1',
'libudev': '254',
'pango': '1.50.14',
'cairo': '1.17.8',
'pangocairo': '1.50.14',
'pango': '1.51.0',
'cairo': '1.18.0',
'pangocairo': '1.51.0',
'math': '-1'
}
@ -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 = 1692353837
secssinceepoch = 1701680868
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);
@ -439,8 +438,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 +451,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 +500,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 +552,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 +562,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

@ -1,2 +1,2 @@
2.2.1
2023-08-21
2.2.2
2023-12-04

View file

@ -1,2 +1,2 @@
2.2.1
2023-08-21
2.2.2
2023-12-04

View file

@ -1,2 +1,2 @@
2.2.1
2023-08-21
2.2.2
2023-12-04

View file

@ -1,2 +1,2 @@
2.2.1
2023-08-21
2.2.2
2023-12-04

View file

@ -1,2 +1,2 @@
2.2.1
2023-08-21
2.2.2
2023-12-04

View file

@ -1,2 +1,2 @@
2.2.1
2023-08-21
2.2.2
2023-12-04

View file

@ -1,2 +1,2 @@
2.2.1
2023-08-21
2.2.2
2023-12-04

View file

@ -1,2 +1,2 @@
2.2.1
2023-08-21
2.2.2
2023-12-04

View file

@ -1,2 +1,2 @@
2.2.1
2023-08-21
2.2.2
2023-12-04

View file

@ -1,2 +1,2 @@
2.2.1
2023-08-21
2.2.2
2023-12-04

48
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

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.

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

@ -107,9 +107,6 @@ workspace_free_tiles(struct cg_workspace *workspace) {
workspace->focused_tile) {
workspace->output->server->seat->cursor_tile = NULL;
}
if(workspace->focused_tile == workspace->server->seat->cursor_tile) {
workspace->server->seat->cursor_tile = NULL;
}
struct cg_tile *next = workspace->focused_tile->next;
free(workspace->focused_tile);
workspace->focused_tile = next;

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