mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-08-09 16:41:53 -07:00
xwayland: move to hyprland impl (#6086)
This commit is contained in:
@@ -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());
|
||||
}
|
||||
|
Reference in New Issue
Block a user