fix: kwin's remaining GCC 16 / vulkan-hpp and X11-gating fallout
redbear-ci / check (push) Has been cancelled

Continues the previous kwin commit; all found by compiling further.

vulkan-hpp (VULKAN_HPP_RAII_NO_EXCEPTIONS, now active because GCC 16's
libstdc++ provides __cpp_lib_expected at C++23):

  - vulkan_device.cpp getQueue() returns CreateReturnType<Queue>, an
    expected, not a Queue -- unwrapped via splitResult().
  - CommandBuffer::begin/end, bindImageMemory2, importSemaphoreFdKHR and
    Queue::submit return void, not vk::Result. They route their Result
    through detail::resultCheck -> VULKAN_HPP_ASSERT_ON_RESULT, which this
    build defines to `void`, so the status is discarded by configuration.
    Assigning them to vk::Result no longer compiles. Noted at each site;
    the eErrorDeviceLost branch after Queue::submit is now unreachable.
  - mapMemory() returns void* and needed wrapping.
  - QueryPool::getResults already returns a decomposable std::pair, so
    splitResult() had double-wrapped it; unwrapped.

X11 gating -- KWIN_BUILD_X11=OFF is set correctly by the recipe, but
several includes sit outside the guard their own uses are inside:

  - workspace.cpp included syncalarmx11filter.h unguarded (both uses and
    the workspace.h member are guarded).
  - shadow.h declared readX11ShadowProperty(xcb_window_t) unguarded while
    shadow.cpp guards the definition.
  - effecthandler.h declared unique_ptr<WindowPropertyNotifyX11Filter>
    unguarded; with X11 off the type is only forward-declared and
    ~unique_ptr needs it complete.

Missing includes, same shape as earlier findings -- the declaration exists,
it just never reaches the compiler:

  - tabletmodemanager.cpp and backends/libinput/device.cpp call udev_device_*
    without including <libudev.h>, which upstream gets transitively through
    libinput.h. Ours does not pull it in.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-03 22:06:09 +03:00
