File indexing completed on 2025-02-16 11:23:02
0001 /* 0002 KWin - the KDE window manager 0003 This file is part of the KDE project. 0004 0005 SPDX-FileCopyrightText: 2013 Martin Gräßlin <mgraesslin@kde.org> 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 0010 #include "cursor.h" 0011 // kwin 0012 #include "composite.h" 0013 #include "core/output.h" 0014 #include "cursorsource.h" 0015 #include "input.h" 0016 #include "keyboard_input.h" 0017 #include "main.h" 0018 #include "scene/workspacescene.h" 0019 #include "utils/common.h" 0020 #include "utils/xcbutils.h" 0021 // KDE 0022 #include <KConfig> 0023 #include <KConfigGroup> 0024 // Qt 0025 #include <QAbstractEventDispatcher> 0026 #include <QDBusConnection> 0027 #include <QScreen> 0028 #include <QTimer> 0029 0030 #include <xcb/xcb_cursor.h> 0031 0032 namespace KWin 0033 { 0034 Cursors *Cursors::s_self = nullptr; 0035 Cursors *Cursors::self() 0036 { 0037 if (!s_self) { 0038 s_self = new Cursors; 0039 } 0040 return s_self; 0041 } 0042 0043 void Cursors::addCursor(Cursor *cursor) 0044 { 0045 Q_ASSERT(!m_cursors.contains(cursor)); 0046 m_cursors += cursor; 0047 0048 connect(cursor, &Cursor::posChanged, this, [this, cursor](const QPoint &pos) { 0049 setCurrentCursor(cursor); 0050 Q_EMIT positionChanged(cursor, pos); 0051 }); 0052 } 0053 0054 void Cursors::removeCursor(Cursor *cursor) 0055 { 0056 m_cursors.removeOne(cursor); 0057 if (m_currentCursor == cursor) { 0058 if (m_cursors.isEmpty()) { 0059 m_currentCursor = nullptr; 0060 } else { 0061 setCurrentCursor(m_cursors.constFirst()); 0062 } 0063 } 0064 if (m_mouse == cursor) { 0065 m_mouse = nullptr; 0066 } 0067 } 0068 0069 void Cursors::hideCursor() 0070 { 0071 m_cursorHideCounter++; 0072 if (m_cursorHideCounter == 1) { 0073 Q_EMIT hiddenChanged(); 0074 } 0075 } 0076 0077 void Cursors::showCursor() 0078 { 0079 m_cursorHideCounter--; 0080 if (m_cursorHideCounter == 0) { 0081 Q_EMIT hiddenChanged(); 0082 } 0083 } 0084 0085 bool Cursors::isCursorHidden() const 0086 { 0087 return m_cursorHideCounter > 0; 0088 } 0089 0090 void Cursors::setCurrentCursor(Cursor *cursor) 0091 { 0092 if (m_currentCursor == cursor) { 0093 return; 0094 } 0095 0096 Q_ASSERT(m_cursors.contains(cursor) || !cursor); 0097 0098 if (m_currentCursor) { 0099 disconnect(m_currentCursor, &Cursor::cursorChanged, this, &Cursors::emitCurrentCursorChanged); 0100 } 0101 m_currentCursor = cursor; 0102 connect(m_currentCursor, &Cursor::cursorChanged, this, &Cursors::emitCurrentCursorChanged); 0103 0104 Q_EMIT currentCursorChanged(m_currentCursor); 0105 } 0106 0107 void Cursors::emitCurrentCursorChanged() 0108 { 0109 Q_EMIT currentCursorChanged(m_currentCursor); 0110 } 0111 0112 Cursor::Cursor(QObject *parent) 0113 : QObject(parent) 0114 , m_mousePollingCounter(0) 0115 , m_cursorTrackingCounter(0) 0116 , m_themeName(defaultThemeName()) 0117 , m_themeSize(defaultThemeSize()) 0118 { 0119 loadThemeSettings(); 0120 QDBusConnection::sessionBus().connect(QString(), QStringLiteral("/KGlobalSettings"), QStringLiteral("org.kde.KGlobalSettings"), 0121 QStringLiteral("notifyChange"), this, SLOT(slotKGlobalSettingsNotifyChange(int, int))); 0122 } 0123 0124 Cursor::~Cursor() 0125 { 0126 Cursors::self()->removeCursor(this); 0127 } 0128 0129 void Cursor::loadThemeSettings() 0130 { 0131 QString themeName = QString::fromUtf8(qgetenv("XCURSOR_THEME")); 0132 bool ok = false; 0133 // XCURSOR_SIZE might not be set (e.g. by startkde) 0134 const uint themeSize = qEnvironmentVariableIntValue("XCURSOR_SIZE", &ok); 0135 if (!themeName.isEmpty() && ok) { 0136 updateTheme(themeName, themeSize); 0137 return; 0138 } 0139 // didn't get from environment variables, read from config file 0140 loadThemeFromKConfig(); 0141 } 0142 0143 void Cursor::loadThemeFromKConfig() 0144 { 0145 KConfigGroup mousecfg(InputConfig::self()->inputConfig(), "Mouse"); 0146 const QString themeName = mousecfg.readEntry("cursorTheme", defaultThemeName()); 0147 const uint themeSize = mousecfg.readEntry("cursorSize", defaultThemeSize()); 0148 updateTheme(themeName, themeSize); 0149 } 0150 0151 void Cursor::updateTheme(const QString &name, int size) 0152 { 0153 if (m_themeName != name || m_themeSize != size) { 0154 m_themeName = name; 0155 m_themeSize = size; 0156 m_cursors.clear(); 0157 Q_EMIT themeChanged(); 0158 } 0159 } 0160 0161 void Cursor::slotKGlobalSettingsNotifyChange(int type, int arg) 0162 { 0163 // #endif 0164 if (type == 5 /*CursorChanged*/) { 0165 InputConfig::self()->inputConfig()->reparseConfiguration(); 0166 loadThemeFromKConfig(); 0167 // sync to environment 0168 qputenv("XCURSOR_THEME", m_themeName.toUtf8()); 0169 qputenv("XCURSOR_SIZE", QByteArray::number(m_themeSize)); 0170 } 0171 } 0172 0173 bool Cursor::isOnOutput(Output *output) const 0174 { 0175 if (Cursors::self()->isCursorHidden()) { 0176 return false; 0177 } 0178 return geometry().intersects(output->geometry()); 0179 } 0180 0181 QImage Cursor::image() const 0182 { 0183 if (Q_UNLIKELY(!m_source)) { 0184 return QImage(); 0185 } 0186 return m_source->image(); 0187 } 0188 0189 QPoint Cursor::hotspot() const 0190 { 0191 if (Q_UNLIKELY(!m_source)) { 0192 return QPoint(); 0193 } 0194 return m_source->hotspot(); 0195 } 0196 0197 QRect Cursor::geometry() const 0198 { 0199 return rect().translated(m_pos - hotspot()); 0200 } 0201 0202 QRect Cursor::rect() const 0203 { 0204 if (Q_UNLIKELY(!m_source)) { 0205 return QRect(); 0206 } else { 0207 return QRect(QPoint(0, 0), m_source->size()); 0208 } 0209 } 0210 0211 QPoint Cursor::pos() 0212 { 0213 doGetPos(); 0214 return m_pos; 0215 } 0216 0217 void Cursor::setPos(const QPointF &pos) 0218 { 0219 setPos(pos.toPoint()); 0220 } 0221 0222 void Cursor::setPos(const QPoint &pos) 0223 { 0224 // first query the current pos to not warp to the already existing pos 0225 if (pos == m_pos) { 0226 return; 0227 } 0228 m_pos = pos; 0229 doSetPos(); 0230 } 0231 0232 void Cursor::setPos(int x, int y) 0233 { 0234 setPos(QPoint(x, y)); 0235 } 0236 0237 void Cursor::markAsRendered(std::chrono::milliseconds timestamp) 0238 { 0239 Q_EMIT rendered(timestamp); 0240 } 0241 0242 xcb_cursor_t Cursor::x11Cursor(CursorShape shape) 0243 { 0244 return x11Cursor(shape.name()); 0245 } 0246 0247 xcb_cursor_t Cursor::x11Cursor(const QByteArray &name) 0248 { 0249 Q_ASSERT(kwinApp()->x11Connection()); 0250 auto it = m_cursors.constFind(name); 0251 if (it != m_cursors.constEnd()) { 0252 return it.value(); 0253 } 0254 0255 if (name.isEmpty()) { 0256 return XCB_CURSOR_NONE; 0257 } 0258 0259 xcb_cursor_context_t *ctx; 0260 if (xcb_cursor_context_new(kwinApp()->x11Connection(), Xcb::defaultScreen(), &ctx) < 0) { 0261 return XCB_CURSOR_NONE; 0262 } 0263 0264 xcb_cursor_t cursor = xcb_cursor_load_cursor(ctx, name.constData()); 0265 if (cursor == XCB_CURSOR_NONE) { 0266 const auto &names = Cursor::cursorAlternativeNames(name); 0267 for (const QByteArray &cursorName : names) { 0268 cursor = xcb_cursor_load_cursor(ctx, cursorName.constData()); 0269 if (cursor != XCB_CURSOR_NONE) { 0270 break; 0271 } 0272 } 0273 } 0274 if (cursor != XCB_CURSOR_NONE) { 0275 m_cursors.insert(name, cursor); 0276 } 0277 0278 xcb_cursor_context_free(ctx); 0279 return cursor; 0280 } 0281 0282 void Cursor::doSetPos() 0283 { 0284 Q_EMIT posChanged(m_pos); 0285 } 0286 0287 void Cursor::doGetPos() 0288 { 0289 } 0290 0291 void Cursor::updatePos(const QPoint &pos) 0292 { 0293 if (m_pos == pos) { 0294 return; 0295 } 0296 m_pos = pos; 0297 Q_EMIT posChanged(m_pos); 0298 } 0299 0300 void Cursor::startMousePolling() 0301 { 0302 ++m_mousePollingCounter; 0303 if (m_mousePollingCounter == 1) { 0304 doStartMousePolling(); 0305 } 0306 } 0307 0308 void Cursor::stopMousePolling() 0309 { 0310 Q_ASSERT(m_mousePollingCounter > 0); 0311 --m_mousePollingCounter; 0312 if (m_mousePollingCounter == 0) { 0313 doStopMousePolling(); 0314 } 0315 } 0316 0317 void Cursor::doStartMousePolling() 0318 { 0319 } 0320 0321 void Cursor::doStopMousePolling() 0322 { 0323 } 0324 0325 void Cursor::startCursorTracking() 0326 { 0327 ++m_cursorTrackingCounter; 0328 if (m_cursorTrackingCounter == 1) { 0329 doStartCursorTracking(); 0330 } 0331 } 0332 0333 void Cursor::stopCursorTracking() 0334 { 0335 Q_ASSERT(m_cursorTrackingCounter > 0); 0336 --m_cursorTrackingCounter; 0337 if (m_cursorTrackingCounter == 0) { 0338 doStopCursorTracking(); 0339 } 0340 } 0341 0342 void Cursor::doStartCursorTracking() 0343 { 0344 } 0345 0346 void Cursor::doStopCursorTracking() 0347 { 0348 } 0349 0350 QVector<QByteArray> Cursor::cursorAlternativeNames(const QByteArray &name) 0351 { 0352 static const QHash<QByteArray, QVector<QByteArray>> alternatives = { 0353 { 0354 QByteArrayLiteral("left_ptr"), 0355 { 0356 QByteArrayLiteral("arrow"), 0357 QByteArrayLiteral("dnd-none"), 0358 QByteArrayLiteral("op_left_arrow"), 0359 }, 0360 }, 0361 { 0362 QByteArrayLiteral("cross"), 0363 { 0364 QByteArrayLiteral("crosshair"), 0365 QByteArrayLiteral("diamond-cross"), 0366 QByteArrayLiteral("cross-reverse"), 0367 }, 0368 }, 0369 { 0370 QByteArrayLiteral("up_arrow"), 0371 { 0372 QByteArrayLiteral("center_ptr"), 0373 QByteArrayLiteral("sb_up_arrow"), 0374 QByteArrayLiteral("centre_ptr"), 0375 }, 0376 }, 0377 { 0378 QByteArrayLiteral("wait"), 0379 { 0380 QByteArrayLiteral("watch"), 0381 QByteArrayLiteral("progress"), 0382 }, 0383 }, 0384 { 0385 QByteArrayLiteral("ibeam"), 0386 { 0387 QByteArrayLiteral("xterm"), 0388 QByteArrayLiteral("text"), 0389 }, 0390 }, 0391 { 0392 QByteArrayLiteral("size_all"), 0393 { 0394 QByteArrayLiteral("fleur"), 0395 }, 0396 }, 0397 { 0398 QByteArrayLiteral("pointing_hand"), 0399 { 0400 QByteArrayLiteral("hand2"), 0401 QByteArrayLiteral("hand"), 0402 QByteArrayLiteral("hand1"), 0403 QByteArrayLiteral("pointer"), 0404 QByteArrayLiteral("e29285e634086352946a0e7090d73106"), 0405 QByteArrayLiteral("9d800788f1b08800ae810202380a0822"), 0406 }, 0407 }, 0408 { 0409 QByteArrayLiteral("size_ver"), 0410 { 0411 QByteArrayLiteral("00008160000006810000408080010102"), 0412 QByteArrayLiteral("sb_v_double_arrow"), 0413 QByteArrayLiteral("v_double_arrow"), 0414 QByteArrayLiteral("n-resize"), 0415 QByteArrayLiteral("s-resize"), 0416 QByteArrayLiteral("col-resize"), 0417 QByteArrayLiteral("top_side"), 0418 QByteArrayLiteral("bottom_side"), 0419 QByteArrayLiteral("base_arrow_up"), 0420 QByteArrayLiteral("base_arrow_down"), 0421 QByteArrayLiteral("based_arrow_down"), 0422 QByteArrayLiteral("based_arrow_up"), 0423 }, 0424 }, 0425 { 0426 QByteArrayLiteral("size_hor"), 0427 { 0428 QByteArrayLiteral("028006030e0e7ebffc7f7070c0600140"), 0429 QByteArrayLiteral("sb_h_double_arrow"), 0430 QByteArrayLiteral("h_double_arrow"), 0431 QByteArrayLiteral("e-resize"), 0432 QByteArrayLiteral("w-resize"), 0433 QByteArrayLiteral("row-resize"), 0434 QByteArrayLiteral("right_side"), 0435 QByteArrayLiteral("left_side"), 0436 }, 0437 }, 0438 { 0439 QByteArrayLiteral("size_bdiag"), 0440 { 0441 QByteArrayLiteral("fcf1c3c7cd4491d801f1e1c78f100000"), 0442 QByteArrayLiteral("fd_double_arrow"), 0443 QByteArrayLiteral("bottom_left_corner"), 0444 QByteArrayLiteral("top_right_corner"), 0445 }, 0446 }, 0447 { 0448 QByteArrayLiteral("size_fdiag"), 0449 { 0450 QByteArrayLiteral("c7088f0f3e6c8088236ef8e1e3e70000"), 0451 QByteArrayLiteral("bd_double_arrow"), 0452 QByteArrayLiteral("bottom_right_corner"), 0453 QByteArrayLiteral("top_left_corner"), 0454 }, 0455 }, 0456 { 0457 QByteArrayLiteral("whats_this"), 0458 { 0459 QByteArrayLiteral("d9ce0ab605698f320427677b458ad60b"), 0460 QByteArrayLiteral("left_ptr_help"), 0461 QByteArrayLiteral("help"), 0462 QByteArrayLiteral("question_arrow"), 0463 QByteArrayLiteral("dnd-ask"), 0464 QByteArrayLiteral("5c6cd98b3f3ebcb1f9c7f1c204630408"), 0465 }, 0466 }, 0467 { 0468 QByteArrayLiteral("split_h"), 0469 { 0470 QByteArrayLiteral("14fef782d02440884392942c11205230"), 0471 QByteArrayLiteral("size_hor"), 0472 }, 0473 }, 0474 { 0475 QByteArrayLiteral("split_v"), 0476 { 0477 QByteArrayLiteral("2870a09082c103050810ffdffffe0204"), 0478 QByteArrayLiteral("size_ver"), 0479 }, 0480 }, 0481 { 0482 QByteArrayLiteral("forbidden"), 0483 { 0484 QByteArrayLiteral("03b6e0fcb3499374a867c041f52298f0"), 0485 QByteArrayLiteral("circle"), 0486 QByteArrayLiteral("dnd-no-drop"), 0487 QByteArrayLiteral("not-allowed"), 0488 }, 0489 }, 0490 { 0491 QByteArrayLiteral("left_ptr_watch"), 0492 { 0493 QByteArrayLiteral("3ecb610c1bf2410f44200f48c40d3599"), 0494 QByteArrayLiteral("00000000000000020006000e7e9ffc3f"), 0495 QByteArrayLiteral("08e8e1c95fe2fc01f976f1e063a24ccd"), 0496 }, 0497 }, 0498 { 0499 QByteArrayLiteral("openhand"), 0500 { 0501 QByteArrayLiteral("9141b49c8149039304290b508d208c40"), 0502 QByteArrayLiteral("all_scroll"), 0503 QByteArrayLiteral("all-scroll"), 0504 }, 0505 }, 0506 { 0507 QByteArrayLiteral("closedhand"), 0508 { 0509 QByteArrayLiteral("05e88622050804100c20044008402080"), 0510 QByteArrayLiteral("4498f0e0c1937ffe01fd06f973665830"), 0511 QByteArrayLiteral("9081237383d90e509aa00f00170e968f"), 0512 QByteArrayLiteral("fcf21c00b30f7e3f83fe0dfd12e71cff"), 0513 }, 0514 }, 0515 { 0516 QByteArrayLiteral("dnd-link"), 0517 { 0518 QByteArrayLiteral("link"), 0519 QByteArrayLiteral("alias"), 0520 QByteArrayLiteral("3085a0e285430894940527032f8b26df"), 0521 QByteArrayLiteral("640fb0e74195791501fd1ed57b41487f"), 0522 QByteArrayLiteral("a2a266d0498c3104214a47bd64ab0fc8"), 0523 }, 0524 }, 0525 { 0526 QByteArrayLiteral("dnd-copy"), 0527 { 0528 QByteArrayLiteral("copy"), 0529 QByteArrayLiteral("1081e37283d90000800003c07f3ef6bf"), 0530 QByteArrayLiteral("6407b0e94181790501fd1e167b474872"), 0531 QByteArrayLiteral("b66166c04f8c3109214a4fbd64a50fc8"), 0532 }, 0533 }, 0534 { 0535 QByteArrayLiteral("dnd-move"), 0536 { 0537 QByteArrayLiteral("move"), 0538 }, 0539 }, 0540 { 0541 QByteArrayLiteral("sw-resize"), 0542 { 0543 QByteArrayLiteral("size_bdiag"), 0544 QByteArrayLiteral("fcf1c3c7cd4491d801f1e1c78f100000"), 0545 QByteArrayLiteral("fd_double_arrow"), 0546 QByteArrayLiteral("bottom_left_corner"), 0547 }, 0548 }, 0549 { 0550 QByteArrayLiteral("se-resize"), 0551 { 0552 QByteArrayLiteral("size_fdiag"), 0553 QByteArrayLiteral("c7088f0f3e6c8088236ef8e1e3e70000"), 0554 QByteArrayLiteral("bd_double_arrow"), 0555 QByteArrayLiteral("bottom_right_corner"), 0556 }, 0557 }, 0558 { 0559 QByteArrayLiteral("ne-resize"), 0560 { 0561 QByteArrayLiteral("size_bdiag"), 0562 QByteArrayLiteral("fcf1c3c7cd4491d801f1e1c78f100000"), 0563 QByteArrayLiteral("fd_double_arrow"), 0564 QByteArrayLiteral("top_right_corner"), 0565 }, 0566 }, 0567 { 0568 QByteArrayLiteral("nw-resize"), 0569 { 0570 QByteArrayLiteral("size_fdiag"), 0571 QByteArrayLiteral("c7088f0f3e6c8088236ef8e1e3e70000"), 0572 QByteArrayLiteral("bd_double_arrow"), 0573 QByteArrayLiteral("top_left_corner"), 0574 }, 0575 }, 0576 { 0577 QByteArrayLiteral("n-resize"), 0578 { 0579 QByteArrayLiteral("size_ver"), 0580 QByteArrayLiteral("00008160000006810000408080010102"), 0581 QByteArrayLiteral("sb_v_double_arrow"), 0582 QByteArrayLiteral("v_double_arrow"), 0583 QByteArrayLiteral("col-resize"), 0584 QByteArrayLiteral("top_side"), 0585 }, 0586 }, 0587 { 0588 QByteArrayLiteral("e-resize"), 0589 { 0590 QByteArrayLiteral("size_hor"), 0591 QByteArrayLiteral("028006030e0e7ebffc7f7070c0600140"), 0592 QByteArrayLiteral("sb_h_double_arrow"), 0593 QByteArrayLiteral("h_double_arrow"), 0594 QByteArrayLiteral("row-resize"), 0595 QByteArrayLiteral("left_side"), 0596 }, 0597 }, 0598 { 0599 QByteArrayLiteral("s-resize"), 0600 { 0601 QByteArrayLiteral("size_ver"), 0602 QByteArrayLiteral("00008160000006810000408080010102"), 0603 QByteArrayLiteral("sb_v_double_arrow"), 0604 QByteArrayLiteral("v_double_arrow"), 0605 QByteArrayLiteral("col-resize"), 0606 QByteArrayLiteral("bottom_side"), 0607 }, 0608 }, 0609 { 0610 QByteArrayLiteral("w-resize"), 0611 { 0612 QByteArrayLiteral("size_hor"), 0613 QByteArrayLiteral("028006030e0e7ebffc7f7070c0600140"), 0614 QByteArrayLiteral("sb_h_double_arrow"), 0615 QByteArrayLiteral("h_double_arrow"), 0616 QByteArrayLiteral("right_side"), 0617 }, 0618 }, 0619 }; 0620 auto it = alternatives.find(name); 0621 if (it != alternatives.end()) { 0622 return it.value(); 0623 } 0624 return QVector<QByteArray>(); 0625 } 0626 0627 QString Cursor::defaultThemeName() 0628 { 0629 return QStringLiteral("default"); 0630 } 0631 0632 int Cursor::defaultThemeSize() 0633 { 0634 return 24; 0635 } 0636 0637 QByteArray CursorShape::name() const 0638 { 0639 switch (m_shape) { 0640 case Qt::ArrowCursor: 0641 return QByteArrayLiteral("left_ptr"); 0642 case Qt::UpArrowCursor: 0643 return QByteArrayLiteral("up_arrow"); 0644 case Qt::CrossCursor: 0645 return QByteArrayLiteral("cross"); 0646 case Qt::WaitCursor: 0647 return QByteArrayLiteral("wait"); 0648 case Qt::IBeamCursor: 0649 return QByteArrayLiteral("ibeam"); 0650 case Qt::SizeVerCursor: 0651 return QByteArrayLiteral("size_ver"); 0652 case Qt::SizeHorCursor: 0653 return QByteArrayLiteral("size_hor"); 0654 case Qt::SizeBDiagCursor: 0655 return QByteArrayLiteral("size_bdiag"); 0656 case Qt::SizeFDiagCursor: 0657 return QByteArrayLiteral("size_fdiag"); 0658 case Qt::SizeAllCursor: 0659 return QByteArrayLiteral("size_all"); 0660 case Qt::SplitVCursor: 0661 return QByteArrayLiteral("split_v"); 0662 case Qt::SplitHCursor: 0663 return QByteArrayLiteral("split_h"); 0664 case Qt::PointingHandCursor: 0665 return QByteArrayLiteral("pointing_hand"); 0666 case Qt::ForbiddenCursor: 0667 return QByteArrayLiteral("forbidden"); 0668 case Qt::OpenHandCursor: 0669 return QByteArrayLiteral("openhand"); 0670 case Qt::ClosedHandCursor: 0671 return QByteArrayLiteral("closedhand"); 0672 case Qt::WhatsThisCursor: 0673 return QByteArrayLiteral("whats_this"); 0674 case Qt::BusyCursor: 0675 return QByteArrayLiteral("left_ptr_watch"); 0676 case Qt::DragMoveCursor: 0677 return QByteArrayLiteral("dnd-move"); 0678 case Qt::DragCopyCursor: 0679 return QByteArrayLiteral("dnd-copy"); 0680 case Qt::DragLinkCursor: 0681 return QByteArrayLiteral("dnd-link"); 0682 case KWin::ExtendedCursor::SizeNorthEast: 0683 return QByteArrayLiteral("ne-resize"); 0684 case KWin::ExtendedCursor::SizeNorth: 0685 return QByteArrayLiteral("n-resize"); 0686 case KWin::ExtendedCursor::SizeNorthWest: 0687 return QByteArrayLiteral("nw-resize"); 0688 case KWin::ExtendedCursor::SizeEast: 0689 return QByteArrayLiteral("e-resize"); 0690 case KWin::ExtendedCursor::SizeWest: 0691 return QByteArrayLiteral("w-resize"); 0692 case KWin::ExtendedCursor::SizeSouthEast: 0693 return QByteArrayLiteral("se-resize"); 0694 case KWin::ExtendedCursor::SizeSouth: 0695 return QByteArrayLiteral("s-resize"); 0696 case KWin::ExtendedCursor::SizeSouthWest: 0697 return QByteArrayLiteral("sw-resize"); 0698 default: 0699 return QByteArray(); 0700 } 0701 } 0702 0703 CursorSource *Cursor::source() const 0704 { 0705 return m_source; 0706 } 0707 0708 void Cursor::setSource(CursorSource *source) 0709 { 0710 if (m_source == source) { 0711 return; 0712 } 0713 if (m_source) { 0714 disconnect(m_source, &CursorSource::changed, this, &Cursor::cursorChanged); 0715 } 0716 m_source = source; 0717 connect(m_source, &CursorSource::changed, this, &Cursor::cursorChanged); 0718 Q_EMIT cursorChanged(); 0719 } 0720 0721 InputConfig *InputConfig::s_self = nullptr; 0722 InputConfig *InputConfig::self() 0723 { 0724 if (!s_self) { 0725 s_self = new InputConfig; 0726 } 0727 return s_self; 0728 } 0729 0730 InputConfig::InputConfig() 0731 : m_inputConfig(KSharedConfig::openConfig(QStringLiteral("kcminputrc"), KConfig::NoGlobals)) 0732 { 0733 } 0734 0735 } // namespace