xwayland: move to hyprland impl (#6086)

This commit is contained in:
Vaxry
2024-05-25 22:43:51 +02:00
committed by GitHub
parent a71207434c
commit addd3e7f1a
36 changed files with 2956 additions and 707 deletions

View File

@@ -7,11 +7,14 @@
#include <any>
#include "../managers/TokenManager.hpp"
#include "../protocols/XDGShell.hpp"
#include "../xwayland/XWayland.hpp"
PHLWINDOW CWindow::create() {
PHLWINDOW pWindow = SP<CWindow>(new CWindow);
PHLWINDOW CWindow::create(SP<CXWaylandSurface> surface) {
PHLWINDOW pWindow = SP<CWindow>(new CWindow(surface));
pWindow->m_pSelf = pWindow;
pWindow->m_pSelf = pWindow;
pWindow->m_bIsX11 = true;
pWindow->m_iX11Type = surface->overrideRedirect ? 2 : 1;
pWindow->m_vRealPosition.create(g_pConfigManager->getAnimationPropertyConfig("windowsIn"), pWindow, AVARDAMAGE_ENTIRE);
pWindow->m_vRealSize.create(g_pConfigManager->getAnimationPropertyConfig("windowsIn"), pWindow, AVARDAMAGE_ENTIRE);
@@ -61,8 +64,19 @@ CWindow::CWindow(SP<CXDGSurfaceResource> resource) : m_pXDGSurface(resource) {
listeners.updateMetadata = m_pXDGSurface->toplevel->events.metadataChanged.registerListener([this](std::any d) { onUpdateMeta(); });
}
CWindow::CWindow() {
;
CWindow::CWindow(SP<CXWaylandSurface> surface) : m_pXWaylandSurface(surface) {
listeners.map = m_pXWaylandSurface->events.map.registerListener([this](std::any d) { Events::listener_mapWindow(this, nullptr); });
listeners.unmap = m_pXWaylandSurface->events.unmap.registerListener([this](std::any d) { Events::listener_unmapWindow(this, nullptr); });
listeners.destroy = m_pXWaylandSurface->events.destroy.registerListener([this](std::any d) { Events::listener_destroyWindow(this, nullptr); });
listeners.commit = m_pXWaylandSurface->events.commit.registerListener([this](std::any d) { Events::listener_commitWindow(this, nullptr); });
listeners.configure = m_pXWaylandSurface->events.configure.registerListener([this](std::any d) { onX11Configure(std::any_cast<CBox>(d)); });
listeners.updateState = m_pXWaylandSurface->events.stateChanged.registerListener([this](std::any d) { onUpdateState(); });
listeners.updateMetadata = m_pXWaylandSurface->events.metadataChanged.registerListener([this](std::any d) { onUpdateMeta(); });
listeners.resourceChange = m_pXWaylandSurface->events.resourceChange.registerListener([this](std::any d) { onResourceChangeX11(); });
listeners.activate = m_pXWaylandSurface->events.activate.registerListener([this](std::any d) { Events::listener_activateX11(this, nullptr); });
if (m_pXWaylandSurface->overrideRedirect)
listeners.setGeometry = m_pXWaylandSurface->events.setGeometry.registerListener([this](std::any d) { Events::listener_unmanagedSetGeometry(this, nullptr); });
}
CWindow::~CWindow() {
@@ -300,10 +314,10 @@ pid_t CWindow::getPID() {
wl_client_get_credentials(m_pXDGSurface->owner->client(), &PID, nullptr, nullptr);
} else {
if (!m_uSurface.xwayland)
if (!m_pXWaylandSurface)
return -1;
PID = m_uSurface.xwayland->pid;
PID = m_pXWaylandSurface->pid;
}
return PID;
@@ -426,22 +440,23 @@ void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) {
}
PHLWINDOW CWindow::X11TransientFor() {
if (!m_bIsX11)
if (!m_pXWaylandSurface || !m_pXWaylandSurface->parent)
return nullptr;
if (!m_uSurface.xwayland->parent)
return nullptr;
auto PPARENT = g_pCompositor->getWindowFromSurface(m_uSurface.xwayland->parent->surface);
while (validMapped(PPARENT) && PPARENT->m_uSurface.xwayland->parent) {
PPARENT = g_pCompositor->getWindowFromSurface(PPARENT->m_uSurface.xwayland->parent->surface);
auto s = m_pXWaylandSurface->parent;
while (s) {
if (!s->parent)
break;
s = s->parent;
}
if (!validMapped(PPARENT))
return nullptr;
for (auto& w : g_pCompositor->m_vWindows) {
if (w->m_pXWaylandSurface != s)
continue;
return w;
}
return PPARENT;
return nullptr;
}
void CWindow::removeDecorationByType(eDecorationType type) {
@@ -494,8 +509,6 @@ void CWindow::onUnmap() {
std::erase_if(g_pCompositor->m_vWindowFocusHistory, [&](const auto& other) { return other.expired() || other.lock().get() == this; });
hyprListener_unmapWindow.removeCallback();
if (*PCLOSEONLASTSPECIAL && g_pCompositor->getWindowsOnWorkspace(workspaceID()) == 0 && onSpecialWorkspace()) {
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
if (PMONITOR && PMONITOR->activeSpecialWorkspace && PMONITOR->activeSpecialWorkspace == m_pWorkspace)
@@ -548,9 +561,6 @@ void CWindow::onMap() {
g_pCompositor->m_vWindowFocusHistory.push_back(m_pSelf);
if (m_bIsX11)
hyprListener_unmapWindow.initCallback(&m_uSurface.xwayland->surface->events.unmap, &Events::listener_unmapWindow, this, "CWindow");
m_vReportedSize = m_vPendingReportedSize;
m_bAnimatingIn = true;
@@ -1119,9 +1129,9 @@ bool CWindow::opaque() {
return false;
if (m_bIsX11)
return !m_uSurface.xwayland->has_alpha;
return false;
if (m_pXDGSurface->surface->opaque)
if (m_pXDGSurface && m_pXDGSurface->surface->opaque)
return true;
const auto EXTENTS = pixman_region32_extents(&m_pXDGSurface->surface->opaque_region);
@@ -1337,23 +1347,23 @@ void CWindow::activate(bool force) {
}
void CWindow::onUpdateState() {
if (!m_pXDGSurface)
return;
std::optional<bool> requestsFS = m_pXDGSurface ? m_pXDGSurface->toplevel->state.requestsFullscreen : m_pXWaylandSurface->state.requestsFullscreen;
std::optional<bool> requestsMX = m_pXDGSurface ? m_pXDGSurface->toplevel->state.requestsMaximize : m_pXWaylandSurface->state.requestsMaximize;
if (m_pXDGSurface->toplevel->state.requestsFullscreen && !(m_eSuppressedEvents & SUPPRESS_FULLSCREEN)) {
bool fs = m_pXDGSurface->toplevel->state.requestsFullscreen.value();
if (requestsFS.has_value() && !(m_eSuppressedEvents & SUPPRESS_FULLSCREEN)) {
bool fs = requestsFS.value();
if (fs != m_bIsFullscreen && m_pXDGSurface->mapped)
if (fs != m_bIsFullscreen && m_bIsMapped)
g_pCompositor->setWindowFullscreen(m_pSelf.lock(), fs, FULLSCREEN_FULL);
if (!m_pXDGSurface->mapped)
if (!m_bIsMapped)
m_bWantsInitialFullscreen = fs;
}
if (m_pXDGSurface->toplevel->state.requestsMaximize && !(m_eSuppressedEvents & SUPPRESS_MAXIMIZE)) {
bool fs = m_pXDGSurface->toplevel->state.requestsMaximize.value();
if (requestsMX.has_value() && !(m_eSuppressedEvents & SUPPRESS_MAXIMIZE)) {
bool fs = requestsMX.value();
if (fs != m_bIsFullscreen && m_pXDGSurface->mapped)
if (fs != m_bIsFullscreen && m_bIsMapped)
g_pCompositor->setWindowFullscreen(m_pSelf.lock(), fs, FULLSCREEN_MAXIMIZED);
}
}
@@ -1402,8 +1412,8 @@ std::string CWindow::fetchTitle() {
if (m_pXDGSurface && m_pXDGSurface->toplevel)
return m_pXDGSurface->toplevel->state.title;
} else {
if (m_uSurface.xwayland && m_uSurface.xwayland->title)
return m_uSurface.xwayland->title;
if (m_pXWaylandSurface)
return m_pXWaylandSurface->state.title;
}
return "";
@@ -1414,8 +1424,8 @@ std::string CWindow::fetchClass() {
if (m_pXDGSurface && m_pXDGSurface->toplevel)
return m_pXDGSurface->toplevel->state.appid;
} else {
if (m_uSurface.xwayland && m_uSurface.xwayland->_class)
return m_uSurface.xwayland->_class;
if (m_pXWaylandSurface)
return m_pXWaylandSurface->state.appid;
}
return "";
@@ -1429,4 +1439,80 @@ void CWindow::onAck(uint32_t serial) {
m_pPendingSizeAck = *SERIAL;
std::erase_if(m_vPendingSizeAcks, [&](const auto& el) { return el.first <= SERIAL->first; });
}
}
void CWindow::onResourceChangeX11() {
if (m_pXWaylandSurface->surface && !m_pWLSurface.wlr())
m_pWLSurface.assign(m_pXWaylandSurface->surface, m_pSelf.lock());
else if (!m_pXWaylandSurface->surface && m_pWLSurface.wlr())
m_pWLSurface.unassign();
// update metadata as well,
// could be first assoc and we need to catch the class
onUpdateMeta();
Debug::log(LOG, "xwayland window {:x} -> association to {:x}", (uintptr_t)m_pXWaylandSurface.get(), (uintptr_t)m_pWLSurface.wlr());
}
void CWindow::onX11Configure(CBox box) {
if (!m_pXWaylandSurface->surface || !m_pXWaylandSurface->mapped || !m_bIsMapped) {
m_pXWaylandSurface->configure(box);
m_vPendingReportedSize = box.size();
m_vReportedSize = box.size();
if (const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID); PMONITOR)
m_fX11SurfaceScaledBy = PMONITOR->scale;
return;
}
g_pHyprRenderer->damageWindow(m_pSelf.lock());
if (!m_bIsFloating || m_bIsFullscreen || g_pInputManager->currentlyDraggedWindow == m_pSelf) {
g_pXWaylandManager->setWindowSize(m_pSelf.lock(), m_vRealSize.goal(), true);
g_pInputManager->refocus();
g_pHyprRenderer->damageWindow(m_pSelf.lock());
return;
}
if (box.size() > Vector2D{1, 1})
setHidden(false);
else
setHidden(true);
const auto LOGICALPOS = g_pXWaylandManager->xwaylandToWaylandCoords(box.pos());
m_vRealPosition.setValueAndWarp(LOGICALPOS);
m_vRealSize.setValueAndWarp(box.size());
static auto PXWLFORCESCALEZERO = CConfigValue<Hyprlang::INT>("xwayland:force_zero_scaling");
if (*PXWLFORCESCALEZERO) {
if (const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID); PMONITOR) {
m_vRealSize.setValueAndWarp(m_vRealSize.goal() / PMONITOR->scale);
m_fX11SurfaceScaledBy = PMONITOR->scale;
}
}
m_vPosition = m_vRealPosition.value();
m_vSize = m_vRealSize.value();
m_pXWaylandSurface->configure(box);
m_vPendingReportedSize = box.size();
m_vReportedSize = box.size();
updateWindowDecos();
if (!g_pCompositor->isWorkspaceVisible(m_pWorkspace))
return; // further things are only for visible windows
m_pWorkspace = g_pCompositor->getMonitorFromVector(m_vRealPosition.value() + m_vRealSize.value() / 2.f)->activeWorkspace;
g_pCompositor->changeWindowZOrder(m_pSelf.lock(), true);
m_bCreatedOverFullscreen = true;
if (!m_sAdditionalConfigData.windowDanceCompat)
g_pInputManager->refocus();
g_pHyprRenderer->damageWindow(m_pSelf.lock());
}