GDK_BACKEND/QT_QPA_PLATFORM forced to wayland stripped toolkits' fallback,
killing X11-only builds like emacs-gtk ('cannot open display' against a
healthy Xwayland). Children now self-select from WAYLAND_DISPLAY/DISPLAY,
and XAUTHORITY is cleared.
Separately, X11 membership decisions moved from window-creation time to
first map: GTK leader windows never map, yet claimed the tab slot at
creation, leaving a permanent black tab while the real frame was demoted
to a stacked member -- and Alt-cycling onto that phantom main member
crashed on wlr_seat_keyboard_notify_enter(NULL). Never-mapped windows now
free silently; keyboard-entry paths guard on live surfaces. New
tests/xleader.c probe (unmapped leader + mapped frame) locks the behaviour
in.
190 lines
7.1 KiB
Meson
190 lines
7.1 KiB
Meson
project('kick', 'c',
|
|
version: '0.1.0',
|
|
meson_version: '>=1.0',
|
|
default_options: ['c_std=c11', 'warning_level=2'])
|
|
|
|
wlroots_ver = '>=0.19,<0.20'
|
|
|
|
# wlroots' pkg-config name varies between distributions (wlroots-0.19 on
|
|
# Debian/Ubuntu, plain wlroots on Arch/Fedora). Prefer the system copy, and
|
|
# fall back to a pinned source build from subprojects/wlroots.wrap when no
|
|
# matching system library is found.
|
|
wlroots = dependency('wlroots-0.19', version: wlroots_ver, required: false)
|
|
if not wlroots.found()
|
|
wlroots = dependency('wlroots', version: wlroots_ver, required: false)
|
|
endif
|
|
if not wlroots.found()
|
|
wlroots_subproj = subproject('wlroots',
|
|
default_options: ['examples=false', 'werror=false'])
|
|
wlroots = wlroots_subproj.get_variable('wlroots')
|
|
endif
|
|
|
|
deps = [
|
|
wlroots,
|
|
dependency('wayland-server'),
|
|
dependency('wayland-client'),
|
|
dependency('wayland-egl'),
|
|
dependency('xkbcommon'),
|
|
dependency('egl'),
|
|
dependency('glesv2'),
|
|
dependency('freetype2'),
|
|
dependency('libpng'),
|
|
dependency('librsvg-2.0'),
|
|
# Direct pixman use in kick.c (pointer-constraint region extents).
|
|
dependency('pixman-1'),
|
|
# Server-side/client-side window decorations via libdecor (nested mode).
|
|
dependency('libdecor-0'),
|
|
]
|
|
|
|
cc = meson.get_compiler('c')
|
|
libm = cc.find_library('m', required: false)
|
|
if libm.found()
|
|
deps += libm
|
|
endif
|
|
|
|
# --- XWayland (optional) ------------------------------------------------
|
|
# Enabling XWayland needs two things: the linked wlroots built with xwayland
|
|
# (advertised publicly as WLR_HAS_XWAYLAND in <wlr/config.h>, checked in
|
|
# kick.c) and the xcb dev packages pulled in by <wlr/xwayland/xwayland.h>.
|
|
# When either is missing the build stays green and kick simply runs without
|
|
# X11 support.
|
|
xcb_deps = []
|
|
xcb_all = true
|
|
foreach depname : ['xcb', 'xcb-icccm', 'xcb-ewmh']
|
|
d = dependency(depname, required: false)
|
|
if d.found()
|
|
xcb_deps += d
|
|
else
|
|
xcb_all = false
|
|
endif
|
|
endforeach
|
|
deps += xcb_deps
|
|
kick_c_args = ['-DWLR_USE_UNSTABLE']
|
|
if xcb_all
|
|
kick_c_args += ['-DKICK_HAVE_XCB=1']
|
|
endif
|
|
|
|
# --- Wayland protocol stubs -------------------------------------------
|
|
# The protocol implementation and headers are generated at build time by
|
|
# wayland-scanner instead of being committed, so they always match the
|
|
# installed wayland-protocols (the previously committed copies were produced
|
|
# by wayland-scanner 1.24/1.26 and drifted apart). Outputs land in the build
|
|
# directory, which Meson adds to every target's include path automatically;
|
|
# that also satisfies the bundled wlroots subproject's wlr_xdg_shell.h and its
|
|
# quoted #include "xdg-shell-protocol.h".
|
|
|
|
wayland_protocols = dependency('wayland-protocols', version: '>=1.17',
|
|
fallback: 'wayland-protocols', default_options: ['tests=false'])
|
|
wl_protocols_dir = wayland_protocols.get_variable('pkgdatadir')
|
|
|
|
wayland_scanner_dep = dependency('wayland-scanner', native: true)
|
|
wayland_scanner = find_program(
|
|
wayland_scanner_dep.get_variable('wayland_scanner'))
|
|
|
|
# (input xml, output base name). The output base names keep historical
|
|
# suffixes: xdg-shell is generated plain because the sources #include that
|
|
# exact name.
|
|
protocols = {
|
|
'xdg-shell': [
|
|
wl_protocols_dir / 'stable/xdg-shell/xdg-shell.xml',
|
|
'xdg-shell',
|
|
],
|
|
'wlr-data-control-unstable-v1': [
|
|
'wlr-protocols/wlr-data-control-unstable-v1.xml',
|
|
'wlr-data-control',
|
|
],
|
|
'cursor-shape': [
|
|
wl_protocols_dir / 'staging/cursor-shape/cursor-shape-v1.xml',
|
|
'cursor-shape-v1',
|
|
],
|
|
# cursor-shape-v1's get_tablet_tool_v2 request points at zwp_tablet_tool_v2,
|
|
# so its private code needs tablet-v2's generated code (wlroots' own copy is
|
|
# not exported: wlroots.syms keeps every non-wlr_* symbol local).
|
|
'tablet-v2': [
|
|
wl_protocols_dir / 'stable/tablet/tablet-v2.xml',
|
|
'tablet-v2',
|
|
],
|
|
'pointer-constraints': [
|
|
wl_protocols_dir / 'unstable/pointer-constraints/pointer-constraints-unstable-v1.xml',
|
|
'pointer-constraints-unstable-v1',
|
|
],
|
|
'relative-pointer': [
|
|
wl_protocols_dir / 'unstable/relative-pointer/relative-pointer-unstable-v1.xml',
|
|
'relative-pointer-unstable-v1',
|
|
],
|
|
'primary-selection': [
|
|
wl_protocols_dir / 'unstable/primary-selection/primary-selection-unstable-v1.xml',
|
|
'primary-selection-unstable-v1',
|
|
],
|
|
}
|
|
|
|
protocol_sources = []
|
|
protocol_headers = []
|
|
client_headers = {}
|
|
code_by_name = {}
|
|
foreach protocol, p : protocols
|
|
xml = p[0]
|
|
base = p[1]
|
|
code = custom_target(protocol + ' protocol code',
|
|
input: xml,
|
|
output: base + '-protocol.c',
|
|
command: [wayland_scanner, 'private-code', '@INPUT@', '@OUTPUT@'])
|
|
protocol_sources += code
|
|
code_by_name += { protocol: code }
|
|
client_header = custom_target(protocol + ' client header',
|
|
input: xml,
|
|
output: base + '-client.h',
|
|
command: [wayland_scanner, 'client-header', '@INPUT@', '@OUTPUT@'])
|
|
protocol_headers += client_header
|
|
client_headers += { protocol: client_header }
|
|
if protocol == 'xdg-shell'
|
|
protocol_headers += custom_target(protocol + ' server header',
|
|
input: xml,
|
|
output: base + '-protocol.h',
|
|
command: [wayland_scanner, 'server-header', '@INPUT@', '@OUTPUT@'])
|
|
endif
|
|
if protocol == 'cursor-shape'
|
|
# Serves the wlroots header's quoted #include "cursor-shape-v1-protocol.h";
|
|
# the system wlroots packages don't install the generated protocol headers.
|
|
protocol_headers += custom_target(protocol + ' server header',
|
|
input: xml,
|
|
output: base + '-protocol.h',
|
|
command: [wayland_scanner, 'server-header', '@INPUT@', '@OUTPUT@'])
|
|
endif
|
|
if protocol == 'pointer-constraints'
|
|
# Serves wlr_pointer_constraints_v1.h's quoted
|
|
# #include "pointer-constraints-unstable-v1-protocol.h".
|
|
protocol_headers += custom_target(protocol + ' server header',
|
|
input: xml,
|
|
output: base + '-protocol.h',
|
|
command: [wayland_scanner, 'server-header', '@INPUT@', '@OUTPUT@'])
|
|
endif
|
|
endforeach
|
|
|
|
executable('kick',
|
|
'kick.c',
|
|
protocol_sources,
|
|
protocol_headers,
|
|
dependencies: deps,
|
|
c_args: kick_c_args)
|
|
|
|
# wltest needs the xdg-shell stub plus the cursor-shape client stack (whose
|
|
# private code references zwp_tablet_tool_v2, hence tablet-v2 too).
|
|
executable('wltest',
|
|
'tests/wltest.c',
|
|
code_by_name['xdg-shell'],
|
|
code_by_name['cursor-shape'],
|
|
code_by_name['tablet-v2'],
|
|
code_by_name['pointer-constraints'],
|
|
code_by_name['relative-pointer'],
|
|
code_by_name['primary-selection'],
|
|
client_headers['xdg-shell'],
|
|
client_headers['cursor-shape'],
|
|
dependencies: dependency('wayland-client'))
|
|
|
|
# xleader: X11 twin-window probe used by the leader-window regression test --
|
|
# an unmapped GTK-style leader plus a mapped frame, both carrying _NET_WM_PID.
|
|
x11_dep = dependency('x11', required: false)
|
|
if x11_dep.found()
|
|
executable('xleader', 'tests/xleader.c', dependencies: x11_dep)
|
|
endif
|