From 93b523c253c9205a0a02223ee212fa2572efbccf Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Fri, 24 Apr 2020 13:52:44 +0200 Subject: React to changed screen setup, update layout --- qt-lightdm-greeter.qrc | 1 - resources/gnome-face-tired.svg | 376 ----------------------------------------- src/main.cpp | 243 ++++++++++++++++---------- src/mainwindow.cpp | 186 ++++++++++---------- src/mainwindow.h | 42 ++--- src/snake.cpp | 4 +- 6 files changed, 273 insertions(+), 579 deletions(-) delete mode 100644 resources/gnome-face-tired.svg diff --git a/qt-lightdm-greeter.qrc b/qt-lightdm-greeter.qrc index eed73f9..aa7accd 100644 --- a/qt-lightdm-greeter.qrc +++ b/qt-lightdm-greeter.qrc @@ -4,6 +4,5 @@ resources/backIcon.svg resources/leaveIcon.svg resources/bwlp.svg - resources/gnome-face-tired.svg diff --git a/resources/gnome-face-tired.svg b/resources/gnome-face-tired.svg deleted file mode 100644 index de43b1a..0000000 --- a/resources/gnome-face-tired.svg +++ /dev/null @@ -1,376 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - Lapo Calamandrei - - - - emoticon, emots, smiley, saint, angel, smile - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main.cpp b/src/main.cpp index d248718..17d07bc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include /* Obtain O_* constant definitions */ #include @@ -32,9 +33,15 @@ Settings *s_settings = new Settings(); static int sockets[2]; +static QMap currentWindows; + +static QTimer setupDelay; + static void createSimpleBackground(); -static void sigUsr1(int); +static void watch(const QScreen *scrn); + +static void setupScreens(); static void messageHandler(QtMsgType type, const QMessageLogContext&, const QString& msg) { @@ -43,16 +50,16 @@ static void messageHandler(QtMsgType type, const QMessageLogContext&, const QStr static inline int size(const QRect& r) { - return r.width() * r.height(); + return r.width() * r.height(); } int main(int argc, char *argv[]) { - if (argc > 1 && QString(argv[1]) == QString("--test")) { - Global::enableTestMode(); - } + if (argc > 1 && QString(argv[1]) == QString("--test")) { + Global::enableTestMode(); + } - QApplication a(argc, argv); + QApplication a(argc, argv); // I have no idea why, but Qt's stock qWarning() output never makes it // to /var/log/lightdm/x-0-greeter.log, so we use std::cerr instead.. @@ -63,36 +70,85 @@ int main(int argc, char *argv[]) } if (!Global::testMode() && !Settings::autoLoginCheckCmd().isEmpty()) { - QProcess p; + QProcess p; int ret = QProcess::execute(Settings::autoLoginCheckCmd()); - if (ret == 0) { - if (Global::autoLoginGuest()) { - qWarning() << "Guest login ok"; + if (ret == 0) { + if (Global::autoLoginGuest()) { + qWarning() << "Guest login ok"; createSimpleBackground(); return a.exec(); - } else { - qWarning() << "Guest login failed"; - // TODO: Set error message, display somewhere - } - } + } else { + qWarning() << "Guest login failed"; + // TODO: Set error message, display somewhere + } + } } - // Build background for X server, in case we start a session that - // doesn't set one on its own this will make sure it's not simply - // black - QImage entire; + QObject::connect(&setupDelay, &QTimer::timeout, []() { + setupScreens(); + }); + setupDelay.setInterval(100); + setupDelay.setSingleShot(true); + setupDelay.start(); - // Get a list of non-overlapping screens, as this might lead to a broken - // greeter with main windows covering other login forms - QMap screens; + if (!Global::testMode()) { + for (const auto scrn : QGuiApplication::screens()) { + watch(scrn); + } + QObject::connect(qApp, &QGuiApplication::screenAdded, [](const QScreen *scrn) { + setupDelay.start(); + watch(scrn); + }); + auto cb = [](const QScreen *) { + setupDelay.start(); + }; + QObject::connect(qApp, &QGuiApplication::screenRemoved, cb); + QObject::connect(qApp, &QGuiApplication::primaryScreenChanged, cb); + } + + /* + if (!entire.isNull()) { + qWarning() << "Setting x background"; + AddPixmapToBackground(entire.constBits(), entire.width(), entire.height(), + 24, entire.bytesPerLine(), entire.byteCount()); + } + */ + + return a.exec(); +} + +static void watch(const QScreen *scrn) +{ + QObject::connect(scrn, &QScreen::geometryChanged, [](const QRect &geom) { + setupDelay.start(); + }); +} + +static void createSimpleBackground() +{ + QImage img = Global::getConfigGradient(); + if (img.isNull()) + return; + img = img.scaled(QApplication::desktop()->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + AddPixmapToBackground(img.constBits(), img.width(), img.height(), + 24, img.bytesPerLine(), img.byteCount()); +} + +static QList allOld; +static int primaryOld = -1; + +void setupScreens() +{ + // Get a list of non-overlapping screens, as this might lead to a broken + // greeter with main windows covering other login forms + QMap screens; + QList allNew; if (Global::testMode()) { screens.insert(0, QRect(0, 0, 1024, 768)); } else { - QSize desktopSize = QApplication::desktop()->size(); - qWarning() << "Desktop full size is " << desktopSize; - entire = QImage(desktopSize, QImage::Format_RGB32); for (int i = 0; i < QApplication::desktop()->screenCount(); ++i) { QRect r = QApplication::desktop()->screenGeometry(i); + allNew.append(r); QMutableMapIteratorit(screens); while (it.hasNext()) { it.next(); @@ -112,79 +168,82 @@ int main(int argc, char *argv[]) } } - // Determine primary screen - int primary; - if (screens.contains(QApplication::desktop()->primaryScreen())) { - // Primary screen still in selection - primary = QApplication::desktop()->primaryScreen(); - } else { - // Fallback to first one - primary = screens.begin().key(); - } - - struct sigaction usr1; - - usr1.sa_handler = &sigUsr1; - sigemptyset(&usr1.sa_mask); - usr1.sa_flags = SA_RESTART; - - QSocketNotifier *sn = nullptr; - if (sigaction(SIGUSR1, &usr1, nullptr) == 0 && ::socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) == 0) { - sn = new QSocketNotifier(sockets[1], QSocketNotifier::Read); - QObject::connect(sn, &QSocketNotifier::activated, [](int fd) { - char tmp[1000]; - read(fd, tmp, sizeof tmp); - }); - } - - // Now set up all the screens - QPainter painter(&entire); - MainWindow *focusWindow = nullptr; + // Spurious event? + int primaryNew = QApplication::desktop()->primaryScreen(); + if (primaryNew == primaryOld && allOld == allNew) + return; + primaryOld = primaryNew; + allOld = allNew; + + // Determine primary screen + int primary; + if (screens.contains(primaryNew)) { + // Primary screen still in selection + primary = primaryNew; + } else { + // Fallback to first one + primary = screens.begin().key(); + } + + // Try to reuse as many mainwindows as possible + QMap remaining = currentWindows; + do { + currentWindows.clear(); + QMutableMapIterator it(screens); + while (it.hasNext()) { + it.next(); + MainWindow *old = remaining.take(it.key()); + if (old != nullptr) { + // Existing + qDebug() << "Re-using existing window"; + old->setGeometry(it.value()); + if (old->showLoginForm() && primary != it.key()) { + qDebug() << "Destroying old login form"; + LoginForm *logForm = old->stealLoginForm(); + if (logForm != nullptr) { + logForm->setParent(nullptr); + logForm->deleteLater(); + } + } + currentWindows.insert(it.key(), old); + it.remove(); + } + } + } while(0); + + // Now set up remaining screens QMapIterator it(screens); while (it.hasNext()) { - it.next(); - MainWindow *w = new MainWindow(primary == it.key(), it.key(), it.value()); - w->show(); - if (sn != nullptr) { - QObject::connect(sn, SIGNAL(activated(int)), w, SLOT(showStandby())); - } - if (w->showLoginForm()) { - focusWindow = w; + it.next(); + MainWindow *old = nullptr; + if (!remaining.empty()) { + qDebug() << "This should never happen, reusing old window II"; + old = remaining.take(remaining.firstKey()); + if (old != nullptr) { + if (old->showLoginForm() && primary != it.key()) { + LoginForm *logForm = old->stealLoginForm(); + if (logForm != nullptr) { + logForm->setParent(nullptr); + logForm->deleteLater(); + } + } + old->setGeometry(it.value()); + } } - if (!entire.isNull()) { - QPoint p = it.value().topLeft(); - painter.drawImage(p, w->getBackground()); + if (old == nullptr) { + qDebug() << "Adding a window"; + old = new MainWindow(primary == it.key(), it.key(), it.value()); + old->show(); + } + currentWindows.insert(it.key(), old); + if (old->showLoginForm()) { + old->setFocus(Qt::OtherFocusReason); + old->activateWindow(); } } - if (!entire.isNull()) { - qWarning() << "Setting x background"; - AddPixmapToBackground(entire.constBits(), entire.width(), entire.height(), - 24, entire.bytesPerLine(), entire.byteCount()); - } - - // Ensure we set the primary screen's widget as active when there - // are more screens - if (focusWindow) { - focusWindow->setFocus(Qt::OtherFocusReason); - focusWindow->activateWindow(); + for (MainWindow *old : remaining) { + old->deleteLater(); } - - return a.exec(); -} - -static void createSimpleBackground() -{ - QImage img = Global::getConfigGradient(); - if (img.isNull()) - return; - img = img.scaled(QApplication::desktop()->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); - AddPixmapToBackground(img.constBits(), img.width(), img.height(), - 24, img.bytesPerLine(), img.byteCount()); } -static void sigUsr1(int) -{ - char a = 1; - ::write(sockets[0], &a, sizeof(a)); -} diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 1e08f0f..7c75489 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -32,106 +32,138 @@ MainWindow::MainWindow(bool primary, int screen, const QRect &screenRect, QWidget *parent) : QWidget(parent), m_ScreenRect(screenRect), - m_Primary(primary), m_LoginForm(nullptr), m_messages(nullptr), m_Clock(nullptr), - m_Snake(nullptr) + m_Snake(nullptr), + m_Banner(nullptr), + m_News(nullptr) { setObjectName(QString("MainWindow_%1").arg(screen)); - setGeometry(screenRect); - - setBackground(); - // TODO: Check if testMode == false and greeter == NULL, if so display big error message // instead of exiting/crashing // display login dialog only in the main screen + if (primary) { + m_LoginForm = new LoginForm(this); + // This hack ensures that the primary screen will have focus + // if there are more screens (move the mouse cursor in the center + // of primary screen - not in the center of all X area). It + // won't affect single-screen environments. + int centerX = screenRect.width()/2 + screenRect.x(); + int centerY = screenRect.height()/2 + screenRect.y(); + QCursor::setPos(centerX, centerY); + } + // Banner + if (!Settings::bannerImageFile().isEmpty()) { + qWarning() << "Have banner " << Settings::bannerImageFile(); + m_Banner = new QSvgWidget(Settings::bannerImageFile(), this); + } + + createLogWindow(); + createClock(); + createNewsWindow(); + + setGeometry(screenRect); +} + +void MainWindow::resizeEvent(QResizeEvent *event) +{ + if (m_Snake != nullptr) { + delete m_Snake; + m_Snake = nullptr; + } + + QWidget::resizeEvent(event); + m_ScreenRect = QRect(this->pos(), event->size()); + setBackground(); /* * Everything is layed out manually here, since I don't know how to represent the size constraints * and interactions of everything using layout classes. You're welcome to improve this, but I double * dare you to not break any combination of having/not having certain logos or elements displayed. */ - int newsY = 100; - int newsX = screenRect.width() / 2; - int newsBottom = screenRect.height(); + int newsX = m_ScreenRect.width() / 2; + int newsBottom = m_ScreenRect.height(); - int spaceY = screenRect.height() / 2; - - if (showLoginForm()) { - m_LoginForm = new LoginForm(this); + int spaceY = m_ScreenRect.height() / 2; + + if (m_LoginForm != nullptr) { spaceY -= m_LoginForm->height() / 2; - int maxX = screenRect.width() - m_LoginForm->width(); - int maxY = screenRect.height() - m_LoginForm->height(); + int maxX = m_ScreenRect.width() - m_LoginForm->width(); + int maxY = m_ScreenRect.height() - m_LoginForm->height(); int defaultX = 50*maxX/100; int defaultY = 50*maxY/100; int offsetX = getOffset(Settings::offsetX(), maxX, defaultX); int offsetY = getOffset(Settings::offsetY(), maxY, defaultY); - + m_LoginForm->move(offsetX, offsetY); m_LoginForm->show(); - - // This hack ensures that the primary screen will have focus - // if there are more screens (move the mouse cursor in the center - // of primary screen - not in the center of all X area). It - // won't affect single-screen environments. - int centerX = screenRect.width()/2 + screenRect.x(); - int centerY = screenRect.height()/2 + screenRect.y(); - QCursor::setPos(centerX, centerY); newsX = m_LoginForm->geometry().right() + 5; } // Banner - if (!Settings::bannerImageFile().isEmpty()) { - qWarning() << "Have banner " << Settings::bannerImageFile(); - QSvgWidget *banner = new QSvgWidget(Settings::bannerImageFile(), this); - qWarning() << banner->sizeHint(); - if (banner->renderer()->isValid()) { + if (m_Banner != nullptr) { + qWarning() << m_Banner->sizeHint(); + if (m_Banner->renderer()->isValid()) { QSize sh; int offs = 0; do { offs += 20; - sh = banner->sizeHint().scaled(screenRect.width() - offs, spaceY - offs - 50, Qt::KeepAspectRatio); - } while (offs < 200 && sh.width() > screenRect.width() / 2 && sh.height() > spaceY / 2); + sh = m_Banner->sizeHint().scaled(m_ScreenRect.width() - offs, spaceY - offs - 50, Qt::KeepAspectRatio); + } while (offs < 200 && sh.width() > m_ScreenRect.width() / 2 && sh.height() > spaceY / 2); int yoff = (spaceY - sh.height()); if (yoff < 100) { yoff = 100; } - banner->setGeometry((screenRect.width() - sh.width()) / 2, yoff / 2, sh.width(), sh.height()); - newsY = banner->geometry().bottom() + 10; + m_Banner->setGeometry((m_ScreenRect.width() - sh.width()) / 2, yoff / 2, sh.width(), sh.height()); + newsY = m_Banner->geometry().bottom() + 10; } } + for (QWidget *w : m_DecoItems) { + w->setParent(nullptr); + w->deleteLater(); + } + // Distro and custom icons left/right bottom + m_DecoItems.clear(); int ls = (spaceY > 500 ? 500 : spaceY); - if (ls > screenRect.height() / 5) ls = screenRect.height() / 5; - if (ls > screenRect.width() / 5) ls = screenRect.width() / 5; - QRect logoRect(QPoint(0, screenRect.height() / 3), QSize(ls, screenRect.height() * 2 / 3)); + if (ls > m_ScreenRect.height() / 5) ls = m_ScreenRect.height() / 5; + if (ls > m_ScreenRect.width() / 5) ls = m_ScreenRect.width() / 5; + QRect logoRect(QPoint(0, m_ScreenRect.height() / 3), QSize(ls, m_ScreenRect.height() * 2 / 3)); QSize logoSize = createLogo(logoRect); - QRect distroRect(QPoint(screenRect.width() - ls, screenRect.height() - ls), QSize(ls, ls)); + QRect distroRect(QPoint(m_ScreenRect.width() - ls, m_ScreenRect.height() - ls), QSize(ls, ls)); QSize distroSize = createDistro(distroRect); if (distroSize.height() > 0) { newsBottom -= distroSize.height() - 10; } - if (showLoginForm()) { - // Log window - QRect lwSize(QPoint(logoSize.width(), screenRect.height() * 3/4), QPoint(screenRect.width() - distroSize.width(), screenRect.height())); + // Log window + if (m_messages != nullptr) { + QRect lwSize(QPoint(logoSize.width(), m_ScreenRect.height() * 3/4), QPoint(m_ScreenRect.width() - distroSize.width(), m_ScreenRect.height())); lwSize.adjust(10, 10, -10, -10); - if (createLogWindow(lwSize)) { - newsBottom = lwSize.top(); - } + m_messages->setGeometry(lwSize); + int ps = lwSize.height() / 20; + if (ps > 20) ps = 20; + m_messages->setFontPointSize(ps); + newsBottom = lwSize.top(); + } + if (m_Clock != nullptr) { + m_Clock->setFixedWidth(m_ScreenRect.width()); + m_Clock->parentWidget()->setFixedWidth(m_ScreenRect.width()); } - createClock(); // News widget - QRect newsSize(QPoint(newsX, newsY), QPoint(screenRect.width() - 10, newsBottom - 10)); - createNewsWindow(newsSize); -} - -MainWindow::~MainWindow() -{ + if (m_News != nullptr) { + QRect newsSize(QPoint(newsX, newsY), QPoint(m_ScreenRect.width() - 10, newsBottom - 10)); + if (newsSize.width() < 200 || newsSize.height() < 80) { + m_News->hide(); + } else { + m_News->setGeometry(newsSize); + m_News->show(); + } + } } void MainWindow::paintEvent(QPaintEvent *event) @@ -194,14 +226,19 @@ void MainWindow::createNextLogo(QRect &max, QSize &retval, const QString &path) if (max.height() <= 0) return; QSvgWidget *img = new QSvgWidget(path, this); - if (!img->renderer()->isValid()) + if (!img->renderer()->isValid()) { + img->deleteLater(); return; + } QSize virtualSize = img->sizeHint().scaled(max.width(), max.height(), Qt::KeepAspectRatio); QSize realSize = img->sizeHint().scaled(max.width() - 20, max.height() - 20, Qt::KeepAspectRatio); - if (virtualSize.width() == 0 || virtualSize.height() == 0) + if (virtualSize.width() == 0 || virtualSize.height() == 0) { + img->deleteLater(); return; + } QRect c(max.left() + 10, max.bottom() - realSize.height() - 10, realSize.width(), realSize.height()); img->setGeometry(c); + m_DecoItems.append(img); max.setHeight(max.height() - virtualSize.height()); retval.setWidth(qMax(retval.width(), virtualSize.width())); retval.setHeight(retval.height() + virtualSize.height()); @@ -222,13 +259,14 @@ QSize MainWindow::createDistro(const QRect &max) } QPixmap pixmap(QPixmap::fromImage(img)); QLabel *lbl = new QLabel(this); + m_DecoItems.append(lbl); lbl->setPixmap(pixmap); QRect c(max.right() - realSize.width() - 10, max.bottom() - realSize.height() - 10, realSize.width(), realSize.height()); lbl->setGeometry(c); return virtualSize; } -bool MainWindow::createLogWindow(const QRect& geom) +bool MainWindow::createLogWindow() { QString path = Settings::logMessageFile(); if (path.isEmpty()) @@ -237,10 +275,6 @@ bool MainWindow::createLogWindow(const QRect& geom) if (f.size() == 0 || !f.open(QFile::ReadOnly)) return false; m_messages = new QTextEdit(this); - m_messages->setGeometry(geom); - int ps = geom.height() / 20; - if (ps > 20) ps = 20; - m_messages->setFontPointSize(ps); QTextStream stream(&f); const QColor black(Qt::black); while (!stream.atEnd()) { @@ -265,21 +299,18 @@ bool MainWindow::createLogWindow(const QRect& geom) return true; } -void MainWindow::createNewsWindow(const QRect &size) +void MainWindow::createNewsWindow() { - if (size.width() < 100 || size.height() < 100) - return; QString path = Settings::newsHtmlFile(); if (path.isEmpty()) return; QFile f(path); if (f.size() == 0 || !f.open(QFile::ReadOnly)) return; - QTextEdit *news = new QTextEdit(this); - news->setReadOnly(true); - news->setStyleSheet("border:none; background:rgba(255,255,255,.33); border-radius:5px"); - news->setHtml(QString::fromUtf8(f.readAll())); - news->setGeometry(size); + m_News = new QTextEdit(this); + m_News->setReadOnly(true); + m_News->setStyleSheet("border:none; background:rgba(255,255,255,.33); border-radius:5px"); + m_News->setHtml(QString::fromUtf8(f.readAll())); } void MainWindow::createClock() @@ -329,7 +360,7 @@ void MainWindow::createClock() bool MainWindow::showLoginForm() { - return m_Primary; + return m_LoginForm != nullptr; } void MainWindow::setFocus(Qt::FocusReason reason) @@ -368,6 +399,7 @@ int MainWindow::getOffset(QString settingsOffset, int maxVal, int defaultVal) void MainWindow::setBackground() { + m_background = QImage(); Qt::AspectRatioMode arMode = Qt::KeepAspectRatioByExpanding; QString bgPath = Settings::backgrundImageFile(); if (bgPath.length() != 0) { @@ -407,28 +439,6 @@ void MainWindow::setBackground() this->setPalette(palette); } -void MainWindow::showStandby() -{ - if (m_LoginForm != nullptr) { - m_LoginForm->hide(); - } - QSvgWidget *img = new QSvgWidget(":/resources/gnome-face-tired.svg", this); - if (img->renderer()->isValid()) { - QSize sh = img->sizeHint().scaled(this->width() / 2, this->height() / 2, Qt::KeepAspectRatio); - img->setGeometry((this->width() - sh.width()) / 2, (this->height() - sh.height()) / 2, sh.width(), sh.height()); - img->show(); - } else { - qWarning() << "Shice!"; - } - QTimer::singleShot(4000, [this, img]() { - img->hide(); - img->deleteLater(); - if (this->m_LoginForm != nullptr) { - m_LoginForm->show(); - } - }); -} - void MainWindow::updateClock() { int next = drawClock(); diff --git a/src/mainwindow.h b/src/mainwindow.h index 8f9245e..fc0249b 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -14,6 +14,7 @@ #include #include #include +#include #include "loginform.h" @@ -22,6 +23,7 @@ namespace Ui { } class QTextEdit; +class QSvgWidget; class GameCore; @@ -30,51 +32,51 @@ class MainWindow : public QWidget Q_OBJECT public: - explicit MainWindow(bool primary, int screen, const QRect &rect, QWidget *parent = 0); - ~MainWindow(); + explicit MainWindow(bool primary, int screen, const QRect &rect, QWidget *parent = nullptr); void setFocus(Qt::FocusReason reason); - QSize createLogo(QRect max); + bool showLoginForm(); - void createNextLogo(QRect &max, QSize &retval, const QString &path); + LoginForm* stealLoginForm() { LoginForm *p = m_LoginForm; m_LoginForm = nullptr; return p; } - QSize createDistro(const QRect &max); +protected: + virtual void paintEvent(QPaintEvent *event) override; - bool createLogWindow(const QRect& geom); + virtual void mouseDoubleClickEvent(QMouseEvent *) override; - void createNewsWindow(const QRect &size); + virtual void keyPressEvent(QKeyEvent *) override; - void createClock(); + virtual void resizeEvent(QResizeEvent *) override; - bool showLoginForm(); +public slots: + void updateClock(); - QImage& getBackground() { return m_background; } +private: - LoginForm* loginForm() { return m_LoginForm; } + QSize createLogo(QRect max); -protected: - virtual void paintEvent(QPaintEvent *event); + void createNextLogo(QRect &max, QSize &retval, const QString &path); - virtual void mouseDoubleClickEvent(QMouseEvent *); + QSize createDistro(const QRect &max); - virtual void keyPressEvent(QKeyEvent *); + bool createLogWindow(); -public slots: - void showStandby(); - void updateClock(); + void createNewsWindow(); -private: + void createClock(); int getOffset(QString offset, int maxVal, int defaultVal); void setBackground(); int drawClock(); QRect m_ScreenRect; - bool m_Primary; LoginForm* m_LoginForm; QImage m_background; QTextEdit *m_messages; QLabel *m_Clock; GameCore *m_Snake; + QSvgWidget *m_Banner; + QList m_DecoItems; + QTextEdit *m_News; }; #endif // MAINWINDOW_H diff --git a/src/snake.cpp b/src/snake.cpp index 9c7fefa..2ce1a0d 100644 --- a/src/snake.cpp +++ b/src/snake.cpp @@ -215,7 +215,7 @@ GameCore::GameCore(QWidget *widget) snake->parts.append(QPoint(snake->x, snake->y)); } // If no food was picked up within a minute, spawn more - if (QDateTime::currentMSecsSinceEpoch() - _lastMeal > 60000) { + if (!_snakes.isEmpty() && QDateTime::currentMSecsSinceEpoch() - _lastMeal > 60000) { _lastMeal = QDateTime::currentMSecsSinceEpoch(); addFood(); } @@ -424,7 +424,7 @@ void GameCore::addSnake() int x = qrand() % _width; int y = qrand() % _height; if (FIELD(x, y)->isFree()) { - if (qrand() % 2 == 0) { + if (_snakes.count() <= _balls.count()) { qDebug() << "Adding Snake at" << x << y; _snakes.append(new Snake(x, y)); } else { -- cgit v1.2.3-55-g7522