LINUX.ORG.RU

Атрибуты «невидимого» окна в Wayland и рендеринг html в pixmap

 , ,


0

2

Вопрос 1

Можно ли средствами Qt отобразить окно так, чтоб его не увидел пользователь и проигнорировал WM?


Пояснение к вопросу

Недавно я поймал баг в Dolphin: при генерации превьюшек для html-файлов появляются ненужные окна, которые захватывают фокус и таким образом мешают работать (в отчёте по ссылке имеется видео). Если файлов в каталоге много, то это происходит долго и парализует всю DE, и единственный выход — так или иначе закрыть dolphin, поймав момент. Важно, что происходит это только в Wayland-сессии. В Xorg ничего такого нет.

Если я правильно понял (а я понятия не имею, как работает KDE и Qt), генерация изображения происходит в плагине, который предоставляет Konqueror. Видимо, это его самое сердце: https://github.com/KDE/konqueror/blob/56c8860135e64a04235fc44bb609408847c0ca2c/plugins/webarchiver/thumbnailer/webarchivecreator.cpp#L91

Суть метода, как я понял, такова (убрал лишнее и раскрыл ifdef’ы):

    QWebEngineView view;

    // ...

    view.load(indexUrl);

    // ...

    view.setAttribute(Qt::WA_ShowWithoutActivating);
    view.setAttribute(Qt::WA_OutsideWSRange);
    view.setWindowFlags(view.windowFlags()|Qt::BypassWindowManagerHint|Qt::FramelessWindowHint);
    view.move(5000, 5000);
    view.show();

    //...
    QPixmap pix(pixSize);
    // ...

    view.render(&pix);					// render the view into the pixmap
    view.hide();					// finished with the view and page
    // ...

То есть формируется окно далеко за пределами разрешения монитора (хотя по нынешним временам не очень-то далеко), там всё рисуется, потом окно убирается.


Вопрос 1.1

Правильно ли я понимаю, что в Wayland игнорируются атрибуты WA_ShowWithoutActivating, BypassWindowManagerHint и метод move? Я слышал, что в Wayland нельзя отобразить окно там, где хочет приложение.


Вопрос 2

Как реализовать рендеринг html в файл, минуя экран, средствами Qt в Wayland?

Этот вопрос мучает не только меня, как оказалось, хотя в том случае Wayland прямо не упоминается, но драма примерно такая же.


Заключение

Понятно, что, во-первых, превью html-файлов — не слишком нужная вещь, во-вторых, можно (наверное) принудительно скрывать эти лишние окна с помощью настроек kwin. Но, во-первых, мне просто интересно, а во-вторых, автор приложения не может гарантировать, что работает именно в kwin.



Последнее исправление: knovich (всего исправлений: 1)

Если файлов в каталоге много, то это происходит долго и парализует всю DE. Важно, что происходит это только в Wayland-сессии.

так это уязвимость, эксплуатируется так: отправляем жертве архив с миллиардом маленьких одинаковых html внутри - хорошо пожмет, жертва его распаковывает и подвешивает себе комп. Заводите CVE и пусть сообщество правит.

borisych ★★★★★
()
Ответ на: комментарий от borisych

так это уязвимость, эксплуатируется так: отправляем жертве архив с миллиардом маленьких одинаковых html внутри - хорошо пожмет, жертва его распаковывает и подвешивает себе комп.

Можно просто zip-бомбу послать тогда уж.

hateyoufeel ★★★★★
()
Ответ на: комментарий от borisych

Строго говоря, DE работает, на клавиатуру отзывается, так что можно переключиться в tty и прибить процесс. Просто окно постоянно теряет фокус.

Я неправильно применил термин «парализует». Исправил.

knovich
() автор топика
Последнее исправление: knovich (всего исправлений: 1)

Как реализовать рендеринг html в файл, минуя экран, средствами Qt в Wayland?

Можно, например, запустить генератор превьюшек с QT_QPA_PLATFORM=offscreen, или программно настроить так же (хотя это надо делать до старта Qt-приложения, вряд ли возможно). Тогда окно в принципе не попадёт в отрисовку.

Ja-Ja-Hey-Ho ★★★★★
()
Последнее исправление: Ja-Ja-Hey-Ho (всего исправлений: 1)

Вот так пофиксилось:

