diff options
Diffstat (limited to 'src/desktop/Window.cpp')
| -rw-r--r-- | src/desktop/Window.cpp | 164 |
1 files changed, 125 insertions, 39 deletions
diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 7a06aa61..093cab5e 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -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) - return nullptr; - - if (!m_uSurface.xwayland->parent) + if (!m_pXWaylandSurface || !m_pXWaylandSurface->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; }); -}
\ No newline at end of file +} + +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()); +} |
