Skip to content

Commit 584655d

Browse files
committed
i3/sway: fix multi monitor crash
1 parent aacf5dd commit 584655d

File tree

2 files changed

+20
-23
lines changed

2 files changed

+20
-23
lines changed

src/x11/i3/ipc/connection.cpp

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ QByteArray I3Ipc::buildRequestMessage(EventCode cmd, const QByteArray& payload)
6060
std::memcpy(lenBytes.data(), &len, 4);
6161
std::memcpy(typeBytes.data(), &cmd, 4);
6262

63-
QByteArray data = QByteArray("i3-ipc") + lenBytes + typeBytes + payload;
63+
QByteArray data = QByteArray(MAGIC) + lenBytes + typeBytes + payload;
6464

6565
return data;
6666
}
@@ -126,10 +126,10 @@ void I3Ipc::eventSocketReady() {
126126

127127
QVector<Event> I3Ipc::parseResponse(QByteArray rawEvent) {
128128
QVector<std::tuple<EventCode, QJsonDocument>> events;
129+
int magicLen = 6;
130+
int header = 8 + magicLen;
129131

130-
while (true) {
131-
int magicLen = 6;
132-
132+
while (rawEvent.startsWith(MAGIC)) {
133133
QDataStream ds(QByteArray(rawEvent.data() + magicLen, 8)); // NOLINT
134134

135135
ds.setByteOrder(static_cast<QDataStream::ByteOrder>(QSysInfo::ByteOrder));
@@ -140,21 +140,24 @@ QVector<Event> I3Ipc::parseResponse(QByteArray rawEvent) {
140140
ds >> size;
141141
ds >> type;
142142

143-
auto byteData = QByteArrayView(rawEvent.data() + magicLen + 8, size) // NOLINT
144-
.trimmed();
143+
if (I3IpcEvent::intToEvent(type) == EventCode::UNKNOWN) {
144+
qWarning(logi3Ipc) << "Received unknown event" << rawEvent;
145+
return events;
146+
}
147+
148+
auto byteData = QByteArray(rawEvent.data() + header, size); // NOLINT
145149

146150
QJsonParseError e;
147151

148-
auto data = QJsonDocument::fromJson(byteData.toByteArray(), &e);
152+
auto data = QJsonDocument::fromJson(byteData, &e);
149153

150154
if (e.error != QJsonParseError::NoError) {
151-
qWarning(logi3Ipc) << "Invalid JSON value:" << e.errorString() << "\n\t" << rawEvent;
155+
qWarning(logi3Ipc) << "Invalid JSON value:" << e.errorString() << "\n\t" << byteData;
152156
} else {
153157
events.push_back(std::tuple(I3IpcEvent::intToEvent(type), data));
154158
}
155159

156-
rawEvent = rawEvent.sliced(magicLen + 8 + size);
157-
if (!rawEvent.startsWith("i3-ipc")) break;
160+
rawEvent = rawEvent.sliced(header + size);
158161
}
159162

160163
return events;
@@ -329,7 +332,6 @@ void I3Ipc::refreshMonitors() {
329332
monitor->updateFromObject(object);
330333

331334
if (monitor->focused()) {
332-
// TODO: Set focused Monitor
333335
this->setFocusedMonitor(monitor);
334336
}
335337

@@ -375,8 +377,9 @@ void I3Ipc::onEvent(I3IpcEvent* event) {
375377
void I3Ipc::handleWorkspaceEvent(I3IpcEvent* event) {
376378
// If a workspace doesn't exist, and is being switch to, no focus change event is emited,
377379
// only the init one, which does not contain the previously focused workspace
380+
auto change = event->mData["change"];
378381

379-
if (event->mData["change"] == "init") {
382+
if (change == "init") {
380383
qCInfo(logi3IpcEvents) << "New workspace has been created";
381384

382385
auto workspaceData = event->mData["current"];
@@ -390,14 +393,7 @@ void I3Ipc::handleWorkspaceEvent(I3IpcEvent* event) {
390393
this->mWorkspaces.insertObject(workspace);
391394
qCInfo(logi3Ipc) << "Added workspace to list";
392395

393-
// Since we don't get a focus change event, we need to manually update the
394-
// status of all workspaces to find out which has the focus, as "init"
395-
// could also be caused by another action, which isn't a focus change
396-
this->refreshWorkspaces();
397-
}
398-
399-
if (event->mData["change"] == "focus") {
400-
396+
} else if (change == "focus") {
401397
auto oldName = event->mData["old"]["name"].toString();
402398
auto newName = event->mData["current"]["name"].toString();
403399

@@ -415,9 +411,7 @@ void I3Ipc::handleWorkspaceEvent(I3IpcEvent* event) {
415411
}
416412

417413
this->setFocusedWorkspace(newWorkspace);
418-
}
419-
420-
if (event->mData["change"] == "empty") {
414+
} else if (change == "empty") {
421415
auto name = event->mData["current"]["name"].toString();
422416

423417
auto* oldWorkspace = I3Ipc::findWorkspaceByName(name);

src/x11/i3/ipc/connection.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "../../../core/model.hpp"
1414

1515
namespace qs::i3::ipc {
16+
1617
class I3Workspace;
1718
class I3Monitor;
1819
} // namespace qs::i3::ipc
@@ -22,6 +23,8 @@ Q_DECLARE_OPAQUE_POINTER(qs::i3::ipc::I3Monitor*);
2223

2324
namespace qs::i3::ipc {
2425

26+
constexpr std::string MAGIC = "i3-ipc";
27+
2528
enum EventCode {
2629
RUN_COMMAND = 0, // NOLINT
2730
GET_WORKSPACES = 1, // NOLINT

0 commit comments

Comments
 (0)