diff --git a/thumbnail/thumbnail.cpp b/thumbnail/thumbnail.cpp
index 7e2a9f2f3..e744078a5 100644
--- a/thumbnail/thumbnail.cpp
+++ b/thumbnail/thumbnail.cpp
@@ -103,6 +103,9 @@ extern "C" Q_DECL_EXPORT int kdemain(int argc, char **argv)
     // need QGuiApplication
     qunsetenv("SESSION_MANAGER");

+    // Hide plugin window on Wayland, just in case...
+    qputenv("QT_QPA_PLATFORM", "offscreen");
+
     // Some thumbnail plugins use QWidget classes for the rendering,
     // so use QApplication here, not just QGuiApplication
     QApplication app(argc, argv);

Там какая-то ругань в консоли, но вроде ничего страшного. Патч для kio-extras, т.е. надо его пересобрать и подложить пересобранный thumbnail.so в /usr.

Ja-Ja-Hey-Ho ★★★★★
()
Ответ на: комментарий от Ja-Ja-Hey-Ho

Ух ты, круто! У меня вроде тоже работает. Что теперь делать, надо им какой-то merge request присылать?

Кстати, правильно я понимаю, что для того, чтобы собрать отдельно thumbnail.so, нужно сначала сделать cmake -B <build_dir> -S <kio-extras_src_dir>, а потом cd <build_dir>;make kio_thumbnail и забрать готовый из <build_dir>/bin (ну если не пересобирать весь пакет kio-extras)? Я этот способ нащупал, но не уверен, что он правильный, я раньше не собирал ничего по отдельности из чужих исходников, только make и make install делал.

knovich
() автор топика
Последнее исправление: knovich (всего исправлений: 1)
Ответ на: комментарий от Ja-Ja-Hey-Ho

Мне, кстати, кажется, что это правильное и элегантное решение проблемы в принципе, ведь генератор превьюшек не должен ни в коем случае показывать окна, и таким образом мы спасаемся от плохо написанных плагинов.

knovich
() автор топика
Ответ на: комментарий от knovich

У меня вроде тоже работает. Что теперь делать, надо им какой-то merge request присылать?

Да.

Кстати, правильно я понимаю, что для того, чтобы собрать отдельно thumbnail.so, нужно сначала сделать…

Скорее всего правильно. Мне было лень разбираться и я пересобирал целиком, а потом просто руками копировал.

Ja-Ja-Hey-Ho ★★★★★
()
Ответ на: комментарий от knovich

Вот кстати что пишут по поводу offscreen в документации:

By using the «offscreen» platform plugin (-platform offscreen) it’s possible to have tests that use QWidget or QWindow run without showing anything on the screen. Currently the offscreen platform plugin is only fully supported on X11.

https://doc.qt.io/qt-6/qtest-overview.html#testing-options

Правда нигде не указано, что значит «fully supported». Видимо только идти читать исходники :)

Ja-Ja-Hey-Ho ★★★★★
()
Ответ на: комментарий от Ja-Ja-Hey-Ho

У меня вроде тоже работает. Что теперь делать, надо им какой-то merge request присылать?

Да.

А кто это будет делать? У меня лапки, я никогда даже гитом не пользовался для совместной разработки. Я могу попробовать, но спрашиваю разрешения, потому что это же не я фикс придумал. Могу им написать в багтрекер, изложить, что вот умный человек придумал решение. Как принято поступать?

knovich
() автор топика
Ответ на: комментарий от knovich

Я могу попробовать, но спрашиваю разрешения, потому что это же не я фикс придумал.

Да я только за, патч-то не сложный. Заодно попробуешь мердж-реквесты отправлять, там не сложно, процесс описан.

Пока можно просто патч с описанием приаттачить к репорту, мейнтенер, думаю, подскажет.

Ja-Ja-Hey-Ho ★★★★★
()
Последнее исправление: Ja-Ja-Hey-Ho (всего исправлений: 1)
Ответ на: комментарий от Ja-Ja-Hey-Ho

Короче, там какой-то удивительный мир с этим offscreen. Сначала он не хотел использовать системную тему иконок, потом мне подсказали, как заставить его это сделать с помощью недокументированных API, а теперь я случайно заметил, что он как-то болезненно реагирует на определённые действия: https://invent.kde.org/network/kio-extras/-/merge_requests/412#note_1144042 https://invent.kde.org/network/kio-extras/-/merge_requests/415#note_1146707

knovich
() автор топика