39#include "ui_debug_console.h"
42#include <KLocalizedString>
45#include <QFutureWatcher>
46#include <QMetaProperty>
50#include <QSortFilterProxyModel>
51#include <QtConcurrentRun>
53#include <wayland-server-core.h>
56#include <xkbcommon/xkbcommon.h>
66static QString tableHeaderRow(
const QString &title)
68 return QStringLiteral(
"<tr><th colspan=\"2\">%1</th></tr>").arg(title);
72static QString tableRow(
const QString &title,
const T &argument)
74 return QStringLiteral(
"<tr><td>%1</td><td>%2</td></tr>").arg(title).arg(argument);
77static QString timestampRow(std::chrono::microseconds timestamp)
79 return tableRow(i18n(
"Timestamp"), std::chrono::duration_cast<std::chrono::milliseconds>(timestamp).count());
82static QString timestampRowUsec(std::chrono::microseconds timestamp)
84 return tableRow(i18n(
"Timestamp (µsec)"), timestamp.count());
87static QString buttonToString(Qt::MouseButton button)
91 return i18nc(
"A mouse button",
"Left");
93 return i18nc(
"A mouse button",
"Right");
94 case Qt::MiddleButton:
95 return i18nc(
"A mouse button",
"Middle");
97 return i18nc(
"A mouse button",
"Back");
98 case Qt::ForwardButton:
99 return i18nc(
"A mouse button",
"Forward");
101 return i18nc(
"A mouse button",
"Task");
102 case Qt::ExtraButton4:
103 return i18nc(
"A mouse button",
"Extra Button 4");
104 case Qt::ExtraButton5:
105 return i18nc(
"A mouse button",
"Extra Button 5");
106 case Qt::ExtraButton6:
107 return i18nc(
"A mouse button",
"Extra Button 6");
108 case Qt::ExtraButton7:
109 return i18nc(
"A mouse button",
"Extra Button 7");
110 case Qt::ExtraButton8:
111 return i18nc(
"A mouse button",
"Extra Button 8");
112 case Qt::ExtraButton9:
113 return i18nc(
"A mouse button",
"Extra Button 9");
114 case Qt::ExtraButton10:
115 return i18nc(
"A mouse button",
"Extra Button 10");
116 case Qt::ExtraButton11:
117 return i18nc(
"A mouse button",
"Extra Button 11");
118 case Qt::ExtraButton12:
119 return i18nc(
"A mouse button",
"Extra Button 12");
120 case Qt::ExtraButton13:
121 return i18nc(
"A mouse button",
"Extra Button 13");
122 case Qt::ExtraButton14:
123 return i18nc(
"A mouse button",
"Extra Button 14");
124 case Qt::ExtraButton15:
125 return i18nc(
"A mouse button",
"Extra Button 15");
126 case Qt::ExtraButton16:
127 return i18nc(
"A mouse button",
"Extra Button 16");
128 case Qt::ExtraButton17:
129 return i18nc(
"A mouse button",
"Extra Button 17");
130 case Qt::ExtraButton18:
131 return i18nc(
"A mouse button",
"Extra Button 18");
132 case Qt::ExtraButton19:
133 return i18nc(
"A mouse button",
"Extra Button 19");
134 case Qt::ExtraButton20:
135 return i18nc(
"A mouse button",
"Extra Button 20");
136 case Qt::ExtraButton21:
137 return i18nc(
"A mouse button",
"Extra Button 21");
138 case Qt::ExtraButton22:
139 return i18nc(
"A mouse button",
"Extra Button 22");
140 case Qt::ExtraButton23:
141 return i18nc(
"A mouse button",
"Extra Button 23");
142 case Qt::ExtraButton24:
143 return i18nc(
"A mouse button",
"Extra Button 24");
152 return tableRow(i18n(
"Input Device"), i18nc(
"The input device of the event is not known",
"Unknown"));
154 return tableRow(i18n(
"Input Device"), QStringLiteral(
"%1 (%2)").arg(device->name(), device->sysName()));
157static QString buttonsToString(Qt::MouseButtons buttons)
160 for (uint i = 1; i < Qt::ExtraButton24; i = i << 1) {
162 ret.append(buttonToString(Qt::MouseButton(uint(buttons) & i)));
163 ret.append(QStringLiteral(
" "));
166 return ret.trimmed();
169static const QString s_hr = QStringLiteral(
"<hr/>");
170static const QString s_tableStart = QStringLiteral(
"<table>");
171static const QString s_tableEnd = QStringLiteral(
"</table>");
175 , m_textEdit(textEdit)
184 const QString timestamp = timestampRow(event->
timestamp());
186 text.append(s_tableStart);
187 switch (event->type()) {
188 case QEvent::MouseMove: {
189 text.append(tableHeaderRow(i18nc(
"A mouse pointer motion event",
"Pointer Motion")));
190 text.append(deviceRow(event->
device()));
191 text.append(timestamp);
192 text.append(timestampRowUsec(event->
timestamp()));
193 if (!event->
delta().isNull()) {
194 text.append(tableRow(i18nc(
"The relative mouse movement",
"Delta"),
195 QStringLiteral(
"%1/%2").arg(event->
delta().x()).arg(event->
delta().y())));
198 text.append(tableRow(i18nc(
"The relative mouse movement",
"Delta (not accelerated)"),
201 text.append(tableRow(i18nc(
"The global mouse pointer position",
"Global Position"), QStringLiteral(
"%1/%2").arg(event->pos().x()).arg(event->pos().y())));
204 case QEvent::MouseButtonPress:
205 text.append(tableHeaderRow(i18nc(
"A mouse pointer button press event",
"Pointer Button Press")));
206 text.append(deviceRow(event->
device()));
207 text.append(timestamp);
208 text.append(tableRow(i18nc(
"A button in a mouse press/release event",
"Button"), buttonToString(event->button())));
209 text.append(tableRow(i18nc(
"A button in a mouse press/release event",
"Native Button code"), event->
nativeButton()));
210 text.append(tableRow(i18nc(
"All currently pressed buttons in a mouse press/release event",
"Pressed Buttons"), buttonsToString(event->buttons())));
212 case QEvent::MouseButtonRelease:
213 text.append(tableHeaderRow(i18nc(
"A mouse pointer button release event",
"Pointer Button Release")));
214 text.append(deviceRow(event->
device()));
215 text.append(timestamp);
216 text.append(tableRow(i18nc(
"A button in a mouse press/release event",
"Button"), buttonToString(event->button())));
217 text.append(tableRow(i18nc(
"A button in a mouse press/release event",
"Native Button code"), event->
nativeButton()));
218 text.append(tableRow(i18nc(
"All currently pressed buttons in a mouse press/release event",
"Pressed Buttons"), buttonsToString(event->buttons())));
223 text.append(s_tableEnd);
225 m_textEdit->insertHtml(text);
226 m_textEdit->ensureCursorVisible();
232 text.append(s_tableStart);
233 text.append(tableHeaderRow(i18nc(
"A mouse pointer axis (wheel) event",
"Pointer Axis")));
234 text.append(deviceRow(event->
device()));
235 text.append(timestampRow(event->
timestamp()));
236 const Qt::Orientation orientation =
event->angleDelta().x() == 0 ? Qt::Vertical : Qt::Horizontal;
237 text.append(tableRow(i18nc(
"The orientation of a pointer axis event",
"Orientation"),
238 orientation == Qt::Horizontal ? i18nc(
"An orientation of a pointer axis event",
"Horizontal")
239 : i18nc(
"An orientation of a pointer axis event",
"Vertical")));
240 text.append(tableRow(i18nc(
"The angle delta of a pointer axis event",
"Delta"),
241 orientation == Qt::Horizontal ?
event->angleDelta().x() :
event->angleDelta().y()));
242 text.append(s_tableEnd);
244 m_textEdit->insertHtml(text);
245 m_textEdit->ensureCursorVisible();
251 text.append(s_tableStart);
253 switch (event->type()) {
254 case QEvent::KeyPress:
255 text.append(tableHeaderRow(i18nc(
"A key press event",
"Key Press")));
257 case QEvent::KeyRelease:
258 text.append(tableHeaderRow(i18nc(
"A key release event",
"Key Release")));
263 text.append(deviceRow(event->
device()));
264 auto modifiersToString = [event] {
266 if (event->modifiers().testFlag(Qt::ShiftModifier)) {
267 ret.append(i18nc(
"A keyboard modifier",
"Shift"));
268 ret.append(QStringLiteral(
" "));
270 if (event->modifiers().testFlag(Qt::ControlModifier)) {
271 ret.append(i18nc(
"A keyboard modifier",
"Control"));
272 ret.append(QStringLiteral(
" "));
274 if (event->modifiers().testFlag(Qt::AltModifier)) {
275 ret.append(i18nc(
"A keyboard modifier",
"Alt"));
276 ret.append(QStringLiteral(
" "));
278 if (event->modifiers().testFlag(Qt::MetaModifier)) {
279 ret.append(i18nc(
"A keyboard modifier",
"Meta"));
280 ret.append(QStringLiteral(
" "));
282 if (event->modifiers().testFlag(Qt::KeypadModifier)) {
283 ret.append(i18nc(
"A keyboard modifier",
"Keypad"));
284 ret.append(QStringLiteral(
" "));
286 if (event->modifiers().testFlag(Qt::GroupSwitchModifier)) {
287 ret.append(i18nc(
"A keyboard modifier",
"Group-switch"));
288 ret.append(QStringLiteral(
" "));
292 text.append(timestampRow(event->
timestamp()));
293 text.append(tableRow(i18nc(
"Whether the event is an automatic key repeat",
"Repeat"), event->isAutoRepeat()));
295 const auto keyMetaObject = Qt::qt_getEnumMetaObject(Qt::Key());
296 const auto enumerator = keyMetaObject->enumerator(keyMetaObject->indexOfEnumerator(
"Key"));
297 text.append(tableRow(i18nc(
"The code as read from the input device",
"Scan code"), event->nativeScanCode()));
298 text.append(tableRow(i18nc(
"Key according to Qt",
"Qt::Key code"),
299 enumerator.valueToKey(event->key())));
300 text.append(tableRow(i18nc(
"The translated code to an Xkb symbol",
"Xkb symbol"), event->nativeVirtualKey()));
301 text.append(tableRow(i18nc(
"The translated code interpreted as text",
"Utf8"), event->text()));
302 text.append(tableRow(i18nc(
"The currently active modifiers",
"Modifiers"), modifiersToString()));
304 text.append(s_tableEnd);
306 m_textEdit->insertHtml(text);
307 m_textEdit->ensureCursorVisible();
313 text.append(s_tableStart);
314 text.append(tableHeaderRow(i18nc(
"A touch down event",
"Touch down")));
315 text.append(timestampRow(time));
316 text.append(tableRow(i18nc(
"The id of the touch point in the touch event",
"Point identifier"),
id));
317 text.append(tableRow(i18nc(
"The global position of the touch point",
"Global position"),
318 QStringLiteral(
"%1/%2").arg(pos.x()).arg(pos.y())));
319 text.append(s_tableEnd);
321 m_textEdit->insertHtml(text);
322 m_textEdit->ensureCursorVisible();
328 text.append(s_tableStart);
329 text.append(tableHeaderRow(i18nc(
"A touch motion event",
"Touch Motion")));
330 text.append(timestampRow(time));
331 text.append(tableRow(i18nc(
"The id of the touch point in the touch event",
"Point identifier"),
id));
332 text.append(tableRow(i18nc(
"The global position of the touch point",
"Global position"),
333 QStringLiteral(
"%1/%2").arg(pos.x()).arg(pos.y())));
334 text.append(s_tableEnd);
336 m_textEdit->insertHtml(text);
337 m_textEdit->ensureCursorVisible();
343 text.append(s_tableStart);
344 text.append(tableHeaderRow(i18nc(
"A touch up event",
"Touch Up")));
345 text.append(timestampRow(time));
346 text.append(tableRow(i18nc(
"The id of the touch point in the touch event",
"Point identifier"),
id));
347 text.append(s_tableEnd);
349 m_textEdit->insertHtml(text);
350 m_textEdit->ensureCursorVisible();
356 text.append(s_tableStart);
357 text.append(tableHeaderRow(i18nc(
"A pinch gesture is started",
"Pinch start")));
358 text.append(timestampRow(time));
359 text.append(tableRow(i18nc(
"Number of fingers in this pinch gesture",
"Finger count"), fingerCount));
360 text.append(s_tableEnd);
362 m_textEdit->insertHtml(text);
363 m_textEdit->ensureCursorVisible();
369 text.append(s_tableStart);
370 text.append(tableHeaderRow(i18nc(
"A pinch gesture is updated",
"Pinch update")));
371 text.append(timestampRow(time));
372 text.append(tableRow(i18nc(
"Current scale in pinch gesture",
"Scale"), scale));
373 text.append(tableRow(i18nc(
"Current angle in pinch gesture",
"Angle delta"), angleDelta));
374 text.append(tableRow(i18nc(
"Current delta in pinch gesture",
"Delta x"), delta.x()));
375 text.append(tableRow(i18nc(
"Current delta in pinch gesture",
"Delta y"), delta.y()));
376 text.append(s_tableEnd);
378 m_textEdit->insertHtml(text);
379 m_textEdit->ensureCursorVisible();
385 text.append(s_tableStart);
386 text.append(tableHeaderRow(i18nc(
"A pinch gesture ended",
"Pinch end")));
387 text.append(timestampRow(time));
388 text.append(s_tableEnd);
390 m_textEdit->insertHtml(text);
391 m_textEdit->ensureCursorVisible();
397 text.append(s_tableStart);
398 text.append(tableHeaderRow(i18nc(
"A pinch gesture got cancelled",
"Pinch cancelled")));
399 text.append(timestampRow(time));
400 text.append(s_tableEnd);
402 m_textEdit->insertHtml(text);
403 m_textEdit->ensureCursorVisible();
409 text.append(s_tableStart);
410 text.append(tableHeaderRow(i18nc(
"A swipe gesture is started",
"Swipe start")));
411 text.append(timestampRow(time));
412 text.append(tableRow(i18nc(
"Number of fingers in this swipe gesture",
"Finger count"), fingerCount));
413 text.append(s_tableEnd);
415 m_textEdit->insertHtml(text);
416 m_textEdit->ensureCursorVisible();
422 text.append(s_tableStart);
423 text.append(tableHeaderRow(i18nc(
"A swipe gesture is updated",
"Swipe update")));
424 text.append(timestampRow(time));
425 text.append(tableRow(i18nc(
"Current delta in swipe gesture",
"Delta x"), delta.x()));
426 text.append(tableRow(i18nc(
"Current delta in swipe gesture",
"Delta y"), delta.y()));
427 text.append(s_tableEnd);
429 m_textEdit->insertHtml(text);
430 m_textEdit->ensureCursorVisible();
436 text.append(s_tableStart);
437 text.append(tableHeaderRow(i18nc(
"A swipe gesture ended",
"Swipe end")));
438 text.append(timestampRow(time));
439 text.append(s_tableEnd);
441 m_textEdit->insertHtml(text);
442 m_textEdit->ensureCursorVisible();
448 text.append(s_tableStart);
449 text.append(tableHeaderRow(i18nc(
"A swipe gesture got cancelled",
"Swipe cancelled")));
450 text.append(timestampRow(time));
451 text.append(s_tableEnd);
453 m_textEdit->insertHtml(text);
454 m_textEdit->ensureCursorVisible();
460 text.append(s_tableStart);
461 text.append(tableHeaderRow(i18nc(
"A hardware switch (e.g. notebook lid) got toggled",
"Switch toggled")));
462 text.append(timestampRow(event->
timestamp()));
463 text.append(timestampRowUsec(event->
timestamp()));
464 text.append(deviceRow(event->
device()));
467 switchName = i18nc(
"Name of a hardware switch",
"Notebook lid");
469 switchName = i18nc(
"Name of a hardware switch",
"Tablet mode");
471 text.append(tableRow(i18nc(
"A hardware switch",
"Switch"), switchName));
473 switch (event->
state()) {
475 switchState = i18nc(
"The hardware switch got turned off",
"Off");
478 switchState = i18nc(
"The hardware switch got turned on",
"On");
483 text.append(tableRow(i18nc(
"State of a hardware switch (on/off)",
"State"), switchState));
484 text.append(s_tableEnd);
486 m_textEdit->insertHtml(text);
487 m_textEdit->ensureCursorVisible();
494 QDebug d(&typeString);
498 QString text = s_hr + s_tableStart + tableHeaderRow(i18n(
"Tablet Tool"))
499 + tableRow(i18n(
"EventType"), typeString)
500 + tableRow(i18n(
"Position"),
501 QStringLiteral(
"%1,%2").arg(event->pos().x()).arg(event->pos().y()))
502 + tableRow(i18n(
"Tilt"),
503 QStringLiteral(
"%1,%2").arg(event->xTilt()).arg(event->yTilt()))
504 + tableRow(i18n(
"Rotation"), QString::number(event->rotation()))
505 + tableRow(i18n(
"Pressure"), QString::number(event->pressure()))
506 + tableRow(i18n(
"Buttons"), QString::number(event->buttons()))
507 + tableRow(i18n(
"Modifiers"), QString::number(event->modifiers()))
510 m_textEdit->insertHtml(text);
511 m_textEdit->ensureCursorVisible();
516 QString text = s_hr + s_tableStart + tableHeaderRow(i18n(
"Tablet Tool Button"))
517 + tableRow(i18n(
"Button"), button)
518 + tableRow(i18n(
"Pressed"), pressed)
523 m_textEdit->insertHtml(text);
524 m_textEdit->ensureCursorVisible();
529 QString text = s_hr + s_tableStart
530 + tableHeaderRow(i18n(
"Tablet Pad Button"))
531 + tableRow(i18n(
"Button"), button)
532 + tableRow(i18n(
"Pressed"), pressed)
533 + tableRow(i18n(
"Tablet"),
qHash(tabletPadId.
data))
537 m_textEdit->insertHtml(text);
538 m_textEdit->ensureCursorVisible();
543 QString text = s_hr + s_tableStart + tableHeaderRow(i18n(
"Tablet Pad Strip"))
544 + tableRow(i18n(
"Number"), number)
545 + tableRow(i18n(
"Position"), position)
546 + tableRow(i18n(
"isFinger"), isFinger)
547 + tableRow(i18n(
"Tablet"),
qHash(tabletPadId.
data))
551 m_textEdit->insertHtml(text);
552 m_textEdit->ensureCursorVisible();
557 QString text = s_hr + s_tableStart + tableHeaderRow(i18n(
"Tablet Pad Ring"))
558 + tableRow(i18n(
"Number"), number)
559 + tableRow(i18n(
"Position"), position)
560 + tableRow(i18n(
"isFinger"), isFinger)
561 + tableRow(i18n(
"Tablet"),
qHash(tabletPadId.
data))
565 m_textEdit->insertHtml(text);
566 m_textEdit->ensureCursorVisible();
576 return QStringLiteral(
"XWayland source");
581 if (
auto dataSource = qobject_cast<const DataSourceInterface *const>(source)) {
582 return QStringLiteral(
"wl_data_source@%1 of %2").arg(wl_resource_get_id(dataSource->resource())).arg(executable);
583 }
else if (qobject_cast<const PrimarySelectionSourceV1Interface *const>(source)) {
584 return QStringLiteral(
"zwp_primary_selection_source_v1 of %2").arg(executable);
585 }
else if (qobject_cast<const DataControlSourceV1Interface *const>(source)) {
586 return QStringLiteral(
"data control by %1").arg(executable);
588 return QStringLiteral(
"unknown source of").arg(executable);
595 setAttribute(Qt::WA_ShowWithoutActivating);
599 QSortFilterProxyModel *proxyWindowsModel =
new QSortFilterProxyModel(
this);
600 proxyWindowsModel->setSourceModel(windowsModel);
601 m_ui->windowsView->setModel(proxyWindowsModel);
602 m_ui->windowsView->sortByColumn(0, Qt::AscendingOrder);
603 m_ui->windowsView->header()->setSortIndicatorShown(
true);
611 m_ui->quitButton->setIcon(QIcon::fromTheme(QStringLiteral(
"application-exit")));
612 m_ui->tabWidget->setTabIcon(0, QIcon::fromTheme(QStringLiteral(
"view-list-tree")));
613 m_ui->tabWidget->setTabIcon(1, QIcon::fromTheme(QStringLiteral(
"view-list-tree")));
616 m_ui->tabWidget->setTabEnabled(1,
false);
617 m_ui->tabWidget->setTabEnabled(2,
false);
618 m_ui->tabWidget->setTabEnabled(6,
false);
619 setWindowFlags(Qt::X11BypassWindowManagerHint);
622 connect(m_ui->quitButton, &QAbstractButton::clicked,
this, &DebugConsole::deleteLater);
623 connect(m_ui->tabWidget, &QTabWidget::currentChanged,
this, [
this](
int index) {
625 if (index == 2 && !m_inputFilter) {
626 m_inputFilter = std::make_unique<DebugConsoleFilter>(m_ui->inputTextEdit);
627 input()->installInputEventSpy(m_inputFilter.get());
635 m_ui->clipboardSource->setText(sourceString(
waylandServer()->seat()->selection()));
638 m_ui->clipboardSource->setText(sourceString(source));
644 m_ui->primarySource->setText(sourceString(source));
652DebugConsole::~DebugConsole() =
default;
654void DebugConsole::initGLTab()
657 m_ui->noOpenGLLabel->setVisible(
true);
658 m_ui->glInfoScrollArea->setVisible(
false);
661 GLPlatform *gl = GLPlatform::instance();
662 m_ui->noOpenGLLabel->setVisible(
false);
663 m_ui->glInfoScrollArea->setVisible(
true);
664 m_ui->glVendorStringLabel->setText(QString::fromLocal8Bit(gl->glVendorString()));
665 m_ui->glRendererStringLabel->setText(QString::fromLocal8Bit(gl->glRendererString()));
666 m_ui->glVersionStringLabel->setText(QString::fromLocal8Bit(gl->glVersionString()));
667 m_ui->glslVersionStringLabel->setText(QString::fromLocal8Bit(gl->glShadingLanguageVersionString()));
668 m_ui->glDriverLabel->setText(GLPlatform::driverToString(gl->driver()));
669 m_ui->glGPULabel->setText(GLPlatform::chipClassToString(gl->chipClass()));
670 m_ui->glVersionLabel->setText(gl->glVersion().toString());
671 m_ui->glslLabel->setText(gl->glslVersion().toString());
673 auto extensionsString = [](
const auto &extensions) {
674 QString text = QStringLiteral(
"<ul>");
675 for (
auto extension : extensions) {
676 text.append(QStringLiteral(
"<li>%1</li>").arg(QString::fromLocal8Bit(extension)));
678 text.append(QStringLiteral(
"</ul>"));
682 const OpenGLBackend *backend =
static_cast<OpenGLBackend *
>(Compositor::self()->backend());
683 m_ui->platformExtensionsLabel->setText(extensionsString(backend->extensions()));
690 QString text = QStringLiteral(
"<ul>");
691 for (T i = 0; i < count; i++) {
692 text.append(QStringLiteral(
"<li>%1</li>").arg(QString::fromLocal8Bit(f(map, i))));
694 text.append(QStringLiteral(
"</ul>"));
699QString
stateActiveComponents(xkb_state *state,
const T &count, std::function<
int(xkb_state *, T)> f, std::function<
const char *(xkb_keymap *, T)> name)
701 QString text = QStringLiteral(
"<ul>");
702 xkb_keymap *map = xkb_state_get_keymap(state);
703 for (T i = 0; i < count; i++) {
704 if (f(state, i) == 1) {
705 text.append(QStringLiteral(
"<li>%1</li>").arg(QString::fromLocal8Bit(name(map, i))));
708 text.append(QStringLiteral(
"</ul>"));
712void DebugConsole::updateKeyboardTab()
715 xkb_keymap *map = xkb->
keymap();
716 xkb_state *state = xkb->state();
717 m_ui->layoutsLabel->setText(keymapComponentToString<xkb_layout_index_t>(map, xkb_keymap_num_layouts(map), &xkb_keymap_layout_get_name));
718 m_ui->currentLayoutLabel->setText(xkb_keymap_layout_get_name(map, xkb->currentLayout()));
719 m_ui->modifiersLabel->setText(keymapComponentToString<xkb_mod_index_t>(map, xkb_keymap_num_mods(map), &xkb_keymap_mod_get_name));
720 m_ui->ledsLabel->setText(keymapComponentToString<xkb_led_index_t>(map, xkb_keymap_num_leds(map), &xkb_keymap_led_get_name));
721 m_ui->activeLedsLabel->setText(stateActiveComponents<xkb_led_index_t>(state, xkb_keymap_num_leds(map), &xkb_state_led_index_is_active, &xkb_keymap_led_get_name));
723 using namespace std::placeholders;
724 auto modActive = std::bind(xkb_state_mod_index_is_active, _1, _2, XKB_STATE_MODS_EFFECTIVE);
725 m_ui->activeModifiersLabel->setText(stateActiveComponents<xkb_mod_index_t>(state, xkb_keymap_num_mods(map), modActive, &xkb_keymap_mod_get_name));
728void DebugConsole::showEvent(QShowEvent *event)
730 QWidget::showEvent(event);
733 connect(windowHandle(), &QWindow::visibleChanged,
this, [
this](
bool visible) {
742DebugConsoleDelegate::DebugConsoleDelegate(QObject *parent)
743 : QStyledItemDelegate(parent)
751 switch (value.userType()) {
752 case QMetaType::QPoint: {
753 const QPoint p = value.toPoint();
754 return QStringLiteral(
"%1,%2").arg(p.x()).arg(p.y());
756 case QMetaType::QPointF: {
757 const QPointF p = value.toPointF();
758 return QStringLiteral(
"%1,%2").arg(p.x()).arg(p.y());
760 case QMetaType::QSize: {
761 const QSize s = value.toSize();
762 return QStringLiteral(
"%1x%2").arg(s.width()).arg(s.height());
764 case QMetaType::QSizeF: {
765 const QSizeF s = value.toSizeF();
766 return QStringLiteral(
"%1x%2").arg(s.width()).arg(s.height());
768 case QMetaType::QRect: {
769 const QRect r = value.toRect();
770 return QStringLiteral(
"%1,%2 %3x%4").arg(r.x()).arg(r.y()).arg(r.width()).arg(r.height());
772 case QMetaType::QRectF: {
773 const QRectF r = value.toRectF();
774 return QStringLiteral(
"%1,%2 %3x%4").arg(r.x()).arg(r.y()).arg(r.width()).arg(r.height());
777 if (value.userType() == qMetaTypeId<KWin::SurfaceInterface *>()) {
779 return QStringLiteral(
"KWin::SurfaceInterface(0x%1)").arg(qulonglong(s), 0, 16);
781 return QStringLiteral(
"nullptr");
784 if (value.userType() == qMetaTypeId<KWin::Window *>()) {
786 return w->caption() + QLatin1Char(
' ') + QString::fromUtf8(w->metaObject()->className());
788 return QStringLiteral(
"nullptr");
791 if (value.userType() == qMetaTypeId<Qt::MouseButtons>()) {
792 const auto buttons = value.value<Qt::MouseButtons>();
793 if (buttons == Qt::NoButton) {
794 return i18n(
"No Mouse Buttons");
797 if (buttons.testFlag(Qt::LeftButton)) {
798 list << i18nc(
"Mouse Button",
"left");
800 if (buttons.testFlag(Qt::RightButton)) {
801 list << i18nc(
"Mouse Button",
"right");
803 if (buttons.testFlag(Qt::MiddleButton)) {
804 list << i18nc(
"Mouse Button",
"middle");
806 if (buttons.testFlag(Qt::BackButton)) {
807 list << i18nc(
"Mouse Button",
"back");
809 if (buttons.testFlag(Qt::ForwardButton)) {
810 list << i18nc(
"Mouse Button",
"forward");
812 if (buttons.testFlag(Qt::ExtraButton1)) {
813 list << i18nc(
"Mouse Button",
"extra 1");
815 if (buttons.testFlag(Qt::ExtraButton2)) {
816 list << i18nc(
"Mouse Button",
"extra 2");
818 if (buttons.testFlag(Qt::ExtraButton3)) {
819 list << i18nc(
"Mouse Button",
"extra 3");
821 if (buttons.testFlag(Qt::ExtraButton4)) {
822 list << i18nc(
"Mouse Button",
"extra 4");
824 if (buttons.testFlag(Qt::ExtraButton5)) {
825 list << i18nc(
"Mouse Button",
"extra 5");
827 if (buttons.testFlag(Qt::ExtraButton6)) {
828 list << i18nc(
"Mouse Button",
"extra 6");
830 if (buttons.testFlag(Qt::ExtraButton7)) {
831 list << i18nc(
"Mouse Button",
"extra 7");
833 if (buttons.testFlag(Qt::ExtraButton8)) {
834 list << i18nc(
"Mouse Button",
"extra 8");
836 if (buttons.testFlag(Qt::ExtraButton9)) {
837 list << i18nc(
"Mouse Button",
"extra 9");
839 if (buttons.testFlag(Qt::ExtraButton10)) {
840 list << i18nc(
"Mouse Button",
"extra 10");
842 if (buttons.testFlag(Qt::ExtraButton11)) {
843 list << i18nc(
"Mouse Button",
"extra 11");
845 if (buttons.testFlag(Qt::ExtraButton12)) {
846 list << i18nc(
"Mouse Button",
"extra 12");
848 if (buttons.testFlag(Qt::ExtraButton13)) {
849 list << i18nc(
"Mouse Button",
"extra 13");
851 if (buttons.testFlag(Qt::ExtraButton14)) {
852 list << i18nc(
"Mouse Button",
"extra 14");
854 if (buttons.testFlag(Qt::ExtraButton15)) {
855 list << i18nc(
"Mouse Button",
"extra 15");
857 if (buttons.testFlag(Qt::ExtraButton16)) {
858 list << i18nc(
"Mouse Button",
"extra 16");
860 if (buttons.testFlag(Qt::ExtraButton17)) {
861 list << i18nc(
"Mouse Button",
"extra 17");
863 if (buttons.testFlag(Qt::ExtraButton18)) {
864 list << i18nc(
"Mouse Button",
"extra 18");
866 if (buttons.testFlag(Qt::ExtraButton19)) {
867 list << i18nc(
"Mouse Button",
"extra 19");
869 if (buttons.testFlag(Qt::ExtraButton20)) {
870 list << i18nc(
"Mouse Button",
"extra 20");
872 if (buttons.testFlag(Qt::ExtraButton21)) {
873 list << i18nc(
"Mouse Button",
"extra 21");
875 if (buttons.testFlag(Qt::ExtraButton22)) {
876 list << i18nc(
"Mouse Button",
"extra 22");
878 if (buttons.testFlag(Qt::ExtraButton23)) {
879 list << i18nc(
"Mouse Button",
"extra 23");
881 if (buttons.testFlag(Qt::ExtraButton24)) {
882 list << i18nc(
"Mouse Button",
"extra 24");
884 if (buttons.testFlag(Qt::TaskButton)) {
885 list << i18nc(
"Mouse Button",
"task");
887 return list.join(QStringLiteral(
", "));
891 return QStyledItemDelegate::displayText(value, locale);
894static const int s_x11WindowId = 1;
895static const int s_x11UnmanagedId = 2;
896static const int s_waylandWindowId = 3;
897static const int s_workspaceInternalId = 4;
898static const quint32 s_propertyBitMask = 0xFFFF0000;
899static const quint32 s_windowBitMask = 0x0000FFFF;
900static const quint32 s_idDistance = 10000;
903void DebugConsoleModel::add(
int parentRow, QList<T *> &windows, T *window)
905 beginInsertRows(
index(parentRow, 0, QModelIndex()), windows.count(), windows.count());
906 windows.append(window);
911void DebugConsoleModel::remove(
int parentRow, QList<T *> &windows, T *window)
913 const int remove = windows.indexOf(window);
917 beginRemoveRows(
index(parentRow, 0, QModelIndex()), remove, remove);
918 windows.removeAt(remove);
923 : QAbstractItemModel(parent)
926 for (
auto window : windows) {
927 handleWindowAdded(window);
933void DebugConsoleModel::handleWindowAdded(
Window *window)
935 if (
auto x11 = qobject_cast<X11Window *>(window)) {
936 if (x11->isUnmanaged()) {
937 add(s_x11UnmanagedId - 1, m_unmanageds, x11);
939 add(s_x11WindowId - 1, m_x11Windows, x11);
944 if (
auto wayland = qobject_cast<WaylandWindow *>(window)) {
945 add(s_waylandWindowId - 1, m_waylandWindows, wayland);
949 if (
auto internal = qobject_cast<InternalWindow *>(window)) {
950 add(s_workspaceInternalId - 1, m_internalWindows, internal);
955void DebugConsoleModel::handleWindowRemoved(
Window *window)
957 if (
auto x11 = qobject_cast<X11Window *>(window)) {
958 if (x11->isUnmanaged()) {
959 remove(s_x11UnmanagedId - 1, m_unmanageds, x11);
961 remove(s_x11WindowId - 1, m_x11Windows, x11);
966 if (
auto wayland = qobject_cast<WaylandWindow *>(window)) {
967 remove(s_waylandWindowId - 1, m_waylandWindows, wayland);
971 if (
auto internal = qobject_cast<InternalWindow *>(window)) {
972 remove(s_workspaceInternalId - 1, m_internalWindows, internal);
984int DebugConsoleModel::topLevelRowCount()
const
986 return kwinApp()->shouldUseWaylandForCompositing() ? 4 : 2;
990int DebugConsoleModel::propertyCount(
const QModelIndex &parent, T *(DebugConsoleModel::*filter)(const QModelIndex &) const) const
992 if (T *t = (this->*filter)(
parent)) {
993 return t->metaObject()->propertyCount();
1001 return topLevelRowCount();
1004 switch (
parent.internalId()) {
1006 return m_x11Windows.count();
1007 case s_x11UnmanagedId:
1008 return m_unmanageds.count();
1009 case s_waylandWindowId:
1010 return m_waylandWindows.count();
1011 case s_workspaceInternalId:
1012 return m_internalWindows.count();
1017 if (
parent.internalId() & s_propertyBitMask) {
1022 if (
parent.internalId() < s_idDistance * (s_x11WindowId + 1)) {
1023 return propertyCount(
parent, &DebugConsoleModel::x11Window);
1024 }
else if (
parent.internalId() < s_idDistance * (s_x11UnmanagedId + 1)) {
1025 return propertyCount(
parent, &DebugConsoleModel::unmanaged);
1026 }
else if (
parent.internalId() < s_idDistance * (s_waylandWindowId + 1)) {
1027 return propertyCount(
parent, &DebugConsoleModel::waylandWindow);
1028 }
else if (
parent.internalId() < s_idDistance * (s_workspaceInternalId + 1)) {
1029 return propertyCount(
parent, &DebugConsoleModel::internalWindow);
1036QModelIndex DebugConsoleModel::indexForWindow(
int row,
int column,
const QList<T *> &windows,
int id)
const
1039 return QModelIndex();
1041 if (row >= windows.count()) {
1042 return QModelIndex();
1044 return createIndex(row, column, s_idDistance *
id + row);
1048QModelIndex DebugConsoleModel::indexForProperty(
int row,
int column,
const QModelIndex &parent, T *(DebugConsoleModel::*filter)(const QModelIndex &) const) const
1050 if (T *t = (this->*filter)(
parent)) {
1051 if (row >= t->metaObject()->propertyCount()) {
1052 return QModelIndex();
1054 return createIndex(row, column, quint32(row + 1) << 16 |
parent.internalId());
1056 return QModelIndex();
1063 if (column != 0 || row >= topLevelRowCount()) {
1064 return QModelIndex();
1066 return createIndex(row, column, row + 1);
1070 return QModelIndex();
1073 switch (
parent.internalId()) {
1075 return indexForWindow(row, column, m_x11Windows, s_x11WindowId);
1076 case s_x11UnmanagedId:
1077 return indexForWindow(row, column, m_unmanageds, s_x11UnmanagedId);
1078 case s_waylandWindowId:
1079 return indexForWindow(row, column, m_waylandWindows, s_waylandWindowId);
1080 case s_workspaceInternalId:
1081 return indexForWindow(row, column, m_internalWindows, s_workspaceInternalId);
1087 if (
parent.internalId() < s_idDistance * (s_x11WindowId + 1)) {
1088 return indexForProperty(row, column,
parent, &DebugConsoleModel::x11Window);
1089 }
else if (
parent.internalId() < s_idDistance * (s_x11UnmanagedId + 1)) {
1090 return indexForProperty(row, column,
parent, &DebugConsoleModel::unmanaged);
1091 }
else if (
parent.internalId() < s_idDistance * (s_waylandWindowId + 1)) {
1092 return indexForProperty(row, column,
parent, &DebugConsoleModel::waylandWindow);
1093 }
else if (
parent.internalId() < s_idDistance * (s_workspaceInternalId + 1)) {
1094 return indexForProperty(row, column,
parent, &DebugConsoleModel::internalWindow);
1097 return QModelIndex();
1102 if (child.internalId() <= s_workspaceInternalId) {
1103 return QModelIndex();
1105 if (child.internalId() & s_propertyBitMask) {
1107 const quint32 parentId = child.internalId() & s_windowBitMask;
1108 if (parentId < s_idDistance * (s_x11WindowId + 1)) {
1109 return createIndex(parentId - (s_idDistance * s_x11WindowId), 0, parentId);
1110 }
else if (parentId < s_idDistance * (s_x11UnmanagedId + 1)) {
1111 return createIndex(parentId - (s_idDistance * s_x11UnmanagedId), 0, parentId);
1112 }
else if (parentId < s_idDistance * (s_waylandWindowId + 1)) {
1113 return createIndex(parentId - (s_idDistance * s_waylandWindowId), 0, parentId);
1114 }
else if (parentId < s_idDistance * (s_workspaceInternalId + 1)) {
1115 return createIndex(parentId - (s_idDistance * s_workspaceInternalId), 0, parentId);
1117 return QModelIndex();
1119 if (child.internalId() < s_idDistance * (s_x11WindowId + 1)) {
1120 return createIndex(s_x11WindowId - 1, 0, s_x11WindowId);
1121 }
else if (child.internalId() < s_idDistance * (s_x11UnmanagedId + 1)) {
1122 return createIndex(s_x11UnmanagedId - 1, 0, s_x11UnmanagedId);
1123 }
else if (child.internalId() < s_idDistance * (s_waylandWindowId + 1)) {
1124 return createIndex(s_waylandWindowId - 1, 0, s_waylandWindowId);
1125 }
else if (child.internalId() < s_idDistance * (s_workspaceInternalId + 1)) {
1126 return createIndex(s_workspaceInternalId - 1, 0, s_workspaceInternalId);
1128 return QModelIndex();
1131QVariant DebugConsoleModel::propertyData(QObject *
object,
const QModelIndex &index,
int role)
const
1133 const auto property =
object->metaObject()->property(
index.row());
1134 if (
index.column() == 0) {
1135 return property.name();
1137 const QVariant value =
property.read(
object);
1138 if (qstrcmp(property.name(),
"windowType") == 0) {
1139 switch (value.toInt()) {
1141 return QStringLiteral(
"NET::Normal");
1143 return QStringLiteral(
"NET::Desktop");
1145 return QStringLiteral(
"NET::Dock");
1147 return QStringLiteral(
"NET::Toolbar");
1149 return QStringLiteral(
"NET::Menu");
1151 return QStringLiteral(
"NET::Dialog");
1153 return QStringLiteral(
"NET::Override");
1155 return QStringLiteral(
"NET::TopMenu");
1157 return QStringLiteral(
"NET::Utility");
1159 return QStringLiteral(
"NET::Splash");
1160 case NET::DropdownMenu:
1161 return QStringLiteral(
"NET::DropdownMenu");
1162 case NET::PopupMenu:
1163 return QStringLiteral(
"NET::PopupMenu");
1165 return QStringLiteral(
"NET::Tooltip");
1166 case NET::Notification:
1167 return QStringLiteral(
"NET::Notification");
1169 return QStringLiteral(
"NET::ComboBox");
1171 return QStringLiteral(
"NET::DNDIcon");
1172 case NET::OnScreenDisplay:
1173 return QStringLiteral(
"NET::OnScreenDisplay");
1174 case NET::CriticalNotification:
1175 return QStringLiteral(
"NET::CriticalNotification");
1176 case NET::AppletPopup:
1177 return QStringLiteral(
"NET::AppletPopup");
1180 return QStringLiteral(
"NET::Unknown");
1182 }
else if (qstrcmp(property.name(),
"layer") == 0) {
1183 return QMetaEnum::fromType<Layer>().valueToKey(value.value<
Layer>());
1191QVariant DebugConsoleModel::windowData(
const QModelIndex &index,
int role,
const QList<T *> windows,
const std::function<QString(T *)> &toString)
const
1193 if (
index.row() >= windows.count()) {
1196 auto c = windows.at(
index.row());
1197 if (role == Qt::DisplayRole) {
1199 }
else if (role == Qt::DecorationRole) {
1207 if (!
index.isValid()) {
1210 if (!
index.parent().isValid()) {
1212 if (
index.column() != 0 || role != Qt::DisplayRole) {
1215 switch (
index.internalId()) {
1217 return i18n(
"X11 Windows");
1218 case s_x11UnmanagedId:
1219 return i18n(
"X11 Unmanaged Windows");
1220 case s_waylandWindowId:
1221 return i18n(
"Wayland Windows");
1222 case s_workspaceInternalId:
1223 return i18n(
"Internal Windows");
1228 if (
index.internalId() & s_propertyBitMask) {
1229 if (
index.column() >= 2 || role != Qt::DisplayRole) {
1233 return propertyData(w,
index, role);
1235 return propertyData(w,
index, role);
1237 return propertyData(w,
index, role);
1239 return propertyData(u,
index, role);
1242 if (
index.column() != 0) {
1246 auto generic = [](
Window *c) -> QString {
1247 return c->caption() + QLatin1Char(
' ') + QString::fromUtf8(c->metaObject()->className());
1249 switch (
index.parent().internalId()) {
1251 return windowData<X11Window>(
index, role, m_x11Windows, [](
X11Window *c) -> QString {
1252 return QStringLiteral(
"0x%1: %2").arg(c->
window(), 0, 16).arg(c->
caption());
1254 case s_x11UnmanagedId: {
1255 if (
index.row() >= m_unmanageds.count()) {
1258 auto u = m_unmanageds.at(
index.row());
1259 if (role == Qt::DisplayRole) {
1260 return QStringLiteral(
"0x%1").arg(u->window(), 0, 16);
1264 case s_waylandWindowId:
1265 return windowData<WaylandWindow>(
index, role, m_waylandWindows, generic);
1266 case s_workspaceInternalId:
1267 return windowData<InternalWindow>(
index, role, m_internalWindows, generic);
1277static T *windowForIndex(
const QModelIndex &index,
const QList<T *> &windows,
int id)
1279 const qint32 row = (index.internalId() & s_windowBitMask) - (s_idDistance *
id);
1280 if (row < 0 || row >= windows.count()) {
1283 return windows.at(row);
1286WaylandWindow *DebugConsoleModel::waylandWindow(
const QModelIndex &index)
const
1288 return windowForIndex(
index, m_waylandWindows, s_waylandWindowId);
1291InternalWindow *DebugConsoleModel::internalWindow(
const QModelIndex &index)
const
1293 return windowForIndex(
index, m_internalWindows, s_workspaceInternalId);
1296X11Window *DebugConsoleModel::x11Window(
const QModelIndex &index)
const
1298 return windowForIndex(
index, m_x11Windows, s_x11WindowId);
1301X11Window *DebugConsoleModel::unmanaged(
const QModelIndex &index)
const
1303 return windowForIndex(
index, m_unmanageds, s_x11UnmanagedId);
1308 : QAbstractItemModel(parent)
1311 auto reset = [
this] {
1316 auto watchSubsurfaces = [
this, reset](
Window *c) {
1317 if (!c->surface()) {
1323 connect(c, &QObject::destroyed, monitor, &QObject::deleteLater);
1327 watchSubsurfaces(c);
1330 watchSubsurfaces(c);
1347 return surface->below().count() + surface->above().count();
1359 return QModelIndex();
1365 const auto &below = surface->below();
1366 if (row < reference + below.count()) {
1367 return createIndex(row, column, below.at(row - reference)->surface());
1369 reference += below.count();
1371 const auto &above = surface->above();
1372 if (row < reference + above.count()) {
1373 return createIndex(row, column, above.at(row - reference)->surface());
1376 return QModelIndex();
1380 if (row < allClients.count()) {
1382 return createIndex(row, column, allClients.at(row)->surface());
1385 return QModelIndex();
1391 const auto &subsurface = surface->subSurface();
1394 return QModelIndex();
1399 return QModelIndex();
1402 if (
parent->subSurface()) {
1403 auto grandParent =
parent->subSurface()->parentSurface();
1406 return QModelIndex();
1409 const auto &below = grandParent->below();
1410 for (
int i = 0; i < below.count(); i++) {
1411 if (below.at(i) ==
parent->subSurface()) {
1412 return createIndex(row + i, 0,
parent);
1415 row += below.count();
1416 const auto &above = grandParent->above();
1417 for (
int i = 0; i < above.count(); i++) {
1418 if (above.at(i) ==
parent->subSurface()) {
1419 return createIndex(row + i, 0,
parent);
1422 return QModelIndex();
1426 for (
int row = 0; row < allClients.count(); row++) {
1427 if (allClients.at(row)->surface() ==
parent) {
1428 return createIndex(row, 0,
parent);
1432 return QModelIndex();
1437 if (!
index.isValid()) {
1441 if (role == Qt::DisplayRole || role == Qt::ToolTipRole) {
1442 return QStringLiteral(
"%1 (%2) - %3").arg(surface->client()->executablePath()).arg(surface->client()->processId()).arg(surface->id());
1443 }
else if (role == Qt::DecorationRole) {
1444 if (surface->buffer()) {
1446 if (
const QImage *image = view.
image()) {
1447 return image->scaled(QSize(64, 64), Qt::KeepAspectRatio);
1457 : QAbstractItemModel(parent)
1458 , m_devices(
input()->devices())
1460 for (
auto it = m_devices.constBegin(); it != m_devices.constEnd(); ++it) {
1461 setupDeviceConnections(*it);
1465 beginInsertRows(QModelIndex(), m_devices.count(), m_devices.count());
1467 setupDeviceConnections(d);
1471 const int index = m_devices.indexOf(d);
1475 beginRemoveRows(QModelIndex(),
index,
index);
1476 m_devices.removeAt(
index);
1490 if (!
index.isValid()) {
1493 if (!
index.parent().isValid() &&
index.column() == 0) {
1494 if (
index.row() >= m_devices.count()) {
1497 if (role == Qt::DisplayRole) {
1498 return m_devices.at(
index.row())->name();
1501 if (
index.parent().isValid()) {
1502 if (role == Qt::DisplayRole) {
1503 const auto device = m_devices.at(
index.parent().row());
1504 const auto property = device->metaObject()->property(
index.row());
1505 if (
index.column() == 0) {
1506 return property.name();
1507 }
else if (
index.column() == 1) {
1508 return device->property(property.name());
1518 return QModelIndex();
1521 if (
parent.internalId() & s_propertyBitMask) {
1522 return QModelIndex();
1524 if (row >= m_devices.at(
parent.row())->metaObject()->propertyCount()) {
1525 return QModelIndex();
1527 return createIndex(row, column, quint32(row + 1) << 16 |
parent.internalId());
1529 if (row >= m_devices.count()) {
1530 return QModelIndex();
1532 return createIndex(row, column, row + 1);
1538 return m_devices.count();
1540 if (
parent.internalId() & s_propertyBitMask) {
1544 return m_devices.at(
parent.row())->metaObject()->propertyCount();
1549 if (child.internalId() & s_propertyBitMask) {
1550 const quintptr parentId = child.internalId() & s_windowBitMask;
1551 return createIndex(parentId - 1, 0, parentId);
1553 return QModelIndex();
1556void InputDeviceModel::slotPropertyChanged()
1558 const auto device =
static_cast<InputDevice *
>(sender());
1560 for (
int i = 0; i < device->metaObject()->propertyCount(); ++i) {
1561 const QMetaProperty metaProperty = device->metaObject()->property(i);
1562 if (metaProperty.notifySignalIndex() == senderSignalIndex()) {
1563 const QModelIndex
parent =
index(m_devices.indexOf(device), 0, QModelIndex());
1565 Q_EMIT dataChanged(child, child, QList<int>{Qt::DisplayRole});
1570void InputDeviceModel::setupDeviceConnections(
InputDevice *device)
1572 QMetaMethod handler = metaObject()->method(metaObject()->indexOfMethod(
"slotPropertyChanged()"));
1573 for (
int i = 0; i < device->metaObject()->propertyCount(); ++i) {
1574 const QMetaProperty metaProperty = device->metaObject()->property(i);
1575 if (metaProperty.hasNotifySignal()) {
1576 connect(device, metaProperty.notifySignal(),
this, handler);
1583 if (!m_source ||
parent.isValid() || column >= 2 || row >= m_source->
mimeTypes().size()) {
1584 return QModelIndex();
1586 return createIndex(row, column,
nullptr);
1591 return QModelIndex();
1597 return m_source ? m_source->
mimeTypes().count() : 0;
1604 if (role != Qt::DisplayRole || orientation != Qt::Horizontal || section >= 2) {
1607 return section == 0 ? QStringLiteral(
"Mime type") : QStringLiteral(
"Content");
1612 if (!checkIndex(
index, CheckIndexOption::ParentIsInvalid | CheckIndexOption::IndexIsValid)) {
1617 if (
index.column() == 0 && role == Qt::DisplayRole) {
1619 }
else if (
index.column() == 1 &&
index.row() < m_data.count()) {
1620 const QByteArray &
data = m_data.at(
index.row());
1621 if (mimeType.contains(QLatin1String(
"image"))) {
1622 if (role == Qt::DecorationRole) {
1623 return QImage::fromData(
data);
1625 }
else if (role == Qt::DisplayRole) {
1632static QByteArray readData(
int fd)
1636 pfd.events = POLLIN;
1640 const int ready = poll(&pfd, 1, 1000);
1642 if (errno != EINTR) {
1643 return QByteArrayLiteral(
"poll() failed: ") + strerror(errno);
1645 }
else if (ready == 0) {
1646 return QByteArrayLiteral(
"timeout reading from pipe");
1649 int n = read(fd, buf,
sizeof buf);
1652 return QByteArrayLiteral(
"read failed: ") + strerror(errno);
1653 }
else if (n == 0) {
1656 data.append(buf, n);
1668 const QStringList mimeTypes = m_source->
mimeTypes();
1669 m_data.resize(mimeTypes.size());
1670 for (
auto type = mimeTypes.begin();
type != mimeTypes.end(); ++
type) {
1672 if (pipe2(pipeFds, O_CLOEXEC) != 0) {
1676 QFuture<QByteArray>
data = QtConcurrent::run(readData, pipeFds[0]);
1678 watcher->setFuture(
data);
1679 const int index =
type - mimeTypes.begin();
1681 watcher->deleteLater();
1682 if (source && source == m_source) {
1683 m_data[
index] = watcher->result();
1684 Q_EMIT dataChanged(this->
index(index, 1), this->
index(index, 1), {Qt::DecorationRole | Qt::DisplayRole});
1693#include "moc_debug_console.cpp"
The AbstractDataSource class abstracts the data that can be transferred to another client.
virtual QStringList mimeTypes() const =0
virtual wl_client * client() const
virtual void requestData(const QString &mimeType, qint32 fd)=0
@ OperationModeX11
KWin uses only X11 for managing windows and compositing.
QString executablePath() const
QModelIndex parent(const QModelIndex &child) const override
int rowCount(const QModelIndex &parent) const override
QVariant data(const QModelIndex &index, int role) const override
void setSource(AbstractDataSource *source)
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
QString displayText(const QVariant &value, const QLocale &locale) const override
~DebugConsoleDelegate() override
void tabletToolEvent(TabletEvent *event) override
void touchMotion(qint32 id, const QPointF &pos, std::chrono::microseconds time) override
void swipeGestureEnd(std::chrono::microseconds time) override
void switchEvent(SwitchEvent *event) override
void touchUp(qint32 id, std::chrono::microseconds time) override
void pinchGestureCancelled(std::chrono::microseconds time) override
void keyEvent(KeyEvent *event) override
DebugConsoleFilter(QTextEdit *textEdit)
void swipeGestureBegin(int fingerCount, std::chrono::microseconds time) override
void touchDown(qint32 id, const QPointF &pos, std::chrono::microseconds time) override
void tabletPadStripEvent(int number, int position, bool isFinger, const TabletPadId &tabletPadId, std::chrono::microseconds time) override
void tabletPadRingEvent(int number, int position, bool isFinger, const TabletPadId &tabletPadId, std::chrono::microseconds time) override
void tabletToolButtonEvent(uint button, bool pressed, const TabletToolId &tabletToolId, std::chrono::microseconds time) override
void tabletPadButtonEvent(uint button, bool pressed, const TabletPadId &tabletPadId, std::chrono::microseconds time) override
void pinchGestureUpdate(qreal scale, qreal angleDelta, const QPointF &delta, std::chrono::microseconds time) override
void swipeGestureCancelled(std::chrono::microseconds time) override
void wheelEvent(WheelEvent *event) override
void pinchGestureBegin(int fingerCount, std::chrono::microseconds time) override
~DebugConsoleFilter() override
void swipeGestureUpdate(const QPointF &delta, std::chrono::microseconds time) override
void pinchGestureEnd(std::chrono::microseconds time) override
void pointerEvent(MouseEvent *event) override
DebugConsoleModel(QObject *parent=nullptr)
QModelIndex index(int row, int column, const QModelIndex &parent) const override
~DebugConsoleModel() override
QModelIndex parent(const QModelIndex &child) const override
int rowCount(const QModelIndex &parent) const override
QVariant data(const QModelIndex &index, int role) const override
int columnCount(const QModelIndex &parent) const override
ClientConnection * getConnection(wl_client *client)
bool isOpenGLCompositing() const
Whether the Compositor is OpenGL based (either GL 1 or 2).
InputDevice * device() const
std::chrono::microseconds timestamp() const
QPointF deltaUnaccelerated() const
quint32 nativeButton() const
InputDevice * device() const
std::chrono::microseconds timestamp() const
void selectionChanged(KWin::AbstractDataSource *)
void primarySelectionChanged(KWin::AbstractDataSource *)
AbstractDataSource * selection() const
AbstractDataSource * primarySelection() const
Resource representing a wl_surface.
SurfaceTreeModel(QObject *parent=nullptr)
~SurfaceTreeModel() override
int rowCount(const QModelIndex &parent) const override
int columnCount(const QModelIndex &parent) const override
QModelIndex parent(const QModelIndex &child) const override
QModelIndex index(int row, int column, const QModelIndex &parent) const override
QVariant data(const QModelIndex &index, int role) const override
std::chrono::microseconds timestamp() const
InputDevice * device() const
SeatInterface * seat() const
Display * display() const
InputDevice * device() const
std::chrono::microseconds timestamp() const
void windowRemoved(KWin::Window *)
void windowAdded(KWin::Window *)
const QList< Window * > windows() const
xcb_window_t window() const
xkb_keymap * keymap() const
QString keymapComponentToString(xkb_keymap *map, const T &count, std::function< const char *(xkb_keymap *, T)> f)
QList< QByteArray > openGLExtensions()
WaylandServer * waylandServer()
InputRedirection * input()
QString stateActiveComponents(xkb_state *state, const T &count, std::function< int(xkb_state *, T)> f, std::function< const char *(xkb_keymap *, T)> name)