Compare commits

...

3 Commits

Author SHA1 Message Date
dd76feea81 Add Window::screenConfiguration() shim
This shim is for 6.6 to maintain compatibility with previous versions.
2026-01-20 14:35:22 +02:00
430ad3630f Allow specifying explicit desired screen
If the window position is not specified, which is a reasonable thing to
do when using the layer shell protocol, setWidth() and setHeight() can
unintentionally change the screen() to the wrong one.

This change adds a setScreen() function so it's harder to shoot
yourself in the foot while using the layer shell protocol.
2026-01-20 14:12:23 +02:00
68df285294 Update version for new release 6.6.80 2026-01-13 21:58:51 +05:30
4 changed files with 120 additions and 19 deletions

View File

@ -4,7 +4,7 @@
cmake_minimum_required(VERSION 3.16) cmake_minimum_required(VERSION 3.16)
project(layershellqt) project(layershellqt)
set(PROJECT_VERSION "6.5.90") set(PROJECT_VERSION "6.6.80")
set(PROJECT_VERSION_MAJOR 6) set(PROJECT_VERSION_MAJOR 6)
set(CMAKE_C_STANDARD 99) set(CMAKE_C_STANDARD 99)

View File

@ -11,6 +11,7 @@
#include <QPlatformSurfaceEvent> #include <QPlatformSurfaceEvent>
#include <QPointer> #include <QPointer>
#include <mutex>
#include <optional> #include <optional>
#include <QtWaylandClient/private/qwaylandwindow_p.h> #include <QtWaylandClient/private/qwaylandwindow_p.h>
@ -34,7 +35,8 @@ public:
Window::Layer layer = Window::LayerTop; Window::Layer layer = Window::LayerTop;
QMargins margins; QMargins margins;
QSize desiredSize = QSize(0, 0); QSize desiredSize = QSize(0, 0);
Window::ScreenConfiguration screenConfiguration = Window::ScreenFromQWindow; QPointer<QScreen> screen;
bool wantsToBeOnActiveScreen = false;
bool closeOnDismissed = true; bool closeOnDismissed = true;
bool activateOnShow = true; bool activateOnShow = true;
}; };
@ -152,14 +154,73 @@ Window::Layer Window::layer() const
return d->layer; return d->layer;
} }
#if LAYERSHELLQTINTERFACE_BUILD_DEPRECATED_SINCE(6, 6)
Window::ScreenConfiguration Window::screenConfiguration() const Window::ScreenConfiguration Window::screenConfiguration() const
{ {
return d->screenConfiguration; if (wantsToBeOnActiveScreen()) {
return ScreenFromCompositor;
} else {
// If an explicit screen is set, it's quite inaccurate but it should be fine.
return ScreenFromQWindow;
}
} }
void Window::setScreenConfiguration(Window::ScreenConfiguration screenConfiguration) void Window::setScreenConfiguration(ScreenConfiguration screenConfiguration)
{ {
d->screenConfiguration = screenConfiguration; static std::once_flag deprecationFlag;
std::call_once(deprecationFlag, []() {
qWarning() << "LayerShellQt.Window.screenConfiguration is deprecated use screen and wantsToBeOnActiveScreen instead";
});
if (screenConfiguration == ScreenFromCompositor) {
setWantsToBeOnActiveScreen(true);
} else {
setWantsToBeOnActiveScreen(false);
setScreen(nullptr);
}
}
#endif
void Window::setWantsToBeOnActiveScreen(bool set)
{
if (d->wantsToBeOnActiveScreen == set) {
return;
}
d->wantsToBeOnActiveScreen = set;
if (d->wantsToBeOnActiveScreen && d->screen) {
d->screen = nullptr;
Q_EMIT screenChanged();
}
Q_EMIT wantsToBeOnActiveScreenChanged();
}
bool Window::wantsToBeOnActiveScreen() const
{
return d->wantsToBeOnActiveScreen;
}
void Window::setScreen(QScreen *screen)
{
if (d->screen == screen) {
return;
}
d->screen = screen;
if (d->screen && d->wantsToBeOnActiveScreen) {
d->wantsToBeOnActiveScreen = false;
Q_EMIT wantsToBeOnActiveScreenChanged();
}
Q_EMIT screenChanged();
}
QScreen *Window::screen() const
{
return d->screen;
} }
bool Window::closeOnDismissed() const bool Window::closeOnDismissed() const

View File

