| 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 |