Layer Shell Qt and QWidgets

I was trying to write a QWidgets application, but I can’t make it to work with Layer Shell Qt.

I have gotten the test copy-pasted from the repo to work:

MyPaintWindow* test = new MyPaintWindow();
auto layer = LayerShellQt::Window::get(test);
layer->setLayer(LayerShellQt::Window::LayerTop)
test->show

But I can’t find a way to use it with a QWidget: I’ve tried a ton of flavors of this, and always end up with either a normal window or no window at all.

QWindow* window = new QWindow();
QPushButton* widget = new QPushButton("Hello Layer!");
QPushButton::createWindowContainer(window, widget);
auto layer = LayerShellQt::Window::get(window);
layer->setLayer(LayerShellQt::Window::LayerTop)
widget->show

So, the my approach is probably wrong here, but I can’t seem to find any helpful documentation.

When you have a toplevel QWidget its QWindow can be retrieved with QWidget::windowHandle()

So in your case probably something like

QPushButton* widget = new QPushButton("Hello Layer!");
auto layer = LayerShellQt::Window::get(widget->windowHandle());
layer->setLayer(LayerShellQt::Window::LayerTop)
widget->show();

widget::windowHandle() retruns null before the widget is shown.

widget->show();
widget->hide();
auto layer = LayerShellQt::Window::get(widget);
widget->show();

Works, but it looks like a hack.

In this case you likely don’t need the hide and second show.

QWidget::show() only requests for the window to be shown, it won’t actually happen until the event loop runs again.

Without the hide and the second show, I get a regular window, and qt.qpa.wayland: Cannot set shell integration while there's already a shell surface created printed to stderr.

You could try QWidget::ensurePolished() or QWidget::createWinId() instead of the show/hide combination before accessing the windowHandle()

widget->createWinId();
auto layer = LayerShellQt::Window::get(widget);
widget->show();

Worked, thanks.