diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5cfbcbfd4..af38e9b79 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -41,11 +41,16 @@ pkg_check_modules(FFMPEG libavcodec)
 if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
 	# Compositor backend
 	find_package(X11)
+	find_package(PkgConfig REQUIRED)
 	pkg_check_modules(XCB xcb xcb-randr)
 
 	find_package(udev REQUIRED)
 	set(BUILD_WITH_LIBUDEV TRUE)
 	set(BUILD_DRIVER_V4L2 TRUE)
+
+	pkg_search_module(WAYLAND wayland-client)
+	pkg_search_module(WAYLAND_SCANNER wayland-scanner)
+	pkg_search_module(WAYLAND_PROTOCOLS wayland-protocols)
 endif()
 
 cmake_dependent_option(BUILD_WITH_WAYLAND "Enable Wayland support" ON "WAYLAND_FOUND" OFF)
diff --git a/src/xrt/compositor/CMakeLists.txt b/src/xrt/compositor/CMakeLists.txt
index a7e8a92e3..e13640bb0 100644
--- a/src/xrt/compositor/CMakeLists.txt
+++ b/src/xrt/compositor/CMakeLists.txt
@@ -38,6 +38,7 @@ set(GL_SOURCE_FILES
 	main/comp_window.h
 	main/comp_window_direct_mode.cpp
 	main/comp_window_xcb.cpp
+	main/comp_window_wayland.c
 	)
 
 if (${XCB_FOUND})
@@ -45,17 +46,48 @@ if (${XCB_FOUND})
 	add_definitions(-DVK_USE_PLATFORM_XLIB_XRANDR_EXT)
 endif()
 
+# generate wayland protocols
+if("${WAYLAND_FOUND}" AND
+   "${WAYLAND_SCANNER_FOUND}" AND
+   "${WAYLAND_PROTOCOLS_FOUND}" AND
+   "${BUILD_WITH_WAYLAND}")
+	pkg_get_variable(WL_PROTOS_PKG_DIR wayland-protocols pkgdatadir)
+	pkg_get_variable(WL_SCANNER wayland-scanner wayland_scanner)
+
+	set(WL_PROTOS_DIR "${CMAKE_CURRENT_BINARY_DIR}/wayland-protocols/")
+	file(MAKE_DIRECTORY "${WL_PROTOS_DIR}")
+
+	set(WL_PROTOS_XML "${WL_PROTOS_PKG_DIR}/stable/xdg-shell/xdg-shell.xml")
+	set(WL_PROTOS_C "${WL_PROTOS_DIR}/xdg-shell.c")
+	set(WL_PROTOS_H "${WL_PROTOS_DIR}/xdg-shell-client-protocol.h")
+
+	add_custom_command(
+		COMMAND
+		${WL_SCANNER} private-code "${WL_PROTOS_XML}" "${WL_PROTOS_C}"
+		OUTPUT "${WL_PROTOS_C}" VERBATIM)
+
+	add_custom_command(
+		COMMAND
+		${WL_SCANNER} client-header "${WL_PROTOS_XML}" "${WL_PROTOS_H}"
+		OUTPUT "${WL_PROTOS_H}" VERBATIM)
+
+	set(WL_PROTOS_SRC ${WL_PROTOS_C} ${WL_PROTOS_H})
+
+	add_definitions(-DVK_USE_PLATFORM_WAYLAND_KHR)
+endif()
+
 if (${VULKAN_ENABLE_VALIDATION})
 	add_definitions(-DXRT_ENABLE_VK_VALIDATION)
 endif()
 
 # Use OBJECT to not create a archive, since it just gets in the way.
-add_library(comp OBJECT ${GL_SOURCE_FILES})
+add_library(comp OBJECT ${GL_SOURCE_FILES} ${WL_PROTOS_SRC})
 set_property(TARGET comp PROPERTY POSITION_INDEPENDENT_CODE ON)
 target_include_directories(comp
 	PRIVATE
 	${XCB_INCLUDE_DIRS}
 	${VULKAN_INCLUDE_DIR}
+	${WL_PROTOS_DIR}
 	${CMAKE_CURRENT_SOURCE_DIR}
 	${CMAKE_CURRENT_SOURCE_DIR}/../include
 	${CMAKE_CURRENT_SOURCE_DIR}/../auxiliary
diff --git a/src/xrt/targets/openxr/CMakeLists.txt b/src/xrt/targets/openxr/CMakeLists.txt
index 35f4ba5a2..4527ed8cd 100644
--- a/src/xrt/targets/openxr/CMakeLists.txt
+++ b/src/xrt/targets/openxr/CMakeLists.txt
@@ -47,6 +47,7 @@ target_link_libraries(${RUNTIME_TARGET}
 	${Vulkan_LIBRARIES}
 	${UDEV_LIBRARIES}
 	${XCB_LIBRARIES}
+	${WAYLAND_LIBRARIES}
 	OpenGL::GLX
 	)