qi3pc 0.3.1 (Debug GNU 15.1.1)


Directory: ./
File: qi3pc.cpp
Date: 2025-06-23 04:52:02
Exec Total Coverage
Lines: 191 394 48.5%
Functions: 38 59 64.4%
Branches: 111 611 18.2%

Line Branch Exec Source
1 #include <QDebug>
2
3 #include "qi3pc.h"
4
5 Q_LOGGING_CATEGORY(Qi3pcLogger, "qi3pc", QtMsgType::QtDebugMsg)
6
7 qi3pc::qi3pc(QObject* parent)
8 : qi3pc(socketPath(), parent)
9 {}
10
11 1 qi3pc::qi3pc(const QString& serverPath, QObject* parent)
12
2/4
✓ Branch 0 (4→5) taken 1 times.
✗ Branch 1 (4→67) not taken.
✓ Branch 2 (5→6) taken 1 times.
✗ Branch 3 (5→65) not taken.
1 : QObject(parent)
13 {
14 1 m_socketPath = serverPath;
15
16
1/2
✓ Branch 0 (17→18) taken 1 times.
✗ Branch 1 (17→37) not taken.
1 m_barConfigs = std::make_pair(QJsonObject(), QDateTime::currentMSecsSinceEpoch());
17
1/2
✗ Branch 0 (23→24) not taken.
✓ Branch 1 (23→32) taken 1 times.
1 if (m_socketPath.isEmpty()) {
18 qCFatal(Qi3pcLogger, "The provided socket path can not be empty.");
19 }
20
21 1 QObject::connect(
22
1/2
✓ Branch 0 (32→33) taken 1 times.
✗ Branch 1 (32→41) not taken.
1 &m_eventSocket, &QLocalSocket::readyRead, this, &qi3pc::processEvent);
23 1 QObject::connect(
24
1/2
✓ Branch 0 (34→35) taken 1 times.
✗ Branch 1 (34→43) not taken.
1 &m_messageSocket, &QLocalSocket::readyRead, this, &qi3pc::processReply);
25 1 }
26
27 2 qi3pc::~qi3pc()
28 {
29 1 m_eventSocket.close();
30 1 m_messageSocket.close();
31
32 1 m_eventSocket.abort();
33 1 m_messageSocket.abort();
34 2 }
35
36 void
37 qi3pc::processEvent()
38 {
39 Message m = processMessage(m_eventSocket);
40 if (!m) {
41 return;
42 }
43
44 auto [data, type] = m.value();
45
46 if (type & (1u << 31)) {
47 switch (static_cast<IpcEvent>(type)) {
48 case IpcEvent::Workspace:
49 processWorkspaceEvent(data);
50 break;
51 case IpcEvent::Output:
52 processOutputEvent(data);
53 break;
54 case IpcEvent::Mode:
55 processModeEvent(data);
56 break;
57 case IpcEvent::Window:
58 processWindowEvent(data);
59 break;
60 case IpcEvent::BarUpdate:
61 processBarUpdateEvent(data);
62 break;
63 case IpcEvent::Binding:
64 processBindingEvent(data);
65 break;
66 case IpcEvent::Shutdown:
67 processShutdownEvent(data);
68 break;
69 case IpcEvent::Tick:
70 processTickEvent(data);
71 break;
72 }
73 } else {
74 switch (static_cast<IpcType>(type)) {
75 case IpcType::Subscribe:
76 emit subscribed(data["success"].toBool());
77 break;
78 default:
79 std::string log = "Received message IpcType::%u while expecting IpcEvent or IpcType::Subscribe (IpcType::%u)";
80 qCWarning(Qi3pcLogger, log.c_str(), type, IpcType::Subscribe);
81 break;
82 }
83 }
84 }
85
86 void
87 10 qi3pc::processReply()
88 {
89
1/2
✓ Branch 0 (2→3) taken 10 times.
✗ Branch 1 (2→85) not taken.
10 Message m = processMessage(m_messageSocket);
90
1/2
✗ Branch 0 (4→5) not taken.
✓ Branch 1 (4→6) taken 10 times.
10 if (!m) {
91 return;
92 }
93
94
2/4
✓ Branch 0 (6→7) taken 10 times.
✗ Branch 1 (6→77) not taken.
✓ Branch 2 (7→8) taken 10 times.
✗ Branch 3 (7→77) not taken.
10 auto [data, type] = m.value();
95
96 10 std::string log;
97
9/14
✗ Branch 0 (11→12) not taken.
✓ Branch 1 (11→14) taken 1 times.
✗ Branch 2 (11→16) not taken.
✓ Branch 3 (11→27) taken 1 times.
✓ Branch 4 (11→29) taken 1 times.
✓ Branch 5 (11→31) taken 1 times.
✓ Branch 6 (11→33) taken 2 times.
✓ Branch 7 (11→35) taken 1 times.
✓ Branch 8 (11→37) taken 1 times.
✓ Branch 9 (11→39) taken 1 times.
✗ Branch 10 (11→41) not taken.
✗ Branch 11 (11→43) not taken.
✓ Branch 12 (11→45) taken 1 times.
✗ Branch 13 (11→47) not taken.
10 switch (static_cast<IpcType>(type)) {
98 case IpcType::Command:
99 processCommandReply(data);
100 break;
101 1 case IpcType::Workspaces:
102
1/2
✓ Branch 0 (14→15) taken 1 times.
✗ Branch 1 (14→75) not taken.
1 processWorkspaceReply(data);
103 1 break;
104 case IpcType::Subscribe:
105 log = "Received reply of type IpcType::Subscribe (IpcType::%u): unexpected.";
106 qCWarning(Qi3pcLogger, log.c_str(), IpcType::Subscribe);
107 break;
108 1 case IpcType::Outputs:
109
1/2
✓ Branch 0 (27→28) taken 1 times.
✗ Branch 1 (27→75) not taken.
1 processOutputReply(data);
110 1 break;
111 1 case IpcType::Tree:
112
1/2
✓ Branch 0 (29→30) taken 1 times.
✗ Branch 1 (29→75) not taken.
1 processTreeReply(data);
113 1 break;
114 1 case IpcType::Marks:
115
1/2
✓ Branch 0 (31→32) taken 1 times.
✗ Branch 1 (31→75) not taken.
1 processMarkReply(data);
116 1 break;
117 2 case IpcType::BarConfig:
118
1/2
✓ Branch 0 (33→34) taken 2 times.
✗ Branch 1 (33→75) not taken.
2 processBarConfigReply(data);
119 2 break;
120 1 case IpcType::Version:
121
1/2
✓ Branch 0 (35→36) taken 1 times.
✗ Branch 1 (35→75) not taken.
1 processVersionReply(data);
122 1 break;
123 1 case IpcType::BindingModes:
124
1/2
✓ Branch 0 (37→38) taken 1 times.
✗ Branch 1 (37→75) not taken.
1 processBindingModesReply(data);
125 1 break;
126 1 case IpcType::Config:
127
1/2
✓ Branch 0 (39→40) taken 1 times.
✗ Branch 1 (39→75) not taken.
1 processConfigReply(data);
128 1 break;
129 case IpcType::Tick:
130 processTickReply(data);
131 break;
132 case IpcType::Sync:
133 processSyncReply(data);
134 break;
135 1 case IpcType::BindingState:
136
1/2
✓ Branch 0 (45→46) taken 1 times.
✗ Branch 1 (45→75) not taken.
1 processBindingStateReply(data);
137 1 break;
138 default:
139 log = "Received reply of unsupported type IpcType::%u.";
140 qCWarning(Qi3pcLogger, log.c_str(), type);
141 break;
142 }
143
2/6
✗ Branch 0 (59→60) not taken.
✓ Branch 1 (59→61) taken 10 times.
✓ Branch 2 (66→67) taken 10 times.
✗ Branch 3 (66→69) not taken.
✗ Branch 4 (77→78) not taken.
✗ Branch 5 (77→79) not taken.
30 }
144
145 void
146 qi3pc::processCommandReply(const QJsonDocument& doc)
147 {
148 if (auto val = doc["parse_error"]; val != QJsonValue::Undefined) {
149 emit parseError();
150 } else if (auto val = doc["error"]; val != QJsonValue::Undefined) {
151 Error error = val.toString();
152 emit commandRan(doc["success"].toBool(), error);
153 } else {
154 emit commandRan(doc["success"].toBool(), {});
155 }
156 }
157
158 void
159 1 qi3pc::processWorkspaceReply(const QJsonDocument& doc)
160 {
161
1/2
✓ Branch 0 (3→4) taken 1 times.
✗ Branch 1 (3→10) not taken.
1 m_workspaces = std::make_pair(doc.array(), QDateTime::currentMSecsSinceEpoch());
162 1 emit workspacesUpdated(m_workspaces);
163 1 }
164
165 void
166 1 qi3pc::processOutputReply(const QJsonDocument& doc)
167 {
168
1/2
✓ Branch 0 (3→4) taken 1 times.
✗ Branch 1 (3→10) not taken.
1 m_outputs = std::make_pair(doc.array(), QDateTime::currentMSecsSinceEpoch());
169 1 emit outputsUpdated(m_outputs);
170 1 }
171
172 void
173 1 qi3pc::processTreeReply(const QJsonDocument& doc)
174 {
175
1/2
✓ Branch 0 (3→4) taken 1 times.
✗ Branch 1 (3→10) not taken.
1 m_tree = std::make_pair(doc.object(), QDateTime::currentMSecsSinceEpoch());
176 1 emit treeUpdated(m_tree);
177 1 }
178
179 void
180 1 qi3pc::processMarkReply(const QJsonDocument& doc)
181 {
182
1/2
✓ Branch 0 (3→4) taken 1 times.
✗ Branch 1 (3→10) not taken.
1 m_marks = std::make_pair(doc.array(), QDateTime::currentMSecsSinceEpoch());
183 1 emit marksUpdated(m_marks);
184 1 }
185
186 void
187 2 qi3pc::processBarConfigReply(const QJsonDocument& doc)
188 {
189
4/6
✓ Branch 0 (2→3) taken 2 times.
✗ Branch 1 (2→71) not taken.
✓ Branch 2 (3→4) taken 2 times.
✗ Branch 3 (3→69) not taken.
✓ Branch 4 (4→5) taken 1 times.
✓ Branch 5 (4→24) taken 1 times.
4 if (const auto& ids = doc.array(); !ids.isEmpty()) {
190
3/4
✓ Branch 0 (6→7) taken 1 times.
✗ Branch 1 (6→53) not taken.
✓ Branch 2 (22→8) taken 1 times.
✓ Branch 3 (22→23) taken 1 times.
2 for (auto ref : ids) {
191
1/2
✓ Branch 0 (10→11) taken 1 times.
✗ Branch 1 (10→43) not taken.
1 if (auto id = ref.toString();
192
4/8
✓ Branch 0 (12→13) taken 1 times.
✗ Branch 1 (12→49) not taken.
✓ Branch 2 (14→15) taken 1 times.
✗ Branch 3 (14→46) not taken.
✓ Branch 4 (15→16) taken 1 times.
✗ Branch 5 (15→46) not taken.
✓ Branch 6 (17→18) taken 1 times.
✗ Branch 7 (17→19) not taken.
1 m_barConfigs->first[id] == QJsonValue::Null) {
193
1/2
✓ Branch 0 (18→19) taken 1 times.
✗ Branch 1 (18→50) not taken.
1 emit newBarConfig(id);
194 1 }
195 }
196 } else {
197
3/6
✓ Branch 0 (24→25) taken 1 times.
✗ Branch 1 (24→58) not taken.
✓ Branch 2 (25→26) taken 1 times.
✗ Branch 3 (25→56) not taken.
✓ Branch 4 (26→27) taken 1 times.
✗ Branch 5 (26→54) not taken.
1 auto id = doc["id"].toString();
198
1/2
✓ Branch 0 (29→30) taken 1 times.
✗ Branch 1 (29→66) not taken.
1 auto config = doc.object();
199
3/6
✓ Branch 0 (30→31) taken 1 times.
✗ Branch 1 (30→63) not taken.
✓ Branch 2 (32→33) taken 1 times.
✗ Branch 3 (32→60) not taken.
✓ Branch 4 (33→34) taken 1 times.
✗ Branch 5 (33→60) not taken.
1 m_barConfigs->first[id] = config;
200 1 m_barConfigs->second = QDateTime::currentMSecsSinceEpoch();
201
1/2
✓ Branch 0 (37→38) taken 1 times.
✗ Branch 1 (37→64) not taken.
1 emit barConfigUpdated(config);
202 1 }
203 2 }
204
205 void
206 1 qi3pc::processVersionReply(const QJsonDocument& doc)
207 {
208
1/2
✓ Branch 0 (3→4) taken 1 times.
✗ Branch 1 (3→10) not taken.
1 m_version = std::make_pair(doc.object(), QDateTime::currentMSecsSinceEpoch());
209 1 emit versionUpdated(m_version);
210 1 }
211
212 void
213 1 qi3pc::processBindingModesReply(const QJsonDocument& doc)
214 {
215
1/2
✓ Branch 0 (3→4) taken 1 times.
✗ Branch 1 (3→10) not taken.
1 m_bindingModes = std::make_pair(doc.array(), QDateTime::currentMSecsSinceEpoch());
216 1 emit bindingModesUpdated(m_bindingModes);
217 1 }
218
219 void
220 1 qi3pc::processConfigReply(const QJsonDocument& doc)
221 {
222
1/2
✓ Branch 0 (3→4) taken 1 times.
✗ Branch 1 (3→10) not taken.
1 m_config = std::make_pair(doc.object(), QDateTime::currentMSecsSinceEpoch());
223 1 emit configUpdated(m_config);
224 1 }
225
226 void
227 qi3pc::processTickReply(const QJsonDocument& doc)
228 {
229 emit tickSent(doc["success"].toBool());
230 }
231
232 void
233 qi3pc::processSyncReply(const QJsonDocument& doc)
234 {
235 emit synced(doc["success"].toBool());
236 }
237
238 void
239 1 qi3pc::processBindingStateReply(const QJsonDocument& doc)
240 {
241
3/6
✓ Branch 0 (3→4) taken 1 times.
✗ Branch 1 (3→18) not taken.
✓ Branch 2 (4→5) taken 1 times.
✗ Branch 3 (4→16) not taken.
✓ Branch 4 (5→6) taken 1 times.
✗ Branch 5 (5→14) not taken.
1 m_bindingState = std::make_pair(doc["name"].toString(), QDateTime::currentMSecsSinceEpoch());
242 1 emit bindingStateUpdated(m_bindingState);
243 1 }
244
245 void
246 qi3pc::processWorkspaceEvent(const QJsonDocument& doc)
247 {
248 auto change = workspaceChangeFromString(doc["change"].toString());
249
250 if (change == WorkspaceChange::Unknown) {
251 return;
252 }
253
254 auto old = doc["old"].toObject();
255 auto current = doc["current"].toObject();
256 emit workspaceEvent(change, current, old);
257 }
258
259 void
260 qi3pc::processOutputEvent(const QJsonDocument& data)
261 {
262 auto change = outputChangeFromString(data["change"].toString());
263
264 if (change == OutputChange::Unknown) {
265 return;
266 }
267
268 emit outputEvent(change);
269 }
270
271 void
272 qi3pc::processModeEvent(const QJsonDocument& doc)
273 {
274 emit modeEvent(doc["change"].toString(), doc["pango_markup"].toBool());
275 }
276
277 void
278 qi3pc::processWindowEvent(const QJsonDocument& doc)
279 {
280 auto change = windowChangeFromString(doc["change"].toString());
281
282 if (change == WindowChange::Unknown) {
283 return;
284 }
285
286 emit windowEvent(change, doc["container"].toObject());
287 }
288
289 void
290 qi3pc::processBarUpdateEvent(const QJsonDocument& doc)
291 {
292 emit barUpdateEvent(doc.object());
293 }
294
295 void
296 qi3pc::processBindingEvent(const QJsonDocument& doc)
297 {
298 auto change = bindingChangeFromString(doc["change"].toString());
299
300 if (change == BindingChange::Unknown) {
301 return;
302 }
303
304 emit bindingEvent(change, doc["binding"].toObject(), doc["mode"].toString());
305 }
306
307 void
308 qi3pc::processShutdownEvent(const QJsonDocument& doc)
309 {
310 auto change = shutdownChangeFromString(doc["change"].toString());
311
312 if (change == ShutdownChange::Unknown) {
313 return;
314 }
315
316 emit shutdownEvent(change);
317 }
318
319 void
320 qi3pc::processTickEvent(const QJsonDocument& doc)
321 {
322 emit tickEvent(doc["first"].toBool(), doc["payload"].toObject());
323 }
324
325 qi3pc::WorkspaceChange
326 qi3pc::workspaceChangeFromString(const QString& s) const
327 {
328 if (s == "focus") {
329 return WorkspaceChange::Focus;
330 } else if (s == "init") {
331 return WorkspaceChange::Init;
332 } else if (s == "empty") {
333 return WorkspaceChange::Empty;
334 } else if (s == "urgent") {
335 return WorkspaceChange::Urgent;
336 } else if (s == "reload") {
337 return WorkspaceChange::Reload;
338 } else if (s == "rename") {
339 return WorkspaceChange::Rename;
340 } else if (s == "restored") {
341 return WorkspaceChange::Restored;
342 } else if (s == "move") {
343 return WorkspaceChange::Move;
344 } else {
345 return WorkspaceChange::Unknown;
346 }
347 }
348
349 qi3pc::WindowChange
350 qi3pc::windowChangeFromString(const QString& s) const
351 {
352 if (s == "new") {
353 return WindowChange::New;
354 } else if (s == "close") {
355 return WindowChange::Close;
356 } else if (s == "focus") {
357 return WindowChange::Focus;
358 } else if (s == "title") {
359 return WindowChange::Title;
360 } else if (s == "fullscreen_mode") {
361 return WindowChange::Fullscreen;
362 } else if (s == "move") {
363 return WindowChange::Move;
364 } else if (s == "floating") {
365 return WindowChange::Floating;
366 } else if (s == "urgent") {
367 return WindowChange::Urgent;
368 } else if (s == "mark") {
369 return WindowChange::Mark;
370 } else {
371 return WindowChange::Unknown;
372 }
373 }
374
375 qi3pc::ShutdownChange
376 qi3pc::shutdownChangeFromString(const QString& s) const
377 {
378 if (s == "restart") {
379 return ShutdownChange::Restart;
380 } else if (s == "exit") {
381 return ShutdownChange::Exit;
382 } else {
383 return ShutdownChange::Unknown;
384 }
385 }
386
387 qi3pc::OutputChange
388 qi3pc::outputChangeFromString(const QString& s) const
389 {
390 if (s == "unspecified") {
391 return OutputChange::Unspecified;
392 } else {
393 return OutputChange::Unknown;
394 }
395 }
396
397 qi3pc::BindingChange
398 qi3pc::bindingChangeFromString(const QString& s) const
399 {
400 if (s == "run") {
401 return BindingChange::Run;
402 } else {
403 return BindingChange::Unknown;
404 }
405 }
406
407 qi3pc::Message
408 10 qi3pc::processMessage(QLocalSocket& socket)
409 {
410 char c[IpcMagicLength];
411
1/2
✓ Branch 0 (2→3) taken 10 times.
✗ Branch 1 (2→127) not taken.
10 socket.read(c, IpcMagicLength);
412
2/4
✓ Branch 0 (5→6) taken 10 times.
✗ Branch 1 (5→92) not taken.
✗ Branch 2 (8→9) not taken.
✓ Branch 3 (8→25) taken 10 times.
20 if (auto s = std::string(c); s != IpcMagicString) {
413 qCWarning(Qi3pcLogger) << "Unexpected magic string in message. Expected"
414 << qi3pc::IpcMagicString << ". - Found" << s << ".";
415 return {};
416
1/2
✓ Branch 0 (27→28) taken 10 times.
✗ Branch 1 (27→30) not taken.
10 }
417
418 quint32 size;
419
2/4
✓ Branch 0 (29→31) taken 10 times.
✗ Branch 1 (29→127) not taken.
✗ Branch 2 (31→32) not taken.
✓ Branch 3 (31→47) taken 10 times.
10 if (auto read_size = socket.read(reinterpret_cast<char*>(&size), sizeof size);
420 read_size != sizeof size) {
421 qCWarning(Qi3pcLogger) << "Insufficient data read for message size. Seeked"
422 << sizeof size <<"bytes. - Read" << read_size << "bytes.";
423 return {};
424 }
425
426 quint32 type;
427
2/4
✓ Branch 0 (47→48) taken 10 times.
✗ Branch 1 (47→127) not taken.
✗ Branch 2 (48→49) not taken.
✓ Branch 3 (48→64) taken 10 times.
10 if (auto read_size = socket.read(reinterpret_cast<char*>(&type), sizeof type);
428 read_size != sizeof type) {
429 qCWarning(Qi3pcLogger) << "Insufficient data read for message type. Seeked"
430 << sizeof type <<"bytes. - Read" << read_size << "bytes.";
431 return {};
432 }
433
434 10 QJsonParseError parseError;
435
2/4
✓ Branch 0 (64→65) taken 10 times.
✗ Branch 1 (64→115) not taken.
✓ Branch 2 (65→66) taken 10 times.
✗ Branch 3 (65→113) not taken.
10 QJsonDocument data = QJsonDocument::fromJson(socket.read(size), &parseError);
436
437
2/4
✓ Branch 0 (67→68) taken 10 times.
✗ Branch 1 (67→125) not taken.
✗ Branch 2 (68→69) not taken.
✓ Branch 3 (68→70) taken 10 times.
10 if (socket.bytesAvailable() > 0) {
438 emit socket.readyRead();
439 }
440
441
1/2
✗ Branch 0 (70→71) not taken.
✓ Branch 1 (70→85) taken 10 times.
10 if (parseError.error != QJsonParseError::NoError) {
442 qCWarning(Qi3pcLogger) << "Parsing message body failed - JSON parse error:" << parseError.errorString();
443 return {};
444 }
445
446
1/2
✓ Branch 0 (85→86) taken 10 times.
✗ Branch 1 (85→124) not taken.
10 return std::make_pair(data, type);
447 10 }
448
449 QString
450 qi3pc::socketPath() const
451 {
452
453 if (auto path = QProcessEnvironment::systemEnvironment().value("I3SOCK");
454 !path.isEmpty()) {
455 return path;
456 }
457
458 // TODO: try to get socket path from root window property
459
460 QProcess process;
461 process.start("i3", QStringList("--get-socketpath"));
462 process.waitForReadyRead();
463 auto path = QString(process.readAllStandardOutput()).trimmed();
464 process.kill();
465 return path;
466 }
467
468 const
469 qi3pc::DataArray&
470 1 qi3pc::workspaces() const
471 {
472 1 return m_workspaces;
473 }
474
475 const
476 qi3pc::DataObject&
477 1 qi3pc::tree() const
478 {
479 1 return m_tree;
480 }
481
482 const
483 qi3pc::DataArray&
484 1 qi3pc::outputs() const
485 {
486 1 return m_outputs;
487 }
488
489 const
490 qi3pc::DataArray&
491 1 qi3pc::marks() const
492 {
493 1 return m_marks;
494 }
495
496 const
497 qi3pc::DataObject&
498 1 qi3pc::barConfigs() const
499 {
500 1 return m_barConfigs;
501 }
502
503 const
504 qi3pc::DataObject&
505 1 qi3pc::version() const
506 {
507 1 return m_version;
508 }
509
510 const
511 qi3pc::DataArray&
512 1 qi3pc::bindingModes() const
513 {
514 1 return m_bindingModes;
515 }
516
517 const
518 qi3pc::DataObject&
519 1 qi3pc::config() const
520 {
521 1 return m_config;
522 }
523
524 const
525 qi3pc::String&
526 1 qi3pc::bindingState() const
527 {
528 1 return m_bindingState;
529 }
530
531 bool
532 10 qi3pc::connect()
533 {
534
535
1/2
✓ Branch 0 (3→4) taken 10 times.
✗ Branch 1 (3→20) not taken.
10 m_messageSocket.connectToServer(m_socketPath);
536
1/2
✓ Branch 0 (5→6) taken 10 times.
✗ Branch 1 (5→21) not taken.
10 m_eventSocket.connectToServer(m_socketPath);
537
538
1/2
✗ Branch 0 (7→8) not taken.
✓ Branch 1 (7→9) taken 10 times.
10 if (m_messageSocket.state() != QLocalSocket::ConnectedState)
539 {
540 m_messageSocket.waitForConnected();
541 }
542
543
1/2
✗ Branch 0 (10→11) not taken.
✓ Branch 1 (10→12) taken 10 times.
10 if (m_eventSocket.state() != QLocalSocket::ConnectedState)
544 {
545 m_eventSocket.waitForConnected();
546 }
547
548
1/2
✓ Branch 0 (13→14) taken 10 times.
✗ Branch 1 (13→17) not taken.
20 return m_messageSocket.state() == QLocalSocket::ConnectedState &&
549
1/2
✓ Branch 0 (15→16) taken 10 times.
✗ Branch 1 (15→17) not taken.
20 m_eventSocket.state() == QLocalSocket::ConnectedState;
550 }
551
552 bool
553 10 qi3pc::disconnect()
554 {
555 10 m_messageSocket.disconnectFromServer();
556 10 m_eventSocket.disconnectFromServer();
557
558
1/2
✗ Branch 0 (5→6) not taken.
✓ Branch 1 (5→7) taken 10 times.
10 if (m_messageSocket.state() != QLocalSocket::UnconnectedState)
559 {
560 m_messageSocket.waitForDisconnected();
561 }
562
563
1/2
✗ Branch 0 (8→9) not taken.
✓ Branch 1 (8→10) taken 10 times.
10 if (m_eventSocket.state() != QLocalSocket::UnconnectedState)
564 {
565 m_eventSocket.waitForDisconnected();
566 }
567
568
1/2
✓ Branch 0 (11→12) taken 10 times.
✗ Branch 1 (11→15) not taken.
20 return m_messageSocket.state() == QLocalSocket::UnconnectedState &&
569
1/2
✓ Branch 0 (13→14) taken 10 times.
✗ Branch 1 (13→15) not taken.
20 m_eventSocket.state() == QLocalSocket::UnconnectedState;
570 }
571
572 bool
573 33 qi3pc::isConnected()
574 {
575
2/4
✓ Branch 0 (3→4) taken 33 times.
✗ Branch 1 (3→6) not taken.
✗ Branch 2 (8→9) not taken.
✓ Branch 3 (8→11) taken 33 times.
66 if (m_messageSocket.state() == QLocalSocket::ConnectingState ||
576
1/2
✗ Branch 0 (5→6) not taken.
✓ Branch 1 (5→7) taken 33 times.
33 m_eventSocket.state() == QLocalSocket::ConnectingState) {
577 m_messageSocket.waitForConnected();
578 m_eventSocket.waitForConnected();
579 }
580
581
2/2
✓ Branch 0 (12→13) taken 10 times.
✓ Branch 1 (12→16) taken 23 times.
43 return m_messageSocket.state() == QLocalSocket::ConnectedState &&
582
1/2
✓ Branch 0 (14→15) taken 10 times.
✗ Branch 1 (14→16) not taken.
43 m_eventSocket.state() == QLocalSocket::ConnectedState;
583 }
584
585 void
586 10 qi3pc::sendMessage(IpcType type, const QByteArray& payload)
587 {
588 10 writePayload(m_messageSocket, payload, type);
589 10 }
590
591 void
592 qi3pc::subscribe(const QStringList& events)
593 {
594 writePayload(
595 m_eventSocket,
596 QJsonDocument(QJsonArray::fromStringList(events)).toJson(),
597 IpcType::Subscribe);
598 }
599
600 void
601 10 qi3pc::writePayload(QLocalSocket& socket, const QByteArray& payload, IpcType type) const
602 {
603 10 QByteArray message;
604
1/2
✓ Branch 0 (3→4) taken 10 times.
✗ Branch 1 (3→16) not taken.
10 QDataStream stream(&message, QIODevice::WriteOnly);
605
606
1/2
✓ Branch 0 (5→6) taken 10 times.
✗ Branch 1 (5→17) not taken.
10 stream.writeRawData(qi3pc::IpcMagicString.data(), qi3pc::IpcMagicLength);
607
608 10 qint32 size = payload.size();
609
1/2
✓ Branch 0 (7→8) taken 10 times.
✗ Branch 1 (7→17) not taken.
10 stream.writeRawData(reinterpret_cast<const char*>(&size), sizeof size);
610
1/2
✓ Branch 0 (8→9) taken 10 times.
✗ Branch 1 (8→17) not taken.
10 stream.writeRawData(reinterpret_cast<const char*>(&type), sizeof type);
611
612
2/2
✓ Branch 0 (9→10) taken 1 times.
✓ Branch 1 (9→12) taken 9 times.
10 if (size > 0) {
613
1/2
✓ Branch 0 (11→12) taken 1 times.
✗ Branch 1 (11→17) not taken.
1 stream.writeRawData(payload.constData(), size);
614 }
615
616
1/2
✓ Branch 0 (12→13) taken 10 times.
✗ Branch 1 (12→17) not taken.
10 socket.write(message);
617 10 }
618
619 void
620 1 qi3pc::fetchWorkspaces()
621 {
622
1/2
✓ Branch 0 (3→4) taken 1 times.
✗ Branch 1 (3→6) not taken.
1 sendMessage(IpcType::Workspaces);
623 1 }
624
625 void
626 1 qi3pc::fetchTree()
627 {
628
1/2
✓ Branch 0 (3→4) taken 1 times.
✗ Branch 1 (3→6) not taken.
1 sendMessage(IpcType::Tree);
629 1 }
630
631 void
632 1 qi3pc::fetchOutputs()
633 {
634
1/2
✓ Branch 0 (3→4) taken 1 times.
✗ Branch 1 (3→6) not taken.
1 sendMessage(IpcType::Outputs);
635 1 }
636
637 void
638 1 qi3pc::fetchMarks()
639 {
640
1/2
✓ Branch 0 (3→4) taken 1 times.
✗ Branch 1 (3→6) not taken.
1 sendMessage(IpcType::Marks);
641 1 }
642
643 void
644 1 qi3pc::fetchVersion()
645 {
646
1/2
✓ Branch 0 (3→4) taken 1 times.
✗ Branch 1 (3→6) not taken.
1 sendMessage(IpcType::Version);
647 1 }
648
649 void
650 1 qi3pc::fetchBindingModes()
651 {
652
1/2
✓ Branch 0 (3→4) taken 1 times.
✗ Branch 1 (3→6) not taken.
1 sendMessage(IpcType::BindingModes);
653 1 }
654
655 void
656 1 qi3pc::fetchConfig()
657 {
658
1/2
✓ Branch 0 (3→4) taken 1 times.
✗ Branch 1 (3→6) not taken.
1 sendMessage(IpcType::Config);
659 1 }
660
661 void
662 1 qi3pc::fetchBarConfigs()
663 {
664
1/2
✓ Branch 0 (3→4) taken 1 times.
✗ Branch 1 (3→6) not taken.
1 sendMessage(IpcType::BarConfig);
665 1 }
666
667 void
668 1 qi3pc::fetchBarConfig(const QString& id)
669 {
670 1 QByteArray payload;
671
2/4
✓ Branch 0 (2→3) taken 1 times.
✗ Branch 1 (2→11) not taken.
✓ Branch 2 (4→5) taken 1 times.
✗ Branch 3 (4→9) not taken.
1 payload.append(id.toStdString().c_str());
672
1/2
✓ Branch 0 (6→7) taken 1 times.
✗ Branch 1 (6→12) not taken.
1 sendMessage(IpcType::BarConfig, payload);
673 1 }
674
675 void
676 1 qi3pc::fetchBindingState()
677 {
678
1/2
✓ Branch 0 (3→4) taken 1 times.
✗ Branch 1 (3→6) not taken.
1 sendMessage(IpcType::BindingState);
679 1 }
680