Choosing startup screen in Weston + Wayland
-
Hello everyone!
Does anyone have issues with the Wayland compositor? Here I have a Linux + Weston + Wayland machine with a small integrated LCD display (800x480) and an external HDMI monitor (1920x1080).
My goal is to programmatically select the screen on which showing a QFrame, but no matter what I do it appears on the main display. Here's an example of my attempts://Start application on selected screen bool Manager::StartOnScreen(int screenIdx) { _desktopWidget = QApplication::desktop(); //Check if requested screen is available if(screenIdx >= _desktopWidget->screenCount()) { qDebug() << "Screen index out of range"; return false; } QWidget* screen = _desktopWidget->screen(screenIdx); QFrame* mainFrame = new QFrame(); //Set frame color if(screenIdx == 0) mainFrame->setStyleSheet("background-color:rgb(0, 0, 254);"); else mainFrame->setStyleSheet("background-color:rgb(254, 0, 0);"); int width = screen->geometry().width(); int height = screen->geometry().height(); int x = screen->geometry().x(); int y = screen->geometry().y(); qDebug() << "Screen config #" + QString::number(screenIdx) + ": position=" + QString::number(x) + "x" + QString::number(y) + " size=" +QString::number(width) + "x" + QString::number(height); //Set frame screen and geometry mainFrame->setGeometry(screen->geometry()); //Show the frame (windowed) mainFrame->show(); //Show the frame (fullscreen) //mainFrame->showFullScreen(); //Try to move the frame with setScreen //mainFrame->windowHandle()->setScreen(qApp->screens().at(screenIdx)); return true; }
-
Hi, I have the same problem. My goal is to show two Qt programs (Qt5.14 Widget) on targeted screens. I used two HDMI display of the same resolution for test purpose. Here is the result of the experiment. By default, Weston desktop appears on each display.
[platform=wayland]
two screens detected. QGuiApplication::screens().size() works.
cannot show a widget in a selected screen. It shows up in a main screen.
setScreen() is executed, but has no effect.
cannot move widget across screens (can do it with a mouse. but not by program).
setGeometry() does not work across the screens.[platform=xcb] using Xwayland
same as above except that setGeometry() can be used to move a widget from one screen to the other screen.[other findings]
showFullScreen is only effective on main screen.
main screen seems to be changed by mouse click.The control of multiple screens is not a special requirement on embedded systems. We used platform=eglfs before, and that was fine. Unfortunately, new platform (i.MX8 series) only supports Wayland and XWayland, and we do not have a good/clean solution. If anyone has a better idea, please let us know.
-
// sample program #1 - use setGeometry to move a widget from one screen to the other. (it works if platform=xcb)
#include "mainwindow.h"
#include <QApplication>
#include <QScreen>
#include <QDebug>
#include <QLabel>// test to show QLabel on two screens. setGeometry
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QLabel label0, label1;
int width[3], height[3];
int num_of_screens;// check multiple screens
QList <QScreen*> screens = QGuiApplication::screens();
num_of_screens = screens.size();
qDebug() << "the number of display: " << num_of_screens;for (int i = 0; i < screens.size(); i++) {
width[i] = screens[i]->geometry().width();
height[i] = screens[i]->geometry().height();
auto name = screens[i]->name();
qDebug() << "[" << i << " " << name << "]" <<
width[i] << " x " << height[i];
}label0.setText(screens[0]->name());
label0.setAlignment(Qt::AlignCenter);label0.setGeometry(0, 0, width[0], height[0]);
if (num_of_screens >= 2) {
qDebug() << "moving the second window to the second display";
label1.setText(screens[1]->name());
label1.setAlignment(Qt::AlignCenter);
label1.setGeometry(width[0], (height[0] - height[1])/2 , width[1], height[1]);
label1.setStyleSheet("background-color:yellow;");
label1.show();
} else {
qDebug() << "moving the first window to the half of the first screen";
label0.setGeometry(width[0]/2, (height[0] - height[1])/2 , width[1], height[1]);
}label0.setStyleSheet("background-color:blue;");
label0.showFullScreen();
// label0.show();return app.exec();
} -
// sample program #2 - use setScreen to show a widget on selected screen. (it does not work in Wayland/Xwayland)
#include "mainwindow.h"
#include <QApplication>
#include <QScreen>
#include <QDebug>
#include <QDesktopWidget>
#include <QWindow>
#include <QLabel>// test to show QLabel on two screens. use SetScreen
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
int width[3], height[3];
int num_of_screens;// check multiple screens
QList <QScreen*> screens = QGuiApplication::screens();
num_of_screens = screens.size();
qDebug() << "the number of display: " << num_of_screens;for (int i = 0; i < screens.size(); i++) {
width[i] = screens[i]->geometry().width();
height[i] = screens[i]->geometry().height();
auto name = screens[i]->name();
qDebug() << "[" << i << " " << name << "]" <<
width[i] << " x " << height[i];
}// show has to proceed setScreen
QLabel* label0 = new QLabel();
label0->show();
label0->windowHandle()->setScreen(screens[0]);
label0->setText(screens[0]->name());
label0->setAlignment(Qt::AlignCenter);
label0->setStyleSheet("background-color:blue;");
label0->setGeometry(0, 0, width[0], height[0]);
label0->hide();
label0->show();if (num_of_screens >= 2) {
QLabel* label1 = new QLabel();
label1->show();
label1->windowHandle()->setScreen(screens[1]);
label1->setText(screens[1]->name());
label1->setAlignment(Qt::AlignCenter);
label1->setStyleSheet("background-color:yellow;");
label1->setGeometry(0, 0, width[1], height[1]);
label1->hide();
label1->show();
}return app.exec();
}