GCC Code Coverage Report


Directory: ./
File: backends/wayland/waylandbackend.cpp
Date: 2023-04-20 22:59:23
Exec Total Coverage
Lines: 53 85 62.4%
Branches: 11 40 27.5%

Line Branch Exec Source
1 /*************************************************************************************
2 * Copyright (C) 2012 by Alejandro Fiestas Olivares <afiestas@kde.org> *
3 * Copyright (C) 2012, 2013 by Daniel Vrátil <dvratil@redhat.com> *
4 * Copyright 2014-2015 Sebastian Kügler <sebas@kde.org> *
5 * *
6 * This library is free software; you can redistribute it and/or *
7 * modify it under the terms of the GNU Lesser General Public *
8 * License as published by the Free Software Foundation; either *
9 * version 2.1 of the License, or (at your option) any later version. *
10 * *
11 * This library is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14 * Lesser General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU Lesser General Public *
17 * License along with this library; if not, write to the Free Software *
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
19 *************************************************************************************/
20 #include "waylandbackend.h"
21
22 #include "wayland_interface.h"
23 #include "waylandoutput.h"
24 #include "waylandscreen.h"
25
26 #include "tabletmodemanager_interface.h"
27 #include "wayland_logging.h"
28
29 #include <config.h>
30 #include <configmonitor.h>
31 #include <generator.h>
32 #include <mode.h>
33
34 #include <QThread>
35
36 using namespace Disman;
37
38 21 WaylandBackend::WaylandBackend()
39 : Disman::BackendImpl()
40 21 , m_screen{new WaylandScreen}
41 {
42
2/2
✓ Branch 7 taken 21 times.
✓ Branch 8 taken 21 times.
42 qCDebug(DISMAN_WAYLAND) << "Loading Wayland backend.";
43 21 initKWinTabletMode();
44 21 queryInterface();
45 21 }
46
47 84 WaylandBackend::~WaylandBackend()
48 {
49
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
42 if (m_thread) {
50 42 m_thread->quit();
51 42 m_thread->wait();
52 }
53 84 }
54
55 21 void WaylandBackend::initKWinTabletMode()
56 {
57 42 auto* interface = new OrgKdeKWinTabletModeManagerInterface(QStringLiteral("org.kde.KWin"),
58 42 QStringLiteral("/org/kde/KWin"),
59 21 QDBusConnection::sessionBus(),
60 42 this);
61
1/2
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
21 if (!interface->isValid()) {
62 21 return;
63 }
64
65 tablet_mode.supported = true;
66 tablet_mode.available = interface->tabletModeAvailable();
67 tablet_mode.engaged = interface->tabletMode();
68
69 connect(interface,
70 &OrgKdeKWinTabletModeManagerInterface::tabletModeChanged,
71 this,
72 [this](bool tabletMode) {
73 if (tablet_mode.engaged == tabletMode) {
74 return;
75 }
76 tablet_mode.engaged = tabletMode;
77 if (m_interface && m_interface->is_initialized) {
78 Q_EMIT config_changed(config());
79 }
80 });
81 connect(interface,
82 &OrgKdeKWinTabletModeManagerInterface::tabletModeAvailableChanged,
83 this,
84 [this](bool available) {
85 if (tablet_mode.available == available) {
86 return;
87 }
88 tablet_mode.available = available;
89 if (m_interface && m_interface->is_initialized) {
90 Q_EMIT config_changed(config());
91 }
92 });
93 }
94
95 43 QString WaylandBackend::name() const
96 {
97 43 return QStringLiteral("wayland");
98 }
99
100 QString WaylandBackend::service_name() const
101 {
102 return QStringLiteral("org.kwinft.disman.backend.wayland");
103 }
104
105 280 void WaylandBackend::update_config(ConfigPtr& config) const
106 {
107 // TODO: do this setScreen call less clunky
108 280 config->setScreen(m_screen->toDismanScreen(config));
109
110 280 m_interface->updateConfig(config);
111
112
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 280 times.
280 if (tablet_mode.supported) {
113 config->set_supported_features(config->supported_features() | Config::Feature::AutoRotation
114 | Config::Feature::TabletMode);
115 config->set_tablet_mode_available(tablet_mode.available);
116 config->set_tablet_mode_engaged(tablet_mode.engaged);
117 }
118
119 280 ScreenPtr screen = config->screen();
120 280 m_screen->updateDismanScreen(screen);
121 280 }
122
123 35 bool WaylandBackend::set_config_system(Disman::ConfigPtr const& config)
124 {
125 35 return m_interface->applyConfig(config);
126 }
127
128 44 std::map<int, WaylandOutput*> WaylandBackend::outputMap() const
129 {
130 44 return m_interface->outputMap();
131 }
132
133 21 bool WaylandBackend::valid() const
134 {
135
2/4
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 21 times.
✗ Branch 5 not taken.
21 return m_interface && m_interface->is_initialized;
136 }
137
138 44 void WaylandBackend::setScreenOutputs()
139 {
140 44 std::vector<WaylandOutput*> outputs;
141
2/2
✓ Branch 8 taken 57 times.
✓ Branch 9 taken 44 times.
101 for (auto const& [key, out] : outputMap()) {
142 57 outputs.push_back(out);
143 44 }
144 44 m_screen->setOutputs(outputs);
145 44 }
146
147 21 void WaylandBackend::queryInterface()
148 {
149 21 QTimer::singleShot(3000, this, [this] {
150 if (m_syncLoop.isRunning()) {
151 qCWarning(DISMAN_WAYLAND) << "Connection to Wayland server timed out. Does the "
152 "compositor support output management?";
153 m_syncLoop.quit();
154 }
155 });
156
157 21 m_thread = new QThread;
158 21 m_interface = std::make_unique<WaylandInterface>(m_thread);
159 21 connect(m_interface.get(), &WaylandInterface::connectionFailed, this, [this] {
160 qCWarning(DISMAN_WAYLAND) << "Backend connection failed.";
161 if (m_syncLoop.isRunning()) {
162 m_syncLoop.quit();
163 }
164 });
165
166 21 connect(m_interface.get(), &WaylandInterface::config_changed, this, [this] {
167
2/2
✓ Branch 1 taken 33 times.
✓ Branch 2 taken 20 times.
53 if (handle_config_change()) {
168 // When windowing system and us have been synced up quit the sync loop.
169 // That returns the current config.
170 33 m_syncLoop.quit();
171 }
172 53 });
173
174 21 setScreenOutputs();
175 21 connect(m_interface.get(),
176 &WaylandInterface::outputsChanged,
177 this,
178 &WaylandBackend::setScreenOutputs);
179
180 21 m_syncLoop.exec();
181 21 }
182