summaryrefslogtreecommitdiff
path: root/src/desktop/Window.cpp
diff options
context:
space:
mode:
authorVaxry <43317083+vaxerski@users.noreply.github.com>2024-05-25 22:43:51 +0200
committerGitHub <noreply@github.com>2024-05-25 22:43:51 +0200
commitaddd3e7f1aeb670dd91d26005aaeccce3efb1ae7 (patch)
tree7eae3cf1d780ab84ff34ee0fce5ed85d9ee69c90 /src/desktop/Window.cpp
parenta71207434c0bc2c8e05e94b1619e68059a002879 (diff)
xwayland: move to hyprland impl (#6086)
Diffstat (limited to 'src/desktop/Window.cpp')
-rw-r--r--src/desktop/Window.cpp164
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());
+}