forked from quickshell/quickshell
hyprland/surface: add hyprland surface opacity support
This commit is contained in:
parent
08836ca1f3
commit
3a40174ed6
|
@ -55,9 +55,10 @@ boption(HYPRLAND " Hyprland" ON REQUIRES WAYLAND)
|
||||||
boption(HYPRLAND_IPC " Hyprland IPC" ON REQUIRES HYPRLAND)
|
boption(HYPRLAND_IPC " Hyprland IPC" ON REQUIRES HYPRLAND)
|
||||||
boption(HYPRLAND_GLOBAL_SHORTCUTS " Hyprland Global Shortcuts" ON REQUIRES HYPRLAND)
|
boption(HYPRLAND_GLOBAL_SHORTCUTS " Hyprland Global Shortcuts" ON REQUIRES HYPRLAND)
|
||||||
boption(HYPRLAND_FOCUS_GRAB " Hyprland Focus Grabbing" ON REQUIRES HYPRLAND)
|
boption(HYPRLAND_FOCUS_GRAB " Hyprland Focus Grabbing" ON REQUIRES HYPRLAND)
|
||||||
boption(I3 " I3/Sway" ON)
|
boption(HYPRLAND_SURFACE_EXTENSIONS " Hyprland Surface Extensions" ON REQUIRES HYPRLAND)
|
||||||
boption(I3_IPC " I3/Sway IPC" ON REQUIRES I3)
|
|
||||||
boption(X11 "X11" ON)
|
boption(X11 "X11" ON)
|
||||||
|
boption(I3 "I3/Sway" ON)
|
||||||
|
boption(I3_IPC " I3/Sway IPC" ON REQUIRES I3)
|
||||||
boption(SERVICE_STATUS_NOTIFIER "System Tray" ON)
|
boption(SERVICE_STATUS_NOTIFIER "System Tray" ON)
|
||||||
boption(SERVICE_PIPEWIRE "PipeWire" ON)
|
boption(SERVICE_PIPEWIRE "PipeWire" ON)
|
||||||
boption(SERVICE_MPRIS "Mpris" ON)
|
boption(SERVICE_MPRIS "Mpris" ON)
|
||||||
|
|
|
@ -77,6 +77,7 @@ qt_add_library(quickshell-wayland STATIC
|
||||||
platformmenu.cpp
|
platformmenu.cpp
|
||||||
popupanchor.cpp
|
popupanchor.cpp
|
||||||
xdgshell.cpp
|
xdgshell.cpp
|
||||||
|
util.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
# required to make sure the constructor is linked
|
# required to make sure the constructor is linked
|
||||||
|
|
|
@ -19,6 +19,11 @@ if (HYPRLAND_GLOBAL_SHORTCUTS)
|
||||||
list(APPEND HYPRLAND_MODULES Quickshell.Hyprland._GlobalShortcuts)
|
list(APPEND HYPRLAND_MODULES Quickshell.Hyprland._GlobalShortcuts)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (HYPRLAND_SURFACE_EXTENSIONS)
|
||||||
|
add_subdirectory(surface)
|
||||||
|
list(APPEND HYPRLAND_MODULES Quickshell.Hyprland._SurfaceExtensions)
|
||||||
|
endif()
|
||||||
|
|
||||||
qt_add_qml_module(quickshell-hyprland
|
qt_add_qml_module(quickshell-hyprland
|
||||||
URI Quickshell.Hyprland
|
URI Quickshell.Hyprland
|
||||||
VERSION 0.1
|
VERSION 0.1
|
||||||
|
|
|
@ -7,5 +7,6 @@ headers = [
|
||||||
"ipc/qml.hpp",
|
"ipc/qml.hpp",
|
||||||
"focus_grab/qml.hpp",
|
"focus_grab/qml.hpp",
|
||||||
"global_shortcuts/qml.hpp",
|
"global_shortcuts/qml.hpp",
|
||||||
|
"surface/qml.hpp",
|
||||||
]
|
]
|
||||||
-----
|
-----
|
||||||
|
|
26
src/wayland/hyprland/surface/CMakeLists.txt
Normal file
26
src/wayland/hyprland/surface/CMakeLists.txt
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
qt_add_library(quickshell-hyprland-surface-extensions STATIC
|
||||||
|
qml.cpp
|
||||||
|
manager.cpp
|
||||||
|
surface.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
qt_add_qml_module(quickshell-hyprland-surface-extensions
|
||||||
|
URI Quickshell.Hyprland._SurfaceExtensions
|
||||||
|
VERSION 0.1
|
||||||
|
DEPENDENCIES QtQml
|
||||||
|
)
|
||||||
|
|
||||||
|
install_qml_module(quickshell-hyprland-surface-extensions)
|
||||||
|
|
||||||
|
wl_proto(quickshell-hyprland-surface-extensions
|
||||||
|
hyprland-surface-v1
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/hyprland-surface-v1.xml"
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(quickshell-hyprland-surface-extensions PRIVATE
|
||||||
|
Qt::Quick Qt::WaylandClient Qt::WaylandClientPrivate wayland-client
|
||||||
|
)
|
||||||
|
|
||||||
|
qs_module_pch(quickshell-hyprland-surface-extensions)
|
||||||
|
|
||||||
|
target_link_libraries(quickshell PRIVATE quickshell-hyprland-surface-extensionsplugin)
|
100
src/wayland/hyprland/surface/hyprland-surface-v1.xml
Normal file
100
src/wayland/hyprland/surface/hyprland-surface-v1.xml
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<protocol name="hyprland_surface_v1">
|
||||||
|
<copyright>
|
||||||
|
Copyright © 2025 outfoxxed
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
3. Neither the name of the copyright holder nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
</copyright>
|
||||||
|
|
||||||
|
<description summary="hyprland-specific wl_surface extensions">
|
||||||
|
This protocol exposes hyprland-specific wl_surface properties.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<interface name="hyprland_surface_manager_v1" version="1">
|
||||||
|
<description summary="manager for hyprland surface objects">
|
||||||
|
This interface allows a client to create hyprland surface objects.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<request name="get_hyprland_surface">
|
||||||
|
<description summary="create a hyprland surface object">
|
||||||
|
Create a hyprland surface object for the given wayland surface.
|
||||||
|
|
||||||
|
If the wl_surface already has an associated hyprland_surface_v1 object,
|
||||||
|
even from a different manager, creation is a protocol error.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<arg name="id" type="new_id" interface="hyprland_surface_v1"/>
|
||||||
|
<arg name="surface" type="object" interface="wl_surface"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="destroy" type="destructor">
|
||||||
|
<description summary="destroy the hyprland surface manager">
|
||||||
|
Destroy the surface manager.
|
||||||
|
This does not destroy existing surface objects.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<enum name="error">
|
||||||
|
<entry name="already_constructed" value="0" summary="wl_surface already has a hyprland surface object"/>
|
||||||
|
</enum>
|
||||||
|
</interface>
|
||||||
|
|
||||||
|
<interface name="hyprland_surface_v1" version="1">
|
||||||
|
<description summary="hyprland-specific wl_surface properties">
|
||||||
|
This interface allows access to hyprland-specific properties of a wl_surface.
|
||||||
|
|
||||||
|
Once the wl_surface has been destroyed, the hyprland surface object must be
|
||||||
|
destroyed as well. All other operations are a protocol error.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<request name="set_opacity">
|
||||||
|
<description summary="set the overall opacity of the surface">
|
||||||
|
Sets a multiplier for the overall opacity of the surface.
|
||||||
|
This multiplier applies to visual effects such as blur behind the surface
|
||||||
|
in addition to the surface's content.
|
||||||
|
|
||||||
|
The default value is 1.0.
|
||||||
|
Setting a value outside of the range 0.0 - 1.0 (inclusive) is a protocol error.
|
||||||
|
Does not take effect until wl_surface.commit is called.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<arg name="opacity" type="fixed"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="destroy" type="destructor">
|
||||||
|
<description summary="destroy the hyprland surface interface">
|
||||||
|
Destroy the hyprland surface object, resetting properties provided
|
||||||
|
by this interface to their default values on the next wl_surface.commit.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<enum name="error">
|
||||||
|
<entry name="no_surface" value="0" summary="wl_surface was destroyed"/>
|
||||||
|
<entry name="out_of_range" value="1" summary="given opacity was not in the range 0.0 - 1.0 (inclusive)"/>
|
||||||
|
</enum>
|
||||||
|
</interface>
|
||||||
|
</protocol>
|
24
src/wayland/hyprland/surface/manager.cpp
Normal file
24
src/wayland/hyprland/surface/manager.cpp
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#include "manager.hpp"
|
||||||
|
|
||||||
|
#include <private/qwaylandwindow_p.h>
|
||||||
|
#include <qwaylandclientextension.h>
|
||||||
|
|
||||||
|
#include "surface.hpp"
|
||||||
|
|
||||||
|
namespace qs::hyprland::surface::impl {
|
||||||
|
|
||||||
|
HyprlandSurfaceManager::HyprlandSurfaceManager(): QWaylandClientExtensionTemplate(1) {
|
||||||
|
this->initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
HyprlandSurface*
|
||||||
|
HyprlandSurfaceManager::createHyprlandExtension(QtWaylandClient::QWaylandWindow* surface) {
|
||||||
|
return new HyprlandSurface(this->get_hyprland_surface(surface->surface()));
|
||||||
|
}
|
||||||
|
|
||||||
|
HyprlandSurfaceManager* HyprlandSurfaceManager::instance() {
|
||||||
|
static auto* instance = new HyprlandSurfaceManager();
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace qs::hyprland::surface::impl
|
22
src/wayland/hyprland/surface/manager.hpp
Normal file
22
src/wayland/hyprland/surface/manager.hpp
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <private/qwaylandwindow_p.h>
|
||||||
|
#include <qwayland-hyprland-surface-v1.h>
|
||||||
|
#include <qwaylandclientextension.h>
|
||||||
|
|
||||||
|
#include "surface.hpp"
|
||||||
|
|
||||||
|
namespace qs::hyprland::surface::impl {
|
||||||
|
|
||||||
|
class HyprlandSurfaceManager
|
||||||
|
: public QWaylandClientExtensionTemplate<HyprlandSurfaceManager>
|
||||||
|
, public QtWayland::hyprland_surface_manager_v1 {
|
||||||
|
public:
|
||||||
|
explicit HyprlandSurfaceManager();
|
||||||
|
|
||||||
|
HyprlandSurface* createHyprlandExtension(QtWaylandClient::QWaylandWindow* surface);
|
||||||
|
|
||||||
|
static HyprlandSurfaceManager* instance();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace qs::hyprland::surface::impl
|
154
src/wayland/hyprland/surface/qml.cpp
Normal file
154
src/wayland/hyprland/surface/qml.cpp
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
#include "qml.hpp"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <private/qwaylandwindow_p.h>
|
||||||
|
#include <qlogging.h>
|
||||||
|
#include <qobject.h>
|
||||||
|
#include <qqmlinfo.h>
|
||||||
|
#include <qtmetamacros.h>
|
||||||
|
#include <qtypes.h>
|
||||||
|
#include <qwindow.h>
|
||||||
|
|
||||||
|
#include "../../../window/proxywindow.hpp"
|
||||||
|
#include "../../../window/windowinterface.hpp"
|
||||||
|
#include "../../util.hpp"
|
||||||
|
#include "manager.hpp"
|
||||||
|
#include "surface.hpp"
|
||||||
|
|
||||||
|
using QtWaylandClient::QWaylandWindow;
|
||||||
|
|
||||||
|
namespace qs::hyprland::surface {
|
||||||
|
|
||||||
|
HyprlandWindow* HyprlandWindow::qmlAttachedProperties(QObject* object) {
|
||||||
|
auto* proxyWindow = qobject_cast<ProxyWindowBase*>(object);
|
||||||
|
|
||||||
|
if (!proxyWindow) {
|
||||||
|
if (auto* iface = qobject_cast<WindowInterface*>(object)) {
|
||||||
|
proxyWindow = iface->proxyWindow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "hlwindow for" << proxyWindow;
|
||||||
|
if (!proxyWindow) return nullptr;
|
||||||
|
return new HyprlandWindow(proxyWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
HyprlandWindow::HyprlandWindow(ProxyWindowBase* window): QObject(nullptr), proxyWindow(window) {
|
||||||
|
QObject::connect(
|
||||||
|
window,
|
||||||
|
&ProxyWindowBase::windowConnected,
|
||||||
|
this,
|
||||||
|
&HyprlandWindow::onWindowConnected
|
||||||
|
);
|
||||||
|
|
||||||
|
QObject::connect(window, &QObject::destroyed, this, &HyprlandWindow::onProxyWindowDestroyed);
|
||||||
|
|
||||||
|
if (window->backingWindow()) {
|
||||||
|
this->onWindowConnected();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal HyprlandWindow::opacity() const { return this->mOpacity; }
|
||||||
|
|
||||||
|
void HyprlandWindow::setOpacity(qreal opacity) {
|
||||||
|
if (opacity == this->mOpacity) return;
|
||||||
|
|
||||||
|
if (opacity < 0.0 || opacity > 1.0) {
|
||||||
|
qmlWarning(this
|
||||||
|
) << "Cannot set HyprlandWindow.opacity to a value larger than 1.0 or smaller than 0.0";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->mOpacity = opacity;
|
||||||
|
|
||||||
|
if (this->surface) {
|
||||||
|
this->surface->setOpacity(opacity);
|
||||||
|
qs::wayland::util::scheduleCommit(this->mWaylandWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
emit this->opacityChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HyprlandWindow::onWindowConnected() {
|
||||||
|
this->mWindow = this->proxyWindow->backingWindow();
|
||||||
|
// disconnected by destructor
|
||||||
|
QObject::connect(
|
||||||
|
this->mWindow,
|
||||||
|
&QWindow::visibleChanged,
|
||||||
|
this,
|
||||||
|
&HyprlandWindow::onWindowVisibleChanged
|
||||||
|
);
|
||||||
|
|
||||||
|
this->onWindowVisibleChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HyprlandWindow::onWindowVisibleChanged() {
|
||||||
|
if (this->mWindow->isVisible()) {
|
||||||
|
if (!this->mWindow->handle()) {
|
||||||
|
this->mWindow->create();
|
||||||
|
}
|
||||||
|
|
||||||
|
this->mWaylandWindow = dynamic_cast<QWaylandWindow*>(this->mWindow->handle());
|
||||||
|
|
||||||
|
if (this->mWaylandWindow) {
|
||||||
|
// disconnected by destructor
|
||||||
|
|
||||||
|
QObject::connect(
|
||||||
|
this->mWaylandWindow,
|
||||||
|
&QWaylandWindow::surfaceCreated,
|
||||||
|
this,
|
||||||
|
&HyprlandWindow::onWaylandSurfaceCreated
|
||||||
|
);
|
||||||
|
|
||||||
|
QObject::connect(
|
||||||
|
this->mWaylandWindow,
|
||||||
|
&QWaylandWindow::surfaceDestroyed,
|
||||||
|
this,
|
||||||
|
&HyprlandWindow::onWaylandSurfaceDestroyed
|
||||||
|
);
|
||||||
|
|
||||||
|
if (this->mWaylandWindow->surface()) {
|
||||||
|
this->onWaylandSurfaceCreated();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HyprlandWindow::onWaylandSurfaceCreated() {
|
||||||
|
auto* manager = impl::HyprlandSurfaceManager::instance();
|
||||||
|
|
||||||
|
if (!manager->isActive()) {
|
||||||
|
qWarning() << "The active compositor does not support the hyprland_surface_v1 protocol. "
|
||||||
|
"HyprlandWindow will not work.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* ext = manager->createHyprlandExtension(this->mWaylandWindow);
|
||||||
|
this->surface = std::unique_ptr<impl::HyprlandSurface>(ext);
|
||||||
|
|
||||||
|
if (this->mOpacity != 1.0) {
|
||||||
|
this->surface->setOpacity(this->mOpacity);
|
||||||
|
qs::wayland::util::scheduleCommit(this->mWaylandWindow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HyprlandWindow::onWaylandSurfaceDestroyed() {
|
||||||
|
this->surface = nullptr;
|
||||||
|
|
||||||
|
if (!this->proxyWindow) {
|
||||||
|
this->deleteLater();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HyprlandWindow::onProxyWindowDestroyed() {
|
||||||
|
// Don't delete the HyprlandWindow, and therefore the impl::HyprlandSurface until the wl_surface is destroyed.
|
||||||
|
// Deleting it when the proxy window is deleted will cause a full opacity frame between the destruction of the
|
||||||
|
// hyprland_surface_v1 and wl_surface objects.
|
||||||
|
|
||||||
|
if (this->surface == nullptr) {
|
||||||
|
this->proxyWindow = nullptr;
|
||||||
|
this->deleteLater();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace qs::hyprland::surface
|
74
src/wayland/hyprland/surface/qml.hpp
Normal file
74
src/wayland/hyprland/surface/qml.hpp
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <private/qwaylandwindow_p.h>
|
||||||
|
#include <qobject.h>
|
||||||
|
#include <qqmlintegration.h>
|
||||||
|
#include <qtmetamacros.h>
|
||||||
|
#include <qtypes.h>
|
||||||
|
#include <qwindow.h>
|
||||||
|
|
||||||
|
#include "../../../window/proxywindow.hpp"
|
||||||
|
#include "surface.hpp"
|
||||||
|
|
||||||
|
namespace qs::hyprland::surface {
|
||||||
|
|
||||||
|
///! Hyprland specific QsWindow properties.
|
||||||
|
/// Allows setting hyprland specific window properties on a @@Quickshell.QsWindow or subclass,
|
||||||
|
/// as an attached object.
|
||||||
|
///
|
||||||
|
/// #### Example
|
||||||
|
/// ```qml
|
||||||
|
/// @@Quickshell.PopupWindow {
|
||||||
|
/// // ...
|
||||||
|
/// HyprlandWindow.opacity: 0.6 // any number or binding
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// > [!NOTE] Requires at least hyprland 0.47.0, or [hyprland-surface-v1] support.
|
||||||
|
///
|
||||||
|
/// [hyprland-surface-v1]: https://github.com/hyprwm/hyprland-protocols/blob/main/protocols/hyprland-surface-v1.xml
|
||||||
|
class HyprlandWindow: public QObject {
|
||||||
|
Q_OBJECT;
|
||||||
|
/// A multiplier for the window's overall opacity, ranging from 1.0 to 0.0. Overall opacity includes the opacity of
|
||||||
|
/// both the window content *and* visual effects such as blur that apply to it.
|
||||||
|
///
|
||||||
|
/// Default: 1.0
|
||||||
|
Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity NOTIFY opacityChanged);
|
||||||
|
QML_ELEMENT;
|
||||||
|
QML_UNCREATABLE("HyprlandWindow can only be used as an attached object.");
|
||||||
|
QML_ATTACHED(HyprlandWindow);
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit HyprlandWindow(ProxyWindowBase* window);
|
||||||
|
|
||||||
|
[[nodiscard]] static bool available();
|
||||||
|
|
||||||
|
[[nodiscard]] qreal opacity() const;
|
||||||
|
void setOpacity(qreal opacity);
|
||||||
|
|
||||||
|
static HyprlandWindow* qmlAttachedProperties(QObject* object);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void opacityChanged();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onWindowConnected();
|
||||||
|
void onWindowVisibleChanged();
|
||||||
|
void onWaylandSurfaceCreated();
|
||||||
|
void onWaylandSurfaceDestroyed();
|
||||||
|
void onProxyWindowDestroyed();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void disconnectWaylandWindow();
|
||||||
|
|
||||||
|
ProxyWindowBase* proxyWindow = nullptr;
|
||||||
|
QWindow* mWindow = nullptr;
|
||||||
|
QtWaylandClient::QWaylandWindow* mWaylandWindow = nullptr;
|
||||||
|
|
||||||
|
qreal mOpacity = 1.0;
|
||||||
|
std::unique_ptr<impl::HyprlandSurface> surface;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace qs::hyprland::surface
|
19
src/wayland/hyprland/surface/surface.cpp
Normal file
19
src/wayland/hyprland/surface/surface.cpp
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#include "surface.hpp"
|
||||||
|
|
||||||
|
#include <qtypes.h>
|
||||||
|
#include <qwayland-hyprland-surface-v1.h>
|
||||||
|
#include <wayland-hyprland-surface-v1-client-protocol.h>
|
||||||
|
#include <wayland-util.h>
|
||||||
|
|
||||||
|
namespace qs::hyprland::surface::impl {
|
||||||
|
|
||||||
|
HyprlandSurface::HyprlandSurface(::hyprland_surface_v1* surface)
|
||||||
|
: QtWayland::hyprland_surface_v1(surface) {}
|
||||||
|
|
||||||
|
HyprlandSurface::~HyprlandSurface() { this->destroy(); }
|
||||||
|
|
||||||
|
void HyprlandSurface::setOpacity(qreal opacity) {
|
||||||
|
this->set_opacity(wl_fixed_from_double(opacity));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace qs::hyprland::surface::impl
|
21
src/wayland/hyprland/surface/surface.hpp
Normal file
21
src/wayland/hyprland/surface/surface.hpp
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <qobject.h>
|
||||||
|
#include <qtclasshelpermacros.h>
|
||||||
|
#include <qtmetamacros.h>
|
||||||
|
#include <qtypes.h>
|
||||||
|
#include <qwayland-hyprland-surface-v1.h>
|
||||||
|
#include <wayland-hyprland-surface-v1-client-protocol.h>
|
||||||
|
|
||||||
|
namespace qs::hyprland::surface::impl {
|
||||||
|
|
||||||
|
class HyprlandSurface: public QtWayland::hyprland_surface_v1 {
|
||||||
|
public:
|
||||||
|
explicit HyprlandSurface(::hyprland_surface_v1* surface);
|
||||||
|
~HyprlandSurface() override;
|
||||||
|
Q_DISABLE_COPY_MOVE(HyprlandSurface);
|
||||||
|
|
||||||
|
void setOpacity(qreal opacity);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace qs::hyprland::surface::impl
|
17
src/wayland/util.cpp
Normal file
17
src/wayland/util.cpp
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#include "util.hpp"
|
||||||
|
|
||||||
|
#include <private/qwaylandwindow_p.h>
|
||||||
|
#include <qpa/qwindowsysteminterface.h>
|
||||||
|
|
||||||
|
namespace qs::wayland::util {
|
||||||
|
|
||||||
|
void scheduleCommit(QtWaylandClient::QWaylandWindow* window) {
|
||||||
|
// This seems to be one of the less offensive ways to force Qt to send a wl_surface.commit on its own terms.
|
||||||
|
// Ideally we would trigger the commit more directly.
|
||||||
|
QWindowSystemInterface::handleExposeEvent(
|
||||||
|
window->window(),
|
||||||
|
QRect(QPoint(), window->geometry().size())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace qs::wayland::util
|
9
src/wayland/util.hpp
Normal file
9
src/wayland/util.hpp
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <private/qwaylandwindow_p.h>
|
||||||
|
|
||||||
|
namespace qs::wayland::util {
|
||||||
|
|
||||||
|
void scheduleCommit(QtWaylandClient::QWaylandWindow* window);
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue