From d2e11be430faf86223f0bf38888f79cc72dfab70 Mon Sep 17 00:00:00 2001 From: Markus Fritsche Date: Sun, 3 May 2026 11:14:46 +0000 Subject: [PATCH] Phase 0: browser X11-overlay inventory + mpv reference cell + tooling installs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Source-level verdict: no browser in the matrix has a code path to hand NV12 to the X server for plane scanout. Chromium ozone-x11 wires StubOverlayManager (ozone_platform_x11.cc:262); Brave 147 + chromium-fourier 149 inherit unchanged. Firefox WindowSurfaceX11 is RGB-only. The campaign's load-bearing hypothesis is structurally weakened — what the X11 cells will measure for browsers is KWin's per-frame RGB-recomposite cost, not the original "force-GL-composite of NV12" framing. mpv --vo=xv becomes the matrix's only direct test of the operator-supplied mechanism. Matrix updated: 12 cells -> 16 cells (+8 mpv VO sub-points). revert.log entries 1-5 capture all package + per-user state mutations from this turn (measurement tools, openbox, XFCE + xfwm4-no-comp pre-seed, firefox + AUR xtrace, XFCE rotation + touchscreen mapping); single SSH-driveable revert chain returns ohm to its pre-campaign 1169-package state. Co-Authored-By: Claude Opus 4.7 (1M context) --- README.md | 10 +- .../browser_overlay_inventory_2026-05-03.md | 507 ++++ .../chromium_ozone_x11_2026-05-03/README.txt | 70 + .../ui/ozone/common/stub_overlay_manager.cc | 24 + .../ui/ozone/common/stub_overlay_manager.h | 30 + .../ui/ozone/platform/x11/BUILD.gn | 204 ++ .../ui/ozone/platform/x11/DEPS | 16 + .../ozone/platform/x11/ozone_platform_x11.cc | 375 +++ .../ozone/platform/x11/ozone_platform_x11.h | 17 + .../ozone/platform/x11/x11_surface_factory.cc | 267 ++ .../ozone/platform/x11/x11_surface_factory.h | 65 + .../ui/ozone/platform/x11/x11_window.cc | 2624 +++++++++++++++++ .../ui/ozone/platform/x11/x11_window.h | 521 ++++ .../ozone/platform/x11/x11_window_manager.cc | 101 + .../ozone/platform/x11/x11_window_manager.h | 61 + .../ui/ozone/public/overlay_manager_ozone.h | 46 + .../entry2.added.list | 70 + .../pacman.entry2.log | 227 ++ .../pacman.entry3a.firefox.log | 30 + .../pacman.entry3b.xtrace.log | 20 + .../pacman.install.log | 47 + .../pkglist.entry2.post.txt | 1250 ++++++++ .../pkglist.entry2.pre.txt | 1180 ++++++++ .../pkglist.entry3.post.txt | 1253 ++++++++ .../pkglist.entry3.pre.txt | 1250 ++++++++ .../x11_inventory_2026-05-03/pkglist.post.txt | 1180 ++++++++ .../x11_inventory_2026-05-03/pkglist.pre.txt | 1169 ++++++++ .../x11_inventory_2026-05-03/revert.log | 483 +++ phase0_findings.md | 67 +- worklist.md | 47 +- 30 files changed, 13176 insertions(+), 35 deletions(-) create mode 100644 phase0_evidence/browser_overlay_inventory_2026-05-03.md create mode 100644 phase0_evidence/chromium_ozone_x11_2026-05-03/README.txt create mode 100644 phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/common/stub_overlay_manager.cc create mode 100644 phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/common/stub_overlay_manager.h create mode 100644 phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/BUILD.gn create mode 100644 phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/DEPS create mode 100644 phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/ozone_platform_x11.cc create mode 100644 phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/ozone_platform_x11.h create mode 100644 phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/x11_surface_factory.cc create mode 100644 phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/x11_surface_factory.h create mode 100644 phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/x11_window.cc create mode 100644 phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/x11_window.h create mode 100644 phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/x11_window_manager.cc create mode 100644 phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/x11_window_manager.h create mode 100644 phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/public/overlay_manager_ozone.h create mode 100644 phase0_evidence/x11_inventory_2026-05-03/entry2.added.list create mode 100644 phase0_evidence/x11_inventory_2026-05-03/pacman.entry2.log create mode 100644 phase0_evidence/x11_inventory_2026-05-03/pacman.entry3a.firefox.log create mode 100644 phase0_evidence/x11_inventory_2026-05-03/pacman.entry3b.xtrace.log create mode 100644 phase0_evidence/x11_inventory_2026-05-03/pacman.install.log create mode 100644 phase0_evidence/x11_inventory_2026-05-03/pkglist.entry2.post.txt create mode 100644 phase0_evidence/x11_inventory_2026-05-03/pkglist.entry2.pre.txt create mode 100644 phase0_evidence/x11_inventory_2026-05-03/pkglist.entry3.post.txt create mode 100644 phase0_evidence/x11_inventory_2026-05-03/pkglist.entry3.pre.txt create mode 100644 phase0_evidence/x11_inventory_2026-05-03/pkglist.post.txt create mode 100644 phase0_evidence/x11_inventory_2026-05-03/pkglist.pre.txt create mode 100644 phase0_evidence/x11_inventory_2026-05-03/revert.log diff --git a/README.md b/README.md index d6b3c74..9eb22b3 100644 --- a/README.md +++ b/README.md @@ -24,9 +24,13 @@ forced GL-composite. **The campaign's load-bearing hypothesis is that this plane-allocation freedom translates into measurable browser-video speedup.** -The matrix is 3 browsers × 2 decode paths × 2 sessions = 12 -cells (some N/A where libva isn't supported). See -`phase0_findings.md` for the full table. +The matrix is (3 browsers + mpv 0.41 as a reference X11-overlay +client) × 2 decode paths × 2 sessions = 16 cells (some N/A +where libva isn't supported). The mpv cells are run twice each +— once with `--vo=xv` (legacy XVideo overlay) and once with +`--vo=gpu --gpu-context=x11` (modern DRI3 + XPresent + Mesa GL). +See `phase0_findings.md` § "Experimental matrix" for the full +table and the rationale for mpv as reference baseline. ## Campaign-contained data discipline diff --git a/phase0_evidence/browser_overlay_inventory_2026-05-03.md b/phase0_evidence/browser_overlay_inventory_2026-05-03.md new file mode 100644 index 0000000..c84cd48 --- /dev/null +++ b/phase0_evidence/browser_overlay_inventory_2026-05-03.md @@ -0,0 +1,507 @@ +# Phase 0 — Browser X11-overlay-path inventory + +**Date:** 2026-05-03 +**Scope:** answer worklist.md item *"Browser X11-overlay-path +inventory"* — for each of Brave 147, chromium-fourier 149, +Firefox 150, and the mpv 0.41 reference client, determine +**whether a code path exists under X11 to request +hardware-overlay scanout of NV12 video buffers**, vs always +GL-compositing internally to RGB before X11 presentation. + +**Method:** source-level inspection. Local Firefox 149 source +tree (acquired by the predecessor as `firefox-fourier-work/`) +read directly. Chromium 147 source acquired from the +`chromium-builder` LXD CT on boltzmann via the his subagent — +13 files, 180 KB, copied into +`phase0_evidence/chromium_ozone_x11_2026-05-03/` with full +provenance in that subtree's `README.txt`. mpv inspected via +upstream docs + its installed binary's `--vo=help`. **Runtime +engagement (does the path actually fire at playback time?) is +NOT covered here** — that's a separate, attended-launch +follow-up; design sketch at the end of this doc. + +## TL;DR + +| Client | X11 overlay path exists in code? | Runtime-engaged today? | Notes | +|---|---|---|---| +| Brave 147 | **No.** ozone-x11 uses `StubOverlayManager`. | N/A | upstream Chromium 147 + Brave UI patches; Ozone unchanged | +| chromium-fourier 149 | **No.** Same as upstream Chromium 149. | N/A | local patches target decode side only; Ozone unchanged | +| Firefox 150 | **No.** `WindowSurfaceX11{,Image,SHM}` are RGB-only. | N/A | gfx/webrender_bindings has DComp (Windows), no Linux equivalent | +| mpv 0.41 `--vo=xv` | **Yes (XVideo legacy path).** | unknown | only path in this matrix that *could* engage a hardware plane via X server's Xv adapter | +| mpv 0.41 `--vo=gpu --gpu-context=x11` | **No.** GL composite, identical plumbing to browsers. | N/A | DRI3 + XPresent of an RGB GL-composited framebuffer, same as Chromium/Firefox under X11 | + +**Headline finding:** every Blink-based browser (Brave, +chromium-fourier) and Firefox under stock X11 ozone *cannot* hand +an NV12 dmabuf to the X server for hardware-overlay scanout; +they always GL-composite NV12 → RGB in their own GPU process and +then present an RGB framebuffer to the X server. + +This **structurally weakens** the campaign's load-bearing +hypothesis (`README.md` § 1: *"the campaign's load-bearing +hypothesis is that this plane-allocation freedom translates into +measurable browser-video speedup"*). The freedom *exists* at the +DRM/Xorg layer — Plane 39 NV12 LINEAR is reachable to X11 +clients in principle — but **no shipping browser ever tries to +exercise it** under X11. What the matrix's X11 cells will +actually measure for browsers is the cost of the GL composite +running in the *browser's* GPU process vs the GL composite +running in *kwin_wayland*'s process — an interesting question, +but a different one from the stated mechanism. + +The mpv `--vo=xv` cell becomes the matrix's most important +single data point: it's the only client in the campaign that +can *attempt* to engage an X11 hardware-overlay plane directly. +A clean `--vo=xv` engagement establishes that the X11 +hardware-overlay path *works on this hardware*; absence +establishes it doesn't even exist on rockchip-drm + Panfrost + +modesetting Xorg. + +--- + +## Chromium ozone-x11: `StubOverlayManager` (decisive) + +Source provenance: +`phase0_evidence/chromium_ozone_x11_2026-05-03/` +(Chromium 147.0.7727.116 from `chromium-builder` LXD CT on +boltzmann; tarball mtime 2026-04-25). + +### The wiring + +`ui/ozone/platform/x11/ozone_platform_x11.cc:262`: + +```cpp +overlay_manager_ = std::make_unique(); +``` + +`StubOverlayManager` (in `ui/ozone/common/stub_overlay_manager.h`) +implements the `OverlayManagerOzone` interface as a no-op — +its `CreateOverlayCandidates()` returns no candidates. Whatever +chromium's `OverlayProcessor` asks the X11 backend, the answer +is "no overlay possible here" and the regular GL-composite path +runs. + +**Contrast with Wayland** +(`ui/ozone/platform/wayland/ozone_platform_wayland.cc:330`): + +```cpp +std::make_unique(buffer_manager_.get()); +``` + +A real `WaylandOverlayManager` backed by the +`WaylandBufferManagerHost`. This is the path the predecessor +campaign `kwin_overlay_subsurface` was investigating — the route +where Chromium emits `wp_subsurface` overlay candidates that +KWin Wayland may or may not promote to scanout planes (and +historically didn't, hence the predecessor's Phase 8 closure). + +### What the X11 directory does NOT contain + +Directory listing of `ui/ozone/platform/x11/` (from `README.txt`) +filtered for relevance: + +``` +$ ls ui/ozone/platform/x11/ | grep -iE 'overlay|buffer.*manager|dmabuf|present' +x11_window_manager.cc +x11_window_manager.h +``` + +`x11_window_manager` is the WM-events bookkeeping class +(focus/raise/restack), unrelated to overlays. **There is no +`x11_overlay_manager.cc`, no `x11_buffer_manager_host.cc`, no +`x11_dmabuf_*.cc`, and no `x11_present_*.cc`** — files that +exist on the Wayland side. The X11 backend has no machinery +to track overlay candidates, no buffer-manager IPC, no +dmabuf-feedback handling, and no Present-extension protocol +support. + +### What the X11 directory DOES contain — and why it's not enough + +`x11_surface_factory.cc:40-43`: + +```cpp +// Native pixmaps are first imported as X11 pixmaps using DRI3 +// and then into EGL. +``` + +DRI3 IS used by ozone-x11. But the path is: + +1. GPU process gets an NV12 dmabuf from the video decoder + (VAAPI / V4L2VideoDecoder). +2. `X11SurfaceFactory::CreateNativePixmap()` wraps it as a + `gfx::NativePixmapDmaBuf`. +3. The dmabuf is imported either directly via + `EGL_EXT_image_dma_buf_import` or, as a fallback, by + creating an X11 Pixmap via DRI3 and binding that as an + EGL image. +4. **Either way, the resulting EGL image is sampled by + Chromium's GL compositor** to render the WebRender output. +5. The browser's final RGB framebuffer is presented to the X + server via `glXSwapBuffers` (or equivalent EGL swap). + +This is the GL-composite path — the same path browsers use on +every X11 + GL-context combo since the late 2000s. The dmabuf +is consumed by the GPU process, not handed to the X server for +plane scanout. Plane 39 (the only NV12-LINEAR-capable plane on +rockchip-drm) is programmed by the X server at scanout time +with the **RGB** browser framebuffer, not the NV12 video buffer. + +### What `chrome://gpu` would show for video acceleration + +Independent of decode-side acceleration, the +*Hardware-accelerated video decode* line in `chrome://gpu` only +reports decoder status, not overlay status. `chrome://gpu` +doesn't have a "Hardware video overlay" line for Linux/X11 — +that line is Windows-only (`DCOMPSurface` on the DirectComposition +swap chain). The absence of such a line in chrome://gpu under +Linux/X11 is itself a sign: there's no overlay surface concept +in this backend. + +### Brave 147 verdict + +Brave is a Chromium fork. Its tree adds ~50 patches on top of +upstream Chromium covering UI/Shields/Wallet/IPFS/Tor/etc. None +of Brave's diff touches `ui/ozone/platform/x11/`, the +`OverlayProcessor`, or the GPU buffer pipeline. **Brave 147 +under X11 has the identical "StubOverlayManager → GL composite" +behavior as upstream Chromium 147.** + +### chromium-fourier 149 verdict + +`marfrit-packages/arch/chromium-fourier/STUDY.md` documents the +patch set: + +- Patch 1: bypass `media/gpu/chromeos/video_decoder_pipeline.cc` + on Linux non-ChromeOS so VaapiVideoDecoder gets used. +- Patch 2: V4L2VideoDecoder factory un-gating for non-ChromeOS. +- Patch 3 (cosmetic): default `LIBVA_DRIVER_NAME=v4l2_request`. +- `nv12-external-oes-on-modifier-external-only.patch`: EGL + import quirk for NV12 modifier-external dmabufs. +- `wayland-allow-direct-egl-gles2.patch`: Wayland-specific. + +**All decode-side. Zero changes to `ui/ozone/platform/x11/`, +zero changes to the OverlayProcessor.** chromium-fourier 149's +X11 behavior is identical to upstream Chromium 149's, which is +in turn identical in Ozone shape to 147 (the +`StubOverlayManager` wiring dates to ~2019 and hasn't moved). + +--- + +## Firefox 150 widget/gtk: RGB-only X11 surfaces (decisive) + +Source: `firefox-fourier-work/firefox-149.0/`. Firefox 149 ≈ 150 +on the X11-surface code path; this layer hasn't changed +materially in 5+ years. + +### The X11 surface implementations + +Firefox's X11 backend lives at `widget/gtk/WindowSurfaceX11*`: + +- `WindowSurfaceX11.cpp` — abstract base. +- `WindowSurfaceX11Image.cpp` — XImage-based (slow legacy path). +- `WindowSurfaceX11SHM.cpp` — XShm-based (shared-memory pixmap). + +`WindowSurfaceX11.cpp::GetVisualFormat()` enumerates exactly +three pixel formats: + +```cpp +case 32: return gfx::SurfaceFormat::B8G8R8A8; +case 24: return gfx::SurfaceFormat::B8G8R8X8; +case 16: return gfx::SurfaceFormat::R5G6B5_UINT16; +``` + +All RGB. No NV12. No YUV. No dmabuf. Final pixel buffer is RGB +before reaching X. + +A grep across all +`widget/gtk/WindowSurfaceX11*.{cpp,h}` files for any of +`dmabuf|DMABuf|NV12|YUV|hardware.*overlay|Plane|XPresent|DRI3` +returns **zero matches**. Firefox's X11 presentation path is +strictly software-RGB-pixmap → X. + +### Why the dmabuf code in widget/gtk/ doesn't apply + +Files like `DMABufSurface.cpp`, `DMABufBuffer.cpp`, +`WaylandSurface.cpp` exist and are reachable on Linux, but +their use is: + +- Wayland-side: produce/consume `wl_buffer` dmabufs for the + client→compositor handoff via `zwp_linux_dmabuf_v1`. +- VAAPI-decode-side: import a hardware-decoded NV12 dmabuf as + an EGL image so Firefox's WebRender can sample it as a + texture. + +In the second case (VAAPI under X11), the dmabuf is consumed by +Firefox's own GPU process for compositing. The composited +output is then handed to `WindowSurfaceX11SHM` as RGB — +identical situation to Chromium. + +### Mozilla's `gfx.x11-egl.force-enabled` pref + +`modules/libpref/init/StaticPrefList.yaml`: + +```yaml +- name: gfx.x11-egl.force-enabled + type: bool + value: false + mirror: once + # Whether to force using EGL over GLX. +``` + +This forces Firefox to use **EGL over GLX** for its GL context +under X11 (better dmabuf import support since EGL has +`EGL_EXT_image_dma_buf_import`, GLX doesn't). It changes the +GPU-process composite-input plumbing, **not** the +WindowSurfaceX11 presentation plumbing. The output to X is +still RGB. + +### Mozilla's hardware-overlay code is Windows-only + +The only files in Firefox 149 source matching +`hardware.*overlay`: + +- `gfx/webrender_bindings/DCLayerTree.cpp` — + DirectComposition layer tree (Windows). +- `gfx/webrender_bindings/RenderCompositorANGLE.cpp` — + ANGLE composition (Windows). +- `gfx/config/gfxFeature.h` — feature-flag enum. +- `gfx/thebes/gfxPlatform.cpp` — feature-flag plumbing. + +There is no Linux/X11 hardware-overlay equivalent. Mozilla's +`MOZ_X11_EGL` env var (sometimes mentioned in forum threads as +a "force X11 hardware overlay" toggle) is just a synonym for +`gfx.x11-egl.force-enabled` — same EGL-vs-GLX scope, no +overlay-scanout effect. + +### Firefox 150 verdict + +**No X11 hardware-overlay path. Firefox under X11 always +GL-composites NV12 → RGB internally and presents RGB to the X +server.** Same architectural shape as Chromium ozone-x11. + +--- + +## mpv 0.41: the only client with a path that *could* engage X11 hardware overlay + +mpv installed: `mpv 1:0.41.0-3` with `libplacebo v7.360.1` +(per `02_x11_paths.txt`). + +### `--vo=xv` — the legacy XVideo overlay path + +XVideo (`Xv`) is an X protocol extension dating to the late +1990s, designed precisely for hardware video overlays: the +client hands the X server a YUV image; the X server programs a +hardware video plane (where available) to scanout that image, +hardware-blended with the rest of the desktop. On modesetting +Xorg driver + a DRM driver that exposes a YUV-capable plane, +the X server's XVideo adapter wires through DRI2/DRI3 to the +DRM plane allocator, and YUV image goes onto a hardware plane. + +`xdpyinfo` on ohm confirms XVideo extension is initialized on +the running X server (`03_xprotocol_extensions.txt:50`, +`Xorg.0.log` line 96-97 in `01_live_session.txt`). + +**Whether modesetting + rockchip-drm actually wires XVideo to +Plane 39 is the empirical question.** Possible outcomes: + +- mpv `--vo=xv` programs Plane 39 NV12 → X11 hardware-overlay + path is reachable on this hardware, and the campaign has its + reference baseline. +- mpv `--vo=xv` falls back to software YUV→RGB conversion in + the X server (the modesetting "shadow Xv adapter" path) → + no hardware-overlay path on this hardware, regardless of + client. + +A 5-second mpv `--vo=xv` run under a non-compositing WM, with +`drm_info` snapshots taken before / during / after, will +unambiguously answer this. *Design at the end of this doc.* + +### `--vo=gpu --gpu-context=x11` — modern Mesa GL path + +mpv's modern GL VO uses the same plumbing as the browsers: +DRI3 + XPresent + Mesa GL. `--hwdec=auto` or +`--hwdec=v4l2request-copy` decodes via libva → NV12 dmabuf → +imports as EGL image → mpv samples it in libplacebo's GL +compositor → glXSwapBuffers RGB to X. + +This is **not** an X11 hardware-overlay path. It's the same +client-side GL composite that browsers do. Useful as a +control: if `--vo=gpu` is markedly slower than `--vo=xv` on +the same machine + same workload, the delta is the +hardware-overlay-vs-GL-composite gap — which is exactly the +quantity the campaign wants to measure. + +### `--vo=drm` — bypass X entirely (NOT in scope) + +mpv has a `--vo=drm` VO that talks directly to KMS, bypassing +X. The KWIN_PIVOT.md from chromium-fourier already reports +0.7 % drops with mpv `--vo=drm --hwdec=v4l2request` under no +compositor — strong evidence the underlying hardware path +(decode + DRM scanout) is healthy on this stack. But `--vo=drm` +isn't an X11 path; it doesn't tell us anything about whether +the X server can do the same plane assignment for a windowed +client. **Not added to the matrix.** Useful as a "this is the +hardware ceiling" reference outside the matrix. + +--- + +## Implications for the matrix + +### What the X11 cells of the matrix actually measure for the three browsers + +Given the StubOverlayManager / WindowSurfaceX11-RGB-only +findings, the X11-cell value chain for browsers is: + +1. Browser GPU process decodes video → NV12 dmabuf. +2. NV12 dmabuf imported as EGL image. +3. **Browser GPU process GL-composites NV12 → RGB** in its own + GL context (via libplacebo equivalents in Chromium's WebRender + or Firefox's WebRender). +4. RGB framebuffer presented via DRI3 + XPresent to the X + server. +5. **X server's plane allocator schedules the RGB pixmap on + Plane 39** (since on rockchip-drm Plane 39 is the only one + that can scan out the browser-window-sized buffer; Plane 45 + doesn't accept RGB AFBC at the resolutions involved either, + though it does accept RGB LINEAR — to be confirmed). + +Compare to Wayland-with-KWin cell: + +1. Browser GPU process decodes → NV12 dmabuf. +2. NV12 dmabuf imported as EGL image (or sent via wp_subsurface + if the browser engages that route — in practice, per the + predecessor campaign, browsers don't engage wp_subsurface for + the test page). +3. **Browser GPU process GL-composites NV12 → RGB** in its own + GL context (same as X11 cell). +4. RGB framebuffer dispatched to KWin via wl_surface attach. +5. **KWin GL-composites the browser's RGB surface** with the + rest of the desktop (the wallpaper, panels, etc.). +6. KWin's merged RGB framebuffer goes to Plane 39. + +The structural delta the matrix's X11 vs Wayland cells will +actually measure for browsers is therefore **the cost of step +5 in the Wayland flow** — KWin's per-frame compositing of +already-RGB browser surfaces onto its merged framebuffer. The +NV12-GL-composite (step 3) happens in *both* sessions, in the +*browser's* GPU process. The campaign's hypothesised "force-GL- +composite of every NV12 video buffer" is performed by the +browser regardless of session, not by KWin. + +This **does not invalidate the campaign**. KWin's per-frame RGB +composite is still measurable and the predecessor's +`kwin_wayland %CPU at steady-state ~36 %` is suggestive that +this overhead is real. But the magnitude and the mechanism are +different from the original framing. + +### Where the original "plane allocation freedom" hypothesis still applies + +For the **mpv `--vo=xv`** cell — and ONLY that cell — the +client genuinely tries to hand NV12 to the X server for +scanout. Under without-KWin (X11 + non-compositing WM), the +X server is free to put that NV12 buffer on Plane 39 and +the desktop on Plane 45 — exactly the campaign's mechanism, +realised. Under Wayland-with-KWin there is no equivalent path +at all (XVideo isn't a Wayland concept; XWayland would route +through KWin and lose any scanout opportunity). So the mpv-xv +row of the matrix is the **direct test** of the +operator-supplied mechanism — and likely the only one that +can produce a positive answer. + +### Recommended Phase 1 framing + +The campaign's research question stays valid but its +sub-questions sharpen: + +- **Q1 (mpv `--vo=xv`):** does X11+non-compositing WM on + rockchip-drm-PineTab2 actually engage hardware-overlay + scanout for an NV12 client? (matrix cells `C-X-mpv-sw` and + `C-X-mpv-hw` with `--vo=xv`) +- **Q2 (browsers):** given that browsers always GL-composite + to RGB before presentation, does removing KWin from the + display path reduce the per-frame RGB-composite cost enough + to matter for video fps / drops? (the existing browser + cells, just with their interpretation tightened) +- **Q3 (mpv `--vo=gpu`):** is the GL-composite cost in mpv's + GPU process comparable to the browsers' GL-composite cost? + (i.e., is the browsers' overhead the GL-composite itself, or + something extra browsers do around it?) + +A clean Q1 positive (mpv-xv hits Plane 39) plus a marginal Q2 +(browsers don't speed up much without KWin) would be the +"X11 path is fast, but browsers leave it on the table" +verdict the campaign already named as a possible outcome +shape. + +A Q1 negative (mpv-xv falls back to RGB anyway) would mean +the campaign's mechanism is structurally absent on this +hardware, regardless of session. In that case the matrix +collapses to "what's the per-frame KWin overhead?" — a +scoping the predecessor `kwin_overlay_subsurface` already +asked at the protocol level and got an answer to. + +--- + +## Open: runtime engagement check (deferred, attended-launch) + +The source-level inventory above answers "does the path +*exist* in the code". To answer "is the path *engaged at +runtime* for THIS hardware × THIS Mesa × THIS X server", a +per-client probe is needed. This is the right thing to do at +**Phase 1 binding-cell-design time**, not at Phase 0 +inventory time. + +### Probe sketch (for later) + +For each client × X11-session combination, around a +short (10-30 s) test-video playback: + +1. Pre-state: `drm_info | grep -A 20 'Plane 39'` and + `drm_info | grep -A 20 'Plane 45'` — capture plane state + before launch. +2. Launch the client (operator action: open the browser to + `brave_drops_test.html` or run mpv on a known short video). +3. Capture for 10 s mid-playback: + - `x11trace -k -d :0 -o /tmp/x11trace..log` for + ~3 s (the AUR `x11trace` binary at `/usr/bin/x11trace` + installed in `revert.log` entry 3) — to see what X + protocol requests the client is issuing per frame. + - `drm_info` snapshot — to see which planes are now + programmed and with what FOURCC/modifier. + - `chrome://gpu` page text via DevTools / about:support + copy — for the browser's own self-report. +4. Post-state `drm_info`. +5. Diff: a positive engagement looks like **Plane 39 + programmed with `NV12` FOURCC during step 3**; a negative + engagement is **Plane 39 programmed with `XR24` / `AR24` + RGB FOURCC for the entire window**. + +The probe is shaped like a Phase 1 measurement protocol but +uses a much shorter window and isn't recording per-frame +metrics — it's just "does NV12 ever reach a hardware plane?" +binary outcome per cell. + +### Why deferred + +Running the probe productively requires: +- A non-compositing-WM session active (entry-1 openbox or + entry-2 XFCE-no-comp) — operator session switch needed. +- An operator at the keyboard to start each client. +- A short test video file on ohm at a known path — minor + prep, not done in this campaign yet. +- The matrix cells finalised with their browser flags + (`--enable-features=...`, `MOZ_X11_EGL=1`, etc.) so the + probe gives the right answer for the conditions Phase 1 + will measure. + +None of those is a blocker — but folding the probe into +Phase 1's first measurement rep (where the operator is +already at the keyboard launching browsers and a test video +is being played for fps-counting purposes) is more efficient +than running it standalone in Phase 0. + +--- + +## Worklist update + +`worklist.md` item *"NEW: Browser X11-overlay-path inventory"* +should flip to `[x]` with a pointer to this file. diff --git a/phase0_evidence/chromium_ozone_x11_2026-05-03/README.txt b/phase0_evidence/chromium_ozone_x11_2026-05-03/README.txt new file mode 100644 index 0000000..a6a4a57 --- /dev/null +++ b/phase0_evidence/chromium_ozone_x11_2026-05-03/README.txt @@ -0,0 +1,70 @@ +# Source provenance +Host: boltzmann +Container: chromium-builder (LXD) +Path inside CT: /build/chromium/src +Tarball mtime: 2026-04-25 (chromium-147.0.7727.116.tar.xz) +Fetched: 2026-05-03 +Reach recipe: ssh boltzmann "sudo lxc exec chromium-builder -- cat /build/chromium/src/" + +## Chromium VERSION + ui/ozone/platform/x11/ listing + +MAJOR=147 +MINOR=0 +BUILD=7727 +PATCH=116 +--- +total 384 +drwxr-xr-x 1 builder builder 2298 Apr 21 17:50 . +drwxr-xr-x 1 builder builder 78 Apr 21 17:50 .. +-rw-r--r-- 1 builder builder 5298 Apr 21 17:50 BUILD.gn +-rw-r--r-- 1 builder builder 360 Apr 21 17:50 DEPS +-rw-r--r-- 1 builder builder 89 Apr 21 17:50 OWNERS +-rw-r--r-- 1 builder builder 2841 Apr 21 17:50 atk_event_conversion.cc +-rw-r--r-- 1 builder builder 1033 Apr 21 17:50 atk_event_conversion.h +-rw-r--r-- 1 builder builder 440 Apr 21 17:50 client_native_pixmap_factory_x11.cc +-rw-r--r-- 1 builder builder 556 Apr 21 17:50 client_native_pixmap_factory_x11.h +-rw-r--r-- 1 builder builder 1255 Apr 21 17:50 gl_egl_utility_x11.cc +-rw-r--r-- 1 builder builder 1133 Apr 21 17:50 gl_egl_utility_x11.h +-rw-r--r-- 1 builder builder 2469 Apr 21 17:50 gl_surface_egl_readback_x11.cc +-rw-r--r-- 1 builder builder 1280 Apr 21 17:50 gl_surface_egl_readback_x11.h +-rw-r--r-- 1 builder builder 1218 Apr 21 17:50 hit_test_x11.cc +-rw-r--r-- 1 builder builder 508 Apr 21 17:50 hit_test_x11.h +-rw-r--r-- 1 builder builder 1198 Apr 21 17:50 linux_ui_delegate_x11.cc +-rw-r--r-- 1 builder builder 894 Apr 21 17:50 linux_ui_delegate_x11.h +-rw-r--r-- 1 builder builder 8235 Apr 21 17:50 native_pixmap_egl_x11_binding.cc +-rw-r--r-- 1 builder builder 1553 Apr 21 17:50 native_pixmap_egl_x11_binding.h +-rw-r--r-- 1 builder builder 1703 Apr 21 17:50 os_exchange_data_provider_x11.cc +-rw-r--r-- 1 builder builder 1726 Apr 21 17:50 os_exchange_data_provider_x11.h +-rw-r--r-- 1 builder builder 13470 Apr 21 17:50 ozone_platform_x11.cc +-rw-r--r-- 1 builder builder 458 Apr 21 17:50 ozone_platform_x11.h +drwxr-xr-x 1 builder builder 366 Apr 21 17:50 test +-rw-r--r-- 1 builder builder 5791 Apr 21 17:50 vulkan_implementation_x11.cc +-rw-r--r-- 1 builder builder 2126 Apr 21 17:50 vulkan_implementation_x11.h +-rw-r--r-- 1 builder builder 4729 Apr 21 17:50 vulkan_surface_x11.cc +-rw-r--r-- 1 builder builder 2797 Apr 21 17:50 vulkan_surface_x11.h +-rw-r--r-- 1 builder builder 1686 Apr 21 17:50 x11_canvas_surface.cc +-rw-r--r-- 1 builder builder 1962 Apr 21 17:50 x11_canvas_surface.h +-rw-r--r-- 1 builder builder 3845 Apr 21 17:50 x11_clipboard_ozone.cc +-rw-r--r-- 1 builder builder 2158 Apr 21 17:50 x11_clipboard_ozone.h +-rw-r--r-- 1 builder builder 1885 Apr 21 17:50 x11_global_shortcut_listener_ozone.cc +-rw-r--r-- 1 builder builder 1736 Apr 21 17:50 x11_global_shortcut_listener_ozone.h +-rw-r--r-- 1 builder builder 4440 Apr 21 17:50 x11_keyboard_hook.cc +-rw-r--r-- 1 builder builder 1600 Apr 21 17:50 x11_keyboard_hook.h +-rw-r--r-- 1 builder builder 440 Apr 21 17:50 x11_menu_utils.cc +-rw-r--r-- 1 builder builder 636 Apr 21 17:50 x11_menu_utils.h +-rw-r--r-- 1 builder builder 2846 Apr 21 17:50 x11_ozone_ui_controls_test_helper.cc +-rw-r--r-- 1 builder builder 2127 Apr 21 17:50 x11_ozone_ui_controls_test_helper.h +-rw-r--r-- 1 builder builder 9385 Apr 21 17:50 x11_screen_ozone.cc +-rw-r--r-- 1 builder builder 3750 Apr 21 17:50 x11_screen_ozone.h +-rw-r--r-- 1 builder builder 18003 Apr 21 17:50 x11_screen_ozone_unittest.cc +-rw-r--r-- 1 builder builder 8966 Apr 21 17:50 x11_surface_factory.cc +-rw-r--r-- 1 builder builder 2267 Apr 21 17:50 x11_surface_factory.h +-rw-r--r-- 1 builder builder 1191 Apr 21 17:50 x11_user_input_monitor.cc +-rw-r--r-- 1 builder builder 1279 Apr 21 17:50 x11_user_input_monitor.h +-rw-r--r-- 1 builder builder 876 Apr 21 17:50 x11_utils.cc +-rw-r--r-- 1 builder builder 754 Apr 21 17:50 x11_utils.h +-rw-r--r-- 1 builder builder 92805 Apr 21 17:50 x11_window.cc +-rw-r--r-- 1 builder builder 19102 Apr 21 17:50 x11_window.h +-rw-r--r-- 1 builder builder 3105 Apr 21 17:50 x11_window_manager.cc +-rw-r--r-- 1 builder builder 1813 Apr 21 17:50 x11_window_manager.h +-rw-r--r-- 1 builder builder 11141 Apr 21 17:50 x11_window_ozone_unittest.cc diff --git a/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/common/stub_overlay_manager.cc b/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/common/stub_overlay_manager.cc new file mode 100644 index 0000000..17c9552 --- /dev/null +++ b/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/common/stub_overlay_manager.cc @@ -0,0 +1,24 @@ +// Copyright 2015 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/ozone/common/stub_overlay_manager.h" + +#include + +#include "ui/ozone/public/overlay_candidates_ozone.h" + +namespace ui { + +StubOverlayManager::StubOverlayManager() { +} + +StubOverlayManager::~StubOverlayManager() { +} + +std::unique_ptr +StubOverlayManager::CreateOverlayCandidates(gfx::AcceleratedWidget w) { + return nullptr; +} + +} // namespace ui diff --git a/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/common/stub_overlay_manager.h b/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/common/stub_overlay_manager.h new file mode 100644 index 0000000..8fe2ef7 --- /dev/null +++ b/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/common/stub_overlay_manager.h @@ -0,0 +1,30 @@ +// Copyright 2015 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_OZONE_COMMON_STUB_OVERLAY_MANAGER_H_ +#define UI_OZONE_COMMON_STUB_OVERLAY_MANAGER_H_ + +#include + +#include "ui/ozone/public/overlay_manager_ozone.h" + +namespace ui { + +class StubOverlayManager : public OverlayManagerOzone { + public: + StubOverlayManager(); + + StubOverlayManager(const StubOverlayManager&) = delete; + StubOverlayManager& operator=(const StubOverlayManager&) = delete; + + ~StubOverlayManager() override; + + // OverlayManagerOzone: + std::unique_ptr CreateOverlayCandidates( + gfx::AcceleratedWidget w) override; +}; + +} // namespace ui + +#endif // UI_OZONE_COMMON_STUB_OVERLAY_MANAGER_H_ diff --git a/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/BUILD.gn b/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/BUILD.gn new file mode 100644 index 0000000..75a94f4 --- /dev/null +++ b/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/BUILD.gn @@ -0,0 +1,204 @@ +# Copyright 2016 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/config/chromeos/ui_mode.gni") +import("//gpu/vulkan/features.gni") +import("//ui/base/ui_features.gni") + +visibility = [ "//ui/ozone/*" ] + +assert(is_linux || is_chromeos) + +source_set("x11") { + sources = [ + "client_native_pixmap_factory_x11.cc", + "client_native_pixmap_factory_x11.h", + "gl_egl_utility_x11.cc", + "gl_egl_utility_x11.h", + "gl_surface_egl_readback_x11.cc", + "gl_surface_egl_readback_x11.h", + "hit_test_x11.cc", + "hit_test_x11.h", + "native_pixmap_egl_x11_binding.cc", + "native_pixmap_egl_x11_binding.h", + "os_exchange_data_provider_x11.cc", + "os_exchange_data_provider_x11.h", + "ozone_platform_x11.cc", + "ozone_platform_x11.h", + "x11_canvas_surface.cc", + "x11_canvas_surface.h", + "x11_clipboard_ozone.cc", + "x11_clipboard_ozone.h", + "x11_global_shortcut_listener_ozone.cc", + "x11_global_shortcut_listener_ozone.h", + "x11_keyboard_hook.cc", + "x11_keyboard_hook.h", + "x11_menu_utils.cc", + "x11_menu_utils.h", + "x11_screen_ozone.cc", + "x11_screen_ozone.h", + "x11_surface_factory.cc", + "x11_surface_factory.h", + "x11_user_input_monitor.cc", + "x11_user_input_monitor.h", + "x11_utils.cc", + "x11_utils.h", + "x11_window.cc", + "x11_window.h", + "x11_window_manager.cc", + "x11_window_manager.h", + ] + + deps = [ + "//base", + "//build:chromecast_buildflags", + "//components/viz/common/resources:shared_image_format", + "//gpu/vulkan:buildflags", + "//net", + "//skia", + "//third_party/angle:includes", + "//ui/base", + "//ui/base:buildflags", + "//ui/base:data_exchange", + "//ui/base:hit_test", + "//ui/base:wm_role_names", + "//ui/base/clipboard:clipboard_types", + "//ui/base/cursor", + "//ui/base/data_transfer_policy", + "//ui/base/dragdrop:types", + "//ui/base/dragdrop/mojom", + "//ui/base/ime", + "//ui/base/x", + "//ui/base/x:gl", + "//ui/display/types", + "//ui/events", + "//ui/events:dom_keycode_converter", + "//ui/events/devices", + "//ui/events/devices/x11", + "//ui/events/ozone", + "//ui/events/ozone/layout", + "//ui/events/platform", + "//ui/events/platform/x11", + "//ui/events/x", + "//ui/gfx", + "//ui/gfx/geometry", + "//ui/gfx/linux:gbm", + "//ui/gfx/linux:gbm_support_x11", + "//ui/gfx/x", + "//ui/gl", + "//ui/ozone:ozone_base", + "//ui/ozone/common", + "//ui/platform_window", + "//ui/platform_window/common", + "//ui/platform_window/wm", + ] + + if (is_linux) { + sources += [ + "linux_ui_delegate_x11.cc", + "linux_ui_delegate_x11.h", + ] + deps += [ + "//components/dbus", + "//ui/base/clipboard:clipboard_util_linux", + "//ui/linux:linux_ui", + ] + } + + if (is_chromeos) { + deps += [ "//ui/base/ime/ash" ] + } else { + deps += [ "//ui/base/ime/linux" ] + } + + if (enable_vulkan) { + sources += [ + "vulkan_implementation_x11.cc", + "vulkan_implementation_x11.h", + "vulkan_surface_x11.cc", + "vulkan_surface_x11.h", + ] + deps += [ "//gpu/vulkan" ] + } + + if (use_xkbcommon) { + configs += [ "//ui/events/ozone/layout:xkbcommon" ] + } + + if (use_atk) { + sources += [ + "atk_event_conversion.cc", + "atk_event_conversion.h", + ] + configs += [ "//build/config/linux/atk" ] + deps += [ "//ui/events/x" ] + } +} + +source_set("x11_unittests") { + testonly = true + sources = [ + "test/device_data_manager_x11_unittest.cc", + "test/events_x_unittest.cc", + "test/x11_event_translation_unittest.cc", + "test/x11_window_unittest.cc", + "x11_screen_ozone_unittest.cc", + "x11_window_ozone_unittest.cc", + ] + + deps = [ + ":x11", + "//base", + "//base/test:test_support", + "//skia", + "//testing/gmock", + "//testing/gtest", + "//ui/base", + "//ui/base:features", + "//ui/base/dragdrop:types", + "//ui/base/x", + "//ui/base/x:test_support", + "//ui/base/x:unittests", + "//ui/display:test_support", + "//ui/events:test_support", + "//ui/events/devices/x11", + "//ui/events/platform/x11", + "//ui/events/x", + "//ui/gfx:test_support", + "//ui/gfx/x", + "//ui/gfx/x:unit_test", + "//ui/ozone:platform", + "//ui/ozone:test_support", + "//ui/ozone/common", + ] + + if (!is_chromeos) { + sources += [ "test/os_exchange_data_provider_x11_unittest.cc" ] + deps += [ "//ui/base/clipboard:clipboard_types" ] + + # ChromeOS uses a non-backed exchange data provider while the tests actually + # expect to use a normal X11 provider. Running these tests with a non-backed + # provided results in crashes when ownership selection call is made. + # Moreover, X11 on ChromeOS is used only for dev purposes and it doesn't + # support DnD between X11 windows. Instead, all the dnd operations are + # performed within a single native windows, where ash spawns number of own + # internal windows. + sources += [ "test/x11_drag_drop_client_unittest.cc" ] + } +} + +source_set("test_support") { + testonly = true + + sources = [ + "x11_ozone_ui_controls_test_helper.cc", + "x11_ozone_ui_controls_test_helper.h", + ] + + deps = [ + "//ui/aura", + "//ui/base/x", + "//ui/base/x:test_support", + ] +} diff --git a/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/DEPS b/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/DEPS new file mode 100644 index 0000000..837e11f --- /dev/null +++ b/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/DEPS @@ -0,0 +1,16 @@ +include_rules = [ + "+components/dbus", + "+components/viz/common/resources/shared_image_format.h", + "+components/viz/common/resources/shared_image_format_utils.h", + "+dbus/bus.h", + "+net/base/network_interfaces.h", + "+ui/base/x", + "+ui/base", + "+ui/linux", +] + +specific_include_rules = { + "x11_ozone_ui_controls_test_helper.cc": [ + "+ui/aura", + ] +} diff --git a/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/ozone_platform_x11.cc b/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/ozone_platform_x11.cc new file mode 100644 index 0000000..71924ab --- /dev/null +++ b/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/ozone_platform_x11.cc @@ -0,0 +1,375 @@ +// Copyright 2016 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/ozone/platform/x11/ozone_platform_x11.h" + +#include +#include +#include + +#include "base/command_line.h" +#include "base/message_loop/message_pump_type.h" +#include "base/metrics/histogram_functions.h" +#include "base/no_destructor.h" +#include "base/strings/utf_string_conversions.h" +#include "base/task/single_thread_task_runner.h" +#include "base/task/thread_pool.h" +#include "build/build_config.h" +#include "ui/base/buildflags.h" +#include "ui/base/cursor/cursor_factory.h" +#include "ui/base/dragdrop/os_exchange_data_provider_factory_ozone.h" +#include "ui/base/x/x11_cursor_factory.h" +#include "ui/base/x/x11_util.h" +#include "ui/display/types/native_display_delegate.h" +#include "ui/events/devices/x11/touch_factory_x11.h" +#include "ui/events/ozone/layout/keyboard_layout_engine_manager.h" +#include "ui/events/ozone/layout/stub/stub_keyboard_layout_engine.h" +#include "ui/events/platform/x11/x11_event_source.h" +#include "ui/gfx/linux/gbm_support_x11.h" +#include "ui/gfx/native_ui_types.h" +#include "ui/gfx/switches.h" +#include "ui/gfx/x/atom_cache.h" +#include "ui/gfx/x/visual_manager.h" +#include "ui/linux/linux_ui_delegate.h" +#include "ui/ozone/common/stub_overlay_manager.h" +#include "ui/ozone/platform/x11/gl_egl_utility_x11.h" +#include "ui/ozone/platform/x11/linux_ui_delegate_x11.h" +#include "ui/ozone/platform/x11/x11_clipboard_ozone.h" +#include "ui/ozone/platform/x11/x11_global_shortcut_listener_ozone.h" +#include "ui/ozone/platform/x11/x11_keyboard_hook.h" +#include "ui/ozone/platform/x11/x11_menu_utils.h" +#include "ui/ozone/platform/x11/x11_screen_ozone.h" +#include "ui/ozone/platform/x11/x11_surface_factory.h" +#include "ui/ozone/platform/x11/x11_user_input_monitor.h" +#include "ui/ozone/platform/x11/x11_utils.h" +#include "ui/ozone/platform/x11/x11_window.h" +#include "ui/ozone/public/gpu_platform_support_host.h" +#include "ui/ozone/public/input_controller.h" +#include "ui/ozone/public/ozone_platform.h" +#include "ui/ozone/public/stub_input_controller.h" +#include "ui/ozone/public/system_input_injector.h" +#include "ui/platform_window/platform_window.h" +#include "ui/platform_window/platform_window_init_properties.h" + +#if BUILDFLAG(IS_CHROMEOS) +#include "ui/base/dragdrop/os_exchange_data_provider_non_backed.h" +#include "ui/base/ime/ash/input_method_ash.h" +#else +#include "ui/base/ime/linux/input_method_auralinux.h" +#include "ui/ozone/platform/x11/os_exchange_data_provider_x11.h" +#endif + +namespace ui { + +namespace { + +// Singleton OzonePlatform implementation for X11 platform. +class OzonePlatformX11 : public OzonePlatform, + public OSExchangeDataProviderFactoryOzone { + public: + OzonePlatformX11() { SetInstance(this); } + + OzonePlatformX11(const OzonePlatformX11&) = delete; + OzonePlatformX11& operator=(const OzonePlatformX11&) = delete; + + ~OzonePlatformX11() override = default; + + // OzonePlatform: + ui::SurfaceFactoryOzone* GetSurfaceFactoryOzone() override { + return surface_factory_ozone_.get(); + } + + ui::OverlayManagerOzone* GetOverlayManager() override { + return overlay_manager_.get(); + } + + CursorFactory* GetCursorFactory() override { return cursor_factory_.get(); } + + std::unique_ptr CreateSystemInputInjector() override { + return nullptr; + } + + InputController* GetInputController() override { + return input_controller_.get(); + } + + GpuPlatformSupportHost* GetGpuPlatformSupportHost() override { + return gpu_platform_support_host_.get(); + } + + std::unique_ptr CreatePlatformWindow( + PlatformWindowDelegate* delegate, + PlatformWindowInitProperties properties) override { + auto window = std::make_unique(delegate); + window->Initialize(std::move(properties)); + return std::move(window); + } + + std::unique_ptr CreateNativeDisplayDelegate() + override { + return nullptr; + } + + std::unique_ptr CreateScreen() override { + return std::make_unique(); + } + + void InitScreen(PlatformScreen* screen) override { + // InitScreen is always called with the same screen that CreateScreen + // hands back, so it is safe to cast here. + static_cast(screen)->Init(); + } + + PlatformClipboard* GetPlatformClipboard() override { + return clipboard_.get(); + } + + PlatformGLEGLUtility* GetPlatformGLEGLUtility() override { + if (!gl_egl_utility_) + gl_egl_utility_ = std::make_unique(); + return gl_egl_utility_.get(); + } + + std::unique_ptr CreateInputMethod( + ImeKeyEventDispatcher* ime_key_event_dispatcher, + gfx::AcceleratedWidget widget) override { +#if BUILDFLAG(IS_CHROMEOS) + return std::make_unique(ime_key_event_dispatcher); +#else + return std::make_unique(ime_key_event_dispatcher, + widget); +#endif + } + + PlatformMenuUtils* GetPlatformMenuUtils() override { + return menu_utils_.get(); + } + + PlatformUtils* GetPlatformUtils() override { return x11_utils_.get(); } + + PlatformGlobalShortcutListener* GetPlatformGlobalShortcutListener( + PlatformGlobalShortcutListenerDelegate* delegate) override { + if (!global_shortcut_listener_) { + global_shortcut_listener_ = + std::make_unique(delegate); + } + return global_shortcut_listener_.get(); + } + + std::unique_ptr CreateKeyboardHook( + PlatformKeyboardHookTypes type, + base::RepeatingCallback callback, + std::optional> dom_codes, + gfx::AcceleratedWidget accelerated_widget) override { + switch (type) { + case PlatformKeyboardHookTypes::kModifier: + return std::make_unique( + std::move(dom_codes), std::move(callback), accelerated_widget); + case PlatformKeyboardHookTypes::kMedia: + return nullptr; + } + } + + std::unique_ptr CreateProvider() override { +#if BUILDFLAG(IS_CHROMEOS) + return std::make_unique(); +#else + return std::make_unique(); +#endif + } + + const PlatformProperties& GetPlatformProperties() override { + using SupportsForTest = OzonePlatform::PlatformProperties::SupportsForTest; + const auto& override_set_parent_for_non_top_level_windows_for_test = + OzonePlatform::PlatformProperties:: + override_set_parent_for_non_top_level_windows_for_test; + + static base::NoDestructor properties; + static bool initialised = false; + if (!initialised) { + properties->custom_frame_pref_default = ui::GetCustomFramePrefDefault(); + + // When the Ozone X11 backend is running, use a UI loop to grab Expose + // events. See GLSurfaceGLX and https://crbug.com/326995. + properties->message_pump_type_for_gpu = base::MessagePumpType::UI; + // When the Ozone X11 backend is running, use a UI loop to dispatch + // SHM completion events. + properties->message_pump_type_for_viz_compositor = + base::MessagePumpType::UI; + properties->supports_vulkan_swap_chain = true; + properties->skia_can_fall_back_to_x11 = true; + properties->platform_shows_drag_image = false; + properties->app_modal_dialogs_use_event_blocker = true; + + // Defaults to false unless explicitly enabled for testing. + properties->set_parent_for_non_top_level_windows = + override_set_parent_for_non_top_level_windows_for_test == + SupportsForTest::kYes; + + initialised = true; + } + + return *properties; + } + + const PlatformRuntimeProperties& GetPlatformRuntimeProperties() override { + static OzonePlatform::PlatformRuntimeProperties properties; + + if (has_initialized_gpu() && + ui::GBMSupportX11::GetInstance()->has_gbm_device()) { + // This property is set when the GetPlatformRuntimeProperties is + // called on the gpu process side. + properties.supports_native_pixmaps = true; + } + properties.supports_subwindows_as_accelerated_widgets = false; + properties.supports_system_tray_windowing = true; + properties.supports_server_window_menus = + x11::Connection::Get()->WmSupportsHint( + x11::GetAtom("_GTK_SHOW_WINDOW_MENU")); + properties.supports_global_application_menus = true; + + return properties; + } + + bool IsNativePixmapConfigSupported(viz::SharedImageFormat format, + gfx::BufferUsage usage) const override { + return false; + } + + bool IsWindowCompositingSupported() const override { + return x11::Connection::Get() + ->GetOrCreateVisualManager() + .ArgbVisualAvailable(); + } + + bool InitializeUI(const InitParams& params) override { + if (ShouldFailInitializeUIForTest()) { + LOG(ERROR) << "Failing for test"; + return false; + } + // If opening the connection failed, we can not do anything. The platform + // cannot initialise. + if (!base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kHeadless) && + !x11::Connection::Get()->Ready()) { + LOG(ERROR) << "Missing X server or $DISPLAY"; + return false; + } + + InitializeCommon(params); + CreatePlatformEventSource(); + overlay_manager_ = std::make_unique(); + input_controller_ = std::make_unique(); + clipboard_ = std::make_unique(); + cursor_factory_ = std::make_unique(); + gpu_platform_support_host_.reset(CreateStubGpuPlatformSupportHost()); + + // TODO(crbug.com/41472924): Support XKB. + keyboard_layout_engine_ = std::make_unique(); + KeyboardLayoutEngineManager::SetKeyboardLayoutEngine( + keyboard_layout_engine_.get()); + + TouchFactory::SetTouchDeviceListFromCommandLine(); + +#if BUILDFLAG(USE_GTK) + linux_ui_delegate_ = std::make_unique(); +#endif + + menu_utils_ = std::make_unique(); + x11_utils_ = std::make_unique(); + + base::UmaHistogramEnumeration("Linux.WindowManager", GetWindowManagerUMA()); + + base::UmaHistogramBoolean( + "Linux.X11.XInput2", + x11::Connection::Get()->xinput_version().first == 2); + + return true; + } + + void InitializeGPU(const InitParams& params) override { + InitializeCommon(params); + if (params.enable_native_gpu_memory_buffers) { + base::ThreadPool::PostTask(FROM_HERE, base::BindOnce([]() { + ui::GBMSupportX11::GetInstance(); + })); + } + // In single process mode either the UI thread will create an event source + // or it's a test and an event source isn't desired. + if (!params.single_process) + CreatePlatformEventSource(); + + // Set up the X11 connection before the sandbox gets set up. This cannot be + // done later since opening the connection requires socket() and connect(). + auto connection = x11::Connection::Get()->Clone(); + connection->DetachFromSequence(); + surface_factory_ozone_ = + std::make_unique(std::move(connection)); + } + + void PostCreateMainMessageLoop( + base::OnceCallback shutdown_cb, + scoped_refptr) override { + // Installs the X11 error handlers for the UI process after the + // main message loop has started. This will allow us to exit cleanly + // if X exits before we do. + x11::Connection::Get()->SetIOErrorHandler(std::move(shutdown_cb)); + } + + std::unique_ptr GetPlatformUserInputMonitor( + const scoped_refptr& io_task_runner) + override { + return std::make_unique(std::move(io_task_runner)); + } + + private: + // Performs initialization steps need by both UI and GPU. + void InitializeCommon(const InitParams& params) { + if (common_initialized_) + return; + + common_initialized_ = true; + } + + // Creates |event_source_| if it doesn't already exist. + void CreatePlatformEventSource() { + if (event_source_) + return; + + auto* connection = x11::Connection::Get(); + event_source_ = std::make_unique(connection); + } + + bool common_initialized_ = false; + + // Objects in the UI process. + std::unique_ptr keyboard_layout_engine_; + std::unique_ptr overlay_manager_; + std::unique_ptr input_controller_; + std::unique_ptr clipboard_; + std::unique_ptr cursor_factory_; + std::unique_ptr gpu_platform_support_host_; + std::unique_ptr menu_utils_; + std::unique_ptr x11_utils_; + std::unique_ptr global_shortcut_listener_; + + // Objects in the GPU process. + std::unique_ptr surface_factory_ozone_; + std::unique_ptr gl_egl_utility_; + + // Objects in both UI and GPU process. + std::unique_ptr event_source_; + +#if BUILDFLAG(USE_GTK) + std::unique_ptr linux_ui_delegate_; +#endif +}; + +} // namespace + +OzonePlatform* CreateOzonePlatformX11() { + return new OzonePlatformX11; +} + +} // namespace ui diff --git a/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/ozone_platform_x11.h b/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/ozone_platform_x11.h new file mode 100644 index 0000000..fd71ca6 --- /dev/null +++ b/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/ozone_platform_x11.h @@ -0,0 +1,17 @@ +// Copyright 2016 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_OZONE_PLATFORM_X11_OZONE_PLATFORM_X11_H_ +#define UI_OZONE_PLATFORM_X11_OZONE_PLATFORM_X11_H_ + +namespace ui { + +class OzonePlatform; + +// Constructor hook for use in ozone_platform_list.cc +OzonePlatform* CreateOzonePlatformX11(); + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_X11_OZONE_PLATFORM_X11_H_ diff --git a/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/x11_surface_factory.cc b/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/x11_surface_factory.cc new file mode 100644 index 0000000..07dd820 --- /dev/null +++ b/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/x11_surface_factory.cc @@ -0,0 +1,267 @@ +// Copyright 2016 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/ozone/platform/x11/x11_surface_factory.h" + +#include + +#include "components/viz/common/resources/shared_image_format_utils.h" +#include "gpu/vulkan/buildflags.h" +#include "ui/events/platform/x11/x11_event_source.h" +#include "ui/gfx/linux/gbm_buffer.h" +#include "ui/gfx/linux/gbm_support_x11.h" +#include "ui/gfx/linux/native_pixmap_dmabuf.h" +#include "ui/gl/gl_bindings.h" +#include "ui/gl/gl_surface_egl.h" +#include "ui/gl/gl_surface_egl_x11_gles2.h" +#include "ui/ozone/common/egl_util.h" +#include "ui/ozone/common/gl_ozone_egl.h" +#include "ui/ozone/common/native_pixmap_egl_binding.h" +#include "ui/ozone/platform/x11/gl_surface_egl_readback_x11.h" +#include "ui/ozone/platform/x11/native_pixmap_egl_x11_binding.h" +#include "ui/ozone/platform/x11/x11_canvas_surface.h" + +#if BUILDFLAG(ENABLE_VULKAN) +#include "ui/ozone/platform/x11/vulkan_implementation_x11.h" +#endif + +namespace ui { +namespace { + +enum class NativePixmapSupportType { + // Importing native pixmaps not supported. + kNone, + + // Native pixmaps are imported directly into EGL using the + // EGL_EXT_image_dma_buf_import extension. + kDMABuf, + + // Native pixmaps are first imported as X11 pixmaps using DRI3 and then into + // EGL. + kX11Pixmap, +}; + +NativePixmapSupportType GetNativePixmapSupportType() { + if (gl::GLSurfaceEGL::GetGLDisplayEGL() + ->ext->b_EGL_EXT_image_dma_buf_import) { + return NativePixmapSupportType::kDMABuf; + } else if (NativePixmapEGLX11Binding::CanImportNativeGLXPixmap()) { + return NativePixmapSupportType::kX11Pixmap; + } else { + return NativePixmapSupportType::kNone; + } +} + +class GLOzoneEGLX11 : public GLOzoneEGL { + public: + GLOzoneEGLX11() = default; + + GLOzoneEGLX11(const GLOzoneEGLX11&) = delete; + GLOzoneEGLX11& operator=(const GLOzoneEGLX11&) = delete; + + ~GLOzoneEGLX11() override = default; + + // GLOzone: + bool InitializeStaticGLBindings( + const gl::GLImplementationParts& implementation) override { + is_swiftshader_ = gl::IsSoftwareGLImplementation(implementation); + return GLOzoneEGL::InitializeStaticGLBindings(implementation); + } + + bool CanImportNativePixmap(viz::SharedImageFormat format) override { + if (GetNativePixmapSupportType() == NativePixmapSupportType::kNone) { + return false; + } + + switch (GetNativePixmapSupportType()) { + case NativePixmapSupportType::kDMABuf: { + return NativePixmapEGLBinding::IsSharedImageFormatSupported(format); + } + case NativePixmapSupportType::kX11Pixmap: { + return NativePixmapEGLX11Binding::IsSharedImageFormatSupported(format); + } + default: + return false; + } + } + + scoped_refptr CreateViewGLSurface( + gl::GLDisplay* display, + gfx::AcceleratedWidget window) override { + if (is_swiftshader_) { + return gl::InitializeGLSurface( + base::MakeRefCounted( + display->GetAs(), window)); + } else { + switch (gl::GetGLImplementation()) { + case gl::kGLImplementationEGLGLES2: + DCHECK(window != gfx::kNullAcceleratedWidget); + return gl::InitializeGLSurface(new gl::NativeViewGLSurfaceEGLX11GLES2( + display->GetAs(), + static_cast(window))); + case gl::kGLImplementationEGLANGLE: + DCHECK(window != gfx::kNullAcceleratedWidget); + return gl::InitializeGLSurface(new gl::NativeViewGLSurfaceEGLX11( + display->GetAs(), + static_cast(window))); + default: + NOTREACHED(); + } + } + } + + scoped_refptr CreateOffscreenGLSurface( + gl::GLDisplay* display, + const gfx::Size& size) override { + gl::GLDisplayEGL* egl_display = display->GetAs(); + if (egl_display->IsEGLSurfacelessContextSupported() && size.width() == 0 && + size.height() == 0) { + return InitializeGLSurface(new gl::SurfacelessEGL(egl_display, size)); + } else { + return InitializeGLSurface( + new gl::PbufferGLSurfaceEGL(egl_display, size)); + } + } + + protected: + // GLOzoneEGL: + gl::EGLDisplayPlatform GetNativeDisplay() override { + return gl::EGLDisplayPlatform(reinterpret_cast( + x11::Connection::Get()->GetXlibDisplay().display())); + } + + bool LoadGLES2Bindings( + const gl::GLImplementationParts& implementation) override { + return LoadDefaultEGLGLES2Bindings(implementation); + } + + private: + std::unique_ptr ImportNativePixmap( + scoped_refptr pixmap, + viz::SharedImageFormat plane_format, + std::optional plane_index, + gfx::Size plane_size, + const gfx::ColorSpace& color_space, + GLenum target, + GLuint texture_id) override { + switch (GetNativePixmapSupportType()) { + case NativePixmapSupportType::kDMABuf: { + return NativePixmapEGLBinding::Create(pixmap, plane_format, plane_index, + plane_size, color_space, target, + texture_id); + } + case NativePixmapSupportType::kX11Pixmap: { + return NativePixmapEGLX11Binding::Create( + pixmap, plane_format, plane_size, target, texture_id); + } + default: + return nullptr; + } + } + + bool is_swiftshader_ = false; +}; + +} // namespace + +X11SurfaceFactory::X11SurfaceFactory( + std::unique_ptr connection) + : egl_implementation_(std::make_unique()), + connection_(std::move(connection)) {} + +X11SurfaceFactory::~X11SurfaceFactory() = default; + +std::vector +X11SurfaceFactory::GetAllowedGLImplementations() { + return std::vector{ + gl::GLImplementationParts(gl::kGLImplementationEGLANGLE), + }; +} + +GLOzone* X11SurfaceFactory::GetGLOzone( + const gl::GLImplementationParts& implementation) { + switch (implementation.gl) { + case gl::kGLImplementationEGLANGLE: + return egl_implementation_.get(); + default: + return nullptr; + } +} + +#if BUILDFLAG(ENABLE_VULKAN) +std::unique_ptr +X11SurfaceFactory::CreateVulkanImplementation(bool use_swiftshader, + bool allow_protected_memory) { + return std::make_unique(use_swiftshader); +} +#endif + +std::unique_ptr X11SurfaceFactory::CreateCanvasForWidget( + gfx::AcceleratedWidget widget) { + // X11SoftwareBitmapPresenter (created via X11CanvasSurface) requres a + // Connection TLS instance and a PlatformEventSource. + if (connection_) { + auto* connection = connection_.get(); + x11::Connection::Set(std::move(connection_)); + connection->platform_event_source = + std::make_unique(connection); + } + return std::make_unique(widget); +} + +scoped_refptr X11SurfaceFactory::CreateNativePixmap( + gfx::AcceleratedWidget widget, + gpu::VulkanDeviceQueue* device_queue, + gfx::Size size, + viz::SharedImageFormat format, + gfx::BufferUsage usage, + std::optional framebuffer_size) { + scoped_refptr pixmap; + auto buffer = + ui::GBMSupportX11::GetInstance()->CreateBuffer(format, size, usage); + if (buffer) { + gfx::NativePixmapHandle handle = buffer->ExportHandle(); + if (handle.planes.empty()) { + return nullptr; + } + pixmap = base::MakeRefCounted(size, format, + std::move(handle)); + } + + // CreateNativePixmap is non-blocking operation. Thus, it is safe to call it + // and return the result with the provided callback. + return pixmap; +} + +bool X11SurfaceFactory::CanCreateNativePixmapForFormat( + viz::SharedImageFormat format) { + return ui::GBMSupportX11::GetInstance()->CanCreateBufferForFormat(format); +} + +scoped_refptr +X11SurfaceFactory::CreateNativePixmapFromHandle( + gfx::AcceleratedWidget widget, + gfx::Size size, + viz::SharedImageFormat format, + gfx::NativePixmapHandle handle) { + scoped_refptr pixmap; + auto buffer = ui::GBMSupportX11::GetInstance()->CreateBufferFromHandle( + size, format, std::move(handle)); + if (buffer) { + gfx::NativePixmapHandle buffer_handle = buffer->ExportHandle(); + if (buffer_handle.planes.empty()) { + return nullptr; + } + pixmap = base::MakeRefCounted( + size, format, std::move(buffer_handle)); + } + return pixmap; +} + +bool X11SurfaceFactory::IsFormatSupportedForTexturing( + viz::SharedImageFormat format) const { + return ui::GBMSupportX11::GetInstance()->CanCreateBufferForFormat(format); +} + +} // namespace ui diff --git a/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/x11_surface_factory.h b/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/x11_surface_factory.h new file mode 100644 index 0000000..78e19a7 --- /dev/null +++ b/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/x11_surface_factory.h @@ -0,0 +1,65 @@ +// Copyright 2016 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_OZONE_PLATFORM_X11_X11_SURFACE_FACTORY_H_ +#define UI_OZONE_PLATFORM_X11_X11_SURFACE_FACTORY_H_ + +#include +#include + +#include "components/viz/common/resources/shared_image_format.h" +#include "gpu/vulkan/buildflags.h" +#include "ui/gfx/x/connection.h" +#include "ui/gl/gl_surface.h" +#include "ui/ozone/public/gl_ozone.h" +#include "ui/ozone/public/surface_factory_ozone.h" + +namespace ui { + +// Handles GL initialization and surface/context creation for X11. +class X11SurfaceFactory : public SurfaceFactoryOzone { + public: + explicit X11SurfaceFactory(std::unique_ptr connection); + + X11SurfaceFactory(const X11SurfaceFactory&) = delete; + X11SurfaceFactory& operator=(const X11SurfaceFactory&) = delete; + + ~X11SurfaceFactory() override; + + // SurfaceFactoryOzone: + std::vector GetAllowedGLImplementations() override; + GLOzone* GetGLOzone(const gl::GLImplementationParts& implementation) override; +#if BUILDFLAG(ENABLE_VULKAN) + std::unique_ptr CreateVulkanImplementation( + bool use_swiftshader, + bool allow_protected_memory) override; +#endif + std::unique_ptr CreateCanvasForWidget( + gfx::AcceleratedWidget widget) override; + scoped_refptr CreateNativePixmap( + gfx::AcceleratedWidget widget, + gpu::VulkanDeviceQueue* device_queue, + gfx::Size size, + viz::SharedImageFormat format, + gfx::BufferUsage usage, + std::optional framebuffer_size = std::nullopt) override; + bool CanCreateNativePixmapForFormat(viz::SharedImageFormat format) override; + scoped_refptr CreateNativePixmapFromHandle( + gfx::AcceleratedWidget widget, + gfx::Size size, + viz::SharedImageFormat format, + gfx::NativePixmapHandle handle) override; + + bool IsFormatSupportedForTexturing( + viz::SharedImageFormat format) const override; + + private: + std::unique_ptr egl_implementation_; + + std::unique_ptr connection_; +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_X11_X11_SURFACE_FACTORY_H_ diff --git a/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/x11_window.cc b/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/x11_window.cc new file mode 100644 index 0000000..7af3482 --- /dev/null +++ b/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/x11_window.cc @@ -0,0 +1,2624 @@ +// Copyright 2014 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/ozone/platform/x11/x11_window.h" + +#include + +#include "base/compiler_specific.h" +#include "base/memory/scoped_refptr.h" +#include "base/no_destructor.h" +#include "base/notimplemented.h" +#include "base/notreached.h" +#include "base/strings/string_number_conversions.h" +#include "base/task/single_thread_task_runner.h" +#include "base/trace_event/trace_event.h" +#include "net/base/network_interfaces.h" +#include "third_party/skia/include/core/SkPath.h" +#include "third_party/skia/include/core/SkRegion.h" +#include "ui/base/buildflags.h" +#include "ui/base/cursor/cursor.h" +#include "ui/base/cursor/platform_cursor.h" +#include "ui/base/dragdrop/drag_drop_types.h" +#include "ui/base/dragdrop/mojom/drag_drop_types.mojom.h" +#include "ui/base/dragdrop/os_exchange_data.h" +#include "ui/base/ui_base_features.h" +#include "ui/base/wm_role_names_linux.h" +#include "ui/base/x/x11_cursor.h" +#include "ui/base/x/x11_os_exchange_data_provider.h" +#include "ui/base/x/x11_pointer_grab.h" +#include "ui/base/x/x11_util.h" +#include "ui/display/screen.h" +#include "ui/events/devices/x11/touch_factory_x11.h" +#include "ui/events/event.h" +#include "ui/events/event_utils.h" +#include "ui/events/ozone/events_ozone.h" +#include "ui/events/platform/platform_event_source.h" +#include "ui/events/platform/x11/x11_event_source.h" +#include "ui/events/x/events_x_utils.h" +#include "ui/events/x/x11_event_translation.h" +#include "ui/gfx/geometry/skia_conversions.h" +#include "ui/gfx/geometry/transform.h" +#include "ui/gfx/image/image_skia_rep.h" +#include "ui/gfx/x/atom_cache.h" +#include "ui/gfx/x/geometry_cache.h" +#include "ui/gfx/x/visual_manager.h" +#include "ui/gfx/x/window_event_manager.h" +#include "ui/gfx/x/wm_sync.h" +#include "ui/gfx/x/x11_path.h" +#include "ui/gfx/x/xproto.h" +#include "ui/ozone/platform/x11/hit_test_x11.h" +#include "ui/ozone/platform/x11/x11_window_manager.h" +#include "ui/platform_window/common/platform_window_defaults.h" +#include "ui/platform_window/extensions/workspace_extension_delegate.h" +#include "ui/platform_window/extensions/x11_extension_delegate.h" +#include "ui/platform_window/wm/wm_drop_handler.h" + +#if BUILDFLAG(USE_ATK) +#include "ui/ozone/platform/x11/atk_event_conversion.h" +#endif + +namespace ui { +namespace { + +using mojom::DragOperation; + +// Opacity for drag widget windows. +constexpr float kDragWidgetOpacity = .75f; + +// Coalesce touch/mouse events if needed +bool CoalesceEventsIfNeeded(const x11::Event& xev, + EventType type, + x11::Event* out) { + if (xev.As() || + (xev.As() && + (type == ui::EventType::kTouchMoved || + type == ui::EventType::kMouseMoved || + type == ui::EventType::kMouseDragged))) { + return ui::CoalescePendingMotionEvents(xev, out) > 0; + } + return false; +} + +int GetKeyModifiers(const XDragDropClient* client) { + if (!client) { + return ui::XGetMaskAsEventFlags(); + } + return client->current_modifier_state(); +} + +// Special value of the _NET_WM_DESKTOP property which indicates that the window +// should appear on all workspaces/desktops. +const int32_t kAllWorkspaces = -1; + +constexpr char kX11WindowRolePopup[] = "popup"; +constexpr char kX11WindowRoleBubble[] = "bubble"; +constexpr char kDarkGtkThemeVariant[] = "dark"; + +constexpr long kSystemTrayRequestDock = 0; + +constexpr int kXembedInfoProtocolVersion = 0; +constexpr int kXembedFlagMap = 1 << 0; +constexpr int kXembedInfoFlags = kXembedFlagMap; + +enum CrossingFlags : uint8_t { + CROSSING_FLAG_FOCUS = 1 << 0, + CROSSING_FLAG_SAME_SCREEN = 1 << 1, +}; + +// In some situations, views tries to make a zero sized window, and that +// makes us crash. Make sure we have valid sizes. +gfx::Rect SanitizeBounds(const gfx::Rect& bounds) { + gfx::Size sanitized_size(std::max(bounds.width(), 1), + std::max(bounds.height(), 1)); + gfx::Rect sanitized_bounds(bounds.origin(), sanitized_size); + return sanitized_bounds; +} + +void SerializeImageRepresentation(const gfx::ImageSkiaRep& rep, + std::vector* data) { + uint32_t width = rep.GetWidth(); + data->push_back(width); + + uint32_t height = rep.GetHeight(); + data->push_back(height); + + const SkBitmap& bitmap = rep.GetBitmap(); + + for (uint32_t y = 0; y < height; ++y) { + for (uint32_t x = 0; x < width; ++x) { + data->push_back(bitmap.getColor(x, y)); + } + } +} + +x11::NotifyMode XI2ModeToXMode(x11::Input::NotifyMode xi2_mode) { + switch (xi2_mode) { + case x11::Input::NotifyMode::Normal: + return x11::NotifyMode::Normal; + case x11::Input::NotifyMode::Grab: + case x11::Input::NotifyMode::PassiveGrab: + return x11::NotifyMode::Grab; + case x11::Input::NotifyMode::Ungrab: + case x11::Input::NotifyMode::PassiveUngrab: + return x11::NotifyMode::Ungrab; + case x11::Input::NotifyMode::WhileGrabbed: + return x11::NotifyMode::WhileGrabbed; + default: + NOTREACHED(); + } +} + +x11::NotifyDetail XI2DetailToXDetail(x11::Input::NotifyDetail xi2_detail) { + switch (xi2_detail) { + case x11::Input::NotifyDetail::Ancestor: + return x11::NotifyDetail::Ancestor; + case x11::Input::NotifyDetail::Virtual: + return x11::NotifyDetail::Virtual; + case x11::Input::NotifyDetail::Inferior: + return x11::NotifyDetail::Inferior; + case x11::Input::NotifyDetail::Nonlinear: + return x11::NotifyDetail::Nonlinear; + case x11::Input::NotifyDetail::NonlinearVirtual: + return x11::NotifyDetail::NonlinearVirtual; + case x11::Input::NotifyDetail::Pointer: + return x11::NotifyDetail::Pointer; + case x11::Input::NotifyDetail::PointerRoot: + return x11::NotifyDetail::PointerRoot; + case x11::Input::NotifyDetail::None: + return x11::NotifyDetail::None; + } +} + +// Returns the whole path from |window| to the root. +std::vector GetParentsList(x11::Connection* connection, + x11::Window window) { + std::vector result; + while (window != x11::Window::None) { + result.push_back(window); + if (auto reply = connection->QueryTree({window}).Sync()) { + window = reply->parent; + } else { + break; + } + } + return result; +} + +std::vector& GetSecuritySurfaces() { + static base::NoDestructor> security_surfaces; + return *security_surfaces; +} + +x11::Window GetWindowForEvent(const x11::Event& xev) { + if (auto* button = xev.As()) { + return button->event; + } + if (auto* key = xev.As()) { + return key->event; + } + if (auto* motion = xev.As()) { + return motion->event; + } + if (auto* xievent = xev.As()) { + return xievent->event; + } + if (auto* crossing = xev.As()) { + return crossing->event; + } + if (auto* expose = xev.As()) { + return expose->window; + } + if (auto* focus = xev.As()) { + return focus->event; + } + if (auto* configure = xev.As()) { + return configure->window; + } + if (auto* crossing_input = xev.As()) { + return crossing_input->event; + } + if (auto* map = xev.As()) { + return map->window; + } + if (auto* unmap = xev.As()) { + return unmap->window; + } + if (auto* client = xev.As()) { + return client->window; + } + if (auto* property = xev.As()) { + return property->window; + } + if (auto* selection = xev.As()) { + return selection->requestor; + } + if (auto* visibility = xev.As()) { + return visibility->window; + } + return x11::Window::None; +} + +} // namespace + +X11Window::X11Window(PlatformWindowDelegate* platform_window_delegate) + : platform_window_delegate_(platform_window_delegate), + connection_(*x11::Connection::Get()), + x_root_window_(GetX11RootWindow()) { + DCHECK_NE(x_root_window_, x11::Window::None); + DCHECK(platform_window_delegate_); + + // Set a class property key, which allows |this| to be used for interactive + // events, e.g. move or resize. + SetWmMoveResizeHandler(this, static_cast(this)); + + // Set extensions property key that extends the interface of this platform + // implementation. + SetWorkspaceExtension(this, static_cast(this)); + SetX11Extension(this, static_cast(this)); +} + +X11Window::~X11Window() { + PrepareForShutdown(); + Close(); +} + +void X11Window::Initialize(PlatformWindowInitProperties properties) { + CreateXWindow(properties); + + // It can be a status icon window. If it fails to initialize, don't provide + // it with a native window handle, close ourselves and let the client destroy + // ourselves. + if (properties.wm_role_name == kStatusIconWmRoleName && + !InitializeAsStatusIcon()) { + CloseXWindow(); + return; + } + + // At this point, the X window is created. Register it and notify the + // platform window delegate. + X11WindowManager::GetInstance()->AddWindow(this); + + connection_->AddEventObserver(this); + DCHECK(X11EventSource::HasInstance()); + X11EventSource::GetInstance()->AddPlatformEventDispatcher(this); + + x11_window_move_client_ = + std::make_unique(this); + + // Mark the window as eligible for the move loop, which allows tab dragging. + SetWmMoveLoopHandler(this, static_cast(this)); + + platform_window_delegate_->OnAcceleratedWidgetAvailable(GetWidget()); + + // TODO(erg): Maybe need to set a ViewProp here like in RWHL::RWHL(). + + auto event_mask = + x11::EventMask::ButtonPress | x11::EventMask::ButtonRelease | + x11::EventMask::FocusChange | x11::EventMask::KeyPress | + x11::EventMask::KeyRelease | x11::EventMask::EnterWindow | + x11::EventMask::LeaveWindow | x11::EventMask::Exposure | + x11::EventMask::VisibilityChange | x11::EventMask::StructureNotify | + x11::EventMask::PropertyChange | x11::EventMask::PointerMotion; + xwindow_events_ = connection_->ScopedSelectEvent(xwindow_, event_mask); + connection_->Flush(); + + if (IsXInput2Available()) { + TouchFactory::GetInstance()->SetupXI2ForXWindow(xwindow_); + } + + std::vector protocols = { + x11::GetAtom("WM_DELETE_WINDOW"), + x11::GetAtom("_NET_WM_PING"), + + // Request the _NET_WM_SYNC_REQUEST protocol which is used for + // synchronizing between chrome and desktop compositor (or WM) during + // resizing. The protocol is documented at + // https://specifications.freedesktop.org/wm-spec/1.3/ar01s06.html + x11::GetAtom("_NET_WM_SYNC_REQUEST"), + }; + connection_->SetArrayProperty(xwindow_, x11::GetAtom("WM_PROTOCOLS"), + x11::Atom::ATOM, protocols); + + // We need a WM_CLIENT_MACHINE value so we integrate with the desktop + // environment. + connection_->SetStringProperty(xwindow_, x11::Atom::WM_CLIENT_MACHINE, + x11::Atom::STRING, net::GetHostName()); + + // Likewise, the X server needs to know this window's pid so it knows which + // program to kill if the window hangs. + // XChangeProperty() expects "pid" to be long. + static_assert(sizeof(uint32_t) >= sizeof(pid_t), + "pid_t should not be larger than uint32_t"); + uint32_t pid = getpid(); + connection_->SetProperty(xwindow_, x11::GetAtom("_NET_WM_PID"), + x11::Atom::CARDINAL, pid); + + x11::Atom window_type; + switch (properties.type) { + case PlatformWindowType::kMenu: + window_type = x11::GetAtom("_NET_WM_WINDOW_TYPE_MENU"); + break; + case PlatformWindowType::kTooltip: + window_type = x11::GetAtom("_NET_WM_WINDOW_TYPE_TOOLTIP"); + break; + case PlatformWindowType::kBubble: + case PlatformWindowType::kPopup: + window_type = x11::GetAtom("_NET_WM_WINDOW_TYPE_NOTIFICATION"); + break; + case PlatformWindowType::kDrag: + window_type = x11::GetAtom("_NET_WM_WINDOW_TYPE_DND"); + break; + default: + window_type = x11::GetAtom("_NET_WM_WINDOW_TYPE_NORMAL"); + break; + } + connection_->SetProperty(xwindow_, x11::GetAtom("_NET_WM_WINDOW_TYPE"), + x11::Atom::ATOM, window_type); + + // The changes to |window_properties_| here will be sent to the X server just + // before the window is mapped. + + // Remove popup windows from taskbar. + if ((properties.type == PlatformWindowType::kPopup || + properties.type == PlatformWindowType::kBubble)) { + window_properties_.insert(x11::GetAtom("_NET_WM_STATE_SKIP_TASKBAR")); + } + + // If the window should stay on top of other windows, add the + // _NET_WM_STATE_ABOVE property. + is_always_on_top_ = properties.keep_on_top; + if (is_always_on_top_) { + window_properties_.insert(x11::GetAtom("_NET_WM_STATE_ABOVE")); + } + + is_security_surface_ = properties.is_security_surface; + if (is_security_surface_) { + GetSecuritySurfaces().push_back(xwindow_); + } else { + // Newly created windows appear at the top of the stacking order, so raise + // any security surfaces since the WM will not do it if the window is + // override-redirect. + for (x11::Window window : GetSecuritySurfaces()) { + connection_->RaiseWindow(window); + } + } + + workspace_ = std::nullopt; + if (properties.visible_on_all_workspaces) { + window_properties_.insert(x11::GetAtom("_NET_WM_STATE_STICKY")); + connection_->SetProperty(xwindow_, x11::GetAtom("_NET_WM_DESKTOP"), + x11::Atom::CARDINAL, kAllWorkspaces); + } else if (!properties.workspace.empty()) { + int32_t workspace; + if (base::StringToInt(properties.workspace, &workspace)) { + connection_->SetProperty(xwindow_, x11::GetAtom("_NET_WM_DESKTOP"), + x11::Atom::CARDINAL, workspace); + } + } + + if (!properties.wm_class_name.empty() || !properties.wm_class_class.empty()) { + SetWindowClassHint(&connection_.get(), xwindow_, properties.wm_class_name, + properties.wm_class_class); + } + + const char* wm_role_name = nullptr; + // If the widget isn't overriding the role, provide a default value for popup + // and bubble types. + if (!properties.wm_role_name.empty()) { + wm_role_name = properties.wm_role_name.c_str(); + } else { + switch (properties.type) { + case PlatformWindowType::kPopup: + wm_role_name = kX11WindowRolePopup; + break; + case PlatformWindowType::kBubble: + wm_role_name = kX11WindowRoleBubble; + break; + default: + break; + } + } + if (wm_role_name) { + SetWindowRole(xwindow_, std::string(wm_role_name)); + } + + SetTitle(u""); + + if (properties.remove_standard_frame) { + // Setting _GTK_HIDE_TITLEBAR_WHEN_MAXIMIZED tells gnome-shell to not force + // fullscreen on the window when it matches the desktop size. + SetHideTitlebarWhenMaximizedProperty(xwindow_, + HIDE_TITLEBAR_WHEN_MAXIMIZED); + } + + if (properties.prefer_dark_theme) { + connection_->SetStringProperty(xwindow_, x11::GetAtom("_GTK_THEME_VARIANT"), + x11::GetAtom("UTF8_STRING"), + kDarkGtkThemeVariant); + } + + if (IsSyncExtensionAvailable()) { + x11::Sync::Int64 value{}; + update_counter_ = connection_->GenerateId(); + connection_->sync().CreateCounter(update_counter_, value); + + // The compositor will listen for counter updates during resizing. + connection_->SetProperty(xwindow_, + x11::GetAtom("_NET_WM_SYNC_REQUEST_COUNTER"), + x11::Atom::CARDINAL, update_counter_); + } + + // Always composite Chromium windows if a compositing WM is used. Sometimes, + // WMs will not composite fullscreen windows as an optimization, but this can + // lead to tearing of fullscreen videos. + connection_->SetProperty(xwindow_, + x11::GetAtom("_NET_WM_BYPASS_COMPOSITOR"), + x11::Atom::CARDINAL, 2); + + if (properties.icon) { + SetWindowIcons(gfx::ImageSkia(), *properties.icon); + } + + if (properties.type == PlatformWindowType::kDrag) { + SetOpacity(kDragWidgetOpacity); + } + + SetWmDragHandler(this, this); + + drag_drop_client_ = std::make_unique(this, window()); +} + +void X11Window::OnXWindowLostCapture() { + platform_window_delegate_->OnLostCapture(); +} + +void X11Window::OnCursorUpdate() { + platform_window_delegate_->OnCursorUpdate(); +} + +gfx::AcceleratedWidget X11Window::GetWidget() const { + // In spite of being defined in Xlib as `unsigned long`, XID (|window()|'s + // type) is fixed at 32-bits (CARD32) in X11 Protocol, therefore can't be + // larger than 32 bits values on the wire (see https://crbug.com/607014 for + // more details). So, It's safe to use static_cast here. + return static_cast(window()); +} + +void X11Window::Show(bool inactive) { + if (window_mapped_in_client_) { + return; + } + + Map(inactive); +} + +void X11Window::Hide() { + if (!window_mapped_in_client_) { + return; + } + + // Make sure no resize task will run after the window is unmapped. + CancelResize(); + + connection_->WithdrawWindow(xwindow_); + window_mapped_in_client_ = false; +} + +void X11Window::Close() { + if (is_shutting_down_) { + return; + } + + X11WindowManager::GetInstance()->RemoveWindow(this); + + is_shutting_down_ = true; + + CloseXWindow(); + + platform_window_delegate_->OnClosed(); +} + +bool X11Window::IsVisible() const { + // On Windows, IsVisible() returns true for minimized windows. On X11, a + // minimized window is not mapped, so an explicit IsMinimized() check is + // necessary. + return window_mapped_in_client_ || IsMinimized(); +} + +void X11Window::PrepareForShutdown() { + if (HasCapture()) { + X11WindowManager::GetInstance()->UngrabEvents(this); + } + connection_->RemoveEventObserver(this); + DCHECK(X11EventSource::HasInstance()); + X11EventSource::GetInstance()->RemovePlatformEventDispatcher(this); +} + +void X11Window::SetBoundsInPixels(const gfx::Rect& bounds) { + gfx::Rect new_bounds_in_pixels(bounds.origin(), + AdjustSizeForDisplay(bounds.size())); + + const bool size_changed = + GetBoundsInPixels().size() != new_bounds_in_pixels.size(); + const bool origin_changed = + GetBoundsInPixels().origin() != new_bounds_in_pixels.origin(); + + // Assume that the resize will go through as requested, which should be the + // case if we're running without a window manager. If there's a window + // manager, it can modify or ignore the request, but (per ICCCM) we'll get a + // (possibly synthetic) ConfigureNotify about the actual size and correct + // |bounds_| later. + + x11::ConfigureWindowRequest req{.window = xwindow_}; + + if (size_changed) { + // Only cancel the delayed resize task if we're already about to call + // OnHostResized in this function. + CancelResize(); + + // Update the minimum and maximum sizes in case they have changed. + UpdateMinAndMaxSize(); + + if (new_bounds_in_pixels.width() < min_size_in_pixels_.width() || + new_bounds_in_pixels.height() < min_size_in_pixels_.height() || + (!max_size_in_pixels_.IsEmpty() && + (new_bounds_in_pixels.width() > max_size_in_pixels_.width() || + new_bounds_in_pixels.height() > max_size_in_pixels_.height()))) { + gfx::Size size_in_pixels = new_bounds_in_pixels.size(); + if (!max_size_in_pixels_.IsEmpty()) { + size_in_pixels.SetToMin(max_size_in_pixels_); + } + size_in_pixels.SetToMax(min_size_in_pixels_); + new_bounds_in_pixels.set_size(size_in_pixels); + } + + req.width = new_bounds_in_pixels.width(); + req.height = new_bounds_in_pixels.height(); + } + + if (origin_changed) { + req.x = new_bounds_in_pixels.x(); + req.y = new_bounds_in_pixels.y(); + } + + if (origin_changed || size_changed) { + connection_->ConfigureWindow(req); + } + + // Assume that the resize will go through as requested, which should be the + // case if we're running without a window manager. If there's a window + // manager, it can modify or ignore the request, but (per ICCCM) we'll get a + // (possibly synthetic) ConfigureNotify about the actual size and correct + // |bounds_in_pixels_| later. + SetBoundsWithWmSync(new_bounds_in_pixels); + ResetWindowRegion(); + + // Even if the pixel bounds didn't change this call to the delegate should + // still happen. The device scale factor may have changed which effectively + // changes the bounds. + platform_window_delegate_->OnBoundsChanged({origin_changed}); +} + +gfx::Rect X11Window::GetBoundsInPixels() const { + return bounds_wm_sync_ || !geometry_cache_ ? last_set_bounds_px_ + : geometry_cache_->GetBoundsPx(); +} + +void X11Window::SetBoundsInDIP(const gfx::Rect& bounds_in_dip) { + SetBoundsInPixels( + platform_window_delegate_->ConvertRectToPixels(bounds_in_dip)); +} + +gfx::Rect X11Window::GetBoundsInDIP() const { + return platform_window_delegate_->ConvertRectToDIP(GetBoundsInPixels()); +} + +void X11Window::SetTitle(const std::u16string& title) { + if (window_title_ == title) { + return; + } + + window_title_ = title; + std::string utf8str = base::UTF16ToUTF8(title); + connection_->SetStringProperty(xwindow_, x11::GetAtom("_NET_WM_NAME"), + x11::GetAtom("UTF8_STRING"), utf8str); + connection_->SetStringProperty(xwindow_, x11::Atom::WM_NAME, + x11::GetAtom("UTF8_STRING"), utf8str); +} + +void X11Window::SetCapture() { + if (HasCapture()) { + return; + } + X11WindowManager::GetInstance()->GrabEvents(this); + + // If the pointer is already in |xwindow_|, we will not get a crossing event + // with a mode of NotifyGrab, so we must record the grab state manually. + has_pointer_grab_ |= + (ui::GrabPointer(xwindow_, true, nullptr) == x11::GrabStatus::Success); +} + +void X11Window::ReleaseCapture() { + if (!HasCapture()) { + return; + } + + UngrabPointer(); + has_pointer_grab_ = false; + + X11WindowManager::GetInstance()->UngrabEvents(this); +} + +bool X11Window::HasCapture() const { + return X11WindowManager::GetInstance()->located_events_grabber() == this; +} + +void X11Window::SetFullscreen(bool fullscreen, int64_t target_display_id) { + // TODO(crbug.com/40111909) Support `target_display_id` on this platform. + DCHECK_EQ(target_display_id, display::kInvalidDisplayId); + if (fullscreen) { + CancelResize(); + } + + // Work around a bug where if we try to unfullscreen, metacity immediately + // fullscreens us again. This is a little flickery and not necessary if + // there's a gnome-panel, but it's not easy to detect whether there's a + // panel or not. + bool unmaximize_and_remaximize = !fullscreen && IsMaximized() && + ui::GuessWindowManager() == ui::WM_METACITY; + + if (unmaximize_and_remaximize) { + SetWMStateMaximize(false); + } + + // Fullscreen state changes have to be handled manually and then checked + // against configuration events, which come from a compositor. The reason + // of manually changing the |state_| is that the compositor answers + // about state changes asynchronously, which leads to a wrong return value in + // DesktopWindowTreeHostPlatform::IsFullscreen, for example, and media + // files can never be set to fullscreen. Wayland does the same. + auto new_state = PlatformWindowState::kNormal; + if (fullscreen) { + new_state = PlatformWindowState::kFullScreen; + } else if (IsMaximized()) { + new_state = PlatformWindowState::kMaximized; + } + + bool was_fullscreen = IsFullscreen(); + state_ = new_state; + SetWMStateFullscreen(fullscreen); + + if (unmaximize_and_remaximize) { + // Setting the should_maximize_after_map_ same way as it is done in + // X11Window::Maximize(). + should_maximize_after_map_ = !window_mapped_in_client_; + SetWMStateMaximize(true); + } + + // Try to guess the size we will have after the switch to/from fullscreen: + // - (may) avoid transient states + // - works around Flash content which expects to have the size updated + // synchronously. + // See https://crbug.com/361408 + gfx::Rect new_bounds_px = GetBoundsInPixels(); + if (fullscreen) { + restored_bounds_in_pixels_ = new_bounds_px; + if (x11_extension_delegate_) { + new_bounds_px = x11_extension_delegate_->GetGuessedFullScreenSizeInPx(); + } + } else { + // Exiting "browser fullscreen mode", but the X11 window is not necessarily + // in fullscreen state (e.g: a WM keybinding might have been used to toggle + // fullscreen state). So check whether the window is in fullscreen state + // before trying to restore its bounds (saved before entering in browser + // fullscreen mode). + if (was_fullscreen) { + new_bounds_px = restored_bounds_in_pixels_; + } else { + restored_bounds_in_pixels_ = gfx::Rect(); + } + } + + UpdateDecorationInsets(); + + // Pretend the bounds changed immediately, and wait for a WM sync to use the + // server's bounds. + bool origin_changed = GetBoundsInPixels().origin() != new_bounds_px.origin(); + SetBoundsWithWmSync(new_bounds_px); + + // This must be the final call in this function, as `this` may be deleted + // during the observation of this event. + platform_window_delegate_->OnBoundsChanged({origin_changed}); +} + +void X11Window::Maximize() { + if (IsFullscreen()) { + // Unfullscreen the window if it is fullscreen. + SetFullscreen(false, display::kInvalidDisplayId); + + // Resize the window so that it does not have the same size as a monitor. + // (Otherwise, some window managers immediately put the window back in + // fullscreen mode). + gfx::Rect bounds_in_pixels = GetBoundsInPixels(); + gfx::Rect adjusted_bounds_in_pixels( + bounds_in_pixels.origin(), + AdjustSizeForDisplay(bounds_in_pixels.size())); + if (adjusted_bounds_in_pixels != bounds_in_pixels) { + SetBoundsInPixels(adjusted_bounds_in_pixels); + } + } + + // When we are in the process of requesting to maximize a window, we can + // accurately keep track of our restored bounds instead of relying on the + // heuristics that are in the PropertyNotify and ConfigureNotify handlers. + restored_bounds_in_pixels_ = GetBoundsInPixels(); + + // Some WMs do not respect maximization hints on unmapped windows, so we + // save this one for later too. + should_maximize_after_map_ = !window_mapped_in_client_; + + SetWMStateMaximize(true); +} + +void X11Window::Minimize() { + if (window_mapped_in_client_) { + SendClientMessage(xwindow_, x_root_window_, x11::GetAtom("WM_CHANGE_STATE"), + {x11::WM_STATE_ICONIC, 0, 0, 0, 0}); + } else { + SetWMSpecState(true, x11::GetAtom("_NET_WM_STATE_HIDDEN"), x11::Atom::None); + } +} + +void X11Window::Restore() { + if (IsMinimized()) { + SetWMSpecState(false, x11::GetAtom("_NET_WM_STATE_HIDDEN"), + x11::Atom::None); + } else if (IsFullscreen()) { + SetFullscreen(false, display::kInvalidDisplayId); + } else if (IsMaximized()) { + should_maximize_after_map_ = false; + SetWMStateMaximize(false); + } +} + +void X11Window::ShowWindowControlsMenu(const gfx::Point& point) { + SendClientMessage(xwindow_, x_root_window_, + x11::GetAtom("_GTK_SHOW_WINDOW_MENU"), + {/*device_id=*/0, base::bit_cast(point.x()), + base::bit_cast(point.y()), 0, 0}); +} + +PlatformWindowState X11Window::GetPlatformWindowState() const { + return state_; +} + +void X11Window::Activate() { + if (!IsVisible() || !activatable_) { + return; + } + + BeforeActivationStateChanged(); + + ignore_keyboard_input_ = false; + + // wmii says that it supports _NET_ACTIVE_WINDOW but does not. + // https://code.google.com/p/wmii/issues/detail?id=266 + static bool wm_supports_active_window = + GuessWindowManager() != WM_WMII && + connection_->WmSupportsHint(x11::GetAtom("_NET_ACTIVE_WINDOW")); + + x11::Time timestamp = X11EventSource::GetInstance()->GetTimestamp(); + + // override_redirect windows ignore _NET_ACTIVE_WINDOW. + // https://crbug.com/940924 + if (wm_supports_active_window && !override_redirect_) { + std::array data = { + // We're an app. + 1, + static_cast(timestamp), + // TODO(thomasanderson): if another chrome window is active, specify + // that here. The EWMH spec claims this may make the WM more likely to + // service our _NET_ACTIVE_WINDOW request. + 0, + 0, + 0, + }; + SendClientMessage(xwindow_, x_root_window_, + x11::GetAtom("_NET_ACTIVE_WINDOW"), data); + } else { + connection_->RaiseWindow(xwindow_); + // Directly ask the X server to give focus to the window. Note that the call + // would have raised an X error if the window is not mapped. + connection_->SetInputFocus({x11::InputFocus::Parent, xwindow_, timestamp}) + .IgnoreError(); + // At this point, we know we will receive focus, and some webdriver tests + // depend on a window being IsActive() immediately after an Activate(), so + // just set this state now. + has_pointer_focus_ = false; + has_window_focus_ = true; + window_mapped_in_server_ = true; + } + + AfterActivationStateChanged(); +} + +void X11Window::Deactivate() { + BeforeActivationStateChanged(); + + // Ignore future input events. + ignore_keyboard_input_ = true; + + connection_->LowerWindow(xwindow_); + + AfterActivationStateChanged(); +} + +void X11Window::SetUseNativeFrame(bool use_native_frame) { + use_native_frame_ = use_native_frame; + SetUseOSWindowFrame(xwindow_, use_native_frame); + ResetWindowRegion(); +} + +bool X11Window::ShouldUseNativeFrame() const { + return use_native_frame_; +} + +void X11Window::SetCursor(scoped_refptr cursor) { + DCHECK(cursor); + + // When a DnD loop is running, DesktopDragDropClientOzone may change the + // cursor type based on the current dnd operation. Setting cursor type with + // the current window that is involved in the DnD is no-op as + // X11WholeScreenMoveLoop grabs the pointer and is responsible for changing + // current pointer's bitmap. Thus, pass the changed cursor to the drag loop so + // that it handles the change. + if (drag_loop_) { + drag_loop_->UpdateCursor(X11Cursor::FromPlatformCursor(cursor)); + return; + } + + last_cursor_ = X11Cursor::FromPlatformCursor(cursor); + on_cursor_loaded_.Reset(base::BindOnce( + &x11::Connection::DefineCursor, base::Unretained(connection_), xwindow_)); + last_cursor_->OnCursorLoaded(on_cursor_loaded_.callback()); +} + +void X11Window::MoveCursorTo(const gfx::Point& location_px) { + connection_->WarpPointer(x11::WarpPointerRequest{ + .dst_window = x_root_window_, + .dst_x = static_cast(GetBoundsInPixels().x() + location_px.x()), + .dst_y = static_cast(GetBoundsInPixels().y() + location_px.y()), + }); + // The cached cursor location is no longer valid. + X11EventSource::GetInstance()->ClearLastCursorLocation(); +} + +void X11Window::ConfineCursorToBounds(const gfx::Rect& bounds) { + UnconfineCursor(); + + if (bounds.IsEmpty()) { + return; + } + + gfx::Rect barrier = bounds + GetBoundsInPixels().OffsetFromOrigin(); + + auto make_barrier = [&](uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, + x11::XFixes::BarrierDirections directions) { + x11::XFixes::Barrier barrier = + connection_->GenerateId(); + connection_->xfixes().CreatePointerBarrier( + {barrier, x_root_window_, x1, y1, x2, y2, directions}); + return barrier; + }; + + // Top horizontal barrier. + pointer_barriers_[0] = + make_barrier(barrier.x(), barrier.y(), barrier.right(), barrier.y(), + x11::XFixes::BarrierDirections::PositiveY); + // Bottom horizontal barrier. + pointer_barriers_[1] = + make_barrier(barrier.x(), barrier.bottom(), barrier.right(), + barrier.bottom(), x11::XFixes::BarrierDirections::NegativeY); + // Left vertical barrier. + pointer_barriers_[2] = + make_barrier(barrier.x(), barrier.y(), barrier.x(), barrier.bottom(), + x11::XFixes::BarrierDirections::PositiveX); + // Right vertical barrier. + pointer_barriers_[3] = + make_barrier(barrier.right(), barrier.y(), barrier.right(), + barrier.bottom(), x11::XFixes::BarrierDirections::NegativeX); + + has_pointer_barriers_ = true; +} + +void X11Window::SetRestoredBoundsInDIP(const gfx::Rect& bounds) { + restored_bounds_in_pixels_ = + platform_window_delegate_->ConvertRectToPixels(bounds); +} + +gfx::Rect X11Window::GetRestoredBoundsInDIP() const { + return platform_window_delegate_->ConvertRectToDIP( + restored_bounds_in_pixels_); +} + +bool X11Window::ShouldWindowContentsBeTransparent() const { + return visual_has_alpha_; +} + +void X11Window::SetZOrderLevel(ZOrderLevel order) { + z_order_ = order; + + // Emulate the multiple window levels provided by other platforms by + // collapsing the z-order enum into kNormal = normal, everything else = always + // on top. + is_always_on_top_ = (z_order_ != ui::ZOrderLevel::kNormal); + SetWMSpecState(is_always_on_top_, x11::GetAtom("_NET_WM_STATE_ABOVE"), + x11::Atom::None); +} + +ZOrderLevel X11Window::GetZOrderLevel() const { + bool level_always_on_top = z_order_ != ui::ZOrderLevel::kNormal; + + if (is_always_on_top_ == level_always_on_top) { + return z_order_; + } + + // If something external has forced a window to be always-on-top, map it to + // kFloatingWindow as a reasonable equivalent. + return is_always_on_top_ ? ui::ZOrderLevel::kFloatingWindow + : ui::ZOrderLevel::kNormal; +} + +void X11Window::StackAbove(gfx::AcceleratedWidget widget) { + // Check comment in the GetWidget method about this cast. + auto window = static_cast(widget); + DCHECK(window != x11::Window::None); + + // Find all parent windows up to the root. + std::vector window_below_parents = + GetParentsList(&connection_.get(), window); + std::vector window_above_parents = + GetParentsList(&connection_.get(), xwindow_); + + // Find their common ancestor. + auto it_below_window = window_below_parents.rbegin(); + auto it_above_window = window_above_parents.rbegin(); + for (; it_below_window != window_below_parents.rend() && + it_above_window != window_above_parents.rend() && + *it_below_window == *it_above_window; + ++it_below_window, ++it_above_window) { + } + + if (it_below_window != window_below_parents.rend() && + it_above_window != window_above_parents.rend()) { + connection_->ConfigureWindow(x11::ConfigureWindowRequest{ + .window = *it_above_window, + .sibling = *it_below_window, + .stack_mode = x11::StackMode::Above, + }); + } +} + +void X11Window::StackAtTop() { + connection_->RaiseWindow(xwindow_); +} + +void X11Window::FlashFrame(bool flash_frame) { + SetFlashFrameHint(flash_frame); +} + +void X11Window::SetShape(std::unique_ptr native_shape, + const gfx::Transform& transform) { + std::unique_ptr> xregion; + if (native_shape) { + SkRegion native_region; + for (const gfx::Rect& rect : *native_shape) { + native_region.op(gfx::RectToSkIRect(rect), SkRegion::kUnion_Op); + } + if (!transform.IsIdentity() && !native_region.isEmpty()) { + if (!native_region.isEmpty()) { + const SkPath path_in_pixels = + native_region.getBoundaryPath().makeTransform( + gfx::TransformToFlattenedSkMatrix(transform)); + xregion = x11::CreateRegionFromSkPath(path_in_pixels); + } else { + xregion = std::make_unique>(); + } + } else { + xregion = x11::CreateRegionFromSkRegion(native_region); + } + } + + custom_window_shape_ = !!xregion; + window_shape_ = std::move(xregion); + ResetWindowRegion(); +} + +void X11Window::SetAspectRatio(const gfx::SizeF& aspect_ratio) { + x11::SizeHints size_hints = {}; + + connection_->GetWmNormalHints(xwindow_, &size_hints); + // Unforce aspect ratio is parameter length is 0, otherwise set normally. + if (aspect_ratio.IsEmpty()) { + size_hints.flags &= ~x11::SIZE_HINT_P_ASPECT; + } else { + size_hints.flags |= x11::SIZE_HINT_P_ASPECT; + size_hints.min_aspect_num = size_hints.max_aspect_num = + aspect_ratio.width(); + size_hints.min_aspect_den = size_hints.max_aspect_den = + aspect_ratio.height(); + } + connection_->SetWmNormalHints(xwindow_, size_hints); +} + +void X11Window::SetWindowIcons(const gfx::ImageSkia& window_icon, + const gfx::ImageSkia& app_icon) { + // TODO(erg): The way we handle icons across different versions of chrome + // could be substantially improved. The Windows version does its own thing + // and only sometimes comes down this code path. The icon stuff in + // ChromeViewsDelegate is hard coded to use HICONs. Likewise, we're hard + // coded to be given two images instead of an arbitrary collection of images + // so that we can pass to the WM. + // + // All of this could be made much, much better. + std::vector data; + + if (!window_icon.isNull()) { + SerializeImageRepresentation(window_icon.GetRepresentation(1.0f), &data); + } + + if (!app_icon.isNull()) { + SerializeImageRepresentation(app_icon.GetRepresentation(1.0f), &data); + } + + if (!data.empty()) { + connection_->SetArrayProperty(xwindow_, x11::GetAtom("_NET_WM_ICON"), + x11::Atom::CARDINAL, data); + } +} + +void X11Window::SizeConstraintsChanged() { + X11Window::UpdateMinAndMaxSize(); +} + +void X11Window::SetOpacity(float opacity) { + // X server opacity is in terms of 32 bit unsigned int space, and counts from + // the opposite direction. + // XChangeProperty() expects "cardinality" to be long. + + // Scale opacity to [0 .. 255] range. + uint32_t opacity_8bit = static_cast(opacity * 255.0f) & 0xFF; + // Use opacity value for all channels. + uint32_t channel_multiplier = 0x1010101; + uint32_t cardinality = opacity_8bit * channel_multiplier; + + if (cardinality == 0xffffffff) { + connection_->DeleteProperty(xwindow_, + x11::GetAtom("_NET_WM_WINDOW_OPACITY")); + } else { + connection_->SetProperty(xwindow_, x11::GetAtom("_NET_WM_WINDOW_OPACITY"), + x11::Atom::CARDINAL, cardinality); + } +} + +bool X11Window::CanSetDecorationInsets() const { + // Xfwm handles _GTK_FRAME_EXTENTS a bit unexpected way. That is a known bug + // that will be eventually fixed, but for now we have to disable the function + // for Xfce. The block below should be removed when Xfwm is updated with the + // fix and is known to work properly. + // See https://crbug.com/1260821. + { + static WindowManagerName wm_name = WM_OTHER; + static bool checked_for_wm = false; + if (!checked_for_wm) { + wm_name = GuessWindowManager(); + checked_for_wm = true; + } + if (wm_name == WM_XFWM4) { + return false; + } + } + return connection_->WmSupportsHint(x11::GetAtom("_GTK_FRAME_EXTENTS")); +} + +void X11Window::SetOpaqueRegion( + std::optional> region_px) { + auto atom = x11::GetAtom("_NET_WM_OPAQUE_REGION"); + if (!region_px) { + connection_->DeleteProperty(xwindow_, atom); + return; + } + std::vector value; + for (const auto& rect : *region_px) { + value.push_back(rect.x()); + value.push_back(rect.y()); + value.push_back(rect.width()); + value.push_back(rect.height()); + } + connection_->SetArrayProperty(xwindow_, atom, x11::Atom::CARDINAL, value); +} + +void X11Window::SetInputRegion( + std::optional> region_px) { + if (!region_px.has_value() || region_px->empty()) { + // Reset the input region. + connection_->shape().Mask({ + .operation = x11::Shape::So::Set, + .destination_kind = x11::Shape::Sk::Input, + .destination_window = xwindow_, + }); + return; + } + DCHECK_EQ(1u, region_px->size()); + connection_->shape().Rectangles(x11::Shape::RectanglesRequest{ + .operation = x11::Shape::So::Set, + .destination_kind = x11::Shape::Sk::Input, + .ordering = x11::ClipOrdering::YXBanded, + .destination_window = xwindow_, + .rectangles = {{static_cast((*region_px)[0].x()), + static_cast((*region_px)[0].y()), + static_cast((*region_px)[0].width()), + static_cast((*region_px)[0].height())}}, + }); +} + +void X11Window::NotifyStartupComplete(const std::string& startup_id) { + std::string message = "remove: ID=\""; + for (char c : startup_id) { + if (c == ' ' || c == '"' || c == '\\') { + message.push_back('\\'); + } + message.push_back(c); + } + message.push_back('"'); + + auto window = connection_->CreateDummyWindow(); + x11::ClientMessageEvent event{ + .format = 8, + .window = window, + .type = x11::GetAtom("_NET_STARTUP_INFO_BEGIN"), + }; + constexpr size_t kChunkSize = event.data.data8.size(); + const x11::Atom net_startup_info = x11::GetAtom("_NET_STARTUP_INFO"); + + // X11 ClientMessageEvents are fixed size, but we need to send a variable + // sized message. Send the message `kChunkSize` bytes at a time with the + // first message having type _NET_STARTUP_INFO_BEGIN and subsequent messages + // having type _NET_STARTUP_INFO. + const char* data = message.c_str(); + const size_t data_size = message.size() + 1; + for (size_t offset = 0; offset < data_size; offset += kChunkSize) { + size_t copy_size = std::min(kChunkSize, data_size - offset); + uint8_t* dst = &event.data.data8[0]; + UNSAFE_TODO(memcpy(dst, data + offset, copy_size)); + UNSAFE_TODO(memset(dst + copy_size, 0, kChunkSize - copy_size)); + connection_->SendEvent(event, x_root_window_, + x11::EventMask::PropertyChange); + event.type = net_startup_info; + } + + geometry_cache_.reset(); + connection_->DestroyWindow(window); + connection_->Flush(); +} + +std::string X11Window::GetWorkspace() const { + std::optional workspace_id = workspace_; + return workspace_id.has_value() ? base::NumberToString(workspace_id.value()) + : std::string(); +} + +void X11Window::SetVisibleOnAllWorkspaces(bool always_visible) { + SetWMSpecState(always_visible, x11::GetAtom("_NET_WM_STATE_STICKY"), + x11::Atom::None); + + int new_desktop = 0; + if (always_visible) { + new_desktop = kAllWorkspaces; + } else { + if (!GetCurrentDesktop(&new_desktop)) { + return; + } + } + + workspace_ = kAllWorkspaces; + SendClientMessage(xwindow_, x_root_window_, x11::GetAtom("_NET_WM_DESKTOP"), + {static_cast(new_desktop), 0, 0, 0, 0}); +} + +bool X11Window::IsVisibleOnAllWorkspaces() const { + // We don't need a check for _NET_WM_STATE_STICKY because that would specify + // that the window remain in a fixed position even if the viewport scrolls. + // This is different from the type of workspace that's associated with + // _NET_WM_DESKTOP. + return workspace_ == kAllWorkspaces; +} + +void X11Window::SetWorkspaceExtensionDelegate( + WorkspaceExtensionDelegate* delegate) { + workspace_extension_delegate_ = delegate; +} + +bool X11Window::IsSyncExtensionAvailable() const { +#if BUILDFLAG(IS_CHROMEOS) + // Chrome for ChromeOS can be run with X11 on a Linux desktop. In this case, + // NotifySwapAfterResize is never called as the compositor does not notify + // about swaps after resize. Thus, simply disable usage of XSyncCounter on + // ChromeOS builds. + return false; +#else + return connection_->sync_version() > std::pair{0, 0}; +#endif +} + +bool X11Window::IsWmTiling() const { + return ui::IsWmTiling(ui::GuessWindowManager()); +} + +void X11Window::OnCompleteSwapAfterResize(const gfx::Size& new_size) { + last_swapped_size_ = new_size; + if (configure_counter_value_) { + MaybeUpdateSyncCounter(); + } +} + +gfx::Rect X11Window::GetXRootWindowOuterBounds() const { + return GetOuterBounds(); +} + +void X11Window::LowerXWindow() { + connection_->LowerWindow(xwindow_); +} + +void X11Window::SetOverrideRedirect(bool override_redirect) { + bool remap = window_mapped_in_client_; + if (remap) { + Hide(); + } + connection_->ChangeWindowAttributes(x11::ChangeWindowAttributesRequest{ + .window = xwindow_, + .override_redirect = x11::Bool32(override_redirect), + }); + if (remap) { + Map(); + // We cannot regrab the pointer now since unmapping/mapping + // happens asynchronously. We must wait until the window is + // mapped to issue a grab request. + if (has_pointer_grab_) { + should_grab_pointer_after_map_ = true; + } + } +} + +bool X11Window::CanResetOverrideRedirect() const { + // Ratpoision sometimes hangs when setting the override-redirect state to a + // new value (https://crbug.com/1216221). + return ui::GuessWindowManager() != ui::WindowManagerName::WM_RATPOISON; +} + +void X11Window::SetX11ExtensionDelegate(X11ExtensionDelegate* delegate) { + x11_extension_delegate_ = delegate; +} + +bool X11Window::IsWmSyncActiveForTest() { + return bounds_wm_sync_.get(); +} + +bool X11Window::HandleAsAtkEvent(const x11::Event& event) { +#if !BUILDFLAG(USE_ATK) + // TODO(crbug.com/40653448): Support ATK in Ozone/X11. + NOTREACHED(); +#else + if (!x11_extension_delegate_) { + return false; + } + auto atk_key_event = AtkKeyEventFromXEvent(event); + if (!atk_key_event) { + return false; + } + return x11_extension_delegate_->OnAtkKeyEvent( + atk_key_event.get(), GetWindowForEvent(event) == transient_window_); +#endif +} + +void X11Window::OnEvent(const x11::Event& xev) { + auto event_type = ui::EventTypeFromXEvent(xev); + if (event_type != EventType::kUnknown) { + // If this event can be translated, it will be handled in ::DispatchEvent. + // Otherwise, we end up processing XEvents twice that could lead to unwanted + // behaviour like loosing activation during tab drag and etc. + return; + } + + auto* prop = xev.As(); + auto* target_current_context = drag_drop_client_->target_current_context(); + if (prop && target_current_context && + prop->window == target_current_context->source_window()) { + target_current_context->DispatchPropertyNotifyEvent(*prop); + } + + HandleEvent(xev); +} + +bool X11Window::CanDispatchEvent(const PlatformEvent& xev) { + if (is_shutting_down_) { + return false; + } + DCHECK_NE(window(), x11::Window::None); + auto* dispatching_event = connection_->dispatching_event(); + return dispatching_event && IsTargetedBy(*dispatching_event); +} + +uint32_t X11Window::DispatchEvent(const PlatformEvent& event) { + TRACE_EVENT1("views", "X11PlatformWindow::Dispatch", "event->type()", + event->type()); + + DCHECK_NE(window(), x11::Window::None); + DCHECK(event); + + auto& current_xevent = *connection_->dispatching_event(); + + if (event->IsMouseEvent()) { + X11WindowManager::GetInstance()->MouseOnWindow(this); + } +#if BUILDFLAG(USE_ATK) + if (HandleAsAtkEvent(current_xevent)) { + return POST_DISPATCH_STOP_PROPAGATION; + } +#endif + + DispatchUiEvent(event, current_xevent); + return POST_DISPATCH_STOP_PROPAGATION; +} + +void X11Window::DispatchUiEvent(ui::Event* event, const x11::Event& xev) { + auto* window_manager = X11WindowManager::GetInstance(); + DCHECK(window_manager); + + // Process X11-specific bits + HandleEvent(xev); + + x11::Event last_xev; + std::unique_ptr last_motion; + if (CoalesceEventsIfNeeded(xev, event->type(), &last_xev)) { + last_motion = ui::BuildEventFromXEvent(last_xev); + event = last_motion.get(); + } + if (!event) { + return; + } + + // If |event| is a located event (mouse, touch, etc) and another X11 window + // is set as the current located events grabber, the |event| must be + // re-routed to that grabber. Otherwise, just send the event. + // Note: We want to coalesce events before doing this, since this modifies our + // ui::Event's coordinates, and coalescing would simply undo the coordinate + // change. + auto* located_events_grabber = window_manager->located_events_grabber(); + if (event->IsLocatedEvent() && located_events_grabber && + located_events_grabber != this) { + if (event->IsMouseEvent() || + (event->IsTouchEvent() && + event->type() == ui::EventType::kTouchPressed)) { + // Another X11Window has installed itself as capture. Translate the + // event's location and dispatch to the other. + ConvertEventLocationToTargetWindowLocation( + located_events_grabber->GetBoundsInPixels().origin(), + GetBoundsInPixels().origin(), event->AsLocatedEvent()); + } + return located_events_grabber->DispatchUiEvent(event, xev); + } + + // If after CoalescePendingMotionEvents the type of xev is resolved to + // UNKNOWN, i.e: xevent translation returns nullptr, don't dispatch the + // event. TODO(crbug.com/40559202): investigate why ColescePendingMotionEvents + // can include mouse wheel events as well. Investigation showed that events on + // Linux are checked with cmt-device path, and can include DT_CMT_SCROLL_ + // data. See more discussion in https://crrev.com/c/853953 + UpdateWMUserTime(event); + DispatchEventFromNativeUiEvent( + event, base::BindOnce(&PlatformWindowDelegate::DispatchEvent, + base::Unretained(platform_window_delegate()))); +} + +void X11Window::UpdateDecorationInsets() { + auto atom = x11::GetAtom("_GTK_FRAME_EXTENTS"); + auto insets_dip = + platform_window_delegate_->CalculateInsetsInDIP(GetPlatformWindowState()); + + if (insets_dip.IsEmpty()) { + connection_->DeleteProperty(xwindow_, atom); + return; + } + + // Insets must be zero when the window state is not normal nor unknown. + CHECK(GetPlatformWindowState() == PlatformWindowState::kNormal || + GetPlatformWindowState() == PlatformWindowState::kUnknown); + + auto insets_px = platform_window_delegate_->ConvertInsetsToPixels(insets_dip); + connection_->SetArrayProperty( + xwindow_, atom, x11::Atom::CARDINAL, + std::vector{static_cast(insets_px.left()), + static_cast(insets_px.right()), + static_cast(insets_px.top()), + static_cast(insets_px.bottom())}); +} + +void X11Window::OnXWindowStateChanged() { + // Determine the new window state information to be propagated to the client. + // Note that the order of checks is important here, because window can have + // several properties at the same time. + auto new_state = PlatformWindowState::kNormal; + if (IsMinimized()) { + new_state = PlatformWindowState::kMinimized; + } else if (IsFullscreen()) { + new_state = PlatformWindowState::kFullScreen; + } else if (IsMaximized()) { + new_state = PlatformWindowState::kMaximized; + } + + // fullscreen state is set syschronously at ToggleFullscreen() and must be + // kept and propagated to the client only when explicitly requested by upper + // layers, as it means we are in "browser fullscreen mode" (where + // decorations, omnibar, buttons, etc are hidden), which is different from + // the case where the request comes from the window manager (or any other + // process), handled by this method. In this case, we follow EWMH guidelines: + // Optimize the whole application for fullscreen usage. Window decorations + // (e.g. borders) should be hidden, but the functionalily of the application + // should not change. Further details: + // https://specifications.freedesktop.org/wm-spec/wm-spec-1.3.html + bool browser_fullconnection_mode = state_ == PlatformWindowState::kFullScreen; + bool window_fullconnection_mode = + new_state == PlatformWindowState::kFullScreen; + // So, we ignore fullscreen state transitions in 2 cases: + // 1. If |new_state| is kFullScreen but |state_| is not, which means the + // fullscreen request is coming from an external process. So the browser + // window must occupies the entire screen but not transitioning to browser + // fullscreen mode. + // 2. if |state_| is kFullScreen but |new_state| is not, we have been + // requested to exit fullscreen by other process (e.g: via WM keybinding), + // in this case we must keep on "browser fullscreen mode" bug the platform + // window gets back to its previous state (e.g: unmaximized, tiled in TWMs, + // etc). + if (window_fullconnection_mode != browser_fullconnection_mode) { + return; + } + + if (!restored_bounds_in_pixels_.IsEmpty() && !IsMaximized() && + !IsFullscreen()) { + // If we have restored bounds, but WM_STATE no longer claims to be + // maximized or fullscreen, we should clear our restored bounds. + restored_bounds_in_pixels_ = gfx::Rect(); + } + + if (new_state != state_) { + auto old_state = state_; + state_ = new_state; + platform_window_delegate_->OnWindowStateChanged(old_state, state_); + if (CanSetDecorationInsets()) { + UpdateDecorationInsets(); + } + } + + WindowTiledEdges tiled_state = GetTiledState(); + if (tiled_state != tiled_state_) { + tiled_state_ = tiled_state; +#if BUILDFLAG(IS_LINUX) + platform_window_delegate_->OnWindowTiledStateChanged(tiled_state); + UpdateDecorationInsets(); +#endif + } +} + +void X11Window::OnXWindowDamageEvent(const gfx::Rect& damage_rect) { + platform_window_delegate_->OnDamageRect(damage_rect); +} + +void X11Window::OnXWindowCloseRequested() { + platform_window_delegate_->OnCloseRequest(); +} + +void X11Window::OnXWindowIsActiveChanged(bool active) { + platform_window_delegate_->OnActivationChanged(active); +} + +void X11Window::OnXWindowWorkspaceChanged() { + if (workspace_extension_delegate_) { + workspace_extension_delegate_->OnWorkspaceChanged(); + } +} + +void X11Window::OnXWindowLostPointerGrab() { + if (x11_extension_delegate_) { + x11_extension_delegate_->OnLostMouseGrab(); + } +} + +void X11Window::OnXWindowSelectionEvent(const x11::SelectionNotifyEvent& xev) { + DCHECK(drag_drop_client_); + drag_drop_client_->OnSelectionNotify(xev); +} + +void X11Window::OnXWindowDragDropEvent(const x11::ClientMessageEvent& xev) { + DCHECK(drag_drop_client_); + drag_drop_client_->HandleXdndEvent(xev); +} + +std::optional X11Window::GetMinimumSizeForXWindow() { + if (auto max_size = platform_window_delegate_->GetMinimumSizeForWindow()) { + return platform_window_delegate_->ConvertRectToPixels(gfx::Rect(*max_size)) + .size(); + } + return std::nullopt; +} + +std::optional X11Window::GetMaximumSizeForXWindow() { + if (auto max_size = platform_window_delegate_->GetMaximumSizeForWindow()) { + return platform_window_delegate_->ConvertRectToPixels(gfx::Rect(*max_size)) + .size(); + } + return std::nullopt; +} + +SkPath X11Window::GetWindowMaskForXWindow() { + return platform_window_delegate_->GetWindowMaskForWindowShapeInPixels(); +} + +void X11Window::DispatchHostWindowDragMovement( + int hittest, + const gfx::Point& pointer_location_in_px) { + int direction = HitTestToWmMoveResizeDirection(hittest); + if (direction == -1) { + return; + } + + DoWMMoveResize(&connection_.get(), x_root_window_, xwindow_, + pointer_location_in_px, direction); +} + +bool X11Window::RunMoveLoop(const gfx::Vector2d& drag_offset) { + return x11_window_move_client_->RunMoveLoop(!HasCapture(), drag_offset); +} + +void X11Window::EndMoveLoop() { + x11_window_move_client_->EndMoveLoop(); +} + +bool X11Window::StartDrag( + const OSExchangeData& data, + int operations, + mojom::DragEventSource source, + gfx::NativeCursor cursor, + bool can_grab_pointer, + base::OnceClosure drag_started_callback, + WmDragHandler::DragFinishedCallback drag_finished_callback, + WmDragHandler::LocationDelegate* location_delegate) { + DCHECK(drag_drop_client_); + DCHECK(!drag_location_delegate_); + + drag_finished_callback_ = std::move(drag_finished_callback); + drag_location_delegate_ = location_delegate; + drag_drop_client_->InitDrag(operations, &data); + allowed_drag_operations_ = 0; + notified_enter_ = false; + + drag_loop_ = std::make_unique(this); + + auto alive = weak_ptr_factory_.GetWeakPtr(); + const bool dropped = + drag_loop_->RunMoveLoop(can_grab_pointer, last_cursor_, last_cursor_, + std::move(drag_started_callback)); + if (!alive) { + return false; + } + + drag_loop_.reset(); + drag_location_delegate_ = nullptr; + drag_drop_client_->CleanupDrag(); + return dropped; +} + +void X11Window::CancelDrag() { + QuitDragLoop(); +} + +void X11Window::UpdateDragImage(const gfx::ImageSkia& image, + const gfx::Vector2d& offset) { + NOTIMPLEMENTED(); +} + +std::optional X11Window::GetDragWidget() { + DCHECK(drag_location_delegate_); + return drag_location_delegate_->GetDragWidget(); +} + +int X11Window::UpdateDrag(const gfx::Point& connection_point) { + WmDropHandler* drop_handler = GetWmDropHandler(*this); + if (!drop_handler) { + return DragDropTypes::DRAG_NONE; + } + + DCHECK(drag_drop_client_); + auto* target_current_context = drag_drop_client_->target_current_context(); + if (!target_current_context) { + return DragDropTypes::DRAG_NONE; + } + + auto data = std::make_unique( + std::make_unique( + drag_drop_client_->xwindow(), target_current_context->source_window(), + target_current_context->fetched_targets())); + int suggested_operations = target_current_context->GetDragOperation(); + // KDE-based file browsers such as Dolphin change the drag operation depending + // on whether alt/ctrl/shift was pressed. However once Chromium gets control + // over the X11 events, the source application does no longer receive X11 + // events for key modifier changes, so the dnd operation gets stuck in an + // incorrect state. Blink can only dnd-open files of type DRAG_COPY, so the + // DRAG_COPY mask is added if the dnd object is a file. + if (data->HasFile() && (suggested_operations & (DragDropTypes::DRAG_MOVE | + DragDropTypes::DRAG_LINK))) { + suggested_operations |= DragDropTypes::DRAG_COPY; + } + + XDragDropClient* source_client = + XDragDropClient::GetForWindow(target_current_context->source_window()); + gfx::PointF local_point_in_dip = + platform_window_delegate_->ConvertScreenPointToLocalDIP(connection_point); + if (!notified_enter_) { + drop_handler->OnDragEnter(local_point_in_dip, suggested_operations, + GetKeyModifiers(source_client)); + + // TODO(crbug.com/40073696): Factor DataFetched out of Enter callback. + drop_handler->OnDragDataAvailable(std::move(data)); + + notified_enter_ = true; + } + allowed_drag_operations_ = drop_handler->OnDragMotion( + local_point_in_dip, suggested_operations, GetKeyModifiers(source_client)); + return allowed_drag_operations_; +} + +void X11Window::UpdateCursor(DragOperation negotiated_operation) { + DCHECK(drag_location_delegate_); + drag_location_delegate_->OnDragOperationChanged(negotiated_operation); +} + +void X11Window::OnBeginForeignDrag(x11::Window window) { + notified_enter_ = false; + source_window_events_ = + connection_->ScopedSelectEvent(window, x11::EventMask::PropertyChange); +} + +void X11Window::OnEndForeignDrag() { + source_window_events_.Reset(); +} + +void X11Window::OnBeforeDragLeave() { + WmDropHandler* drop_handler = GetWmDropHandler(*this); + if (!drop_handler) { + return; + } + drop_handler->OnDragLeave(); + notified_enter_ = false; +} + +DragOperation X11Window::PerformDrop() { + WmDropHandler* drop_handler = GetWmDropHandler(*this); + if (!drop_handler || !notified_enter_) { + return DragOperation::kNone; + } + + auto* target_current_context = drag_drop_client_->target_current_context(); + if (!target_current_context) { + return DragOperation::kNone; + } + + drop_handler->OnDragDrop(GetKeyModifiers( + XDragDropClient::GetForWindow(target_current_context->source_window()))); + notified_enter_ = false; + return PreferredDragOperation(allowed_drag_operations_); +} + +void X11Window::EndDragLoop() { + DCHECK(!drag_finished_callback_.is_null()); + std::move(drag_finished_callback_) + .Run(PreferredDragOperation(allowed_drag_operations_)); + drag_loop_->EndMoveLoop(); +} + +void X11Window::OnMouseMovement(const gfx::Point& connection_point, + int flags, + base::TimeTicks event_time) { + drag_location_delegate_->OnDragLocationChanged(connection_point); + drag_drop_client_->HandleMouseMovement(connection_point, flags, event_time); +} + +void X11Window::OnMouseReleased() { + drag_drop_client_->HandleMouseReleased(); +} + +void X11Window::OnMoveLoopEnded() { + drag_drop_client_->HandleMoveLoopEnded(); +} + +void X11Window::SetBoundsOnMove(const gfx::Rect& requested_bounds) { + SetBoundsInPixels(requested_bounds); +} + +scoped_refptr X11Window::GetLastCursor() { + return last_cursor_; +} + +gfx::Size X11Window::GetSize() { + return GetBoundsInPixels().size(); +} + +void X11Window::QuitDragLoop() { + DCHECK(drag_loop_); + drag_loop_->EndMoveLoop(); +} + +gfx::Size X11Window::AdjustSizeForDisplay( + const gfx::Size& requested_size_in_pixels) { +#if BUILDFLAG(IS_CHROMEOS) + // We do not need to apply the workaround for the ChromeOS. + return requested_size_in_pixels; +#else + auto* screen = display::Screen::Get(); + if (screen && !UseTestConfigForPlatformWindows()) { + std::vector displays = screen->GetAllDisplays(); + // Compare against all monitor sizes. The window manager can move the window + // to whichever monitor it wants. + for (const auto& display : displays) { + if (requested_size_in_pixels == display.GetSizeInPixel()) { + return gfx::Size(requested_size_in_pixels.width() - 1, + requested_size_in_pixels.height() - 1); + } + } + } + + // Do not request a 0x0 window size. It causes an XError. + gfx::Size size_in_pixels = requested_size_in_pixels; + size_in_pixels.SetToMax(gfx::Size(1, 1)); + return size_in_pixels; +#endif +} + +void X11Window::CreateXWindow(const PlatformWindowInitProperties& properties) { + auto bounds = + platform_window_delegate_->ConvertRectToPixels(properties.bounds); + + gfx::Size adjusted_size_in_pixels = AdjustSizeForDisplay(bounds.size()); + bounds.set_size(adjusted_size_in_pixels); + const auto override_redirect = + properties.x11_extension_delegate && + properties.x11_extension_delegate->IsOverrideRedirect(*this); + + workspace_extension_delegate_ = properties.workspace_extension_delegate; + x11_extension_delegate_ = properties.x11_extension_delegate; + + activatable_ = properties.activatable; + + x11::CreateWindowRequest req; + req.bit_gravity = x11::Gravity::NorthWest; + req.background_pixel = properties.background_color.has_value() + ? properties.background_color.value() + : connection_->default_screen().white_pixel; + + switch (properties.type) { + case PlatformWindowType::kMenu: + req.override_redirect = x11::Bool32(true); + break; + case PlatformWindowType::kTooltip: + req.override_redirect = x11::Bool32(true); + break; + case PlatformWindowType::kPopup: + req.override_redirect = x11::Bool32(true); + break; + case PlatformWindowType::kDrag: + req.override_redirect = x11::Bool32(true); + break; + default: + break; + } + // An in-activatable window should not interact with the system wm. + if (!activatable_ || override_redirect) { + req.override_redirect = x11::Bool32(true); + } + +#if BUILDFLAG(IS_CHROMEOS) + req.override_redirect = x11::Bool32(UseTestConfigForPlatformWindows()); +#endif + + override_redirect_ = req.override_redirect.has_value(); + + bool enable_transparent_visuals; + switch (properties.opacity) { + case PlatformWindowOpacity::kOpaqueWindow: + enable_transparent_visuals = false; + break; + case PlatformWindowOpacity::kTranslucentWindow: + enable_transparent_visuals = true; + break; + case PlatformWindowOpacity::kInferOpacity: + enable_transparent_visuals = properties.type == PlatformWindowType::kDrag; + } + + if (properties.wm_role_name == kStatusIconWmRoleName) { + std::string atom_name = + "_NET_SYSTEM_TRAY_S" + + base::NumberToString(connection_->DefaultScreenId()); + auto selection = + connection_->GetSelectionOwner({x11::GetAtom(atom_name.c_str())}); + if (auto reply = selection.Sync()) { + connection_->GetPropertyAs( + reply->owner, x11::GetAtom("_NET_SYSTEM_TRAY_VISUAL"), &visual_id_); + } + } + + x11::VisualId visual_id = visual_id_; + uint8_t depth = 0; + x11::ColorMap colormap{}; + auto& visual_manager = connection_->GetOrCreateVisualManager(); + if (visual_id_ == x11::VisualId{} || + !visual_manager.GetVisualInfo(visual_id_, &depth, &colormap, + &visual_has_alpha_)) { + visual_manager.ChooseVisualForWindow(enable_transparent_visuals, &visual_id, + &depth, &colormap, &visual_has_alpha_); + } + // When drawing translucent windows, ensure a translucent background pixel + // value so that a colored border won't be shown in the time after the window + // has been resized smaller but before Chrome has finished drawing a frame. + if (visual_has_alpha_) { + req.background_pixel = 0; + } + + // x.org will BadMatch if we don't set a border when the depth isn't the + // same as the parent depth. + req.border_pixel = 0; + + last_set_bounds_px_ = SanitizeBounds(bounds); + req.parent = x_root_window_; + req.x = last_set_bounds_px_.x(); + req.y = last_set_bounds_px_.y(); + req.width = last_set_bounds_px_.width(); + req.height = last_set_bounds_px_.height(); + req.depth = depth; + req.c_class = x11::WindowClass::InputOutput; + req.visual = visual_id; + req.colormap = colormap; + xwindow_ = connection_->GenerateId(); + req.wid = xwindow_; + connection_->CreateWindow(req); + // Unretained is safe since we own `geometry_cache_`. + geometry_cache_ = std::make_unique( + &*connection_, xwindow_, + base::BindRepeating(&X11Window::OnBoundsChanged, base::Unretained(this))); +} + +void X11Window::CloseXWindow() { + if (xwindow_ == x11::Window::None) { + return; + } + + CancelResize(); + UnconfineCursor(); + // Unregister from the global security surface list if necessary. + if (is_security_surface_) { + auto& security_surfaces = GetSecuritySurfaces(); + security_surfaces.erase(std::ranges::find(security_surfaces, xwindow_), + security_surfaces.end()); + } + + geometry_cache_.reset(); + connection_->DestroyWindow({xwindow_}); + xwindow_ = x11::Window::None; + + if (update_counter_ != x11::Sync::Counter{}) { + connection_->sync().DestroyCounter(update_counter_); + update_counter_ = {}; + } +} + +void X11Window::Map(bool inactive) { + // Before we map the window, set size hints. Otherwise, some window managers + // will ignore toplevel XMoveWindow commands. + x11::SizeHints size_hints = {}; + connection_->GetWmNormalHints(xwindow_, &size_hints); + size_hints.flags |= x11::SIZE_HINT_P_POSITION; + size_hints.x = GetBoundsInPixels().x(); + size_hints.y = GetBoundsInPixels().y(); + // Set STATIC_GRAVITY so that the window position is not affected by the + // frame width when running with window manager. + size_hints.flags |= x11::SIZE_HINT_P_WIN_GRAVITY; + size_hints.win_gravity = x11::WIN_GRAVITY_HINT_STATIC_GRAVITY; + connection_->SetWmNormalHints(xwindow_, size_hints); + + ignore_keyboard_input_ = inactive; + auto wm_user_time_ms = ignore_keyboard_input_ + ? x11::Time::CurrentTime + : X11EventSource::GetInstance()->GetTimestamp(); + if (inactive || wm_user_time_ms != x11::Time::CurrentTime) { + connection_->SetProperty(xwindow_, x11::GetAtom("_NET_WM_USER_TIME"), + x11::Atom::CARDINAL, wm_user_time_ms); + } + + UpdateMinAndMaxSize(); + + UpdateDecorationInsets(); + + if (window_properties_.empty()) { + connection_->DeleteProperty(xwindow_, x11::GetAtom("_NET_WM_STATE")); + } else { + connection_->SetArrayProperty( + xwindow_, x11::GetAtom("_NET_WM_STATE"), x11::Atom::ATOM, + std::vector(std::begin(window_properties_), + std::end(window_properties_))); + } + + connection_->MapWindow({xwindow_}); + window_mapped_in_client_ = true; + + // TODO(thomasanderson): Find out why this flush is necessary. + connection_->Flush(); +} + +void X11Window::SetWMStateFullscreen(bool fullscreen) { + SetWMSpecState(fullscreen, x11::GetAtom("_NET_WM_STATE_FULLSCREEN"), + x11::Atom::None); +} + +void X11Window::SetWMStateMaximize(bool maximize) { + SetWMSpecState(maximize, x11::GetAtom("_NET_WM_STATE_MAXIMIZED_VERT"), + x11::GetAtom("_NET_WM_STATE_MAXIMIZED_HORZ")); +} + +bool X11Window::IsActive() const { + // Focus and stacking order are independent in X11. Since we cannot guarantee + // a window is topmost iff it has focus, just use the focus state to determine + // if a window is active. Note that Activate() and Deactivate() change the + // stacking order in addition to changing the focus state. + return (has_window_focus_ || has_pointer_focus_) && !ignore_keyboard_input_; +} + +bool X11Window::IsMinimized() const { + return HasWMSpecProperty(window_properties_, + x11::GetAtom("_NET_WM_STATE_HIDDEN")); +} + +bool X11Window::IsMaximized() const { + // In X11, if a maximized window is minimized, it will have both the "hidden" + // and "maximized" states. + if (IsMinimized()) { + return false; + } + return (HasWMSpecProperty(window_properties_, + x11::GetAtom("_NET_WM_STATE_MAXIMIZED_VERT")) && + HasWMSpecProperty(window_properties_, + x11::GetAtom("_NET_WM_STATE_MAXIMIZED_HORZ"))); +} + +bool X11Window::IsFullscreen() const { + return HasWMSpecProperty(window_properties_, + x11::GetAtom("_NET_WM_STATE_FULLSCREEN")); +} + +gfx::Rect X11Window::GetOuterBounds() const { + gfx::Rect outer_bounds(GetBoundsInPixels()); + outer_bounds.Inset(-native_window_frame_borders_in_pixels_); + return outer_bounds; +} + +void X11Window::ResetWindowRegion() { + std::unique_ptr> xregion; + if (!custom_window_shape_ && !IsMaximized() && !IsFullscreen()) { + SkPath window_mask = GetWindowMaskForXWindow(); + // Some frame views define a custom (non-rectangular) window mask. If + // so, use it to define the window shape. If not, fall through. + if (window_mask.countPoints() > 0) { + xregion = x11::CreateRegionFromSkPath(window_mask); + } + } + UpdateWindowRegion(std::move(xregion)); +} + +void X11Window::OnWorkspaceUpdated() { + auto old_workspace = workspace_; + int workspace; + if (GetWindowDesktop(xwindow_, &workspace)) { + workspace_ = workspace; + } else { + workspace_ = std::nullopt; + } + + if (workspace_ != old_workspace) { + OnXWindowWorkspaceChanged(); + } +} + +void X11Window::SetFlashFrameHint(bool flash_frame) { + if (urgency_hint_set_ == flash_frame) { + return; + } + + x11::WmHints hints = {}; + connection_->GetWmHints(xwindow_, &hints); + + if (flash_frame) { + hints.flags |= x11::WM_HINT_X_URGENCY; + } else { + hints.flags &= ~x11::WM_HINT_X_URGENCY; + } + + connection_->SetWmHints(xwindow_, hints); + + urgency_hint_set_ = flash_frame; +} + +void X11Window::UpdateMinAndMaxSize() { + std::optional minimum_in_pixels = GetMinimumSizeForXWindow(); + std::optional maximum_in_pixels = GetMaximumSizeForXWindow(); + if ((!minimum_in_pixels || + min_size_in_pixels_ == minimum_in_pixels.value()) && + (!maximum_in_pixels || + max_size_in_pixels_ == maximum_in_pixels.value())) { + return; + } + + min_size_in_pixels_ = minimum_in_pixels.value(); + max_size_in_pixels_ = maximum_in_pixels.value(); + + x11::SizeHints hints = {}; + connection_->GetWmNormalHints(xwindow_, &hints); + + if (min_size_in_pixels_.IsEmpty()) { + hints.flags &= ~x11::SIZE_HINT_P_MIN_SIZE; + } else { + hints.flags |= x11::SIZE_HINT_P_MIN_SIZE; + hints.min_width = min_size_in_pixels_.width(); + hints.min_height = min_size_in_pixels_.height(); + } + + if (max_size_in_pixels_.IsEmpty()) { + hints.flags &= ~x11::SIZE_HINT_P_MAX_SIZE; + } else { + hints.flags |= x11::SIZE_HINT_P_MAX_SIZE; + hints.max_width = max_size_in_pixels_.width(); + hints.max_height = max_size_in_pixels_.height(); + } + + connection_->SetWmNormalHints(xwindow_, hints); +} + +void X11Window::BeforeActivationStateChanged() { + was_active_ = IsActive(); + had_pointer_ = has_pointer_; + had_pointer_grab_ = has_pointer_grab_; + had_window_focus_ = has_window_focus_; +} + +void X11Window::AfterActivationStateChanged() { + if (had_pointer_grab_ && !has_pointer_grab_) { + OnXWindowLostPointerGrab(); + } + + if (had_pointer_grab_ && !has_pointer_grab_) { + OnXWindowLostCapture(); + } + + bool is_active = IsActive(); + if (!was_active_ && is_active) { + SetFlashFrameHint(false); + } + + if (was_active_ != is_active) { + OnXWindowIsActiveChanged(is_active); + } +} + +void X11Window::MaybeUpdateOcclusionState() { + PlatformWindowOcclusionState occlusion_state = + is_occluded_ ? PlatformWindowOcclusionState::kOccluded + : PlatformWindowOcclusionState::kVisible; + + if (!window_mapped_in_client_ || IsMinimized()) { + occlusion_state = PlatformWindowOcclusionState::kHidden; + } + + if (occlusion_state != occlusion_state_) { + occlusion_state_ = occlusion_state; + platform_window_delegate_->OnOcclusionStateChanged(occlusion_state); + } +} + +void X11Window::OnCrossingEvent(bool enter, + bool focus_in_window_or_ancestor, + x11::NotifyMode mode, + x11::NotifyDetail detail) { + // NotifyInferior on a crossing event means the pointer moved into or out of a + // child window, but the pointer is still within |xwindow_|. + if (detail == x11::NotifyDetail::Inferior) { + return; + } + + BeforeActivationStateChanged(); + + if (mode == x11::NotifyMode::Grab) { + has_pointer_grab_ = enter; + } else if (mode == x11::NotifyMode::Ungrab) { + has_pointer_grab_ = false; + } + + has_pointer_ = enter; + if (focus_in_window_or_ancestor && !has_window_focus_) { + // If we reach this point, we know the focus is in an ancestor or the + // pointer root. The definition of |has_pointer_focus_| is (An ancestor + // window or the PointerRoot is focused) && |has_pointer_|. Therefore, we + // can just use |has_pointer_| in the assignment. The transitions for when + // the focus changes are handled in OnFocusEvent(). + has_pointer_focus_ = has_pointer_; + } + + AfterActivationStateChanged(); +} + +void X11Window::OnFocusEvent(bool focus_in, + x11::NotifyMode mode, + x11::NotifyDetail detail) { + // NotifyInferior on a focus event means the focus moved into or out of a + // child window, but the focus is still within |xwindow_|. + if (detail == x11::NotifyDetail::Inferior) { + return; + } + + bool notify_grab = + mode == x11::NotifyMode::Grab || mode == x11::NotifyMode::Ungrab; + + BeforeActivationStateChanged(); + + // For every focus change, the X server sends normal focus events which are + // useful for tracking |has_window_focus_|, but supplements these events with + // NotifyPointer events which are only useful for tracking pointer focus. + + // For |has_pointer_focus_| and |has_window_focus_|, we continue tracking + // state during a grab, but ignore grab/ungrab events themselves. + if (!notify_grab && detail != x11::NotifyDetail::Pointer) { + has_window_focus_ = focus_in; + } + + if (!notify_grab && has_pointer_) { + switch (detail) { + case x11::NotifyDetail::Ancestor: + case x11::NotifyDetail::Virtual: + // If we reach this point, we know |has_pointer_| was true before and + // after this event. Since the definition of |has_pointer_focus_| is + // (An ancestor window or the PointerRoot is focused) && |has_pointer_|, + // we only need to worry about transitions on the first conjunct. + // Therefore, |has_pointer_focus_| will become true when: + // 1. Focus moves from |xwindow_| to an ancestor + // (FocusOut with NotifyAncestor) + // 2. Focus moves from a descendant of |xwindow_| to an ancestor + // (FocusOut with NotifyVirtual) + // |has_pointer_focus_| will become false when: + // 1. Focus moves from an ancestor to |xwindow_| + // (FocusIn with NotifyAncestor) + // 2. Focus moves from an ancestor to a child of |xwindow_| + // (FocusIn with NotifyVirtual) + has_pointer_focus_ = !focus_in; + break; + case x11::NotifyDetail::Pointer: + // The remaining cases for |has_pointer_focus_| becoming true are: + // 3. Focus moves from |xwindow_| to the PointerRoot + // 4. Focus moves from a descendant of |xwindow_| to the PointerRoot + // 5. Focus moves from None to the PointerRoot + // 6. Focus moves from Other to the PointerRoot + // 7. Focus moves from None to an ancestor of |xwindow_| + // 8. Focus moves from Other to an ancestor of |xwindow_| + // In each case, we will get a FocusIn with a detail of NotifyPointer. + // The remaining cases for |has_pointer_focus_| becoming false are: + // 3. Focus moves from the PointerRoot to |xwindow_| + // 4. Focus moves from the PointerRoot to a descendant of |xwindow| + // 5. Focus moves from the PointerRoot to None + // 6. Focus moves from an ancestor of |xwindow_| to None + // 7. Focus moves from the PointerRoot to Other + // 8. Focus moves from an ancestor of |xwindow_| to Other + // In each case, we will get a FocusOut with a detail of NotifyPointer. + has_pointer_focus_ = focus_in; + break; + case x11::NotifyDetail::Nonlinear: + case x11::NotifyDetail::NonlinearVirtual: + // We get Nonlinear(Virtual) events when + // 1. Focus moves from Other to |xwindow_| + // (FocusIn with NotifyNonlinear) + // 2. Focus moves from Other to a descendant of |xwindow_| + // (FocusIn with NotifyNonlinearVirtual) + // 3. Focus moves from |xwindow_| to Other + // (FocusOut with NotifyNonlinear) + // 4. Focus moves from a descendant of |xwindow_| to Other + // (FocusOut with NotifyNonlinearVirtual) + // |has_pointer_focus_| should be false before and after this event. + has_pointer_focus_ = false; + break; + default: + break; + } + } + + ignore_keyboard_input_ = false; + + AfterActivationStateChanged(); +} + +bool X11Window::IsTargetedBy(const x11::Event& xev) const { + return xwindow_ != x11::Window::None && GetWindowForEvent(xev) == xwindow_; +} + +void X11Window::SetTransientWindow(x11::Window window) { + transient_window_ = window; +} + +void X11Window::HandleEvent(const x11::Event& xev) { + if (!IsTargetedBy(xev)) { + return; + } + + // May want to factor CheckXEventForConsistency(xev); into a common location + // since it is called here. + if (auto* crossing = xev.As()) { + bool focus = crossing->same_screen_focus & CROSSING_FLAG_FOCUS; + OnCrossingEvent(crossing->opcode == x11::CrossingEvent::EnterNotify, focus, + crossing->mode, crossing->detail); + } else if (auto* expose = xev.As()) { + gfx::Rect damage_rect_in_pixels(expose->x, expose->y, expose->width, + expose->height); + OnXWindowDamageEvent(damage_rect_in_pixels); + } else if (auto* focus = xev.As()) { + OnFocusEvent(focus->opcode == x11::FocusEvent::In, focus->mode, + focus->detail); + } else if (auto* configure = xev.As()) { + OnConfigureEvent(*configure); + } else if (auto* crossing_input = xev.As()) { + TouchFactory* factory = TouchFactory::GetInstance(); + if (factory->ShouldProcessCrossingEvent(*crossing_input)) { + auto mode = XI2ModeToXMode(crossing_input->mode); + auto detail = XI2DetailToXDetail(crossing_input->detail); + switch (crossing_input->opcode) { + case x11::Input::CrossingEvent::Enter: + OnCrossingEvent(true, crossing_input->focus, mode, detail); + break; + case x11::Input::CrossingEvent::Leave: + OnCrossingEvent(false, crossing_input->focus, mode, detail); + break; + case x11::Input::CrossingEvent::FocusIn: + OnFocusEvent(true, mode, detail); + break; + case x11::Input::CrossingEvent::FocusOut: + OnFocusEvent(false, mode, detail); + break; + } + } + } else if (xev.As()) { + OnWindowMapped(); + } else if (xev.As()) { + window_mapped_in_server_ = false; + has_pointer_ = false; + has_pointer_grab_ = false; + has_pointer_focus_ = false; + has_window_focus_ = false; + } else if (auto* client = xev.As()) { + x11::Atom message_type = client->type; + if (message_type == x11::GetAtom("WM_PROTOCOLS")) { + x11::Atom protocol = static_cast(client->data.data32[0]); + if (protocol == x11::GetAtom("WM_DELETE_WINDOW")) { + // We have received a close message from the window manager. + OnXWindowCloseRequested(); + } else if (protocol == x11::GetAtom("_NET_WM_PING")) { + x11::ClientMessageEvent reply_event = *client; + reply_event.window = x_root_window_; + connection_->SendEvent(reply_event, x_root_window_, + x11::EventMask::SubstructureNotify | + x11::EventMask::SubstructureRedirect); + } else if (protocol == x11::GetAtom("_NET_WM_SYNC_REQUEST")) { + configure_counter_value_.reset(); + const int32_t hi = static_cast(client->data.data32[3]); + const uint32_t lo = client->data.data32[2]; + // The spec says the WM should never send a counter value of 0, so + // ignore it if it does. + if (hi || lo) { + configure_counter_value_ = x11::Sync::Int64{.hi = hi, .lo = lo}; + } + } + } else { + OnXWindowDragDropEvent(*client); + } + } else if (auto* property = xev.As()) { + x11::Atom changed_atom = property->atom; + if (changed_atom == x11::GetAtom("_NET_WM_STATE")) { + OnWMStateUpdated(); + } else if (changed_atom == x11::GetAtom("_NET_FRAME_EXTENTS")) { + OnFrameExtentsUpdated(); + } else if (changed_atom == x11::GetAtom("_NET_WM_DESKTOP")) { + OnWorkspaceUpdated(); + } + } else if (auto* selection = xev.As()) { + OnXWindowSelectionEvent(*selection); + } else if (auto* visibility = xev.As()) { + is_occluded_ = visibility->state == x11::Visibility::FullyObscured; + MaybeUpdateOcclusionState(); + } +} + +void X11Window::UpdateWMUserTime(Event* event) { + if (!IsActive()) { + return; + } + DCHECK(event); + EventType type = event->type(); + if (type == EventType::kMousePressed || type == EventType::kKeyPressed || + type == EventType::kTouchPressed) { + connection_->SetProperty(xwindow_, x11::GetAtom("_NET_WM_USER_TIME"), + x11::Atom::CARDINAL, + X11EventSource::GetInstance()->GetTimestamp()); + } +} + +void X11Window::OnWindowMapped() { + window_mapped_in_server_ = true; + // Some WMs only respect maximize hints after the window has been mapped. + // Check whether we need to re-do a maximization. + if (should_maximize_after_map_) { + Maximize(); + should_maximize_after_map_ = false; + } + if (should_grab_pointer_after_map_) { + has_pointer_grab_ |= + (ui::GrabPointer(xwindow_, true, nullptr) == x11::GrabStatus::Success); + should_grab_pointer_after_map_ = false; + } +} + +void X11Window::OnConfigureEvent(const x11::ConfigureNotifyEvent& configure) { + DCHECK_EQ(xwindow_, configure.window); + + if (configure_counter_value_ && !last_configure_size_) { + last_configure_size_ = gfx::Size(configure.width, configure.height); + MaybeUpdateSyncCounter(); + } +} + +void X11Window::SetWMSpecState(bool enabled, + x11::Atom state1, + x11::Atom state2) { + if (window_mapped_in_client_) { + ui::SetWMSpecState(xwindow_, enabled, state1, state2); + } else { + // The updated state will be set when the window is (re)mapped. + base::flat_set new_window_properties = window_properties_; + for (x11::Atom atom : {state1, state2}) { + if (enabled) { + new_window_properties.insert(atom); + } else { + new_window_properties.erase(atom); + } + } + UpdateWindowProperties(new_window_properties); + } +} + +void X11Window::OnWMStateUpdated() { + // The EWMH spec requires window managers to remove the _NET_WM_STATE property + // when a window is unmapped. However, Chromium code wants the state to + // persist across a Hide() and Show(). So if the window is currently + // unmapped, leave the state unchanged so it will be restored when the window + // is remapped. + std::vector atom_list; + if (connection_->GetArrayProperty(xwindow_, x11::GetAtom("_NET_WM_STATE"), + &atom_list) || + window_mapped_in_client_) { + UpdateWindowProperties( + base::flat_set(std::begin(atom_list), std::end(atom_list))); + } +} + +WindowTiledEdges X11Window::GetTiledState() const { + const bool vert = HasWMSpecProperty( + window_properties_, x11::GetAtom("_NET_WM_STATE_MAXIMIZED_VERT")); + const bool horz = HasWMSpecProperty( + window_properties_, x11::GetAtom("_NET_WM_STATE_MAXIMIZED_HORZ")); + return WindowTiledEdges{vert, vert, horz, horz}; +} + +void X11Window::UpdateWindowProperties( + const base::flat_set& new_window_properties) { + // If the window is hidden, ignore new properties. + // See https://crbug.com/1260832 + if (!window_mapped_in_client_) { + return; + } + + window_properties_ = new_window_properties; + + // Ignore requests by the window manager to enter or exit fullscreen (e.g. as + // a result of pressing a window manager accelerator key). Chrome does not + // handle window manager initiated fullscreen. In particular, Chrome needs to + // do preprocessing before the x window's fullscreen state is toggled. + + is_always_on_top_ = HasWMSpecProperty(window_properties_, + x11::GetAtom("_NET_WM_STATE_ABOVE")); + OnXWindowStateChanged(); + MaybeUpdateOcclusionState(); + ResetWindowRegion(); +} + +void X11Window::OnFrameExtentsUpdated() { + std::vector insets; + if (connection_->GetArrayProperty( + xwindow_, x11::GetAtom("_NET_FRAME_EXTENTS"), &insets) && + insets.size() == 4) { + // |insets| are returned in the order: [left, right, top, bottom]. + native_window_frame_borders_in_pixels_ = + gfx::Insets::TLBR(insets[2], insets[0], insets[3], insets[1]); + } else { + native_window_frame_borders_in_pixels_ = gfx::Insets(); + } +} + +void X11Window::DispatchResize(bool origin_changed) { + last_swapped_size_.reset(); + if (configure_counter_value_) { + // WM handles resize throttling. No need to delay resize events. + DelayedResize(origin_changed); + } else { + // Debounce resize events to avoid falling behind. + delayed_resize_task_.Reset(base::BindOnce( + &X11Window::DelayedResize, base::Unretained(this), origin_changed)); + base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask( + FROM_HERE, delayed_resize_task_.callback()); + return; + } +} + +void X11Window::DelayedResize(bool origin_changed) { + CancelResize(); + NotifyBoundsChanged(/*origin changed=*/origin_changed); + + // No more member accesses here: bounds change propagation may have deleted + // |this| (e.g. when a chrome window is snapped into a tab strip. Further + // details at crbug.com/1068755). +} + +void X11Window::CancelResize() { + delayed_resize_task_.Cancel(); +} + +void X11Window::UnconfineCursor() { + if (!has_pointer_barriers_) { + return; + } + + for (auto pointer_barrier : pointer_barriers_) { + connection_->xfixes().DeletePointerBarrier({pointer_barrier}); + } + + pointer_barriers_.fill({}); + + has_pointer_barriers_ = false; +} + +void X11Window::UpdateWindowRegion( + std::unique_ptr> region) { + auto set_shape = [&](const std::vector& rectangles) { + connection_->shape().Rectangles(x11::Shape::RectanglesRequest{ + .operation = x11::Shape::So::Set, + .destination_kind = x11::Shape::Sk::Bounding, + .ordering = x11::ClipOrdering::YXBanded, + .destination_window = xwindow_, + .rectangles = rectangles, + }); + }; + + // If a custom window shape was supplied then apply it. + if (custom_window_shape_) { + set_shape(*window_shape_); + return; + } + + window_shape_ = std::move(region); + if (window_shape_) { + set_shape(*window_shape_); + return; + } + + // If we didn't set the shape for any reason, reset the shaping information. + // How this is done depends on the border style, due to quirks and bugs in + // various window managers. + if (use_native_frame_) { + // If the window has system borders, the mask must be set to null (not a + // rectangle), because several window managers (eg, KDE, XFCE, XMonad) will + // not put borders on a window with a custom shape. + connection_->shape().Mask(x11::Shape::MaskRequest{ + .operation = x11::Shape::So::Set, + .destination_kind = x11::Shape::Sk::Bounding, + .destination_window = xwindow_, + .source_bitmap = x11::Pixmap::None, + }); + } +} + +void X11Window::NotifyBoundsChanged(bool origin_changed) { + ResetWindowRegion(); + platform_window_delegate_->OnBoundsChanged({origin_changed}); +} + +bool X11Window::InitializeAsStatusIcon() { + std::string atom_name = "_NET_SYSTEM_TRAY_S" + + base::NumberToString(connection_->DefaultScreenId()); + auto reply = + connection_->GetSelectionOwner({x11::GetAtom(atom_name.c_str())}).Sync(); + if (!reply || reply->owner == x11::Window::None) { + return false; + } + auto manager = reply->owner; + + connection_->SetArrayProperty( + xwindow_, x11::GetAtom("_XEMBED_INFO"), x11::Atom::CARDINAL, + std::vector{kXembedInfoProtocolVersion, kXembedInfoFlags}); + + x11::ChangeWindowAttributesRequest req{xwindow_}; + if (visual_has_alpha_) { + req.background_pixel = 0; + } else { + connection_->SetProperty(xwindow_, + x11::GetAtom("CHROMIUM_COMPOSITE_WINDOW"), + x11::Atom::CARDINAL, static_cast(1)); + req.background_pixmap = + static_cast(x11::BackPixmap::ParentRelative); + } + connection_->ChangeWindowAttributes(req); + + auto future = SendClientMessage( + manager, manager, x11::GetAtom("_NET_SYSTEM_TRAY_OPCODE"), + {static_cast(X11EventSource::GetInstance()->GetTimestamp()), + kSystemTrayRequestDock, static_cast(xwindow_), 0, 0}, + x11::EventMask::NoEvent); + return !future.Sync().error; +} + +void X11Window::SetBoundsWithWmSync(const gfx::Rect& bounds_px) { + last_set_bounds_px_ = bounds_px; + // Unretained is safe since we own `bounds_wm_sync_`. + bounds_wm_sync_ = std::make_unique( + &*connection_, + base::BindOnce(&X11Window::OnWmSynced, base::Unretained(this))); +} + +void X11Window::OnWmSynced() { + bounds_wm_sync_.reset(); + OnBoundsChanged(last_set_bounds_px_, GetBoundsInPixels()); +} + +void X11Window::OnBoundsChanged(const std::optional& old_bounds_px, + const gfx::Rect& new_bounds_px) { + const bool size_changed = !old_bounds_px.has_value() || + old_bounds_px->size() != new_bounds_px.size(); + const bool origin_changed = !old_bounds_px.has_value() || + old_bounds_px->origin() != new_bounds_px.origin(); + + if (size_changed) { + DispatchResize(origin_changed); + } else if (origin_changed) { + NotifyBoundsChanged(/*origin changed=*/true); + } +} + +void X11Window::MaybeUpdateSyncCounter() { + if (last_configure_size_ == last_swapped_size_) { + connection_->sync().SetCounter(update_counter_, *configure_counter_value_); + configure_counter_value_.reset(); + last_configure_size_.reset(); + } +} + +} // namespace ui diff --git a/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/x11_window.h b/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/x11_window.h new file mode 100644 index 0000000..f744189 --- /dev/null +++ b/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/x11_window.h @@ -0,0 +1,521 @@ +// Copyright 2014 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_OZONE_PLATFORM_X11_X11_WINDOW_H_ +#define UI_OZONE_PLATFORM_X11_X11_WINDOW_H_ + +#include +#include +#include +#include + +#include "base/cancelable_callback.h" +#include "base/containers/flat_set.h" +#include "base/gtest_prod_util.h" +#include "base/memory/raw_ptr.h" +#include "base/memory/raw_ref.h" +#include "ui/base/dragdrop/mojom/drag_drop_types.mojom-forward.h" +#include "ui/base/x/x11_desktop_window_move_client.h" +#include "ui/base/x/x11_drag_drop_client.h" +#include "ui/base/x/x11_move_loop_delegate.h" +#include "ui/events/platform/platform_event_dispatcher.h" +#include "ui/gfx/geometry/insets.h" +#include "ui/gfx/x/connection.h" +#include "ui/gfx/x/event.h" +#include "ui/gfx/x/sync.h" +#include "ui/gfx/x/xfixes.h" +#include "ui/gfx/x/xproto.h" +#include "ui/platform_window/extensions/workspace_extension.h" +#include "ui/platform_window/extensions/x11_extension.h" +#include "ui/platform_window/platform_window.h" +#include "ui/platform_window/platform_window_init_properties.h" +#include "ui/platform_window/wm/wm_drag_handler.h" +#include "ui/platform_window/wm/wm_move_loop_handler.h" +#include "ui/platform_window/wm/wm_move_resize_handler.h" + +class SkPath; + +namespace x11 { +class GeometryCache; +class WmSync; +} // namespace x11 + +namespace ui { + +class PlatformWindowDelegate; +class X11ExtensionDelegate; +class X11MoveLoop; +class WorkspaceExtensionDelegate; + +// PlatformWindow implementation for X11. +class X11Window : public PlatformWindow, + public WmMoveResizeHandler, + public PlatformEventDispatcher, + public x11::EventObserver, + public WorkspaceExtension, + public X11Extension, + public WmDragHandler, + public XDragDropClient::Delegate, + public X11MoveLoopDelegate, + public WmMoveLoopHandler, + public X11DesktopWindowMoveClient::Delegate { + public: + explicit X11Window(PlatformWindowDelegate* platform_window_delegate); + + X11Window(const X11Window&) = delete; + X11Window& operator=(const X11Window&) = delete; + + ~X11Window() override; + + virtual void Initialize(PlatformWindowInitProperties properties); + + // X11WindowManager calls this. + void OnXWindowLostCapture(); + + void OnCursorUpdate(); + + gfx::AcceleratedWidget GetWidget() const; + gfx::Rect GetOuterBounds() const; + void SetTransientWindow(x11::Window window); + + bool has_pointer() const { return has_pointer_; } + + // PlatformWindow: + void Show(bool inactive) override; + void Hide() override; + void Close() override; + bool IsVisible() const override; + void PrepareForShutdown() override; + void SetBoundsInPixels(const gfx::Rect& bounds) override; + gfx::Rect GetBoundsInPixels() const override; + void SetBoundsInDIP(const gfx::Rect& bounds) override; + gfx::Rect GetBoundsInDIP() const override; + void SetTitle(const std::u16string& title) override; + void SetCapture() override; + void ReleaseCapture() override; + bool HasCapture() const override; + void SetFullscreen(bool fullscreen, int64_t target_display_id) override; + void Maximize() override; + void Minimize() override; + void Restore() override; + void ShowWindowControlsMenu(const gfx::Point& point) override; + PlatformWindowState GetPlatformWindowState() const override; + void Activate() override; + void Deactivate() override; + void SetUseNativeFrame(bool use_native_frame) override; + bool ShouldUseNativeFrame() const override; + void SetCursor(scoped_refptr cursor) override; + void MoveCursorTo(const gfx::Point& location) override; + void ConfineCursorToBounds(const gfx::Rect& bounds) override; + void SetRestoredBoundsInDIP(const gfx::Rect& bounds) final; + gfx::Rect GetRestoredBoundsInDIP() const final; + bool ShouldWindowContentsBeTransparent() const override; + void SetZOrderLevel(ZOrderLevel order) override; + ZOrderLevel GetZOrderLevel() const override; + void StackAbove(gfx::AcceleratedWidget widget) override; + void StackAtTop() override; + void FlashFrame(bool flash_frame) override; + void SetShape(std::unique_ptr native_shape, + const gfx::Transform& transform) override; + void SetAspectRatio(const gfx::SizeF& aspect_ratio) override; + void SetWindowIcons(const gfx::ImageSkia& window_icon, + const gfx::ImageSkia& app_icon) override; + void SizeConstraintsChanged() override; + void SetOpacity(float opacity) override; + bool CanSetDecorationInsets() const override; + void SetOpaqueRegion( + std::optional> region_px) override; + void SetInputRegion(std::optional> region_px) override; + void NotifyStartupComplete(const std::string& startup_id) override; + + // WorkspaceExtension: + std::string GetWorkspace() const override; + void SetVisibleOnAllWorkspaces(bool always_visible) override; + bool IsVisibleOnAllWorkspaces() const override; + void SetWorkspaceExtensionDelegate( + WorkspaceExtensionDelegate* delegate) override; + + // X11Extension: + bool IsSyncExtensionAvailable() const override; + bool IsWmTiling() const override; + void OnCompleteSwapAfterResize(const gfx::Size& new_size) override; + gfx::Rect GetXRootWindowOuterBounds() const override; + void LowerXWindow() override; + void SetOverrideRedirect(bool override_redirect) override; + bool CanResetOverrideRedirect() const override; + void SetX11ExtensionDelegate(X11ExtensionDelegate* delegate) override; + bool IsWmSyncActiveForTest() override; + + // x11::EventObserver: + void OnEvent(const x11::Event& event) override; + + protected: + PlatformWindowDelegate* platform_window_delegate() const { + return platform_window_delegate_; + } + + void OnXWindowStateChanged(); + void OnXWindowDamageEvent(const gfx::Rect& damage_rect); + void OnXWindowCloseRequested(); + void OnXWindowIsActiveChanged(bool active); + void OnXWindowWorkspaceChanged(); + void OnXWindowLostPointerGrab(); + void OnXWindowSelectionEvent(const x11::SelectionNotifyEvent& xev); + void OnXWindowDragDropEvent(const x11::ClientMessageEvent& xev); + std::optional GetMinimumSizeForXWindow(); + std::optional GetMaximumSizeForXWindow(); + SkPath GetWindowMaskForXWindow(); + + private: + FRIEND_TEST_ALL_PREFIXES(X11WindowTest, Shape); + FRIEND_TEST_ALL_PREFIXES(X11WindowTest, WindowManagerTogglesFullscreen); + FRIEND_TEST_ALL_PREFIXES(X11WindowTest, + ToggleMinimizePropogateToPlatformWindowDelegate); + + void UpdateDecorationInsets(); + + // PlatformEventDispatcher: + bool CanDispatchEvent(const PlatformEvent& event) override; + uint32_t DispatchEvent(const PlatformEvent& event) override; + + void DispatchUiEvent(ui::Event* event, const x11::Event& xev); + + // WmMoveResizeHandler + void DispatchHostWindowDragMovement( + int hittest, + const gfx::Point& pointer_location_in_px) override; + + // WmMoveLoopHandler: + bool RunMoveLoop(const gfx::Vector2d& drag_offset) override; + void EndMoveLoop() override; + + // WmDragHandler: + bool StartDrag(const OSExchangeData& data, + int operations, + mojom::DragEventSource source, + gfx::NativeCursor cursor, + bool can_grab_pointer, + base::OnceClosure drag_started_callback, + WmDragHandler::DragFinishedCallback drag_finished_callback, + WmDragHandler::LocationDelegate* delegate) override; + void CancelDrag() override; + void UpdateDragImage(const gfx::ImageSkia& image, + const gfx::Vector2d& offset) override; + + // XDragDropClient::Delegate + std::optional GetDragWidget() override; + int UpdateDrag(const gfx::Point& screen_point) override; + void UpdateCursor(mojom::DragOperation negotiated_operation) override; + void OnBeginForeignDrag(x11::Window window) override; + void OnEndForeignDrag() override; + void OnBeforeDragLeave() override; + mojom::DragOperation PerformDrop() override; + void EndDragLoop() override; + + // X11MoveLoopDelegate + void OnMouseMovement(const gfx::Point& screen_point, + int flags, + base::TimeTicks event_time) override; + void OnMouseReleased() override; + void OnMoveLoopEnded() override; + + // X11DesktopWindowMoveClient::Delegate: + void SetBoundsOnMove(const gfx::Rect& requested_bounds) override; + scoped_refptr GetLastCursor() override; + gfx::Size GetSize() override; + + void QuitDragLoop(); + + // Handles `event` as an Atk Key Event + bool HandleAsAtkEvent(const x11::Event& event); + + // Adjusts |requested_size_in_pixels| to avoid the WM "feature" where setting + // the window size to the monitor size causes the WM to set the EWMH for + // fullscreen. + gfx::Size AdjustSizeForDisplay(const gfx::Size& requested_size_in_pixels); + + // Creates the X window with the given properties. + // Depending on presence of the compositing manager and window type, may + // change the opacity, in which case returns the final opacity type through + // |opacity|. + void CreateXWindow(const PlatformWindowInitProperties& properties); + void CloseXWindow(); + void Map(bool inactive = false); + void SetWMStateFullscreen(bool fullscreen); + void SetWMStateMaximize(bool maximize); + bool IsActive() const; + bool IsTargetedBy(const x11::Event& xev) const; + void HandleEvent(const x11::Event& xev); + + bool IsMinimized() const; + bool IsMaximized() const; + bool IsFullscreen() const; + + void SetFlashFrameHint(bool flash_frame); + void UpdateMinAndMaxSize(); + void DispatchResize(bool origin_changed); + void CancelResize(); + + // Resets the window region for the current window bounds if necessary. + void ResetWindowRegion(); + + x11::Window window() const { return xwindow_; } + x11::Window root_window() const { return x_root_window_; } + std::vector* shape() const { return window_shape_.get(); } + + // Updates |xwindow_|'s _NET_WM_USER_TIME if |xwindow_| is active. + void UpdateWMUserTime(ui::Event* event); + + // Called on an XFocusInEvent, XFocusOutEvent, XIFocusInEvent, or an + // XIFocusOutEvent. + void OnFocusEvent(bool focus_in, + x11::NotifyMode mode, + x11::NotifyDetail detail); + + // Called on an XEnterWindowEvent, XLeaveWindowEvent, XIEnterEvent, or an + // XILeaveEvent. + void OnCrossingEvent(bool enter, + bool focus_in_window_or_ancestor, + x11::NotifyMode mode, + x11::NotifyDetail detail); + + // Called when |xwindow_|'s _NET_WM_STATE property is updated. + void OnWMStateUpdated(); + + WindowTiledEdges GetTiledState() const; + + // Called when |xwindow_|'s _NET_FRAME_EXTENTS property is updated. + void OnFrameExtentsUpdated(); + + void OnConfigureEvent(const x11::ConfigureNotifyEvent& event); + + void OnWorkspaceUpdated(); + + void OnWindowMapped(); + + // Record the activation state. + void BeforeActivationStateChanged(); + + // Handle the state change since BeforeActivationStateChanged(). + void AfterActivationStateChanged(); + + void MaybeUpdateOcclusionState(); + + void DelayedResize(bool origin_changed); + + // If mapped, sends a message to the window manager to enable or disable the + // states |state1| and |state2|. Otherwise, the states will be enabled or + // disabled on the next map. It's the caller's responsibility to make sure + // atoms are set and unset in the appropriate pairs. For example, if a caller + // sets (_NET_WM_STATE_MAXIMIZED_VERT, _NET_WM_STATE_MAXIMIZED_HORZ), it would + // be invalid to unset the maximized state by making two calls like + // (_NET_WM_STATE_MAXIMIZED_VERT, x11::None), (_NET_WM_STATE_MAXIMIZED_HORZ, + // x11::None). + void SetWMSpecState(bool enabled, x11::Atom state1, x11::Atom state2); + + // Updates |window_properties_| with |new_window_properties|. + void UpdateWindowProperties( + const base::flat_set& new_window_properties); + + void UnconfineCursor(); + + void UpdateWindowRegion(std::unique_ptr> region); + + void NotifyBoundsChanged(bool origin_changed); + + // Initializes as a status icon window. + bool InitializeAsStatusIcon(); + + void SetBoundsWithWmSync(const gfx::Rect& bounds_px); + + void OnWmSynced(); + + void OnBoundsChanged(const std::optional& old_bounds_px, + const gfx::Rect& new_bounds_px); + + void MaybeUpdateSyncCounter(); + + // Stores current state of this window. + PlatformWindowState state_ = PlatformWindowState::kUnknown; + + WindowTiledEdges tiled_state_; + + const raw_ptr platform_window_delegate_; + + raw_ptr + workspace_extension_delegate_ = nullptr; + + raw_ptr x11_extension_delegate_ = + nullptr; + + // Tells if the window got a ::Close call. + bool is_shutting_down_ = false; + + // The z-order level of the window; the window exhibits "always on top" + // behavior if > 0. + ui::ZOrderLevel z_order_ = ui::ZOrderLevel::kNormal; + + // The bounds of our window before the window was maximized. + gfx::Rect restored_bounds_in_pixels_; + + std::unique_ptr x11_window_move_client_; + + // Whether the drop handler has notified that the drag has entered. + bool notified_enter_ = false; + // Keeps the last negotiated operations returned by the drop handler. + int allowed_drag_operations_ = 0; + + // Handles XDND events going through this window. + std::unique_ptr drag_drop_client_; + WmDragHandler::DragFinishedCallback drag_finished_callback_; + raw_ptr + drag_location_delegate_ = nullptr; + + // Run loop used while dragging from this window. + std::unique_ptr drag_loop_; + + // Events that we have selected on the source window of the incoming drag. + x11::ScopedEventSelector source_window_events_; + + // The display and the native X window hosting the root window. + const raw_ref connection_; + x11::Window xwindow_ = x11::Window::None; + x11::Window x_root_window_ = x11::Window::None; + + // Any native, modal dialog hanging from this window. + x11::Window transient_window_ = x11::Window::None; + + // Events selected on |xwindow_|. + x11::ScopedEventSelector xwindow_events_; + + // The window manager state bits. + base::flat_set window_properties_; + + // Is this window able to receive focus? + bool activatable_ = true; + + // Was this window initialized with the override_redirect window attribute? + bool override_redirect_ = false; + + std::optional window_title_; + + // Whether the window is visible with respect to Aura. + bool window_mapped_in_client_ = false; + + // Whether the window is mapped with respect to the X server. + bool window_mapped_in_server_ = false; + + // The bounds of `xwindow_`. If `bounds_wm_sync_` is active, then + // `last_set_bounds_px_` should be treated as the current bounds. Otherwise, + // the bounds from `geometry_cache_` should be used. + gfx::Rect last_set_bounds_px_; + std::unique_ptr bounds_wm_sync_; + std::unique_ptr geometry_cache_; + + x11::VisualId visual_id_{}; + + // Whether we used an ARGB visual for our window. + bool visual_has_alpha_ = false; + + // The workspace containing |xwindow_|. This will be std::nullopt when + // _NET_WM_DESKTOP is unset. + std::optional workspace_; + + // True if the window should stay on top of most other windows. + bool is_always_on_top_ = false; + + // True if the window is security-sensitive. Implies |is_always_on_top_|. + bool is_security_surface_ = false; + + // True if the window is fully obscured by another window. + bool is_occluded_ = false; + + PlatformWindowOcclusionState occlusion_state_ = + PlatformWindowOcclusionState::kUnknown; + + // Does |xwindow_| have the pointer grab (XI2 or normal)? + bool has_pointer_grab_ = false; + + // The focus-tracking state variables are as described in + // gtk/docs/focus_tracking.txt + // + // |xwindow_| is active iff: + // (|has_window_focus_| || |has_pointer_focus_|) && + // !|ignore_keyboard_input_| + + // Is the pointer in |xwindow_| or one of its children? + bool has_pointer_ = false; + + // Is |xwindow_| or one of its children focused? + bool has_window_focus_ = false; + + // (An ancestor window or the PointerRoot is focused) && |has_pointer_|. + // |has_pointer_focus_| == true is the odd case where we will receive keyboard + // input when |has_window_focus_| == false. |has_window_focus_| and + // |has_pointer_focus_| are mutually exclusive. + bool has_pointer_focus_ = false; + + // X11 does not support defocusing windows; you can only focus a different + // window. If we would like to be defocused, we just ignore keyboard input we + // no longer care about. + bool ignore_keyboard_input_ = false; + + // Used for tracking activation state in {Before|After}ActivationStateChanged. + bool was_active_ = false; + bool had_pointer_ = false; + bool had_pointer_grab_ = false; + bool had_window_focus_ = false; + + // True if a Maximize() call should be done after mapping the window. + bool should_maximize_after_map_ = false; + + // True if GrabPointer() should be called after mapping the window. + bool should_grab_pointer_after_map_ = false; + + // Whether we currently are flashing our frame. This feature is implemented + // by setting the urgency hint with the window manager, which can draw + // attention to the window or completely ignore the hint. We stop flashing + // the frame when |xwindow_| gains focus or handles a mouse button event. + bool urgency_hint_set_ = false; + + // |xwindow_|'s minimum size. + gfx::Size min_size_in_pixels_; + + // |xwindow_|'s maximum size. + gfx::Size max_size_in_pixels_; + + // The window shape if the window is non-rectangular. + std::unique_ptr> window_shape_; + + // Whether |window_shape_| was set via SetShape(). + bool custom_window_shape_ = false; + + // True if the window has title-bar / borders provided by the window manager. + bool use_native_frame_ = false; + + // The size of the window manager provided borders (if any). + gfx::Insets native_window_frame_borders_in_pixels_; + + // Used for synchronizing between `xwindow_` and the WM during resizing. + x11::Sync::Counter update_counter_{}; + std::optional configure_counter_value_; + std::optional last_configure_size_; + std::optional last_swapped_size_; + + base::CancelableOnceClosure delayed_resize_task_; + + // Keep track of barriers to confine cursor. + bool has_pointer_barriers_ = false; + std::array pointer_barriers_; + + scoped_refptr last_cursor_; + + base::CancelableOnceCallback on_cursor_loaded_; + + base::WeakPtrFactory weak_ptr_factory_{this}; +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_X11_X11_WINDOW_H_ diff --git a/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/x11_window_manager.cc b/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/x11_window_manager.cc new file mode 100644 index 0000000..1cc302f --- /dev/null +++ b/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/x11_window_manager.cc @@ -0,0 +1,101 @@ +// Copyright 2019 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/ozone/platform/x11/x11_window_manager.h" + +#include "ui/ozone/platform/x11/x11_window.h" + +namespace ui { + +namespace { + +X11WindowManager* g_instance = nullptr; + +} // namespace + +X11WindowManager::X11WindowManager() { + DCHECK(!g_instance) << "There should only be a single X11WindowManager"; + g_instance = this; +} + +X11WindowManager::~X11WindowManager() = default; + +// static +X11WindowManager* X11WindowManager::GetInstance() { + if (!g_instance) { + auto manager = std::make_unique(); + X11WindowManager* manager_ptr = manager.release(); + DCHECK_EQ(g_instance, manager_ptr); + } + return g_instance; +} + +void X11WindowManager::GrabEvents(X11Window* window) { + DCHECK_NE(located_events_grabber_, window); + + // Grabbing the mouse is asynchronous. However, we synchronously start + // forwarding all mouse events received by Chrome to the + // aura::WindowEventDispatcher which has capture. This makes capture + // synchronous for all intents and purposes if either: + // - |located_events_grabber_| is set to have capture. + // OR + // - The topmost window underneath the mouse is managed by Chrome. + auto* old_grabber = located_events_grabber_.get(); + + // Update |located_events_grabber_| prior to calling OnXWindowLostCapture() to + // avoid releasing pointer grab. + located_events_grabber_ = window; + if (old_grabber) + old_grabber->OnXWindowLostCapture(); + + // the X11Window calls GrabPointer by itself. +} + +void X11WindowManager::UngrabEvents(X11Window* window) { + DCHECK_EQ(located_events_grabber_, window); + // Release mouse grab asynchronously. A window managed by Chrome is likely + // the topmost window underneath the mouse so the capture release being + // asynchronous is likely inconsequential. + auto* old_grabber = located_events_grabber_.get(); + located_events_grabber_ = nullptr; + old_grabber->OnXWindowLostCapture(); +} + +void X11WindowManager::AddWindow(X11Window* window) { + DCHECK(window); + auto widget = window->GetWidget(); + DCHECK_NE(gfx::kNullAcceleratedWidget, widget); + DCHECK(!windows_.contains(widget)); + windows_.emplace(widget, window); +} + +void X11WindowManager::RemoveWindow(X11Window* window) { + DCHECK(window); + auto widget = window->GetWidget(); + auto it = windows_.find(widget); + // The XWindow might not have been initialized due to some errors. + if (widget == gfx::kNullAcceleratedWidget) { + DCHECK(it == windows_.end()); + } else { + CHECK(it != windows_.end()); + if (window_mouse_currently_on_ == it->second) + window_mouse_currently_on_ = nullptr; + windows_.erase(it); + } +} + +X11Window* X11WindowManager::GetWindow(gfx::AcceleratedWidget widget) const { + auto it = windows_.find(widget); + return it != windows_.end() ? it->second : nullptr; +} + +void X11WindowManager::MouseOnWindow(X11Window* window) { + if (window_mouse_currently_on_ == window) + return; + + window_mouse_currently_on_ = window; + window->OnCursorUpdate(); +} + +} // namespace ui diff --git a/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/x11_window_manager.h b/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/x11_window_manager.h new file mode 100644 index 0000000..32e02fe --- /dev/null +++ b/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/platform/x11/x11_window_manager.h @@ -0,0 +1,61 @@ +// Copyright 2019 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_OZONE_PLATFORM_X11_X11_WINDOW_MANAGER_H_ +#define UI_OZONE_PLATFORM_X11_X11_WINDOW_MANAGER_H_ + +#include "base/containers/flat_map.h" +#include "base/memory/raw_ptr.h" +#include "ui/gfx/native_ui_types.h" + +namespace ui { + +class X11Window; + +class X11WindowManager { + public: + X11WindowManager(); + + X11WindowManager(const X11WindowManager&) = delete; + X11WindowManager& operator=(const X11WindowManager&) = delete; + + ~X11WindowManager(); + + // Returns instance of X11WindowManager. + static X11WindowManager* GetInstance(); + + // Sets a given X11Window as the recipient for events and calls + // OnLostCapture for another |located_events_grabber_| if it has been set + // previously. + void GrabEvents(X11Window* window); + + // Unsets a given X11Window as the recipient for events and calls + // OnLostCapture. + void UngrabEvents(X11Window* window); + + // Gets the current X11PlatformWindow recipient of mouse events. + X11Window* located_events_grabber() const { return located_events_grabber_; } + + // Gets the window corresponding to the AcceleratedWidget |widget|. + void AddWindow(X11Window* window); + void RemoveWindow(X11Window* window); + X11Window* GetWindow(gfx::AcceleratedWidget widget) const; + + void MouseOnWindow(X11Window* delegate); + + const X11Window* window_mouse_currently_on_for_test() const { + return window_mouse_currently_on_; + } + + private: + raw_ptr located_events_grabber_ = nullptr; + raw_ptr window_mouse_currently_on_ = nullptr; + + base::flat_map> + windows_; +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_X11_X11_WINDOW_MANAGER_H_ diff --git a/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/public/overlay_manager_ozone.h b/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/public/overlay_manager_ozone.h new file mode 100644 index 0000000..08e6060 --- /dev/null +++ b/phase0_evidence/chromium_ozone_x11_2026-05-03/ui/ozone/public/overlay_manager_ozone.h @@ -0,0 +1,46 @@ +// Copyright 2015 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_OZONE_PUBLIC_OVERLAY_MANAGER_OZONE_H_ +#define UI_OZONE_PUBLIC_OVERLAY_MANAGER_OZONE_H_ + +#include + +#include "ui/gfx/native_ui_types.h" + +namespace ui { + +class OverlayCandidatesOzone; + +// Responsible for providing the oracles used to decide when overlays can be +// used. +class OverlayManagerOzone { + public: + virtual ~OverlayManagerOzone() {} + + // Get the hal struct to check for overlay support. + virtual std::unique_ptr CreateOverlayCandidates( + gfx::AcceleratedWidget w) = 0; + + bool allow_sync_and_real_buffer_page_flip_testing() const { + return allow_sync_and_real_buffer_page_flip_testing_; + } + + // Tell the manager that the overlay delegation is enabled. This is only + // useful for Wayland as checking for overlay support depends on + // features::IsDelegatedCompositingEnabled, which cannot be accessed from + // //ui/ozone. + // TODO(msisov, petermcneeley): remove this once Wayland uses only delegated + // context. + virtual void SetContextDelegated() {} + + protected: + // TODO(fangzhoug): Some Chrome OS boards still use the legacy video decoder. + // Remove this once ChromeOSVideoDecoder is on everywhere. + bool allow_sync_and_real_buffer_page_flip_testing_ = false; +}; + +} // namespace ui + +#endif // UI_OZONE_PUBLIC_OVERLAY_MANAGER_OZONE_H_ diff --git a/phase0_evidence/x11_inventory_2026-05-03/entry2.added.list b/phase0_evidence/x11_inventory_2026-05-03/entry2.added.list new file mode 100644 index 0000000..088c2f9 --- /dev/null +++ b/phase0_evidence/x11_inventory_2026-05-03/entry2.added.list @@ -0,0 +1,70 @@ +dbus-glib +elementary-icon-theme +exo +garcon +gnome-themes-extra +gtk-layer-shell +gtksourceview4 +libburn +libgtop +libisofs +libkeybinder3 +libmpd +libwnck3 +libxfce4ui +libxfce4util +libxfce4windowing +libxklavier +libxres +mousepad +parole +polkit-gnome +ristretto +thunar +thunar-archive-plugin +thunar-media-tags-plugin +thunar-volman +tumbler +xfburn +xfce4-appfinder +xfce4-battery-plugin +xfce4-clipman-plugin +xfce4-cpufreq-plugin +xfce4-cpugraph-plugin +xfce4-dict +xfce4-diskperf-plugin +xfce4-eyes-plugin +xfce4-fsguard-plugin +xfce4-genmon-plugin +xfce4-mailwatch-plugin +xfce4-mount-plugin +xfce4-mpc-plugin +xfce4-netload-plugin +xfce4-notes-plugin +xfce4-notifyd +xfce4-panel +xfce4-places-plugin +xfce4-power-manager +xfce4-pulseaudio-plugin +xfce4-screensaver +xfce4-screenshooter +xfce4-sensors-plugin +xfce4-session +xfce4-settings +xfce4-smartbookmark-plugin +xfce4-systemload-plugin +xfce4-taskmanager +xfce4-terminal +xfce4-time-out-plugin +xfce4-timer-plugin +xfce4-verve-plugin +xfce4-wavelan-plugin +xfce4-weather-plugin +xfce4-whiskermenu-plugin +xfce4-xkb-plugin +xfconf +xfdesktop +xfwm4 +xorg-iceauth +xorg-xinit +xorg-xmodmap diff --git a/phase0_evidence/x11_inventory_2026-05-03/pacman.entry2.log b/phase0_evidence/x11_inventory_2026-05-03/pacman.entry2.log new file mode 100644 index 0000000..e0089d5 --- /dev/null +++ b/phase0_evidence/x11_inventory_2026-05-03/pacman.entry2.log @@ -0,0 +1,227 @@ +:: There are 14 members in group xfce4: +:: Repository extra + 1) exo 2) garcon 3) thunar 4) thunar-volman 5) tumbler 6) xfce4-appfinder 7) xfce4-panel 8) xfce4-power-manager 9) xfce4-session 10) xfce4-settings 11) xfce4-terminal 12) xfconf 13) xfdesktop 14) xfwm4 + +Enter a selection (default=all): +:: There are 36 members in group xfce4-goodies: +:: Repository extra + 1) mousepad 2) parole 3) ristretto 4) thunar-archive-plugin 5) thunar-media-tags-plugin 6) xfburn 7) xfce4-battery-plugin 8) xfce4-clipman-plugin 9) xfce4-cpufreq-plugin 10) xfce4-cpugraph-plugin 11) xfce4-dict 12) xfce4-diskperf-plugin 13) xfce4-eyes-plugin 14) xfce4-fsguard-plugin 15) xfce4-genmon-plugin 16) xfce4-mailwatch-plugin 17) xfce4-mount-plugin 18) xfce4-mpc-plugin 19) xfce4-netload-plugin 20) xfce4-notes-plugin 21) xfce4-notifyd 22) xfce4-places-plugin 23) xfce4-pulseaudio-plugin 24) xfce4-screensaver 25) xfce4-screenshooter 26) xfce4-sensors-plugin 27) xfce4-smartbookmark-plugin 28) xfce4-systemload-plugin 29) xfce4-taskmanager 30) xfce4-time-out-plugin 31) xfce4-timer-plugin 32) xfce4-verve-plugin 33) xfce4-wavelan-plugin 34) xfce4-weather-plugin 35) xfce4-whiskermenu-plugin 36) xfce4-xkb-plugin + +Enter a selection (default=all): +resolving dependencies... +looking for conflicting packages... + +Packages (70) dbus-glib-0.114-1 elementary-icon-theme-8.2.0-1 gnome-themes-extra-1:3.28-1 gtk-layer-shell-0.10.1-1 gtksourceview4-4.8.4-2 libburn-1.5.8-1 libgtop-2.41.3-2 libisofs-1.5.8.1-1 libkeybinder3-0.3.2-5 libmpd-11.8.17-7 libwnck3-43.3-1 libxfce4ui-4.20.2-1 libxfce4util-4.20.1-1 libxfce4windowing-4.20.5-3 libxklavier-5.4-7 libxres-1.2.3-1 polkit-gnome-0.105-12 xorg-iceauth-1.0.11-1 xorg-xinit-1.4.4-1 xorg-xmodmap-1.0.11-2 exo-4.20.0-2 garcon-4.20.0-2 mousepad-0.7.0-1 parole-4.20.0-1 ristretto-0.14.0-1 thunar-4.20.8-3 thunar-archive-plugin-0.6.0-1 thunar-media-tags-plugin-0.6.0-1 thunar-volman-4.20.0-2 tumbler-4.20.1-1 xfburn-0.8.0-1 xfce4-appfinder-4.20.0-2 xfce4-battery-plugin-1.2.0-1 xfce4-clipman-plugin-1.7.0-1 xfce4-cpufreq-plugin-1.3.0-1 xfce4-cpugraph-plugin-1.3.0-1 xfce4-dict-0.8.9-1 xfce4-diskperf-plugin-2.8.0-2 xfce4-eyes-plugin-4.7.0-1 xfce4-fsguard-plugin-1.2.0-1 xfce4-genmon-plugin-4.3.0-1 xfce4-mailwatch-plugin-1.4.0-1 xfce4-mount-plugin-1.2.0-1 xfce4-mpc-plugin-0.6.0-1 xfce4-netload-plugin-1.5.0-1 xfce4-notes-plugin-1.12.0-1 xfce4-notifyd-0.9.7-2 xfce4-panel-4.20.7-1 xfce4-places-plugin-1.9.0-1 xfce4-power-manager-4.20.0-3 xfce4-pulseaudio-plugin-0.5.1-1 xfce4-screensaver-4.20.2-1 xfce4-screenshooter-1.11.3-3 xfce4-sensors-plugin-1.4.5-1 xfce4-session-4.20.4-1 xfce4-settings-4.20.4-1 xfce4-smartbookmark-plugin-0.6.0-2 xfce4-systemload-plugin-1.4.0-1 xfce4-taskmanager-1.6.0-1 xfce4-terminal-1.2.0-1 xfce4-time-out-plugin-1.2.0-1 xfce4-timer-plugin-1.8.0-1 xfce4-verve-plugin-2.1.0-1 xfce4-wavelan-plugin-0.7.0-2 xfce4-weather-plugin-0.12.0-2 xfce4-whiskermenu-plugin-2.10.1-2 xfce4-xkb-plugin-0.9.0-1 xfconf-4.20.0-2 xfdesktop-4.20.2-1 xfwm4-4.20.0-2 + +Total Download Size: 22.20 MiB +Total Installed Size: 136.65 MiB + +:: Proceed with installation? [Y/n] +:: Retrieving packages... + elementary-icon-theme-8.2.0-1-any downloading... + gnome-themes-extra-1:3.28-1-any downloading... + xfce4-weather-plugin-0.12.0-2-aarch64 downloading... + thunar-4.20.8-3-aarch64 downloading... + xfdesktop-4.20.2-1-aarch64 downloading... + gtksourceview4-4.8.4-2-aarch64 downloading... + xfce4-settings-4.20.4-1-aarch64 downloading... + xfce4-panel-4.20.7-1-aarch64 downloading... + xfce4-power-manager-4.20.0-3-aarch64 downloading... + xfwm4-4.20.0-2-aarch64 downloading... + mousepad-0.7.0-1-aarch64 downloading... + xfburn-0.8.0-1-aarch64 downloading... + xfce4-terminal-1.2.0-1-aarch64 downloading... + libwnck3-43.3-1-aarch64 downloading... + libxfce4ui-4.20.2-1-aarch64 downloading... + xfce4-session-4.20.4-1-aarch64 downloading... + parole-4.20.0-1-aarch64 downloading... + exo-4.20.0-2-aarch64 downloading... + xfce4-xkb-plugin-0.9.0-1-aarch64 downloading... + libburn-1.5.8-1-aarch64 downloading... + libisofs-1.5.8.1-1-aarch64 downloading... + ristretto-0.14.0-1-aarch64 downloading... + xfce4-screensaver-4.20.2-1-aarch64 downloading... + xfce4-whiskermenu-plugin-2.10.1-2-aarch64 downloading... + xfce4-notifyd-0.9.7-2-aarch64 downloading... + libgtop-2.41.3-2-aarch64 downloading... + xfce4-sensors-plugin-1.4.5-1-aarch64 downloading... + xfconf-4.20.0-2-aarch64 downloading... + xfce4-clipman-plugin-1.7.0-1-aarch64 downloading... + xfce4-dict-0.8.9-1-aarch64 downloading... + tumbler-4.20.1-1-aarch64 downloading... + xfce4-appfinder-4.20.0-2-aarch64 downloading... + libxfce4windowing-4.20.5-3-aarch64 downloading... + garcon-4.20.0-2-aarch64 downloading... + xfce4-mailwatch-plugin-1.4.0-1-aarch64 downloading... + xfce4-screenshooter-1.11.3-3-aarch64 downloading... + xfce4-notes-plugin-1.12.0-1-aarch64 downloading... + libxfce4util-4.20.1-1-aarch64 downloading... + dbus-glib-0.114-1-aarch64 downloading... + thunar-volman-4.20.0-2-aarch64 downloading... + xfce4-taskmanager-1.6.0-1-aarch64 downloading... + xfce4-cpugraph-plugin-1.3.0-1-aarch64 downloading... + xfce4-pulseaudio-plugin-0.5.1-1-aarch64 downloading... + xfce4-cpufreq-plugin-1.3.0-1-aarch64 downloading... + xfce4-battery-plugin-1.2.0-1-aarch64 downloading... + xfce4-mount-plugin-1.2.0-1-aarch64 downloading... + libxklavier-5.4-7-aarch64 downloading... + xfce4-fsguard-plugin-1.2.0-1-aarch64 downloading... + xfce4-places-plugin-1.9.0-1-aarch64 downloading... + gtk-layer-shell-0.10.1-1-aarch64 downloading... + xfce4-genmon-plugin-4.3.0-1-aarch64 downloading... + thunar-media-tags-plugin-0.6.0-1-aarch64 downloading... + polkit-gnome-0.105-12-aarch64 downloading... + xfce4-timer-plugin-1.8.0-1-aarch64 downloading... + xfce4-time-out-plugin-1.2.0-1-aarch64 downloading... + xfce4-diskperf-plugin-2.8.0-2-aarch64 downloading... + xfce4-systemload-plugin-1.4.0-1-aarch64 downloading... + xfce4-netload-plugin-1.5.0-1-aarch64 downloading... + libmpd-11.8.17-7-aarch64 downloading... + xfce4-eyes-plugin-4.7.0-1-aarch64 downloading... + xfce4-verve-plugin-2.1.0-1-aarch64 downloading... + xfce4-mpc-plugin-0.6.0-1-aarch64 downloading... + thunar-archive-plugin-0.6.0-1-aarch64 downloading... + xfce4-wavelan-plugin-0.7.0-2-aarch64 downloading... + xfce4-smartbookmark-plugin-0.6.0-2-aarch64 downloading... + xorg-xmodmap-1.0.11-2-aarch64 downloading... + libkeybinder3-0.3.2-5-aarch64 downloading... + xorg-xinit-1.4.4-1-aarch64 downloading... + xorg-iceauth-1.0.11-1-aarch64 downloading... + libxres-1.2.3-1-aarch64 downloading... +checking keyring... +checking package integrity... +loading package files... +checking for file conflicts... +:: Processing package changes... +installing libxfce4util... +installing xfconf... +installing libgtop... +installing libxfce4ui... +installing exo... +installing garcon... +installing thunar... +Optional dependencies for thunar + catfish: file searching + gvfs: trash support, mounting with udisk and remote filesystems + tumbler: thumbnail previews [pending] + thunar-volman: removable device management [pending] + thunar-archive-plugin: archive creation and extraction [pending] + thunar-media-tags-plugin: view/edit ID3/OGG tags [pending] +installing thunar-volman... +installing tumbler... +Optional dependencies for tumbler + ffmpegthumbnailer: video thumbnails + poppler-glib: PDF thumbnails + libgsf: ODF thumbnails + libgepub: EPUB thumbnails + libopenraw: RAW thumbnails + freetype2: font thumbnails [installed] +installing xfce4-appfinder... +installing gtk-layer-shell... +installing libxres... +installing libwnck3... +installing libxfce4windowing... +installing xfce4-panel... +installing xfce4-notifyd... +installing xfce4-power-manager... +installing xorg-iceauth... +installing xorg-xmodmap... +installing xorg-xinit... +Optional dependencies for xorg-xinit + xorg-twm + xterm +installing polkit-gnome... +installing xfce4-session... +Optional dependencies for xfce4-session + gnome-keyring: for keyring support when GNOME compatibility is enabled + xfce4-screensaver: for locking screen with xflock4 [pending] + xscreensaver: for locking screen with xflock4 + light-locker: for locking screen with xflock4 + labwc: recommended compositor for the experimental Wayland session +installing libxklavier... +installing elementary-icon-theme... +installing gnome-themes-extra... +installing xfce4-settings... +Optional dependencies for xfce4-settings + python: xfce4-compose-mail -- "mailto:" URI handling [installed] + xiccd: for displays support in xfce4-color-settings + cups: for printers support in xfce4-color-settings [installed] + sane: for scanners support in xfce4-color-settings +installing xfce4-terminal... +installing xfdesktop... +installing xfwm4... +installing gtksourceview4... +installing mousepad... +Optional dependencies for mousepad + gspell: spell checking plugin + libxfce4ui: shortcuts editor plugin [installed] +installing dbus-glib... +installing parole... +Optional dependencies for parole + gst-libav: Extra media codecs + gst-plugins-bad: Extra media codecs [installed] + gst-plugins-ugly: Extra media codecs +installing ristretto... +installing thunar-archive-plugin... +Optional dependencies for thunar-archive-plugin + file-roller + engrampa + ark [installed] + xarchiver +installing thunar-media-tags-plugin... +installing libburn... +installing libisofs... +installing xfburn... +installing xfce4-battery-plugin... +installing xfce4-clipman-plugin... +installing xfce4-cpufreq-plugin... +installing xfce4-cpugraph-plugin... +installing xfce4-dict... +installing xfce4-diskperf-plugin... +installing xfce4-eyes-plugin... +installing xfce4-fsguard-plugin... +installing xfce4-genmon-plugin... +installing xfce4-mailwatch-plugin... +installing xfce4-mount-plugin... +installing libmpd... +installing xfce4-mpc-plugin... +installing xfce4-netload-plugin... +installing xfce4-notes-plugin... +installing xfce4-places-plugin... +installing libkeybinder3... +Optional dependencies for libkeybinder3 + lua-lgi: lua bindings +installing xfce4-pulseaudio-plugin... +Optional dependencies for xfce4-pulseaudio-plugin + pavucontrol: default pulseaudio mixer +installing xfce4-screensaver... +Optional dependencies for xfce4-screensaver + onboard: on screen keyboard for unlocking + xscreensaver: additional themes +installing xfce4-screenshooter... +installing xfce4-sensors-plugin... +Optional dependencies for xfce4-sensors-plugin + hddtemp: for monitoring the temperature of hard drives +installing xfce4-smartbookmark-plugin... +installing xfce4-systemload-plugin... +installing xfce4-taskmanager... +installing xfce4-time-out-plugin... +installing xfce4-timer-plugin... +installing xfce4-verve-plugin... +installing xfce4-wavelan-plugin... +installing xfce4-weather-plugin... +installing xfce4-whiskermenu-plugin... +Optional dependencies for xfce4-whiskermenu-plugin + mugshot: Update user details +installing xfce4-xkb-plugin... +Optional dependencies for xfce4-xkb-plugin + xfce4-notifyd: show notifications on layout change [installed] +:: Running post-transaction hooks... +(1/8) Reloading user manager configuration... +(2/8) Arming ConditionNeedsUpdate... +(3/8) Refreshing PackageKit... +(4/8) Updating GIO module cache... +(5/8) Compiling GSettings XML schema files... +(6/8) Updating icon theme caches... +(7/8) Updating the info directory file... +(8/8) Updating the desktop file MIME type cache... diff --git a/phase0_evidence/x11_inventory_2026-05-03/pacman.entry3a.firefox.log b/phase0_evidence/x11_inventory_2026-05-03/pacman.entry3a.firefox.log new file mode 100644 index 0000000..16c5672 --- /dev/null +++ b/phase0_evidence/x11_inventory_2026-05-03/pacman.entry3a.firefox.log @@ -0,0 +1,30 @@ +resolving dependencies... +looking for conflicting packages... + +Packages (2) mailcap-2.1.54-2 firefox-150.0.1-1 + +Total Download Size: 63.40 MiB +Total Installed Size: 256.95 MiB + +:: Proceed with installation? [Y/n] +:: Retrieving packages... + firefox-150.0.1-1-aarch64 downloading... + mailcap-2.1.54-2-any downloading... +checking keyring... +checking package integrity... +loading package files... +checking for file conflicts... +:: Processing package changes... +installing mailcap... +installing firefox... +Optional dependencies for firefox + hunspell-en_US: Spell checking, American English + libnotify: Notification integration [installed] + networkmanager: Location detection via available WiFi networks [installed] + speech-dispatcher: Text-to-Speech + xdg-desktop-portal: Screensharing with Wayland [installed] +:: Running post-transaction hooks... +(1/4) Arming ConditionNeedsUpdate... +(2/4) Refreshing PackageKit... +(3/4) Updating icon theme caches... +(4/4) Updating the desktop file MIME type cache... diff --git a/phase0_evidence/x11_inventory_2026-05-03/pacman.entry3b.xtrace.log b/phase0_evidence/x11_inventory_2026-05-03/pacman.entry3b.xtrace.log new file mode 100644 index 0000000..d4c7f6e --- /dev/null +++ b/phase0_evidence/x11_inventory_2026-05-03/pacman.entry3b.xtrace.log @@ -0,0 +1,20 @@ +loading packages... +resolving dependencies... +looking for conflicting packages... + +Packages (1) xtrace-1.4.0-2 + +Total Installed Size: 0.31 MiB + +:: Proceed with installation? [Y/n] +checking keyring... +checking package integrity... +loading package files... +checking for file conflicts... +:: Processing package changes... +installing xtrace... +Optional dependencies for xtrace + xorg-xauth [installed] +:: Running post-transaction hooks... +(1/2) Arming ConditionNeedsUpdate... +(2/2) Refreshing PackageKit... diff --git a/phase0_evidence/x11_inventory_2026-05-03/pacman.install.log b/phase0_evidence/x11_inventory_2026-05-03/pacman.install.log new file mode 100644 index 0000000..7d42f39 --- /dev/null +++ b/phase0_evidence/x11_inventory_2026-05-03/pacman.install.log @@ -0,0 +1,47 @@ +resolving dependencies... +looking for conflicting packages... + +Packages (11) libadwaita-1:1.9.0-1 libdex-1.1.0-1 libpanel-1.10.4-1 startup-notification-0.12-9 openbox-3.6.1-14 sysprof-50.0-2 xorg-xev-1.2.6-2 xorg-xinput-1.6.4-2 xorg-xkill-1.0.7-1 xorg-xrandr-1.5.4-1 xorg-xwininfo-1.1.6-2 + +Total Download Size: 2.31 MiB +Total Installed Size: 16.01 MiB + +:: Proceed with installation? [Y/n] +:: Retrieving packages... + sysprof-50.0-2-aarch64 downloading... + libadwaita-1:1.9.0-1-aarch64 downloading... + openbox-3.6.1-14-aarch64 downloading... + libpanel-1.10.4-1-aarch64 downloading... + libdex-1.1.0-1-aarch64 downloading... + xorg-xrandr-1.5.4-1-aarch64 downloading... + xorg-xinput-1.6.4-2-aarch64 downloading... + xorg-xwininfo-1.1.6-2-aarch64 downloading... + startup-notification-0.12-9-aarch64 downloading... + xorg-xev-1.2.6-2-aarch64 downloading... + xorg-xkill-1.0.7-1-aarch64 downloading... +checking keyring... +checking package integrity... +loading package files... +checking for file conflicts... +:: Processing package changes... +installing xorg-xrandr... +installing xorg-xev... +installing xorg-xinput... +installing xorg-xwininfo... +installing xorg-xkill... +installing libadwaita... +installing libdex... +installing libpanel... +installing sysprof... +installing startup-notification... +installing openbox... +Optional dependencies for openbox + python-pyxdg: for the openbox-xdg-autostart script +:: Running post-transaction hooks... +(1/7) Reloading system manager configuration... +(2/7) Updating the MIME type database... +(3/7) Arming ConditionNeedsUpdate... +(4/7) Refreshing PackageKit... +(5/7) Reloading system bus configuration... +(6/7) Updating icon theme caches... +(7/7) Updating the desktop file MIME type cache... diff --git a/phase0_evidence/x11_inventory_2026-05-03/pkglist.entry2.post.txt b/phase0_evidence/x11_inventory_2026-05-03/pkglist.entry2.post.txt new file mode 100644 index 0000000..2f4e198 --- /dev/null +++ b/phase0_evidence/x11_inventory_2026-05-03/pkglist.entry2.post.txt @@ -0,0 +1,1250 @@ +a52dec +aalib +abseil-cpp +accounts-qml-module +accountsservice +acl +adwaita-cursors +adwaita-fonts +adwaita-icon-theme +adwaita-icon-theme-legacy +aha +akonadi +akonadi-calendar +akonadi-contacts +akonadi-import-wizard +akonadi-mime +akonadi-search +alsa-card-profiles +alsa-lib +alsa-topology-conf +alsa-ucm-conf +aom +apparmor +appstream +appstream-glib +appstream-qt +arch-install-scripts +archlinux-appstream-data +archlinux-keyring +archlinuxarm-keyring +argon2 +ark +asciidoctor +at-spi2-core +atkmm +attica +attr +audit +aurorae +autoconf +automake +avahi +ayatana-ido +backintime +backintime-cli +baloo +baloo-widgets +base +base-devel +bash +bash-completion +bes2600-firmware +bind +binutils +bison +blas +bluedevil +bluez +bluez-libs +bluez-qt +bluez-utils +bolt +boost-libs +brave-bin +breeze +breeze-cursors +breeze-gtk +breeze-icons +breeze-plymouth +brotli +btrfs-progs +bubblewrap +bzip2 +ca-certificates +ca-certificates-mozilla +ca-certificates-utils +cage +cairo +cairomm +calendarsupport +cantarell-fonts +cblas +ccache +cdparanoia +cfitsio +chromaprint +cifs-utils +claude-code +claude-his-agent +clinfo +cmake +colord +colord-kde +composefs +convertlit +coreutils +cppdap +cryptsetup +cups +cups-filters +curl +danctnix-keyring +danctnix-plasma-desktop-settings +dav1d +db5.3 +dbus +dbus-broker +dbus-broker-units +dbus-glib +dbus-units +dconf +ddcutil +debugedit +default-cursors +desktop-file-utils +device-mapper +device-pine64-pinetab2 +dhcpcd +dialog +diffutils +discount +discover +distcc +djvulibre +dmidecode +dnssec-anchors +docbook-xml +docbook-xsl +dolphin +dolphin-plugins +dosfstools +double-conversion +drkonqi +drm-info +duktape +e2fsprogs +ebook-tools +editorconfig-core-c +elementary-icon-theme +elfutils +elisa +enchant +eventviews +ex-vi-compat +exfatprogs +exiv2 +exo +expat +extra-cmake-modules +f2fs-tools +faac +faad2 +fakeroot +fcft +ffmpeg-v4l2-request +ffmpeg4.4 +fftw +file +filelight +filesystem +findutils +flac +flatpak +flatpak-kcm +flex +fluidsynth +fmt +fontconfig +foot +frameworkintegration +freeglut +freerdp +freetds +freetype2 +fribidi +fuse-common +fuse2 +fuse3 +garcon +gawk +gc +gcc +gcc-libs +gcr-4 +gd +gdb +gdb-common +gdbm +gdk-pixbuf2 +gettext +ghostscript +giflib +git +glad +glib-networking +glib2 +glib2-devel +glib2-docs +glibc +glibc-locales +glibmm +glslang +glu +glycin +gmp +gnome-themes-extra +gnulib-l10n +gnupg +gnutls +go +gobject-introspection +gobject-introspection-runtime +gocryptfs +gparted +gperftools +gpgme +gpgmepp +gpm +grantleetheme +graphene +graphite +graphviz +grep +groff +gsettings-desktop-schemas +gsettings-system-schemas +gsfonts +gsm +gssdp +gst-plugins-bad +gst-plugins-bad-libs +gst-plugins-base +gst-plugins-base-libs +gst-plugins-good +gstreamer +gtest +gtk-doc +gtk-layer-shell +gtk-update-icon-cache +gtk-vnc +gtk3 +gtk4 +gtkmm3 +gtksourceview4 +gts +guile +gupnp +gupnp-igd +gwenview +gzip +harfbuzz +harfbuzz-icu +hicolor-icon-theme +hidapi +highway +hiredis +htop +hunspell +hwdata +hwloc +hyphen +i2c-tools +iana-etc +icaclient +icu +iftop +iio-sensor-proxy +ijs +imagemagick +imath +imlib2 +incidenceeditor +inetutils +iotop +iproute2 +iptables +iputils +iso-codes +itstool +iw +jansson +jasper +jbig2dec +jbigkit +jemalloc +json-c +json-glib +jsoncpp +judy +kaccounts-integration +kactivitymanagerd +kalk +karchive +kate +kauth +kbd +kbookmarks +kcalendarcore +kcalutils +kcmutils +kcodecs +kcolorpicker +kcolorscheme +kcompletion +kconfig +kconfigwidgets +kcontacts +kcoreaddons +kcrash +kdbusaddons +kde-cli-tools +kde-gtk-config +kdeclarative +kdeconnect +kdecoration +kded +kdegraphics-mobipocket +kdegraphics-thumbnailers +kdenetwork-filesharing +kdepim-addons +kdeplasma-addons +kdesu +kdiagram +kdialog +kdnssd +kdoctools +kdsoap +kdsoap-ws-discovery-client +keyutils +kfilemetadata +kgamma +kglobalaccel +kglobalacceld +kguiaddons +kholidays +ki18n +kiconthemes +kidentitymanagement +kidletime +kimageannotator +kimageformats +kimap +kinfocenter +kio +kio-admin +kio-extras +kio-fuse +kirigami +kirigami-addons +kitemmodels +kitemviews +kitinerary +kjobwidgets +kjournald +kldap +kmailtransport +kmbox +kmenuedit +kmime +kmod +knewstuff +knighttime +knotifications +knotifyconfig +konsole +kpackage +kparts +kpeople +kpimtextedit +kpipewire +kpkpass +kpty +kquickcharts +kquickimageeditor +krb5 +krdp +krecorder +krunner +kscreen +kscreenlocker +kservice +ksmtp +ksshaskpass +kstatusnotifieritem +ksvg +ksystemlog +ksystemstats +ktextaddons +ktexteditor +ktexttemplate +ktextwidgets +ktnef +kunitconversion +kuserfeedback +kwallet +kwallet-pam +kwalletmanager +kwayland +kweather +kweathercore +kwidgetsaddons +kwin-fourier +kwin-x11 +kwindowsystem +kwrited +kxmlgui +l-smash +lame +lapack +layer-shell-qt +layer-shell-qt5 +lcms2 +ldb +ldns +leancrypto +less +libaccounts-glib +libaccounts-qt +libadwaita +libarchive +libasan +libass +libassuan +libasyncns +libatasmart +libatomic +libavc1394 +libavif +libavtp +libayatana-appindicator +libayatana-indicator +libb2 +libblake3 +libblockdev +libblockdev-crypto +libblockdev-fs +libblockdev-loop +libblockdev-mdraid +libblockdev-nvme +libblockdev-part +libblockdev-smart +libblockdev-swap +libbluray +libbpf +libbs2b +libbsd +libburn +libbytesize +libc++ +libc++abi +libcaca +libcacard +libcanberra +libcap +libcap-ng +libcdio +libcdio-paranoia +libcloudproviders +libcolord +libcups +libcupsfilters +libdaemon +libdatrie +libdbusmenu-glib +libdbusmenu-gtk3 +libdc1394 +libdca +libde265 +libdecor +libdeflate +libdex +libdisplay-info +libdmtx +libdovi +libdrm +libdv +libdvdnav +libdvdread +libebur128 +libedit +libei +libelf +libepoxy +libevdev +libevent +libexif +libfakekey +libfbclient +libfdk-aac +libffi +libfontenc +libfreeaptx +libfyaml +libgcc +libgcrypt +libgfortran +libgirepository +libglvnd +libgme +libgomp +libgovirt +libgpg-error +libgravatar +libgtop +libgudev +libgusb +libheif +libical +libice +libidn +libidn2 +libiec61883 +libimobiledevice +libimobiledevice-glue +libinih +libinput +libinstpatch +libisl +libisofs +libjpeg-turbo +libjxl +libkdcraw +libkdepim +libkexiv2 +libkeybinder3 +libkgapi +libkleo +libksba +libkscreen +libksieve +libksysguard +liblc3 +libldac +libldap +libliftoff +liblqr +liblrdf +liblsan +libltc +libmakepkg-dropins +libmalcontent +libmanette +libmaxminddb +libmbim +libmd +libmicrodns +libmm-glib +libmng +libmnl +libmodplug +libmpc +libmpcdec +libmpd +libmtp +libmysofa +libnbd +libndp +libnetfilter_conntrack +libnewt +libnfnetlink +libnftnl +libnghttp2 +libnghttp3 +libngtcp2 +libnice +libnl +libnm +libnma-common +libnma-gtk4 +libnotify +libnsl +libnvme +libobjc +libogg +libopenmpt +libp11-kit +libpackagekit-glib +libpanel +libpaper +libpcap +libpciaccess +libpfm +libpgm +libphonenumber +libpipeline +libpipewire +libplacebo +libplasma +libplist +libpng +libppd +libproxy +libpsl +libpulse +libqaccessibilityclient-qt6 +libqalculate +libqmi +libqrtr-glib +libquadmath +libraqm +libraw +libraw1394 +librest +librsvg +libsamplerate +libsasl +libseccomp +libsecret +libshout +libsigc++ +libsixel +libsm +libsndfile +libsodium +libsoup +libsoup3 +libsoxr +libspectre +libsrtp +libssc +libssh +libssh2 +libstdc++ +libstemmer +libsysprof-capture +libtasn1 +libtatsu +libteam +libthai +libtheora +libtiff +libtirpc +libtommath +libtool +libtraceevent +libtsan +libubsan +libunibreak +libunistring +libunwind +liburcu +liburing +libusb +libusbmuxd +libutempter +libutf8proc +libuv +libva +libva-utils +libva-v4l2-request-ohm-gl-fix +libvdpau +libverto +libvirt +libvirt-glib +libvlc +libvorbis +libvpx +libwacom +libwbclient +libwebp +libwireplumber +libwnck3 +libx11 +libxau +libxaw +libxcb +libxcomposite +libxcrypt +libxcursor +libxcvt +libxdamage +libxdmcp +libxext +libxfce4ui +libxfce4util +libxfce4windowing +libxfixes +libxfont2 +libxft +libxi +libxinerama +libxkbcommon +libxkbcommon-x11 +libxkbfile +libxklavier +libxml2 +libxml2-legacy +libxmlb +libxmu +libxp +libxpm +libxpresent +libxrandr +libxrender +libxres +libxshmfence +libxslt +libxss +libxt +libxtst +libxv +libxxf86vm +libyaml +libyuv +libzip +licenses +lilv +linux-api-headers +linux-firmware +linux-firmware-amdgpu +linux-firmware-atheros +linux-firmware-broadcom +linux-firmware-cirrus +linux-firmware-intel +linux-firmware-mediatek +linux-firmware-nvidia +linux-firmware-other +linux-firmware-radeon +linux-firmware-realtek +linux-firmware-whence +linux-pinetab2 +linux-pinetab2-headers +lksctp-tools +llvm-libs +llvm21-libs +lm_sensors +lmcp +lmdb +lsof +lua +lua-socket +lua54 +luajit +lv2 +lz4 +lzo +m4 +mailcommon +mailimporter +make +mallard-ducktype +man-db +mariadb +mariadb-clients +mariadb-libs +mbox-importer +md4c +mdadm +media-player-info +memtester +mesa +mesa-utils +meson +messagelib +milou +minicom +minizip +mjpegtools +mkinitcpio +mkinitcpio-busybox +mobile-broadband-provider-info +modemmanager +modemmanager-qt +mousepad +mpdecimal +mpfr +mpg123 +mpv +mtd-utils +mtdev +mtools +mujs +nano +ncurses +neon +net-tools +netctl +netpbm +nettle +networkmanager +networkmanager-openvpn +networkmanager-qt +networkmanager-vpn-plugin-openvpn +nftables +ninja +noto-fonts +noto-fonts-cjk +noto-fonts-emoji +npth +nspr +nss +nuklear +numactl +ocean-sound-theme +ocl-icd +oh-my-posh +okular +onetbb +openal +openbox +opencore-amr +opencv +openexr +openh264 +openjpeg2 +openjph +openresolv +openssh +openssl +openvpn +openxr +opus +orc +ostree +oxygen +oxygen-cursors +oxygen-icons +oxygen-sounds +p11-kit +packagekit +packagekit-qt6 +pacman +pacman-mirrorlist +pahole +pam +pambase +pango +pangomm +parole +parted +patch +pciutils +pcre +pcre2 +pcsclite +perf +perl +perl-error +perl-mailtools +perl-timedate +phodav +phonon-qt6 +phonon-qt6-vlc +picocom +pim-data-exporter +pimcommon +pinentry +pipewire +pipewire-alsa +pipewire-audio +pipewire-jack +pipewire-pulse +pipewire-session-manager +pixman +pkcs11-helper +pkgconf +plasma-activities +plasma-activities-stats +plasma-browser-integration +plasma-desktop +plasma-disks +plasma-firewall +plasma-integration +plasma-keyboard +plasma-maliit-framework +plasma-nm +plasma-pa +plasma-sdk +plasma-systemmonitor +plasma-thunderbolt +plasma-vault +plasma-welcome +plasma-workspace +plasma-workspace-wallpapers +plasma-x11-session +plasma5support +plymouth +plymouth-kcm +polkit +polkit-gnome +polkit-kde-agent +polkit-qt6 +poppler +poppler-data +poppler-qt6 +popt +portaudio +postgresql +postgresql-libs +power-profiles-daemon +powerdevil +ppp +print-manager +prison +procps-ng +protobuf +protobuf-c +psmisc +pulseaudio-qt +purpose +pv +python +python-autocommand +python-certifi +python-cffi +python-cryptography +python-dbus +python-gobject +python-iniconfig +python-jaraco.classes +python-jaraco.collections +python-jaraco.context +python-jaraco.functools +python-jaraco.text +python-jeepney +python-jinja +python-keyring +python-legacy-cgi +python-lxml +python-mako +python-markdown +python-markupsafe +python-more-itertools +python-packaging +python-pkg_resources +python-platformdirs +python-pluggy +python-psutil +python-pycparser +python-pyfakefs +python-pygdbmi +python-pygments +python-pyqt6 +python-pyqt6-sip +python-pytest +python-secretstorage +python-sentry_sdk +python-setuptools +python-tqdm +python-typing_extensions +python-urllib3 +python-wheel +qca-qt6 +qcoro +qgpgme +qpdf +qqc2-breeze-style +qqc2-desktop-style +qrencode +qt5-base +qt5-declarative +qt5-svg +qt5-translations +qt5-wayland +qt5-x11extras +qt6-5compat +qt6-base-fourier +qt6-charts +qt6-connectivity +qt6-declarative +qt6-imageformats +qt6-location +qt6-multimedia +qt6-multimedia-ffmpeg +qt6-positioning +qt6-quick3d +qt6-quicktimeline +qt6-sensors +qt6-shadertools +qt6-speech +qt6-svg +qt6-tools +qt6-translations +qt6-virtualkeyboard +qt6-wayland +qt6-webchannel +qt6-webengine +qt6-websockets +qt6-webview +qtkeychain-qt6 +raptor +rav1e +re2 +readline +remmina +renderdoc +rhash +ripgrep +ripgrep-all +ristretto +rkdeveloptool-git +rpi-imager +rsync +rtkit +rtmpdump +rubberband +ruby +rubygems +samba +sbc +screen +sddm +sddm-kcm +sdl2-compat +sdl2_ttf +sdl3 +sdl3_ttf +seatd +sed +serd +shaderc +shadow +shared-mime-info +signon-kwallet-extension +signon-plugin-oauth2 +signon-ui +signond +slang +smartmontools +smbclient +snappy +sndio +socat +solid +sonnet +sord +sound-theme-freedesktop +soundtouch +source-highlight +spandsp +spectacle +speex +speexdsp +spice-gtk +spice-protocol +spirv-tools +sqlite +sratom +srt +sshfs +startup-notification +strace +stress-ng +sudo +sweeper +syndication +syntax-highlighting +sysprof +systemd +systemd-libs +systemd-sysvcompat +systemsettings +taglib +talloc +tar +tdb +tevent +texinfo +threadweaver +thunar +thunar-archive-plugin +thunar-media-tags-plugin +thunar-volman +time +tinysparql +tpm2-tss +tslib +ttf-hack +tumbler +twolame +tzdata +uboot-pinetab2 +uboot-tools +uchardet +udisks2 +unixodbc +unzip +upower +usbredir +usbutils +util-linux +util-linux-libs +v4l-utils +vala +vapoursynth +verdict +vid.stab +vim +vim-runtime +virt-viewer +visual-studio-code-bin +vlc +vlc-cli +vlc-gui-qt +vlc-plugin-a52dec +vlc-plugin-alsa +vlc-plugin-archive +vlc-plugin-dav1d +vlc-plugin-dbus +vlc-plugin-dbus-screensaver +vlc-plugin-faad2 +vlc-plugin-ffmpeg +vlc-plugin-flac +vlc-plugin-gnutls +vlc-plugin-inflate +vlc-plugin-journal +vlc-plugin-jpeg +vlc-plugin-lua +vlc-plugin-mpg123 +vlc-plugin-ogg +vlc-plugin-opus +vlc-plugin-png +vlc-plugin-pulse +vlc-plugin-shout +vlc-plugin-speex +vlc-plugin-tag +vlc-plugin-theora +vlc-plugin-twolame +vlc-plugin-vorbis +vlc-plugin-vpx +vlc-plugin-xml +vlc-plugins-base +vlc-plugins-video-output +vmaf +volume_key +vte-common +vte3 +vulkan-extra-tools +vulkan-headers +vulkan-icd-loader +vulkan-mesa-implicit-layers +vulkan-mesa-layers +vulkan-panfrost +vulkan-tools +wacomtablet +wavpack +wayland +wayland-protocols +wayland-utils +webkit2gtk +webrtc-audio-processing-1 +weston +which +wildmidi +wireless-regdb +wireplumber +wlroots0.20 +woff2 +wpa_supplicant +x264 +x265 +xapian-core +xcb-proto +xcb-util +xcb-util-cursor +xcb-util-errors +xcb-util-image +xcb-util-keysyms +xcb-util-renderutil +xcb-util-wm +xdg-dbus-proxy +xdg-desktop-portal +xdg-desktop-portal-gtk +xdg-desktop-portal-kde +xdg-user-dirs +xdg-utils +xf86-input-libinput +xf86-input-wacom +xfburn +xfce4-appfinder +xfce4-battery-plugin +xfce4-clipman-plugin +xfce4-cpufreq-plugin +xfce4-cpugraph-plugin +xfce4-dict +xfce4-diskperf-plugin +xfce4-eyes-plugin +xfce4-fsguard-plugin +xfce4-genmon-plugin +xfce4-mailwatch-plugin +xfce4-mount-plugin +xfce4-mpc-plugin +xfce4-netload-plugin +xfce4-notes-plugin +xfce4-notifyd +xfce4-panel +xfce4-places-plugin +xfce4-power-manager +xfce4-pulseaudio-plugin +xfce4-screensaver +xfce4-screenshooter +xfce4-sensors-plugin +xfce4-session +xfce4-settings +xfce4-smartbookmark-plugin +xfce4-systemload-plugin +xfce4-taskmanager +xfce4-terminal +xfce4-time-out-plugin +xfce4-timer-plugin +xfce4-verve-plugin +xfce4-wavelan-plugin +xfce4-weather-plugin +xfce4-whiskermenu-plugin +xfce4-xkb-plugin +xfconf +xfdesktop +xfwm4 +xkeyboard-config +xmlstarlet +xorg-fonts-encodings +xorg-iceauth +xorg-server +xorg-server-common +xorg-server-xvfb +xorg-setxkbmap +xorg-xauth +xorg-xdpyinfo +xorg-xev +xorg-xinit +xorg-xinput +xorg-xkbcomp +xorg-xkill +xorg-xmessage +xorg-xmodmap +xorg-xprop +xorg-xrandr +xorg-xrdb +xorg-xset +xorg-xwayland +xorg-xwininfo +xorgproto +xsettingsd +xvidcore +xxhash +xz +yay +yelp-tools +yelp-xsl +zbar +zeromq +zimg +zint +zix +zlib +zlib-ng +zramswap +zstd +zvbi +zxing-cpp diff --git a/phase0_evidence/x11_inventory_2026-05-03/pkglist.entry2.pre.txt b/phase0_evidence/x11_inventory_2026-05-03/pkglist.entry2.pre.txt new file mode 100644 index 0000000..b057406 --- /dev/null +++ b/phase0_evidence/x11_inventory_2026-05-03/pkglist.entry2.pre.txt @@ -0,0 +1,1180 @@ +a52dec +aalib +abseil-cpp +accounts-qml-module +accountsservice +acl +adwaita-cursors +adwaita-fonts +adwaita-icon-theme +adwaita-icon-theme-legacy +aha +akonadi +akonadi-calendar +akonadi-contacts +akonadi-import-wizard +akonadi-mime +akonadi-search +alsa-card-profiles +alsa-lib +alsa-topology-conf +alsa-ucm-conf +aom +apparmor +appstream +appstream-glib +appstream-qt +arch-install-scripts +archlinux-appstream-data +archlinux-keyring +archlinuxarm-keyring +argon2 +ark +asciidoctor +at-spi2-core +atkmm +attica +attr +audit +aurorae +autoconf +automake +avahi +ayatana-ido +backintime +backintime-cli +baloo +baloo-widgets +base +base-devel +bash +bash-completion +bes2600-firmware +bind +binutils +bison +blas +bluedevil +bluez +bluez-libs +bluez-qt +bluez-utils +bolt +boost-libs +brave-bin +breeze +breeze-cursors +breeze-gtk +breeze-icons +breeze-plymouth +brotli +btrfs-progs +bubblewrap +bzip2 +ca-certificates +ca-certificates-mozilla +ca-certificates-utils +cage +cairo +cairomm +calendarsupport +cantarell-fonts +cblas +ccache +cdparanoia +cfitsio +chromaprint +cifs-utils +claude-code +claude-his-agent +clinfo +cmake +colord +colord-kde +composefs +convertlit +coreutils +cppdap +cryptsetup +cups +cups-filters +curl +danctnix-keyring +danctnix-plasma-desktop-settings +dav1d +db5.3 +dbus +dbus-broker +dbus-broker-units +dbus-units +dconf +ddcutil +debugedit +default-cursors +desktop-file-utils +device-mapper +device-pine64-pinetab2 +dhcpcd +dialog +diffutils +discount +discover +distcc +djvulibre +dmidecode +dnssec-anchors +docbook-xml +docbook-xsl +dolphin +dolphin-plugins +dosfstools +double-conversion +drkonqi +drm-info +duktape +e2fsprogs +ebook-tools +editorconfig-core-c +elfutils +elisa +enchant +eventviews +ex-vi-compat +exfatprogs +exiv2 +expat +extra-cmake-modules +f2fs-tools +faac +faad2 +fakeroot +fcft +ffmpeg-v4l2-request +ffmpeg4.4 +fftw +file +filelight +filesystem +findutils +flac +flatpak +flatpak-kcm +flex +fluidsynth +fmt +fontconfig +foot +frameworkintegration +freeglut +freerdp +freetds +freetype2 +fribidi +fuse-common +fuse2 +fuse3 +gawk +gc +gcc +gcc-libs +gcr-4 +gd +gdb +gdb-common +gdbm +gdk-pixbuf2 +gettext +ghostscript +giflib +git +glad +glib-networking +glib2 +glib2-devel +glib2-docs +glibc +glibc-locales +glibmm +glslang +glu +glycin +gmp +gnulib-l10n +gnupg +gnutls +go +gobject-introspection +gobject-introspection-runtime +gocryptfs +gparted +gperftools +gpgme +gpgmepp +gpm +grantleetheme +graphene +graphite +graphviz +grep +groff +gsettings-desktop-schemas +gsettings-system-schemas +gsfonts +gsm +gssdp +gst-plugins-bad +gst-plugins-bad-libs +gst-plugins-base +gst-plugins-base-libs +gst-plugins-good +gstreamer +gtest +gtk-doc +gtk-update-icon-cache +gtk-vnc +gtk3 +gtk4 +gtkmm3 +gts +guile +gupnp +gupnp-igd +gwenview +gzip +harfbuzz +harfbuzz-icu +hicolor-icon-theme +hidapi +highway +hiredis +htop +hunspell +hwdata +hwloc +hyphen +i2c-tools +iana-etc +icaclient +icu +iftop +iio-sensor-proxy +ijs +imagemagick +imath +imlib2 +incidenceeditor +inetutils +iotop +iproute2 +iptables +iputils +iso-codes +itstool +iw +jansson +jasper +jbig2dec +jbigkit +jemalloc +json-c +json-glib +jsoncpp +judy +kaccounts-integration +kactivitymanagerd +kalk +karchive +kate +kauth +kbd +kbookmarks +kcalendarcore +kcalutils +kcmutils +kcodecs +kcolorpicker +kcolorscheme +kcompletion +kconfig +kconfigwidgets +kcontacts +kcoreaddons +kcrash +kdbusaddons +kde-cli-tools +kde-gtk-config +kdeclarative +kdeconnect +kdecoration +kded +kdegraphics-mobipocket +kdegraphics-thumbnailers +kdenetwork-filesharing +kdepim-addons +kdeplasma-addons +kdesu +kdiagram +kdialog +kdnssd +kdoctools +kdsoap +kdsoap-ws-discovery-client +keyutils +kfilemetadata +kgamma +kglobalaccel +kglobalacceld +kguiaddons +kholidays +ki18n +kiconthemes +kidentitymanagement +kidletime +kimageannotator +kimageformats +kimap +kinfocenter +kio +kio-admin +kio-extras +kio-fuse +kirigami +kirigami-addons +kitemmodels +kitemviews +kitinerary +kjobwidgets +kjournald +kldap +kmailtransport +kmbox +kmenuedit +kmime +kmod +knewstuff +knighttime +knotifications +knotifyconfig +konsole +kpackage +kparts +kpeople +kpimtextedit +kpipewire +kpkpass +kpty +kquickcharts +kquickimageeditor +krb5 +krdp +krecorder +krunner +kscreen +kscreenlocker +kservice +ksmtp +ksshaskpass +kstatusnotifieritem +ksvg +ksystemlog +ksystemstats +ktextaddons +ktexteditor +ktexttemplate +ktextwidgets +ktnef +kunitconversion +kuserfeedback +kwallet +kwallet-pam +kwalletmanager +kwayland +kweather +kweathercore +kwidgetsaddons +kwin-fourier +kwin-x11 +kwindowsystem +kwrited +kxmlgui +l-smash +lame +lapack +layer-shell-qt +layer-shell-qt5 +lcms2 +ldb +ldns +leancrypto +less +libaccounts-glib +libaccounts-qt +libadwaita +libarchive +libasan +libass +libassuan +libasyncns +libatasmart +libatomic +libavc1394 +libavif +libavtp +libayatana-appindicator +libayatana-indicator +libb2 +libblake3 +libblockdev +libblockdev-crypto +libblockdev-fs +libblockdev-loop +libblockdev-mdraid +libblockdev-nvme +libblockdev-part +libblockdev-smart +libblockdev-swap +libbluray +libbpf +libbs2b +libbsd +libbytesize +libc++ +libc++abi +libcaca +libcacard +libcanberra +libcap +libcap-ng +libcdio +libcdio-paranoia +libcloudproviders +libcolord +libcups +libcupsfilters +libdaemon +libdatrie +libdbusmenu-glib +libdbusmenu-gtk3 +libdc1394 +libdca +libde265 +libdecor +libdeflate +libdex +libdisplay-info +libdmtx +libdovi +libdrm +libdv +libdvdnav +libdvdread +libebur128 +libedit +libei +libelf +libepoxy +libevdev +libevent +libexif +libfakekey +libfbclient +libfdk-aac +libffi +libfontenc +libfreeaptx +libfyaml +libgcc +libgcrypt +libgfortran +libgirepository +libglvnd +libgme +libgomp +libgovirt +libgpg-error +libgravatar +libgudev +libgusb +libheif +libical +libice +libidn +libidn2 +libiec61883 +libimobiledevice +libimobiledevice-glue +libinih +libinput +libinstpatch +libisl +libjpeg-turbo +libjxl +libkdcraw +libkdepim +libkexiv2 +libkgapi +libkleo +libksba +libkscreen +libksieve +libksysguard +liblc3 +libldac +libldap +libliftoff +liblqr +liblrdf +liblsan +libltc +libmakepkg-dropins +libmalcontent +libmanette +libmaxminddb +libmbim +libmd +libmicrodns +libmm-glib +libmng +libmnl +libmodplug +libmpc +libmpcdec +libmtp +libmysofa +libnbd +libndp +libnetfilter_conntrack +libnewt +libnfnetlink +libnftnl +libnghttp2 +libnghttp3 +libngtcp2 +libnice +libnl +libnm +libnma-common +libnma-gtk4 +libnotify +libnsl +libnvme +libobjc +libogg +libopenmpt +libp11-kit +libpackagekit-glib +libpanel +libpaper +libpcap +libpciaccess +libpfm +libpgm +libphonenumber +libpipeline +libpipewire +libplacebo +libplasma +libplist +libpng +libppd +libproxy +libpsl +libpulse +libqaccessibilityclient-qt6 +libqalculate +libqmi +libqrtr-glib +libquadmath +libraqm +libraw +libraw1394 +librest +librsvg +libsamplerate +libsasl +libseccomp +libsecret +libshout +libsigc++ +libsixel +libsm +libsndfile +libsodium +libsoup +libsoup3 +libsoxr +libspectre +libsrtp +libssc +libssh +libssh2 +libstdc++ +libstemmer +libsysprof-capture +libtasn1 +libtatsu +libteam +libthai +libtheora +libtiff +libtirpc +libtommath +libtool +libtraceevent +libtsan +libubsan +libunibreak +libunistring +libunwind +liburcu +liburing +libusb +libusbmuxd +libutempter +libutf8proc +libuv +libva +libva-utils +libva-v4l2-request-ohm-gl-fix +libvdpau +libverto +libvirt +libvirt-glib +libvlc +libvorbis +libvpx +libwacom +libwbclient +libwebp +libwireplumber +libx11 +libxau +libxaw +libxcb +libxcomposite +libxcrypt +libxcursor +libxcvt +libxdamage +libxdmcp +libxext +libxfixes +libxfont2 +libxft +libxi +libxinerama +libxkbcommon +libxkbcommon-x11 +libxkbfile +libxml2 +libxml2-legacy +libxmlb +libxmu +libxp +libxpm +libxpresent +libxrandr +libxrender +libxshmfence +libxslt +libxss +libxt +libxtst +libxv +libxxf86vm +libyaml +libyuv +libzip +licenses +lilv +linux-api-headers +linux-firmware +linux-firmware-amdgpu +linux-firmware-atheros +linux-firmware-broadcom +linux-firmware-cirrus +linux-firmware-intel +linux-firmware-mediatek +linux-firmware-nvidia +linux-firmware-other +linux-firmware-radeon +linux-firmware-realtek +linux-firmware-whence +linux-pinetab2 +linux-pinetab2-headers +lksctp-tools +llvm-libs +llvm21-libs +lm_sensors +lmcp +lmdb +lsof +lua +lua-socket +lua54 +luajit +lv2 +lz4 +lzo +m4 +mailcommon +mailimporter +make +mallard-ducktype +man-db +mariadb +mariadb-clients +mariadb-libs +mbox-importer +md4c +mdadm +media-player-info +memtester +mesa +mesa-utils +meson +messagelib +milou +minicom +minizip +mjpegtools +mkinitcpio +mkinitcpio-busybox +mobile-broadband-provider-info +modemmanager +modemmanager-qt +mpdecimal +mpfr +mpg123 +mpv +mtd-utils +mtdev +mtools +mujs +nano +ncurses +neon +net-tools +netctl +netpbm +nettle +networkmanager +networkmanager-openvpn +networkmanager-qt +networkmanager-vpn-plugin-openvpn +nftables +ninja +noto-fonts +noto-fonts-cjk +noto-fonts-emoji +npth +nspr +nss +nuklear +numactl +ocean-sound-theme +ocl-icd +oh-my-posh +okular +onetbb +openal +openbox +opencore-amr +opencv +openexr +openh264 +openjpeg2 +openjph +openresolv +openssh +openssl +openvpn +openxr +opus +orc +ostree +oxygen +oxygen-cursors +oxygen-icons +oxygen-sounds +p11-kit +packagekit +packagekit-qt6 +pacman +pacman-mirrorlist +pahole +pam +pambase +pango +pangomm +parted +patch +pciutils +pcre +pcre2 +pcsclite +perf +perl +perl-error +perl-mailtools +perl-timedate +phodav +phonon-qt6 +phonon-qt6-vlc +picocom +pim-data-exporter +pimcommon +pinentry +pipewire +pipewire-alsa +pipewire-audio +pipewire-jack +pipewire-pulse +pipewire-session-manager +pixman +pkcs11-helper +pkgconf +plasma-activities +plasma-activities-stats +plasma-browser-integration +plasma-desktop +plasma-disks +plasma-firewall +plasma-integration +plasma-keyboard +plasma-maliit-framework +plasma-nm +plasma-pa +plasma-sdk +plasma-systemmonitor +plasma-thunderbolt +plasma-vault +plasma-welcome +plasma-workspace +plasma-workspace-wallpapers +plasma-x11-session +plasma5support +plymouth +plymouth-kcm +polkit +polkit-kde-agent +polkit-qt6 +poppler +poppler-data +poppler-qt6 +popt +portaudio +postgresql +postgresql-libs +power-profiles-daemon +powerdevil +ppp +print-manager +prison +procps-ng +protobuf +protobuf-c +psmisc +pulseaudio-qt +purpose +pv +python +python-autocommand +python-certifi +python-cffi +python-cryptography +python-dbus +python-gobject +python-iniconfig +python-jaraco.classes +python-jaraco.collections +python-jaraco.context +python-jaraco.functools +python-jaraco.text +python-jeepney +python-jinja +python-keyring +python-legacy-cgi +python-lxml +python-mako +python-markdown +python-markupsafe +python-more-itertools +python-packaging +python-pkg_resources +python-platformdirs +python-pluggy +python-psutil +python-pycparser +python-pyfakefs +python-pygdbmi +python-pygments +python-pyqt6 +python-pyqt6-sip +python-pytest +python-secretstorage +python-sentry_sdk +python-setuptools +python-tqdm +python-typing_extensions +python-urllib3 +python-wheel +qca-qt6 +qcoro +qgpgme +qpdf +qqc2-breeze-style +qqc2-desktop-style +qrencode +qt5-base +qt5-declarative +qt5-svg +qt5-translations +qt5-wayland +qt5-x11extras +qt6-5compat +qt6-base-fourier +qt6-charts +qt6-connectivity +qt6-declarative +qt6-imageformats +qt6-location +qt6-multimedia +qt6-multimedia-ffmpeg +qt6-positioning +qt6-quick3d +qt6-quicktimeline +qt6-sensors +qt6-shadertools +qt6-speech +qt6-svg +qt6-tools +qt6-translations +qt6-virtualkeyboard +qt6-wayland +qt6-webchannel +qt6-webengine +qt6-websockets +qt6-webview +qtkeychain-qt6 +raptor +rav1e +re2 +readline +remmina +renderdoc +rhash +ripgrep +ripgrep-all +rkdeveloptool-git +rpi-imager +rsync +rtkit +rtmpdump +rubberband +ruby +rubygems +samba +sbc +screen +sddm +sddm-kcm +sdl2-compat +sdl2_ttf +sdl3 +sdl3_ttf +seatd +sed +serd +shaderc +shadow +shared-mime-info +signon-kwallet-extension +signon-plugin-oauth2 +signon-ui +signond +slang +smartmontools +smbclient +snappy +sndio +socat +solid +sonnet +sord +sound-theme-freedesktop +soundtouch +source-highlight +spandsp +spectacle +speex +speexdsp +spice-gtk +spice-protocol +spirv-tools +sqlite +sratom +srt +sshfs +startup-notification +strace +stress-ng +sudo +sweeper +syndication +syntax-highlighting +sysprof +systemd +systemd-libs +systemd-sysvcompat +systemsettings +taglib +talloc +tar +tdb +tevent +texinfo +threadweaver +time +tinysparql +tpm2-tss +tslib +ttf-hack +twolame +tzdata +uboot-pinetab2 +uboot-tools +uchardet +udisks2 +unixodbc +unzip +upower +usbredir +usbutils +util-linux +util-linux-libs +v4l-utils +vala +vapoursynth +verdict +vid.stab +vim +vim-runtime +virt-viewer +visual-studio-code-bin +vlc +vlc-cli +vlc-gui-qt +vlc-plugin-a52dec +vlc-plugin-alsa +vlc-plugin-archive +vlc-plugin-dav1d +vlc-plugin-dbus +vlc-plugin-dbus-screensaver +vlc-plugin-faad2 +vlc-plugin-ffmpeg +vlc-plugin-flac +vlc-plugin-gnutls +vlc-plugin-inflate +vlc-plugin-journal +vlc-plugin-jpeg +vlc-plugin-lua +vlc-plugin-mpg123 +vlc-plugin-ogg +vlc-plugin-opus +vlc-plugin-png +vlc-plugin-pulse +vlc-plugin-shout +vlc-plugin-speex +vlc-plugin-tag +vlc-plugin-theora +vlc-plugin-twolame +vlc-plugin-vorbis +vlc-plugin-vpx +vlc-plugin-xml +vlc-plugins-base +vlc-plugins-video-output +vmaf +volume_key +vte-common +vte3 +vulkan-extra-tools +vulkan-headers +vulkan-icd-loader +vulkan-mesa-implicit-layers +vulkan-mesa-layers +vulkan-panfrost +vulkan-tools +wacomtablet +wavpack +wayland +wayland-protocols +wayland-utils +webkit2gtk +webrtc-audio-processing-1 +weston +which +wildmidi +wireless-regdb +wireplumber +wlroots0.20 +woff2 +wpa_supplicant +x264 +x265 +xapian-core +xcb-proto +xcb-util +xcb-util-cursor +xcb-util-errors +xcb-util-image +xcb-util-keysyms +xcb-util-renderutil +xcb-util-wm +xdg-dbus-proxy +xdg-desktop-portal +xdg-desktop-portal-gtk +xdg-desktop-portal-kde +xdg-user-dirs +xdg-utils +xf86-input-libinput +xf86-input-wacom +xkeyboard-config +xmlstarlet +xorg-fonts-encodings +xorg-server +xorg-server-common +xorg-server-xvfb +xorg-setxkbmap +xorg-xauth +xorg-xdpyinfo +xorg-xev +xorg-xinput +xorg-xkbcomp +xorg-xkill +xorg-xmessage +xorg-xprop +xorg-xrandr +xorg-xrdb +xorg-xset +xorg-xwayland +xorg-xwininfo +xorgproto +xsettingsd +xvidcore +xxhash +xz +yay +yelp-tools +yelp-xsl +zbar +zeromq +zimg +zint +zix +zlib +zlib-ng +zramswap +zstd +zvbi +zxing-cpp diff --git a/phase0_evidence/x11_inventory_2026-05-03/pkglist.entry3.post.txt b/phase0_evidence/x11_inventory_2026-05-03/pkglist.entry3.post.txt new file mode 100644 index 0000000..64f1064 --- /dev/null +++ b/phase0_evidence/x11_inventory_2026-05-03/pkglist.entry3.post.txt @@ -0,0 +1,1253 @@ +a52dec +aalib +abseil-cpp +accounts-qml-module +accountsservice +acl +adwaita-cursors +adwaita-fonts +adwaita-icon-theme +adwaita-icon-theme-legacy +aha +akonadi +akonadi-calendar +akonadi-contacts +akonadi-import-wizard +akonadi-mime +akonadi-search +alsa-card-profiles +alsa-lib +alsa-topology-conf +alsa-ucm-conf +aom +apparmor +appstream +appstream-glib +appstream-qt +arch-install-scripts +archlinux-appstream-data +archlinux-keyring +archlinuxarm-keyring +argon2 +ark +asciidoctor +at-spi2-core +atkmm +attica +attr +audit +aurorae +autoconf +automake +avahi +ayatana-ido +backintime +backintime-cli +baloo +baloo-widgets +base +base-devel +bash +bash-completion +bes2600-firmware +bind +binutils +bison +blas +bluedevil +bluez +bluez-libs +bluez-qt +bluez-utils +bolt +boost-libs +brave-bin +breeze +breeze-cursors +breeze-gtk +breeze-icons +breeze-plymouth +brotli +btrfs-progs +bubblewrap +bzip2 +ca-certificates +ca-certificates-mozilla +ca-certificates-utils +cage +cairo +cairomm +calendarsupport +cantarell-fonts +cblas +ccache +cdparanoia +cfitsio +chromaprint +cifs-utils +claude-code +claude-his-agent +clinfo +cmake +colord +colord-kde +composefs +convertlit +coreutils +cppdap +cryptsetup +cups +cups-filters +curl +danctnix-keyring +danctnix-plasma-desktop-settings +dav1d +db5.3 +dbus +dbus-broker +dbus-broker-units +dbus-glib +dbus-units +dconf +ddcutil +debugedit +default-cursors +desktop-file-utils +device-mapper +device-pine64-pinetab2 +dhcpcd +dialog +diffutils +discount +discover +distcc +djvulibre +dmidecode +dnssec-anchors +docbook-xml +docbook-xsl +dolphin +dolphin-plugins +dosfstools +double-conversion +drkonqi +drm-info +duktape +e2fsprogs +ebook-tools +editorconfig-core-c +elementary-icon-theme +elfutils +elisa +enchant +eventviews +ex-vi-compat +exfatprogs +exiv2 +exo +expat +extra-cmake-modules +f2fs-tools +faac +faad2 +fakeroot +fcft +ffmpeg-v4l2-request +ffmpeg4.4 +fftw +file +filelight +filesystem +findutils +firefox +flac +flatpak +flatpak-kcm +flex +fluidsynth +fmt +fontconfig +foot +frameworkintegration +freeglut +freerdp +freetds +freetype2 +fribidi +fuse-common +fuse2 +fuse3 +garcon +gawk +gc +gcc +gcc-libs +gcr-4 +gd +gdb +gdb-common +gdbm +gdk-pixbuf2 +gettext +ghostscript +giflib +git +glad +glib-networking +glib2 +glib2-devel +glib2-docs +glibc +glibc-locales +glibmm +glslang +glu +glycin +gmp +gnome-themes-extra +gnulib-l10n +gnupg +gnutls +go +gobject-introspection +gobject-introspection-runtime +gocryptfs +gparted +gperftools +gpgme +gpgmepp +gpm +grantleetheme +graphene +graphite +graphviz +grep +groff +gsettings-desktop-schemas +gsettings-system-schemas +gsfonts +gsm +gssdp +gst-plugins-bad +gst-plugins-bad-libs +gst-plugins-base +gst-plugins-base-libs +gst-plugins-good +gstreamer +gtest +gtk-doc +gtk-layer-shell +gtk-update-icon-cache +gtk-vnc +gtk3 +gtk4 +gtkmm3 +gtksourceview4 +gts +guile +gupnp +gupnp-igd +gwenview +gzip +harfbuzz +harfbuzz-icu +hicolor-icon-theme +hidapi +highway +hiredis +htop +hunspell +hwdata +hwloc +hyphen +i2c-tools +iana-etc +icaclient +icu +iftop +iio-sensor-proxy +ijs +imagemagick +imath +imlib2 +incidenceeditor +inetutils +iotop +iproute2 +iptables +iputils +iso-codes +itstool +iw +jansson +jasper +jbig2dec +jbigkit +jemalloc +json-c +json-glib +jsoncpp +judy +kaccounts-integration +kactivitymanagerd +kalk +karchive +kate +kauth +kbd +kbookmarks +kcalendarcore +kcalutils +kcmutils +kcodecs +kcolorpicker +kcolorscheme +kcompletion +kconfig +kconfigwidgets +kcontacts +kcoreaddons +kcrash +kdbusaddons +kde-cli-tools +kde-gtk-config +kdeclarative +kdeconnect +kdecoration +kded +kdegraphics-mobipocket +kdegraphics-thumbnailers +kdenetwork-filesharing +kdepim-addons +kdeplasma-addons +kdesu +kdiagram +kdialog +kdnssd +kdoctools +kdsoap +kdsoap-ws-discovery-client +keyutils +kfilemetadata +kgamma +kglobalaccel +kglobalacceld +kguiaddons +kholidays +ki18n +kiconthemes +kidentitymanagement +kidletime +kimageannotator +kimageformats +kimap +kinfocenter +kio +kio-admin +kio-extras +kio-fuse +kirigami +kirigami-addons +kitemmodels +kitemviews +kitinerary +kjobwidgets +kjournald +kldap +kmailtransport +kmbox +kmenuedit +kmime +kmod +knewstuff +knighttime +knotifications +knotifyconfig +konsole +kpackage +kparts +kpeople +kpimtextedit +kpipewire +kpkpass +kpty +kquickcharts +kquickimageeditor +krb5 +krdp +krecorder +krunner +kscreen +kscreenlocker +kservice +ksmtp +ksshaskpass +kstatusnotifieritem +ksvg +ksystemlog +ksystemstats +ktextaddons +ktexteditor +ktexttemplate +ktextwidgets +ktnef +kunitconversion +kuserfeedback +kwallet +kwallet-pam +kwalletmanager +kwayland +kweather +kweathercore +kwidgetsaddons +kwin-fourier +kwin-x11 +kwindowsystem +kwrited +kxmlgui +l-smash +lame +lapack +layer-shell-qt +layer-shell-qt5 +lcms2 +ldb +ldns +leancrypto +less +libaccounts-glib +libaccounts-qt +libadwaita +libarchive +libasan +libass +libassuan +libasyncns +libatasmart +libatomic +libavc1394 +libavif +libavtp +libayatana-appindicator +libayatana-indicator +libb2 +libblake3 +libblockdev +libblockdev-crypto +libblockdev-fs +libblockdev-loop +libblockdev-mdraid +libblockdev-nvme +libblockdev-part +libblockdev-smart +libblockdev-swap +libbluray +libbpf +libbs2b +libbsd +libburn +libbytesize +libc++ +libc++abi +libcaca +libcacard +libcanberra +libcap +libcap-ng +libcdio +libcdio-paranoia +libcloudproviders +libcolord +libcups +libcupsfilters +libdaemon +libdatrie +libdbusmenu-glib +libdbusmenu-gtk3 +libdc1394 +libdca +libde265 +libdecor +libdeflate +libdex +libdisplay-info +libdmtx +libdovi +libdrm +libdv +libdvdnav +libdvdread +libebur128 +libedit +libei +libelf +libepoxy +libevdev +libevent +libexif +libfakekey +libfbclient +libfdk-aac +libffi +libfontenc +libfreeaptx +libfyaml +libgcc +libgcrypt +libgfortran +libgirepository +libglvnd +libgme +libgomp +libgovirt +libgpg-error +libgravatar +libgtop +libgudev +libgusb +libheif +libical +libice +libidn +libidn2 +libiec61883 +libimobiledevice +libimobiledevice-glue +libinih +libinput +libinstpatch +libisl +libisofs +libjpeg-turbo +libjxl +libkdcraw +libkdepim +libkexiv2 +libkeybinder3 +libkgapi +libkleo +libksba +libkscreen +libksieve +libksysguard +liblc3 +libldac +libldap +libliftoff +liblqr +liblrdf +liblsan +libltc +libmakepkg-dropins +libmalcontent +libmanette +libmaxminddb +libmbim +libmd +libmicrodns +libmm-glib +libmng +libmnl +libmodplug +libmpc +libmpcdec +libmpd +libmtp +libmysofa +libnbd +libndp +libnetfilter_conntrack +libnewt +libnfnetlink +libnftnl +libnghttp2 +libnghttp3 +libngtcp2 +libnice +libnl +libnm +libnma-common +libnma-gtk4 +libnotify +libnsl +libnvme +libobjc +libogg +libopenmpt +libp11-kit +libpackagekit-glib +libpanel +libpaper +libpcap +libpciaccess +libpfm +libpgm +libphonenumber +libpipeline +libpipewire +libplacebo +libplasma +libplist +libpng +libppd +libproxy +libpsl +libpulse +libqaccessibilityclient-qt6 +libqalculate +libqmi +libqrtr-glib +libquadmath +libraqm +libraw +libraw1394 +librest +librsvg +libsamplerate +libsasl +libseccomp +libsecret +libshout +libsigc++ +libsixel +libsm +libsndfile +libsodium +libsoup +libsoup3 +libsoxr +libspectre +libsrtp +libssc +libssh +libssh2 +libstdc++ +libstemmer +libsysprof-capture +libtasn1 +libtatsu +libteam +libthai +libtheora +libtiff +libtirpc +libtommath +libtool +libtraceevent +libtsan +libubsan +libunibreak +libunistring +libunwind +liburcu +liburing +libusb +libusbmuxd +libutempter +libutf8proc +libuv +libva +libva-utils +libva-v4l2-request-ohm-gl-fix +libvdpau +libverto +libvirt +libvirt-glib +libvlc +libvorbis +libvpx +libwacom +libwbclient +libwebp +libwireplumber +libwnck3 +libx11 +libxau +libxaw +libxcb +libxcomposite +libxcrypt +libxcursor +libxcvt +libxdamage +libxdmcp +libxext +libxfce4ui +libxfce4util +libxfce4windowing +libxfixes +libxfont2 +libxft +libxi +libxinerama +libxkbcommon +libxkbcommon-x11 +libxkbfile +libxklavier +libxml2 +libxml2-legacy +libxmlb +libxmu +libxp +libxpm +libxpresent +libxrandr +libxrender +libxres +libxshmfence +libxslt +libxss +libxt +libxtst +libxv +libxxf86vm +libyaml +libyuv +libzip +licenses +lilv +linux-api-headers +linux-firmware +linux-firmware-amdgpu +linux-firmware-atheros +linux-firmware-broadcom +linux-firmware-cirrus +linux-firmware-intel +linux-firmware-mediatek +linux-firmware-nvidia +linux-firmware-other +linux-firmware-radeon +linux-firmware-realtek +linux-firmware-whence +linux-pinetab2 +linux-pinetab2-headers +lksctp-tools +llvm-libs +llvm21-libs +lm_sensors +lmcp +lmdb +lsof +lua +lua-socket +lua54 +luajit +lv2 +lz4 +lzo +m4 +mailcap +mailcommon +mailimporter +make +mallard-ducktype +man-db +mariadb +mariadb-clients +mariadb-libs +mbox-importer +md4c +mdadm +media-player-info +memtester +mesa +mesa-utils +meson +messagelib +milou +minicom +minizip +mjpegtools +mkinitcpio +mkinitcpio-busybox +mobile-broadband-provider-info +modemmanager +modemmanager-qt +mousepad +mpdecimal +mpfr +mpg123 +mpv +mtd-utils +mtdev +mtools +mujs +nano +ncurses +neon +net-tools +netctl +netpbm +nettle +networkmanager +networkmanager-openvpn +networkmanager-qt +networkmanager-vpn-plugin-openvpn +nftables +ninja +noto-fonts +noto-fonts-cjk +noto-fonts-emoji +npth +nspr +nss +nuklear +numactl +ocean-sound-theme +ocl-icd +oh-my-posh +okular +onetbb +openal +openbox +opencore-amr +opencv +openexr +openh264 +openjpeg2 +openjph +openresolv +openssh +openssl +openvpn +openxr +opus +orc +ostree +oxygen +oxygen-cursors +oxygen-icons +oxygen-sounds +p11-kit +packagekit +packagekit-qt6 +pacman +pacman-mirrorlist +pahole +pam +pambase +pango +pangomm +parole +parted +patch +pciutils +pcre +pcre2 +pcsclite +perf +perl +perl-error +perl-mailtools +perl-timedate +phodav +phonon-qt6 +phonon-qt6-vlc +picocom +pim-data-exporter +pimcommon +pinentry +pipewire +pipewire-alsa +pipewire-audio +pipewire-jack +pipewire-pulse +pipewire-session-manager +pixman +pkcs11-helper +pkgconf +plasma-activities +plasma-activities-stats +plasma-browser-integration +plasma-desktop +plasma-disks +plasma-firewall +plasma-integration +plasma-keyboard +plasma-maliit-framework +plasma-nm +plasma-pa +plasma-sdk +plasma-systemmonitor +plasma-thunderbolt +plasma-vault +plasma-welcome +plasma-workspace +plasma-workspace-wallpapers +plasma-x11-session +plasma5support +plymouth +plymouth-kcm +polkit +polkit-gnome +polkit-kde-agent +polkit-qt6 +poppler +poppler-data +poppler-qt6 +popt +portaudio +postgresql +postgresql-libs +power-profiles-daemon +powerdevil +ppp +print-manager +prison +procps-ng +protobuf +protobuf-c +psmisc +pulseaudio-qt +purpose +pv +python +python-autocommand +python-certifi +python-cffi +python-cryptography +python-dbus +python-gobject +python-iniconfig +python-jaraco.classes +python-jaraco.collections +python-jaraco.context +python-jaraco.functools +python-jaraco.text +python-jeepney +python-jinja +python-keyring +python-legacy-cgi +python-lxml +python-mako +python-markdown +python-markupsafe +python-more-itertools +python-packaging +python-pkg_resources +python-platformdirs +python-pluggy +python-psutil +python-pycparser +python-pyfakefs +python-pygdbmi +python-pygments +python-pyqt6 +python-pyqt6-sip +python-pytest +python-secretstorage +python-sentry_sdk +python-setuptools +python-tqdm +python-typing_extensions +python-urllib3 +python-wheel +qca-qt6 +qcoro +qgpgme +qpdf +qqc2-breeze-style +qqc2-desktop-style +qrencode +qt5-base +qt5-declarative +qt5-svg +qt5-translations +qt5-wayland +qt5-x11extras +qt6-5compat +qt6-base-fourier +qt6-charts +qt6-connectivity +qt6-declarative +qt6-imageformats +qt6-location +qt6-multimedia +qt6-multimedia-ffmpeg +qt6-positioning +qt6-quick3d +qt6-quicktimeline +qt6-sensors +qt6-shadertools +qt6-speech +qt6-svg +qt6-tools +qt6-translations +qt6-virtualkeyboard +qt6-wayland +qt6-webchannel +qt6-webengine +qt6-websockets +qt6-webview +qtkeychain-qt6 +raptor +rav1e +re2 +readline +remmina +renderdoc +rhash +ripgrep +ripgrep-all +ristretto +rkdeveloptool-git +rpi-imager +rsync +rtkit +rtmpdump +rubberband +ruby +rubygems +samba +sbc +screen +sddm +sddm-kcm +sdl2-compat +sdl2_ttf +sdl3 +sdl3_ttf +seatd +sed +serd +shaderc +shadow +shared-mime-info +signon-kwallet-extension +signon-plugin-oauth2 +signon-ui +signond +slang +smartmontools +smbclient +snappy +sndio +socat +solid +sonnet +sord +sound-theme-freedesktop +soundtouch +source-highlight +spandsp +spectacle +speex +speexdsp +spice-gtk +spice-protocol +spirv-tools +sqlite +sratom +srt +sshfs +startup-notification +strace +stress-ng +sudo +sweeper +syndication +syntax-highlighting +sysprof +systemd +systemd-libs +systemd-sysvcompat +systemsettings +taglib +talloc +tar +tdb +tevent +texinfo +threadweaver +thunar +thunar-archive-plugin +thunar-media-tags-plugin +thunar-volman +time +tinysparql +tpm2-tss +tslib +ttf-hack +tumbler +twolame +tzdata +uboot-pinetab2 +uboot-tools +uchardet +udisks2 +unixodbc +unzip +upower +usbredir +usbutils +util-linux +util-linux-libs +v4l-utils +vala +vapoursynth +verdict +vid.stab +vim +vim-runtime +virt-viewer +visual-studio-code-bin +vlc +vlc-cli +vlc-gui-qt +vlc-plugin-a52dec +vlc-plugin-alsa +vlc-plugin-archive +vlc-plugin-dav1d +vlc-plugin-dbus +vlc-plugin-dbus-screensaver +vlc-plugin-faad2 +vlc-plugin-ffmpeg +vlc-plugin-flac +vlc-plugin-gnutls +vlc-plugin-inflate +vlc-plugin-journal +vlc-plugin-jpeg +vlc-plugin-lua +vlc-plugin-mpg123 +vlc-plugin-ogg +vlc-plugin-opus +vlc-plugin-png +vlc-plugin-pulse +vlc-plugin-shout +vlc-plugin-speex +vlc-plugin-tag +vlc-plugin-theora +vlc-plugin-twolame +vlc-plugin-vorbis +vlc-plugin-vpx +vlc-plugin-xml +vlc-plugins-base +vlc-plugins-video-output +vmaf +volume_key +vte-common +vte3 +vulkan-extra-tools +vulkan-headers +vulkan-icd-loader +vulkan-mesa-implicit-layers +vulkan-mesa-layers +vulkan-panfrost +vulkan-tools +wacomtablet +wavpack +wayland +wayland-protocols +wayland-utils +webkit2gtk +webrtc-audio-processing-1 +weston +which +wildmidi +wireless-regdb +wireplumber +wlroots0.20 +woff2 +wpa_supplicant +x264 +x265 +xapian-core +xcb-proto +xcb-util +xcb-util-cursor +xcb-util-errors +xcb-util-image +xcb-util-keysyms +xcb-util-renderutil +xcb-util-wm +xdg-dbus-proxy +xdg-desktop-portal +xdg-desktop-portal-gtk +xdg-desktop-portal-kde +xdg-user-dirs +xdg-utils +xf86-input-libinput +xf86-input-wacom +xfburn +xfce4-appfinder +xfce4-battery-plugin +xfce4-clipman-plugin +xfce4-cpufreq-plugin +xfce4-cpugraph-plugin +xfce4-dict +xfce4-diskperf-plugin +xfce4-eyes-plugin +xfce4-fsguard-plugin +xfce4-genmon-plugin +xfce4-mailwatch-plugin +xfce4-mount-plugin +xfce4-mpc-plugin +xfce4-netload-plugin +xfce4-notes-plugin +xfce4-notifyd +xfce4-panel +xfce4-places-plugin +xfce4-power-manager +xfce4-pulseaudio-plugin +xfce4-screensaver +xfce4-screenshooter +xfce4-sensors-plugin +xfce4-session +xfce4-settings +xfce4-smartbookmark-plugin +xfce4-systemload-plugin +xfce4-taskmanager +xfce4-terminal +xfce4-time-out-plugin +xfce4-timer-plugin +xfce4-verve-plugin +xfce4-wavelan-plugin +xfce4-weather-plugin +xfce4-whiskermenu-plugin +xfce4-xkb-plugin +xfconf +xfdesktop +xfwm4 +xkeyboard-config +xmlstarlet +xorg-fonts-encodings +xorg-iceauth +xorg-server +xorg-server-common +xorg-server-xvfb +xorg-setxkbmap +xorg-xauth +xorg-xdpyinfo +xorg-xev +xorg-xinit +xorg-xinput +xorg-xkbcomp +xorg-xkill +xorg-xmessage +xorg-xmodmap +xorg-xprop +xorg-xrandr +xorg-xrdb +xorg-xset +xorg-xwayland +xorg-xwininfo +xorgproto +xsettingsd +xtrace +xvidcore +xxhash +xz +yay +yelp-tools +yelp-xsl +zbar +zeromq +zimg +zint +zix +zlib +zlib-ng +zramswap +zstd +zvbi +zxing-cpp diff --git a/phase0_evidence/x11_inventory_2026-05-03/pkglist.entry3.pre.txt b/phase0_evidence/x11_inventory_2026-05-03/pkglist.entry3.pre.txt new file mode 100644 index 0000000..2f4e198 --- /dev/null +++ b/phase0_evidence/x11_inventory_2026-05-03/pkglist.entry3.pre.txt @@ -0,0 +1,1250 @@ +a52dec +aalib +abseil-cpp +accounts-qml-module +accountsservice +acl +adwaita-cursors +adwaita-fonts +adwaita-icon-theme +adwaita-icon-theme-legacy +aha +akonadi +akonadi-calendar +akonadi-contacts +akonadi-import-wizard +akonadi-mime +akonadi-search +alsa-card-profiles +alsa-lib +alsa-topology-conf +alsa-ucm-conf +aom +apparmor +appstream +appstream-glib +appstream-qt +arch-install-scripts +archlinux-appstream-data +archlinux-keyring +archlinuxarm-keyring +argon2 +ark +asciidoctor +at-spi2-core +atkmm +attica +attr +audit +aurorae +autoconf +automake +avahi +ayatana-ido +backintime +backintime-cli +baloo +baloo-widgets +base +base-devel +bash +bash-completion +bes2600-firmware +bind +binutils +bison +blas +bluedevil +bluez +bluez-libs +bluez-qt +bluez-utils +bolt +boost-libs +brave-bin +breeze +breeze-cursors +breeze-gtk +breeze-icons +breeze-plymouth +brotli +btrfs-progs +bubblewrap +bzip2 +ca-certificates +ca-certificates-mozilla +ca-certificates-utils +cage +cairo +cairomm +calendarsupport +cantarell-fonts +cblas +ccache +cdparanoia +cfitsio +chromaprint +cifs-utils +claude-code +claude-his-agent +clinfo +cmake +colord +colord-kde +composefs +convertlit +coreutils +cppdap +cryptsetup +cups +cups-filters +curl +danctnix-keyring +danctnix-plasma-desktop-settings +dav1d +db5.3 +dbus +dbus-broker +dbus-broker-units +dbus-glib +dbus-units +dconf +ddcutil +debugedit +default-cursors +desktop-file-utils +device-mapper +device-pine64-pinetab2 +dhcpcd +dialog +diffutils +discount +discover +distcc +djvulibre +dmidecode +dnssec-anchors +docbook-xml +docbook-xsl +dolphin +dolphin-plugins +dosfstools +double-conversion +drkonqi +drm-info +duktape +e2fsprogs +ebook-tools +editorconfig-core-c +elementary-icon-theme +elfutils +elisa +enchant +eventviews +ex-vi-compat +exfatprogs +exiv2 +exo +expat +extra-cmake-modules +f2fs-tools +faac +faad2 +fakeroot +fcft +ffmpeg-v4l2-request +ffmpeg4.4 +fftw +file +filelight +filesystem +findutils +flac +flatpak +flatpak-kcm +flex +fluidsynth +fmt +fontconfig +foot +frameworkintegration +freeglut +freerdp +freetds +freetype2 +fribidi +fuse-common +fuse2 +fuse3 +garcon +gawk +gc +gcc +gcc-libs +gcr-4 +gd +gdb +gdb-common +gdbm +gdk-pixbuf2 +gettext +ghostscript +giflib +git +glad +glib-networking +glib2 +glib2-devel +glib2-docs +glibc +glibc-locales +glibmm +glslang +glu +glycin +gmp +gnome-themes-extra +gnulib-l10n +gnupg +gnutls +go +gobject-introspection +gobject-introspection-runtime +gocryptfs +gparted +gperftools +gpgme +gpgmepp +gpm +grantleetheme +graphene +graphite +graphviz +grep +groff +gsettings-desktop-schemas +gsettings-system-schemas +gsfonts +gsm +gssdp +gst-plugins-bad +gst-plugins-bad-libs +gst-plugins-base +gst-plugins-base-libs +gst-plugins-good +gstreamer +gtest +gtk-doc +gtk-layer-shell +gtk-update-icon-cache +gtk-vnc +gtk3 +gtk4 +gtkmm3 +gtksourceview4 +gts +guile +gupnp +gupnp-igd +gwenview +gzip +harfbuzz +harfbuzz-icu +hicolor-icon-theme +hidapi +highway +hiredis +htop +hunspell +hwdata +hwloc +hyphen +i2c-tools +iana-etc +icaclient +icu +iftop +iio-sensor-proxy +ijs +imagemagick +imath +imlib2 +incidenceeditor +inetutils +iotop +iproute2 +iptables +iputils +iso-codes +itstool +iw +jansson +jasper +jbig2dec +jbigkit +jemalloc +json-c +json-glib +jsoncpp +judy +kaccounts-integration +kactivitymanagerd +kalk +karchive +kate +kauth +kbd +kbookmarks +kcalendarcore +kcalutils +kcmutils +kcodecs +kcolorpicker +kcolorscheme +kcompletion +kconfig +kconfigwidgets +kcontacts +kcoreaddons +kcrash +kdbusaddons +kde-cli-tools +kde-gtk-config +kdeclarative +kdeconnect +kdecoration +kded +kdegraphics-mobipocket +kdegraphics-thumbnailers +kdenetwork-filesharing +kdepim-addons +kdeplasma-addons +kdesu +kdiagram +kdialog +kdnssd +kdoctools +kdsoap +kdsoap-ws-discovery-client +keyutils +kfilemetadata +kgamma +kglobalaccel +kglobalacceld +kguiaddons +kholidays +ki18n +kiconthemes +kidentitymanagement +kidletime +kimageannotator +kimageformats +kimap +kinfocenter +kio +kio-admin +kio-extras +kio-fuse +kirigami +kirigami-addons +kitemmodels +kitemviews +kitinerary +kjobwidgets +kjournald +kldap +kmailtransport +kmbox +kmenuedit +kmime +kmod +knewstuff +knighttime +knotifications +knotifyconfig +konsole +kpackage +kparts +kpeople +kpimtextedit +kpipewire +kpkpass +kpty +kquickcharts +kquickimageeditor +krb5 +krdp +krecorder +krunner +kscreen +kscreenlocker +kservice +ksmtp +ksshaskpass +kstatusnotifieritem +ksvg +ksystemlog +ksystemstats +ktextaddons +ktexteditor +ktexttemplate +ktextwidgets +ktnef +kunitconversion +kuserfeedback +kwallet +kwallet-pam +kwalletmanager +kwayland +kweather +kweathercore +kwidgetsaddons +kwin-fourier +kwin-x11 +kwindowsystem +kwrited +kxmlgui +l-smash +lame +lapack +layer-shell-qt +layer-shell-qt5 +lcms2 +ldb +ldns +leancrypto +less +libaccounts-glib +libaccounts-qt +libadwaita +libarchive +libasan +libass +libassuan +libasyncns +libatasmart +libatomic +libavc1394 +libavif +libavtp +libayatana-appindicator +libayatana-indicator +libb2 +libblake3 +libblockdev +libblockdev-crypto +libblockdev-fs +libblockdev-loop +libblockdev-mdraid +libblockdev-nvme +libblockdev-part +libblockdev-smart +libblockdev-swap +libbluray +libbpf +libbs2b +libbsd +libburn +libbytesize +libc++ +libc++abi +libcaca +libcacard +libcanberra +libcap +libcap-ng +libcdio +libcdio-paranoia +libcloudproviders +libcolord +libcups +libcupsfilters +libdaemon +libdatrie +libdbusmenu-glib +libdbusmenu-gtk3 +libdc1394 +libdca +libde265 +libdecor +libdeflate +libdex +libdisplay-info +libdmtx +libdovi +libdrm +libdv +libdvdnav +libdvdread +libebur128 +libedit +libei +libelf +libepoxy +libevdev +libevent +libexif +libfakekey +libfbclient +libfdk-aac +libffi +libfontenc +libfreeaptx +libfyaml +libgcc +libgcrypt +libgfortran +libgirepository +libglvnd +libgme +libgomp +libgovirt +libgpg-error +libgravatar +libgtop +libgudev +libgusb +libheif +libical +libice +libidn +libidn2 +libiec61883 +libimobiledevice +libimobiledevice-glue +libinih +libinput +libinstpatch +libisl +libisofs +libjpeg-turbo +libjxl +libkdcraw +libkdepim +libkexiv2 +libkeybinder3 +libkgapi +libkleo +libksba +libkscreen +libksieve +libksysguard +liblc3 +libldac +libldap +libliftoff +liblqr +liblrdf +liblsan +libltc +libmakepkg-dropins +libmalcontent +libmanette +libmaxminddb +libmbim +libmd +libmicrodns +libmm-glib +libmng +libmnl +libmodplug +libmpc +libmpcdec +libmpd +libmtp +libmysofa +libnbd +libndp +libnetfilter_conntrack +libnewt +libnfnetlink +libnftnl +libnghttp2 +libnghttp3 +libngtcp2 +libnice +libnl +libnm +libnma-common +libnma-gtk4 +libnotify +libnsl +libnvme +libobjc +libogg +libopenmpt +libp11-kit +libpackagekit-glib +libpanel +libpaper +libpcap +libpciaccess +libpfm +libpgm +libphonenumber +libpipeline +libpipewire +libplacebo +libplasma +libplist +libpng +libppd +libproxy +libpsl +libpulse +libqaccessibilityclient-qt6 +libqalculate +libqmi +libqrtr-glib +libquadmath +libraqm +libraw +libraw1394 +librest +librsvg +libsamplerate +libsasl +libseccomp +libsecret +libshout +libsigc++ +libsixel +libsm +libsndfile +libsodium +libsoup +libsoup3 +libsoxr +libspectre +libsrtp +libssc +libssh +libssh2 +libstdc++ +libstemmer +libsysprof-capture +libtasn1 +libtatsu +libteam +libthai +libtheora +libtiff +libtirpc +libtommath +libtool +libtraceevent +libtsan +libubsan +libunibreak +libunistring +libunwind +liburcu +liburing +libusb +libusbmuxd +libutempter +libutf8proc +libuv +libva +libva-utils +libva-v4l2-request-ohm-gl-fix +libvdpau +libverto +libvirt +libvirt-glib +libvlc +libvorbis +libvpx +libwacom +libwbclient +libwebp +libwireplumber +libwnck3 +libx11 +libxau +libxaw +libxcb +libxcomposite +libxcrypt +libxcursor +libxcvt +libxdamage +libxdmcp +libxext +libxfce4ui +libxfce4util +libxfce4windowing +libxfixes +libxfont2 +libxft +libxi +libxinerama +libxkbcommon +libxkbcommon-x11 +libxkbfile +libxklavier +libxml2 +libxml2-legacy +libxmlb +libxmu +libxp +libxpm +libxpresent +libxrandr +libxrender +libxres +libxshmfence +libxslt +libxss +libxt +libxtst +libxv +libxxf86vm +libyaml +libyuv +libzip +licenses +lilv +linux-api-headers +linux-firmware +linux-firmware-amdgpu +linux-firmware-atheros +linux-firmware-broadcom +linux-firmware-cirrus +linux-firmware-intel +linux-firmware-mediatek +linux-firmware-nvidia +linux-firmware-other +linux-firmware-radeon +linux-firmware-realtek +linux-firmware-whence +linux-pinetab2 +linux-pinetab2-headers +lksctp-tools +llvm-libs +llvm21-libs +lm_sensors +lmcp +lmdb +lsof +lua +lua-socket +lua54 +luajit +lv2 +lz4 +lzo +m4 +mailcommon +mailimporter +make +mallard-ducktype +man-db +mariadb +mariadb-clients +mariadb-libs +mbox-importer +md4c +mdadm +media-player-info +memtester +mesa +mesa-utils +meson +messagelib +milou +minicom +minizip +mjpegtools +mkinitcpio +mkinitcpio-busybox +mobile-broadband-provider-info +modemmanager +modemmanager-qt +mousepad +mpdecimal +mpfr +mpg123 +mpv +mtd-utils +mtdev +mtools +mujs +nano +ncurses +neon +net-tools +netctl +netpbm +nettle +networkmanager +networkmanager-openvpn +networkmanager-qt +networkmanager-vpn-plugin-openvpn +nftables +ninja +noto-fonts +noto-fonts-cjk +noto-fonts-emoji +npth +nspr +nss +nuklear +numactl +ocean-sound-theme +ocl-icd +oh-my-posh +okular +onetbb +openal +openbox +opencore-amr +opencv +openexr +openh264 +openjpeg2 +openjph +openresolv +openssh +openssl +openvpn +openxr +opus +orc +ostree +oxygen +oxygen-cursors +oxygen-icons +oxygen-sounds +p11-kit +packagekit +packagekit-qt6 +pacman +pacman-mirrorlist +pahole +pam +pambase +pango +pangomm +parole +parted +patch +pciutils +pcre +pcre2 +pcsclite +perf +perl +perl-error +perl-mailtools +perl-timedate +phodav +phonon-qt6 +phonon-qt6-vlc +picocom +pim-data-exporter +pimcommon +pinentry +pipewire +pipewire-alsa +pipewire-audio +pipewire-jack +pipewire-pulse +pipewire-session-manager +pixman +pkcs11-helper +pkgconf +plasma-activities +plasma-activities-stats +plasma-browser-integration +plasma-desktop +plasma-disks +plasma-firewall +plasma-integration +plasma-keyboard +plasma-maliit-framework +plasma-nm +plasma-pa +plasma-sdk +plasma-systemmonitor +plasma-thunderbolt +plasma-vault +plasma-welcome +plasma-workspace +plasma-workspace-wallpapers +plasma-x11-session +plasma5support +plymouth +plymouth-kcm +polkit +polkit-gnome +polkit-kde-agent +polkit-qt6 +poppler +poppler-data +poppler-qt6 +popt +portaudio +postgresql +postgresql-libs +power-profiles-daemon +powerdevil +ppp +print-manager +prison +procps-ng +protobuf +protobuf-c +psmisc +pulseaudio-qt +purpose +pv +python +python-autocommand +python-certifi +python-cffi +python-cryptography +python-dbus +python-gobject +python-iniconfig +python-jaraco.classes +python-jaraco.collections +python-jaraco.context +python-jaraco.functools +python-jaraco.text +python-jeepney +python-jinja +python-keyring +python-legacy-cgi +python-lxml +python-mako +python-markdown +python-markupsafe +python-more-itertools +python-packaging +python-pkg_resources +python-platformdirs +python-pluggy +python-psutil +python-pycparser +python-pyfakefs +python-pygdbmi +python-pygments +python-pyqt6 +python-pyqt6-sip +python-pytest +python-secretstorage +python-sentry_sdk +python-setuptools +python-tqdm +python-typing_extensions +python-urllib3 +python-wheel +qca-qt6 +qcoro +qgpgme +qpdf +qqc2-breeze-style +qqc2-desktop-style +qrencode +qt5-base +qt5-declarative +qt5-svg +qt5-translations +qt5-wayland +qt5-x11extras +qt6-5compat +qt6-base-fourier +qt6-charts +qt6-connectivity +qt6-declarative +qt6-imageformats +qt6-location +qt6-multimedia +qt6-multimedia-ffmpeg +qt6-positioning +qt6-quick3d +qt6-quicktimeline +qt6-sensors +qt6-shadertools +qt6-speech +qt6-svg +qt6-tools +qt6-translations +qt6-virtualkeyboard +qt6-wayland +qt6-webchannel +qt6-webengine +qt6-websockets +qt6-webview +qtkeychain-qt6 +raptor +rav1e +re2 +readline +remmina +renderdoc +rhash +ripgrep +ripgrep-all +ristretto +rkdeveloptool-git +rpi-imager +rsync +rtkit +rtmpdump +rubberband +ruby +rubygems +samba +sbc +screen +sddm +sddm-kcm +sdl2-compat +sdl2_ttf +sdl3 +sdl3_ttf +seatd +sed +serd +shaderc +shadow +shared-mime-info +signon-kwallet-extension +signon-plugin-oauth2 +signon-ui +signond +slang +smartmontools +smbclient +snappy +sndio +socat +solid +sonnet +sord +sound-theme-freedesktop +soundtouch +source-highlight +spandsp +spectacle +speex +speexdsp +spice-gtk +spice-protocol +spirv-tools +sqlite +sratom +srt +sshfs +startup-notification +strace +stress-ng +sudo +sweeper +syndication +syntax-highlighting +sysprof +systemd +systemd-libs +systemd-sysvcompat +systemsettings +taglib +talloc +tar +tdb +tevent +texinfo +threadweaver +thunar +thunar-archive-plugin +thunar-media-tags-plugin +thunar-volman +time +tinysparql +tpm2-tss +tslib +ttf-hack +tumbler +twolame +tzdata +uboot-pinetab2 +uboot-tools +uchardet +udisks2 +unixodbc +unzip +upower +usbredir +usbutils +util-linux +util-linux-libs +v4l-utils +vala +vapoursynth +verdict +vid.stab +vim +vim-runtime +virt-viewer +visual-studio-code-bin +vlc +vlc-cli +vlc-gui-qt +vlc-plugin-a52dec +vlc-plugin-alsa +vlc-plugin-archive +vlc-plugin-dav1d +vlc-plugin-dbus +vlc-plugin-dbus-screensaver +vlc-plugin-faad2 +vlc-plugin-ffmpeg +vlc-plugin-flac +vlc-plugin-gnutls +vlc-plugin-inflate +vlc-plugin-journal +vlc-plugin-jpeg +vlc-plugin-lua +vlc-plugin-mpg123 +vlc-plugin-ogg +vlc-plugin-opus +vlc-plugin-png +vlc-plugin-pulse +vlc-plugin-shout +vlc-plugin-speex +vlc-plugin-tag +vlc-plugin-theora +vlc-plugin-twolame +vlc-plugin-vorbis +vlc-plugin-vpx +vlc-plugin-xml +vlc-plugins-base +vlc-plugins-video-output +vmaf +volume_key +vte-common +vte3 +vulkan-extra-tools +vulkan-headers +vulkan-icd-loader +vulkan-mesa-implicit-layers +vulkan-mesa-layers +vulkan-panfrost +vulkan-tools +wacomtablet +wavpack +wayland +wayland-protocols +wayland-utils +webkit2gtk +webrtc-audio-processing-1 +weston +which +wildmidi +wireless-regdb +wireplumber +wlroots0.20 +woff2 +wpa_supplicant +x264 +x265 +xapian-core +xcb-proto +xcb-util +xcb-util-cursor +xcb-util-errors +xcb-util-image +xcb-util-keysyms +xcb-util-renderutil +xcb-util-wm +xdg-dbus-proxy +xdg-desktop-portal +xdg-desktop-portal-gtk +xdg-desktop-portal-kde +xdg-user-dirs +xdg-utils +xf86-input-libinput +xf86-input-wacom +xfburn +xfce4-appfinder +xfce4-battery-plugin +xfce4-clipman-plugin +xfce4-cpufreq-plugin +xfce4-cpugraph-plugin +xfce4-dict +xfce4-diskperf-plugin +xfce4-eyes-plugin +xfce4-fsguard-plugin +xfce4-genmon-plugin +xfce4-mailwatch-plugin +xfce4-mount-plugin +xfce4-mpc-plugin +xfce4-netload-plugin +xfce4-notes-plugin +xfce4-notifyd +xfce4-panel +xfce4-places-plugin +xfce4-power-manager +xfce4-pulseaudio-plugin +xfce4-screensaver +xfce4-screenshooter +xfce4-sensors-plugin +xfce4-session +xfce4-settings +xfce4-smartbookmark-plugin +xfce4-systemload-plugin +xfce4-taskmanager +xfce4-terminal +xfce4-time-out-plugin +xfce4-timer-plugin +xfce4-verve-plugin +xfce4-wavelan-plugin +xfce4-weather-plugin +xfce4-whiskermenu-plugin +xfce4-xkb-plugin +xfconf +xfdesktop +xfwm4 +xkeyboard-config +xmlstarlet +xorg-fonts-encodings +xorg-iceauth +xorg-server +xorg-server-common +xorg-server-xvfb +xorg-setxkbmap +xorg-xauth +xorg-xdpyinfo +xorg-xev +xorg-xinit +xorg-xinput +xorg-xkbcomp +xorg-xkill +xorg-xmessage +xorg-xmodmap +xorg-xprop +xorg-xrandr +xorg-xrdb +xorg-xset +xorg-xwayland +xorg-xwininfo +xorgproto +xsettingsd +xvidcore +xxhash +xz +yay +yelp-tools +yelp-xsl +zbar +zeromq +zimg +zint +zix +zlib +zlib-ng +zramswap +zstd +zvbi +zxing-cpp diff --git a/phase0_evidence/x11_inventory_2026-05-03/pkglist.post.txt b/phase0_evidence/x11_inventory_2026-05-03/pkglist.post.txt new file mode 100644 index 0000000..b057406 --- /dev/null +++ b/phase0_evidence/x11_inventory_2026-05-03/pkglist.post.txt @@ -0,0 +1,1180 @@ +a52dec +aalib +abseil-cpp +accounts-qml-module +accountsservice +acl +adwaita-cursors +adwaita-fonts +adwaita-icon-theme +adwaita-icon-theme-legacy +aha +akonadi +akonadi-calendar +akonadi-contacts +akonadi-import-wizard +akonadi-mime +akonadi-search +alsa-card-profiles +alsa-lib +alsa-topology-conf +alsa-ucm-conf +aom +apparmor +appstream +appstream-glib +appstream-qt +arch-install-scripts +archlinux-appstream-data +archlinux-keyring +archlinuxarm-keyring +argon2 +ark +asciidoctor +at-spi2-core +atkmm +attica +attr +audit +aurorae +autoconf +automake +avahi +ayatana-ido +backintime +backintime-cli +baloo +baloo-widgets +base +base-devel +bash +bash-completion +bes2600-firmware +bind +binutils +bison +blas +bluedevil +bluez +bluez-libs +bluez-qt +bluez-utils +bolt +boost-libs +brave-bin +breeze +breeze-cursors +breeze-gtk +breeze-icons +breeze-plymouth +brotli +btrfs-progs +bubblewrap +bzip2 +ca-certificates +ca-certificates-mozilla +ca-certificates-utils +cage +cairo +cairomm +calendarsupport +cantarell-fonts +cblas +ccache +cdparanoia +cfitsio +chromaprint +cifs-utils +claude-code +claude-his-agent +clinfo +cmake +colord +colord-kde +composefs +convertlit +coreutils +cppdap +cryptsetup +cups +cups-filters +curl +danctnix-keyring +danctnix-plasma-desktop-settings +dav1d +db5.3 +dbus +dbus-broker +dbus-broker-units +dbus-units +dconf +ddcutil +debugedit +default-cursors +desktop-file-utils +device-mapper +device-pine64-pinetab2 +dhcpcd +dialog +diffutils +discount +discover +distcc +djvulibre +dmidecode +dnssec-anchors +docbook-xml +docbook-xsl +dolphin +dolphin-plugins +dosfstools +double-conversion +drkonqi +drm-info +duktape +e2fsprogs +ebook-tools +editorconfig-core-c +elfutils +elisa +enchant +eventviews +ex-vi-compat +exfatprogs +exiv2 +expat +extra-cmake-modules +f2fs-tools +faac +faad2 +fakeroot +fcft +ffmpeg-v4l2-request +ffmpeg4.4 +fftw +file +filelight +filesystem +findutils +flac +flatpak +flatpak-kcm +flex +fluidsynth +fmt +fontconfig +foot +frameworkintegration +freeglut +freerdp +freetds +freetype2 +fribidi +fuse-common +fuse2 +fuse3 +gawk +gc +gcc +gcc-libs +gcr-4 +gd +gdb +gdb-common +gdbm +gdk-pixbuf2 +gettext +ghostscript +giflib +git +glad +glib-networking +glib2 +glib2-devel +glib2-docs +glibc +glibc-locales +glibmm +glslang +glu +glycin +gmp +gnulib-l10n +gnupg +gnutls +go +gobject-introspection +gobject-introspection-runtime +gocryptfs +gparted +gperftools +gpgme +gpgmepp +gpm +grantleetheme +graphene +graphite +graphviz +grep +groff +gsettings-desktop-schemas +gsettings-system-schemas +gsfonts +gsm +gssdp +gst-plugins-bad +gst-plugins-bad-libs +gst-plugins-base +gst-plugins-base-libs +gst-plugins-good +gstreamer +gtest +gtk-doc +gtk-update-icon-cache +gtk-vnc +gtk3 +gtk4 +gtkmm3 +gts +guile +gupnp +gupnp-igd +gwenview +gzip +harfbuzz +harfbuzz-icu +hicolor-icon-theme +hidapi +highway +hiredis +htop +hunspell +hwdata +hwloc +hyphen +i2c-tools +iana-etc +icaclient +icu +iftop +iio-sensor-proxy +ijs +imagemagick +imath +imlib2 +incidenceeditor +inetutils +iotop +iproute2 +iptables +iputils +iso-codes +itstool +iw +jansson +jasper +jbig2dec +jbigkit +jemalloc +json-c +json-glib +jsoncpp +judy +kaccounts-integration +kactivitymanagerd +kalk +karchive +kate +kauth +kbd +kbookmarks +kcalendarcore +kcalutils +kcmutils +kcodecs +kcolorpicker +kcolorscheme +kcompletion +kconfig +kconfigwidgets +kcontacts +kcoreaddons +kcrash +kdbusaddons +kde-cli-tools +kde-gtk-config +kdeclarative +kdeconnect +kdecoration +kded +kdegraphics-mobipocket +kdegraphics-thumbnailers +kdenetwork-filesharing +kdepim-addons +kdeplasma-addons +kdesu +kdiagram +kdialog +kdnssd +kdoctools +kdsoap +kdsoap-ws-discovery-client +keyutils +kfilemetadata +kgamma +kglobalaccel +kglobalacceld +kguiaddons +kholidays +ki18n +kiconthemes +kidentitymanagement +kidletime +kimageannotator +kimageformats +kimap +kinfocenter +kio +kio-admin +kio-extras +kio-fuse +kirigami +kirigami-addons +kitemmodels +kitemviews +kitinerary +kjobwidgets +kjournald +kldap +kmailtransport +kmbox +kmenuedit +kmime +kmod +knewstuff +knighttime +knotifications +knotifyconfig +konsole +kpackage +kparts +kpeople +kpimtextedit +kpipewire +kpkpass +kpty +kquickcharts +kquickimageeditor +krb5 +krdp +krecorder +krunner +kscreen +kscreenlocker +kservice +ksmtp +ksshaskpass +kstatusnotifieritem +ksvg +ksystemlog +ksystemstats +ktextaddons +ktexteditor +ktexttemplate +ktextwidgets +ktnef +kunitconversion +kuserfeedback +kwallet +kwallet-pam +kwalletmanager +kwayland +kweather +kweathercore +kwidgetsaddons +kwin-fourier +kwin-x11 +kwindowsystem +kwrited +kxmlgui +l-smash +lame +lapack +layer-shell-qt +layer-shell-qt5 +lcms2 +ldb +ldns +leancrypto +less +libaccounts-glib +libaccounts-qt +libadwaita +libarchive +libasan +libass +libassuan +libasyncns +libatasmart +libatomic +libavc1394 +libavif +libavtp +libayatana-appindicator +libayatana-indicator +libb2 +libblake3 +libblockdev +libblockdev-crypto +libblockdev-fs +libblockdev-loop +libblockdev-mdraid +libblockdev-nvme +libblockdev-part +libblockdev-smart +libblockdev-swap +libbluray +libbpf +libbs2b +libbsd +libbytesize +libc++ +libc++abi +libcaca +libcacard +libcanberra +libcap +libcap-ng +libcdio +libcdio-paranoia +libcloudproviders +libcolord +libcups +libcupsfilters +libdaemon +libdatrie +libdbusmenu-glib +libdbusmenu-gtk3 +libdc1394 +libdca +libde265 +libdecor +libdeflate +libdex +libdisplay-info +libdmtx +libdovi +libdrm +libdv +libdvdnav +libdvdread +libebur128 +libedit +libei +libelf +libepoxy +libevdev +libevent +libexif +libfakekey +libfbclient +libfdk-aac +libffi +libfontenc +libfreeaptx +libfyaml +libgcc +libgcrypt +libgfortran +libgirepository +libglvnd +libgme +libgomp +libgovirt +libgpg-error +libgravatar +libgudev +libgusb +libheif +libical +libice +libidn +libidn2 +libiec61883 +libimobiledevice +libimobiledevice-glue +libinih +libinput +libinstpatch +libisl +libjpeg-turbo +libjxl +libkdcraw +libkdepim +libkexiv2 +libkgapi +libkleo +libksba +libkscreen +libksieve +libksysguard +liblc3 +libldac +libldap +libliftoff +liblqr +liblrdf +liblsan +libltc +libmakepkg-dropins +libmalcontent +libmanette +libmaxminddb +libmbim +libmd +libmicrodns +libmm-glib +libmng +libmnl +libmodplug +libmpc +libmpcdec +libmtp +libmysofa +libnbd +libndp +libnetfilter_conntrack +libnewt +libnfnetlink +libnftnl +libnghttp2 +libnghttp3 +libngtcp2 +libnice +libnl +libnm +libnma-common +libnma-gtk4 +libnotify +libnsl +libnvme +libobjc +libogg +libopenmpt +libp11-kit +libpackagekit-glib +libpanel +libpaper +libpcap +libpciaccess +libpfm +libpgm +libphonenumber +libpipeline +libpipewire +libplacebo +libplasma +libplist +libpng +libppd +libproxy +libpsl +libpulse +libqaccessibilityclient-qt6 +libqalculate +libqmi +libqrtr-glib +libquadmath +libraqm +libraw +libraw1394 +librest +librsvg +libsamplerate +libsasl +libseccomp +libsecret +libshout +libsigc++ +libsixel +libsm +libsndfile +libsodium +libsoup +libsoup3 +libsoxr +libspectre +libsrtp +libssc +libssh +libssh2 +libstdc++ +libstemmer +libsysprof-capture +libtasn1 +libtatsu +libteam +libthai +libtheora +libtiff +libtirpc +libtommath +libtool +libtraceevent +libtsan +libubsan +libunibreak +libunistring +libunwind +liburcu +liburing +libusb +libusbmuxd +libutempter +libutf8proc +libuv +libva +libva-utils +libva-v4l2-request-ohm-gl-fix +libvdpau +libverto +libvirt +libvirt-glib +libvlc +libvorbis +libvpx +libwacom +libwbclient +libwebp +libwireplumber +libx11 +libxau +libxaw +libxcb +libxcomposite +libxcrypt +libxcursor +libxcvt +libxdamage +libxdmcp +libxext +libxfixes +libxfont2 +libxft +libxi +libxinerama +libxkbcommon +libxkbcommon-x11 +libxkbfile +libxml2 +libxml2-legacy +libxmlb +libxmu +libxp +libxpm +libxpresent +libxrandr +libxrender +libxshmfence +libxslt +libxss +libxt +libxtst +libxv +libxxf86vm +libyaml +libyuv +libzip +licenses +lilv +linux-api-headers +linux-firmware +linux-firmware-amdgpu +linux-firmware-atheros +linux-firmware-broadcom +linux-firmware-cirrus +linux-firmware-intel +linux-firmware-mediatek +linux-firmware-nvidia +linux-firmware-other +linux-firmware-radeon +linux-firmware-realtek +linux-firmware-whence +linux-pinetab2 +linux-pinetab2-headers +lksctp-tools +llvm-libs +llvm21-libs +lm_sensors +lmcp +lmdb +lsof +lua +lua-socket +lua54 +luajit +lv2 +lz4 +lzo +m4 +mailcommon +mailimporter +make +mallard-ducktype +man-db +mariadb +mariadb-clients +mariadb-libs +mbox-importer +md4c +mdadm +media-player-info +memtester +mesa +mesa-utils +meson +messagelib +milou +minicom +minizip +mjpegtools +mkinitcpio +mkinitcpio-busybox +mobile-broadband-provider-info +modemmanager +modemmanager-qt +mpdecimal +mpfr +mpg123 +mpv +mtd-utils +mtdev +mtools +mujs +nano +ncurses +neon +net-tools +netctl +netpbm +nettle +networkmanager +networkmanager-openvpn +networkmanager-qt +networkmanager-vpn-plugin-openvpn +nftables +ninja +noto-fonts +noto-fonts-cjk +noto-fonts-emoji +npth +nspr +nss +nuklear +numactl +ocean-sound-theme +ocl-icd +oh-my-posh +okular +onetbb +openal +openbox +opencore-amr +opencv +openexr +openh264 +openjpeg2 +openjph +openresolv +openssh +openssl +openvpn +openxr +opus +orc +ostree +oxygen +oxygen-cursors +oxygen-icons +oxygen-sounds +p11-kit +packagekit +packagekit-qt6 +pacman +pacman-mirrorlist +pahole +pam +pambase +pango +pangomm +parted +patch +pciutils +pcre +pcre2 +pcsclite +perf +perl +perl-error +perl-mailtools +perl-timedate +phodav +phonon-qt6 +phonon-qt6-vlc +picocom +pim-data-exporter +pimcommon +pinentry +pipewire +pipewire-alsa +pipewire-audio +pipewire-jack +pipewire-pulse +pipewire-session-manager +pixman +pkcs11-helper +pkgconf +plasma-activities +plasma-activities-stats +plasma-browser-integration +plasma-desktop +plasma-disks +plasma-firewall +plasma-integration +plasma-keyboard +plasma-maliit-framework +plasma-nm +plasma-pa +plasma-sdk +plasma-systemmonitor +plasma-thunderbolt +plasma-vault +plasma-welcome +plasma-workspace +plasma-workspace-wallpapers +plasma-x11-session +plasma5support +plymouth +plymouth-kcm +polkit +polkit-kde-agent +polkit-qt6 +poppler +poppler-data +poppler-qt6 +popt +portaudio +postgresql +postgresql-libs +power-profiles-daemon +powerdevil +ppp +print-manager +prison +procps-ng +protobuf +protobuf-c +psmisc +pulseaudio-qt +purpose +pv +python +python-autocommand +python-certifi +python-cffi +python-cryptography +python-dbus +python-gobject +python-iniconfig +python-jaraco.classes +python-jaraco.collections +python-jaraco.context +python-jaraco.functools +python-jaraco.text +python-jeepney +python-jinja +python-keyring +python-legacy-cgi +python-lxml +python-mako +python-markdown +python-markupsafe +python-more-itertools +python-packaging +python-pkg_resources +python-platformdirs +python-pluggy +python-psutil +python-pycparser +python-pyfakefs +python-pygdbmi +python-pygments +python-pyqt6 +python-pyqt6-sip +python-pytest +python-secretstorage +python-sentry_sdk +python-setuptools +python-tqdm +python-typing_extensions +python-urllib3 +python-wheel +qca-qt6 +qcoro +qgpgme +qpdf +qqc2-breeze-style +qqc2-desktop-style +qrencode +qt5-base +qt5-declarative +qt5-svg +qt5-translations +qt5-wayland +qt5-x11extras +qt6-5compat +qt6-base-fourier +qt6-charts +qt6-connectivity +qt6-declarative +qt6-imageformats +qt6-location +qt6-multimedia +qt6-multimedia-ffmpeg +qt6-positioning +qt6-quick3d +qt6-quicktimeline +qt6-sensors +qt6-shadertools +qt6-speech +qt6-svg +qt6-tools +qt6-translations +qt6-virtualkeyboard +qt6-wayland +qt6-webchannel +qt6-webengine +qt6-websockets +qt6-webview +qtkeychain-qt6 +raptor +rav1e +re2 +readline +remmina +renderdoc +rhash +ripgrep +ripgrep-all +rkdeveloptool-git +rpi-imager +rsync +rtkit +rtmpdump +rubberband +ruby +rubygems +samba +sbc +screen +sddm +sddm-kcm +sdl2-compat +sdl2_ttf +sdl3 +sdl3_ttf +seatd +sed +serd +shaderc +shadow +shared-mime-info +signon-kwallet-extension +signon-plugin-oauth2 +signon-ui +signond +slang +smartmontools +smbclient +snappy +sndio +socat +solid +sonnet +sord +sound-theme-freedesktop +soundtouch +source-highlight +spandsp +spectacle +speex +speexdsp +spice-gtk +spice-protocol +spirv-tools +sqlite +sratom +srt +sshfs +startup-notification +strace +stress-ng +sudo +sweeper +syndication +syntax-highlighting +sysprof +systemd +systemd-libs +systemd-sysvcompat +systemsettings +taglib +talloc +tar +tdb +tevent +texinfo +threadweaver +time +tinysparql +tpm2-tss +tslib +ttf-hack +twolame +tzdata +uboot-pinetab2 +uboot-tools +uchardet +udisks2 +unixodbc +unzip +upower +usbredir +usbutils +util-linux +util-linux-libs +v4l-utils +vala +vapoursynth +verdict +vid.stab +vim +vim-runtime +virt-viewer +visual-studio-code-bin +vlc +vlc-cli +vlc-gui-qt +vlc-plugin-a52dec +vlc-plugin-alsa +vlc-plugin-archive +vlc-plugin-dav1d +vlc-plugin-dbus +vlc-plugin-dbus-screensaver +vlc-plugin-faad2 +vlc-plugin-ffmpeg +vlc-plugin-flac +vlc-plugin-gnutls +vlc-plugin-inflate +vlc-plugin-journal +vlc-plugin-jpeg +vlc-plugin-lua +vlc-plugin-mpg123 +vlc-plugin-ogg +vlc-plugin-opus +vlc-plugin-png +vlc-plugin-pulse +vlc-plugin-shout +vlc-plugin-speex +vlc-plugin-tag +vlc-plugin-theora +vlc-plugin-twolame +vlc-plugin-vorbis +vlc-plugin-vpx +vlc-plugin-xml +vlc-plugins-base +vlc-plugins-video-output +vmaf +volume_key +vte-common +vte3 +vulkan-extra-tools +vulkan-headers +vulkan-icd-loader +vulkan-mesa-implicit-layers +vulkan-mesa-layers +vulkan-panfrost +vulkan-tools +wacomtablet +wavpack +wayland +wayland-protocols +wayland-utils +webkit2gtk +webrtc-audio-processing-1 +weston +which +wildmidi +wireless-regdb +wireplumber +wlroots0.20 +woff2 +wpa_supplicant +x264 +x265 +xapian-core +xcb-proto +xcb-util +xcb-util-cursor +xcb-util-errors +xcb-util-image +xcb-util-keysyms +xcb-util-renderutil +xcb-util-wm +xdg-dbus-proxy +xdg-desktop-portal +xdg-desktop-portal-gtk +xdg-desktop-portal-kde +xdg-user-dirs +xdg-utils +xf86-input-libinput +xf86-input-wacom +xkeyboard-config +xmlstarlet +xorg-fonts-encodings +xorg-server +xorg-server-common +xorg-server-xvfb +xorg-setxkbmap +xorg-xauth +xorg-xdpyinfo +xorg-xev +xorg-xinput +xorg-xkbcomp +xorg-xkill +xorg-xmessage +xorg-xprop +xorg-xrandr +xorg-xrdb +xorg-xset +xorg-xwayland +xorg-xwininfo +xorgproto +xsettingsd +xvidcore +xxhash +xz +yay +yelp-tools +yelp-xsl +zbar +zeromq +zimg +zint +zix +zlib +zlib-ng +zramswap +zstd +zvbi +zxing-cpp diff --git a/phase0_evidence/x11_inventory_2026-05-03/pkglist.pre.txt b/phase0_evidence/x11_inventory_2026-05-03/pkglist.pre.txt new file mode 100644 index 0000000..2b9c52e --- /dev/null +++ b/phase0_evidence/x11_inventory_2026-05-03/pkglist.pre.txt @@ -0,0 +1,1169 @@ +a52dec +aalib +abseil-cpp +accounts-qml-module +accountsservice +acl +adwaita-cursors +adwaita-fonts +adwaita-icon-theme +adwaita-icon-theme-legacy +aha +akonadi +akonadi-calendar +akonadi-contacts +akonadi-import-wizard +akonadi-mime +akonadi-search +alsa-card-profiles +alsa-lib +alsa-topology-conf +alsa-ucm-conf +aom +apparmor +appstream +appstream-glib +appstream-qt +arch-install-scripts +archlinux-appstream-data +archlinux-keyring +archlinuxarm-keyring +argon2 +ark +asciidoctor +at-spi2-core +atkmm +attica +attr +audit +aurorae +autoconf +automake +avahi +ayatana-ido +backintime +backintime-cli +baloo +baloo-widgets +base +base-devel +bash +bash-completion +bes2600-firmware +bind +binutils +bison +blas +bluedevil +bluez +bluez-libs +bluez-qt +bluez-utils +bolt +boost-libs +brave-bin +breeze +breeze-cursors +breeze-gtk +breeze-icons +breeze-plymouth +brotli +btrfs-progs +bubblewrap +bzip2 +ca-certificates +ca-certificates-mozilla +ca-certificates-utils +cage +cairo +cairomm +calendarsupport +cantarell-fonts +cblas +ccache +cdparanoia +cfitsio +chromaprint +cifs-utils +claude-code +claude-his-agent +clinfo +cmake +colord +colord-kde +composefs +convertlit +coreutils +cppdap +cryptsetup +cups +cups-filters +curl +danctnix-keyring +danctnix-plasma-desktop-settings +dav1d +db5.3 +dbus +dbus-broker +dbus-broker-units +dbus-units +dconf +ddcutil +debugedit +default-cursors +desktop-file-utils +device-mapper +device-pine64-pinetab2 +dhcpcd +dialog +diffutils +discount +discover +distcc +djvulibre +dmidecode +dnssec-anchors +docbook-xml +docbook-xsl +dolphin +dolphin-plugins +dosfstools +double-conversion +drkonqi +drm-info +duktape +e2fsprogs +ebook-tools +editorconfig-core-c +elfutils +elisa +enchant +eventviews +ex-vi-compat +exfatprogs +exiv2 +expat +extra-cmake-modules +f2fs-tools +faac +faad2 +fakeroot +fcft +ffmpeg-v4l2-request +ffmpeg4.4 +fftw +file +filelight +filesystem +findutils +flac +flatpak +flatpak-kcm +flex +fluidsynth +fmt +fontconfig +foot +frameworkintegration +freeglut +freerdp +freetds +freetype2 +fribidi +fuse-common +fuse2 +fuse3 +gawk +gc +gcc +gcc-libs +gcr-4 +gd +gdb +gdb-common +gdbm +gdk-pixbuf2 +gettext +ghostscript +giflib +git +glad +glib-networking +glib2 +glib2-devel +glib2-docs +glibc +glibc-locales +glibmm +glslang +glu +glycin +gmp +gnulib-l10n +gnupg +gnutls +go +gobject-introspection +gobject-introspection-runtime +gocryptfs +gparted +gperftools +gpgme +gpgmepp +gpm +grantleetheme +graphene +graphite +graphviz +grep +groff +gsettings-desktop-schemas +gsettings-system-schemas +gsfonts +gsm +gssdp +gst-plugins-bad +gst-plugins-bad-libs +gst-plugins-base +gst-plugins-base-libs +gst-plugins-good +gstreamer +gtest +gtk-doc +gtk-update-icon-cache +gtk-vnc +gtk3 +gtk4 +gtkmm3 +gts +guile +gupnp +gupnp-igd +gwenview +gzip +harfbuzz +harfbuzz-icu +hicolor-icon-theme +hidapi +highway +hiredis +htop +hunspell +hwdata +hwloc +hyphen +i2c-tools +iana-etc +icaclient +icu +iftop +iio-sensor-proxy +ijs +imagemagick +imath +imlib2 +incidenceeditor +inetutils +iotop +iproute2 +iptables +iputils +iso-codes +itstool +iw +jansson +jasper +jbig2dec +jbigkit +jemalloc +json-c +json-glib +jsoncpp +judy +kaccounts-integration +kactivitymanagerd +kalk +karchive +kate +kauth +kbd +kbookmarks +kcalendarcore +kcalutils +kcmutils +kcodecs +kcolorpicker +kcolorscheme +kcompletion +kconfig +kconfigwidgets +kcontacts +kcoreaddons +kcrash +kdbusaddons +kde-cli-tools +kde-gtk-config +kdeclarative +kdeconnect +kdecoration +kded +kdegraphics-mobipocket +kdegraphics-thumbnailers +kdenetwork-filesharing +kdepim-addons +kdeplasma-addons +kdesu +kdiagram +kdialog +kdnssd +kdoctools +kdsoap +kdsoap-ws-discovery-client +keyutils +kfilemetadata +kgamma +kglobalaccel +kglobalacceld +kguiaddons +kholidays +ki18n +kiconthemes +kidentitymanagement +kidletime +kimageannotator +kimageformats +kimap +kinfocenter +kio +kio-admin +kio-extras +kio-fuse +kirigami +kirigami-addons +kitemmodels +kitemviews +kitinerary +kjobwidgets +kjournald +kldap +kmailtransport +kmbox +kmenuedit +kmime +kmod +knewstuff +knighttime +knotifications +knotifyconfig +konsole +kpackage +kparts +kpeople +kpimtextedit +kpipewire +kpkpass +kpty +kquickcharts +kquickimageeditor +krb5 +krdp +krecorder +krunner +kscreen +kscreenlocker +kservice +ksmtp +ksshaskpass +kstatusnotifieritem +ksvg +ksystemlog +ksystemstats +ktextaddons +ktexteditor +ktexttemplate +ktextwidgets +ktnef +kunitconversion +kuserfeedback +kwallet +kwallet-pam +kwalletmanager +kwayland +kweather +kweathercore +kwidgetsaddons +kwin-fourier +kwin-x11 +kwindowsystem +kwrited +kxmlgui +l-smash +lame +lapack +layer-shell-qt +layer-shell-qt5 +lcms2 +ldb +ldns +leancrypto +less +libaccounts-glib +libaccounts-qt +libarchive +libasan +libass +libassuan +libasyncns +libatasmart +libatomic +libavc1394 +libavif +libavtp +libayatana-appindicator +libayatana-indicator +libb2 +libblake3 +libblockdev +libblockdev-crypto +libblockdev-fs +libblockdev-loop +libblockdev-mdraid +libblockdev-nvme +libblockdev-part +libblockdev-smart +libblockdev-swap +libbluray +libbpf +libbs2b +libbsd +libbytesize +libc++ +libc++abi +libcaca +libcacard +libcanberra +libcap +libcap-ng +libcdio +libcdio-paranoia +libcloudproviders +libcolord +libcups +libcupsfilters +libdaemon +libdatrie +libdbusmenu-glib +libdbusmenu-gtk3 +libdc1394 +libdca +libde265 +libdecor +libdeflate +libdisplay-info +libdmtx +libdovi +libdrm +libdv +libdvdnav +libdvdread +libebur128 +libedit +libei +libelf +libepoxy +libevdev +libevent +libexif +libfakekey +libfbclient +libfdk-aac +libffi +libfontenc +libfreeaptx +libfyaml +libgcc +libgcrypt +libgfortran +libgirepository +libglvnd +libgme +libgomp +libgovirt +libgpg-error +libgravatar +libgudev +libgusb +libheif +libical +libice +libidn +libidn2 +libiec61883 +libimobiledevice +libimobiledevice-glue +libinih +libinput +libinstpatch +libisl +libjpeg-turbo +libjxl +libkdcraw +libkdepim +libkexiv2 +libkgapi +libkleo +libksba +libkscreen +libksieve +libksysguard +liblc3 +libldac +libldap +libliftoff +liblqr +liblrdf +liblsan +libltc +libmakepkg-dropins +libmalcontent +libmanette +libmaxminddb +libmbim +libmd +libmicrodns +libmm-glib +libmng +libmnl +libmodplug +libmpc +libmpcdec +libmtp +libmysofa +libnbd +libndp +libnetfilter_conntrack +libnewt +libnfnetlink +libnftnl +libnghttp2 +libnghttp3 +libngtcp2 +libnice +libnl +libnm +libnma-common +libnma-gtk4 +libnotify +libnsl +libnvme +libobjc +libogg +libopenmpt +libp11-kit +libpackagekit-glib +libpaper +libpcap +libpciaccess +libpfm +libpgm +libphonenumber +libpipeline +libpipewire +libplacebo +libplasma +libplist +libpng +libppd +libproxy +libpsl +libpulse +libqaccessibilityclient-qt6 +libqalculate +libqmi +libqrtr-glib +libquadmath +libraqm +libraw +libraw1394 +librest +librsvg +libsamplerate +libsasl +libseccomp +libsecret +libshout +libsigc++ +libsixel +libsm +libsndfile +libsodium +libsoup +libsoup3 +libsoxr +libspectre +libsrtp +libssc +libssh +libssh2 +libstdc++ +libstemmer +libsysprof-capture +libtasn1 +libtatsu +libteam +libthai +libtheora +libtiff +libtirpc +libtommath +libtool +libtraceevent +libtsan +libubsan +libunibreak +libunistring +libunwind +liburcu +liburing +libusb +libusbmuxd +libutempter +libutf8proc +libuv +libva +libva-utils +libva-v4l2-request-ohm-gl-fix +libvdpau +libverto +libvirt +libvirt-glib +libvlc +libvorbis +libvpx +libwacom +libwbclient +libwebp +libwireplumber +libx11 +libxau +libxaw +libxcb +libxcomposite +libxcrypt +libxcursor +libxcvt +libxdamage +libxdmcp +libxext +libxfixes +libxfont2 +libxft +libxi +libxinerama +libxkbcommon +libxkbcommon-x11 +libxkbfile +libxml2 +libxml2-legacy +libxmlb +libxmu +libxp +libxpm +libxpresent +libxrandr +libxrender +libxshmfence +libxslt +libxss +libxt +libxtst +libxv +libxxf86vm +libyaml +libyuv +libzip +licenses +lilv +linux-api-headers +linux-firmware +linux-firmware-amdgpu +linux-firmware-atheros +linux-firmware-broadcom +linux-firmware-cirrus +linux-firmware-intel +linux-firmware-mediatek +linux-firmware-nvidia +linux-firmware-other +linux-firmware-radeon +linux-firmware-realtek +linux-firmware-whence +linux-pinetab2 +linux-pinetab2-headers +lksctp-tools +llvm-libs +llvm21-libs +lm_sensors +lmcp +lmdb +lsof +lua +lua-socket +lua54 +luajit +lv2 +lz4 +lzo +m4 +mailcommon +mailimporter +make +mallard-ducktype +man-db +mariadb +mariadb-clients +mariadb-libs +mbox-importer +md4c +mdadm +media-player-info +memtester +mesa +mesa-utils +meson +messagelib +milou +minicom +minizip +mjpegtools +mkinitcpio +mkinitcpio-busybox +mobile-broadband-provider-info +modemmanager +modemmanager-qt +mpdecimal +mpfr +mpg123 +mpv +mtd-utils +mtdev +mtools +mujs +nano +ncurses +neon +net-tools +netctl +netpbm +nettle +networkmanager +networkmanager-openvpn +networkmanager-qt +networkmanager-vpn-plugin-openvpn +nftables +ninja +noto-fonts +noto-fonts-cjk +noto-fonts-emoji +npth +nspr +nss +nuklear +numactl +ocean-sound-theme +ocl-icd +oh-my-posh +okular +onetbb +openal +opencore-amr +opencv +openexr +openh264 +openjpeg2 +openjph +openresolv +openssh +openssl +openvpn +openxr +opus +orc +ostree +oxygen +oxygen-cursors +oxygen-icons +oxygen-sounds +p11-kit +packagekit +packagekit-qt6 +pacman +pacman-mirrorlist +pahole +pam +pambase +pango +pangomm +parted +patch +pciutils +pcre +pcre2 +pcsclite +perf +perl +perl-error +perl-mailtools +perl-timedate +phodav +phonon-qt6 +phonon-qt6-vlc +picocom +pim-data-exporter +pimcommon +pinentry +pipewire +pipewire-alsa +pipewire-audio +pipewire-jack +pipewire-pulse +pipewire-session-manager +pixman +pkcs11-helper +pkgconf +plasma-activities +plasma-activities-stats +plasma-browser-integration +plasma-desktop +plasma-disks +plasma-firewall +plasma-integration +plasma-keyboard +plasma-maliit-framework +plasma-nm +plasma-pa +plasma-sdk +plasma-systemmonitor +plasma-thunderbolt +plasma-vault +plasma-welcome +plasma-workspace +plasma-workspace-wallpapers +plasma-x11-session +plasma5support +plymouth +plymouth-kcm +polkit +polkit-kde-agent +polkit-qt6 +poppler +poppler-data +poppler-qt6 +popt +portaudio +postgresql +postgresql-libs +power-profiles-daemon +powerdevil +ppp +print-manager +prison +procps-ng +protobuf +protobuf-c +psmisc +pulseaudio-qt +purpose +pv +python +python-autocommand +python-certifi +python-cffi +python-cryptography +python-dbus +python-gobject +python-iniconfig +python-jaraco.classes +python-jaraco.collections +python-jaraco.context +python-jaraco.functools +python-jaraco.text +python-jeepney +python-jinja +python-keyring +python-legacy-cgi +python-lxml +python-mako +python-markdown +python-markupsafe +python-more-itertools +python-packaging +python-pkg_resources +python-platformdirs +python-pluggy +python-psutil +python-pycparser +python-pyfakefs +python-pygdbmi +python-pygments +python-pyqt6 +python-pyqt6-sip +python-pytest +python-secretstorage +python-sentry_sdk +python-setuptools +python-tqdm +python-typing_extensions +python-urllib3 +python-wheel +qca-qt6 +qcoro +qgpgme +qpdf +qqc2-breeze-style +qqc2-desktop-style +qrencode +qt5-base +qt5-declarative +qt5-svg +qt5-translations +qt5-wayland +qt5-x11extras +qt6-5compat +qt6-base-fourier +qt6-charts +qt6-connectivity +qt6-declarative +qt6-imageformats +qt6-location +qt6-multimedia +qt6-multimedia-ffmpeg +qt6-positioning +qt6-quick3d +qt6-quicktimeline +qt6-sensors +qt6-shadertools +qt6-speech +qt6-svg +qt6-tools +qt6-translations +qt6-virtualkeyboard +qt6-wayland +qt6-webchannel +qt6-webengine +qt6-websockets +qt6-webview +qtkeychain-qt6 +raptor +rav1e +re2 +readline +remmina +renderdoc +rhash +ripgrep +ripgrep-all +rkdeveloptool-git +rpi-imager +rsync +rtkit +rtmpdump +rubberband +ruby +rubygems +samba +sbc +screen +sddm +sddm-kcm +sdl2-compat +sdl2_ttf +sdl3 +sdl3_ttf +seatd +sed +serd +shaderc +shadow +shared-mime-info +signon-kwallet-extension +signon-plugin-oauth2 +signon-ui +signond +slang +smartmontools +smbclient +snappy +sndio +socat +solid +sonnet +sord +sound-theme-freedesktop +soundtouch +source-highlight +spandsp +spectacle +speex +speexdsp +spice-gtk +spice-protocol +spirv-tools +sqlite +sratom +srt +sshfs +strace +stress-ng +sudo +sweeper +syndication +syntax-highlighting +systemd +systemd-libs +systemd-sysvcompat +systemsettings +taglib +talloc +tar +tdb +tevent +texinfo +threadweaver +time +tinysparql +tpm2-tss +tslib +ttf-hack +twolame +tzdata +uboot-pinetab2 +uboot-tools +uchardet +udisks2 +unixodbc +unzip +upower +usbredir +usbutils +util-linux +util-linux-libs +v4l-utils +vala +vapoursynth +verdict +vid.stab +vim +vim-runtime +virt-viewer +visual-studio-code-bin +vlc +vlc-cli +vlc-gui-qt +vlc-plugin-a52dec +vlc-plugin-alsa +vlc-plugin-archive +vlc-plugin-dav1d +vlc-plugin-dbus +vlc-plugin-dbus-screensaver +vlc-plugin-faad2 +vlc-plugin-ffmpeg +vlc-plugin-flac +vlc-plugin-gnutls +vlc-plugin-inflate +vlc-plugin-journal +vlc-plugin-jpeg +vlc-plugin-lua +vlc-plugin-mpg123 +vlc-plugin-ogg +vlc-plugin-opus +vlc-plugin-png +vlc-plugin-pulse +vlc-plugin-shout +vlc-plugin-speex +vlc-plugin-tag +vlc-plugin-theora +vlc-plugin-twolame +vlc-plugin-vorbis +vlc-plugin-vpx +vlc-plugin-xml +vlc-plugins-base +vlc-plugins-video-output +vmaf +volume_key +vte-common +vte3 +vulkan-extra-tools +vulkan-headers +vulkan-icd-loader +vulkan-mesa-implicit-layers +vulkan-mesa-layers +vulkan-panfrost +vulkan-tools +wacomtablet +wavpack +wayland +wayland-protocols +wayland-utils +webkit2gtk +webrtc-audio-processing-1 +weston +which +wildmidi +wireless-regdb +wireplumber +wlroots0.20 +woff2 +wpa_supplicant +x264 +x265 +xapian-core +xcb-proto +xcb-util +xcb-util-cursor +xcb-util-errors +xcb-util-image +xcb-util-keysyms +xcb-util-renderutil +xcb-util-wm +xdg-dbus-proxy +xdg-desktop-portal +xdg-desktop-portal-gtk +xdg-desktop-portal-kde +xdg-user-dirs +xdg-utils +xf86-input-libinput +xf86-input-wacom +xkeyboard-config +xmlstarlet +xorg-fonts-encodings +xorg-server +xorg-server-common +xorg-server-xvfb +xorg-setxkbmap +xorg-xauth +xorg-xdpyinfo +xorg-xkbcomp +xorg-xmessage +xorg-xprop +xorg-xrdb +xorg-xset +xorg-xwayland +xorgproto +xsettingsd +xvidcore +xxhash +xz +yay +yelp-tools +yelp-xsl +zbar +zeromq +zimg +zint +zix +zlib +zlib-ng +zramswap +zstd +zvbi +zxing-cpp diff --git a/phase0_evidence/x11_inventory_2026-05-03/revert.log b/phase0_evidence/x11_inventory_2026-05-03/revert.log new file mode 100644 index 0000000..93fec9a --- /dev/null +++ b/phase0_evidence/x11_inventory_2026-05-03/revert.log @@ -0,0 +1,483 @@ +# revert.log — campaign-installed state on ohm + +This file lists every change this campaign made to ohm's *system +state* during Phase 0 inventory work that was done **purely for +testing and analysis**. To return ohm to the state it was in +before this campaign opened, run the "Revert" commands at the +bottom of this file in order. + +This file is updated whenever the campaign installs a package or +mutates a sysctl/service/config. Closing the campaign without +reverting is a deliberate operator decision; if reverted, this +file is the authoritative record of what to undo. + +Inherited state from the predecessor (`kwin_overlay_subsurface`) +is **not** in scope here — those carry-overs are documented in +`README.md` § "Carry-overs from predecessor (system state, not +data)" and would be reverted via that campaign's +`phase1_evidence/ohm_tooling_revert_log.md` instead. + +--- + +## Entry 1 — 2026-05-03 ~09:20 CEST + +**Trigger:** Phase 0 deliverables 2 + 4 (`x11_inventory_2026-05-03/inventory.md`) +identified missing measurement tools and the absence of a +non-compositing WM. Operator instructed: "fire the installs." + +**Driven from:** `mfritsche@noether` over SSH to `ohm.fritz.box`, +passwordless `sudo` (verified before firing). + +**Pre-install snapshot:** `pkglist.pre.txt` (1169 packages, +sha256 `fd72bcf6a7289d2f2dd6ce02706240006b534731540bf63f56ee9b666e7be68f`). +**Post-install snapshot:** `pkglist.post.txt` (1180 packages). +**Full pacman transaction log:** `pacman.install.log`. + +### What was installed + +Single transaction: `sudo pacman -Sy && sudo pacman -S --needed +xorg-xrandr xorg-xev xorg-xinput xorg-xwininfo xorg-xkill sysprof openbox` + +| Package | Version | Reason | +|---|---|---| +| xorg-xrandr | 1.5.4-1 | explicit — RandR CLI for output/vblank probing | +| xorg-xev | 1.2.6-2 | explicit — per-window event capture | +| xorg-xinput | 1.6.4-2 | explicit — input-device probe (touchscreen confound) | +| xorg-xwininfo | 1.1.6-2 | explicit — get browser window geometry/wid | +| xorg-xkill | 1.0.7-1 | explicit — clean kill of stuck X clients between reps | +| sysprof | 50.0-2 | explicit — kernel perf alternative w/ flamegraph default | +| openbox | 3.6.1-14 | explicit — non-compositing WM for the without-KWin matrix cell | +| libadwaita | 1:1.9.0-1 | dep of sysprof | +| libdex | 1.1.0-1 | dep of sysprof | +| libpanel | 1.10.4-1 | dep of sysprof | +| startup-notification | 0.12-9 | dep of openbox | + +11 added, 0 removed. Cross-checked via `comm -13 +pkglist.pre.txt pkglist.post.txt` — exact same 11. + +### What was changed (config, not packages) + +- **`/etc/sysctl.d/90-x11-research-perf.conf` was created with + `kernel.perf_event_paranoid = 1`, then reverted same session.** + - Created: applied via `sudo sysctl --system`; effective + value went 2 → 1. + - Verification probe revealed the tweak was **not delivering + the promised behavior**: even with `task-clock` (a software + event that should be allowed at paranoid=1), `perf record + -p ` on this aarch64 kernel still failed with + "Failure to open any events for recording". Predecessor + pattern confirmed in + `kwin_overlay_subsurface/phase3_protocol.md:121,158,216`: + they used **`sudo perf record`** per-rep, not a sysctl + tweak. Passwordless sudo over SSH already works on ohm so + this is unattended-friendly. + - Reverted: `sudo rm /etc/sysctl.d/90-x11-research-perf.conf` + and `sudo sysctl kernel.perf_event_paranoid=2` (the + `--system` reapply does not reset removed-file values; an + explicit set was required). + - Net state change: **none** (paranoid back at kernel + default 2; `/etc/sysctl.d/` empty again). + - Lesson: the inventory's "set paranoid=1" recommendation + was wrong. Updated `inventory.md` will reflect that the + actual pattern is `sudo perf record -p ` per-rep. + +### What was created as a side effect (no operator action) + +- `/usr/share/xsessions/openbox.desktop` (shipped by the + `openbox` package). SDDM will list "Openbox" as a session + choice on next greet. Removing the openbox package removes + the .desktop file. + +### What was *not* installed (deliberate, operator-decision-pending) + +- **firefox** — 2 of the 6 matrix cells reference Firefox + (`C-W-ff-*`, `C-X-ff-*`). Operator decides whether to install + or to mark those cells N/A. If installed later, append a new + entry below. +- **xtrace (X protocol tracer, AUR)** — explicitly marked + optional in `inventory.md`. The matrix's primary metrics + (effective_fps / drops / latency / CPU%) don't require it. + If installed later, append a new entry below. + +--- + +## Entry 2 — 2026-05-03 ~09:30 CEST + +**Trigger:** Operator preference for a desktop-environment-flavored +without-KWin testbed alongside the bare openbox cell ("I like +desktop environments. With respect to the test - should xfce or +cinnamon be our test bed?" → "yes add xfce with goodies"). +Cinnamon was excluded because Muffin is a mandatory compositor; +XFCE qualifies if `xfwm4`'s built-in compositor is left disabled. + +**Driven from:** `mfritsche@noether` over SSH to `ohm.fritz.box`, +passwordless `sudo`. + +**Pre-install snapshot:** `pkglist.entry2.pre.txt` (1180 packages, +sha256 `1f72c7ed2f9d476d24d0dfb53fcb387ea39f882c89375d68fc21298313252d78`). +**Post-install snapshot:** `pkglist.entry2.post.txt` (1250 packages). +**Full pacman transaction log:** `pacman.entry2.log`. + +### What was installed + +Single transaction: `sudo pacman -S --needed xfce4 xfce4-goodies` +(both are package groups; pacman expanded them). + +- **50 explicit packages** (the union of the `xfce4` group's 14 + members and the `xfce4-goodies` group's 36 members): + exo, garcon, mousepad, parole, ristretto, thunar, thunar-archive-plugin, + thunar-media-tags-plugin, thunar-volman, tumbler, xfburn, + xfce4-appfinder, xfce4-battery-plugin, xfce4-clipman-plugin, + xfce4-cpufreq-plugin, xfce4-cpugraph-plugin, xfce4-dict, + xfce4-diskperf-plugin, xfce4-eyes-plugin, xfce4-fsguard-plugin, + xfce4-genmon-plugin, xfce4-mailwatch-plugin, xfce4-mount-plugin, + xfce4-mpc-plugin, xfce4-netload-plugin, xfce4-notes-plugin, + xfce4-notifyd, xfce4-panel, xfce4-places-plugin, + xfce4-power-manager, xfce4-pulseaudio-plugin, xfce4-screensaver, + xfce4-screenshooter, xfce4-sensors-plugin, xfce4-session, + xfce4-settings, xfce4-smartbookmark-plugin, xfce4-systemload-plugin, + xfce4-taskmanager, xfce4-terminal, xfce4-time-out-plugin, + xfce4-timer-plugin, xfce4-verve-plugin, xfce4-wavelan-plugin, + xfce4-weather-plugin, xfce4-whiskermenu-plugin, xfce4-xkb-plugin, + xfconf, xfdesktop, xfwm4 +- **20 transitive deps**: + dbus-glib, elementary-icon-theme, gnome-themes-extra, + gtk-layer-shell, gtksourceview4, libburn, libgtop, libisofs, + libkeybinder3, libmpd, libwnck3, libxfce4ui, libxfce4util, + libxfce4windowing, libxklavier, libxres, polkit-gnome, + xorg-iceauth, xorg-xinit, xorg-xmodmap + +70 added, 0 removed. Cross-checked via +`comm -13 pkglist.entry2.pre.txt pkglist.entry2.post.txt` — full +list in `entry2.added.list` (sourced from same diff). + +### What was changed (config) + +- **`~/.config/xfce4/xfconf/xfce-perchannel-xml/xfwm4.xml` created** + (208 bytes), pre-seeding `general/use_compositing = false`. This + ensures the **first XFCE login lands with xfwm4's built-in GL + compositor disabled**, matching the matrix's "without-KWin = + no compositor in the display path" definition. Without this + pre-seed, `xfwm4` would default to `use_compositing=true` and + the operator would have to remember to toggle it via *Settings + → Window Manager Tweaks → Compositor* before every measurement + rep — a confound waiting to happen. + + The directory tree `~/.config/xfce4/` did not exist before this + write; the entire tree is removable. + +### What was created as a side effect (no operator action) + +- `/usr/share/xsessions/xfce.desktop` (shipped by `xfce4-session`). + SDDM now lists three X11 sessions: openbox.desktop (entry 1), + plasmax11.desktop (pre-existing), xfce.desktop (this entry). + +### After-revert verification + +The first-login compositor pre-seed is per-user state in +`~/.config/xfce4/`. The revert procedure deletes the entire +xfce4 user-config tree if (and only if) it contains nothing but +the pre-seeded xfwm4.xml. If the operator logs into XFCE before +revert, xfconfd will populate that tree with other settings +files; the revert then becomes a manual decision. + +--- + +## Entry 3 — 2026-05-03 ~09:45 CEST + +**Trigger:** Operator instructed "install both" — closing the two +operator-decision items left open in entry 1's "What was *not* +installed" section: firefox (matrix completeness — 2 of 6 cells +need it) and the X-protocol tracer xtrace. + +**Driven from:** `mfritsche@noether` over SSH to `ohm.fritz.box`, +passwordless `sudo` for pacman, regular user for `yay` / +`makepkg`. + +**Pre-install snapshot:** `pkglist.entry3.pre.txt` (1250 packages, +sha256 `e73ffdd41b683aaba2ad18efa5ce3e7252577c13b4f0bb14e9de7bdfbfd5e26e`). +**Post-install snapshot:** `pkglist.entry3.post.txt` (1253 packages). +**Transaction logs:** `pacman.entry3a.firefox.log`, +`pacman.entry3b.xtrace.log`. + +### What was installed + +Two transactions in one entry: + +| Package | Version | Source | Reason | +|---|---|---|---| +| firefox | 150.0.1-1 | extra | explicit — matrix's `C-W-ff-*` and `C-X-ff-*` cells | +| mailcap | 2.1.54-2 | extra | dep of firefox | +| xtrace | 1.4.0-2 | AUR | explicit — X protocol tracer (parallel to `WAYLAND_DEBUG=1`) | + +3 added, 0 removed. + +Firefox was a clean `pacman -S firefox`. xtrace went via +`yay -G xtrace; cd ~/.cache/yay/xtrace; makepkg -s --noconfirm +--ignorearch; sudo pacman -U --noconfirm xtrace-1.4.0-2-aarch64.pkg.tar.zst`. +The `--ignorearch` was needed because the AUR PKGBUILD declares +`arch=('i686' 'x86_64')` only — the package builds cleanly on +aarch64, the maintainer just hasn't updated the array. + +### File-conflict probe (no actual conflict) + +A pre-install probe suggested AUR `xtrace` would conflict with +glibc's `/usr/bin/xtrace` (glibc ships a syscall-tracer shell +script under that path). Investigation showed the **Arch AUR +PKGBUILD renames the binary to `/usr/bin/x11trace`** specifically +to avoid this collision. Both binaries now coexist: + +- `/usr/bin/xtrace` — glibc's syscall/function tracer (5 KB + bash script). Unchanged. +- `/usr/bin/x11trace` — the X protocol tracer (133 KB aarch64 + ELF, AUR `xtrace` 1.4.0). New. + +The early `pacman -U --overwrite '/usr/bin/xtrace'` flag turned +out to be unnecessary; pacman would have allowed the install +without it because nothing actually overlapped on disk. No +state was overwritten. + +### Verification + +- `firefox --version` → `Mozilla Firefox 150.0.1` +- `x11trace --version` → `xtrace version 1.4.0` +- `x11trace --help` confirms X-protocol semantics + ("Dump all X protocol data being tunneled from a fake X + display to a real one") +- `head -3 /usr/bin/xtrace` still shows the GNU libc copyright + banner — glibc's xtrace untouched. + +### What is now fully resolved from earlier "operator-decision-pending" + +- ✅ firefox installed → all 6 matrix cells now have a binary + available. +- ✅ xtrace (X protocol tracer) installed at `/usr/bin/x11trace` + → if any Phase 1 cell wants protocol-level evidence parallel + to the predecessor's `WAYLAND_DEBUG=1`, the instrument is + ready. + +--- + +## Entry 4 — 2026-05-03 ~10:25 CEST + +**Trigger:** Operator was in the freshly-switched XFCE session +("Can you rotate the xfce session for me? Right now, left is up +and right is down"). The PineTab2 panel is mounted portrait +(native mode 800×1280@59.98) and XFCE's default rotation +("normal") shows it that way; Plasma X11 / Plasma Wayland have +historically used `right` rotation to present landscape +1280×800. This entry brings XFCE in line. + +**Driven from:** `mfritsche@noether` over SSH to `ohm.fritz.box`, +regular user (no sudo needed; per-user state only). + +### What was changed + +1. **Live rotation applied** to the active XFCE session (session + id 395, Xorg pid 32073, DISPLAY=:0, + XAUTHORITY=/run/user/1001/xauth_QctOSR): + ``` + xrandr --output DSI-1 --rotate right + ``` + Result: `Screen 0 ... current 1280 x 800` and `DSI-1 + connected 1280x800+0+0 right`. Matches the Plasma X11 + orientation. + +2. **Persistence: `~/.config/autostart/99-rotate-dsi1.desktop` + created** so every future XFCE login runs the rotation + immediately. File contents: + ``` + [Desktop Entry] + Type=Application + Name=Rotate DSI-1 to landscape (right) + Comment=Created 2026-05-03 by x11-session-research campaign — + see phase0_evidence/x11_inventory_2026-05-03/revert.log entry 4 + Exec=sh -c "xrandr --output DSI-1 --rotate right" + OnlyShowIn=XFCE; + Terminal=false + ``` + `OnlyShowIn=XFCE` keeps it from running under Plasma X11 / + openbox — those handle their own rotation state. + +### Why not via xfconf + +XFCE's `displays` xfconf channel was empty +(`xfconf-query -c displays -lv` showed only `/ActiveProfile` += `Default` with no per-monitor data). xfce4-display-settings +populates that profile on first GUI use; without that population, +writing rotation codes by hand into xfconf is brittle (the +encoding of "right" depends on xfce4-settings version). An +autostart .desktop file is version-independent and easy to +inspect. + +If the operator subsequently runs *Settings → Display* in the +XFCE GUI and clicks Save / Apply, xfconf will write a real +profile and the autostart file becomes redundant — at that +point either can stay (no conflict) or the autostart can be +removed. + +### What is NOT changed + +- No system-wide config touched. +- No package install. +- Plasma X11 and openbox sessions unaffected — `OnlyShowIn=XFCE` + scopes the autostart to XFCE only. +- Touchscreen orientation: **NOT** auto-corrected by this entry. + After rotation, the Goodix Capacitive TouchScreen will likely + report touches in the panel's native (portrait) coordinate + space, so taps land on the wrong screen position. Fix when + it becomes a concern: + ``` + xinput map-to-output "Goodix Capacitive TouchScreen" DSI-1 + ``` + This is **not auto-applied** in this entry because the matrix + cells use mouse + keyboard for navigation, not touch — and + also because mapping the touchscreen would itself need + another autostart entry. If touch becomes relevant later, + add it as entry 5. + +--- + +## Entry 5 — 2026-05-03 ~10:29 CEST + +**Trigger:** Operator confirmed XFCE session alive after entry 4 +("xfce-session alive"), then accepted the touchscreen-mapping +follow-up offered in entry 4's "What is NOT changed" note. + +**Driven from:** `mfritsche@noether` over SSH to `ohm.fritz.box`, +regular user. + +### What was changed + +1. **Live mapping applied:** + ``` + xinput map-to-output "pointer:Goodix Capacitive TouchScreen" DSI-1 + ``` + The `pointer:` prefix is required because the Goodix exposes + both a pointer device (id 13) and a keyboard subdevice + (id 15) — `xinput` needs the disambiguation. Verified by + `xinput list-props`: Coordinate Transformation Matrix + updated to `[0 1 0 / -1 0 1 / 0 0 1]` — the homogeneous + 90°-clockwise rotation matrix matching the screen. + +2. **Persistence: + `~/.config/autostart/99-rotate-touchscreen.desktop` created**. + Same `OnlyShowIn=XFCE` scoping. The Exec uses `sh -c "sleep 2; + xinput ..."` because XFCE may launch this autostart before + entry 4's xrandr rotation has finished applying — without + the sleep, the xinput remap can race against an unrotated + screen state. + +### What is NOT changed + +- Other input devices (touchpad, USB mouse, USB keyboard) + unchanged — they don't report panel-relative coordinates so + rotation doesn't affect them. +- Plasma X11 / openbox sessions unaffected + (`OnlyShowIn=XFCE`). +- Wayland sessions unaffected (xinput is X11-only). When KDE + Plasma Wayland next runs, it uses its own + `kwriteconfig5 --file kwinrc` mapping — that's predecessor + state, not touched here. + +--- + +## How to revert this campaign's installs + +Entries reverted in **reverse order** (entry 5 → 4 → 3 → 2 → 1): + +```sh +ssh ohm.fritz.box ' + set -e + + # ----- Entry 5 revert: touchscreen mapping ----- + rm -f ~/.config/autostart/99-rotate-touchscreen.desktop + # Live revert: reset Coordinate Transformation Matrix to identity. + # Only meaningful in an X11 session; harmless if no XFCE running. + if pgrep -x xfwm4 >/dev/null; then + DISPLAY=:0 XAUTHORITY=$(ls /run/user/$(id -u)/xauth_* 2>/dev/null | head -1) \ + xinput set-prop "pointer:Goodix Capacitive TouchScreen" \ + "Coordinate Transformation Matrix" \ + 1 0 0 0 1 0 0 0 1 || true + fi + + # ----- Entry 4 revert: XFCE rotation ----- + rm -f ~/.config/autostart/99-rotate-dsi1.desktop + # Live rotation revert (only if currently in XFCE): + if pgrep -x xfwm4 >/dev/null; then + DISPLAY=:0 XAUTHORITY=$(ls /run/user/$(id -u)/xauth_* 2>/dev/null | head -1) \ + xrandr --output DSI-1 --rotate normal || true + fi + + # ----- Entry 3 revert: firefox + xtrace ----- + sudo pacman -Rsn --noconfirm firefox xtrace + # mailcap was pulled as a firefox dep; -Rs cleans it up if no other + # dependent remains. + + # ----- Entry 2 revert: XFCE ----- + sudo pacman -Rsn --noconfirm \ + exo garcon mousepad parole ristretto thunar \ + thunar-archive-plugin thunar-media-tags-plugin thunar-volman tumbler \ + xfburn xfce4-appfinder xfce4-battery-plugin xfce4-clipman-plugin \ + xfce4-cpufreq-plugin xfce4-cpugraph-plugin xfce4-dict \ + xfce4-diskperf-plugin xfce4-eyes-plugin xfce4-fsguard-plugin \ + xfce4-genmon-plugin xfce4-mailwatch-plugin xfce4-mount-plugin \ + xfce4-mpc-plugin xfce4-netload-plugin xfce4-notes-plugin \ + xfce4-notifyd xfce4-panel xfce4-places-plugin xfce4-power-manager \ + xfce4-pulseaudio-plugin xfce4-screensaver xfce4-screenshooter \ + xfce4-sensors-plugin xfce4-session xfce4-settings \ + xfce4-smartbookmark-plugin xfce4-systemload-plugin xfce4-taskmanager \ + xfce4-terminal xfce4-time-out-plugin xfce4-timer-plugin \ + xfce4-verve-plugin xfce4-wavelan-plugin xfce4-weather-plugin \ + xfce4-whiskermenu-plugin xfce4-xkb-plugin xfconf xfdesktop xfwm4 + + # Per-user xfconf tree: only safe to remove if the operator never + # logged into XFCE (otherwise xfconfd may have written other settings + # the operator would lose). Manual check: + if [ "$(find ~/.config/xfce4 -type f | sort)" = "$HOME/.config/xfce4/xfconf/xfce-perchannel-xml/xfwm4.xml" ]; then + rm -rf ~/.config/xfce4 + echo " ~/.config/xfce4 removed (only the pre-seeded xfwm4.xml was there)" + else + echo " ~/.config/xfce4 contains operator-added files; manual review required" + find ~/.config/xfce4 -type f + fi + + # ----- Entry 1 revert: measurement tools + openbox ----- + sudo pacman -Rsn --noconfirm \ + openbox sysprof \ + xorg-xrandr xorg-xev xorg-xinput xorg-xwininfo xorg-xkill + + # Sysctl: nothing to undo (entry 1's paranoid=1 was already reverted + # in-session — see entry 1 § "What was changed"). + + # ----- Verification ----- + echo "expected pkg count after revert: 1169" + pacman -Qq | wc -l + + echo "expected sysctl: kernel.perf_event_paranoid = 2" + sysctl kernel.perf_event_paranoid + + echo "expected sessions: only plasmax11.desktop" + ls /usr/share/xsessions/ + + echo "expected /etc/sysctl.d/: empty" + ls /etc/sysctl.d/ +' +``` + +Sanity-check: `pacman -Qq | wc -l` should report **1169**, matching +`pkglist.pre.txt`. If it reports anything else, the operator +added/removed a package between an entry and the revert; +investigate before declaring revert complete. + +--- + +## Adding a new entry + +When a future Phase install/mutation happens, append a new +`## Entry N — YYYY-MM-DD` section above the "How to revert" +section. Re-snapshot `pacman -Qq` into a new +`pkglist.entryN.{pre,post}.txt` so each entry is independently +revertible. Prepend the new entry's revert step to the +"How to revert" block (entries revert in reverse install +order — newest first). diff --git a/phase0_findings.md b/phase0_findings.md index ef3c407..8c64b7a 100644 --- a/phase0_findings.md +++ b/phase0_findings.md @@ -279,17 +279,48 @@ dominates per browser × decode path. ### Experimental matrix -Six 2-axis cells (3 browsers × 2 decode paths) × 2 -session conditions (with-KWin / without-KWin): +Eight 2-axis cells (3 browsers + 1 reference client × 2 decode +paths) × 2 session conditions (with-KWin / without-KWin): -| Browser | Decode | with-KWin (Plasma Wayland) | without-KWin (X11 session, no compositor) | +| Client | Decode | with-KWin (Plasma Wayland) | without-KWin (X11 session, no compositor) | |---|---|---|---| | Brave 147 | full SW | C-W-brave-sw | C-X-brave-sw | | Brave 147 | libva (if it works) | C-W-brave-libva | C-X-brave-libva | | chromium-fourier 149 (Step 1 + Step 2) | full SW | C-W-chrf-sw | C-X-chrf-sw | | chromium-fourier 149 | libva (Step 1 enables it) | C-W-chrf-libva | C-X-chrf-libva | -| Firefox | full SW | C-W-ff-sw | C-X-ff-sw | -| Firefox | libva | C-W-ff-libva | C-X-ff-libva | +| Firefox 150 | full SW | C-W-ff-sw | C-X-ff-sw | +| Firefox 150 | libva | C-W-ff-libva | C-X-ff-libva | +| **mpv 0.41 (reference)** | **full SW** | **C-W-mpv-sw** | **C-X-mpv-sw** | +| **mpv 0.41 (reference)** | **libva / v4l2request** | **C-W-mpv-hw** | **C-X-mpv-hw** | + +Each mpv cell is run twice — once with `--vo=xv` (XVideo +extension, the legacy X11-hardware-overlay path mpv has used +since the late 1990s) and once with `--vo=gpu --gpu-context=x11` +(modern Mesa GL + DRI3 + XPresent path). Two VOs × 8 mpv cells += 16 mpv data points. The two mpv VOs probe orthogonal +questions: + +- `--vo=xv`: does the X server's XVideo adapter route NV12 to + a hardware plane on rockchip-drm RK3568 at all? If yes, + XVideo is a known-good baseline that the browsers' more + modern overlay paths *should* match or beat. +- `--vo=gpu --gpu-context=x11`: does the Mesa Panfrost + GL+DRI3+XPresent path on rockchip allow the X server to + route an NV12 dmabuf to Plane 39 (the Primary plane, the + only NV12-LINEAR-capable plane on this hardware)? This is + the same plumbing the browsers use, so a positive result + here means the browsers *could* but might not. A negative + result means even mpv can't, in which case the browsers + cannot either. + +mpv's role is **reference baseline**, not target. If both mpv +VOs show clean hardware-overlay scanout but the browsers don't, +the campaign verdict is "the X11 path is fast on this hardware, +but the browsers leave the speedup on the table." If even mpv's +two VOs can't engage Plane 39 NV12, the "X11 hardware-overlay +mechanism is structurally avoidable" claim is challenged on +this specific kernel/Mesa stack and the campaign needs to +re-frame. The "(if it works)" / "where possible" qualifier per the operator's directive: libva on rockchip-drm RK3568 only works @@ -298,7 +329,9 @@ stock Brave 147 and stock Firefox, libva probably doesn't engage and those cells are documented N/A. For Firefox, the Mesa-side `libva-v4l2-request` may make libva work via Mozilla's VAAPI backend even on stock Firefox — to be verified in -Phase 0 inventory. +Phase 0 inventory. mpv on this hardware should be able to +engage `--hwdec=v4l2request-copy` (the Mesa libva-v4l2-request +backend) for the libva mpv cells. ### What "cutting out the KWin compositor" means @@ -357,15 +390,15 @@ unknown: presentation (rather than internally composing to RGB) is open. Mozilla has a `MOZ_X11_EGL` hint and a "hardware video overlay" pref but these are not universally engaged. -- **Reference clients**: mpv with `--vo=xv` or - `--vo=gpu --hwdec=auto-copy --gpu-context=x11`, or `gst-play-1.0` - with `xvimagesink` or `glimagesink`, are known-good X11 - hardware-overlay paths. **Adding mpv to the matrix as a - reference client** would isolate "does the X11 hardware- - overlay path work AT ALL on this hardware" from "do - browsers actually use it." If mpv hardware-overlays cleanly - but browsers don't, the conclusion is "the X11 path is fast, - but browsers leave the speedup on the table." +- **Reference clients**: mpv was added to the matrix as a 4th + client (see § "Experimental matrix" above) — two cells, each + run with both `--vo=xv` and `--vo=gpu --gpu-context=x11` to + cover both the legacy XVideo overlay path and the modern + DRI3+XPresent+Mesa-GL path. `gst-play-1.0` with `xvimagesink` + or `glimagesink` would be a possible extension if the mpv + cells produce ambiguous results, but mpv alone covers the + "is the X11 hardware-overlay path even reachable on this + hardware" question. If the operator agrees, Phase 0 inventory should: @@ -378,8 +411,8 @@ If the operator agrees, Phase 0 inventory should: 2. Inventory Brave's, chromium-fourier's, and Firefox's X11 overlay-presentation paths to see which (if any) request hardware-overlay presentation. -3. Add mpv as a reference X11-overlay client to the matrix, - so the campaign has a known-good comparison point. +3. ~~Add mpv as a reference X11-overlay client to the matrix~~ + Done — mpv 0.41 added as a 4th client row 2026-05-03. ### What this question does NOT cover diff --git a/worklist.md b/worklist.md index ec789e4..3d75b58 100644 --- a/worklist.md +++ b/worklist.md @@ -52,21 +52,38 @@ inventory and baseline-anchor work below. sessions. Operator action: `pacman -S` a non-compositing WM (recommend openbox) and create/switch to its SDDM session before without-KWin cells can run. -- [ ] **NEW: Browser X11-overlay-path inventory.** Per - `phase0_findings.md` § "Open questions": determine whether - Brave 147 ozone-x11, chromium-fourier 149 ozone-x11, and - Firefox X11 backends actually request hardware-overlay - presentation for windowed video, or whether they always - internally composite to RGB. Browser-specific source-grep - + chrome trace inspection. -- [ ] **NEW: Add mpv as a reference X11-overlay client.** - mpv with `--vo=xv` or `--vo=gpu --gpu-context=x11` is a - known-good X11 hardware-overlay path. Adding mpv to the - matrix as a 4th client provides "is the X11 hardware-overlay - path even reachable on this hardware" baseline, separate - from "do browsers use it." If mpv hits Plane 39 NV12 cleanly - but browsers don't, the answer is "X11 path is fast, but - the browsers don't take advantage of it." +- [x] **Browser X11-overlay-path inventory.** Captured + 2026-05-03 in + `phase0_evidence/browser_overlay_inventory_2026-05-03.md` + + acquired-source subtree + `phase0_evidence/chromium_ozone_x11_2026-05-03/` (Chromium + 147 from `chromium-builder` LXD CT on boltzmann via the + his subagent). **Decisive verdict at the source level:** + Chromium ozone-x11 instantiates `StubOverlayManager` + (`ozone_platform_x11.cc:262`) — no overlay candidates ever + promoted; Brave 147 + chromium-fourier 149 inherit this + unchanged (their patches don't touch Ozone). Firefox 150 + `WindowSurfaceX11{,Image,SHM}` are RGB-only (zero NV12 / + dmabuf / DRI3 / XPresent references in any X11-surface + file). **No browser in the matrix has a code path to + hand NV12 to the X server for plane scanout.** Only mpv + `--vo=xv` does; mpv `--vo=gpu --gpu-context=x11` is the + same GL-composite shape as the browsers. Implication: + campaign's load-bearing hypothesis is structurally + weakened — the X11-vs-Wayland delta the matrix will + measure for browsers is "browser-side GL composite + + X-scanout-of-RGB" vs "browser-side GL composite + + KWin-RGB-recomposite + scanout". mpv-xv becomes the + matrix's only direct test of the original mechanism. + Runtime-engagement probe deferred to Phase 1 first rep + (design sketched in the inventory doc). +- [x] **mpv added as 4th matrix client** 2026-05-03. Two cells + (full SW, libva/v4l2request) × 2 sessions × 2 VOs (`--vo=xv` + and `--vo=gpu --gpu-context=x11`) = 8 reference data points. + README + `phase0_findings.md` § "Experimental matrix" + updated; matrix grew from 12 → 16 cells (+8 mpv VO sub-points). + mpv 0.41.0 already installed via predecessor (see + `phase0_evidence/x11_inventory_2026-05-03/02_x11_paths.txt`). - [x] Inventory of X11-side measurement instruments. Captured 2026-05-03 in `phase0_evidence/x11_inventory_2026-05-03/` (raw `04_measurement_instruments.txt` + summary `inventory.md`