Commit aa739c59 authored by Vlad Zahorodnii's avatar Vlad Zahorodnii
Browse files

wayland: Make mapping from xinerama indices to Output correct

We assume that outputs in kwinApp()->platform()->enabledOutputs() are
stored in the xinerama order. However, this is not the case on Wayland
and it's not going to be changed because it increases the complexity.

This change makes Workspace::xineramaIndexToOutput() use Xinerama
extension API to map a xinerama index to the associated Output object.

With this, Xwayland applications will be able to put on outputs as

Note that xinerama indices are not cached because
Workspace::xineramaIndexToOutput() is not used in any hot code path. If
that changes, xinerama indices can be cached. The cache must be
invalidated whenever we get screens changed notify event from RANDR.
parent 5a8beacd
Pipeline #206521 passed with stage
in 11 minutes and 9 seconds
......@@ -281,6 +281,7 @@ find_package(XCB 1.10 REQUIRED COMPONENTS
set_package_properties(XCB PROPERTIES TYPE REQUIRED)
......@@ -200,6 +200,7 @@ target_link_libraries(kwin
......@@ -60,6 +60,8 @@
#include <KStartupInfo>
// Qt
#include <QtConcurrentRun>
// xcb
#include <xcb/xinerama.h>
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<xcb_xinerama_is_active_reply_t> active{xcb_xinerama_is_active_reply(connection, xcb_xinerama_is_active(connection), nullptr)};
if (!active || !active->state) {
return nullptr;
const ScopedCPointer<xcb_xinerama_query_screens_reply_t> 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(;
if (index >= infoCount) {
return nullptr;
const xcb_xinerama_screen_info_t *infos = xcb_xinerama_query_screens_screen_info(;
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
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment