diff --git a/CMakeLists.txt b/CMakeLists.txt index 202b06e30e..4916d0f47d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -281,6 +281,7 @@ find_package(XCB 1.10 REQUIRED COMPONENTS SYNC XCB XFIXES + XINERAMA ) set_package_properties(XCB PROPERTIES TYPE REQUIRED) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9fef87e009..0bd7e665fa 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -200,6 +200,7 @@ target_link_libraries(kwin XCB::SYNC XCB::XCB XCB::XFIXES + XCB::XINERAMA UDev::UDev XKB::XKB diff --git a/src/workspace.cpp b/src/workspace.cpp index 57b569b73a..da1f354a3c 100644 --- a/src/workspace.cpp +++ b/src/workspace.cpp @@ -60,6 +60,8 @@ #include // Qt #include +// xcb +#include namespace KWin { @@ -2354,7 +2356,37 @@ int Workspace::oldDisplayHeight() const Output *Workspace::xineramaIndexToOutput(int index) const { - return kwinApp()->platform()->enabledOutputs().value(index); + xcb_connection_t *connection = kwinApp()->x11Connection(); + if (!connection) { + return nullptr; + } + + const ScopedCPointer active{xcb_xinerama_is_active_reply(connection, xcb_xinerama_is_active(connection), nullptr)}; + if (!active || !active->state) { + return nullptr; + } + + const ScopedCPointer screens(xcb_xinerama_query_screens_reply(connection, xcb_xinerama_query_screens(connection), nullptr)); + if (!screens) { + return nullptr; + } + + const int infoCount = xcb_xinerama_query_screens_screen_info_length(screens.data()); + if (index >= infoCount) { + return nullptr; + } + + const xcb_xinerama_screen_info_t *infos = xcb_xinerama_query_screens_screen_info(screens.data()); + const QRect needle(infos[index].x_org, infos[index].y_org, infos[index].width, infos[index].height); + + const auto haystack = kwinApp()->platform()->enabledOutputs(); + for (Output *output : haystack) { + if (Xcb::toXNative(output->geometry()) == needle) { + return output; + } + } + + return nullptr; } Output *Workspace::activeOutput() const