project('kick', 'c', version: '0.1.0', meson_version: '>=1.0', default_options: ['c_std=c11', 'warning_level=2']) wlroots_ver = '>=0.20,<0.21' # wlroots' pkg-config name varies between distributions (wlroots-0.20 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.20', 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'), # Overlay tab-title text via Pango+Cairo (the labwc/sway/mutter stack): # shaping, UTF-8 and fontconfig fallback in, no hand-rolled atlas. dependency('pangocairo'), 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'), # libdrm for render-node discovery (dmabuf main device override). dependency('libdrm'), ] 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 , checked in # kick.c) and the xcb dev packages pulled in by . # 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', ], # xdg-decoration is the unstable-v1 protocol but keeps the plain # "xdg-decoration" base name because the host-window code includes # those exact generated names (SSD-compositor direct path). 'xdg-decoration': [ wl_protocols_dir / 'unstable/xdg-decoration/xdg-decoration-unstable-v1.xml', 'xdg-decoration', ], 'ext-data-control': [ wl_protocols_dir / 'staging/ext-data-control/ext-data-control-v1.xml', 'ext-data-control-v1', ], # wlr-layer-shell is what waybar and other panels use to make an # always-visible bar. Bundled locally (like the foreign-toplevel and # output-management XMLs) rather than referenced from the wlroots tree, # so it works with either a system wlroots or the pinned subproject. 'wlr-layer-shell-unstable-v1': [ 'wlr-protocols/wlr-layer-shell-unstable-v1.xml', 'wlr-layer-shell-unstable-v1', ], # wlr-foreign-toplevel-management is the taskbar protocol: a per-window # handle with client-pull state. Bundled locally (like the layer-shell # XML) so it works with either a system wlroots or the pinned subproject. 'wlr-foreign-toplevel-management-unstable-v1': [ 'wlr-protocols/wlr-foreign-toplevel-management-unstable-v1.xml', 'wlr-foreign-toplevel-management', ], # ext-foreign-toplevel-list ships as a staging protocol in # wayland-protocols (>= 1.36); it is the shipman/taskbar-side read of the # same per-window list, driven server-side rather than by the client. 'ext-foreign-toplevel-list': [ wl_protocols_dir / 'staging/ext-foreign-toplevel-list/ext-foreign-toplevel-list-v1.xml', 'ext-foreign-toplevel-list-v1', ], # Idle: ext-idle-notify (a client asks for a timeout, the compositor fires # "idle" once that much time passes without input) and idle-inhibit (a # client can suppress idle notifications while its buffer stays up). 'ext-idle-notify': [ wl_protocols_dir / 'staging/ext-idle-notify/ext-idle-notify-v1.xml', 'ext-idle-notify-v1', ], 'idle-inhibit-unstable-v1': [ wl_protocols_dir / 'unstable/idle-inhibit/idle-inhibit-unstable-v1.xml', 'idle-inhibit-unstable-v1', ], # Session lock: the lock client (swaylock) grabs the session and private # protocol surfaces cover each output; the compositor blanking the screen # while locked. 'ext-session-lock': [ wl_protocols_dir / 'staging/ext-session-lock/ext-session-lock-v1.xml', 'ext-session-lock-v1', ], # Screen capture (ext-image-copy-capture-v1 + ext-image-capture-source-v1), # the protocol grim uses. Staging protocols from wayland-protocols; the # XMLs are referenced from the installed package. 'ext-image-copy-capture': [ wl_protocols_dir / 'staging/ext-image-copy-capture/ext-image-copy-capture-v1.xml', 'ext-image-copy-capture-v1', ], 'ext-image-capture-source': [ wl_protocols_dir / 'staging/ext-image-capture-source/ext-image-capture-source-v1.xml', 'ext-image-capture-source-v1', ], # Tearing control (a surface asks for unthrottled presentation) and # fractional scale (a surface learns a non-integer output scale). # Both are staging protocols; tearing drives the output commit's # async-flip flag from the shown surface's hint, fractional scale is # notified from the output scale on claim. 'tearing-control': [ wl_protocols_dir / 'staging/tearing-control/tearing-control-v1.xml', 'tearing-control-v1', ], 'fractional-scale': [ wl_protocols_dir / 'staging/fractional-scale/fractional-scale-v1.xml', 'fractional-scale-v1', ], # Output power management (a client blanks/unblanks an output). Bundled # locally like the other wlr-protocols XMLs (copied from the pinned # wlroots subproject). 'wlr-output-power-management-unstable-v1': [ 'wlr-protocols/wlr-output-power-management-unstable-v1.xml', 'wlr-output-power-management-unstable-v1', ], # Keyboard shortcuts inhibit (a fullscreen game/VM grabs the compositor's # shortcuts). Unstable protocol; the test client binds it to prove the # compositor activates the inhibitor for the focused surface. 'keyboard-shortcuts-inhibit': [ wl_protocols_dir / 'unstable/keyboard-shortcuts-inhibit/keyboard-shortcuts-inhibit-unstable-v1.xml', 'keyboard-shortcuts-inhibit-unstable-v1', ], # Virtual keyboard/pointer (synthesised input from clients like wtype). # Bundled locally (copied from the pinned wlroots subproject). 'virtual-keyboard-unstable-v1': [ 'wlr-protocols/virtual-keyboard-unstable-v1.xml', 'virtual-keyboard-unstable-v1', ], 'wlr-virtual-pointer-unstable-v1': [ 'wlr-protocols/wlr-virtual-pointer-unstable-v1.xml', 'wlr-virtual-pointer-unstable-v1', ], # Xdg-activation (launchers focus windows by token). Staging protocol. 'xdg-activation': [ wl_protocols_dir / 'staging/xdg-activation/xdg-activation-v1.xml', 'xdg-activation-v1', ], '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', ], # Text input (OSK/IME): zwp_text_input_v3 (clients) + input-method-v2 # (the IME side). text-input comes from the system wayland-protocols; # input-method-v2 only ships inside wlroots, so like the other bundled # wlr-protocols XMLs it is vendored under wlr-protocols/ (Meson forbids # referencing a nested subproject's files from the parent project). 'text-input': [ wl_protocols_dir / 'unstable/text-input/text-input-unstable-v3.xml', 'text-input-unstable-v3', ], 'input-method': [ 'wlr-protocols/input-method-unstable-v2.xml', 'input-method-unstable-v2', ], # Gamma control (night-light tools like wlsunset/gammastep): wlroots # extension, vendored like the other wlr-protocols XMLs. 'gamma-control': [ 'wlr-protocols/wlr-gamma-control-unstable-v1.xml', 'wlr-gamma-control-unstable-v1', ], # xdg-dialog (modal toplevels): staging protocol from the system # wayland-protocols. Only the client stub is generated for wltest; # the server side is wlroots' wlr_xdg_wm_dialog_v1 (no quoted # server-header include, so no extra custom_target needed). 'xdg-dialog': [ wl_protocols_dir / 'staging/xdg-dialog/xdg-dialog-v1.xml', 'xdg-dialog-v1', ], # Pointer gestures (touchpad swipe/pinch/hold): unstable protocol # from the system wayland-protocols. Only client stubs are needed # for wltest; the server side is wlroots' wlr_pointer_gestures_v1 # (no quoted server-header include). 'pointer-gestures': [ wl_protocols_dir / 'unstable/pointer-gestures/pointer-gestures-unstable-v1.xml', 'pointer-gestures-unstable-v1', ], # Toplevel icons (exact window artwork from the client): staging # protocol from the system wayland-protocols. Only client stubs are # needed for wltest; the server side is wlroots' # wlr_xdg_toplevel_icon_manager_v1 (no quoted server-header include). 'toplevel-icon': [ wl_protocols_dir / 'staging/xdg-toplevel-icon/xdg-toplevel-icon-v1.xml', 'xdg-toplevel-icon-v1', ], # Toplevel tags (client-supplied window labels like "settings" plus a # translated description): staging protocol from the system # wayland-protocols. Only client stubs are needed for wltest; the # server side is wlroots' wlr_xdg_toplevel_tag_manager_v1 (no quoted # server-header include). 'toplevel-tag': [ wl_protocols_dir / 'staging/xdg-toplevel-tag/xdg-toplevel-tag-v1.xml', 'xdg-toplevel-tag-v1', ], # Color representation (a surface declares its alpha mode / matrix # coefficients / range): staging protocol from the system # wayland-protocols. Only client stubs are needed for wltest; the # server side is wlroots' wlr_color_representation_manager_v1 (the # generated enum header ships with wayland-protocols). 'color-representation': [ wl_protocols_dir / 'staging/color-representation/color-representation-v1.xml', 'color-representation-v1', ], # Color management (clients describe surface colors, outputs advertise # image descriptions): staging protocol from the system # wayland-protocols. Only client stubs are needed for wltest; the # server side is wlroots' wlr_color_manager_v1 (the generated enum # header ships with wayland-protocols). 'color-management': [ wl_protocols_dir / 'staging/color-management/color-management-v1.xml', 'color-management-v1', ], # System bell (a client asks the compositor to ring the bell): # staging protocol from the system wayland-protocols. Only client # stubs are needed for wltest; the server side is wlroots' # wlr_xdg_system_bell_v1. 'system-bell': [ wl_protocols_dir / 'staging/xdg-system-bell/xdg-system-bell-v1.xml', 'xdg-system-bell-v1', ], # Output management (kanshi/wdisplays reconfigure the output): # wlroots extension, vendored like the other wlr-protocols XMLs. 'output-management': [ 'wlr-protocols/wlr-output-management-unstable-v1.xml', 'wlr-output-management-unstable-v1', ], # Content hints (photo/video/game) + single-pixel buffers (1x1 solid # color without a shm pool). Both are staging protocols from the # system wayland-protocols, like wlroots itself uses. 'content-type': [ wl_protocols_dir / 'staging/content-type/content-type-v1.xml', 'content-type-v1', ], 'single-pixel': [ wl_protocols_dir / 'staging/single-pixel-buffer/single-pixel-buffer-v1.xml', 'single-pixel-buffer-v1', ], # Alpha modifier (a surface multiplies its own alpha): staging # protocol from the system wayland-protocols. Only client stubs are # needed for wltest; the server side is wlroots' # wlr_alpha_modifier_v1. 'alpha-modifier': [ wl_protocols_dir / 'staging/alpha-modifier/alpha-modifier-v1.xml', 'alpha-modifier-v1', ], # Viewporter (stable): only the client stub is needed (the server side # is wlroots' wlr_viewporter_create). wltest uses it to scale a 1x1 # single-pixel buffer up to the window size. 'viewporter': [ wl_protocols_dir / 'stable/viewporter/viewporter.xml', 'viewporter', ], } 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 if protocol == 'wlr-layer-shell-unstable-v1' # Serves wlr_layer_shell_v1.h's quoted # #include "wlr-layer-shell-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 if protocol == 'tearing-control' # Serves wlr_tearing_control_v1.h's quoted # #include "tearing-control-v1-protocol.h". protocol_headers += custom_target(protocol + ' server header', input: xml, output: base + '-protocol.h', command: [wayland_scanner, 'server-header', '@INPUT@', '@OUTPUT@']) endif if protocol == 'content-type' # Serves wlr_content_type_v1.h's quoted # #include "content-type-v1-protocol.h". protocol_headers += custom_target(protocol + ' server header', input: xml, output: base + '-protocol.h', command: [wayland_scanner, 'server-header', '@INPUT@', '@OUTPUT@']) endif if protocol == 'wlr-output-power-management-unstable-v1' # Serves wlr_output_power_management_v1.h's quoted # #include "wlr-output-power-management-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). The # --layer mode uses the wlr-layer-shell client protocol; the --foreign mode # uses the wlr-foreign-toplevel and ext-foreign-toplevel-list client stubs. # --idle mode uses ext-idle-notify and idle-inhibit. --tearing and # --fractional-out need their own protocol code linked in. executable('wltest', 'tests/wltest.c', code_by_name['xdg-shell'], code_by_name['cursor-shape'], code_by_name['tablet-v2'], code_by_name['tearing-control'], code_by_name['fractional-scale'], code_by_name['pointer-constraints'], code_by_name['relative-pointer'], code_by_name['primary-selection'], code_by_name['ext-data-control'], code_by_name['wlr-layer-shell-unstable-v1'], code_by_name['wlr-foreign-toplevel-management-unstable-v1'], code_by_name['ext-foreign-toplevel-list'], code_by_name['ext-idle-notify'], code_by_name['idle-inhibit-unstable-v1'], code_by_name['ext-session-lock'], code_by_name['ext-image-copy-capture'], code_by_name['ext-image-capture-source'], code_by_name['keyboard-shortcuts-inhibit'], code_by_name['wlr-output-power-management-unstable-v1'], code_by_name['virtual-keyboard-unstable-v1'], code_by_name['wlr-virtual-pointer-unstable-v1'], code_by_name['xdg-activation'], code_by_name['text-input'], code_by_name['input-method'], code_by_name['content-type'], code_by_name['single-pixel'], code_by_name['alpha-modifier'], code_by_name['viewporter'], code_by_name['gamma-control'], code_by_name['xdg-dialog'], code_by_name['pointer-gestures'], code_by_name['toplevel-icon'], code_by_name['color-representation'], code_by_name['color-management'], code_by_name['system-bell'], code_by_name['toplevel-tag'], code_by_name['output-management'], client_headers['xdg-shell'], client_headers['cursor-shape'], client_headers['wlr-layer-shell-unstable-v1'], client_headers['wlr-foreign-toplevel-management-unstable-v1'], client_headers['ext-foreign-toplevel-list'], client_headers['ext-idle-notify'], client_headers['idle-inhibit-unstable-v1'], client_headers['ext-session-lock'], client_headers['ext-image-copy-capture'], client_headers['ext-image-capture-source'], client_headers['keyboard-shortcuts-inhibit'], client_headers['virtual-keyboard-unstable-v1'], client_headers['wlr-virtual-pointer-unstable-v1'], client_headers['xdg-activation'], client_headers['text-input'], client_headers['input-method'], client_headers['content-type'], client_headers['single-pixel'], client_headers['alpha-modifier'], client_headers['viewporter'], client_headers['gamma-control'], client_headers['xdg-dialog'], client_headers['pointer-gestures'], client_headers['tearing-control'], client_headers['fractional-scale'], client_headers['toplevel-icon'], client_headers['color-representation'], client_headers['color-management'], client_headers['system-bell'], client_headers['toplevel-tag'], client_headers['output-management'], client_headers['ext-data-control'], dependencies: [dependency('wayland-client'), dependency('xkbcommon')]) # xdeco: xdg-decoration mode probe for the client-side regression test -- # maps one toplevel and reports the configured decoration mode. executable('xdeco', 'tests/xdeco.c', code_by_name['xdg-shell'], code_by_name['xdg-decoration'], client_headers['xdg-shell'], client_headers['xdg-decoration'], 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) # xpopup: instantly-mapped managed transient (synthetic menu) for the # late-association regression test. executable('xpopup', 'tests/xpopup.c', dependencies: x11_dep) # xormenu: override-redirect focus-stealing menu probe (frame + menu in # separate processes) for the or_focus_owner regression test. executable('xormenu', 'tests/xormenu.c', dependencies: x11_dep) # xclass: WM_CLASS set-then-delete probe for the set_class NULL # app_id regression test. executable('xclass', 'tests/xclass.c', dependencies: x11_dep) # xreqs: client-request probe driving a managed X11 window through # retitle/minimize/fullscreen/move+resize/raise/maximize/close, plus an # unmapped create+destroy for the pending-surface teardown path. executable('xreqs', 'tests/xreqs.c', dependencies: x11_dep) endif