fix(qt): restore window lifecycle and improve grid artwork
Restore tray-aware close and quit confirmation, circular label covers, and missing label artist portraits. Publish artwork progressively, preload two grid rows, and skip redundant motion reports while preserving data refreshes. Include regression tests and isolated artwork benchmarks. Verified Linux build, QML checks, and scrolling smoke tests. cx
This commit is contained in:
61 files changed
+1591
-151
No files matched your search
@@ -0,0 +1,45 @@
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QEvent>
|
||||
#include <QtCore/QObject>
|
||||
#include <QtGui/QKeyEvent>
|
||||
|
||||
namespace {
|
||||
// Lifecycle commands are reserved even while a text field or mini window
|
||||
// owns focus. Qt maps ControlModifier to Command on macOS.
|
||||
class LifecycleFilter final : public QObject {
|
||||
public:
|
||||
LifecycleFilter(QObject *parent, void (*request)(bool))
|
||||
: QObject(parent), request_(request) {}
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *receiver, QEvent *event) override {
|
||||
if (receiver == QCoreApplication::instance() && event->type() == QEvent::Quit) {
|
||||
event->ignore(); // termination is pending until QML confirms
|
||||
request_(true);
|
||||
return true;
|
||||
}
|
||||
if (event->type() != QEvent::KeyPress && event->type() != QEvent::ShortcutOverride)
|
||||
return false;
|
||||
auto *key = static_cast<QKeyEvent *>(event);
|
||||
if (key->modifiers() != Qt::ControlModifier
|
||||
|| (key->key() != Qt::Key_Q && key->key() != Qt::Key_W))
|
||||
return false;
|
||||
event->accept();
|
||||
if (event->type() == QEvent::KeyPress && !key->isAutoRepeat())
|
||||
request_(key->key() == Qt::Key_Q);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
void (*request_)(bool);
|
||||
};
|
||||
}
|
||||
|
||||
extern "C" void qbz_install_lifecycle_filter(void (*request)(bool)) {
|
||||
static LifecycleFilter *filter = nullptr;
|
||||
auto *app = QCoreApplication::instance();
|
||||
if (!filter && app) {
|
||||
filter = new LifecycleFilter(app, request);
|
||||
app->installEventFilter(filter);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QEvent>
|
||||
#include <QtGui/QKeyEvent>
|
||||
#include <cassert>
|
||||
|
||||
extern "C" void qbz_install_lifecycle_filter(void (*request)(bool));
|
||||
static int quits = 0;
|
||||
static int closes = 0;
|
||||
static void request(bool quit) { quit ? ++quits : ++closes; }
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
QCoreApplication app(argc, argv);
|
||||
qbz_install_lifecycle_filter(request);
|
||||
qbz_install_lifecycle_filter(request); // no duplicate installation
|
||||
QObject focused;
|
||||
QKeyEvent override(QEvent::ShortcutOverride, Qt::Key_W, Qt::ControlModifier);
|
||||
QCoreApplication::sendEvent(&focused, &override);
|
||||
assert(override.isAccepted() && closes == 0);
|
||||
QKeyEvent close(QEvent::KeyPress, Qt::Key_W, Qt::ControlModifier);
|
||||
QCoreApplication::sendEvent(&focused, &close);
|
||||
assert(closes == 1 && quits == 0);
|
||||
QKeyEvent repeat(QEvent::KeyPress, Qt::Key_W, Qt::ControlModifier, {}, true);
|
||||
QCoreApplication::sendEvent(&focused, &repeat);
|
||||
assert(closes == 1);
|
||||
QKeyEvent unrelated(QEvent::KeyPress, Qt::Key_Q, Qt::ControlModifier | Qt::ShiftModifier);
|
||||
QCoreApplication::sendEvent(&focused, &unrelated);
|
||||
assert(quits == 0);
|
||||
QKeyEvent quit(QEvent::KeyPress, Qt::Key_Q, Qt::ControlModifier);
|
||||
QCoreApplication::sendEvent(&focused, &quit);
|
||||
assert(quits == 1);
|
||||
QEvent nativeQuit(QEvent::Quit);
|
||||
QCoreApplication::sendEvent(&app, &nativeQuit);
|
||||
assert(!nativeQuit.isAccepted() && quits == 2 && closes == 1);
|
||||
}
|
||||
Reference in new issue
Block a user