From d2fbca623473bb75dba4a187716fba669bfac8c4 Mon Sep 17 00:00:00 2001 From: mcol Date: Tue, 3 Oct 2023 23:34:14 +0100 Subject: [PATCH 01/92] (wlroots 9f793d3) layer-shell-v1: specify version in constructor --- wlroots/ffi_build.py | 3 ++- wlroots/wlr_types/layer_shell_v1.py | 10 ++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index b2e6f0cc..23c6acf2 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -3169,7 +3169,8 @@ def has_xwayland() -> bool: ...; }; -struct wlr_layer_shell_v1 *wlr_layer_shell_v1_create(struct wl_display *display); +struct wlr_layer_shell_v1 *wlr_layer_shell_v1_create(struct wl_display *display, + uint32_t version); void wlr_layer_surface_v1_configure(struct wlr_layer_surface_v1 *surface, uint32_t width, uint32_t height); diff --git a/wlroots/wlr_types/layer_shell_v1.py b/wlroots/wlr_types/layer_shell_v1.py index 1698cd54..fc722336 100644 --- a/wlroots/wlr_types/layer_shell_v1.py +++ b/wlroots/wlr_types/layer_shell_v1.py @@ -197,10 +197,16 @@ def surface_at(self, sx: float, sy: float) -> tuple[Surface | None, float, float return Surface(surface_ptr), sub_x_data[0], sub_y_data[0] +LAYER_SHELL_VERSION = 4 + + class LayerShellV1(PtrHasData): - def __init__(self, display: Display) -> None: + def __init__(self, display: Display, version: int) -> None: """Create an wlr_xdg_output_manager_v1""" - self._ptr = lib.wlr_layer_shell_v1_create(display._ptr) + if not 0 < version <= LAYER_SHELL_VERSION: + raise ValueError("Invalid layer shell version.") + + self._ptr = lib.wlr_layer_shell_v1_create(display._ptr, version) self.new_surface_event = Signal( ptr=ffi.addressof(self._ptr.events.new_surface), data_wrapper=LayerSurfaceV1 From 53ef31205cce3526317632740e5dc198838c1677 Mon Sep 17 00:00:00 2001 From: mcol Date: Tue, 3 Oct 2023 23:53:44 +0100 Subject: [PATCH 02/92] (wlroots c8a5dfc) wlr_scene: Add drag icon helper --- wlroots/ffi_build.py | 3 +++ wlroots/wlr_types/scene.py | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 23c6acf2..22c7adac 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -1979,6 +1979,9 @@ def has_xwayland() -> bool: void wlr_scene_layer_surface_v1_configure( struct wlr_scene_layer_surface_v1 *scene_layer_surface, const struct wlr_box *full_area, struct wlr_box *usable_area); + +struct wlr_scene_tree *wlr_scene_drag_icon_create( + struct wlr_scene_tree *parent, struct wlr_drag_icon *drag_icon); """ # types/wlr_screencopy_v1.h diff --git a/wlroots/wlr_types/scene.py b/wlroots/wlr_types/scene.py index d34951cc..48782d3e 100644 --- a/wlroots/wlr_types/scene.py +++ b/wlroots/wlr_types/scene.py @@ -13,6 +13,7 @@ from wlroots.util.box import Box from wlroots.util.clock import Timespec from wlroots.wlr_types import Buffer, Output, OutputLayout + from wlroots.wlr_types.data_device_manager import DragIcon from wlroots.wlr_types.layer_shell_v1 import LayerSurfaceV1 from wlroots.wlr_types.presentation_time import Presentation from wlroots.wlr_types.xdg_shell import XdgSurface @@ -133,6 +134,10 @@ def subsurface_tree_create(cls, parent: SceneTree, surface: Surface) -> SceneTre lib.wlr_scene_subsurface_tree_create(parent._ptr, surface._ptr) ) + @classmethod + def drag_icon_create(cls, parent: SceneTree, drag_icon: DragIcon) -> SceneTree: + return SceneTree(lib.wlr_scene_drag_icon_create(parent._ptr, drag_icon._ptr)) + class SceneBuffer(Ptr): def __init__(self, ptr) -> None: From 83b6efc491d71e4b295289006a8712204eb5ac98 Mon Sep 17 00:00:00 2001 From: mcol Date: Wed, 4 Oct 2023 00:11:35 +0100 Subject: [PATCH 03/92] (wlroots 258bf9b) compositor: drop wlr_surface.{sx,sy} --- wlroots/ffi_build.py | 1 - wlroots/wlr_types/compositor.py | 10 ---------- 2 files changed, 11 deletions(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 22c7adac..4620deb4 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -373,7 +373,6 @@ def has_xwayland() -> bool: struct wl_resource *resource; struct wlr_renderer *renderer; struct wlr_client_buffer *buffer; - int sx, sy; struct pixman_region32 buffer_damage; struct pixman_region32 external_damage; struct pixman_region32 opaque_region; diff --git a/wlroots/wlr_types/compositor.py b/wlroots/wlr_types/compositor.py index 42d114fe..d9eae97a 100644 --- a/wlroots/wlr_types/compositor.py +++ b/wlroots/wlr_types/compositor.py @@ -71,16 +71,6 @@ def is_xwayland_surface(self) -> bool: """ return lib.wlr_surface_is_xwayland_surface(self._ptr) - @property - def sx(self) -> int: - """Surface local buffer x position""" - return self._ptr.sx - - @property - def sy(self) -> int: - """Surface local buffer y position""" - return self._ptr.sy - @property def current(self) -> SurfaceState: """The current commited surface state""" From fcc5f7e2e2c92360ff1ca5ad4089319678985858 Mon Sep 17 00:00:00 2001 From: mcol Date: Wed, 4 Oct 2023 00:58:57 +0100 Subject: [PATCH 04/92] (wlroots ff55663) output: introduce request_state event --- wlroots/ffi_build.py | 27 ++++++++++++++++++++++----- wlroots/wlr_types/output.py | 17 +++++++++++++++++ 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 4620deb4..2d2cbe25 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -1123,13 +1123,19 @@ def has_xwayland() -> bool: float scale; enum wl_output_subpixel subpixel; enum wl_output_transform transform; + enum wlr_output_adaptive_sync_status adaptive_sync_status; + uint32_t render_format; bool needs_frame; bool frame_pending; float transform_matrix[9]; + bool non_desktop; struct wlr_output_state pending; + // Commit sequence number. Incremented on each commit, may overflow. + uint32_t commit_seq; + struct { struct wl_signal frame; struct wl_signal damage; @@ -1141,24 +1147,35 @@ def has_xwayland() -> bool: struct wl_signal enable; struct wl_signal mode; struct wl_signal description; + struct wl_signal request_state; struct wl_signal destroy; } events; struct wl_event_source *idle_frame; struct wl_event_source *idle_done; - - int attach_render_locks; // number of locks forcing rendering - - struct wl_list cursors; // wlr_output_cursor::link + int attach_render_locks; + struct wl_list cursors; struct wlr_output_cursor *hardware_cursor; + struct wlr_swapchain *cursor_swapchain; + struct wlr_buffer *cursor_front_buffer; int software_cursor_locks; - + struct wlr_allocator *allocator; + struct wlr_renderer *renderer; + struct wlr_swapchain *swapchain; + struct wlr_buffer *back_buffer; struct wl_listener display_destroy; + struct wlr_addon_set addons; void *data; ...; }; +struct wlr_output_event_request_state { + struct wlr_output *output; + const struct wlr_output_state *state; + ...; +}; + void wlr_output_enable(struct wlr_output *output, bool enable); void wlr_output_create_global(struct wlr_output *output); void wlr_output_destroy_global(struct wlr_output *output); diff --git a/wlroots/wlr_types/output.py b/wlroots/wlr_types/output.py index e1895147..bc12b5c1 100644 --- a/wlroots/wlr_types/output.py +++ b/wlroots/wlr_types/output.py @@ -51,6 +51,10 @@ def __init__(self, ptr) -> None: self.enable_event = Signal(ptr=ffi.addressof(self._ptr.events.enable)) self.mode_event = Signal(ptr=ffi.addressof(self._ptr.events.mode)) self.description_event = Signal(ptr=ffi.addressof(self._ptr.events.description)) + self.request_state_event = Signal( + ptr=ffi.addressof(self._ptr.events.request_state), + data_wrapper=OutputEventRequestState, + ) self.destroy_event = Signal(ptr=ffi.addressof(self._ptr.events.destroy)) @property @@ -410,3 +414,16 @@ def custom_mode(self, mode: CustomMode) -> None: lib.wlr_output_state_set_custom_mode( self._ptr, mode.width, mode.height, mode.refresh ) + + +class OutputEventRequestState(Ptr): + def __init__(self, ptr) -> None: + self._ptr = ffi.cast("struct wlr_output_event_request_state *", ptr) + + @property + def output(self) -> Output: + return Output(self._ptr.output) + + @property + def state(self) -> OutputState: + return OutputState(self._ptr.state) From 0b1e927a0e3ae883d50442fe635de92c1b80a864 Mon Sep 17 00:00:00 2001 From: mcol Date: Wed, 4 Oct 2023 01:03:16 +0100 Subject: [PATCH 05/92] (wlroots a541c95) render: make wlr_renderer_begin return a bool --- wlroots/ffi_build.py | 2 +- wlroots/renderer.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 2d2cbe25..73a75277 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -154,7 +154,7 @@ def has_xwayland() -> bool: CDEF += """ struct wlr_renderer *wlr_renderer_autocreate(struct wlr_backend *backend); -void wlr_renderer_begin(struct wlr_renderer *r, int width, int height); +bool wlr_renderer_begin(struct wlr_renderer *r, int width, int height); void wlr_renderer_end(struct wlr_renderer *r); void wlr_renderer_clear(struct wlr_renderer *r, const float color[static 4]); diff --git a/wlroots/renderer.py b/wlroots/renderer.py index 329e903c..373fe923 100644 --- a/wlroots/renderer.py +++ b/wlroots/renderer.py @@ -50,9 +50,9 @@ def render(self, width: int, height: int) -> Iterator[Renderer]: finally: self.end() - def begin(self, width: int, height: int) -> None: + def begin(self, width: int, height: int) -> bool: """Begin rendering with the given height and width""" - lib.wlr_renderer_begin(self._ptr, width, height) + return lib.wlr_renderer_begin(self._ptr, width, height) def end(self): """Finish rendering""" From f2930bda372b8822ab42c1ae3b952fc754fd93ac Mon Sep 17 00:00:00 2001 From: mcol Date: Wed, 4 Oct 2023 01:05:54 +0100 Subject: [PATCH 06/92] (wlroots 8cfd449) input-inhibitor: deprecate --- wlroots/wlr_types/input_inhibit.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/wlroots/wlr_types/input_inhibit.py b/wlroots/wlr_types/input_inhibit.py index 7a31c0a3..ef44567b 100644 --- a/wlroots/wlr_types/input_inhibit.py +++ b/wlroots/wlr_types/input_inhibit.py @@ -1,5 +1,7 @@ # Copyright (c) 2021 Graeme Holliday +import warnings + from pywayland.server import Client, Display, Signal from wlroots import Ptr, ffi, lib @@ -8,6 +10,13 @@ class InputInhibitManager(Ptr): def __init__(self, display: Display) -> None: """Creates a wlr_input_inhibit_manager""" + warnings.warn( + "Following the protocol deprecation, wlr/types/wlr_input_inhibitor.h is" + " deprecated and will be removed in the next release.", + DeprecationWarning, + stacklevel=1, + ) + self._ptr = lib.wlr_input_inhibit_manager_create(display._ptr) self.activate_event = Signal(ptr=ffi.addressof(self._ptr.events.activate)) From d050f906638001d6b207ee843980baebee7a8dc2 Mon Sep 17 00:00:00 2001 From: mcol Date: Wed, 4 Oct 2023 01:12:29 +0100 Subject: [PATCH 07/92] (wlroots 41b7acb) backend: return wlr_session in wlr_backend_autocreate() call --- wlroots/backend.py | 2 +- wlroots/ffi_build.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/wlroots/backend.py b/wlroots/backend.py index d54d41ff..63d1d3e8 100644 --- a/wlroots/backend.py +++ b/wlroots/backend.py @@ -33,7 +33,7 @@ def __init__(self, display: Display, *, backend_type=BackendType.AUTO) -> None: $WLR_BACKENDS (to set the available backends). """ if backend_type == BackendType.AUTO: - ptr = lib.wlr_backend_autocreate(display._ptr) + ptr = lib.wlr_backend_autocreate(display._ptr, ffi.NULL) elif backend_type == BackendType.HEADLESS: ptr = lib.wlr_headless_backend_create(display._ptr) else: diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 73a75277..4c2040d6 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -114,7 +114,8 @@ def has_xwayland() -> bool: ...; }; -struct wlr_backend *wlr_backend_autocreate(struct wl_display *display); +struct wlr_backend *wlr_backend_autocreate(struct wl_display *display, + struct wlr_session **session_ptr); bool wlr_backend_start(struct wlr_backend *backend); void wlr_backend_destroy(struct wlr_backend *backend); From 295155a7cc3e0a76f59f8dfc0d56667b7b0a7421 Mon Sep 17 00:00:00 2001 From: mcol Date: Wed, 4 Oct 2023 23:11:14 +0100 Subject: [PATCH 08/92] (wlroots e7c556f) backend: drop wlr_backend_get_session() --- wlroots/backend.py | 14 ++++++++++---- wlroots/ffi_build.py | 1 - 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/wlroots/backend.py b/wlroots/backend.py index 63d1d3e8..34f79944 100644 --- a/wlroots/backend.py +++ b/wlroots/backend.py @@ -32,8 +32,12 @@ def __init__(self, display: Display, *, backend_type=BackendType.AUTO) -> None: backends), $WAYLAND_DISPLAY (for Wayland backends), and $WLR_BACKENDS (to set the available backends). """ + self.session: Session | None = None + if backend_type == BackendType.AUTO: - ptr = lib.wlr_backend_autocreate(display._ptr, ffi.NULL) + session_ptr = ffi.new("struct wlr_session **") + ptr = lib.wlr_backend_autocreate(display._ptr, session_ptr) + self.session = Session(session_ptr[0]) elif backend_type == BackendType.HEADLESS: ptr = lib.wlr_headless_backend_create(display._ptr) else: @@ -92,7 +96,9 @@ def __exit__(self, exc_type, exc_value, exc_tb) -> None: self.destroy() def get_session(self) -> Session: - return Session(self) + if self.session is None: + raise ValueError("Backend does not have a session") + return self.session @property def is_headless(self) -> bool: @@ -110,9 +116,9 @@ def is_multi(self) -> bool: class Session: - def __init__(self, backend: Backend) -> None: + def __init__(self, ptr) -> None: """The running session""" - self._ptr = lib.wlr_backend_get_session(backend._ptr) + self._ptr = ptr def change_vt(self, vt: int) -> bool: return lib.wlr_session_change_vt(self._ptr, vt) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 4c2040d6..26fcdf55 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -119,7 +119,6 @@ def has_xwayland() -> bool: bool wlr_backend_start(struct wlr_backend *backend); void wlr_backend_destroy(struct wlr_backend *backend); -struct wlr_session *wlr_backend_get_session(struct wlr_backend *backend); """ # wlr/backend/libinput.h From eb5c0ced0030a64a54ab0f037756b29810c9fd1c Mon Sep 17 00:00:00 2001 From: mcol Date: Wed, 4 Oct 2023 23:17:47 +0100 Subject: [PATCH 09/92] (wlroots 236918d) Nuke deprecated include/wlr/types/wlr_surface.h --- wlroots/wlr_types/surface.py | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 wlroots/wlr_types/surface.py diff --git a/wlroots/wlr_types/surface.py b/wlroots/wlr_types/surface.py deleted file mode 100644 index 31a47dff..00000000 --- a/wlroots/wlr_types/surface.py +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright Sean Vig (c) 2020 -# -# The contents of this module has been moved to compositor.py for wlroots 0.16.0 and -# this file will be removed in the future. - -import warnings - -from wlroots.wlr_types.compositor import * # noqa: F403 - -warnings.warn( - "wlroots.wlr_types.surface has moved to wlroots.wlr_types.compositor and will be removed in the future.", - DeprecationWarning, - stacklevel=1, -) From b7e2835cbc423882cebeda67fec0360f1b537255 Mon Sep 17 00:00:00 2001 From: mcol Date: Wed, 4 Oct 2023 23:29:04 +0100 Subject: [PATCH 10/92] (wlroots 42016fa) compositor: make renderer optional --- wlroots/wlr_types/compositor.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/wlroots/wlr_types/compositor.py b/wlroots/wlr_types/compositor.py index d9eae97a..0314b12e 100644 --- a/wlroots/wlr_types/compositor.py +++ b/wlroots/wlr_types/compositor.py @@ -20,7 +20,7 @@ class Compositor(Ptr): - def __init__(self, display: Display, renderer: Renderer) -> None: + def __init__(self, display: Display, renderer: Renderer | None = None) -> None: """A compositor for clients to be able to allocate surfaces :param display: @@ -28,7 +28,10 @@ def __init__(self, display: Display, renderer: Renderer) -> None: :param renderer: The wlroots renderer to attach the compositor to. """ - self._ptr = lib.wlr_compositor_create(display._ptr, renderer._ptr) + if renderer is None: + self._ptr = lib.wlr_compositor_create(display._ptr, ffi.NULL) + else: + self._ptr = lib.wlr_compositor_create(display._ptr, renderer._ptr) class SubCompositor(Ptr): From 999df6aa250fad42155429e1b268de24245ada02 Mon Sep 17 00:00:00 2001 From: mcol Date: Wed, 4 Oct 2023 23:31:24 +0100 Subject: [PATCH 11/92] (wlroots 060df4c) scene: introduce wlr_scene_buffer.events.outputs_update --- wlroots/ffi_build.py | 1 + 1 file changed, 1 insertion(+) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 26fcdf55..9cdfcadc 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -1857,6 +1857,7 @@ def has_xwayland() -> bool: struct wlr_buffer *buffer; struct { + struct wl_signal outputs_update; struct wl_signal output_enter; // struct wlr_scene_output struct wl_signal output_leave; // struct wlr_scene_output struct wl_signal output_present; // struct wlr_scene_output From 493f5e0d5b5854bafa99f02a67d5a3d11f9ea6c6 Mon Sep 17 00:00:00 2001 From: mcol Date: Wed, 4 Oct 2023 23:41:44 +0100 Subject: [PATCH 12/92] (wlroots f103dc74) linux-dmabuf-v1: introduce wlr_linux_dmabuf_v1_create() --- wlroots/ffi_build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 9cdfcadc..8eacde89 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -1025,7 +1025,7 @@ def has_xwayland() -> bool: # types/wlr_linux_dmabuf_v1.h CDEF += """ struct wlr_linux_dmabuf_v1 *wlr_linux_dmabuf_v1_create(struct wl_display *display, - struct wlr_renderer *renderer); + uint32_t version, const struct wlr_linux_dmabuf_feedback_v1 *default_feedback); """ # types/wlr_matrix.h From 5c6104611ba6b74bea5781a41bc8df4229e0263a Mon Sep 17 00:00:00 2001 From: mcol Date: Wed, 4 Oct 2023 23:42:09 +0100 Subject: [PATCH 13/92] (wlroots 19dfe99) output-damage: stop listening for output mode events --- wlroots/ffi_build.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 8eacde89..bcd81715 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -1254,13 +1254,6 @@ def has_xwayland() -> bool: struct wl_signal frame; struct wl_signal destroy; } events; - - struct wl_listener output_destroy; - struct wl_listener output_mode; - struct wl_listener output_needs_frame; - struct wl_listener output_damage; - struct wl_listener output_frame; - struct wl_listener output_commit; ...; }; From 143e1ba5464262f62bbc645b0855e8a8ed34a683 Mon Sep 17 00:00:00 2001 From: mcol Date: Thu, 5 Oct 2023 00:21:32 +0100 Subject: [PATCH 14/92] (wlroots c8eb24d) output: drop enable/mode events --- wlroots/ffi_build.py | 2 -- wlroots/wlr_types/output.py | 2 -- 2 files changed, 4 deletions(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index bcd81715..98689fee 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -1144,8 +1144,6 @@ def has_xwayland() -> bool: struct wl_signal commit; struct wl_signal present; struct wl_signal bind; - struct wl_signal enable; - struct wl_signal mode; struct wl_signal description; struct wl_signal request_state; struct wl_signal destroy; diff --git a/wlroots/wlr_types/output.py b/wlroots/wlr_types/output.py index bc12b5c1..577f1fd3 100644 --- a/wlroots/wlr_types/output.py +++ b/wlroots/wlr_types/output.py @@ -48,8 +48,6 @@ def __init__(self, ptr) -> None: self.commit_event = Signal(ptr=ffi.addressof(self._ptr.events.commit)) self.present_event = Signal(ptr=ffi.addressof(self._ptr.events.present)) self.bind_event = Signal(ptr=ffi.addressof(self._ptr.events.bind)) - self.enable_event = Signal(ptr=ffi.addressof(self._ptr.events.enable)) - self.mode_event = Signal(ptr=ffi.addressof(self._ptr.events.mode)) self.description_event = Signal(ptr=ffi.addressof(self._ptr.events.description)) self.request_state_event = Signal( ptr=ffi.addressof(self._ptr.events.request_state), From 012fa9d2ebd58965edf899a4e267b340838b823a Mon Sep 17 00:00:00 2001 From: mcol Date: Thu, 5 Oct 2023 00:25:06 +0100 Subject: [PATCH 15/92] (wlroots 512deeb) compositor: add wlr_surface.events.precommit --- wlroots/ffi_build.py | 1 + wlroots/wlr_types/compositor.py | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 98689fee..962fee58 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -386,6 +386,7 @@ def has_xwayland() -> bool: struct { struct wl_signal client_commit; + struct wl_signal precommit; struct wl_signal commit; struct wl_signal new_subsurface; struct wl_signal destroy; diff --git a/wlroots/wlr_types/compositor.py b/wlroots/wlr_types/compositor.py index 0314b12e..f7574086 100644 --- a/wlroots/wlr_types/compositor.py +++ b/wlroots/wlr_types/compositor.py @@ -48,6 +48,10 @@ def __init__(self, ptr) -> None: """ self._ptr = ptr + self.precommit_event = Signal( + ptr=ffi.addressof(self._ptr.events.precommit), + data_wrapper=SurfaceState, + ) self.commit_event = Signal(ptr=ffi.addressof(self._ptr.events.commit)) self.new_subsurface_event = Signal( ptr=ffi.addressof(self._ptr.events.new_subsurface), From 8ce44dac8ca2e7c96d46da4e8478422955ac7956 Mon Sep 17 00:00:00 2001 From: mcol Date: Thu, 5 Oct 2023 22:15:46 +0100 Subject: [PATCH 16/92] (wlroots 097ea84) output-layout: improve API --- wlroots/ffi_build.py | 7 ++----- wlroots/wlr_types/output_layout.py | 32 +++++++++++++----------------- 2 files changed, 16 insertions(+), 23 deletions(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 962fee58..576d8cfb 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -1295,10 +1295,7 @@ def has_xwayland() -> bool: struct wlr_output *reference, double lx, double ly, double *dest_lx, double *dest_ly); -void wlr_output_layout_add(struct wlr_output_layout *layout, - struct wlr_output *output, int lx, int ly); - -void wlr_output_layout_move(struct wlr_output_layout *layout, +bool wlr_output_layout_add(struct wlr_output_layout *layout, struct wlr_output *output, int lx, int ly); void wlr_output_layout_remove(struct wlr_output_layout *layout, @@ -1307,7 +1304,7 @@ def has_xwayland() -> bool: void wlr_output_layout_get_box(struct wlr_output_layout *layout, struct wlr_output *reference, struct wlr_box *dest_box); -void wlr_output_layout_add_auto(struct wlr_output_layout *layout, +bool wlr_output_layout_add_auto(struct wlr_output_layout *layout, struct wlr_output *output); struct wlr_output *wlr_output_layout_output_at(struct wlr_output_layout *layout, diff --git a/wlroots/wlr_types/output_layout.py b/wlroots/wlr_types/output_layout.py index a7bf3a73..b5e29f9f 100644 --- a/wlroots/wlr_types/output_layout.py +++ b/wlroots/wlr_types/output_layout.py @@ -31,19 +31,16 @@ def destroy(self) -> None: ffi.release(self._ptr) self._ptr = None - def add_auto(self, output: Output) -> None: - """Add an auto configured output to the layout - - This will place the output in a sensible location in the layout. The - coordinates of the output in the layout may adjust dynamically when the - layout changes. If the output is already in the layout, it will become - auto configured. If the position of the output is set such as with - `wlr_output_layout_move()`, the output will become manually configured. + def add_auto(self, output: Output) -> bool: + """ + Add the output to the layout as automatically configured. This will place the + output in a sensible location in the layout. The coordinates of the output in + the layout will be adjusted dynamically when the layout changes. If the output + is already a part of the layout, it will become automatically configured. - :param output: - The output to configure the layout against. + Returns true on success, false on a memory allocation error. """ - lib.wlr_output_layout_add_auto(self._ptr, output._ptr) + return lib.wlr_output_layout_add_auto(self._ptr, output._ptr) def output_coords(self, output: Output) -> tuple[float, float]: """Determine coordinates of the output in the layout @@ -75,16 +72,15 @@ def output_at(self, x: float, y: float) -> Output | None: return None return Output(output_ptr) - def add(self, output: Output, lx: int, ly: int) -> None: + def add(self, output: Output, lx: int, ly: int) -> bool: """ Add the output to the layout at the specified coordinates. If the output is - already part of the output layout, this moves the output. - """ - lib.wlr_output_layout_add(self._ptr, output._ptr, lx, ly) + already a part of the output layout, it will become manually configured and will + be moved to the specified coordinates. - def move(self, output: Output, lx: int, ly: int) -> None: - """Move an output to specified coordinates.""" - lib.wlr_output_layout_move(self._ptr, output._ptr, lx, ly) + Returns true on success, false on a memory allocation error. + """ + return lib.wlr_output_layout_add(self._ptr, output._ptr, lx, ly) def remove(self, output: Output) -> None: """Remove an output from the layout.""" From e3b88eb9df201d1df8a9cb727c1deea6ffd11a15 Mon Sep 17 00:00:00 2001 From: mcol Date: Thu, 5 Oct 2023 22:18:31 +0100 Subject: [PATCH 17/92] (wlroots f8e70af) wlr_xdg_activation_v1: add new_token event --- wlroots/ffi_build.py | 1 + 1 file changed, 1 insertion(+) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 576d8cfb..151e7f37 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -2573,6 +2573,7 @@ def has_xwayland() -> bool: struct { struct wl_signal destroy; struct wl_signal request_activate; + struct wl_signal new_token; } events; ...; }; From 50c461418e6c8313d6b65e06ceaec022e972feeb Mon Sep 17 00:00:00 2001 From: mcol Date: Thu, 5 Oct 2023 22:25:25 +0100 Subject: [PATCH 18/92] add method for wlr_output_commit_state --- wlroots/wlr_types/output.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/wlroots/wlr_types/output.py b/wlroots/wlr_types/output.py index 577f1fd3..5be068a3 100644 --- a/wlroots/wlr_types/output.py +++ b/wlroots/wlr_types/output.py @@ -202,6 +202,10 @@ def rollback(self) -> None: """Discard the pending output state""" lib.wlr_output_rollback(self._ptr) + def commit_state(self, state: OutputEventRequestState) -> None: + """Commit requested state""" + lib.wlr_output_commit_state(self._ptr, state._ptr) + def effective_resolution(self) -> tuple[int, int]: """Computes the transformed and scaled output resolution""" width_ptr = ffi.new("int *") From 5f148b0f92f707c2964107f15a1689f72263561b Mon Sep 17 00:00:00 2001 From: mcol Date: Thu, 5 Oct 2023 22:35:24 +0100 Subject: [PATCH 19/92] (wlroots 7f6d646) keyboard: only update LEDs when changed --- wlroots/ffi_build.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 151e7f37..96bc462d 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -974,11 +974,13 @@ def has_xwayland() -> bool: char *keymap_string; size_t keymap_size; + int keymap_fd; struct xkb_keymap *keymap; struct xkb_state *xkb_state; xkb_led_index_t led_indexes[WLR_LED_COUNT]; xkb_mod_index_t mod_indexes[WLR_MODIFIER_COUNT]; + uint32_t leds; uint32_t keycodes[WLR_KEYBOARD_KEYS_CAP]; size_t num_keycodes; struct wlr_keyboard_modifiers modifiers; From df5d12b89b30cfd3b8520ec2317f6e9c5e5477ad Mon Sep 17 00:00:00 2001 From: mcol Date: Thu, 5 Oct 2023 22:44:23 +0100 Subject: [PATCH 20/92] (wlroots df0c926) xdg-shell: rename wlr_xdg_toplevel.added to sent_initial_configure --- wlroots/ffi_build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 96bc462d..5bf4074b 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -2819,7 +2819,7 @@ def has_xwayland() -> bool: struct wlr_xdg_toplevel { struct wl_resource *resource; struct wlr_xdg_surface *base; - bool added; + bool sent_initial_configure; struct wlr_xdg_toplevel *parent; struct wl_listener parent_unmap; From bef1ac6df73e9ffbfdfe364bfe88216442ce3f14 Mon Sep 17 00:00:00 2001 From: mcol Date: Thu, 5 Oct 2023 22:45:50 +0100 Subject: [PATCH 21/92] (wlroots 0f24d27) xdg-shell: rename wlr_xdg_popup.committed to sent_initial_configure --- wlroots/ffi_build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 5bf4074b..96937fd1 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -2774,7 +2774,7 @@ def has_xwayland() -> bool: struct wl_list link; struct wl_resource *resource; - bool committed; + bool sent_initial_configure; struct wlr_surface *parent; struct wlr_seat *seat; From 98a88879c51ba924a4b2b9171596376efb6529cc Mon Sep 17 00:00:00 2001 From: mcol Date: Thu, 5 Oct 2023 22:59:00 +0100 Subject: [PATCH 22/92] (wlroots fbf5982) xwayland/xwm: introduce wlr_xwayland_surface_try_from_wlr_surface() --- wlroots/ffi_build.py | 3 +-- wlroots/wlr_types/compositor.py | 9 --------- wlroots/xwayland.py | 7 +++++-- 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 96937fd1..339b206f 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -3411,8 +3411,7 @@ def has_xwayland() -> bool: bool fullscreen); void wlr_xwayland_set_seat(struct wlr_xwayland *xwayland, struct wlr_seat *seat); - bool wlr_surface_is_xwayland_surface(struct wlr_surface *surface); - struct wlr_xwayland_surface *wlr_xwayland_surface_from_wlr_surface( + struct wlr_xwayland_surface *wlr_xwayland_surface_try_from_wlr_surface( struct wlr_surface *surface); void wlr_xwayland_surface_ping(struct wlr_xwayland_surface *surface); bool wlr_xwayland_or_surface_wants_focus( diff --git a/wlroots/wlr_types/compositor.py b/wlroots/wlr_types/compositor.py index f7574086..f264f8d2 100644 --- a/wlroots/wlr_types/compositor.py +++ b/wlroots/wlr_types/compositor.py @@ -69,15 +69,6 @@ def is_layer_surface(self) -> bool: """True if the current surface is a layer surface""" return lib.wlr_surface_is_layer_surface(self._ptr) - @property - def is_xwayland_surface(self) -> bool: - """ - True if the current surface is an XWayland surface. - - Requires that pywlroots was built with XWayland support. - """ - return lib.wlr_surface_is_xwayland_surface(self._ptr) - @property def current(self) -> SurfaceState: """The current commited surface state""" diff --git a/wlroots/xwayland.py b/wlroots/xwayland.py index e5c052d0..496deee8 100644 --- a/wlroots/xwayland.py +++ b/wlroots/xwayland.py @@ -224,8 +224,11 @@ def set_fullscreen(self, fullscreen: bool) -> None: lib.wlr_xwayland_surface_set_fullscreen(self._ptr, fullscreen) @classmethod - def from_wlr_surface(cls, surface: WlrSurface) -> Surface: - return cls(lib.wlr_xwayland_surface_from_wlr_surface(surface._ptr)) + def try_from_wlr_surface(cls, surface: WlrSurface) -> Surface | None: + maybe_ptr = lib.wlr_xwayland_surface_try_from_wlr_surface(surface._ptr) + if maybe_ptr == ffi.NULL: + return None + return cls(maybe_ptr) def ping(self) -> None: lib.wlr_xwayland_surface_ping(self._ptr) From d0e8ccf0964ebadb676ae0a903f3279f9ed6ff5d Mon Sep 17 00:00:00 2001 From: mcol Date: Thu, 5 Oct 2023 23:12:54 +0100 Subject: [PATCH 23/92] (wlroots 711a1a3) xdg-shell: convert to try_from --- wlroots/ffi_build.py | 3 +-- wlroots/wlr_types/compositor.py | 5 ----- wlroots/wlr_types/xdg_shell.py | 12 ++++++------ 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 339b206f..5bb6cf50 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -2965,9 +2965,8 @@ def has_xwayland() -> bool: struct wlr_surface *wlr_xdg_surface_surface_at( struct wlr_xdg_surface *surface, double sx, double sy, double *sub_x, double *sub_y); -bool wlr_surface_is_xdg_surface(struct wlr_surface *surface); -struct wlr_xdg_surface *wlr_xdg_surface_from_wlr_surface( +struct wlr_xdg_surface *wlr_xdg_surface_try_from_wlr_surface( struct wlr_surface *surface); void wlr_xdg_surface_get_geometry(struct wlr_xdg_surface *surface, diff --git a/wlroots/wlr_types/compositor.py b/wlroots/wlr_types/compositor.py index f264f8d2..a71f48d7 100644 --- a/wlroots/wlr_types/compositor.py +++ b/wlroots/wlr_types/compositor.py @@ -59,11 +59,6 @@ def __init__(self, ptr) -> None: ) self.destroy_event = Signal(ptr=ffi.addressof(self._ptr.events.destroy)) - @property - def is_xdg_surface(self) -> bool: - """True if the current surface is an XDG surface""" - return lib.wlr_surface_is_xdg_surface(self._ptr) - @property def is_layer_surface(self) -> bool: """True if the current surface is a layer surface""" diff --git a/wlroots/wlr_types/xdg_shell.py b/wlroots/wlr_types/xdg_shell.py index 27742afa..4afdf229 100644 --- a/wlroots/wlr_types/xdg_shell.py +++ b/wlroots/wlr_types/xdg_shell.py @@ -87,13 +87,13 @@ def __init__(self, ptr) -> None: data_wrapper=XdgSurfaceConfigure, ) - @staticmethod - def from_surface(surface: Surface) -> XdgSurface: + @classmethod + def try_from_surface(cls, surface: Surface) -> XdgSurface | None: """Get the xdg surface associated with the given surface""" - if not surface.is_xdg_surface: - raise RuntimeError("Surface is not XDG surface") - surface_ptr = lib.wlr_xdg_surface_from_wlr_surface(surface._ptr) - return XdgSurface(surface_ptr) + maybe_ptr = lib.wlr_xdg_surface_try_from_wlr_surface(surface._ptr) + if maybe_ptr == ffi.NULL: + return None + return XdgSurface(maybe_ptr) @property def surface(self) -> Surface: From eb3d921dcf6ad41b0e096433973e260ac50275c4 Mon Sep 17 00:00:00 2001 From: mcol Date: Thu, 5 Oct 2023 23:19:33 +0100 Subject: [PATCH 24/92] (wlroots f9bd416) layer-shell-v1: convert to try_from --- wlroots/ffi_build.py | 4 +--- wlroots/wlr_types/compositor.py | 5 ----- wlroots/wlr_types/layer_shell_v1.py | 12 +++++++----- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 5bb6cf50..86711f4f 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -3188,9 +3188,7 @@ def has_xwayland() -> bool: void wlr_layer_surface_v1_destroy(struct wlr_layer_surface_v1 *surface); -bool wlr_surface_is_layer_surface(struct wlr_surface *surface); - -struct wlr_layer_surface_v1 *wlr_layer_surface_v1_from_wlr_surface( +struct wlr_layer_surface_v1 *wlr_layer_surface_v1_try_from_wlr_surface( struct wlr_surface *surface); void wlr_layer_surface_v1_for_each_surface(struct wlr_layer_surface_v1 *surface, diff --git a/wlroots/wlr_types/compositor.py b/wlroots/wlr_types/compositor.py index a71f48d7..3d023aed 100644 --- a/wlroots/wlr_types/compositor.py +++ b/wlroots/wlr_types/compositor.py @@ -59,11 +59,6 @@ def __init__(self, ptr) -> None: ) self.destroy_event = Signal(ptr=ffi.addressof(self._ptr.events.destroy)) - @property - def is_layer_surface(self) -> bool: - """True if the current surface is a layer surface""" - return lib.wlr_surface_is_layer_surface(self._ptr) - @property def current(self) -> SurfaceState: """The current commited surface state""" diff --git a/wlroots/wlr_types/layer_shell_v1.py b/wlroots/wlr_types/layer_shell_v1.py index fc722336..9e88d5aa 100644 --- a/wlroots/wlr_types/layer_shell_v1.py +++ b/wlroots/wlr_types/layer_shell_v1.py @@ -162,11 +162,13 @@ def configure(self, width: int, height: int) -> None: def destroy(self) -> None: lib.wlr_layer_surface_v1_destroy(self._ptr) - @staticmethod - def from_wlr_surface(surface: Surface): - surface_ptr = lib.wlr_layer_surface_v1_from_wlr_surface(surface._ptr) - _weakkeydict[surface_ptr] = surface._ptr - return LayerSurfaceV1(surface_ptr) + @classmethod + def try_from_wlr_surface(cls, surface: Surface) -> LayerSurfaceV1 | None: + maybe_ptr = lib.wlr_layer_surface_v1_try_from_wlr_surface(surface._ptr) + if maybe_ptr == ffi.NULL: + return None + _weakkeydict[maybe_ptr] = maybe_ptr._ptr + return LayerSurfaceV1(maybe_ptr) def for_each_surface( self, iterator: SurfaceCallback[T], data: T | None = None From b9646430399b4611fec98cf5895cb782bd340cbb Mon Sep 17 00:00:00 2001 From: mcol Date: Thu, 5 Oct 2023 23:35:40 +0100 Subject: [PATCH 25/92] (wlroots 7b32c25) wlr_scene: Rename wlr_scene_surface_from_buffer --- wlroots/ffi_build.py | 7 +------ wlroots/wlr_types/scene.py | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 86711f4f..5de32e39 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -489,11 +489,6 @@ def has_xwayland() -> bool: ...; }; -bool wlr_surface_is_subsurface(struct wlr_surface *surface); - -struct wlr_subsurface *wlr_subsurface_from_wlr_surface( - struct wlr_surface *surface); - struct wlr_subcompositor *wlr_subcompositor_create(struct wl_display *display); """ @@ -1919,7 +1914,7 @@ def has_xwayland() -> bool: struct wlr_scene_buffer *wlr_scene_buffer_from_node(struct wlr_scene_node *node); -struct wlr_scene_surface *wlr_scene_surface_from_buffer( +struct wlr_scene_surface *wlr_scene_surface_try_from_buffer( struct wlr_scene_buffer *scene_buffer); struct wlr_scene_rect *wlr_scene_rect_create(struct wlr_scene_tree *parent, diff --git a/wlroots/wlr_types/scene.py b/wlroots/wlr_types/scene.py index 48782d3e..aba24815 100644 --- a/wlroots/wlr_types/scene.py +++ b/wlroots/wlr_types/scene.py @@ -285,7 +285,7 @@ def __init__(self, ptr) -> None: @classmethod def from_buffer(cls, buffer: SceneBuffer) -> SceneSurface | None: - ptr = lib.wlr_scene_surface_from_buffer(buffer._ptr) + ptr = lib.wlr_scene_surface_try_from_buffer(buffer._ptr) if ptr == ffi.NULL: return None return cls(ptr) From ea89d0c50d76ff5226738ff50e00e2a53f657937 Mon Sep 17 00:00:00 2001 From: mcol Date: Thu, 5 Oct 2023 23:44:57 +0100 Subject: [PATCH 26/92] (wlroots 0682802) xwayland: Read and publish _NET_WM_STRUT_PARTIAL property --- wlroots/ffi_build.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 5de32e39..2782b908 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -3209,6 +3209,9 @@ def has_xwayland() -> bool: typedef struct { ...; } xcb_generic_event_t; + typedef struct { + ...; + } xcb_ewmh_wm_strut_partial_t; typedef uint32_t xcb_pixmap_t; typedef uint32_t xcb_window_t; typedef uint32_t xcb_atom_t; @@ -3292,10 +3295,14 @@ def has_xwayland() -> bool: xcb_window_t window_id; struct wlr_xwm *xwm; uint32_t surface_id; + uint64_t serial; struct wl_list link; struct wl_list stack_link; struct wl_list unpaired_link; struct wlr_surface *surface; + struct wlr_addon surface_addon; + struct wl_listener surface_commit; + struct wl_listener surface_precommit; int16_t x, y; uint16_t width, height; uint16_t saved_width, saved_height; @@ -3318,9 +3325,9 @@ def has_xwayland() -> bool: uint32_t decorations; xcb_icccm_wm_hints_t *hints; xcb_size_hints_t *size_hints; + xcb_ewmh_wm_strut_partial_t *strut_partial; bool pinging; struct wl_event_source *ping_timer; - // _NET_WM_STATE bool modal; bool fullscreen; bool maximized_vert, maximized_horz; @@ -3346,6 +3353,7 @@ def has_xwayland() -> bool: struct wl_signal set_window_type; struct wl_signal set_hints; struct wl_signal set_decorations; + struct wl_signal set_strut_partial; struct wl_signal set_override_redirect; struct wl_signal set_geometry; struct wl_signal ping_timeout; From a5dab5f2960031f14350e75327d3e7791b4fe15e Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 6 Oct 2023 11:52:08 +0100 Subject: [PATCH 27/92] (wlroots 9ef9845) output-damage: drop --- wlroots/ffi_build.py | 37 -------------- wlroots/wlr_types/__init__.py | 3 +- wlroots/wlr_types/output_damage.py | 78 ------------------------------ 3 files changed, 1 insertion(+), 117 deletions(-) delete mode 100644 wlroots/wlr_types/output_damage.py diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 2782b908..6819f7a5 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -1232,42 +1232,6 @@ def has_xwayland() -> bool: """ -# types/wlr_output_damage.h -CDEF += """ -#define WLR_OUTPUT_DAMAGE_PREVIOUS_LEN 2 - -struct wlr_output_damage { - struct wlr_output *output; - int max_rects; // max number of damaged rectangles - - struct pixman_region32 current; // in output-local coordinates - - // circular queue for previous damage - struct pixman_region32 previous[WLR_OUTPUT_DAMAGE_PREVIOUS_LEN]; - size_t previous_idx; - - struct { - struct wl_signal frame; - struct wl_signal destroy; - } events; - ...; -}; - -struct wlr_output_damage *wlr_output_damage_create(struct wlr_output *output); -void wlr_output_damage_destroy(struct wlr_output_damage *output_damage); - -bool wlr_output_damage_attach_render(struct wlr_output_damage *output_damage, - bool *needs_frame, struct pixman_region32 *buffer_damage); - -void wlr_output_damage_add(struct wlr_output_damage *output_damage, - struct pixman_region32 *damage); - -void wlr_output_damage_add_whole(struct wlr_output_damage *output_damage); - -void wlr_output_damage_add_box(struct wlr_output_damage *output_damage, - struct wlr_box *box); -""" - # types/wlr_output_layout.h CDEF += """ struct wlr_output_layout { @@ -3058,7 +3022,6 @@ def has_xwayland() -> bool: #include #include #include -#include #include #include #include diff --git a/wlroots/wlr_types/__init__.py b/wlroots/wlr_types/__init__.py index 78952fdf..b261a2a3 100644 --- a/wlroots/wlr_types/__init__.py +++ b/wlroots/wlr_types/__init__.py @@ -19,8 +19,7 @@ from .keyboard import Keyboard # noqa: F401 from .layer_shell_v1 import LayerShellV1 # noqa: F401 from .matrix import Matrix # noqa: F401 -from .output import Output, OutputState # noqa: F401 -from .output_damage import OutputDamage # noqa: F401 +from .output import Output # noqa: F401 from .output_layout import OutputLayout # noqa: F401 from .pointer import ( # noqa: F401 PointerAxisEvent, diff --git a/wlroots/wlr_types/output_damage.py b/wlroots/wlr_types/output_damage.py deleted file mode 100644 index 9d58bedf..00000000 --- a/wlroots/wlr_types/output_damage.py +++ /dev/null @@ -1,78 +0,0 @@ -# Copyright (c) Matt Colligan 2021 - -from pywayland.server import Signal - -from wlroots import Ptr, ffi, lib -from wlroots.util.box import Box -from wlroots.util.region import PixmanRegion32 - -from .output import Output - - -class OutputDamage(Ptr): - def __init__(self, output: Output) -> None: - """ - Tracks damage for an output. - - The `frame` event will be emitted when it is a good time for the compositor - to submit a new frame. - - To render a new frame, compositors should call - `wlr_output_damage_attach_render`, render and call `wlr_output_commit`. No - rendering should happen outside a `frame` event handler or before - `wlr_output_damage_attach_render`. - """ - self._ptr = lib.wlr_output_damage_create(output._ptr) - - self.frame_event = Signal(ptr=ffi.addressof(self._ptr.events.frame)) - self.destroy_event = Signal(ptr=ffi.addressof(self._ptr.events.destroy)) - - @property - def output(self) -> Output: - """The name of the output""" - return Output(self._ptr.output) - - @property - def current(self) -> PixmanRegion32: - return PixmanRegion32(ffi.addressof(self._ptr.current)) - - def destroy(self) -> None: - """The name of the output""" - lib.wlr_output_damage_destroy(self._ptr) - self._ptr = None - - def attach_render(self, damage: PixmanRegion32) -> bool: - """ - Attach the renderer's buffer to the output. Compositors must call this - function before rendering. After they are done rendering, they should call - `wlr_output_set_damage` and `wlr_output_commit` to submit the new frame. - - `needs_frame` will be set to true if a frame should be submitted. `damage` - will be set to the region of the output that needs to be repainted, in - output-buffer-local coordinates. - - The buffer damage region accumulates all damage since the buffer has last - been swapped. This is not to be confused with the output surface damage, - which only contains the changes between two frames. - - Returns a bool specifying whether the output needs a new frame rendered. - """ - needs_frame_ptr = ffi.new("bool *") - if not lib.wlr_output_damage_attach_render( - self._ptr, needs_frame_ptr, damage._ptr - ): - raise RuntimeError("Rendering on output failed") - - return needs_frame_ptr[0] - - def add(self, damage: PixmanRegion32) -> None: - """Accumulates damage and schedules a `frame` event.""" - lib.wlr_output_damage_add(self._ptr, damage._ptr) - - def add_whole(self) -> None: - """Damages the whole output and schedules a `frame` event.""" - lib.wlr_output_damage_add_whole(self._ptr) - - def add_box(self, box: Box) -> None: - """Accumulates damage from a box and schedules a `frame` event.""" - lib.wlr_output_damage_add_box(self._ptr, box._ptr) From 57bfa38ac84eb458193390f6e04dc63be47bb353 Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 6 Oct 2023 11:58:36 +0100 Subject: [PATCH 28/92] (wlroots 0bb5742) compositor: pass version in wlr_compositor_create --- wlroots/ffi_build.py | 2 +- wlroots/helper.py | 9 +++++++-- wlroots/wlr_types/compositor.py | 17 ++++++++++++++--- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 6819f7a5..29c890a8 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -329,7 +329,7 @@ def has_xwayland() -> bool: }; struct wlr_compositor *wlr_compositor_create(struct wl_display *display, - struct wlr_renderer *renderer); + uint32_t version, struct wlr_renderer *renderer); struct wlr_surface_state { uint32_t committed; diff --git a/wlroots/helper.py b/wlroots/helper.py index 2c4bcedf..daf347e5 100644 --- a/wlroots/helper.py +++ b/wlroots/helper.py @@ -11,7 +11,10 @@ def build_compositor( - display: Display, *, backend_type=BackendType.AUTO + display: Display, + *, + backend_type=BackendType.AUTO, + compositor_version: int = 5, ) -> tuple[Compositor, Allocator, Renderer, Backend, SubCompositor]: """Build and run a compositor @@ -21,6 +24,8 @@ def build_compositor( :param backend_type: The type of the backend to setup the compositor for, by default use the auto-detected backend. + :param compositor_version: + The version of the wlr_compositor interface to use. :return: The compositor, allocator, renderer, and the backend. """ @@ -28,7 +33,7 @@ def build_compositor( renderer = Renderer.autocreate(backend) renderer.init_display(display) allocator = Allocator.autocreate(backend, renderer) - compositor = Compositor(display, renderer) + compositor = Compositor(display, compositor_version, renderer) subcompositor = SubCompositor(display) return compositor, allocator, renderer, backend, subcompositor diff --git a/wlroots/wlr_types/compositor.py b/wlroots/wlr_types/compositor.py index 3d023aed..3ca595a3 100644 --- a/wlroots/wlr_types/compositor.py +++ b/wlroots/wlr_types/compositor.py @@ -19,19 +19,30 @@ from wlroots.renderer import Renderer +COMPOSITOR_VERSION = 5 + + class Compositor(Ptr): - def __init__(self, display: Display, renderer: Renderer | None = None) -> None: + def __init__( + self, display: Display, version: int, renderer: Renderer | None = None + ) -> None: """A compositor for clients to be able to allocate surfaces :param display: The Wayland server display to attach to the compositor. + :param version: + The version of the wlr_compositor interface to use. :param renderer: The wlroots renderer to attach the compositor to. """ + if not version <= COMPOSITOR_VERSION: + raise ValueError( + f"Compositor version must be less than or equal to {COMPOSITOR_VERSION}" + ) if renderer is None: - self._ptr = lib.wlr_compositor_create(display._ptr, ffi.NULL) + self._ptr = lib.wlr_compositor_create(display._ptr, version, ffi.NULL) else: - self._ptr = lib.wlr_compositor_create(display._ptr, renderer._ptr) + self._ptr = lib.wlr_compositor_create(display._ptr, version, renderer._ptr) class SubCompositor(Ptr): From 784bcac081c8357edea8c1c6ebda53680cc156da Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 6 Oct 2023 13:05:10 +0100 Subject: [PATCH 29/92] (wlroots 9506290) wlr_scene: Introduce wlr_scene_buffer_set_opacity --- wlroots/ffi_build.py | 3 +++ wlroots/wlr_types/scene.py | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 29c890a8..6b355ea2 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -1912,6 +1912,9 @@ def has_xwayland() -> bool: void wlr_scene_buffer_send_frame_done(struct wlr_scene_buffer *scene_buffer, struct timespec *now); +void wlr_scene_buffer_set_opacity(struct wlr_scene_buffer *scene_buffer, + float opacity); + struct wlr_scene_output *wlr_scene_output_create(struct wlr_scene *scene, struct wlr_output *output); diff --git a/wlroots/wlr_types/scene.py b/wlroots/wlr_types/scene.py index aba24815..e246c626 100644 --- a/wlroots/wlr_types/scene.py +++ b/wlroots/wlr_types/scene.py @@ -174,6 +174,10 @@ def set_buffer_with_damage( region_ptr = region._ptr if region else ffi.NULL lib.wlr_scene_buffer_set_buffer_with_damage(self._ptr, buffer_ptr, region_ptr) + def set_opacity(self, opacity: float) -> None: + """Sets the opacity of this buffer""" + lib.wlr_scene_buffer_set_opacity(self._ptr, opacity) + T = TypeVar("T") BufferCallback = Callable[[SceneBuffer, int, int, T], None] From 443865704dea6190f938112647c23c10fa1d3f98 Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 6 Oct 2023 20:10:40 +0100 Subject: [PATCH 30/92] (wlroots 75d03f2) xwm: introduce associate/dissociate events I miss this wlroots commit and these changes earlier; this pywlroots commit is out of order compared with the others and re-ordering during a rebase caused some conflicts that aren't worth the time. --- wlroots/ffi_build.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 6b355ea2..7f8ecf39 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -3308,6 +3308,8 @@ def has_xwayland() -> bool: struct wl_signal request_maximize; struct wl_signal request_fullscreen; struct wl_signal request_activate; + struct wl_signal associate; + struct wl_signal dissociate; struct wl_signal map; struct wl_signal unmap; struct wl_signal set_title; From 7b54e5d903992a5c10d76900f54e8347c2072cdd Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 6 Oct 2023 16:17:17 +0100 Subject: [PATCH 31/92] (wlroots 6b40e08) compositor: introduce unified map logic --- wlroots/ffi_build.py | 5 ++++- wlroots/wlr_types/compositor.py | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 7f8ecf39..90366f4b 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -356,6 +356,7 @@ def has_xwayland() -> bool: void (*commit)(struct wlr_surface *surface); void (*precommit)(struct wlr_surface *surface, const struct wlr_surface_state *state); + void (*unmap)(struct wlr_surface *surface); void (*destroy)(struct wlr_surface *surface); ...; }; @@ -380,6 +381,7 @@ def has_xwayland() -> bool: struct wlr_surface_state current, pending; struct wl_list cached; + bool mapped; const struct wlr_surface_role *role; void *role_data; @@ -388,6 +390,8 @@ def has_xwayland() -> bool: struct wl_signal client_commit; struct wl_signal precommit; struct wl_signal commit; + struct wl_signal map; + struct wl_signal unmap; struct wl_signal new_subsurface; struct wl_signal destroy; } events; @@ -395,7 +399,6 @@ def has_xwayland() -> bool: struct wl_list current_outputs; struct wlr_addon_set addons; void *data; - struct wl_listener renderer_destroy; ...; }; diff --git a/wlroots/wlr_types/compositor.py b/wlroots/wlr_types/compositor.py index 3ca595a3..652f8454 100644 --- a/wlroots/wlr_types/compositor.py +++ b/wlroots/wlr_types/compositor.py @@ -64,6 +64,8 @@ def __init__(self, ptr) -> None: data_wrapper=SurfaceState, ) self.commit_event = Signal(ptr=ffi.addressof(self._ptr.events.commit)) + self.map_event = Signal(ptr=ffi.addressof(self._ptr.events.map)) + self.unmap_event = Signal(ptr=ffi.addressof(self._ptr.events.unmap)) self.new_subsurface_event = Signal( ptr=ffi.addressof(self._ptr.events.new_subsurface), data_wrapper=SubSurface, From 3a8ed75ac4c6d28dc57d16853d9df1837642fb1e Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 6 Oct 2023 17:00:52 +0100 Subject: [PATCH 32/92] (wlroots c590bb6) subcompositor: use unified map logic --- wlroots/ffi_build.py | 3 --- wlroots/wlr_types/compositor.py | 2 -- 2 files changed, 5 deletions(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 90366f4b..c8a61aca 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -471,7 +471,6 @@ def has_xwayland() -> bool: bool synchronized; bool reordered; - bool mapped; bool added; struct wl_listener surface_client_commit; @@ -479,8 +478,6 @@ def has_xwayland() -> bool: struct { struct wl_signal destroy; - struct wl_signal map; - struct wl_signal unmap; } events; void *data; diff --git a/wlroots/wlr_types/compositor.py b/wlroots/wlr_types/compositor.py index 652f8454..8f3232d9 100644 --- a/wlroots/wlr_types/compositor.py +++ b/wlroots/wlr_types/compositor.py @@ -138,8 +138,6 @@ def __init__(self, ptr): self._ptr = ffi.cast("struct wlr_subsurface *", ptr) self.destroy_event = Signal(ptr=ffi.addressof(self._ptr.events.destroy)) - self.map_event = Signal(ptr=ffi.addressof(self._ptr.events.map)) - self.unmap_event = Signal(ptr=ffi.addressof(self._ptr.events.unmap)) @property def surface(self) -> Surface: From 698e15f4e86cf733b4508b303f9245619ed4e10f Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 6 Oct 2023 17:37:13 +0100 Subject: [PATCH 33/92] (wlroots b0437fc) xdg-shell: use unified map logic --- wlroots/ffi_build.py | 4 +--- wlroots/wlr_types/xdg_shell.py | 2 -- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index c8a61aca..b7bbb263 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -2837,7 +2837,7 @@ def has_xwayland() -> bool: struct wl_list popups; // wlr_xdg_popup::link - bool added, configured, mapped; + bool added, configured; struct wl_event_source *configure_idle; uint32_t scheduled_serial; struct wl_list configure_list; @@ -2850,8 +2850,6 @@ def has_xwayland() -> bool: struct wl_signal destroy; struct wl_signal ping_timeout; struct wl_signal new_popup; - struct wl_signal map; - struct wl_signal unmap; struct wl_signal configure; // wlr_xdg_surface_configure struct wl_signal ack_configure; // wlr_xdg_surface_configure diff --git a/wlroots/wlr_types/xdg_shell.py b/wlroots/wlr_types/xdg_shell.py index 4afdf229..6e3ab671 100644 --- a/wlroots/wlr_types/xdg_shell.py +++ b/wlroots/wlr_types/xdg_shell.py @@ -72,8 +72,6 @@ def __init__(self, ptr) -> None: """ self._ptr = ffi.cast("struct wlr_xdg_surface *", ptr) - self.map_event = Signal(ptr=ffi.addressof(self._ptr.events.map)) - self.unmap_event = Signal(ptr=ffi.addressof(self._ptr.events.unmap)) self.destroy_event = Signal(ptr=ffi.addressof(self._ptr.events.destroy)) self.new_popup_event = Signal( ptr=ffi.addressof(self._ptr.events.new_popup), data_wrapper=XdgPopup From c752f4ac4bb38c7958aae31620599c3d603e8d6b Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 6 Oct 2023 17:40:21 +0100 Subject: [PATCH 34/92] (wlroots c63f365) layer-shell: use unified map logic --- wlroots/ffi_build.py | 4 +--- wlroots/wlr_types/layer_shell_v1.py | 2 -- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index b7bbb263..7b584ed7 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -3125,13 +3125,11 @@ def has_xwayland() -> bool: struct wlr_layer_shell_v1 *shell; struct wl_list popups; // wlr_xdg_popup::link char *namespace; - bool added, configured, mapped; + bool added, configured; struct wl_list configure_list; struct wlr_layer_surface_v1_state current, pending; struct { struct wl_signal destroy; - struct wl_signal map; - struct wl_signal unmap; struct wl_signal new_popup; } events; diff --git a/wlroots/wlr_types/layer_shell_v1.py b/wlroots/wlr_types/layer_shell_v1.py index 9e88d5aa..f696102f 100644 --- a/wlroots/wlr_types/layer_shell_v1.py +++ b/wlroots/wlr_types/layer_shell_v1.py @@ -97,8 +97,6 @@ def __init__(self, ptr): self._ptr = ffi.cast("struct wlr_layer_surface_v1 *", ptr) self.destroy_event = Signal(ptr=ffi.addressof(self._ptr.events.destroy)) - self.map_event = Signal(ptr=ffi.addressof(self._ptr.events.map)) - self.unmap_event = Signal(ptr=ffi.addressof(self._ptr.events.unmap)) self.new_popup_event = Signal(ptr=ffi.addressof(self._ptr.events.new_popup)) @property From f841658bd3cc699d705977b1ca85f1e5f8371726 Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 6 Oct 2023 17:45:54 +0100 Subject: [PATCH 35/92] (wlroots af4181f) drag: use unified map logic --- wlroots/ffi_build.py | 3 --- wlroots/wlr_types/data_device_manager.py | 2 -- 2 files changed, 5 deletions(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 7b584ed7..9170277c 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -533,10 +533,7 @@ def has_xwayland() -> bool: struct wlr_drag_icon { struct wlr_drag *drag; struct wlr_surface *surface; - bool mapped; struct { - struct wl_signal map; - struct wl_signal unmap; struct wl_signal destroy; } events; void *data; diff --git a/wlroots/wlr_types/data_device_manager.py b/wlroots/wlr_types/data_device_manager.py index 4970e13c..ab43e6f2 100644 --- a/wlroots/wlr_types/data_device_manager.py +++ b/wlroots/wlr_types/data_device_manager.py @@ -86,8 +86,6 @@ class DragIcon(PtrHasData): def __init__(self, ptr) -> None: self._ptr = ffi.cast("struct wlr_drag_icon *", ptr) - self.map_event = Signal(ptr=ffi.addressof(self._ptr.events.map)) - self.unmap_event = Signal(ptr=ffi.addressof(self._ptr.events.unmap)) self.destroy_event = Signal(ptr=ffi.addressof(self._ptr.events.destroy)) @property From af66b82707fd88a2dd3c5d8fddd1370f72489e67 Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 6 Oct 2023 17:47:57 +0100 Subject: [PATCH 36/92] (wlroots 26676c8) xwm: use unified map logic --- wlroots/ffi_build.py | 6 ++---- wlroots/xwayland.py | 6 ------ 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 9170277c..f48f622b 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -3261,12 +3261,12 @@ def has_xwayland() -> bool: struct wlr_surface *surface; struct wlr_addon surface_addon; struct wl_listener surface_commit; - struct wl_listener surface_precommit; + struct wl_listener surface_map; + struct wl_listener surface_unmap; int16_t x, y; uint16_t width, height; uint16_t saved_width, saved_height; bool override_redirect; - bool mapped; char *title; char *class; char *instance; @@ -3303,8 +3303,6 @@ def has_xwayland() -> bool: struct wl_signal request_activate; struct wl_signal associate; struct wl_signal dissociate; - struct wl_signal map; - struct wl_signal unmap; struct wl_signal set_title; struct wl_signal set_class; struct wl_signal set_role; diff --git a/wlroots/xwayland.py b/wlroots/xwayland.py index 496deee8..553a93b2 100644 --- a/wlroots/xwayland.py +++ b/wlroots/xwayland.py @@ -172,8 +172,6 @@ def __init__(self, ptr) -> None: self.request_activate_event = Signal( ptr=ffi.addressof(self._ptr.events.request_activate) ) - self.map_event = Signal(ptr=ffi.addressof(self._ptr.events.map)) - self.unmap_event = Signal(ptr=ffi.addressof(self._ptr.events.unmap)) self.set_title_event = Signal(ptr=ffi.addressof(self._ptr.events.set_title)) self.set_class_event = Signal(ptr=ffi.addressof(self._ptr.events.set_class)) self.set_role_event = Signal(ptr=ffi.addressof(self._ptr.events.set_role)) @@ -263,10 +261,6 @@ def height(self) -> int: def override_redirect(self) -> bool: return self._ptr.override_redirect - @property - def mapped(self) -> bool: - return self._ptr.mapped - @property def title(self) -> str | None: return str_or_none(self._ptr.title) From 89443ae93c09e76e33732c27ec31bb21cc02b353 Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 6 Oct 2023 17:48:55 +0100 Subject: [PATCH 37/92] (wlroots d086ee1) compositor: remove wlr_surface_role.precommit --- wlroots/ffi_build.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index f48f622b..7718dfd0 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -354,8 +354,6 @@ def has_xwayland() -> bool: struct wlr_surface_role { const char *name; void (*commit)(struct wlr_surface *surface); - void (*precommit)(struct wlr_surface *surface, - const struct wlr_surface_state *state); void (*unmap)(struct wlr_surface *surface); void (*destroy)(struct wlr_surface *surface); ...; From eb0b0b8bbe8a426d9eab3ebf28e270aa13d9cbde Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 6 Oct 2023 17:55:52 +0100 Subject: [PATCH 38/92] (wlroots 24a479a) drag: don't set icon's role_data --- wlroots/ffi_build.py | 1 + 1 file changed, 1 insertion(+) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 7718dfd0..6e1b5fc0 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -534,6 +534,7 @@ def has_xwayland() -> bool: struct { struct wl_signal destroy; } events; + struct wl_listener surface_destroy; void *data; ...; }; From c06d937579ca882acb363c9cc6acf424bee0e63d Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 6 Oct 2023 19:36:35 +0100 Subject: [PATCH 39/92] (wlroots 70c1a57) gamma-control-v1: introduce set_gamma event --- wlroots/ffi_build.py | 1 + 1 file changed, 1 insertion(+) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 6e1b5fc0..a485e45d 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -745,6 +745,7 @@ def has_xwayland() -> bool: struct { struct wl_signal destroy; + struct wl_signal set_gamma; } events; void *data; From d8e87e9ca3555b29bd5a7c11c7bca4b3e81545ad Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 6 Oct 2023 18:44:39 +0100 Subject: [PATCH 40/92] Add bindings to wlr_output_state methods --- wlroots/ffi_build.py | 7 +++++++ wlroots/wlr_types/__init__.py | 2 +- wlroots/wlr_types/output.py | 3 +++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index a485e45d..cccb3d0f 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -1227,6 +1227,13 @@ def has_xwayland() -> bool: enum wl_output_transform wlr_output_transform_compose( enum wl_output_transform tr_a, enum wl_output_transform tr_b); +void wlr_output_state_finish(struct wlr_output_state *state); +void wlr_output_state_set_enabled(struct wlr_output_state *state, + bool enabled); +void wlr_output_state_set_mode(struct wlr_output_state *state, + struct wlr_output_mode *mode); +void wlr_output_state_set_custom_mode(struct wlr_output_state *state, + int32_t width, int32_t height, int32_t refresh); """ # types/wlr_output_layout.h diff --git a/wlroots/wlr_types/__init__.py b/wlroots/wlr_types/__init__.py index b261a2a3..9507ac0c 100644 --- a/wlroots/wlr_types/__init__.py +++ b/wlroots/wlr_types/__init__.py @@ -19,7 +19,7 @@ from .keyboard import Keyboard # noqa: F401 from .layer_shell_v1 import LayerShellV1 # noqa: F401 from .matrix import Matrix # noqa: F401 -from .output import Output # noqa: F401 +from .output import Output, OutputState # noqa: F401 from .output_layout import OutputLayout # noqa: F401 from .pointer import ( # noqa: F401 PointerAxisEvent, diff --git a/wlroots/wlr_types/output.py b/wlroots/wlr_types/output.py index 5be068a3..ed7c4dce 100644 --- a/wlroots/wlr_types/output.py +++ b/wlroots/wlr_types/output.py @@ -417,6 +417,9 @@ def custom_mode(self, mode: CustomMode) -> None: self._ptr, mode.width, mode.height, mode.refresh ) + def finish(self) -> None: + lib.wlr_output_state_finish(self._ptr) + class OutputEventRequestState(Ptr): def __init__(self, ptr) -> None: From bb8dd9e2172491e9c038de5ff1d4034507c198ff Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 6 Oct 2023 18:59:26 +0100 Subject: [PATCH 41/92] fix OutputState.commit_state signature --- wlroots/wlr_types/output.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wlroots/wlr_types/output.py b/wlroots/wlr_types/output.py index ed7c4dce..b5953dca 100644 --- a/wlroots/wlr_types/output.py +++ b/wlroots/wlr_types/output.py @@ -202,9 +202,9 @@ def rollback(self) -> None: """Discard the pending output state""" lib.wlr_output_rollback(self._ptr) - def commit_state(self, state: OutputEventRequestState) -> None: + def commit_state(self, state: OutputState) -> bool: """Commit requested state""" - lib.wlr_output_commit_state(self._ptr, state._ptr) + return lib.wlr_output_commit_state(self._ptr, state._ptr) def effective_resolution(self) -> tuple[int, int]: """Computes the transformed and scaled output resolution""" From 206fdd89bc85c58ec0e39fb4c109fd8e2847da35 Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 6 Oct 2023 19:41:38 +0100 Subject: [PATCH 42/92] (wlroots 753f3cc) compositor: add wlr_surface_role.no_object --- wlroots/ffi_build.py | 1 + 1 file changed, 1 insertion(+) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index cccb3d0f..116712ea 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -353,6 +353,7 @@ def has_xwayland() -> bool: struct wlr_surface_role { const char *name; + bool no_object; void (*commit)(struct wlr_surface *surface); void (*unmap)(struct wlr_surface *surface); void (*destroy)(struct wlr_surface *surface); From 26c26fca904284985d860dca1fdf8a99c0ecbd83 Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 6 Oct 2023 20:40:44 +0100 Subject: [PATCH 43/92] (wlroots da04b06) cursor: add wlr_cursor_set_xcursor() --- wlroots/ffi_build.py | 2 ++ wlroots/wlr_types/cursor.py | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 116712ea..14bfff36 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -311,6 +311,8 @@ def has_xwayland() -> bool: struct wlr_output *output); void wlr_cursor_map_input_to_output(struct wlr_cursor *cur, struct wlr_input_device *dev, struct wlr_output *output); +void wlr_cursor_set_xcursor(struct wlr_cursor *cur, + struct wlr_xcursor_manager *manager, const char *name); """ # types/wlr_compositor.h diff --git a/wlroots/wlr_types/cursor.py b/wlroots/wlr_types/cursor.py index efd9753f..6662bc0e 100644 --- a/wlroots/wlr_types/cursor.py +++ b/wlroots/wlr_types/cursor.py @@ -2,6 +2,7 @@ from __future__ import annotations import enum +from typing import TYPE_CHECKING from pywayland.server import Signal @@ -32,6 +33,9 @@ TouchUpEvent, ) +if TYPE_CHECKING: + from .xcursor_manager import XCursorManager + class WarpMode(enum.Enum): Layout = enum.auto() @@ -292,3 +296,11 @@ def map_input_to_output( """ output_ptr = ptr_or_null(output) lib.wlr_cursor_map_input_to_output(self._ptr, input_device._ptr, output_ptr) + + def set_xcursor(self, manager: XCursorManager, name: str) -> None: + """ + Set the cursor image from an XCursor theme. + + The image will be loaded from the struct wlr_xcursor_manager. + """ + lib.wlr_cursor_set_xcursor(self._ptr, manager._ptr, name.encode()) From c6d92aa7457f1b0d34bcd7c0dd39f910df5e9af6 Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 6 Oct 2023 19:53:36 +0100 Subject: [PATCH 44/92] (wlroots 0f67580) compositor: introduce wlr_surface_set_role_object() --- wlroots/ffi_build.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 14bfff36..ed1ba652 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -406,8 +406,7 @@ def has_xwayland() -> bool: typedef void (*wlr_surface_iterator_func_t)(struct wlr_surface *surface, int sx, int sy, void *data); -bool wlr_surface_set_role(struct wlr_surface *surface, - const struct wlr_surface_role *role, void *role_data, +bool wlr_surface_set_role(struct wlr_surface *surface, const struct wlr_surface_role *role, struct wl_resource *error_resource, uint32_t error_code); void wlr_surface_destroy_role_object(struct wlr_surface *surface); From 48be1f5554f2241bc9e19ef3674125a177636d1c Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 6 Oct 2023 19:55:17 +0100 Subject: [PATCH 45/92] (wlroots 89cb484) compositor: replace role_data with role_resource --- wlroots/ffi_build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index ed1ba652..e46cafac 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -385,7 +385,7 @@ def has_xwayland() -> bool: bool mapped; const struct wlr_surface_role *role; - void *role_data; + struct wl_resource *role_resource; struct { struct wl_signal client_commit; From 0d2863a34391a61b2e93ed537bc33df340feb600 Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 6 Oct 2023 19:58:00 +0100 Subject: [PATCH 46/92] (wlroots be05097) output: add wlr_output_state_init() --- wlroots/ffi_build.py | 1 + wlroots/wlr_types/output.py | 1 + 2 files changed, 2 insertions(+) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index e46cafac..3187c3ec 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -1229,6 +1229,7 @@ def has_xwayland() -> bool: enum wl_output_transform wlr_output_transform_compose( enum wl_output_transform tr_a, enum wl_output_transform tr_b); +void wlr_output_state_init(struct wlr_output_state *state); void wlr_output_state_finish(struct wlr_output_state *state); void wlr_output_state_set_enabled(struct wlr_output_state *state, bool enabled); diff --git a/wlroots/wlr_types/output.py b/wlroots/wlr_types/output.py index b5953dca..3f13f97e 100644 --- a/wlroots/wlr_types/output.py +++ b/wlroots/wlr_types/output.py @@ -347,6 +347,7 @@ class OutputState(Ptr): def __init__(self, ptr: ffi.CData | None = None) -> None: if ptr is None: ptr = ffi.new("struct wlr_output_state *") + lib.wlr_output_state_init(ptr) self._ptr = ptr @property From 3e9b229d7dce89e7c11f1cf6f6cf0715249b8b01 Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 6 Oct 2023 20:20:02 +0100 Subject: [PATCH 47/92] add missing wlr_xwayland_surface.withdrawn --- wlroots/ffi_build.py | 1 + 1 file changed, 1 insertion(+) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 3187c3ec..9dd8ab92 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -3301,6 +3301,7 @@ def has_xwayland() -> bool: bool fullscreen; bool maximized_vert, maximized_horz; bool minimized; + bool withdrawn; bool has_alpha; struct { struct wl_signal destroy; From 254409dd372c18385c462fd49ec57efb9e6fd945 Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 6 Oct 2023 20:31:20 +0100 Subject: [PATCH 48/92] (wlroots 18bafbf) xcursor-manager: drop wlr_xcursor_manager_set_cursor_image() --- wlroots/ffi_build.py | 2 -- wlroots/wlr_types/xcursor_manager.py | 11 ----------- 2 files changed, 13 deletions(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 9dd8ab92..2c4fb102 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -2511,8 +2511,6 @@ def has_xwayland() -> bool: int wlr_xcursor_manager_load(struct wlr_xcursor_manager *manager, float scale); -void wlr_xcursor_manager_set_cursor_image(struct wlr_xcursor_manager *manager, - const char *name, struct wlr_cursor *cursor); struct wlr_xcursor *wlr_xcursor_manager_get_xcursor( struct wlr_xcursor_manager *manager, const char *name, float scale); """ diff --git a/wlroots/wlr_types/xcursor_manager.py b/wlroots/wlr_types/xcursor_manager.py index f83eb7c5..d8502ffa 100644 --- a/wlroots/wlr_types/xcursor_manager.py +++ b/wlroots/wlr_types/xcursor_manager.py @@ -29,17 +29,6 @@ def destroy(self): ffi.release(self._ptr) self._ptr = None - def set_cursor_image(self, name: str, cursor: Cursor): - """Set the cursor image - - Set a Cursor image to the specified cursor name for all scale factors. - The wlroots cursor will take over from this point and ensure the - correct cursor is used on each output, assuming an output layout is - attached to it. - """ - name_cdata = ffi.new("char []", name.encode()) - lib.wlr_xcursor_manager_set_cursor_image(self._ptr, name_cdata, cursor._ptr) - def get_xcursor(self, name: str, scale: float = 1) -> XCursor | None: """ Retrieves a wlr_xcursor reference for the given cursor name at the given scale From b4078dab89afa93971b4176b1cc403d5c5f09357 Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 6 Oct 2023 20:50:04 +0100 Subject: [PATCH 49/92] (wlroots 19ba3f0) xwayland: drop struct wlr_xwayland_move_event --- wlroots/ffi_build.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 2c4fb102..1c2cc177 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -3336,10 +3336,6 @@ def has_xwayland() -> bool: uint16_t mask; // xcb_config_window_t ...; }; - struct wlr_xwayland_move_event { - struct wlr_xwayland_surface *surface; - ...; - }; struct wlr_xwayland_remove_startup_info_event { const char *id; xcb_window_t window; From 0d8f05d3b8f34006bb2ca9388a56e0f7f86b8a2c Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 6 Oct 2023 20:57:33 +0100 Subject: [PATCH 50/92] (wlroots 214df8e) scene_output: optionally record and report timings --- wlroots/ffi_build.py | 7 ++++++- wlroots/wlr_types/scene.py | 12 ++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 1c2cc177..11614e09 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -1846,6 +1846,10 @@ def has_xwayland() -> bool: ...; }; +struct wlr_scene_output_state_options { + struct wlr_scene_timer *timer; +}; + void wlr_scene_node_destroy(struct wlr_scene_node *node); void wlr_scene_node_set_enabled(struct wlr_scene_node *node, bool enabled); @@ -1930,7 +1934,8 @@ def has_xwayland() -> bool: void wlr_scene_output_set_position(struct wlr_scene_output *scene_output, int lx, int ly); -bool wlr_scene_output_commit(struct wlr_scene_output *scene_output); +bool wlr_scene_output_commit(struct wlr_scene_output *scene_output, + const struct wlr_scene_output_state_options *options); void wlr_scene_output_send_frame_done(struct wlr_scene_output *scene_output, struct timespec *now); diff --git a/wlroots/wlr_types/scene.py b/wlroots/wlr_types/scene.py index e246c626..eb888bff 100644 --- a/wlroots/wlr_types/scene.py +++ b/wlroots/wlr_types/scene.py @@ -91,9 +91,11 @@ def create(cls, scene: Scene, output: Output) -> SceneOutput: """ return cls(lib.wlr_scene_output_create(scene._ptr, output._ptr)) - def commit(self) -> bool: + def commit(self, options: SceneOutputStateOptions | None = None) -> bool: """Render and commit an output.""" - return lib.wlr_scene_output_commit(self._ptr) + options_ptr = options._ptr if options is not None else ffi.NULL + + return lib.wlr_scene_output_commit(self._ptr, options_ptr) def destroy(self) -> None: """Destroy a scene-graph output.""" @@ -344,3 +346,9 @@ def configure(self, full_area: Box, usable_area: Box) -> None: lib.wlr_scene_layer_surface_v1_configure( self._ptr, full_area._ptr, usable_area._ptr ) + + +class SceneOutputStateOptions(Ptr): + def __init__(self, ptr) -> None: + """A `struct wlr_scene_output_state_options`.""" + self._ptr = ptr From c4d4b018902ed18cda844ef5cf64a77ae364b674 Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 6 Oct 2023 20:59:57 +0100 Subject: [PATCH 51/92] (wlroots 88942d4) scene: rename output_present event to output_sample --- wlroots/ffi_build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 11614e09..717768c5 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -1817,7 +1817,7 @@ def has_xwayland() -> bool: struct wl_signal outputs_update; struct wl_signal output_enter; // struct wlr_scene_output struct wl_signal output_leave; // struct wlr_scene_output - struct wl_signal output_present; // struct wlr_scene_output + struct wl_signal output_sample; // struct wlr_scene_output struct wl_signal frame_done; // struct timespec } events; From 5da8f061b8c5ea2ae5e1399f72276e45018a37ec Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 6 Oct 2023 21:27:22 +0100 Subject: [PATCH 52/92] (wlroots 77dc1c2) xwayland: drop wlr_xwayland_surface.events.set_pid --- wlroots/ffi_build.py | 1 - wlroots/xwayland.py | 1 - 2 files changed, 2 deletions(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 717768c5..165c6056 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -3321,7 +3321,6 @@ def has_xwayland() -> bool: struct wl_signal set_class; struct wl_signal set_role; struct wl_signal set_parent; - struct wl_signal set_pid; struct wl_signal set_startup_id; struct wl_signal set_window_type; struct wl_signal set_hints; diff --git a/wlroots/xwayland.py b/wlroots/xwayland.py index 553a93b2..7d126ab2 100644 --- a/wlroots/xwayland.py +++ b/wlroots/xwayland.py @@ -176,7 +176,6 @@ def __init__(self, ptr) -> None: self.set_class_event = Signal(ptr=ffi.addressof(self._ptr.events.set_class)) self.set_role_event = Signal(ptr=ffi.addressof(self._ptr.events.set_role)) self.set_parent_event = Signal(ptr=ffi.addressof(self._ptr.events.set_parent)) - self.set_pid_event = Signal(ptr=ffi.addressof(self._ptr.events.set_pid)) self.set_startup_id_event = Signal( ptr=ffi.addressof(self._ptr.events.set_startup_id) ) From 3cd1031e8dce682f0d1bbd3709c0e1f0a2285c9d Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 6 Oct 2023 21:19:23 +0100 Subject: [PATCH 53/92] (wlroots bdc3440) xdg-decoration: store an xdg_toplevel instead of xdg_surface --- wlroots/ffi_build.py | 2 +- wlroots/wlr_types/xdg_decoration_v1.py | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 165c6056..58d73561 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -2599,7 +2599,7 @@ def has_xwayland() -> bool: struct wlr_xdg_toplevel_decoration_v1 { struct wl_resource *resource; - struct wlr_xdg_surface *surface; + struct wlr_xdg_toplevel *toplevel; struct wlr_xdg_decoration_manager_v1 *manager; struct wl_list link; // wlr_xdg_decoration_manager_v1::link diff --git a/wlroots/wlr_types/xdg_decoration_v1.py b/wlroots/wlr_types/xdg_decoration_v1.py index d0f09ef0..f6df86ec 100644 --- a/wlroots/wlr_types/xdg_decoration_v1.py +++ b/wlroots/wlr_types/xdg_decoration_v1.py @@ -11,6 +11,7 @@ from wlroots import PtrHasData, ffi, lib from .compositor import Surface +from .xdg_shell import XdgTopLevel if TYPE_CHECKING: from pywayland.server import Display @@ -53,10 +54,10 @@ def __init__(self, ptr) -> None: ) @property - def surface(self) -> Surface: - surface_ptr = self._ptr.surface - _weakkeydict[surface_ptr] = self._ptr - return Surface(surface_ptr) + def toplevel(self) -> XdgTopLevel: + toplevel_ptr = self._ptr.toplevel + _weakkeydict[toplevel_ptr] = self._ptr + return XdgTopLevel(toplevel_ptr) @property def manager(self) -> XdgDecorationManagerV1: From 9dfabca08e15e458bea55f9e598be2928bf6a396 Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 6 Oct 2023 21:44:07 +0100 Subject: [PATCH 54/92] (wlroots bd5c4f4) xdg-shell: rework roles --- wlroots/ffi_build.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 58d73561..c91f3334 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -2839,6 +2839,7 @@ def has_xwayland() -> bool: struct wlr_surface *surface; struct wl_list link; // wlr_xdg_client::surfaces enum wlr_xdg_surface_role role; + struct wl_resource *role_resource; union { struct wlr_xdg_toplevel *toplevel; @@ -2854,8 +2855,6 @@ def has_xwayland() -> bool: struct wlr_xdg_surface_state current, pending; - struct wl_listener surface_commit; - struct { struct wl_signal destroy; struct wl_signal ping_timeout; From 37546e7cef394c58f8a9f192f552dba8b51fea9d Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 6 Oct 2023 21:57:16 +0100 Subject: [PATCH 55/92] (wlroots 72787db) compositor: drop wlr_surface_destroy_role_object() --- wlroots/ffi_build.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index c91f3334..48771f60 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -409,8 +409,6 @@ def has_xwayland() -> bool: bool wlr_surface_set_role(struct wlr_surface *surface, const struct wlr_surface_role *role, struct wl_resource *error_resource, uint32_t error_code); -void wlr_surface_destroy_role_object(struct wlr_surface *surface); - bool wlr_surface_has_buffer(struct wlr_surface *surface); struct wlr_texture *wlr_surface_get_texture(struct wlr_surface *surface); From 09f654b2965c6e3e75c0a06384e64de3937290f3 Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 6 Oct 2023 22:06:13 +0100 Subject: [PATCH 56/92] (wlroots 91f813f) output_layout: return wlr_output_layout_output when adding output --- wlroots/ffi_build.py | 4 ++-- wlroots/wlr_types/__init__.py | 2 +- wlroots/wlr_types/output_layout.py | 22 ++++++++++++++++------ 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 48771f60..74f58b23 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -1261,7 +1261,7 @@ def has_xwayland() -> bool: struct wlr_output *reference, double lx, double ly, double *dest_lx, double *dest_ly); -bool wlr_output_layout_add(struct wlr_output_layout *layout, +struct wlr_output_layout_output *wlr_output_layout_add(struct wlr_output_layout *layout, struct wlr_output *output, int lx, int ly); void wlr_output_layout_remove(struct wlr_output_layout *layout, @@ -1270,7 +1270,7 @@ def has_xwayland() -> bool: void wlr_output_layout_get_box(struct wlr_output_layout *layout, struct wlr_output *reference, struct wlr_box *dest_box); -bool wlr_output_layout_add_auto(struct wlr_output_layout *layout, +struct wlr_output_layout_output *wlr_output_layout_add_auto(struct wlr_output_layout *layout, struct wlr_output *output); struct wlr_output *wlr_output_layout_output_at(struct wlr_output_layout *layout, diff --git a/wlroots/wlr_types/__init__.py b/wlroots/wlr_types/__init__.py index 9507ac0c..1666d18a 100644 --- a/wlroots/wlr_types/__init__.py +++ b/wlroots/wlr_types/__init__.py @@ -20,7 +20,7 @@ from .layer_shell_v1 import LayerShellV1 # noqa: F401 from .matrix import Matrix # noqa: F401 from .output import Output, OutputState # noqa: F401 -from .output_layout import OutputLayout # noqa: F401 +from .output_layout import OutputLayout, OutputLayoutOutput # noqa: F401 from .pointer import ( # noqa: F401 PointerAxisEvent, PointerButtonEvent, diff --git a/wlroots/wlr_types/output_layout.py b/wlroots/wlr_types/output_layout.py index b5e29f9f..ae40dadf 100644 --- a/wlroots/wlr_types/output_layout.py +++ b/wlroots/wlr_types/output_layout.py @@ -31,7 +31,7 @@ def destroy(self) -> None: ffi.release(self._ptr) self._ptr = None - def add_auto(self, output: Output) -> bool: + def add_auto(self, output: Output) -> OutputLayoutOutput | None: """ Add the output to the layout as automatically configured. This will place the output in a sensible location in the layout. The coordinates of the output in @@ -40,7 +40,10 @@ def add_auto(self, output: Output) -> bool: Returns true on success, false on a memory allocation error. """ - return lib.wlr_output_layout_add_auto(self._ptr, output._ptr) + ptr = lib.wlr_output_layout_add_auto(self._ptr, output._ptr) + if ptr == ffi.NULL: + return None + return OutputLayoutOutput(ptr) def output_coords(self, output: Output) -> tuple[float, float]: """Determine coordinates of the output in the layout @@ -72,15 +75,16 @@ def output_at(self, x: float, y: float) -> Output | None: return None return Output(output_ptr) - def add(self, output: Output, lx: int, ly: int) -> bool: + def add(self, output: Output, lx: int, ly: int) -> OutputLayoutOutput | None: """ Add the output to the layout at the specified coordinates. If the output is already a part of the output layout, it will become manually configured and will be moved to the specified coordinates. - - Returns true on success, false on a memory allocation error. """ - return lib.wlr_output_layout_add(self._ptr, output._ptr, lx, ly) + ptr = lib.wlr_output_layout_add(self._ptr, output._ptr, lx, ly) + if ptr == ffi.NULL: + return None + return OutputLayoutOutput(ptr) def remove(self, output: Output) -> None: """Remove an output from the layout.""" @@ -123,3 +127,9 @@ def closest_point( self._ptr, reference_ptr, lx, ly, dest_lx, dest_ly ) return dest_lx[0], dest_ly[0] + + +class OutputLayoutOutput(Ptr): + def __init__(self, ptr) -> None: + """A `struct wlr_output_layout_output`""" + self._ptr = ptr From 0f63a666ae6f3f651d0e88b8e44a365a2307b23f Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 6 Oct 2023 22:14:51 +0100 Subject: [PATCH 57/92] (wlroots f5917f0) scene_output_layout: make output adding explicit --- wlroots/ffi_build.py | 2 +- wlroots/wlr_types/scene.py | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 74f58b23..999b1434 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -1944,7 +1944,7 @@ def has_xwayland() -> bool: struct wlr_scene_output *wlr_scene_get_scene_output(struct wlr_scene *scene, struct wlr_output *output); -bool wlr_scene_attach_output_layout(struct wlr_scene *scene, +struct wlr_scene_output_layout *wlr_scene_attach_output_layout(struct wlr_scene *scene, struct wlr_output_layout *output_layout); struct wlr_scene_tree *wlr_scene_subsurface_tree_create( diff --git a/wlroots/wlr_types/scene.py b/wlroots/wlr_types/scene.py index eb888bff..6d33658e 100644 --- a/wlroots/wlr_types/scene.py +++ b/wlroots/wlr_types/scene.py @@ -7,7 +7,7 @@ from wlroots import Ptr, PtrHasData, ffi, lib from wlroots.util.region import PixmanRegion32 -from wlroots.wlr_types import Surface +from wlroots.wlr_types import Surface, OutputLayoutOutput if TYPE_CHECKING: from wlroots.util.box import Box @@ -36,9 +36,14 @@ def tree(self) -> SceneTree: ptr = ffi.addressof(self._ptr.tree) return SceneTree(ptr) - def attach_output_layout(self, output_layout: OutputLayout) -> bool: + def attach_output_layout( + self, output_layout: OutputLayout + ) -> OutputLayoutOutput | None: """Get a scene-graph output from a wlr_output.""" - return lib.wlr_scene_attach_output_layout(self._ptr, output_layout._ptr) + ptr = lib.wlr_scene_attach_output_layout(self._ptr, output_layout._ptr) + if ptr == ffi.NULL: + return None + return OutputLayoutOutput(ptr) def set_presentation(self, presentation: Presentation) -> None: """ From 975f1d708e2d8a638126e2e0c918694e50d23b38 Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 6 Oct 2023 22:37:36 +0100 Subject: [PATCH 58/92] (wlroots 0fdbdc3) xdg-surface: fix init state flow --- wlroots/ffi_build.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 999b1434..bbff44d0 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -2789,7 +2789,6 @@ def has_xwayland() -> bool: struct wlr_xdg_toplevel { struct wl_resource *resource; struct wlr_xdg_surface *base; - bool sent_initial_configure; struct wlr_xdg_toplevel *parent; struct wl_listener parent_unmap; @@ -2853,6 +2852,9 @@ def has_xwayland() -> bool: struct wlr_xdg_surface_state current, pending; + bool initialized; + bool initial_commit; + struct { struct wl_signal destroy; struct wl_signal ping_timeout; From ef10ab0d44e1050bedfae15a23cabf72975be6dd Mon Sep 17 00:00:00 2001 From: mcol Date: Sat, 7 Oct 2023 00:23:54 +0100 Subject: [PATCH 59/92] (wlroots a289f81) drop KDE idle protocol support --- wlroots/ffi_build.py | 68 --------------------------------------- wlroots/wlr_types/idle.py | 67 -------------------------------------- 2 files changed, 135 deletions(-) delete mode 100644 wlroots/wlr_types/idle.py diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index bbff44d0..75c959ae 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -755,73 +755,6 @@ def has_xwayland() -> bool: struct wl_display *display); """ -# types/wlr_idle.h -CDEF += """ -struct wlr_idle { - struct wl_global *global; - struct wl_list idle_timers; // wlr_idle_timeout::link - struct wl_event_loop *event_loop; - bool enabled; - - struct wl_listener display_destroy; - struct { - struct wl_signal activity_notify; - struct wl_signal destroy; - } events; - - void *data; - ...; -}; - -struct wlr_idle_timeout { - struct wl_resource *resource; - struct wl_list link; - struct wlr_seat *seat; - - struct wl_event_source *idle_source; - bool idle_state; - bool enabled; - uint32_t timeout; // milliseconds - - struct { - struct wl_signal idle; - struct wl_signal resume; - struct wl_signal destroy; - } events; - - struct wl_listener input_listener; - struct wl_listener seat_destroy; - - void *data; - ...; -}; - -struct wlr_idle *wlr_idle_create(struct wl_display *display); - -/** - * Send notification to restart all timers for the given seat. Called by - * compositor when there is an user activity event on that seat. - */ -void wlr_idle_notify_activity(struct wlr_idle *idle, struct wlr_seat *seat); - -/** - * Enable or disable timers for a given idle resource by seat. - * Passing a NULL seat means update timers for all seats. - */ -void wlr_idle_set_enabled(struct wlr_idle *idle, struct wlr_seat *seat, - bool enabled); - -/** - * Create a new timer on the given seat. The idle event will be called after - * the given amount of milliseconds of inactivity, and the resumed event will - * be sent at the first user activity after the fired event. - */ -struct wlr_idle_timeout *wlr_idle_timeout_create(struct wlr_idle *idle, - struct wlr_seat *seat, uint32_t timeout); - -void wlr_idle_timeout_destroy(struct wlr_idle_timeout *timeout); -""" - # types/wlr_input_inhibit_v1.h CDEF += """ struct wlr_idle_inhibit_manager_v1 { @@ -3023,7 +2956,6 @@ def has_xwayland() -> bool: #include #include #include -#include #include #include #include diff --git a/wlroots/wlr_types/idle.py b/wlroots/wlr_types/idle.py deleted file mode 100644 index 2e7414bd..00000000 --- a/wlroots/wlr_types/idle.py +++ /dev/null @@ -1,67 +0,0 @@ -from pywayland.server import Display, Signal - -from wlroots import Ptr, ffi, lib - -from .seat import Seat - - -class IdleTimeout(Ptr): - def __init__(self, ptr) -> None: - self._ptr = ffi.cast("struct wlr_idle_timeout *", ptr) - - self.idle_event = Signal(ptr=ffi.addressof(self._ptr.events.idle)) - self.resume_event = Signal(ptr=ffi.addressof(self._ptr.events.resume)) - self.destroy_event = Signal(ptr=ffi.addressof(self._ptr.events.destroy)) - - @property - def idle_state(self) -> bool: - return self._ptr.idle_state - - @property - def enabled(self) -> bool: - return self._ptr.enabled - - @property - def timeout(self) -> int: - return self._ptr.timeout - - def destroy(self) -> None: - if self._ptr is not None: - ffi.release(self._ptr) - self._ptr = None - - -class Idle(Ptr): - def __init__(self, display: Display) -> None: - self._ptr = lib.wlr_idle_create(display._ptr) - - self.activity_notify_event = Signal( - ptr=ffi.addressof(self._ptr.events.activity_notify) - ) - self.destroy_event = Signal(ptr=ffi.addressof(self._ptr.events.destroy)) - - @property - def enabled(self) -> bool: - return self._ptr.enabled - - def notify_activity(self, seat: Seat) -> None: - """ - Send notification to restart all timers for the given seat. Called by - compositor when there is an user activity event on that seat. - """ - lib.wlr_idle_notify_activity(self._ptr, seat._ptr) - - def set_enabled(self, seat: Seat, enabled: bool): - """ - Enable or disable timers for a given idle resource by seat. - Passing a NULL seat means update timers for all seats. - """ - lib.wlr_idle_set_enabled(self._ptr, seat._ptr, enabled) - - def idle_timeout_create(self, seat: Seat, timeout: int) -> IdleTimeout: - """ - Create a new timer on the given seat. The idle event will be called after - the given amount of milliseconds of inactivity, and the resumed event will - be sent at the first user activity after the fired event. - """ - return IdleTimeout(lib.wlr_idle_timeout_create(self._ptr, seat._ptr, timeout)) From b5ff93557d4fea5765254a561a400ca146baab02 Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 1 Dec 2023 20:33:22 +0000 Subject: [PATCH 60/92] (wlroots bdcf997) xwayland/server: add ready flag --- wlroots/ffi_build.py | 1 + wlroots/xwayland.py | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 75c959ae..a32703ee 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -3147,6 +3147,7 @@ def has_xwayland() -> bool: struct wl_client *client; struct wl_event_source *pipe_source; int wm_fd[2], wl_fd[2]; + bool ready; time_t server_start; int display; char display_name[16]; diff --git a/wlroots/xwayland.py b/wlroots/xwayland.py index 7d126ab2..7a604ada 100644 --- a/wlroots/xwayland.py +++ b/wlroots/xwayland.py @@ -71,6 +71,10 @@ def __init__(self, display: Display, options: ServerOptions) -> None: self.ready_event = Signal(ptr=ffi.addressof(self._ptr.events.ready)) self.destroy_event = Signal(ptr=ffi.addressof(self._ptr.events.destroy)) + @property + def ready(self) -> bool: + return self._ptr.ready + class XWayland(PtrHasData): def __init__(self, display: Display, compositor: Compositor, lazy: bool) -> None: From e825777fba8ae69eb9f98dec712726e61c049c98 Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 1 Dec 2023 21:23:47 +0000 Subject: [PATCH 61/92] make xwayland.Surface.surface an optional type --- wlroots/xwayland.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/wlroots/xwayland.py b/wlroots/xwayland.py index 7a604ada..23fa7a96 100644 --- a/wlroots/xwayland.py +++ b/wlroots/xwayland.py @@ -241,7 +241,9 @@ def icccm_input_model(self) -> int: return lib.wlr_xwayland_icccm_input_model(self._ptr) @property - def surface(self) -> WlrSurface: + def surface(self) -> WlrSurface | None: + if self._ptr.surface == ffi.NULL: + return None return WlrSurface(self._ptr.surface) @property From e6a51250f0bf12404ad65beb776eeaa3c1432d9c Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 1 Dec 2023 21:23:57 +0000 Subject: [PATCH 62/92] add xwayland.Surface associate/dissociate events --- wlroots/xwayland.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wlroots/xwayland.py b/wlroots/xwayland.py index 23fa7a96..0ff154e6 100644 --- a/wlroots/xwayland.py +++ b/wlroots/xwayland.py @@ -176,6 +176,8 @@ def __init__(self, ptr) -> None: self.request_activate_event = Signal( ptr=ffi.addressof(self._ptr.events.request_activate) ) + self.associate_event = Signal(ptr=ffi.addressof(self._ptr.events.associate)) + self.dissociate_event = Signal(ptr=ffi.addressof(self._ptr.events.dissociate)) self.set_title_event = Signal(ptr=ffi.addressof(self._ptr.events.set_title)) self.set_class_event = Signal(ptr=ffi.addressof(self._ptr.events.set_class)) self.set_role_event = Signal(ptr=ffi.addressof(self._ptr.events.set_role)) From 2160ed52f5d2bccaf20ab0a6a857fdcb4b437812 Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 1 Dec 2023 21:37:07 +0000 Subject: [PATCH 63/92] (wlroots 33b437d) wlr_scene: Amend scene_buffer.point_accepts_input to take coordinate pointers --- wlroots/ffi_build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index a32703ee..6c1088d5 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -1684,7 +1684,7 @@ def has_xwayland() -> bool: # types/wlr_scene.h CDEF += """ typedef bool (*wlr_scene_buffer_point_accepts_input_func_t)( - struct wlr_scene_buffer *buffer, int sx, int sy); + struct wlr_scene_buffer *buffer, double *sx, double *sy); typedef void (*wlr_scene_buffer_iterator_func_t)( struct wlr_scene_buffer *buffer, int sx, int sy, void *user_data); extern "Python" void buffer_iterator_callback( From 5ba424462f103177e52f06e81d44bd3226f0ba97 Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 1 Dec 2023 21:55:59 +0000 Subject: [PATCH 64/92] ruff --- wlroots/wlr_types/scene.py | 2 +- wlroots/wlr_types/xcursor_manager.py | 2 -- wlroots/wlr_types/xdg_decoration_v1.py | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/wlroots/wlr_types/scene.py b/wlroots/wlr_types/scene.py index 6d33658e..ee5f880b 100644 --- a/wlroots/wlr_types/scene.py +++ b/wlroots/wlr_types/scene.py @@ -7,7 +7,7 @@ from wlroots import Ptr, PtrHasData, ffi, lib from wlroots.util.region import PixmanRegion32 -from wlroots.wlr_types import Surface, OutputLayoutOutput +from wlroots.wlr_types import OutputLayoutOutput, Surface if TYPE_CHECKING: from wlroots.util.box import Box diff --git a/wlroots/wlr_types/xcursor_manager.py b/wlroots/wlr_types/xcursor_manager.py index d8502ffa..7e43fb40 100644 --- a/wlroots/wlr_types/xcursor_manager.py +++ b/wlroots/wlr_types/xcursor_manager.py @@ -6,8 +6,6 @@ from wlroots import Ptr, ffi, lib -from .cursor import Cursor - if TYPE_CHECKING: from typing import Iterator diff --git a/wlroots/wlr_types/xdg_decoration_v1.py b/wlroots/wlr_types/xdg_decoration_v1.py index f6df86ec..adfdeae2 100644 --- a/wlroots/wlr_types/xdg_decoration_v1.py +++ b/wlroots/wlr_types/xdg_decoration_v1.py @@ -10,7 +10,6 @@ from wlroots import PtrHasData, ffi, lib -from .compositor import Surface from .xdg_shell import XdgTopLevel if TYPE_CHECKING: From 9ffb75df2596a2557cba670d7c8cc4960c6b8c7b Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 1 Dec 2023 21:58:55 +0000 Subject: [PATCH 65/92] misc type fixes --- wlroots/xwayland.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wlroots/xwayland.py b/wlroots/xwayland.py index 0ff154e6..c6853a87 100644 --- a/wlroots/xwayland.py +++ b/wlroots/xwayland.py @@ -364,7 +364,8 @@ def for_each_surface( The iterator is called using the only wlr_surface and it's local coordinates. """ - iterator(self.surface, 0, 0, data) + if surface := self.surface: + iterator(surface, 0, 0, data) class SurfaceConfigureEvent(Ptr): From 4dbe9e0c5a0d8d89f35369a31b45fc45f5880e4b Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 1 Dec 2023 22:44:49 +0000 Subject: [PATCH 66/92] update tinywl --- tiny/server.py | 32 +++++++++++++++++++++++--------- tiny/view.py | 4 ++-- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/tiny/server.py b/tiny/server.py index 3c8eb70c..efb0915d 100644 --- a/tiny/server.py +++ b/tiny/server.py @@ -26,6 +26,7 @@ Scene, SceneBuffer, SceneNodeType, + SceneOutput, SceneSurface, SceneTree, Seat, @@ -52,6 +53,7 @@ if TYPE_CHECKING: from wlroots.wlr_types import InputDevice from wlroots.wlr_types.keyboard import KeyboardKeyEvent, KeyboardModifiers + from wlroots.wlr_types.output import OutputEventRequestState _weakkeydict: WeakKeyDictionary = WeakKeyDictionary() @@ -214,7 +216,7 @@ def process_cursor_motion(self, time) -> None: logging.debug("Processing cursor motion: %s, %s", sx, sy) if view is None: - self._cursor_manager.set_cursor_image("left_ptr", self._cursor) + self._cursor.set_xcursor(self._cursor_manager, "default") if surface is None: # Clear pointer focus so future button events and such are not sent @@ -290,8 +292,8 @@ def focus_view(self, view: View, surface: Surface | None = None) -> None: if previous_surface is not None: # Deactivate the previously focused surface logging.info("Un-focusing previous") - previous_xdg_surface = XdgSurface.from_surface(previous_surface) - previous_xdg_surface.set_activated(False) + if previous_xdg_surface := XdgSurface.try_from_surface(previous_surface): + previous_xdg_surface.set_activated(False) view.scene_node.raise_to_top() # roll the given surface to the front of the list, copy and modify the @@ -323,10 +325,12 @@ def server_new_xdg_surface(self, listener, xdg_surface: XdgSurface) -> None: # we must provide the proper parent scene node of the xdg popup. To # enable this, we always set the user data field of xdg_surfaces to # the corresponding scene node. - parent_xdg_surface = XdgSurface.from_surface(xdg_surface.popup.parent) - parent_scene_tree = cast(SceneTree, parent_xdg_surface.data) - scene_tree = Scene.xdg_surface_create(parent_scene_tree, xdg_surface) - xdg_surface.data = scene_tree + if parent_xdg_surface := XdgSurface.try_from_surface( + xdg_surface.popup.parent + ): + parent_scene_tree = cast(SceneTree, parent_xdg_surface.data) + scene_tree = Scene.xdg_surface_create(parent_scene_tree, xdg_surface) + xdg_surface.data = scene_tree return assert xdg_surface.role == XdgSurfaceRole.TOPLEVEL @@ -345,18 +349,24 @@ def server_new_xdg_surface(self, listener, xdg_surface: XdgSurface) -> None: # output and frame handling callbacks def server_new_output(self, listener, output: Output) -> None: + SceneOutput.create(self._scene, output) output.init_render(self._allocator, self._renderer) state = OutputState() state.enabled = True - state.mode = output.preferred_mode() + if mode := output.preferred_mode(): + state.mode = mode output.commit(state) + state.finish() self.outputs.append(output) - self._output_layout.add_auto(output) + if not self._output_layout.add_auto(output): + logging.warning("Failed to add output to layout.") + return output.frame_event.add(Listener(self.output_frame)) + output.request_state_event.add(Listener(self.output_request_state)) def output_frame(self, listener, data) -> None: output = self.outputs[0] @@ -366,6 +376,10 @@ def output_frame(self, listener, data) -> None: now = Timespec.get_monotonic_time() scene_output.send_frame_done(now) + def output_request_state(self, listener, request: OutputEventRequestState) -> None: + output = self.outputs[0] + output.commit_state(request.state) + # ############################################################# # input handling callbacks diff --git a/tiny/view.py b/tiny/view.py index 82266b3d..7089e523 100644 --- a/tiny/view.py +++ b/tiny/view.py @@ -31,8 +31,8 @@ def __init__( self.x = 0.0 self.y = 0.0 - xdg_surface.map_event.add(Listener(self.xdg_toplevel_map)) - xdg_surface.unmap_event.add(Listener(self.xdg_toplevel_unmap)) + xdg_surface.surface.map_event.add(Listener(self.xdg_toplevel_map)) + xdg_surface.surface.unmap_event.add(Listener(self.xdg_toplevel_unmap)) xdg_surface.destroy_event.add(Listener(self.xdg_toplevel_destroy)) toplevel = xdg_surface.toplevel From efc595fde72f4779d79eeeceed5f1c176e5a964f Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 1 Dec 2023 22:55:22 +0000 Subject: [PATCH 67/92] bump wlroots version to 0.17 in CI --- .github/workflows/ci.yml | 8 ++++---- .github/workflows/release.yml | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index da0928e8..fc08fdd1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ jobs: strategy: fail-fast: false matrix: - wlroots-version: ["0.16.2", master] + wlroots-version: ["0.17.0", master] steps: - name: Install dependencies run: | @@ -147,7 +147,7 @@ jobs: - "pypy-3.8" - "pypy-3.9" - "pypy-3.10" - wlroots-version: ["0.16.2"] + wlroots-version: ["0.17.0"] include: - python-version: "3.12" wlroots-version: master @@ -262,7 +262,7 @@ jobs: needs: build-wayland env: python-version: "3.12" - wlroots-version: "0.16.2" + wlroots-version: "0.17.0" steps: - name: Download wayland libraries uses: actions/download-artifact@v3 @@ -298,7 +298,7 @@ jobs: needs: build-wayland env: python-version: "3.12" - wlroots-version: "0.16.2" + wlroots-version: "0.17.0" steps: - name: Download wayland libraries uses: actions/download-artifact@v3 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 28ba559a..38db66c4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,9 +13,9 @@ jobs: libdrm-version: "2.4.114" seatd-version: "0.6.3" pixman-version: "0.42.0" - wayland-protocols-version: "1.31" + wayland-protocols-version: "1.32" wayland-version: "1.22.0" - wlroots-version: "0.16.2" + wlroots-version: "0.17.0" steps: - name: Install dependencies run: | From ebf4d7634b99df85c83a18012719cef38d90af9d Mon Sep 17 00:00:00 2001 From: mcol Date: Fri, 1 Dec 2023 23:08:14 +0000 Subject: [PATCH 68/92] bump protocols version in CI --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fc08fdd1..4b06089e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,7 @@ jobs: pixman-version: "0.42.0" hwdata-version: "0.364" wayland-version: "1.22.0" - wayland-protocols-version: "1.31" + wayland-protocols-version: "1.32" strategy: fail-fast: false matrix: From 5ca9f62491866833fcf3c3420763c8dedb663f5a Mon Sep 17 00:00:00 2001 From: Jeroen Wijenbergh Date: Sun, 5 May 2024 19:34:40 +0200 Subject: [PATCH 69/92] Add wlr_fractional_scale_manager_v1 --- wlroots/ffi_build.py | 21 +++++++++++++++++++++ wlroots/wlr_types/__init__.py | 1 + wlroots/wlr_types/fractional_scale_v1.py | 17 +++++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 wlroots/wlr_types/fractional_scale_v1.py diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 6c1088d5..84a853f7 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -735,6 +735,26 @@ def has_xwayland() -> bool: struct wlr_foreign_toplevel_handle_v1 *parent); """ +# types/wlr_fractional_scale_v1.h +CDEF += """ +struct wlr_fractional_scale_manager_v1 { + struct wl_global *global; + + struct { + struct wl_signal destroy; + } events; + + ...; +}; + + +void wlr_fractional_scale_v1_notify_scale( + struct wlr_surface *surface, double scale); + +struct wlr_fractional_scale_manager_v1 *wlr_fractional_scale_manager_v1_create( + struct wl_display *display, uint32_t version); +""" + # types/wlr_gamma_control_v1.h CDEF += """ struct wlr_gamma_control_manager_v1 { @@ -2955,6 +2975,7 @@ def has_xwayland() -> bool: #include #include #include +#include #include #include #include diff --git a/wlroots/wlr_types/__init__.py b/wlroots/wlr_types/__init__.py index 1666d18a..726e9765 100644 --- a/wlroots/wlr_types/__init__.py +++ b/wlroots/wlr_types/__init__.py @@ -13,6 +13,7 @@ from .data_device_manager import DataDeviceManager # noqa: F401 from .export_dmabuf_v1 import ExportDmabufManagerV1 # noqa: F401 from .foreign_toplevel_management_v1 import ForeignToplevelManagerV1 # noqa: F401 +from .fractional_scale_v1 import FractionalScaleManagerV1 # noqa: F401 from .gamma_control_v1 import GammaControlManagerV1 # noqa: F401 from .input_device import InputDevice # noqa: F401 from .input_inhibit import InputInhibitManager # noqa: F401 diff --git a/wlroots/wlr_types/fractional_scale_v1.py b/wlroots/wlr_types/fractional_scale_v1.py new file mode 100644 index 00000000..17802064 --- /dev/null +++ b/wlroots/wlr_types/fractional_scale_v1.py @@ -0,0 +1,17 @@ +# Copyright (c) 2024 Jeroen Wijenbergh + +from pywayland.server import Display + +from wlroots import PtrHasData, lib + +from .compositor import Surface + + +class FractionalScaleManagerV1(PtrHasData): + def __init__(self, display: Display, version: int = 1) -> None: + """Create a wlr_fractional_scale_manager_v1""" + self._ptr = lib.wlr_fractional_scale_manager_v1_create(display._ptr, version) + + +def notify_scale(surface: Surface, scale: float): + lib.wlr_fractional_scale_v1_notify_scale(surface._ptr, scale) From e5ddbb89f317d8f8644173248cac16fa11febae8 Mon Sep 17 00:00:00 2001 From: Jeroen Wijenbergh Date: Sun, 5 May 2024 19:34:48 +0200 Subject: [PATCH 70/92] WLR Types: WLR 0.17 session lock changes --- wlroots/ffi_build.py | 23 +---------------------- wlroots/wlr_types/session_lock_v1.py | 11 ++--------- 2 files changed, 3 insertions(+), 31 deletions(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 84a853f7..16bfb1d6 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -2267,25 +2267,6 @@ def has_xwayland() -> bool: void *data; }; -struct wlr_session_lock_surface_v1 { - struct wl_resource *resource; - struct wl_list link; // wlr_session_lock_v1.surfaces - - struct wlr_output *output; - struct wlr_surface *surface; - - bool configured, mapped; - - struct { - struct wl_signal map; - struct wl_signal destroy; - } events; - - void *data; - - ...; -}; - struct wlr_session_lock_manager_v1 *wlr_session_lock_manager_v1_create( struct wl_display *display); @@ -2296,9 +2277,7 @@ def has_xwayland() -> bool: struct wlr_session_lock_surface_v1 *lock_surface, uint32_t width, uint32_t height); -bool wlr_surface_is_session_lock_surface_v1(struct wlr_surface *surface); - -struct wlr_session_lock_surface_v1 *wlr_session_lock_surface_v1_from_wlr_surface( +struct wlr_session_lock_surface_v1 *wlr_session_lock_surface_v1_try_from_wlr_surface( struct wlr_surface *surface); """ diff --git a/wlroots/wlr_types/session_lock_v1.py b/wlroots/wlr_types/session_lock_v1.py index fa7e77b2..6c25d6f6 100644 --- a/wlroots/wlr_types/session_lock_v1.py +++ b/wlroots/wlr_types/session_lock_v1.py @@ -97,7 +97,7 @@ def configure(self, width: int, height: int) -> int: return lib.wlr_session_lock_surface_v1_configure(self._ptr, width, height) @staticmethod - def from_surface(surface: Surface) -> SessionLockSurfaceV1 | None: + def try_from_surface(surface: Surface) -> SessionLockSurfaceV1 | None: """ Get a SessionLockSurfaceV1 from a surface. @@ -105,12 +105,5 @@ def from_surface(surface: Surface) -> SessionLockSurfaceV1 | None: May return None even if the surface has the session lock surface role if the corresponding session lock surface has been destroyed. """ - surface_ptr = lib.wlr_session_lock_surface_v1_from_wlr_surface(surface._ptr) + surface_ptr = lib.wlr_session_lock_surface_v1_try_from_wlr_surface(surface._ptr) return SessionLockSurfaceV1(surface_ptr) if surface_ptr != ffi.NULL else None - - -def surface_is_session_lock_surface_v1(surface: Surface) -> bool: - """ - Returns true if the surface has the session lock surface role. - """ - return lib.wlr_surface_is_session_lock_surface_v1(surface._ptr) From fed105856450f5c3a941207e5d5a504dfdc5ac8b Mon Sep 17 00:00:00 2001 From: Jeroen Wijenbergh Date: Sun, 5 May 2024 19:34:55 +0200 Subject: [PATCH 71/92] FFI Build: Fix duplicate wlr_output_state declarations --- wlroots/ffi_build.py | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 16bfb1d6..011eabd7 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -1155,6 +1155,8 @@ def has_xwayland() -> bool: bool wlr_output_commit_state(struct wlr_output *output, const struct wlr_output_state *state); +void wlr_output_state_init(struct wlr_output_state *state); +void wlr_output_state_finish(struct wlr_output_state *state); void wlr_output_state_set_enabled(struct wlr_output_state *state, bool enabled); void wlr_output_state_set_mode(struct wlr_output_state *state, @@ -1179,15 +1181,6 @@ def has_xwayland() -> bool: enum wl_output_transform wlr_output_transform_compose( enum wl_output_transform tr_a, enum wl_output_transform tr_b); - -void wlr_output_state_init(struct wlr_output_state *state); -void wlr_output_state_finish(struct wlr_output_state *state); -void wlr_output_state_set_enabled(struct wlr_output_state *state, - bool enabled); -void wlr_output_state_set_mode(struct wlr_output_state *state, - struct wlr_output_mode *mode); -void wlr_output_state_set_custom_mode(struct wlr_output_state *state, - int32_t width, int32_t height, int32_t refresh); """ # types/wlr_output_layout.h From fc504fe7ca5a659f44567b6049084e46cabdad10 Mon Sep 17 00:00:00 2001 From: Jeroen Wijenbergh Date: Mon, 6 May 2024 22:02:38 +0200 Subject: [PATCH 72/92] Headers: Drop KDE idle protocol --- check_headers.py | 1 - wlroots/include/idle-protocol.h | 176 -------------------------------- 2 files changed, 177 deletions(-) delete mode 100644 wlroots/include/idle-protocol.h diff --git a/check_headers.py b/check_headers.py index f98d7ff5..94470e53 100644 --- a/check_headers.py +++ b/check_headers.py @@ -13,7 +13,6 @@ "unstable/pointer-constraints/pointer-constraints-unstable-v1.xml", ] WLROOTS_PROTOCOLS = [ - "protocol/idle.xml", "protocol/wlr-output-power-management-unstable-v1.xml", "protocol/wlr-layer-shell-unstable-v1.xml", ] diff --git a/wlroots/include/idle-protocol.h b/wlroots/include/idle-protocol.h deleted file mode 100644 index 7351126f..00000000 --- a/wlroots/include/idle-protocol.h +++ /dev/null @@ -1,176 +0,0 @@ -/* Generated by wayland-scanner 1.21.0 */ - -#ifndef IDLE_SERVER_PROTOCOL_H -#define IDLE_SERVER_PROTOCOL_H - -#include -#include -#include "wayland-server.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct wl_client; -struct wl_resource; - -/** - * @page page_idle The idle protocol - * @section page_ifaces_idle Interfaces - * - @subpage page_iface_org_kde_kwin_idle - User idle time manager - * - @subpage page_iface_org_kde_kwin_idle_timeout - - * @section page_copyright_idle Copyright - *
- *
- * Copyright (C) 2015 Martin Gräßlin
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see .
- * 
- */ -struct org_kde_kwin_idle; -struct org_kde_kwin_idle_timeout; -struct wl_seat; - -#ifndef ORG_KDE_KWIN_IDLE_INTERFACE -#define ORG_KDE_KWIN_IDLE_INTERFACE -/** - * @page page_iface_org_kde_kwin_idle org_kde_kwin_idle - * @section page_iface_org_kde_kwin_idle_desc Description - * - * This interface allows to monitor user idle time on a given seat. The interface - * allows to register timers which trigger after no user activity was registered - * on the seat for a given interval. It notifies when user activity resumes. - * - * This is useful for applications wanting to perform actions when the user is not - * interacting with the system, e.g. chat applications setting the user as away, power - * management features to dim screen, etc.. - * @section page_iface_org_kde_kwin_idle_api API - * See @ref iface_org_kde_kwin_idle. - */ -/** - * @defgroup iface_org_kde_kwin_idle The org_kde_kwin_idle interface - * - * This interface allows to monitor user idle time on a given seat. The interface - * allows to register timers which trigger after no user activity was registered - * on the seat for a given interval. It notifies when user activity resumes. - * - * This is useful for applications wanting to perform actions when the user is not - * interacting with the system, e.g. chat applications setting the user as away, power - * management features to dim screen, etc.. - */ -extern const struct wl_interface org_kde_kwin_idle_interface; -#endif -#ifndef ORG_KDE_KWIN_IDLE_TIMEOUT_INTERFACE -#define ORG_KDE_KWIN_IDLE_TIMEOUT_INTERFACE -/** - * @page page_iface_org_kde_kwin_idle_timeout org_kde_kwin_idle_timeout - * @section page_iface_org_kde_kwin_idle_timeout_api API - * See @ref iface_org_kde_kwin_idle_timeout. - */ -/** - * @defgroup iface_org_kde_kwin_idle_timeout The org_kde_kwin_idle_timeout interface - */ -extern const struct wl_interface org_kde_kwin_idle_timeout_interface; -#endif - -/** - * @ingroup iface_org_kde_kwin_idle - * @struct org_kde_kwin_idle_interface - */ -struct org_kde_kwin_idle_interface { - /** - * @param timeout The idle timeout in msec - */ - void (*get_idle_timeout)(struct wl_client *client, - struct wl_resource *resource, - uint32_t id, - struct wl_resource *seat, - uint32_t timeout); -}; - - -/** - * @ingroup iface_org_kde_kwin_idle - */ -#define ORG_KDE_KWIN_IDLE_GET_IDLE_TIMEOUT_SINCE_VERSION 1 - -/** - * @ingroup iface_org_kde_kwin_idle_timeout - * @struct org_kde_kwin_idle_timeout_interface - */ -struct org_kde_kwin_idle_timeout_interface { - /** - * release the timeout object - * - * - */ - void (*release)(struct wl_client *client, - struct wl_resource *resource); - /** - * Simulates user activity for this timeout, behaves just like real user activity on the seat - * - * - */ - void (*simulate_user_activity)(struct wl_client *client, - struct wl_resource *resource); -}; - -#define ORG_KDE_KWIN_IDLE_TIMEOUT_IDLE 0 -#define ORG_KDE_KWIN_IDLE_TIMEOUT_RESUMED 1 - -/** - * @ingroup iface_org_kde_kwin_idle_timeout - */ -#define ORG_KDE_KWIN_IDLE_TIMEOUT_IDLE_SINCE_VERSION 1 -/** - * @ingroup iface_org_kde_kwin_idle_timeout - */ -#define ORG_KDE_KWIN_IDLE_TIMEOUT_RESUMED_SINCE_VERSION 1 - -/** - * @ingroup iface_org_kde_kwin_idle_timeout - */ -#define ORG_KDE_KWIN_IDLE_TIMEOUT_RELEASE_SINCE_VERSION 1 -/** - * @ingroup iface_org_kde_kwin_idle_timeout - */ -#define ORG_KDE_KWIN_IDLE_TIMEOUT_SIMULATE_USER_ACTIVITY_SINCE_VERSION 1 - -/** - * @ingroup iface_org_kde_kwin_idle_timeout - * Sends an idle event to the client owning the resource. - * @param resource_ The client's resource - */ -static inline void -org_kde_kwin_idle_timeout_send_idle(struct wl_resource *resource_) -{ - wl_resource_post_event(resource_, ORG_KDE_KWIN_IDLE_TIMEOUT_IDLE); -} - -/** - * @ingroup iface_org_kde_kwin_idle_timeout - * Sends an resumed event to the client owning the resource. - * @param resource_ The client's resource - */ -static inline void -org_kde_kwin_idle_timeout_send_resumed(struct wl_resource *resource_) -{ - wl_resource_post_event(resource_, ORG_KDE_KWIN_IDLE_TIMEOUT_RESUMED); -} - -#ifdef __cplusplus -} -#endif - -#endif From f30788cc7ec47f6ad1bb9d6e31e31cd479d0e80e Mon Sep 17 00:00:00 2001 From: Jeroen Wijenbergh Date: Mon, 6 May 2024 22:03:02 +0200 Subject: [PATCH 73/92] wlroots: re-gen --- .../idle-inhibit-unstable-v1-protocol.h | 2 +- ...pointer-constraints-unstable-v1-protocol.h | 2 +- .../wlr-layer-shell-unstable-v1-protocol.h | 2 +- ...ut-power-management-unstable-v1-protocol.h | 2 +- wlroots/include/xdg-shell-protocol.h | 66 +++++++++++++------ 5 files changed, 51 insertions(+), 23 deletions(-) diff --git a/wlroots/include/idle-inhibit-unstable-v1-protocol.h b/wlroots/include/idle-inhibit-unstable-v1-protocol.h index 9673a68e..f1425b55 100644 --- a/wlroots/include/idle-inhibit-unstable-v1-protocol.h +++ b/wlroots/include/idle-inhibit-unstable-v1-protocol.h @@ -1,4 +1,4 @@ -/* Generated by wayland-scanner 1.21.0 */ +/* Generated by wayland-scanner 1.22.0 */ #ifndef IDLE_INHIBIT_UNSTABLE_V1_SERVER_PROTOCOL_H #define IDLE_INHIBIT_UNSTABLE_V1_SERVER_PROTOCOL_H diff --git a/wlroots/include/pointer-constraints-unstable-v1-protocol.h b/wlroots/include/pointer-constraints-unstable-v1-protocol.h index 2802032b..cd12cf17 100644 --- a/wlroots/include/pointer-constraints-unstable-v1-protocol.h +++ b/wlroots/include/pointer-constraints-unstable-v1-protocol.h @@ -1,4 +1,4 @@ -/* Generated by wayland-scanner 1.21.0 */ +/* Generated by wayland-scanner 1.22.0 */ #ifndef POINTER_CONSTRAINTS_UNSTABLE_V1_SERVER_PROTOCOL_H #define POINTER_CONSTRAINTS_UNSTABLE_V1_SERVER_PROTOCOL_H diff --git a/wlroots/include/wlr-layer-shell-unstable-v1-protocol.h b/wlroots/include/wlr-layer-shell-unstable-v1-protocol.h index 3b4d7e7d..6c82a16c 100644 --- a/wlroots/include/wlr-layer-shell-unstable-v1-protocol.h +++ b/wlroots/include/wlr-layer-shell-unstable-v1-protocol.h @@ -1,4 +1,4 @@ -/* Generated by wayland-scanner 1.21.0 */ +/* Generated by wayland-scanner 1.22.0 */ #ifndef WLR_LAYER_SHELL_UNSTABLE_V1_SERVER_PROTOCOL_H #define WLR_LAYER_SHELL_UNSTABLE_V1_SERVER_PROTOCOL_H diff --git a/wlroots/include/wlr-output-power-management-unstable-v1-protocol.h b/wlroots/include/wlr-output-power-management-unstable-v1-protocol.h index 6d92e782..4387c518 100644 --- a/wlroots/include/wlr-output-power-management-unstable-v1-protocol.h +++ b/wlroots/include/wlr-output-power-management-unstable-v1-protocol.h @@ -1,4 +1,4 @@ -/* Generated by wayland-scanner 1.21.0 */ +/* Generated by wayland-scanner 1.22.0 */ #ifndef WLR_OUTPUT_POWER_MANAGEMENT_UNSTABLE_V1_SERVER_PROTOCOL_H #define WLR_OUTPUT_POWER_MANAGEMENT_UNSTABLE_V1_SERVER_PROTOCOL_H diff --git a/wlroots/include/xdg-shell-protocol.h b/wlroots/include/xdg-shell-protocol.h index 8db7e1c6..184572b5 100644 --- a/wlroots/include/xdg-shell-protocol.h +++ b/wlroots/include/xdg-shell-protocol.h @@ -1,4 +1,4 @@ -/* Generated by wayland-scanner 1.21.0 */ +/* Generated by wayland-scanner 1.22.0 */ #ifndef XDG_SHELL_SERVER_PROTOCOL_H #define XDG_SHELL_SERVER_PROTOCOL_H @@ -172,8 +172,10 @@ extern const struct wl_interface xdg_positioner_interface; * * After creating a role-specific object and setting it up, the client must * perform an initial commit without any buffer attached. The compositor - * will reply with an xdg_surface.configure event. The client must - * acknowledge it and is then allowed to attach a buffer to map the surface. + * will reply with initial wl_surface state such as + * wl_surface.preferred_buffer_scale followed by an xdg_surface.configure + * event. The client must acknowledge it and is then allowed to attach a + * buffer to map the surface. * * Mapping an xdg_surface-based role surface is defined as making it * possible for the surface to be shown by the compositor. Note that @@ -223,8 +225,10 @@ extern const struct wl_interface xdg_positioner_interface; * * After creating a role-specific object and setting it up, the client must * perform an initial commit without any buffer attached. The compositor - * will reply with an xdg_surface.configure event. The client must - * acknowledge it and is then allowed to attach a buffer to map the surface. + * will reply with initial wl_surface state such as + * wl_surface.preferred_buffer_scale followed by an xdg_surface.configure + * event. The client must acknowledge it and is then allowed to attach a + * buffer to map the surface. * * Mapping an xdg_surface-based role surface is defined as making it * possible for the surface to be shown by the compositor. Note that @@ -959,13 +963,22 @@ struct xdg_surface_interface { * commit. This unset is meant for extremely simple clients. * * The arguments are given in the surface-local coordinate space of - * the wl_surface associated with this xdg_surface. + * the wl_surface associated with this xdg_surface, and may extend + * outside of the wl_surface itself to mark parts of the subsurface + * tree as part of the window geometry. * - * The width and height must be greater than zero. Setting an - * invalid size will raise an invalid_size error. When applied, the - * effective window geometry will be the set window geometry - * clamped to the bounding rectangle of the combined geometry of - * the surface of the xdg_surface and the associated subsurfaces. + * When applied, the effective window geometry will be the set + * window geometry clamped to the bounding rectangle of the + * combined geometry of the surface of the xdg_surface and the + * associated subsurfaces. + * + * The effective geometry will not be recalculated unless a new + * call to set_window_geometry is done and the new pending surface + * state is subsequently applied. + * + * The width and height of the effective window geometry must be + * greater than zero. Setting an invalid size will raise an + * invalid_size error. */ void (*set_window_geometry)(struct wl_client *client, struct wl_resource *resource, @@ -1117,7 +1130,8 @@ enum xdg_toplevel_state { * the surface is maximized * * The surface is maximized. The window geometry specified in the - * configure event must be obeyed by the client. + * configure event must be obeyed by the client, or the + * xdg_wm_base.invalid_surface_state error is raised. * * The client should draw without shadow or other decoration * outside of the window geometry. @@ -1185,6 +1199,15 @@ enum xdg_toplevel_state { * @since 2 */ XDG_TOPLEVEL_STATE_TILED_BOTTOM = 8, + /** + * surface repaint is suspended + * + * The surface is currently not ordinarily being repainted; for + * example because its content is occluded by another window, or + * its outputs are switched off due to screen locking. + * @since 6 + */ + XDG_TOPLEVEL_STATE_SUSPENDED = 9, }; /** * @ingroup iface_xdg_toplevel @@ -1202,6 +1225,10 @@ enum xdg_toplevel_state { * @ingroup iface_xdg_toplevel */ #define XDG_TOPLEVEL_STATE_TILED_BOTTOM_SINCE_VERSION 2 +/** + * @ingroup iface_xdg_toplevel + */ +#define XDG_TOPLEVEL_STATE_SUSPENDED_SINCE_VERSION 6 #endif /* XDG_TOPLEVEL_STATE_ENUM */ #ifndef XDG_TOPLEVEL_WM_CAPABILITIES_ENUM @@ -1397,11 +1424,12 @@ struct xdg_toplevel_interface { * * The edges parameter specifies how the surface should be resized, * and is one of the values of the resize_edge enum. Values not - * matching a variant of the enum will cause a protocol error. The - * compositor may use this information to update the surface - * position for example when dragging the top left corner. The - * compositor may also use this information to adapt its behavior, - * e.g. choose an appropriate cursor image. + * matching a variant of the enum will cause the + * invalid_resize_edge protocol error. The compositor may use this + * information to update the surface position for example when + * dragging the top left corner. The compositor may also use this + * information to adapt its behavior, e.g. choose an appropriate + * cursor image. * @param seat the wl_seat of the user event * @param serial the serial of the user event * @param edges which edge or corner is being dragged @@ -1765,8 +1793,8 @@ struct xdg_popup_interface { * This destroys the popup. Explicitly destroying the xdg_popup * object will also dismiss the popup, and unmap the surface. * - * If this xdg_popup is not the "topmost" popup, a protocol error - * will be sent. + * If this xdg_popup is not the "topmost" popup, the + * xdg_wm_base.not_the_topmost_popup protocol error will be sent. */ void (*destroy)(struct wl_client *client, struct wl_resource *resource); From cbff1cf88819cbd754da20ea3f92f61cc419d9cf Mon Sep 17 00:00:00 2001 From: Jeroen Wijenbergh Date: Mon, 6 May 2024 22:03:29 +0200 Subject: [PATCH 74/92] CI: Build xwayland from source For some reason using xwayland from apt/yum will make wlroots not find it. Maybe compiling xwayland from source is better anyways as we can have a newer version --- .github/workflows/ci.yml | 21 +++++++++++++++-- .github/workflows/release.yml | 43 ++++++++++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4b06089e..5c40e2cb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,6 +14,7 @@ jobs: libdrm-version: "2.4.114" seatd-version: "0.6.4" pixman-version: "0.42.0" + xwayland-version: "22.1.9" hwdata-version: "0.364" wayland-version: "1.22.0" wayland-protocols-version: "1.32" @@ -26,6 +27,7 @@ jobs: run: | sudo apt update sudo apt-get install -y --no-install-recommends \ + libepoxy-dev \ libegl1-mesa-dev \ libgbm-dev \ libgles2-mesa-dev \ @@ -33,6 +35,7 @@ jobs: libpciaccess-dev \ libxcb-composite0-dev \ libxcb-dri3-dev \ + libxcb-ewmh-dev \ libxcb-icccm4-dev \ libxcb-image0-dev \ libxcb-present-dev \ @@ -41,9 +44,12 @@ jobs: libxcb-xfixes0-dev \ libxcb-xinput-dev \ libxcb1-dev \ + libxfont-dev \ libxkbcommon-dev \ - ninja-build \ - xwayland + libxshmfence-dev \ + xfonts-utils \ + xserver-xorg-dev \ + ninja-build sudo pip install meson - name: Set environment variables run: | @@ -55,6 +61,7 @@ jobs: run: | wget $WAYLAND_URL wget $WAYLAND_PROTOCOLS_URL + wget $XWAYLAND_URL wget $LIBDRM_URL wget -O seatd.tar.gz $SEATD_URL wget $PIXMAN_URL @@ -62,6 +69,7 @@ jobs: wget -O wlroots.tar.gz $WLROOTS_URL tar -xJf wayland-${{ env.wayland-version }}.tar.xz tar -xJf wayland-protocols-${{ env.wayland-protocols-version }}.tar.xz + tar -xzf xserver-xwayland-${{ env.xwayland-version }}.tar.gz tar -xzf drm-libdrm-${{ env.libdrm-version }}.tar.gz tar -xzf seatd.tar.gz tar -xjf pixman-pixman-${{ env.pixman-version }}.tar.bz2 @@ -70,6 +78,7 @@ jobs: env: WAYLAND_URL: https://gitlab.freedesktop.org/wayland/wayland/-/releases/${{ env.wayland-version }}/downloads/wayland-${{ env.wayland-version }}.tar.xz WAYLAND_PROTOCOLS_URL: https://gitlab.freedesktop.org/wayland/wayland-protocols/-/releases/${{ env.wayland-protocols-version }}/downloads/wayland-protocols-${{ env.wayland-protocols-version }}.tar.xz + XWAYLAND_URL: https://gitlab.freedesktop.org/xorg/xserver/-/archive/xwayland-${{ env.xwayland-version }}/xserver-xwayland-${{ env.xwayland-version }}.tar.gz LIBDRM_URL: https://gitlab.freedesktop.org/mesa/drm/-/archive/libdrm-${{ env.libdrm-version }}/drm-libdrm-${{ env.libdrm-version }}.tar.gz SEATD_URL: https://git.sr.ht/~kennylevinsen/seatd/archive/${{ env.seatd-version }}.tar.gz PIXMAN_URL: https://gitlab.freedesktop.org/pixman/pixman/-/archive/pixman-${{ env.pixman-version }}/pixman-pixman-${{ env.pixman-version }}.tar.bz2 @@ -116,6 +125,13 @@ jobs: ./configure --prefix=/usr --libdir=/lib --datadir=/usr/share make sudo make install + - name: Build xwayland + working-directory: xserver-xwayland-${{ env.xwayland-version }} + run: | + meson build --prefix=/usr + ninja -C build + DESTDIR=~/wayland ninja -C build install + sudo ninja -C build install - name: Build wlroots working-directory: wlroots-${{ matrix.wlroots-version }} continue-on-error: ${{ matrix.wlroots-version == 'master' }} @@ -174,6 +190,7 @@ jobs: libinput-dev \ libpciaccess-dev \ libxcb-composite0-dev \ + libxcb-ewmh-dev \ libxcb-dri3-dev \ libxcb-icccm4-dev \ libxcb-image0-dev \ diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 38db66c4..cdf54672 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,6 +13,9 @@ jobs: libdrm-version: "2.4.114" seatd-version: "0.6.3" pixman-version: "0.42.0" + xwayland-version: "22.1.9" + xcvt-version: "0.1.2" + inputproto-version: "2021.5" wayland-protocols-version: "1.32" wayland-version: "1.22.0" wlroots-version: "0.17.0" @@ -22,20 +25,28 @@ jobs: yum -y install \ hwdata \ python3-pip \ + libepoxy-devel \ libffi-devel \ libinput-devel \ libpciaccess-devel \ + libtirpc-devel \ libudev-devel \ + libXdmcp-devel \ + libXfont2-devel \ libxkbcommon-x11-devel \ + libxkbfile-devel \ libxml2-devel \ + libxshmfence-devel \ mesa-libEGL-devel \ mesa-libgbm-devel \ + openssl-devel \ xcb-util-devel \ xcb-util-image-devel \ xcb-util-keysyms-devel \ xcb-util-renderutil-devel \ xcb-util-wm-devel \ - xorg-x11-server-Xwayland \ + xorg-x11-font-utils \ + xorg-x11-xtrans-devel \ ninja-build \ wget - name: Set environment variables @@ -48,12 +59,18 @@ jobs: run: | wget $WAYLAND_URL wget $WAYLAND_PROTOCOLS_URL + wget $XCVT_URL + wget $INPUTPROTO_URL + wget $XWAYLAND_URL wget $LIBDRM_URL wget -O seatd.tar.gz $SEATD_URL wget $PIXMAN_URL wget -O wlroots.tar.gz $WLROOTS_URL tar -xJf wayland-${{ env.wayland-version }}.tar.xz tar -xJf wayland-protocols-${{ env.wayland-protocols-version }}.tar.xz + tar -xzf xorgproto-xorgproto-${{ env.inputproto-version }}.tar.gz + tar -xzf libxcvt-libxcvt-${{ env.xcvt-version }}.tar.gz + tar -xzf xserver-xwayland-${{ env.xwayland-version }}.tar.gz tar -xzf drm-libdrm-${{ env.libdrm-version }}.tar.gz tar -xjf pixman-pixman-${{ env.pixman-version }}.tar.bz2 tar -xzf seatd.tar.gz @@ -61,6 +78,9 @@ jobs: env: WAYLAND_URL: https://gitlab.freedesktop.org/wayland/wayland/-/releases/${{ env.wayland-version }}/downloads/wayland-${{ env.wayland-version }}.tar.xz WAYLAND_PROTOCOLS_URL: https://gitlab.freedesktop.org/wayland/wayland-protocols/-/releases/${{ env.wayland-protocols-version }}/downloads/wayland-protocols-${{ env.wayland-protocols-version }}.tar.xz + XWAYLAND_URL: https://gitlab.freedesktop.org/xorg/xserver/-/archive/xwayland-${{ env.xwayland-version }}/xserver-xwayland-${{ env.xwayland-version }}.tar.gz + XCVT_URL: https://gitlab.freedesktop.org/xorg/lib/libxcvt/-/archive/libxcvt-${{ env.xcvt-version }}/libxcvt-libxcvt-${{ env.xcvt-version }}.tar.gz + INPUTPROTO_URL: https://gitlab.freedesktop.org/xorg/proto/xorgproto/-/archive/xorgproto-${{ env.inputproto-version}}/xorgproto-xorgproto-${{ env.inputproto-version}}.tar.gz LIBDRM_URL: https://gitlab.freedesktop.org/mesa/drm/-/archive/libdrm-${{ env.libdrm-version }}/drm-libdrm-${{ env.libdrm-version }}.tar.gz SEATD_URL: https://git.sr.ht/~kennylevinsen/seatd/archive/${{ env.seatd-version }}.tar.gz PIXMAN_URL: https://gitlab.freedesktop.org/pixman/pixman/-/archive/pixman-${{ env.pixman-version }}/pixman-pixman-${{ env.pixman-version }}.tar.bz2 @@ -103,6 +123,27 @@ jobs: ninja -C build DESTDIR=~/wayland ninja -C build install ninja -C build install + - name: Build inputproto + working-directory: xorgproto-xorgproto-${{ env.inputproto-version }} + run: | + meson build --prefix=/usr + ninja -C build + DESTDIR=~/wayland ninja -C build install + ninja -C build install + - name: Build libxcvt + working-directory: libxcvt-libxcvt-${{ env.xcvt-version }} + run: | + meson build --prefix=/usr + ninja -C build + DESTDIR=~/wayland ninja -C build install + ninja -C build install + - name: Build xwayland + working-directory: xserver-xwayland-${{ env.xwayland-version }} + run: | + meson build --prefix=/usr + ninja -C build + DESTDIR=~/wayland ninja -C build install + ninja -C build install - name: Build wlroots working-directory: wlroots-${{ env.wlroots-version }} run: | From 357f645aea1e7851f7b3b5007f9004bd6cbbbcc0 Mon Sep 17 00:00:00 2001 From: Jeroen Wijenbergh Date: Mon, 6 May 2024 22:06:32 +0200 Subject: [PATCH 75/92] ffi: Add back definitions of wlr_session_lock_surface_v1 --- wlroots/ffi_build.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 011eabd7..2ab5703f 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -2260,6 +2260,40 @@ def has_xwayland() -> bool: void *data; }; +struct wlr_session_lock_surface_v1_state { + uint32_t width, height; + uint32_t configure_serial; +}; + +struct wlr_session_lock_surface_v1_configure { + struct wl_list link; // wlr_session_lock_surface_v1.configure_list + uint32_t serial; + + uint32_t width, height; +}; + +struct wlr_session_lock_surface_v1 { + struct wl_resource *resource; + struct wl_list link; // wlr_session_lock_v1.surfaces + + struct wlr_output *output; + struct wlr_surface *surface; + + bool configured; + + struct wl_list configure_list; // wlr_session_lock_surface_v1_configure.link + + struct wlr_session_lock_surface_v1_state current; + struct wlr_session_lock_surface_v1_state pending; + + struct { + struct wl_signal destroy; + } events; + + void *data; + ...; +}; + struct wlr_session_lock_manager_v1 *wlr_session_lock_manager_v1_create( struct wl_display *display); From a8a067fd553a7560256ab6bbc6d44b6a217c1491 Mon Sep 17 00:00:00 2001 From: Jeroen Wijenbergh Date: Mon, 6 May 2024 22:08:02 +0200 Subject: [PATCH 76/92] output: remove commit_state commit was already there taking a state... --- tiny/server.py | 2 +- wlroots/wlr_types/output.py | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/tiny/server.py b/tiny/server.py index efb0915d..b91df1ae 100644 --- a/tiny/server.py +++ b/tiny/server.py @@ -378,7 +378,7 @@ def output_frame(self, listener, data) -> None: def output_request_state(self, listener, request: OutputEventRequestState) -> None: output = self.outputs[0] - output.commit_state(request.state) + output.commit(request.state) # ############################################################# # input handling callbacks diff --git a/wlroots/wlr_types/output.py b/wlroots/wlr_types/output.py index 3f13f97e..5be41797 100644 --- a/wlroots/wlr_types/output.py +++ b/wlroots/wlr_types/output.py @@ -202,10 +202,6 @@ def rollback(self) -> None: """Discard the pending output state""" lib.wlr_output_rollback(self._ptr) - def commit_state(self, state: OutputState) -> bool: - """Commit requested state""" - return lib.wlr_output_commit_state(self._ptr, state._ptr) - def effective_resolution(self) -> tuple[int, int]: """Computes the transformed and scaled output resolution""" width_ptr = ffi.new("int *") From 25fabf8323b1390998f26efc4fab4095f373d689 Mon Sep 17 00:00:00 2001 From: Jeroen Wijenbergh Date: Mon, 6 May 2024 22:10:25 +0200 Subject: [PATCH 77/92] ci: set wlroots to 0.17.3 --- .github/workflows/ci.yml | 8 ++++---- .github/workflows/release.yml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5c40e2cb..8d34c3de 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: strategy: fail-fast: false matrix: - wlroots-version: ["0.17.0", master] + wlroots-version: ["0.17.3", master] steps: - name: Install dependencies run: | @@ -163,7 +163,7 @@ jobs: - "pypy-3.8" - "pypy-3.9" - "pypy-3.10" - wlroots-version: ["0.17.0"] + wlroots-version: ["0.17.3"] include: - python-version: "3.12" wlroots-version: master @@ -279,7 +279,7 @@ jobs: needs: build-wayland env: python-version: "3.12" - wlroots-version: "0.17.0" + wlroots-version: "0.17.3" steps: - name: Download wayland libraries uses: actions/download-artifact@v3 @@ -315,7 +315,7 @@ jobs: needs: build-wayland env: python-version: "3.12" - wlroots-version: "0.17.0" + wlroots-version: "0.17.3" steps: - name: Download wayland libraries uses: actions/download-artifact@v3 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cdf54672..6d098e49 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,7 +18,7 @@ jobs: inputproto-version: "2021.5" wayland-protocols-version: "1.32" wayland-version: "1.22.0" - wlroots-version: "0.17.0" + wlroots-version: "0.17.3" steps: - name: Install dependencies run: | From 3a96a3c30af3841e8f9de003c2acc5a54ed8e11e Mon Sep 17 00:00:00 2001 From: Jeroen Wijenbergh Date: Mon, 6 May 2024 22:30:10 +0200 Subject: [PATCH 78/92] xdg: Rename TopLevel to Toplevel fixes #192 --- wlroots/wlr_types/xdg_decoration_v1.py | 6 ++-- wlroots/wlr_types/xdg_shell.py | 44 +++++++++++++------------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/wlroots/wlr_types/xdg_decoration_v1.py b/wlroots/wlr_types/xdg_decoration_v1.py index adfdeae2..53b04b99 100644 --- a/wlroots/wlr_types/xdg_decoration_v1.py +++ b/wlroots/wlr_types/xdg_decoration_v1.py @@ -10,7 +10,7 @@ from wlroots import PtrHasData, ffi, lib -from .xdg_shell import XdgTopLevel +from .xdg_shell import XdgToplevel if TYPE_CHECKING: from pywayland.server import Display @@ -53,10 +53,10 @@ def __init__(self, ptr) -> None: ) @property - def toplevel(self) -> XdgTopLevel: + def toplevel(self) -> XdgToplevel: toplevel_ptr = self._ptr.toplevel _weakkeydict[toplevel_ptr] = self._ptr - return XdgTopLevel(toplevel_ptr) + return XdgToplevel(toplevel_ptr) @property def manager(self) -> XdgDecorationManagerV1: diff --git a/wlroots/wlr_types/xdg_shell.py b/wlroots/wlr_types/xdg_shell.py index 6e3ab671..67e25756 100644 --- a/wlroots/wlr_types/xdg_shell.py +++ b/wlroots/wlr_types/xdg_shell.py @@ -35,7 +35,7 @@ class XdgSurfaceRole(enum.IntEnum): POPUP = lib.WLR_XDG_SURFACE_ROLE_POPUP -class XdgTopLevelWMCapabilities(enum.IntFlag): +class XdgToplevelWMCapabilities(enum.IntFlag): WINDOW_MENU = lib.WLR_XDG_TOPLEVEL_WM_CAPABILITIES_WINDOW_MENU MAXIMIZE = lib.WLR_XDG_TOPLEVEL_WM_CAPABILITIES_MAXIMIZE FULLSCREEN = lib.WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN @@ -104,7 +104,7 @@ def role(self) -> XdgSurfaceRole: return XdgSurfaceRole(self._ptr.role) @property - def toplevel(self) -> XdgTopLevel: + def toplevel(self) -> XdgToplevel: """Return the top level xdg object This shell must be a top level role @@ -112,7 +112,7 @@ def toplevel(self) -> XdgTopLevel: if self.role != XdgSurfaceRole.TOPLEVEL: raise ValueError(f"xdg surface must be top-level, got: {self.role}") - toplevel = XdgTopLevel(self._ptr.toplevel) + toplevel = XdgToplevel(self._ptr.toplevel) # the toplevel does not own the ptr data, ensure the underlying cdata # is kept alive @@ -170,7 +170,7 @@ def set_tiled(self, tiled_edges: int) -> int: def set_bounds(self, width: int, height: int) -> int: return lib.wlr_xdg_toplevel_set_bounds(self._ptr.toplevel, width, height) - def set_wm_capabilities(self, caps: XdgTopLevelWMCapabilities) -> int: + def set_wm_capabilities(self, caps: XdgToplevelWMCapabilities) -> int: return lib.wlr_xdg_toplevel_set_wm_capabilities(self._ptr.toplevel, caps) def send_close(self) -> int: @@ -236,7 +236,7 @@ def serial(self) -> int: return self._ptr.serial -class XdgTopLevel(Ptr): +class XdgToplevel(Ptr): def __init__(self, ptr) -> None: """A top level surface object @@ -256,27 +256,27 @@ def __init__(self, ptr) -> None: ) self.request_move_event = Signal( ptr=ffi.addressof(self._ptr.events.request_move), - data_wrapper=XdgTopLevelMoveEvent, + data_wrapper=XdgToplevelMoveEvent, ) self.request_resize_event = Signal( ptr=ffi.addressof(self._ptr.events.request_resize), - data_wrapper=XdgTopLevelResizeEvent, + data_wrapper=XdgToplevelResizeEvent, ) self.request_show_window_menu_event = Signal( ptr=ffi.addressof(self._ptr.events.request_show_window_menu), - data_wrapper=XdgTopLevelShowWindowMenuEvent, + data_wrapper=XdgToplevelShowWindowMenuEvent, ) self.set_parent_event = Signal(ptr=ffi.addressof(self._ptr.events.set_parent)) self.set_title_event = Signal(ptr=ffi.addressof(self._ptr.events.set_title)) self.set_app_id_event = Signal(ptr=ffi.addressof(self._ptr.events.set_app_id)) @property - def parent(self) -> XdgTopLevel | None: + def parent(self) -> XdgToplevel | None: """The parent of this toplevel""" parent_ptr = self._ptr.parent if parent_ptr == ffi.NULL: return None - return XdgTopLevel(parent_ptr) + return XdgToplevel(parent_ptr) @property def title(self) -> str | None: @@ -289,19 +289,19 @@ def app_id(self) -> str | None: return str_or_none(self._ptr.app_id) @property - def requested(self) -> XdgTopLevelRequested: + def requested(self) -> XdgToplevelRequested: """Requested initial state""" - return XdgTopLevelRequested(self._ptr.requested) + return XdgToplevelRequested(self._ptr.requested) -class XdgTopLevelMoveEvent(Ptr): +class XdgToplevelMoveEvent(Ptr): def __init__(self, ptr) -> None: self._ptr = ffi.cast("struct wlr_xdg_toplevel_move_event *", ptr) @property - def toplevel(self) -> XdgTopLevel: + def toplevel(self) -> XdgToplevel: # TODO: keep weakref - return XdgTopLevel(self._ptr.toplevel) + return XdgToplevel(self._ptr.toplevel) # TODO: seat client @@ -310,14 +310,14 @@ def serial(self) -> int: return self._ptr.serial -class XdgTopLevelResizeEvent(Ptr): +class XdgToplevelResizeEvent(Ptr): def __init__(self, ptr) -> None: self._ptr = ffi.cast("struct wlr_xdg_toplevel_resize_event *", ptr) @property - def toplevel(self) -> XdgTopLevel: + def toplevel(self) -> XdgToplevel: # TODO: keep weakref - return XdgTopLevel(self._ptr.toplevel) + return XdgToplevel(self._ptr.toplevel) # TODO: seat client @@ -330,14 +330,14 @@ def edges(self) -> Edges: return self._ptr.edges -class XdgTopLevelShowWindowMenuEvent(Ptr): +class XdgToplevelShowWindowMenuEvent(Ptr): def __init__(self, ptr) -> None: self._ptr = ffi.cast("struct wlr_xdg_toplevel_show_window_menu_event *", ptr) @property - def toplevel(self) -> XdgTopLevel: + def toplevel(self) -> XdgToplevel: # TODO: keep weakref - return XdgTopLevel(self._ptr.toplevel) + return XdgToplevel(self._ptr.toplevel) # TODO: seat client @@ -420,7 +420,7 @@ def reactive(self) -> bool: return self._ptr.reactive -class XdgTopLevelRequested(Ptr): +class XdgToplevelRequested(Ptr): def __init__(self, ptr) -> None: self._ptr = ptr From e2d5413ad92b31b6c72de150621e6b76fd49f982 Mon Sep 17 00:00:00 2001 From: Jeroen Wijenbergh Date: Mon, 6 May 2024 22:33:36 +0200 Subject: [PATCH 79/92] Add initial changes for 0.17.0 --- CHANGES.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index 76cf61f1..4112a1f8 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,3 +1,9 @@ +0.17.0 +------ +* Support for wlroots 0.17.x +* rename all declarations of XdgTopLevel.* to XdgToplevel.* + + 0.16.8 -- 2024-05-04 -------------------- * Fixed: ``XdgTopLevel.parent`` always returnd a parent even if the parent is NULL. From 9f292089658656c607c73dd13d5e49a5464a918b Mon Sep 17 00:00:00 2001 From: Jeroen Wijenbergh Date: Fri, 10 May 2024 16:28:36 +0200 Subject: [PATCH 80/92] Tiny + Wlroots: Fix SceneOutputLayout API --- tiny/__main__.py | 4 +++- tiny/server.py | 10 ++++++++-- wlroots/ffi_build.py | 2 ++ wlroots/wlr_types/__init__.py | 1 + wlroots/wlr_types/scene.py | 20 +++++++++++++++++--- 5 files changed, 31 insertions(+), 6 deletions(-) diff --git a/tiny/__main__.py b/tiny/__main__.py index 704253e5..8f08497b 100644 --- a/tiny/__main__.py +++ b/tiny/__main__.py @@ -18,6 +18,7 @@ DataDeviceManager, OutputLayout, Scene, + SceneOutputLayout, Seat, XCursorManager, XdgShell, @@ -39,7 +40,7 @@ def main(argv) -> None: display, "seat0" ) as seat: scene = Scene() - scene.attach_output_layout(output_layout) + scene_layout = scene.attach_output_layout(output_layout) tinywl_server = TinywlServer( # noqa: F841 display=display, backend=backend, @@ -51,6 +52,7 @@ def main(argv) -> None: cursor_manager=xcursor_manager, seat=seat, output_layout=output_layout, + scene_layout=scene_layout, ) socket = display.add_socket() diff --git a/tiny/server.py b/tiny/server.py index b91df1ae..ffe39139 100644 --- a/tiny/server.py +++ b/tiny/server.py @@ -27,6 +27,7 @@ SceneBuffer, SceneNodeType, SceneOutput, + SceneOutputLayout, SceneSurface, SceneTree, Seat, @@ -83,6 +84,7 @@ def __init__( cursor_manager: XCursorManager, seat: Seat, output_layout: OutputLayout, + scene_layout: SceneOutputLayout, ) -> None: # elements that we need to hold on to self._display = display @@ -118,6 +120,7 @@ def __init__( self.resize_edges: Edges = Edges.NONE self._output_layout = output_layout + self._scene_layout = scene_layout self.outputs: list[Output] = [] xdg_shell.new_surface_event.add(Listener(self.server_new_xdg_surface)) @@ -349,7 +352,6 @@ def server_new_xdg_surface(self, listener, xdg_surface: XdgSurface) -> None: # output and frame handling callbacks def server_new_output(self, listener, output: Output) -> None: - SceneOutput.create(self._scene, output) output.init_render(self._allocator, self._renderer) state = OutputState() @@ -361,13 +363,17 @@ def server_new_output(self, listener, output: Output) -> None: state.finish() self.outputs.append(output) - if not self._output_layout.add_auto(output): + l_output = self._output_layout.add_auto(output) + if not l_output: logging.warning("Failed to add output to layout.") return output.frame_event.add(Listener(self.output_frame)) output.request_state_event.add(Listener(self.output_request_state)) + scene_output = SceneOutput.create(self._scene, output) + self._scene_layout.add_output(l_output, scene_output) + def output_frame(self, listener, data) -> None: output = self.outputs[0] scene_output = self._scene.get_scene_output(output) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 2ab5703f..08795e46 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -1893,6 +1893,8 @@ def has_xwayland() -> bool: struct wlr_scene_output_layout *wlr_scene_attach_output_layout(struct wlr_scene *scene, struct wlr_output_layout *output_layout); +void wlr_scene_output_layout_add_output(struct wlr_scene_output_layout *sol, struct wlr_output_layout_output *lo, struct wlr_scene_output *so); + struct wlr_scene_tree *wlr_scene_subsurface_tree_create( struct wlr_scene_tree *parent, struct wlr_surface *surface); diff --git a/wlroots/wlr_types/__init__.py b/wlroots/wlr_types/__init__.py index 726e9765..ab214ed0 100644 --- a/wlroots/wlr_types/__init__.py +++ b/wlroots/wlr_types/__init__.py @@ -42,6 +42,7 @@ SceneNode, SceneNodeType, SceneOutput, + SceneOutputLayout, SceneSurface, SceneTree, ) diff --git a/wlroots/wlr_types/scene.py b/wlroots/wlr_types/scene.py index ee5f880b..5a5da120 100644 --- a/wlroots/wlr_types/scene.py +++ b/wlroots/wlr_types/scene.py @@ -38,12 +38,12 @@ def tree(self) -> SceneTree: def attach_output_layout( self, output_layout: OutputLayout - ) -> OutputLayoutOutput | None: - """Get a scene-graph output from a wlr_output.""" + ) -> SceneOutputLayout | None: + """Attach an output layout to a scene.""" ptr = lib.wlr_scene_attach_output_layout(self._ptr, output_layout._ptr) if ptr == ffi.NULL: return None - return OutputLayoutOutput(ptr) + return SceneOutputLayout(ptr) def set_presentation(self, presentation: Presentation) -> None: """ @@ -353,6 +353,20 @@ def configure(self, full_area: Box, usable_area: Box) -> None: ) +class SceneOutputLayout(Ptr): + def __init__(self, ptr) -> None: + """A `struct wlr_scene_output_layout_scene`""" + self._ptr = ptr + + def add_output( + self, output_layout_output: OutputLayoutOutput, scene_output: SceneOutput + ) -> None: + """Add an output to the scene output layout.""" + lib.wlr_scene_output_layout_add_output( + self._ptr, output_layout_output._ptr, scene_output._ptr + ) + + class SceneOutputStateOptions(Ptr): def __init__(self, ptr) -> None: """A `struct wlr_scene_output_state_options`.""" From 1a21d9e41313c49794d9014d1433c418b71c2c96 Mon Sep 17 00:00:00 2001 From: Jeroen Wijenbergh Date: Fri, 10 May 2024 16:30:35 +0200 Subject: [PATCH 81/92] Wlroots: Make some functions static instead of classmethod --- wlroots/wlr_types/layer_shell_v1.py | 4 ++-- wlroots/wlr_types/xdg_shell.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/wlroots/wlr_types/layer_shell_v1.py b/wlroots/wlr_types/layer_shell_v1.py index f696102f..f3f19074 100644 --- a/wlroots/wlr_types/layer_shell_v1.py +++ b/wlroots/wlr_types/layer_shell_v1.py @@ -160,8 +160,8 @@ def configure(self, width: int, height: int) -> None: def destroy(self) -> None: lib.wlr_layer_surface_v1_destroy(self._ptr) - @classmethod - def try_from_wlr_surface(cls, surface: Surface) -> LayerSurfaceV1 | None: + @staticmethod + def try_from_wlr_surface(surface: Surface) -> LayerSurfaceV1 | None: maybe_ptr = lib.wlr_layer_surface_v1_try_from_wlr_surface(surface._ptr) if maybe_ptr == ffi.NULL: return None diff --git a/wlroots/wlr_types/xdg_shell.py b/wlroots/wlr_types/xdg_shell.py index 67e25756..c334ffdc 100644 --- a/wlroots/wlr_types/xdg_shell.py +++ b/wlroots/wlr_types/xdg_shell.py @@ -85,8 +85,8 @@ def __init__(self, ptr) -> None: data_wrapper=XdgSurfaceConfigure, ) - @classmethod - def try_from_surface(cls, surface: Surface) -> XdgSurface | None: + @staticmethod + def try_from_surface(surface: Surface) -> XdgSurface | None: """Get the xdg surface associated with the given surface""" maybe_ptr = lib.wlr_xdg_surface_try_from_wlr_surface(surface._ptr) if maybe_ptr == ffi.NULL: From 011c3ad6d967d59fa43be14e8846bc23e3356171 Mon Sep 17 00:00:00 2001 From: Jeroen Wijenbergh Date: Fri, 10 May 2024 16:39:30 +0200 Subject: [PATCH 82/92] Tiny + Wlroots: Use seat.set_keyboard again --- tiny/server.py | 6 +++--- wlroots/wlr_types/seat.py | 18 +----------------- 2 files changed, 4 insertions(+), 20 deletions(-) diff --git a/tiny/server.py b/tiny/server.py index ffe39139..895a6d22 100644 --- a/tiny/server.py +++ b/tiny/server.py @@ -234,7 +234,7 @@ def send_modifiers( self, modifiers: KeyboardModifiers, input_device: InputDevice ) -> None: keyboard = Keyboard.from_input_device(input_device) - self._seat.keyboard = keyboard + self._seat.set_keyboard(keyboard) self._seat.keyboard_notify_modifiers(modifiers) def send_key(self, key_event: KeyboardKeyEvent, input_device: InputDevice) -> None: @@ -260,7 +260,7 @@ def send_key(self, key_event: KeyboardKeyEvent, input_device: InputDevice) -> No # Otherwise, we pass it along to the client if not handled: - self._seat.keyboard = keyboard + self._seat.set_keyboard(keyboard) self._seat.keyboard_notify_key(key_event) def handle_keybinding(self, keysym: int) -> bool: @@ -419,7 +419,7 @@ def _server_new_keyboard(self, input_device: InputDevice) -> None: keyboard_handler = KeyboardHandler(keyboard, input_device, self) self.keyboards.append(keyboard_handler) - self._seat.keyboard = keyboard + self._seat.set_keyboard(keyboard) # ############################################################# # cursor motion callbacks diff --git a/wlroots/wlr_types/seat.py b/wlroots/wlr_types/seat.py index 50331cb7..09d0ef71 100644 --- a/wlroots/wlr_types/seat.py +++ b/wlroots/wlr_types/seat.py @@ -123,8 +123,7 @@ def keyboard(self) -> Keyboard | None: """Get the active keyboard for the seat.""" return instance_or_none(Keyboard, lib.wlr_seat_get_keyboard(self._ptr)) - @keyboard.setter - def keyboard(self, keyboard: Keyboard | None) -> None: + def set_keyboard(self, keyboard: Keyboard | None) -> None: """Set this keyboard as the active keyboard for the seat""" lib.wlr_seat_set_keyboard(self._ptr, ptr_or_null(keyboard)) @@ -233,21 +232,6 @@ def pointer_has_grab(self) -> bool: """Whether or not the pointer has a grab other than the default grab""" return lib.wlr_seat_pointer_has_grab(self._ptr) - def set_keyboard(self, keyboard: Keyboard | None) -> None: - """Set this keyboard as the active keyboard for the seat - - Deprecated: Use the keyboard property. - - :param keyboard: - The keyboard to set as active. - """ - warnings.warn( - "Use the keyboard property of the seat, this method will be removed in the future.", - DeprecationWarning, - stacklevel=1, - ) - self.keyboard = keyboard - def grab(self) -> KeyboardGrab: """Start a grab of the keyboard of this seat""" return KeyboardGrab(self) From 94f91ac022e07c0f9765699b964d125924e36957 Mon Sep 17 00:00:00 2001 From: Jeroen Wijenbergh Date: Fri, 10 May 2024 16:45:00 +0200 Subject: [PATCH 83/92] Tiny + Wlroots: Fix diff between Output and OutputState setters OutputState used property setters, whereas Output uses set_. In this codebase, it seems like there is a preference for explicit set_ functions as there is little use of these setters --- tiny/server.py | 4 ++-- wlroots/wlr_types/output.py | 28 ++++++++++------------------ 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/tiny/server.py b/tiny/server.py index 895a6d22..27271ec1 100644 --- a/tiny/server.py +++ b/tiny/server.py @@ -355,9 +355,9 @@ def server_new_output(self, listener, output: Output) -> None: output.init_render(self._allocator, self._renderer) state = OutputState() - state.enabled = True + state.set_enabled(True) if mode := output.preferred_mode(): - state.mode = mode + state.set_mode(mode) output.commit(state) state.finish() diff --git a/wlroots/wlr_types/output.py b/wlroots/wlr_types/output.py index 5be41797..ea65cfd1 100644 --- a/wlroots/wlr_types/output.py +++ b/wlroots/wlr_types/output.py @@ -140,13 +140,13 @@ def set_mode(self, mode: OutputMode | None) -> None: """ lib.wlr_output_set_mode(self._ptr, ptr_or_null(mode)) - def set_custom_mode(self, width: int, height: int, refresh: int) -> None: + def set_custom_mode(self, custom_mode: CustomMode) -> None: """ Sets a custom mode on the output. If modes are available, they are preferred. Setting `refresh` to zero lets the backend pick a preferred value. The output needs to be enabled. """ - lib.wlr_output_set_custom_mode(self._ptr, width, height, refresh) + lib.wlr_output_set_custom_mode(self._ptr, custom_mode.width, custom_mode.height, custom_mode.refresh) def create_global(self) -> None: """Create the global corresponding to the output""" @@ -350,48 +350,42 @@ def __init__(self, ptr: ffi.CData | None = None) -> None: def enabled(self) -> bool: return self._ptr.enabled - @enabled.setter - def enabled(self, enabled: bool) -> None: + def set_enabled(self, enabled: bool) -> None: lib.wlr_output_state_set_enabled(self._ptr, enabled) @property def scale(self) -> float: return self._ptr.scale - @scale.setter - def scale(self, scale: float) -> None: + def set_scale(self, scale: float) -> None: lib.wlr_output_state_set_scale(self._ptr, scale) @property def transform(self) -> WlOutput.transform: return WlOutput.transform(self._ptr.transform) - @transform.setter - def transform(self, transform: WlOutput.transform) -> None: + def set_transform(self, transform: WlOutput.transform) -> None: lib.wlr_output_state_set_transform(self._ptr, transform) @property def adaptive_sync_enabled(self) -> bool: return self._ptr.adaptive_sync_enabled - @adaptive_sync_enabled.setter - def adaptive_sync_enabled(self, enabled: bool) -> None: + def set_adaptive_sync_enabled(self, enabled: bool) -> None: lib.wlr_output_state_set_adaptive_sync_enabled(self._ptr, enabled) @property def render_format(self) -> int: return self._ptr.render_format - @render_format.setter - def render_format(self, format: int) -> None: + def set_render_format(self, format: int) -> None: lib.wlr_output_state_set_render_format(self._ptr, format) @property def subpixel(self) -> WlOutput.subpixel: return WlOutput.subpixel(self._ptr.subpixel) - @subpixel.setter - def subpixel(self, subpixel: WlOutput.subpixel) -> None: + def set_subpixel(self, subpixel: WlOutput.subpixel) -> None: lib.wlr_output_state_set_subpixel(self._ptr, subpixel) @property @@ -399,8 +393,7 @@ def mode(self) -> OutputMode | None: mode_ptr = self._ptr.mode return OutputMode(mode_ptr) if mode_ptr != ffi.NULL else None - @mode.setter - def mode(self, mode: OutputMode | None) -> None: + def set_mode(self, mode: OutputMode | None) -> None: lib.wlr_output_state_set_mode(self._ptr, ptr_or_null(mode)) @property @@ -408,8 +401,7 @@ def custom_mode(self) -> CustomMode: mode = self._ptr.custom_mode return CustomMode(width=mode.width, height=mode.height, refresh=mode.refresh) - @custom_mode.setter - def custom_mode(self, mode: CustomMode) -> None: + def set_custom_mode(self, mode: CustomMode) -> None: lib.wlr_output_state_set_custom_mode( self._ptr, mode.width, mode.height, mode.refresh ) From 975b30f20e16314148edd5d460554eb0d64bdedc Mon Sep 17 00:00:00 2001 From: Jeroen Wijenbergh Date: Fri, 10 May 2024 16:52:58 +0200 Subject: [PATCH 84/92] Format + Lint fixes --- tiny/__main__.py | 1 - tiny/server.py | 5 +++-- wlroots/wlr_types/output.py | 4 +++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/tiny/__main__.py b/tiny/__main__.py index 8f08497b..b6504900 100644 --- a/tiny/__main__.py +++ b/tiny/__main__.py @@ -18,7 +18,6 @@ DataDeviceManager, OutputLayout, Scene, - SceneOutputLayout, Seat, XCursorManager, XdgShell, diff --git a/tiny/server.py b/tiny/server.py index 27271ec1..8628a9be 100644 --- a/tiny/server.py +++ b/tiny/server.py @@ -84,7 +84,7 @@ def __init__( cursor_manager: XCursorManager, seat: Seat, output_layout: OutputLayout, - scene_layout: SceneOutputLayout, + scene_layout: Optional[SceneOutputLayout], ) -> None: # elements that we need to hold on to self._display = display @@ -372,7 +372,8 @@ def server_new_output(self, listener, output: Output) -> None: output.request_state_event.add(Listener(self.output_request_state)) scene_output = SceneOutput.create(self._scene, output) - self._scene_layout.add_output(l_output, scene_output) + if self._scene_layout: + self._scene_layout.add_output(l_output, scene_output) def output_frame(self, listener, data) -> None: output = self.outputs[0] diff --git a/wlroots/wlr_types/output.py b/wlroots/wlr_types/output.py index ea65cfd1..cc4f8480 100644 --- a/wlroots/wlr_types/output.py +++ b/wlroots/wlr_types/output.py @@ -146,7 +146,9 @@ def set_custom_mode(self, custom_mode: CustomMode) -> None: Setting `refresh` to zero lets the backend pick a preferred value. The output needs to be enabled. """ - lib.wlr_output_set_custom_mode(self._ptr, custom_mode.width, custom_mode.height, custom_mode.refresh) + lib.wlr_output_set_custom_mode( + self._ptr, custom_mode.width, custom_mode.height, custom_mode.refresh + ) def create_global(self) -> None: """Create the global corresponding to the output""" From 967f1b1b3d2f64fd1c11221ed037d5bab6fee7ec Mon Sep 17 00:00:00 2001 From: Lars Date: Fri, 10 May 2024 15:17:14 +0200 Subject: [PATCH 85/92] XdgToplevel: Added missing base property --- wlroots/wlr_types/xdg_shell.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/wlroots/wlr_types/xdg_shell.py b/wlroots/wlr_types/xdg_shell.py index c334ffdc..5cba883a 100644 --- a/wlroots/wlr_types/xdg_shell.py +++ b/wlroots/wlr_types/xdg_shell.py @@ -110,7 +110,7 @@ def toplevel(self) -> XdgToplevel: This shell must be a top level role """ if self.role != XdgSurfaceRole.TOPLEVEL: - raise ValueError(f"xdg surface must be top-level, got: {self.role}") + raise ValueError(f"xdg surface must be top-level, got: {self.role.name}") toplevel = XdgToplevel(self._ptr.toplevel) @@ -151,7 +151,7 @@ def set_size(self, width: int, height: int) -> int: def set_activated(self, activated: bool) -> int: if self.role != XdgSurfaceRole.TOPLEVEL: - raise ValueError(f"xdg surface must be top-level, got: {self.role}") + raise ValueError(f"xdg surface must be top-level, got: {self.role.name}") return lib.wlr_xdg_toplevel_set_activated(self._ptr.toplevel, activated) @@ -270,6 +270,11 @@ def __init__(self, ptr) -> None: self.set_title_event = Signal(ptr=ffi.addressof(self._ptr.events.set_title)) self.set_app_id_event = Signal(ptr=ffi.addressof(self._ptr.events.set_app_id)) + @property + def base(self) -> XdgSurface: + """The XDG surface associated with this toplevel""" + return XdgSurface(self._ptr.base) + @property def parent(self) -> XdgToplevel | None: """The parent of this toplevel""" From f1369f2bff6e6ebc8aabe334384a27fa70b5a206 Mon Sep 17 00:00:00 2001 From: Jeroen Wijenbergh Date: Fri, 10 May 2024 16:56:30 +0200 Subject: [PATCH 86/92] Tiny: Use | None for Optional typing --- tiny/server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tiny/server.py b/tiny/server.py index 8628a9be..7df5c6aa 100644 --- a/tiny/server.py +++ b/tiny/server.py @@ -84,7 +84,7 @@ def __init__( cursor_manager: XCursorManager, seat: Seat, output_layout: OutputLayout, - scene_layout: Optional[SceneOutputLayout], + scene_layout: SceneOutputLayout | None, ) -> None: # elements that we need to hold on to self._display = display From b1b7b67241e450466d06e09d14f901434364c4b5 Mon Sep 17 00:00:00 2001 From: Jeroen Wijenbergh Date: Fri, 10 May 2024 17:00:23 +0200 Subject: [PATCH 87/92] Seat: Remove warnings import --- wlroots/wlr_types/seat.py | 1 - 1 file changed, 1 deletion(-) diff --git a/wlroots/wlr_types/seat.py b/wlroots/wlr_types/seat.py index 09d0ef71..dc916005 100644 --- a/wlroots/wlr_types/seat.py +++ b/wlroots/wlr_types/seat.py @@ -2,7 +2,6 @@ from __future__ import annotations -import warnings from typing import Iterator from weakref import WeakKeyDictionary From 00198c3baea5003b07f9698a44d274ca6646e2a1 Mon Sep 17 00:00:00 2001 From: Jeroen Wijenbergh Date: Fri, 10 May 2024 19:45:06 +0200 Subject: [PATCH 88/92] wlroots: Support themes for xcursor manager --- tiny/__main__.py | 2 +- wlroots/wlr_types/xcursor_manager.py | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/tiny/__main__.py b/tiny/__main__.py index b6504900..a998b9b4 100644 --- a/tiny/__main__.py +++ b/tiny/__main__.py @@ -35,7 +35,7 @@ def main(argv) -> None: xdg_shell = XdgShell(display) with OutputLayout() as output_layout, Cursor( output_layout - ) as cursor, XCursorManager(24) as xcursor_manager, Seat( + ) as cursor, XCursorManager(None, 24) as xcursor_manager, Seat( display, "seat0" ) as seat: scene = Scene() diff --git a/wlroots/wlr_types/xcursor_manager.py b/wlroots/wlr_types/xcursor_manager.py index 7e43fb40..98663a87 100644 --- a/wlroots/wlr_types/xcursor_manager.py +++ b/wlroots/wlr_types/xcursor_manager.py @@ -11,12 +11,15 @@ class XCursorManager(Ptr): - def __init__(self, size, scale=1): - """Creates a new XCursor manager + def __init__(self, theme: str | None, size: int = 24, scale: float = 1.0): + """Creates a new XCursor manager using the theme and size - Create cursor with base size and scale. + and ensures an xcursor with scale is loaded """ - ptr = lib.wlr_xcursor_manager_create(ffi.NULL, size) + theme_ptr = ffi.NULL + if theme is not None: + theme_ptr = theme.encode() + ptr = lib.wlr_xcursor_manager_create(theme_ptr, size) self._ptr = ffi.gc(ptr, lib.wlr_xcursor_manager_destroy) lib.wlr_xcursor_manager_load(self._ptr, scale) From 5cc1a94bf88c2c78c7d899f0f93be32f703eeb8e Mon Sep 17 00:00:00 2001 From: Jeroen Wijenbergh Date: Sun, 12 May 2024 12:29:51 +0200 Subject: [PATCH 89/92] Wlroots: Rename *_VERSION, mark as Final and change err --- wlroots/wlr_types/compositor.py | 8 ++++---- wlroots/wlr_types/layer_shell_v1.py | 10 ++++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/wlroots/wlr_types/compositor.py b/wlroots/wlr_types/compositor.py index 8f3232d9..acfdd524 100644 --- a/wlroots/wlr_types/compositor.py +++ b/wlroots/wlr_types/compositor.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Final from weakref import WeakKeyDictionary from pywayland.protocol.wayland import WlOutput @@ -19,7 +19,7 @@ from wlroots.renderer import Renderer -COMPOSITOR_VERSION = 5 +_MAX_COMPOSITOR_VERSION: Final = 5 class Compositor(Ptr): @@ -35,9 +35,9 @@ def __init__( :param renderer: The wlroots renderer to attach the compositor to. """ - if not version <= COMPOSITOR_VERSION: + if not 0 < version <= _MAX_COMPOSITOR_VERSION: raise ValueError( - f"Compositor version must be less than or equal to {COMPOSITOR_VERSION}" + f"Invalid compositor version, should be a value between 1 (inclusive) and {_MAX_COMPOSITOR_VERSION} (inclusive), got: {version}" ) if renderer is None: self._ptr = lib.wlr_compositor_create(display._ptr, version, ffi.NULL) diff --git a/wlroots/wlr_types/layer_shell_v1.py b/wlroots/wlr_types/layer_shell_v1.py index f3f19074..ec8c75af 100644 --- a/wlroots/wlr_types/layer_shell_v1.py +++ b/wlroots/wlr_types/layer_shell_v1.py @@ -3,7 +3,7 @@ import enum from dataclasses import dataclass -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Final from weakref import WeakKeyDictionary from pywayland.server import Signal @@ -197,14 +197,16 @@ def surface_at(self, sx: float, sy: float) -> tuple[Surface | None, float, float return Surface(surface_ptr), sub_x_data[0], sub_y_data[0] -LAYER_SHELL_VERSION = 4 +_MAX_LAYER_SHELL_VERSION: Final = 4 class LayerShellV1(PtrHasData): def __init__(self, display: Display, version: int) -> None: """Create an wlr_xdg_output_manager_v1""" - if not 0 < version <= LAYER_SHELL_VERSION: - raise ValueError("Invalid layer shell version.") + if not 0 < version <= _MAX_LAYER_SHELL_VERSION: + raise ValueError( + f"Invalid layer shell version, should be a value between 1 (inclusive) and {_MAX_LAYER_SHELL_VERSION} (inclusive), got: {version}" + ) self._ptr = lib.wlr_layer_shell_v1_create(display._ptr, version) From 575a8168286d4f4f08b2013d8ceab49c151a10e0 Mon Sep 17 00:00:00 2001 From: Jeroen Wijenbergh Date: Sun, 12 May 2024 12:37:43 +0200 Subject: [PATCH 90/92] Wlroots + Tiny: Convert keyboard property to get_keyboard --- tiny/server.py | 2 +- wlroots/wlr_types/seat.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/tiny/server.py b/tiny/server.py index 7df5c6aa..4025da5c 100644 --- a/tiny/server.py +++ b/tiny/server.py @@ -312,7 +312,7 @@ def focus_view(self, view: View, surface: Surface | None = None) -> None: # Tell the seat to have the keyboard enter this surface. wlroots will # keep track of this and automatically send key events to the # appropriate clients without additional work on your part. - keyboard = self._seat.keyboard + keyboard = self._seat.get_keyboard() if keyboard: self._seat.keyboard_notify_enter(view.xdg_surface.surface, keyboard) diff --git a/wlroots/wlr_types/seat.py b/wlroots/wlr_types/seat.py index dc916005..8c7ecaaf 100644 --- a/wlroots/wlr_types/seat.py +++ b/wlroots/wlr_types/seat.py @@ -117,8 +117,7 @@ def keyboard_state(self) -> SeatKeyboardState: _weakkeydict[keyboard_state_ptr] = self._ptr return SeatKeyboardState(keyboard_state_ptr) - @property - def keyboard(self) -> Keyboard | None: + def get_keyboard(self) -> Keyboard | None: """Get the active keyboard for the seat.""" return instance_or_none(Keyboard, lib.wlr_seat_get_keyboard(self._ptr)) From 2b4919bf938e481b8db283d935a028e5ed55138d Mon Sep 17 00:00:00 2001 From: Jeroen Wijenbergh Date: Sun, 12 May 2024 14:14:59 +0200 Subject: [PATCH 91/92] Wlroots Scene: Add wlr_scene_subsurface_tree_set_clip --- wlroots/ffi_build.py | 3 +++ wlroots/wlr_types/scene.py | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/wlroots/ffi_build.py b/wlroots/ffi_build.py index 08795e46..8a0a0747 100644 --- a/wlroots/ffi_build.py +++ b/wlroots/ffi_build.py @@ -1898,6 +1898,9 @@ def has_xwayland() -> bool: struct wlr_scene_tree *wlr_scene_subsurface_tree_create( struct wlr_scene_tree *parent, struct wlr_surface *surface); +void wlr_scene_subsurface_tree_set_clip(struct wlr_scene_node *node, + struct wlr_box *clip); + struct wlr_scene_tree *wlr_scene_xdg_surface_create( struct wlr_scene_tree *parent, struct wlr_xdg_surface *xdg_surface); diff --git a/wlroots/wlr_types/scene.py b/wlroots/wlr_types/scene.py index 5a5da120..9e73a524 100644 --- a/wlroots/wlr_types/scene.py +++ b/wlroots/wlr_types/scene.py @@ -288,6 +288,17 @@ def for_each_buffer( self._ptr, lib.buffer_iterator_callback, handle ) + def subsurface_tree_set_clip(self, clip: Box | None): + """ + Sets a cropping region for any subsurface trees that are children of this scene node. + + A None value will disable clipping + """ + clip_ptr = ffi.NULL + if clip is not None: + clip_ptr = clip._ptr + lib.wlr_scene_subsurface_tree_set_clip(self._ptr, clip_ptr) + class SceneSurface(Ptr): def __init__(self, ptr) -> None: From 13a4fb3c9aa6f6c6f0d2f6fe496fa2bfbeb3d656 Mon Sep 17 00:00:00 2001 From: Jeroen Wijenbergh Date: Sun, 12 May 2024 15:26:50 +0200 Subject: [PATCH 92/92] Wlroots SceneTree: Add a children iterator --- wlroots/wlr_types/scene.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/wlroots/wlr_types/scene.py b/wlroots/wlr_types/scene.py index 9e73a524..3972e700 100644 --- a/wlroots/wlr_types/scene.py +++ b/wlroots/wlr_types/scene.py @@ -5,11 +5,15 @@ import enum from typing import TYPE_CHECKING, Callable, TypeVar +from pywayland.utils import wl_list_for_each + from wlroots import Ptr, PtrHasData, ffi, lib from wlroots.util.region import PixmanRegion32 from wlroots.wlr_types import OutputLayoutOutput, Surface if TYPE_CHECKING: + from typing import Iterator + from wlroots.util.box import Box from wlroots.util.clock import Timespec from wlroots.wlr_types import Buffer, Output, OutputLayout @@ -145,6 +149,16 @@ def subsurface_tree_create(cls, parent: SceneTree, surface: Surface) -> SceneTre def drag_icon_create(cls, parent: SceneTree, drag_icon: DragIcon) -> SceneTree: return SceneTree(lib.wlr_scene_drag_icon_create(parent._ptr, drag_icon._ptr)) + @property + def children(self) -> Iterator[SceneNode]: + for ptr in wl_list_for_each( + "struct wlr_scene_node *", + self._ptr.children, + "link", + ffi=ffi, + ): + yield SceneNode(ptr) + class SceneBuffer(Ptr): def __init__(self, ptr) -> None: