File indexing completed on 2025-01-26 05:06:34
0001 /* 0002 SPDX-FileCopyrightText: 2017 Xuetian Weng <wengxt@gmail.com> 0003 SPDX-FileCopyrightText: 2018 Roman Gilg <subdiff@gmail.com> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "x11_backend.h" 0009 #include "x11_libinput_backend.h" 0010 0011 #include "logging.h" 0012 0013 #include <config-X11.h> 0014 0015 #include <libinput-properties.h> 0016 0017 #include <KConfig> 0018 #include <KConfigGroup> 0019 #include <KLocalizedString> 0020 #include <KSharedConfig> 0021 #include <QFile> 0022 0023 #include <X11/X.h> 0024 #include <X11/Xatom.h> 0025 #include <X11/Xlib.h> 0026 #include <X11/Xutil.h> 0027 #include <X11/extensions/XI.h> 0028 #include <X11/extensions/XInput2.h> 0029 #if HAVE_XCURSOR 0030 #include <X11/Xcursor/Xcursor.h> 0031 #include <X11/extensions/XInput.h> 0032 #endif 0033 0034 X11Backend *X11Backend::implementation(QObject *parent) 0035 { 0036 auto dpy = QX11Info::display(); 0037 Atom testAtom = XInternAtom(dpy, LIBINPUT_PROP_ACCEL, True); 0038 0039 if (testAtom) { 0040 qCDebug(KCM_MOUSE) << "Using libinput driver on X11."; 0041 return new X11LibinputBackend(parent); 0042 } 0043 0044 return nullptr; 0045 } 0046 0047 X11Backend::X11Backend(QObject *parent) 0048 : InputBackend(parent) 0049 { 0050 m_platformX11 = QX11Info::isPlatformX11(); 0051 if (m_platformX11) { 0052 m_dpy = QX11Info::display(); 0053 } else { 0054 // TODO: remove this - not needed anymore with Wayland backend! 0055 // let's hope we have a compatibility system like Xwayland ready 0056 m_dpy = XOpenDisplay(nullptr); 0057 } 0058 } 0059 0060 X11Backend::~X11Backend() 0061 { 0062 if (!m_platformX11 && m_dpy) { 0063 XCloseDisplay(m_dpy); 0064 } 0065 } 0066 0067 QString X11Backend::currentCursorTheme() 0068 { 0069 if (!m_dpy) { 0070 return QString(); 0071 } 0072 0073 QByteArray name = XGetDefault(m_dpy, "Xcursor", "theme"); 0074 #if HAVE_XCURSOR 0075 if (name.isEmpty()) { 0076 name = QByteArray(XcursorGetTheme(m_dpy)); 0077 } 0078 #endif 0079 return QFile::decodeName(name); 0080 } 0081 0082 void X11Backend::applyCursorTheme(const QString &theme, int size) 0083 { 0084 #if HAVE_XCURSOR 0085 0086 // Apply the KDE cursor theme to ourselves 0087 if (!m_dpy) { 0088 return; 0089 } 0090 if (!theme.isEmpty()) { 0091 XcursorSetTheme(m_dpy, QFile::encodeName(theme)); 0092 } 0093 0094 if (size >= 0) { 0095 XcursorSetDefaultSize(m_dpy, size); 0096 } 0097 0098 // Load the default cursor from the theme and apply it to the root window. 0099 Cursor handle = XcursorLibraryLoadCursor(m_dpy, "left_ptr"); 0100 XDefineCursor(m_dpy, DefaultRootWindow(m_dpy), handle); 0101 XFreeCursor(m_dpy, handle); // Don't leak the cursor 0102 XFlush(m_dpy); 0103 #endif 0104 } 0105 0106 void X11Backend::kcmInit() 0107 { 0108 auto config = KSharedConfig::openConfig("kcminputrc", KConfig::NoGlobals); 0109 KConfigGroup group = config->group(QStringLiteral("Mouse")); 0110 const QString theme = group.readEntry("cursorTheme", QStringLiteral("breeze_cursors")); 0111 const int size = group.readEntry("cursorSize", 24); 0112 0113 // Note: If you update this code, update kapplymousetheme as well. 0114 0115 applyCursorTheme(theme, size); 0116 }