From e7d02ad35596be5d679cfab4a6a9e1bb7c745e79 Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Tue, 28 Jul 2020 10:58:35 +0300 Subject: [PATCH] Introduce X11 default screen property in Application This spares unnecessary looping through all available X11 screens. --- .../integration/desktop_window_x11_test.cpp | 2 +- autotests/integration/scene_qpainter_test.cpp | 2 +- autotests/integration/xwaylandserver_test.cpp | 1 + libkwineffects/kwinglobals.h | 32 ------------------- main.h | 15 +++++++++ main_x11.cpp | 14 ++++++++ .../x11/standalone/screens_xrandr.cpp | 4 +-- .../platforms/x11/standalone/x11cursor.cpp | 2 +- plugins/scenes/xrender/scene_xrender.cpp | 2 +- workspace.cpp | 4 +-- xwl/clipboard.cpp | 2 +- xwl/dnd.cpp | 2 +- xwl/drag_x.cpp | 2 +- xwl/transfer.cpp | 2 +- xwl/xwayland.cpp | 10 +++--- xwl/xwayland.h | 6 ---- 16 files changed, 47 insertions(+), 55 deletions(-) diff --git a/autotests/integration/desktop_window_x11_test.cpp b/autotests/integration/desktop_window_x11_test.cpp index f14b006bb5..3b58f6a295 100644 --- a/autotests/integration/desktop_window_x11_test.cpp +++ b/autotests/integration/desktop_window_x11_test.cpp @@ -124,7 +124,7 @@ void X11DesktopWindowTest::testDesktopWindow() auto cmCookie = xcb_create_colormap_checked(c.data(), XCB_COLORMAP_ALLOC_NONE, colormapId, rootWindow(), visualId); QVERIFY(!xcb_request_check(c.data(), cmCookie)); - const uint32_t values[] = {XCB_PIXMAP_NONE, defaultScreen()->black_pixel, colormapId}; + const uint32_t values[] = {XCB_PIXMAP_NONE, kwinApp()->x11DefaultScreen()->black_pixel, colormapId}; auto cookie = xcb_create_window_checked(c.data(), 32, w, rootWindow(), windowGeometry.x(), windowGeometry.y(), diff --git a/autotests/integration/scene_qpainter_test.cpp b/autotests/integration/scene_qpainter_test.cpp index c5f48bd526..015234e044 100644 --- a/autotests/integration/scene_qpainter_test.cpp +++ b/autotests/integration/scene_qpainter_test.cpp @@ -327,7 +327,7 @@ void SceneQPainterTest::testX11Window() QVERIFY(!xcb_connection_has_error(c.data())); const QRect windowGeometry(0, 0, 100, 200); xcb_window_t w = xcb_generate_id(c.data()); - uint32_t value = defaultScreen()->white_pixel; + uint32_t value = kwinApp()->x11DefaultScreen()->white_pixel; xcb_create_window(c.data(), XCB_COPY_FROM_PARENT, w, rootWindow(), windowGeometry.x(), windowGeometry.y(), diff --git a/autotests/integration/xwaylandserver_test.cpp b/autotests/integration/xwaylandserver_test.cpp index 22bf31e99a..4bc17a19ee 100644 --- a/autotests/integration/xwaylandserver_test.cpp +++ b/autotests/integration/xwaylandserver_test.cpp @@ -129,6 +129,7 @@ void XwaylandServerTest::testCrash() QTRY_VERIFY(!client); QTRY_VERIFY(!unmanaged); QCOMPARE(kwinApp()->x11Connection(), nullptr); + QCOMPARE(kwinApp()->x11DefaultScreen(), nullptr); QCOMPARE(kwinApp()->x11RootWindow(), XCB_WINDOW_NONE); QCOMPARE(kwinApp()->x11ScreenNumber(), -1); } diff --git a/libkwineffects/kwinglobals.h b/libkwineffects/kwinglobals.h index 04e92a1b08..20b629f434 100644 --- a/libkwineffects/kwinglobals.h +++ b/libkwineffects/kwinglobals.h @@ -167,38 +167,6 @@ KWIN_EXPORT xcb_timestamp_t xTime() return qApp->property("x11Time").value(); } -inline -KWIN_EXPORT xcb_screen_t *defaultScreen() -{ - xcb_connection_t *c = connection(); - if (!c) { - return nullptr; - } - int screen = qApp->property("x11ScreenNumber").toInt(); - for (xcb_screen_iterator_t it = xcb_setup_roots_iterator(xcb_get_setup(c)); - it.rem; - --screen, xcb_screen_next(&it)) { - if (screen == 0) { - return it.data; - } - } - return nullptr; -} - -inline -KWIN_DEPRECATED_EXPORT int displayWidth() -{ - xcb_screen_t *screen = defaultScreen(); - return screen ? screen->width_in_pixels : 0; -} - -inline -KWIN_DEPRECATED_EXPORT int displayHeight() -{ - xcb_screen_t *screen = defaultScreen(); - return screen ? screen->height_in_pixels : 0; -} - /** * Short wrapper for a cursor image provided by the Platform. * @since 5.9 diff --git a/main.h b/main.h index 1290b3671d..812c1dddd6 100644 --- a/main.h +++ b/main.h @@ -162,6 +162,13 @@ public: return m_connection; } + /** + * @returns the X11 default screen + */ + xcb_screen_t *x11DefaultScreen() const { + return m_defaultScreen; + } + #ifdef KWIN_BUILD_ACTIVITIES bool usesKActivities() const { return m_useKActivities; @@ -224,6 +231,13 @@ protected: void setX11Connection(xcb_connection_t *c) { m_connection = c; } + /** + * Inheriting classes should use this method to set the default screen + * before accessing any X11 specific code pathes. + */ + void setX11DefaultScreen(xcb_screen_t *screen) { + m_defaultScreen = screen; + } void destroyAtoms(); void destroyPlatform(); @@ -246,6 +260,7 @@ private: xcb_timestamp_t m_x11Time = XCB_TIME_CURRENT_TIME; xcb_window_t m_rootWindow = XCB_WINDOW_NONE; xcb_connection_t *m_connection = nullptr; + xcb_screen_t *m_defaultScreen = nullptr; #ifdef KWIN_BUILD_ACTIVITIES bool m_useKActivities = true; #endif diff --git a/main_x11.cpp b/main_x11.cpp index 051058ca0a..316476e93f 100644 --- a/main_x11.cpp +++ b/main_x11.cpp @@ -208,6 +208,19 @@ void ApplicationX11::lostSelection() quit(); } + +static xcb_screen_t *findXcbScreen(xcb_connection_t *connection, int screen) +{ + for (xcb_screen_iterator_t it = xcb_setup_roots_iterator(xcb_get_setup(connection)); + it.rem; + --screen, xcb_screen_next(&it)) { + if (screen == 0) { + return it.data; + } + } + return nullptr; +} + void ApplicationX11::performStartup() { crashChecking(); @@ -215,6 +228,7 @@ void ApplicationX11::performStartup() if (Application::x11ScreenNumber() == -1) { Application::setX11ScreenNumber(QX11Info::appScreen()); } + setX11DefaultScreen(findXcbScreen(x11Connection(), x11ScreenNumber())); owner.reset(new KWinSelectionOwner(Application::x11ScreenNumber())); connect(owner.data(), &KSelectionOwner::failedToClaimOwnership, []{ diff --git a/plugins/platforms/x11/standalone/screens_xrandr.cpp b/plugins/platforms/x11/standalone/screens_xrandr.cpp index 0acb111eab..3ba90603e9 100644 --- a/plugins/platforms/x11/standalone/screens_xrandr.cpp +++ b/plugins/platforms/x11/standalone/screens_xrandr.cpp @@ -78,7 +78,7 @@ bool XRandRScreens::event(xcb_generic_event_t *event) // update default screen auto *xrrEvent = reinterpret_cast(event); - xcb_screen_t *screen = defaultScreen(); + xcb_screen_t *screen = kwinApp()->x11DefaultScreen(); if (xrrEvent->rotation & (XCB_RANDR_ROTATION_ROTATE_90 | XCB_RANDR_ROTATION_ROTATE_270)) { screen->width_in_pixels = xrrEvent->height; screen->height_in_pixels = xrrEvent->width; @@ -96,7 +96,7 @@ bool XRandRScreens::event(xcb_generic_event_t *event) QSize XRandRScreens::displaySize() const { - xcb_screen_t *screen = defaultScreen(); + xcb_screen_t *screen = kwinApp()->x11DefaultScreen(); if (!screen) { return Screens::size(); } diff --git a/plugins/platforms/x11/standalone/x11cursor.cpp b/plugins/platforms/x11/standalone/x11cursor.cpp index 402bc39306..06761e82bc 100644 --- a/plugins/platforms/x11/standalone/x11cursor.cpp +++ b/plugins/platforms/x11/standalone/x11cursor.cpp @@ -165,7 +165,7 @@ xcb_cursor_t X11Cursor::createCursor(const QByteArray &name) return XCB_CURSOR_NONE; } xcb_cursor_context_t *ctx; - if (xcb_cursor_context_new(connection(), defaultScreen(), &ctx) < 0) { + if (xcb_cursor_context_new(kwinApp()->x11Connection(), kwinApp()->x11DefaultScreen(), &ctx) < 0) { return XCB_CURSOR_NONE; } xcb_cursor_t cursor = xcb_cursor_load_cursor(ctx, name.constData()); diff --git a/plugins/scenes/xrender/scene_xrender.cpp b/plugins/scenes/xrender/scene_xrender.cpp index ab664d5c66..35f5c39b85 100644 --- a/plugins/scenes/xrender/scene_xrender.cpp +++ b/plugins/scenes/xrender/scene_xrender.cpp @@ -162,7 +162,7 @@ void X11XRenderBackend::init(bool createOverlay) xcb_render_create_picture(connection(), m_front, m_overlayWindow->window(), m_format, 0, nullptr); } else { // create XRender picture for the root window - m_format = XRenderUtils::findPictFormat(defaultScreen()->root_visual); + m_format = XRenderUtils::findPictFormat(kwinApp()->x11DefaultScreen()->root_visual); if (m_format == 0) { setFailed("Failed to find XRender format for root window"); return; // error diff --git a/workspace.cpp b/workspace.cpp index b1592a3db1..be5e0f3488 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -79,8 +79,8 @@ extern bool is_multihead; ColorMapper::ColorMapper(QObject *parent) : QObject(parent) - , m_default(defaultScreen()->default_colormap) - , m_installed(defaultScreen()->default_colormap) + , m_default(kwinApp()->x11DefaultScreen()->default_colormap) + , m_installed(kwinApp()->x11DefaultScreen()->default_colormap) { } diff --git a/xwl/clipboard.cpp b/xwl/clipboard.cpp index 46b357ca4c..32c72109d6 100644 --- a/xwl/clipboard.cpp +++ b/xwl/clipboard.cpp @@ -61,7 +61,7 @@ Clipboard::Clipboard(xcb_atom_t atom, QObject *parent) 10, 10, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, - Xwayland::self()->xcbScreen()->root_visual, + XCB_COPY_FROM_PARENT, XCB_CW_EVENT_MASK, clipboardValues); registerXfixes(); diff --git a/xwl/dnd.cpp b/xwl/dnd.cpp index 4b74ab5c3e..5e4b63496b 100644 --- a/xwl/dnd.cpp +++ b/xwl/dnd.cpp @@ -68,7 +68,7 @@ Dnd::Dnd(xcb_atom_t atom, QObject *parent) 8192, 8192, // TODO: get current screen size and connect to changes 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, - Xwayland::self()->xcbScreen()->root_visual, + XCB_COPY_FROM_PARENT, XCB_CW_EVENT_MASK, dndValues); registerXfixes(); diff --git a/xwl/drag_x.cpp b/xwl/drag_x.cpp index 85571d7072..76a9bde633 100644 --- a/xwl/drag_x.cpp +++ b/xwl/drag_x.cpp @@ -304,7 +304,7 @@ WlVisit::WlVisit(AbstractClient *target, XToWlDrag *drag) 8192, 8192, // TODO: get current screen size and connect to changes 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, - Xwayland::self()->xcbScreen()->root_visual, + XCB_COPY_FROM_PARENT, XCB_CW_EVENT_MASK, dndValues); diff --git a/xwl/transfer.cpp b/xwl/transfer.cpp index b82b2fde5f..97949e0285 100644 --- a/xwl/transfer.cpp +++ b/xwl/transfer.cpp @@ -293,7 +293,7 @@ TransferXtoWl::TransferXtoWl(xcb_atom_t selection, xcb_atom_t target, qint32 fd, 10, 10, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, - Xwayland::self()->xcbScreen()->root_visual, + XCB_COPY_FROM_PARENT, XCB_CW_EVENT_MASK, values); // convert selection diff --git a/xwl/xwayland.cpp b/xwl/xwayland.cpp index 84f63d3da7..65e8e3c0fb 100644 --- a/xwl/xwayland.cpp +++ b/xwl/xwayland.cpp @@ -281,13 +281,13 @@ void Xwayland::createX11Connection() return; } - xcb_screen_iterator_t iter = xcb_setup_roots_iterator(xcb_get_setup(connection)); - m_xcbScreen = iter.data; - Q_ASSERT(m_xcbScreen); + xcb_screen_t *screen = xcb_setup_roots_iterator(xcb_get_setup(connection)).data; + Q_ASSERT(screen); m_app->setX11Connection(connection); + m_app->setX11DefaultScreen(screen); m_app->setX11ScreenNumber(0); - m_app->setX11RootWindow(defaultScreen()->root); + m_app->setX11RootWindow(screen->root); m_app->createAtoms(); m_app->installNativeX11EventFilter(); @@ -313,11 +313,11 @@ void Xwayland::destroyX11Connection() xcb_disconnect(m_app->x11Connection()); - m_xcbScreen = nullptr; m_xcbConnectionFd = -1; m_xfixes = nullptr; m_app->setX11Connection(nullptr); + m_app->setX11DefaultScreen(nullptr); m_app->setX11ScreenNumber(-1); m_app->setX11RootWindow(XCB_WINDOW_NONE); diff --git a/xwl/xwayland.h b/xwl/xwayland.h index 5d2f06ebeb..78de85d3aa 100644 --- a/xwl/xwayland.h +++ b/xwl/xwayland.h @@ -28,8 +28,6 @@ along with this program. If not, see . #include -class xcb_screen_t; - namespace KWin { class ApplicationWaylandAbstract; @@ -48,9 +46,6 @@ public: Xwayland(ApplicationWaylandAbstract *app, QObject *parent = nullptr); ~Xwayland() override; - xcb_screen_t *xcbScreen() const { - return m_xcbScreen; - } const xcb_query_extension_reply_t *xfixes() const { return m_xfixes; } @@ -115,7 +110,6 @@ private: int m_displayFileDescriptor = -1; int m_xcbConnectionFd = -1; QProcess *m_xwaylandProcess = nullptr; - xcb_screen_t *m_xcbScreen = nullptr; const xcb_query_extension_reply_t *m_xfixes = nullptr; DataBridge *m_dataBridge = nullptr; QSocketNotifier *m_socketNotifier = nullptr;