@ -27,8 +27,12 @@ class LAYERSHELLQT_EXPORT Window : public QObject
Q_PROPERTY(qint32 exclusionZone READ exclusionZone WRITE setExclusiveZone NOTIFY exclusionZoneChanged) Q_PROPERTY(qint32 exclusionZone READ exclusionZone WRITE setExclusiveZone NOTIFY exclusionZoneChanged)
Q_PROPERTY(Layer layer READ layer WRITE setLayer NOTIFY layerChanged) Q_PROPERTY(Layer layer READ layer WRITE setLayer NOTIFY layerChanged)
Q_PROPERTY(KeyboardInteractivity keyboardInteractivity READ keyboardInteractivity WRITE setKeyboardInteractivity NOTIFY keyboardInteractivityChanged) Q_PROPERTY(KeyboardInteractivity keyboardInteractivity READ keyboardInteractivity WRITE setKeyboardInteractivity NOTIFY keyboardInteractivityChanged)
Q_PROPERTY(ScreenConfiguration screenConfiguration READ screenConfiguration WRITE setScreenConfiguration)
Q_PROPERTY(bool activateOnShow READ activateOnShow WRITE setActivateOnShow) Q_PROPERTY(bool activateOnShow READ activateOnShow WRITE setActivateOnShow)
Q_PROPERTY(bool wantsToBeOnActiveScreen READ wantsToBeOnActiveScreen WRITE setWantsToBeOnActiveScreen NOTIFY wantsToBeOnActiveScreenChanged)
Q_PROPERTY(QScreen *screen READ screen WRITE setScreen NOTIFY screenChanged)
#if LAYERSHELLQTINTERFACE_ENABLE_DEPRECATED_SINCE(6, 6)
Q_PROPERTY(ScreenConfiguration screenConfiguration READ screenConfiguration WRITE setScreenConfiguration)
#endif
public: public:
~Window() override; ~Window() override;
@ -64,17 +68,6 @@ public:
}; };
Q_ENUM(KeyboardInteractivity) Q_ENUM(KeyboardInteractivity)
/**
* This enum type is used to specify which screen to place the surface on.
* ScreenFromQWindow (the default) reads QWindow::screen() while ScreenFromCompositor
* passes nil and lets the compositor decide.
*/
enum ScreenConfiguration {
ScreenFromQWindow = 0,
ScreenFromCompositor = 1,
};
Q_ENUM(ScreenConfiguration)
void setAnchors(Anchors anchor); void setAnchors(Anchors anchor);
Anchors anchors() const; Anchors anchors() const;
@ -96,8 +89,48 @@ public:
void setLayer(Layer layer); void setLayer(Layer layer);
Layer layer() const; Layer layer() const;
#if LAYERSHELLQTINTERFACE_ENABLE_DEPRECATED_SINCE(6, 6)
/**
* This enum type is used to specify which screen to place the surface on.
* ScreenFromQWindow (the default) reads QWindow::screen() while ScreenFromCompositor
* passes nil and lets the compositor decide.
*/
LAYERSHELLQTINTERFACE_DEPRECATED_VERSION(6, 6, "Use wantsToBeOnActiveScreen and screen instead")
enum ScreenConfiguration {
ScreenFromQWindow = 0,
ScreenFromCompositor = 1,
};
Q_ENUM(ScreenConfiguration)
LAYERSHELLQTINTERFACE_DEPRECATED_VERSION(6, 6, "Use wantsToBeOnActiveScreen and screen instead")
void setScreenConfiguration(ScreenConfiguration screenConfiguration); void setScreenConfiguration(ScreenConfiguration screenConfiguration);
LAYERSHELLQTINTERFACE_DEPRECATED_VERSION(6, 6, "Use wantsToBeOnActiveScreen and screen instead")
ScreenConfiguration screenConfiguration() const; ScreenConfiguration screenConfiguration() const;
#endif
/**
* Indicates whether the layer shell surface should be placed on the active screen based on @a set.
*
* The active screen depends on the compositor policies.
*
* If the screen() is @c null and the wantsToBeOnActiveScreen() is @c false, then the
* QWindow::screen() will be used to decide what screen the layer shell surface should be placed on.
*
* The screen() will be reset if @a set is @c true.
*/
void setWantsToBeOnActiveScreen(bool set);
bool wantsToBeOnActiveScreen() const;
/**
* Indicates that the layer shell surface should be placed on the specified @a screen.
*
* If the screen() is @c null and the wantsToBeOnActiveScreen() is @c false, then the
* QWindow::screen() will be used to decide what screen the layer shell surface should be placed on.
*
* The wantsToBeOnActiveScreen() will be reset to @c false after calling this function.
*/
void setScreen(QScreen *screen);
QScreen *screen() const;
/** /**
* Sets a string based identifier for this window. * Sets a string based identifier for this window.
@ -148,6 +181,8 @@ Q_SIGNALS:
void desiredSizeChanged(); void desiredSizeChanged();
void keyboardInteractivityChanged(); void keyboardInteractivityChanged();
void layerChanged(); void layerChanged();
void wantsToBeOnActiveScreenChanged();
void screenChanged();
private: private:
void initializeShell(); void initializeShell();

View File

@ -27,8 +27,13 @@ QWaylandLayerSurface::QWaylandLayerSurface(QWaylandLayerShellIntegration *shell,
, m_window(window) , m_window(window)
{ {
wl_output *output = nullptr; wl_output *output = nullptr;
if (m_interface->screenConfiguration() == Window::ScreenFromQWindow) { if (!m_interface->wantsToBeOnActiveScreen()) {
auto waylandScreen = dynamic_cast<QtWaylandClient::QWaylandScreen *>(window->window()->screen()->handle()); QScreen *desiredScreen = m_interface->screen();
if (!desiredScreen) {
desiredScreen = window->window()->screen();
}
auto waylandScreen = dynamic_cast<QtWaylandClient::QWaylandScreen *>(desiredScreen->handle());
// Qt will always assign a screen to a window, but if the compositor has no screens available a dummy QScreen object is created // Qt will always assign a screen to a window, but if the compositor has no screens available a dummy QScreen object is created
// this will not cast to a QWaylandScreen // this will not cast to a QWaylandScreen
if (!waylandScreen) { if (!waylandScreen) {