Introduce X11 default screen property in Application

This spares unnecessary looping through all available X11 screens.
This commit is contained in:
Vlad Zahorodnii 2020-07-28 10:58:35 +03:00
parent 7ec93493c9
commit e7d02ad355
16 changed files with 47 additions and 55 deletions

View file

@ -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(),

View file

@ -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(),

View file

@ -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);
}

View file

@ -167,38 +167,6 @@ KWIN_EXPORT xcb_timestamp_t xTime()
return qApp->property("x11Time").value<xcb_timestamp_t>();
}
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

15
main.h
View file

@ -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

View file

@ -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, []{

View file

@ -78,7 +78,7 @@ bool XRandRScreens::event(xcb_generic_event_t *event)
// update default screen
auto *xrrEvent = reinterpret_cast<xcb_randr_screen_change_notify_event_t*>(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();
}

View file

@ -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());

View file

@ -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

View file

@ -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)
{
}

View file

@ -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();

View file

@ -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();

View file

@ -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);

View file

@ -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

View file

@ -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);

View file

@ -28,8 +28,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <xcb/xproto.h>
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;