13#include "virtualdesktops.h"
16#include <KConfigGroup>
17#include <KLocalizedString>
18#include <KSharedConfig>
21#include <QJsonDocument>
31 QList<Tile *> tiles({tileManager->
rootTile()});
32 QList<Tile *> tilePath;
33 QString indent(QStringLiteral(
"|-"));
34 debug << tileManager->metaObject()->className() <<
'(' <<
static_cast<const void *
>(tileManager) <<
')' <<
'\n';
35 while (!tiles.isEmpty()) {
36 auto *tile = tiles.last();
38 debug << indent << qobject_cast<CustomTile *>(tile) <<
'\n';
39 if (tile->childCount() > 0) {
40 tiles.append(tile->childTiles());
41 tilePath.append(tile->childTiles().first());
42 indent.prepend(QStringLiteral(
"| "));
44 if (!tilePath.isEmpty() && tile == tilePath.last()) {
61 m_saveTimer = std::make_unique<QTimer>(
this);
62 m_saveTimer->setSingleShot(
true);
63 m_saveTimer->setInterval(2000);
64 connect(m_saveTimer.get(), &QTimer::timeout,
this, &TileManager::saveSettings);
66 m_rootTile = std::make_unique<RootTile>(
this);
67 m_rootTile->setRelativeGeometry(QRectF(0, 0, 1, 1));
71 m_quickRootTile = std::make_unique<QuickRootTile>(
this);
87 const auto tiles = m_rootTile->descendants();
88 qreal minimumDistance = std::numeric_limits<qreal>::max();
91 for (
auto *t : tiles) {
95 qreal distance = (r.center() - pos).manhattanLength();
96 if (!exclusiveContains(r, pos)) {
99 distance += m_output->
geometryF().width();
101 if (distance < minimumDistance) {
102 minimumDistance = distance;
117 return m_rootTile.get();
122 return m_quickRootTile->tileForMode(mode);
127 return m_tileModel.get();
132 if (dir == QStringLiteral(
"horizontal")) {
134 }
else if (dir == QStringLiteral(
"vertical")) {
141CustomTile *TileManager::parseTilingJSon(
const QJsonValue &val,
const QRectF &availableArea, CustomTile *parentTile)
143 if (availableArea.isEmpty()) {
147 if (val.isObject()) {
148 const auto &obj = val.toObject();
152 QRectF rect = availableArea;
153 const auto width = obj.value(QStringLiteral(
"width"));
154 if (width.isDouble()) {
155 rect.setWidth(std::min(width.toDouble(), availableArea.width()));
157 if (!rect.isEmpty()) {
158 createdTile = parentTile->createChildAt(rect, parentTile->layoutDirection(), parentTile->childCount());
162 QRectF rect = availableArea;
163 const auto height = obj.value(QStringLiteral(
"height"));
164 if (height.isDouble()) {
165 rect.setHeight(std::min(height.toDouble(), availableArea.height()));
167 if (!rect.isEmpty()) {
168 createdTile = parentTile->createChildAt(rect, parentTile->layoutDirection(), parentTile->childCount());
172 QRectF rect(0, 0, 1, 1);
173 rect = QRectF(obj.value(QStringLiteral(
"x")).toDouble(),
174 obj.value(QStringLiteral(
"y")).toDouble(),
175 obj.value(QStringLiteral(
"width")).toDouble(),
176 obj.value(QStringLiteral(
"height")).toDouble());
178 if (!rect.isEmpty()) {
179 createdTile = parentTile->createChildAt(rect, parentTile->layoutDirection(), parentTile->childCount());
183 if (createdTile && obj.contains(QStringLiteral(
"tiles"))) {
185 const auto arr = obj.value(QStringLiteral(
"tiles"));
186 const auto direction = obj.value(QStringLiteral(
"layoutDirection"));
188 if (arr.isArray() && arr.toArray().count() > 0) {
190 createdTile->setLayoutDirection(dir);
191 parseTilingJSon(arr, createdTile->relativeGeometry(), createdTile);
195 }
else if (val.isArray()) {
196 const auto arr = val.toArray();
197 auto avail = availableArea;
198 for (
auto it = arr.cbegin(); it != arr.cend(); it++) {
199 if ((*it).isObject()) {
200 auto *tile = parseTilingJSon(*it, avail, parentTile);
202 avail.setLeft(tile->relativeGeometry().right());
204 avail.setTop(tile->relativeGeometry().bottom());
210 && parentTile->childCount() > 0) {
211 auto *last = parentTile->childTile(parentTile->childCount() - 1);
212 auto geom = last->relativeGeometry();
213 geom.setRight(parentTile->relativeGeometry().right());
214 last->setRelativeGeometry(geom);
221void TileManager::readSettings()
223 KConfigGroup cg = kwinApp()->config()->group(QStringLiteral(
"Tiling"));
224 qreal padding = cg.readEntry(
"padding", 4);
225 cg = KConfigGroup(&cg, m_output->
uuid().toString(QUuid::WithoutBraces));
227 auto createDefaultSetup = [
this]() {
228 Q_ASSERT(m_rootTile->childCount() == 0);
233 Q_ASSERT(m_rootTile->childCount() == 3);
235 m_rootTile->childTile(1)->setRelativeGeometry({0.25, 0.0, 0.5, 1.0});
238 QJsonParseError error;
239 const auto tiles = cg.readEntry(
"tiles", QByteArray());
240 if (tiles.isEmpty()) {
241 qCDebug(KWIN_CORE) <<
"Empty tiles configuration for monitor" << m_output->
uuid().toString(QUuid::WithoutBraces) <<
":"
242 <<
"Creating default setup";
243 createDefaultSetup();
246 QJsonDocument doc = QJsonDocument::fromJson(tiles, &error);
248 if (error.error != QJsonParseError::NoError) {
249 qCWarning(KWIN_CORE) <<
"Parse error in tiles configuration for monitor" << m_output->
uuid().toString(QUuid::WithoutBraces) <<
":" << error.errorString() <<
"Creating default setup";
250 createDefaultSetup();
254 if (doc.object().contains(QStringLiteral(
"tiles"))) {
255 const auto arr = doc.object().value(QStringLiteral(
"tiles"));
256 if (arr.isArray() && arr.toArray().count() > 0) {
257 m_rootTile->setLayoutDirection(
strToLayoutDirection(doc.object().value(QStringLiteral(
"layoutDirection")).toString()));
258 parseTilingJSon(arr, QRectF(0, 0, 1, 1), m_rootTile.get());
262 m_rootTile->setPadding(padding);
265QJsonObject TileManager::tileToJSon(CustomTile *tile)
269 auto *parentTile =
static_cast<CustomTile *
>(tile->parentTile());
273 switch (parentTile->layoutDirection()) {
275 obj[QStringLiteral(
"width")] = tile->relativeGeometry().width();
278 obj[QStringLiteral(
"height")] = tile->relativeGeometry().height();
282 obj[QStringLiteral(
"x")] = tile->relativeGeometry().x();
283 obj[QStringLiteral(
"y")] = tile->relativeGeometry().y();
284 obj[QStringLiteral(
"width")] = tile->relativeGeometry().width();
285 obj[QStringLiteral(
"height")] = tile->relativeGeometry().height();
289 if (tile->isLayout()) {
290 switch (tile->layoutDirection()) {
292 obj[QStringLiteral(
"layoutDirection")] = QStringLiteral(
"horizontal");
295 obj[QStringLiteral(
"layoutDirection")] = QStringLiteral(
"vertical");
299 obj[QStringLiteral(
"layoutDirection")] = QStringLiteral(
"floating");
303 const int nChildren = tile->childCount();
304 for (
int i = 0; i < nChildren; ++i) {
305 tiles.append(tileToJSon(
static_cast<CustomTile *
>(tile->childTile(i))));
307 obj[QStringLiteral(
"tiles")] = tiles;
313void TileManager::saveSettings()
315 auto obj = tileToJSon(m_rootTile.get());
316 QJsonDocument doc(obj);
317 KConfigGroup cg = kwinApp()->config()->group(QStringLiteral(
"Tiling"));
318 cg.writeEntry(
"padding", m_rootTile->padding());
319 cg = KConfigGroup(&cg, m_output->
uuid().toString(QUuid::WithoutBraces));
320 cg.writeEntry(
"tiles", doc.toJson(QJsonDocument::Compact));
326#include "moc_tilemanager.cpp"
void paddingChanged(qreal padding)
TileManager(Output *parent=nullptr)
KWin::Tile * quickTile(QuickTileMode mode) const
KWin::Tile * bestTileForPosition(const QPointF &pos)
Tile::LayoutDirection strToLayoutDirection(const QString &dir)
QDebug & operator<<(QDebug &s, const KWin::DrmConnector *obj)