mirror of
https://invent.kde.org/plasma/layer-shell-qt.git
synced 2025-11-23 02:02:43 -05:00
Compare commits
2 Commits
work/zzag/
...
work/zzag/
| Author | SHA1 | Date | |
|---|---|---|---|
| e9b257954b | |||
| 7629761b71 |
@ -17,6 +17,49 @@
|
||||
|
||||
using namespace LayerShellQt;
|
||||
|
||||
Margin::Margin()
|
||||
: m_value(0)
|
||||
{
|
||||
}
|
||||
|
||||
Margin::Margin(int pixels)
|
||||
: m_value(pixels)
|
||||
{
|
||||
}
|
||||
|
||||
Margin::Margin(qreal percents)
|
||||
: m_value(percents)
|
||||
{
|
||||
}
|
||||
|
||||
Margin Margin::fromPixels(int pixels)
|
||||
{
|
||||
return Margin(pixels);
|
||||
}
|
||||
|
||||
Margin Margin::fromPercents(qreal percents)
|
||||
{
|
||||
return Margin(percents);
|
||||
}
|
||||
|
||||
std::optional<int> Margin::pixels() const
|
||||
{
|
||||
if (std::holds_alternative<int>(m_value)) {
|
||||
return std::get<int>(m_value);
|
||||
} else {
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<qreal> Margin::percents() const
|
||||
{
|
||||
if (std::holds_alternative<qreal>(m_value)) {
|
||||
return std::get<qreal>(m_value);
|
||||
} else {
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
class LayerShellQt::WindowPrivate
|
||||
{
|
||||
public:
|
||||
@ -32,10 +75,12 @@ public:
|
||||
Window::Anchor exclusiveEdge = Window::AnchorNone;
|
||||
Window::KeyboardInteractivity keyboardInteractivity = Window::KeyboardInteractivityOnDemand;
|
||||
Window::Layer layer = Window::LayerTop;
|
||||
QMargins margins;
|
||||
Margin leftMargin;
|
||||
Margin topMargin;
|
||||
Margin rightMargin;
|
||||
Margin bottomMargin;
|
||||
QSize desiredSize = QSize(0, 0);
|
||||
QPointer<QScreen> desiredScreen;
|
||||
bool desiredActiveScreen = false;
|
||||
Window::ScreenConfiguration screenConfiguration = Window::ScreenFromQWindow;
|
||||
bool closeOnDismissed = true;
|
||||
bool activateOnShow = true;
|
||||
};
|
||||
@ -90,15 +135,74 @@ Window::Anchor Window::exclusiveEdge() const
|
||||
|
||||
void Window::setMargins(const QMargins &margins)
|
||||
{
|
||||
if (d->margins != margins) {
|
||||
d->margins = margins;
|
||||
Q_EMIT marginsChanged();
|
||||
}
|
||||
setLeftMargin(Margin::fromPixels(margins.left()));
|
||||
setTopMargin(Margin::fromPixels(margins.top()));
|
||||
setRightMargin(Margin::fromPixels(margins.right()));
|
||||
setBottomMargin(Margin::fromPixels(margins.bottom()));
|
||||
}
|
||||
|
||||
QMargins Window::margins() const
|
||||
{
|
||||
return d->margins;
|
||||
return QMargins(d->leftMargin.pixels().value_or(0),
|
||||
d->topMargin.pixels().value_or(0),
|
||||
d->rightMargin.pixels().value_or(0),
|
||||
d->bottomMargin.pixels().value_or(0));
|
||||
}
|
||||
|
||||
void Window::setLeftMargin(Margin margin)
|
||||
{
|
||||
if (d->leftMargin != margin) {
|
||||
d->leftMargin = margin;
|
||||
Q_EMIT leftMarginChanged();
|
||||
Q_EMIT marginsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
Margin Window::leftMargin() const
|
||||
{
|
||||
return d->leftMargin;
|
||||
}
|
||||
|
||||
void Window::setTopMargin(Margin margin)
|
||||
{
|
||||
if (d->topMargin != margin) {
|
||||
d->topMargin = margin;
|
||||
Q_EMIT topMarginChanged();
|
||||
Q_EMIT marginsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
Margin Window::topMargin() const
|
||||
{
|
||||
return d->topMargin;
|
||||
}
|
||||
|
||||
void Window::setRightMargin(Margin margin)
|
||||
{
|
||||
if (d->rightMargin != margin) {
|
||||
d->rightMargin = margin;
|
||||
Q_EMIT rightMarginChanged();
|
||||
Q_EMIT marginsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
Margin Window::rightMargin() const
|
||||
{
|
||||
return d->rightMargin;
|
||||
}
|
||||
|
||||
void Window::setBottomMargin(Margin margin)
|
||||
{
|
||||
if (d->bottomMargin != margin) {
|
||||
d->bottomMargin = margin;
|
||||
Q_EMIT bottomMarginChanged();
|
||||
Q_EMIT marginsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
Margin Window::bottomMargin() const
|
||||
{
|
||||
return d->bottomMargin;
|
||||
}
|
||||
|
||||
void Window::setDesiredSize(const QSize &size)
|
||||
@ -153,46 +257,14 @@ Window::Layer Window::layer() const
|
||||
return d->layer;
|
||||
}
|
||||
|
||||
void Window::setDesiredActiveScreen(bool set)
|
||||
Window::ScreenConfiguration Window::screenConfiguration() const
|
||||
{
|
||||
if (d->desiredActiveScreen == set) {
|
||||
return;
|
||||
}
|
||||
|
||||
d->desiredActiveScreen = set;
|
||||
|
||||
if (d->desiredActiveScreen && d->desiredScreen) {
|
||||
d->desiredScreen = nullptr;
|
||||
Q_EMIT desiredScreenChanged();
|
||||
}
|
||||
|
||||
Q_EMIT desiredActiveScreenChanged();
|
||||
return d->screenConfiguration;
|
||||
}
|
||||
|
||||
bool Window::desiredActiveScreen() const
|
||||
void Window::setScreenConfiguration(Window::ScreenConfiguration screenConfiguration)
|
||||
{
|
||||
return d->desiredActiveScreen;
|
||||
}
|
||||
|
||||
void Window::setDesiredScreen(QScreen *screen)
|
||||
{
|
||||
if (d->desiredScreen == screen) {
|
||||
return;
|
||||
}
|
||||
|
||||
d->desiredScreen = screen;
|
||||
|
||||
if (d->desiredScreen && d->desiredActiveScreen) {
|
||||
d->desiredActiveScreen = false;
|
||||
Q_EMIT desiredActiveScreenChanged();
|
||||
}
|
||||
|
||||
Q_EMIT desiredScreenChanged();
|
||||
}
|
||||
|
||||
QScreen *Window::desiredScreen() const
|
||||
{
|
||||
return d->desiredScreen;
|
||||
d->screenConfiguration = screenConfiguration;
|
||||
}
|
||||
|
||||
bool Window::closeOnDismissed() const
|
||||
|
||||
@ -18,6 +18,34 @@ namespace LayerShellQt
|
||||
{
|
||||
class WindowPrivate;
|
||||
|
||||
/**
|
||||
* The Margin type provides a way to specify how far a layer surface should be away from a screen edge.
|
||||
*
|
||||
* A margin can have an absolute value or a percent value. An absolute value indicates the distance
|
||||
* in pixels. A percent value indicates the distance as a percentage of the output size, for example
|
||||
* this can be used to tell the compositor that the surface should be one third of the output height from
|
||||
* a screen edge, etc.
|
||||
*/
|
||||
class LAYERSHELLQT_EXPORT Margin
|
||||
{
|
||||
public:
|
||||
static Margin fromPixels(int pixels);
|
||||
static Margin fromPercents(qreal percents);
|
||||
|
||||
Margin();
|
||||
|
||||
std::optional<int> pixels() const;
|
||||
std::optional<qreal> percents() const;
|
||||
|
||||
auto operator<=>(const Margin &other) const = default;
|
||||
|
||||
private:
|
||||
Margin(int pixels);
|
||||
Margin(qreal percents);
|
||||
|
||||
std::variant<int, qreal> m_value;
|
||||
};
|
||||
|
||||
class LAYERSHELLQT_EXPORT Window : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -27,9 +55,8 @@ class LAYERSHELLQT_EXPORT Window : public QObject
|
||||
Q_PROPERTY(qint32 exclusionZone READ exclusionZone WRITE setExclusiveZone NOTIFY exclusionZoneChanged)
|
||||
Q_PROPERTY(Layer layer READ layer WRITE setLayer NOTIFY layerChanged)
|
||||
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 desiredActiveScreen READ desiredActiveScreen WRITE setDesiredActiveScreen NOTIFY desiredActiveScreenChanged)
|
||||
Q_PROPERTY(QScreen *desiredScreen READ desiredScreen WRITE setDesiredScreen NOTIFY desiredScreenChanged)
|
||||
|
||||
public:
|
||||
~Window() override;
|
||||
@ -65,6 +92,17 @@ public:
|
||||
};
|
||||
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);
|
||||
Anchors anchors() const;
|
||||
|
||||
@ -77,6 +115,18 @@ public:
|
||||
void setMargins(const QMargins &margins);
|
||||
QMargins margins() const;
|
||||
|
||||
void setLeftMargin(Margin margin);
|
||||
Margin leftMargin() const;
|
||||
|
||||
void setTopMargin(Margin margin);
|
||||
Margin topMargin() const;
|
||||
|
||||
void setRightMargin(Margin margin);
|
||||
Margin rightMargin() const;
|
||||
|
||||
void setBottomMargin(Margin margin);
|
||||
Margin bottomMargin() const;
|
||||
|
||||
void setDesiredSize(const QSize &size);
|
||||
QSize desiredSize() const;
|
||||
|
||||
@ -86,33 +136,8 @@ public:
|
||||
void setLayer(Layer layer);
|
||||
Layer layer() const;
|
||||
|
||||
/**
|
||||
* 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 no explicit desired screen has been specified with the setDesiredScreen() function or the layer
|
||||
* surface doesn't need to be placed on the active screen, i.e. setDesiredActiveScreen() has not
|
||||
* been called, the QWindow::screen() will be used to decide what screen the layer shell surface
|
||||
* should be placed on.
|
||||
*
|
||||
* The desiredScreen() will be reset if @a set is @c true.
|
||||
*/
|
||||
void setDesiredActiveScreen(bool set);
|
||||
bool desiredActiveScreen() const;
|
||||
|
||||
/**
|
||||
* Indicates that the layer shell surface should be placed on the specified @a screen.
|
||||
*
|
||||
* If no explicit desired screen has been specified with the setDesiredScreen() function or the layer
|
||||
* surface doesn't need to be placed on the active screen, i.e. setDesiredActiveScreen() has not
|
||||
* been called, the QWindow::screen() will be used to decide what screen the layer shell surface
|
||||
* should be placed on.
|
||||
*
|
||||
* The desiredActiveScreen() will be reset to @c false after calling this function.
|
||||
*/
|
||||
void setDesiredScreen(QScreen *screen);
|
||||
QScreen *desiredScreen() const;
|
||||
void setScreenConfiguration(ScreenConfiguration screenConfiguration);
|
||||
ScreenConfiguration screenConfiguration() const;
|
||||
|
||||
/**
|
||||
* Sets a string based identifier for this window.
|
||||
@ -160,11 +185,13 @@ Q_SIGNALS:
|
||||
void exclusionZoneChanged();
|
||||
void exclusiveEdgeChanged();
|
||||
void marginsChanged();
|
||||
void leftMarginChanged();
|
||||
void topMarginChanged();
|
||||
void rightMarginChanged();
|
||||
void bottomMarginChanged();
|
||||
void desiredSizeChanged();
|
||||
void keyboardInteractivityChanged();
|
||||
void layerChanged();
|
||||
void desiredActiveScreenChanged();
|
||||
void desiredScreenChanged();
|
||||
|
||||
private:
|
||||
void initializeShell();
|
||||
|
||||
@ -26,12 +26,7 @@ QWaylandLayerSurface::QWaylandLayerSurface(QWaylandLayerShellIntegration *shell,
|
||||
, m_window(window)
|
||||
{
|
||||
wl_output *output = nullptr;
|
||||
if (!m_interface->desiredActiveScreen()) {
|
||||
QScreen *desiredScreen = m_interface->desiredScreen();
|
||||
if (!desiredScreen) {
|
||||
window->window()->screen();
|
||||
}
|
||||
|
||||
if (m_interface->screenConfiguration() == Window::ScreenFromQWindow) {
|
||||
auto waylandScreen = dynamic_cast<QtWaylandClient::QWaylandScreen *>(window->window()->screen()->handle());
|
||||
// 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
|
||||
@ -65,9 +60,24 @@ QWaylandLayerSurface::QWaylandLayerSurface(QWaylandLayerShellIntegration *shell,
|
||||
setExclusiveEdge(m_interface->exclusiveEdge());
|
||||
});
|
||||
|
||||
setMargins(m_interface->margins());
|
||||
connect(m_interface, &Window::marginsChanged, this, [this]() {
|
||||
setMargins(m_interface->margins());
|
||||
setLeftMargin(m_interface->leftMargin());
|
||||
connect(m_interface, &Window::leftMarginChanged, this, [this]() {
|
||||
setLeftMargin(m_interface->leftMargin());
|
||||
});
|
||||
|
||||
setTopMargin(m_interface->topMargin());
|
||||
connect(m_interface, &Window::topMarginChanged, this, [this]() {
|
||||
setTopMargin(m_interface->topMargin());
|
||||
});
|
||||
|
||||
setRightMargin(m_interface->rightMargin());
|
||||
connect(m_interface, &Window::rightMarginChanged, this, [this]() {
|
||||
setRightMargin(m_interface->rightMargin());
|
||||
});
|
||||
|
||||
setBottomMargin(m_interface->bottomMargin());
|
||||
connect(m_interface, &Window::bottomMarginChanged, this, [this]() {
|
||||
setBottomMargin(m_interface->bottomMargin());
|
||||
});
|
||||
|
||||
connect(m_interface, &Window::desiredSizeChanged, this, [this]() {
|
||||
@ -164,9 +174,68 @@ void QWaylandLayerSurface::setExclusiveEdge(uint32_t edge)
|
||||
}
|
||||
}
|
||||
|
||||
void QWaylandLayerSurface::setMargins(const QMargins &margins)
|
||||
void QWaylandLayerSurface::setLeftMargin(const Margin &margin)
|
||||
{
|
||||
set_margin(margins.top(), margins.right(), margins.bottom(), margins.left());
|
||||
if (zwlr_layer_surface_v1_get_version(object()) >= 6) {
|
||||
if (const auto pixels = margin.pixels()) {
|
||||
set_left_margin_absolute(*pixels);
|
||||
} else if (const auto percents = margin.percents()) {
|
||||
set_left_margin_percents(wl_fixed_from_double(*percents));
|
||||
} else {
|
||||
qCWarning(LAYERSHELLQT) << "Unspecified left margin for" << m_window->window();
|
||||
}
|
||||
} else {
|
||||
const QMargins margins = m_interface->margins();
|
||||
set_margin(margins.top(), margins.right(), margins.bottom(), margins.left());
|
||||
}
|
||||
}
|
||||
|
||||
void QWaylandLayerSurface::setTopMargin(const Margin &margin)
|
||||
{
|
||||
if (zwlr_layer_surface_v1_get_version(object()) >= 6) {
|
||||
if (const auto pixels = margin.pixels()) {
|
||||
set_top_margin_absolute(*pixels);
|
||||
} else if (const auto percents = margin.percents()) {
|
||||
set_top_margin_percents(wl_fixed_from_double(*percents));
|
||||
} else {
|
||||
qCWarning(LAYERSHELLQT) << "Unspecified top margin for" << m_window->window();
|
||||
}
|
||||
} else {
|
||||
const QMargins margins = m_interface->margins();
|
||||
set_margin(margins.top(), margins.right(), margins.bottom(), margins.left());
|
||||
}
|
||||
}
|
||||
|
||||
void QWaylandLayerSurface::setRightMargin(const Margin &margin)
|
||||
{
|
||||
if (zwlr_layer_surface_v1_get_version(object()) >= 6) {
|
||||
if (const auto pixels = margin.pixels()) {
|
||||
set_right_margin_absolute(*pixels);
|
||||
} else if (const auto percents = margin.percents()) {
|
||||
set_right_margin_percents(wl_fixed_from_double(*percents));
|
||||
} else {
|
||||
qCWarning(LAYERSHELLQT) << "Unspecified right margin for" << m_window->window();
|
||||
}
|
||||
} else {
|
||||
const QMargins margins = m_interface->margins();
|
||||
set_margin(margins.top(), margins.right(), margins.bottom(), margins.left());
|
||||
}
|
||||
}
|
||||
|
||||
void QWaylandLayerSurface::setBottomMargin(const Margin &margin)
|
||||
{
|
||||
if (zwlr_layer_surface_v1_get_version(object()) >= 6) {
|
||||
if (const auto pixels = margin.pixels()) {
|
||||
set_bottom_margin_absolute(*pixels);
|
||||
} else if (const auto percents = margin.percents()) {
|
||||
set_bottom_margin_percents(wl_fixed_from_double(*percents));
|
||||
} else {
|
||||
qCWarning(LAYERSHELLQT) << "Unspecified bottom margin for" << m_window->window();
|
||||
}
|
||||
} else {
|
||||
const QMargins margins = m_interface->margins();
|
||||
set_margin(margins.top(), margins.right(), margins.bottom(), margins.left());
|
||||
}
|
||||
}
|
||||
|
||||
void QWaylandLayerSurface::setKeyboardInteractivity(uint32_t interactivity)
|
||||
|
||||
@ -19,6 +19,7 @@
|
||||
namespace LayerShellQt
|
||||
{
|
||||
|
||||
class Margin;
|
||||
class Window;
|
||||
|
||||
class LAYERSHELLQT_EXPORT QWaylandLayerSurface : public QtWaylandClient::QWaylandShellSurface, public QtWayland::zwlr_layer_surface_v1
|
||||
@ -38,7 +39,10 @@ public:
|
||||
void setAnchor(uint32_t anchor);
|
||||
void setExclusiveZone(int32_t zone);
|
||||
void setExclusiveEdge(uint32_t edge);
|
||||
void setMargins(const QMargins &margins);
|
||||
void setLeftMargin(const Margin &margin);
|
||||
void setTopMargin(const Margin &margin);
|
||||
void setRightMargin(const Margin &margin);
|
||||
void setBottomMargin(const Margin &margin);
|
||||
void setKeyboardInteractivity(uint32_t interactivity);
|
||||
void setLayer(uint32_t layer);
|
||||
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
THIS SOFTWARE.
|
||||
</copyright>
|
||||
|
||||
<interface name="zwlr_layer_shell_v1" version="5">
|
||||
<interface name="zwlr_layer_shell_v1" version="6">
|
||||
<description summary="create surfaces that are layers of the desktop">
|
||||
Clients can use this interface to assign the surface_layer role to
|
||||
wl_surfaces. Such surfaces are assigned to a "layer" of the output and
|
||||
@ -100,7 +100,7 @@
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="zwlr_layer_surface_v1" version="5">
|
||||
<interface name="zwlr_layer_surface_v1" version="6">
|
||||
<description summary="layer metadata interface">
|
||||
An interface that may be implemented by a wl_surface, for surfaces that
|
||||
are designed to be rendered as a layer of a stacked desktop-like
|
||||
@ -403,5 +403,83 @@
|
||||
</description>
|
||||
<arg name="edge" type="uint"/>
|
||||
</request>
|
||||
|
||||
<!-- Version 6 additions -->
|
||||
|
||||
<request name="set_left_margin_absolute" since="6">
|
||||
<description summary="set left margin in absolute pixels">
|
||||
Sets the left margin in absolute pixels.
|
||||
|
||||
The left margin specified in percents will be overwritten.
|
||||
</description>
|
||||
<arg name="margin" type="int"/>
|
||||
</request>
|
||||
|
||||
<request name="set_left_margin_percents" since="6">
|
||||
<description summary="set the left margin proportional to area width">
|
||||
Sets the left margin as a percentage of the area width. The
|
||||
margin value is a number between 0 and 1.
|
||||
|
||||
The left margin specified in absolute values will be overwritten.
|
||||
</description>
|
||||
<arg name="margin" type="fixed"/>
|
||||
</request>
|
||||
|
||||
<request name="set_top_margin_absolute" since="6">
|
||||
<description summary="set top margin in absolute pixels">
|
||||
Sets the top margin in absolute pixels.
|
||||
|
||||
The top margin specified in percents will be overwritten.
|
||||
</description>
|
||||
<arg name="margin" type="int"/>
|
||||
</request>
|
||||
|
||||
<request name="set_top_margin_percents" since="6">
|
||||
<description summary="set the top margin proportional to area width">
|
||||
Sets the top margin as a percentage of the area width. The
|
||||
margin value is a number between 0 and 1.
|
||||
|
||||
The top margin specified in absolute values will be overwritten.
|
||||
</description>
|
||||
<arg name="margin" type="fixed"/>
|
||||
</request>
|
||||
|
||||
<request name="set_right_margin_absolute" since="6">
|
||||
<description summary="set right margin in absolute pixels">
|
||||
Sets the right margin in absolute pixels.
|
||||
|
||||
The right margin specified in percents will be overwritten.
|
||||
</description>
|
||||
<arg name="margin" type="int"/>
|
||||
</request>
|
||||
|
||||
<request name="set_right_margin_percents" since="6">
|
||||
<description summary="set the right margin proportional to area width">
|
||||
Sets the right margin as a percentage of the area width. The
|
||||
margin value is a number between 0 and 1.
|
||||
|
||||
The right margin specified in absolute values will be overwritten.
|
||||
</description>
|
||||
<arg name="margin" type="fixed"/>
|
||||
</request>
|
||||
|
||||
<request name="set_bottom_margin_absolute" since="6">
|
||||
<description summary="set bottom margin in absolute pixels">
|
||||
Sets the bottom margin in absolute pixels.
|
||||
|
||||
The bottom margin specified in percents will be overwritten.
|
||||
</description>
|
||||
<arg name="margin" type="int"/>
|
||||
</request>
|
||||
|
||||
<request name="set_bottom_margin_percents" since="6">
|
||||
<description summary="set the bottom margin proportional to area width">
|
||||
Sets the bottom margin as a percentage of the area width. The
|
||||
margin value is a number between 0 and 1.
|
||||
|
||||
The bottom margin specified in absolute values will be overwritten.
|
||||
</description>
|
||||
<arg name="margin" type="fixed"/>
|
||||
</request>
|
||||
</interface>
|
||||
</protocol>
|
||||
|
||||
Reference in New Issue
Block a user