summaryrefslogtreecommitdiffhomepage
path: root/packages/ext-window-field/meson.build
blob: d0ba386996ed64020c3e2460833dbdc291fa7044 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# ext-window-field — RML compositing Phase 2, Wave 3 (GLOSSARY: "window field").
# The core extension that composites application toplevels as RCSS SURFACE
# ELEMENTS inside ONE ui surface (the "window field"), instead of as wlr_scene
# nodes: it subscribes to ext-xdg-shell's toplevel lifecycle, turns each
# toplevel's root wl_surface into a kernel SurfaceElement, lists them into its
# RML document, and lets RCSS lay them out + animate. Layout/animation are RCSS
# (the user's contract decision); this glue only DRIVES the document + focus.
#
# Installed by host-bin ONLY when RML compositing is enabled (the flag) — so the
# classic wlr_scene path stays the default until this is proven on the real seat.
# Tier: core; depends_on "xdg-shell".

ext_window_field_inc = include_directories('include')

# toml++: the APPROVED config dep (notes/plan.md §2), a project-global Meson wrap
# (subprojects/tomlplusplus.wrap). Force default_library=static so the installed
# `unbox` binary bakes it in (the wrap's own meson.build hardcodes shared, which
# would need libtomlplusplus.so at runtime). Same rationale as ext-keybindings.
tomlplusplus_dep = dependency('tomlplusplus',
                              default_options: ['default_library=static'])

# Glue library: needs the kernel ABI (ui substrate + SurfaceElement), ext-xdg-
# shell's public contract (Toplevel::wl_surface()/set_size(), the Service events),
# and toml++ (the [window-field] resize-policy loader, src/config.cpp). The policy
# parse is a PURE core in src/config.{hpp,cpp} (toml++ only; doctest-covered).
ext_window_field_lib = static_library(
  'unbox-ext-window-field',
  'src/extension.cpp',
  'src/config.cpp',
  'src/geometry.cpp',
  include_directories: ext_window_field_inc,
  dependencies: [kernel_dep, ext_xdg_shell_dep, tomlplusplus_dep],
)

# What host-bin links against (the factory). kernel_dep rides through for the
# Extension ABI the factory returns; ext-xdg-shell stays a build-time dep of OUR
# lib only.
ext_window_field_dep = declare_dependency(
  link_with: ext_window_field_lib,
  include_directories: ext_window_field_inc,
  dependencies: [kernel_dep],
)

# Tests, asymmetric (AGENTS.md: strict cores, lenient shell). Window LAYOUT lives
# in RCSS (no C++ decision core), but the resize-policy CONFIG parse (src/config.
# cpp) IS a pure core and is doctest-hard below. The SMOKE test (factory/manifest)
# + a lenient HEADLESS GLUE test round out the suite.

# CONFIG core test: the pure [window-field] toml parser (defaults, every
# resize_mode value, debounce clamping, malformed input). No kernel/wlroots; the
# core TU compiles config.cpp directly and needs `src` on the include path
# (a unit may read its own src/) plus toml++.
ext_window_field_config_test = executable(
  'ext-window-field-config-tests',
  'tests/test_config.cpp',
  'src/config.cpp',
  include_directories: [ext_window_field_inc, include_directories('src')],
  dependencies: [doctest_dep, tomlplusplus_dep],
)
test(
  'ext-window-field-config',
  ext_window_field_config_test,
  suite: 'ext-window-field',
)

# GEOMETRY core test: the pure floating-window drag/resize math (move, the two
# bottom resize grips with the anchored-opposite-edge rule, min-size clamp,
# field clamp). No kernel/wlroots.
ext_window_field_geometry_test = executable(
  'ext-window-field-geometry-tests',
  'tests/test_geometry.cpp',
  'src/geometry.cpp',
  include_directories: [ext_window_field_inc, include_directories('src')],
  dependencies: [doctest_dep],
)
test(
  'ext-window-field-geometry',
  ext_window_field_geometry_test,
  suite: 'ext-window-field',
)

# SMOKE test: the factory yields the window-field extension with the right
# manifest. Cheap, no kernel/wlroots running.
ext_window_field_smoke_test = executable(
  'ext-window-field-smoke-tests',
  'tests/test_window_field.cpp',
  include_directories: [ext_window_field_inc, include_directories('src')],
  dependencies: [ext_window_field_dep, doctest_dep],
)
test(
  'ext-window-field-smoke',
  ext_window_field_smoke_test,
  suite: 'ext-window-field',
)

# HEADLESS GLUE test: install ext-xdg-shell + ext-window-field on the wlr
# headless backend, map REAL in-process client toplevels, then drive the
# map/unmap/focus PIPELINE and assert the bound window MODEL via the private test
# probe (src/probe.hpp) + that Toplevel::hide() was driven. Lenient ext-tier
# glue: the substrate is null on pixman (no GL), so the field UiSurface +
# SurfaceElements are null — this exercises the model + hide(), not the visual
# (same posture as ext-stage-dock's test_glue.cpp). Needs CLIENT-side xdg-shell
# bindings generated from the canonical xdg-shell.xml exactly as ext-stage-dock's
# test_glue.cpp does (header + private-code-as-header, #included once by the
# single C++ TU). `src` on the include path so the test reaches the private probe
# factory (own src/ only).
wf_wayland_client_dep = dependency('wayland-client')
wf_wayland_protocols_dir = dependency('wayland-protocols').get_variable('pkgdatadir')
wf_xdg_shell_xml = wf_wayland_protocols_dir / 'stable' / 'xdg-shell' / 'xdg-shell.xml'

wf_xdg_shell_client_header = custom_target(
  'wf-xdg-shell-client-header',
  input: wf_xdg_shell_xml,
  output: 'xdg-shell-client-protocol.h',
  command: [wayland_scanner, 'client-header', '@INPUT@', '@OUTPUT@'],
)
# private-code emitted as a .h so the C++ TU #includes it exactly once.
wf_xdg_shell_client_code = custom_target(
  'wf-xdg-shell-client-code-impl',
  input: wf_xdg_shell_xml,
  output: 'xdg-shell-client-protocol-code.h',
  command: [wayland_scanner, 'private-code', '@INPUT@', '@OUTPUT@'],
)

ext_window_field_glue_test = executable(
  'ext-window-field-glue-tests',
  'tests/test_glue.cpp',
  wf_xdg_shell_client_header,
  wf_xdg_shell_client_code,
  include_directories: [ext_window_field_inc, include_directories('src')],
  dependencies: [ext_window_field_dep, ext_xdg_shell_dep, wf_wayland_client_dep, doctest_dep],
)
test(
  'ext-window-field-glue',
  ext_window_field_glue_test,
  suite: 'ext-window-field',
  # Real socket handshake + cooperative event-loop pump; generous timeout so a
  # slow CI box does not flake (the test fails fast on its own logic).
  timeout: 60,
)

# Aggregate alias: `ninja -C build ext-window-field-tests`.
alias_target('ext-window-field-tests',
  ext_window_field_smoke_test,
  ext_window_field_config_test,
  ext_window_field_geometry_test,
  ext_window_field_glue_test,
)