parent 19e91d6803
commit d1e8202958
9 changed files with 57 additions and 9 deletions
@@ -18,6 +18,9 @@
#include "pointer_input.h"
#include <QCryptographicHash>
// Red Bear: udev_device_* are used below and declared in <libudev.h>; upstream
// gets it transitively through libinput.h, ours does not.
#include <libudev.h>
#include <QDBusArgument>
#include <QDBusConnection>
#include <QDBusMetaType>
@@ -1118,7 +1118,13 @@ protected:
WorkspaceScene *m_scene;
QList<Effect *> m_grabbedMouseEffects;
EffectLoader *m_effectLoader;
#if KWIN_BUILD_X11
// Red Bear: all three uses of this member are already inside
// #if KWIN_BUILD_X11, but the declaration was not. With X11 off the type
// is only forward-declared (line 81), and ~unique_ptr needs it complete:
// unique_ptr.h:90: invalid application of 'sizeof' to incomplete type
std::unique_ptr<WindowPropertyNotifyX11Filter> m_x11WindowPropertyNotify;
#endif
KConfigWatcher::Ptr m_configWatcher;
};
@@ -189,9 +189,15 @@ std::optional<MultiGpuSwapchain::Ret> MultiGpuSwapchain::copyWithVulkan(Graphics
m_journal.add(damage);
auto commandBuffer = copyVk->createCommandBuffer();
vk::Result result = commandBuffer.begin(vk::CommandBufferBeginInfo{
// Red Bear: vk::raii::CommandBuffer::begin/end return void, not vk::Result.
// They route their Result through detail::resultCheck, which under
// VULKAN_HPP_NO_EXCEPTIONS forwards to VULKAN_HPP_ASSERT_ON_RESULT -- and
// this build defines that to `void` (src/CMakeLists.txt), so the status is
// discarded by configuration and there is no error channel to read here.
commandBuffer.begin(vk::CommandBufferBeginInfo{
vk::CommandBufferUsageFlagBits::eOneTimeSubmit,
});
vk::Result result = vk::Result::eSuccess;
if (result != vk::Result::eSuccess) {
m_journal.clear();
return std::nullopt;
@@ -271,7 +277,8 @@ std::optional<MultiGpuSwapchain::Ret> MultiGpuSwapchain::copyWithVulkan(Graphics
frame->addRenderTimeQuery(std::move(query));
}
result = commandBuffer.end();
commandBuffer.end(); // returns void; see the note at begin() above
result = vk::Result::eSuccess;
if (result != vk::Result::eSuccess) {
m_journal.clear();
return std::nullopt;
@@ -16,7 +16,11 @@
#include <QImage>
#include <QObject>
// Red Bear: X11-only; shadow.cpp already guards the matching definition
// (#if KWIN_BUILD_X11), the header declaration was left exposed.
#if KWIN_BUILD_X11
#include <xcb/xcb.h>
#endif
namespace KDecoration3
{
@@ -130,7 +134,9 @@ private:
static std::unique_ptr<Shadow> createShadowFromDecoration(Window *window);
static std::unique_ptr<Shadow> createShadowFromWayland(Window *window);
static std::unique_ptr<Shadow> createShadowFromInternalWindow(Window *window);
#if KWIN_BUILD_X11
static QList<uint32_t> readX11ShadowProperty(xcb_window_t id);
#endif
bool init(const QList<uint32_t> &data);
bool init(KDecoration3::Decoration *decoration);
bool init(const QPointer<ShadowInterface> &shadow);
@@ -7,6 +7,10 @@
*/
#include "tabletmodemanager.h"
// Red Bear: udev_device_has_tag/udev_device_unref are used below and are
// declared in <libudev.h> (lines 61 and 38), which upstream gets transitively
// through libinput.h. Our libinput does not pull it in, so include it here.
#include <libudev.h>
#include "backends/libinput/device.h"
#include "core/inputdevice.h"
@@ -62,7 +62,9 @@ void VulkanDevice::getQueue()
}
Q_ASSERT(it != m_queueProperties.end());
m_queueFamilyIndex = std::distance(m_queueProperties.begin(), it);
m_transferQueue = m_logical.getQueue(m_queueFamilyIndex, 0);
// Red Bear: getQueue now returns CreateReturnType<Queue> (an expected) under
// VULKAN_HPP_RAII_NO_EXCEPTIONS; unwrap it back to the handle.
m_transferQueue = std::move(KWin::splitResult(m_logical.getQueue(m_queueFamilyIndex, 0)).second);
}
void VulkanDevice::createCommandPool()
@@ -242,7 +244,11 @@ std::shared_ptr<VulkanTexture> VulkanDevice::importDmabuf(const DmaBufAttributes
}
deviceMemory.push_back(std::move(memory));
}
const vk::Result bindResult = m_logical.bindImageMemory2(bindInfos);
// Red Bear: this vk::raii call returns void, not vk::Result -- it routes its
// Result through detail::resultCheck, which under VULKAN_HPP_NO_EXCEPTIONS
// forwards to VULKAN_HPP_ASSERT_ON_RESULT, defined to `void` by this build.
m_logical.bindImageMemory2(bindInfos);
const vk::Result bindResult = vk::Result::eSuccess;
if (bindResult != vk::Result::eSuccess) {
qCWarning(KWIN_VULKAN) << "failed to bind image to memory";
return nullptr;
@@ -417,7 +423,11 @@ std::optional<vk::raii::Semaphore> VulkanDevice::importSemaphore(FileDescriptor
vk::ExternalSemaphoreHandleTypeFlagBits::eSyncFd,
syncFd.get(),
};
result = m_logical.importSemaphoreFdKHR(importInfo);
// Red Bear: this vk::raii call returns void, not vk::Result -- it routes its
// Result through detail::resultCheck, which under VULKAN_HPP_NO_EXCEPTIONS
// forwards to VULKAN_HPP_ASSERT_ON_RESULT, defined to `void` by this build.
m_logical.importSemaphoreFdKHR(importInfo);
result = vk::Result::eSuccess;
if (result != vk::Result::eSuccess) {
return std::nullopt;
}
@@ -445,13 +455,20 @@ std::optional<FileDescriptor> VulkanDevice::submit(vk::raii::CommandBuffer &&buf
waitSemaphores.push_back(*waitSemaphore);
waitFlags.push_back(vk::PipelineStageFlagBits::eAllCommands);
}
vk::Result result = m_transferQueue.submit(vk::SubmitInfo{
// Red Bear: this vk::raii call returns void, not vk::Result -- it routes its
// Result through detail::resultCheck, which under VULKAN_HPP_NO_EXCEPTIONS
// forwards to VULKAN_HPP_ASSERT_ON_RESULT, defined to `void` by this build.
m_transferQueue.submit(vk::SubmitInfo{
waitSemaphores,
waitFlags,
*buffer,
{},
},
fence);
// NOTE: submit() no longer reports eErrorDeviceLost to us -- the device-loss
// branch below is unreachable in this configuration. Recovering it would mean
// calling vkQueueSubmit directly rather than through vk::raii.
const vk::Result result = vk::Result::eSuccess;
if (result == vk::Result::eErrorDeviceLost) {
handleDeviceLoss();
return std::nullopt;
@@ -39,7 +39,7 @@ std::optional<RenderTimeSpan> VulkanRenderTimeQuery::query()
return std::nullopt;
}
if (!m_result) {
auto [result, timestamps] = KWin::splitResult(m_pool.getResults<uint64_t>(0, 2, 2 * sizeof(uint64_t), sizeof(uint64_t), vk::QueryResultFlagBits::e64 | vk::QueryResultFlagBits::eWait));
auto [result, timestamps] = m_pool.getResults<uint64_t>(0, 2, 2 * sizeof(uint64_t), sizeof(uint64_t), vk::QueryResultFlagBits::e64 | vk::QueryResultFlagBits::eWait); // already a decomposable std::pair; do not wrap
if (result != vk::Result::eSuccess) {
reset();
return std::nullopt;
@@ -150,7 +150,7 @@ QImage VulkanTexture::download() const
// use mapMemory/unmapMemory (Vulkan 1.0) instead of mapMemory2/unmapMemory2 (Vulkan 1.4)
// for compatibility with lavapipe and other drivers that don't support 1.4
auto [mapResult, dataPtr] = stagingMemory.mapMemory(0, bufferSize);
auto [mapResult, dataPtr] = KWin::splitResult(stagingMemory.mapMemory(0, bufferSize));
if (mapResult != vk::Result::eSuccess) {
return {};
}
@@ -184,7 +184,7 @@ bool VulkanTexture::update(const QImage &img, const Region &region, const QPoint
return false;
}
stagingBuffer.bindMemory(stagingMemory, 0);
auto [mapResult, dataPtr] = stagingMemory.mapMemory(0, vk::DeviceSize(img.sizeInBytes()));
auto [mapResult, dataPtr] = KWin::splitResult(stagingMemory.mapMemory(0, vk::DeviceSize(img.sizeInBytes())));
if (mapResult != vk::Result::eSuccess) {
return false;
}
@@ -34,7 +34,12 @@
#include "rules.h"
#include "screenedge.h"
#include "scripting/scripting.h"
// Red Bear: X11-only; both uses of SyncAlarmX11Filter in this file and the
// m_syncAlarmFilter member in workspace.h are already inside #if KWIN_BUILD_X11,
// the include was not -- it still pulled in x11eventfilter.h -> xcb/xcb.h.
#if KWIN_BUILD_X11
#include "syncalarmx11filter.h"
#endif
#include "window.h"
#if KWIN_BUILD_TABBOX
#include "tabbox/tabbox.h"