mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-05-19 00:20:23 -07:00
xwayland: refactor class member vars (#10312)
* xwayland: refactor class member vars * xwayland: fix pure wayland build
This commit is contained in:
parent
f8bbe5124c
commit
e5df8cdc62
@ -2394,7 +2394,7 @@ PHLWINDOW CCompositor::getX11Parent(PHLWINDOW pWindow) {
|
||||
if (!w->m_isX11)
|
||||
continue;
|
||||
|
||||
if (w->m_xwaylandSurface == pWindow->m_xwaylandSurface->parent)
|
||||
if (w->m_xwaylandSurface == pWindow->m_xwaylandSurface->m_parent)
|
||||
return w;
|
||||
}
|
||||
|
||||
|
@ -100,18 +100,18 @@ CWindow::CWindow(SP<CXDGSurfaceResource> resource) : m_xdgSurface(resource) {
|
||||
CWindow::CWindow(SP<CXWaylandSurface> surface) : m_xwaylandSurface(surface) {
|
||||
m_wlSurface = CWLSurface::create();
|
||||
|
||||
m_listeners.map = m_xwaylandSurface->events.map.registerListener([this](std::any d) { Events::listener_mapWindow(this, nullptr); });
|
||||
m_listeners.unmap = m_xwaylandSurface->events.unmap.registerListener([this](std::any d) { Events::listener_unmapWindow(this, nullptr); });
|
||||
m_listeners.destroy = m_xwaylandSurface->events.destroy.registerListener([this](std::any d) { Events::listener_destroyWindow(this, nullptr); });
|
||||
m_listeners.commit = m_xwaylandSurface->events.commit.registerListener([this](std::any d) { Events::listener_commitWindow(this, nullptr); });
|
||||
m_listeners.configureRequest = m_xwaylandSurface->events.configureRequest.registerListener([this](std::any d) { onX11ConfigureRequest(std::any_cast<CBox>(d)); });
|
||||
m_listeners.updateState = m_xwaylandSurface->events.stateChanged.registerListener([this](std::any d) { onUpdateState(); });
|
||||
m_listeners.updateMetadata = m_xwaylandSurface->events.metadataChanged.registerListener([this](std::any d) { onUpdateMeta(); });
|
||||
m_listeners.resourceChange = m_xwaylandSurface->events.resourceChange.registerListener([this](std::any d) { onResourceChangeX11(); });
|
||||
m_listeners.activate = m_xwaylandSurface->events.activate.registerListener([this](std::any d) { Events::listener_activateX11(this, nullptr); });
|
||||
m_listeners.map = m_xwaylandSurface->m_events.map.registerListener([this](std::any d) { Events::listener_mapWindow(this, nullptr); });
|
||||
m_listeners.unmap = m_xwaylandSurface->m_events.unmap.registerListener([this](std::any d) { Events::listener_unmapWindow(this, nullptr); });
|
||||
m_listeners.destroy = m_xwaylandSurface->m_events.destroy.registerListener([this](std::any d) { Events::listener_destroyWindow(this, nullptr); });
|
||||
m_listeners.commit = m_xwaylandSurface->m_events.commit.registerListener([this](std::any d) { Events::listener_commitWindow(this, nullptr); });
|
||||
m_listeners.configureRequest = m_xwaylandSurface->m_events.configureRequest.registerListener([this](std::any d) { onX11ConfigureRequest(std::any_cast<CBox>(d)); });
|
||||
m_listeners.updateState = m_xwaylandSurface->m_events.stateChanged.registerListener([this](std::any d) { onUpdateState(); });
|
||||
m_listeners.updateMetadata = m_xwaylandSurface->m_events.metadataChanged.registerListener([this](std::any d) { onUpdateMeta(); });
|
||||
m_listeners.resourceChange = m_xwaylandSurface->m_events.resourceChange.registerListener([this](std::any d) { onResourceChangeX11(); });
|
||||
m_listeners.activate = m_xwaylandSurface->m_events.activate.registerListener([this](std::any d) { Events::listener_activateX11(this, nullptr); });
|
||||
|
||||
if (m_xwaylandSurface->overrideRedirect)
|
||||
m_listeners.setGeometry = m_xwaylandSurface->events.setGeometry.registerListener([this](std::any d) { Events::listener_unmanagedSetGeometry(this, nullptr); });
|
||||
if (m_xwaylandSurface->m_overrideRedirect)
|
||||
m_listeners.setGeometry = m_xwaylandSurface->m_events.setGeometry.registerListener([this](std::any d) { Events::listener_unmanagedSetGeometry(this, nullptr); });
|
||||
}
|
||||
|
||||
CWindow::~CWindow() {
|
||||
@ -352,7 +352,7 @@ pid_t CWindow::getPID() {
|
||||
if (!m_xwaylandSurface)
|
||||
return -1;
|
||||
|
||||
PID = m_xwaylandSurface->pid;
|
||||
PID = m_xwaylandSurface->m_pid;
|
||||
}
|
||||
|
||||
return PID;
|
||||
@ -471,10 +471,10 @@ void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) {
|
||||
}
|
||||
|
||||
PHLWINDOW CWindow::x11TransientFor() {
|
||||
if (!m_xwaylandSurface || !m_xwaylandSurface->parent)
|
||||
if (!m_xwaylandSurface || !m_xwaylandSurface->m_parent)
|
||||
return nullptr;
|
||||
|
||||
auto s = m_xwaylandSurface->parent;
|
||||
auto s = m_xwaylandSurface->m_parent;
|
||||
std::vector<SP<CXWaylandSurface>> visited;
|
||||
while (s) {
|
||||
// break loops. Some X apps make them, and it seems like it's valid behavior?!?!?!
|
||||
@ -483,7 +483,7 @@ PHLWINDOW CWindow::x11TransientFor() {
|
||||
break;
|
||||
|
||||
visited.emplace_back(s.lock());
|
||||
s = s->parent;
|
||||
s = s->m_parent;
|
||||
}
|
||||
|
||||
if (s == m_xwaylandSurface)
|
||||
@ -1159,8 +1159,8 @@ bool CWindow::opaque() {
|
||||
if (PWORKSPACE->m_alpha->value() != 1.f)
|
||||
return false;
|
||||
|
||||
if (m_isX11 && m_xwaylandSurface && m_xwaylandSurface->surface && m_xwaylandSurface->surface->m_current.texture)
|
||||
return m_xwaylandSurface->surface->m_current.texture->m_opaque;
|
||||
if (m_isX11 && m_xwaylandSurface && m_xwaylandSurface->m_surface && m_xwaylandSurface->m_surface->m_current.texture)
|
||||
return m_xwaylandSurface->m_surface->m_current.texture->m_opaque;
|
||||
|
||||
if (!m_wlSurface->resource() || !m_wlSurface->resource()->m_current.texture)
|
||||
return false;
|
||||
@ -1418,9 +1418,9 @@ void CWindow::activate(bool force) {
|
||||
}
|
||||
|
||||
void CWindow::onUpdateState() {
|
||||
std::optional<bool> requestsFS = m_xdgSurface ? m_xdgSurface->m_toplevel->m_state.requestsFullscreen : m_xwaylandSurface->state.requestsFullscreen;
|
||||
std::optional<bool> requestsFS = m_xdgSurface ? m_xdgSurface->m_toplevel->m_state.requestsFullscreen : m_xwaylandSurface->m_state.requestsFullscreen;
|
||||
std::optional<MONITORID> requestsID = m_xdgSurface ? m_xdgSurface->m_toplevel->m_state.requestsFullscreenMonitor : MONITOR_INVALID;
|
||||
std::optional<bool> requestsMX = m_xdgSurface ? m_xdgSurface->m_toplevel->m_state.requestsMaximize : m_xwaylandSurface->state.requestsMaximize;
|
||||
std::optional<bool> requestsMX = m_xdgSurface ? m_xdgSurface->m_toplevel->m_state.requestsMaximize : m_xwaylandSurface->m_state.requestsMaximize;
|
||||
|
||||
if (requestsFS.has_value() && !(m_suppressedEvents & SUPPRESS_FULLSCREEN)) {
|
||||
if (requestsID.has_value() && (requestsID.value() != MONITOR_INVALID) && !(m_suppressedEvents & SUPPRESS_FULLSCREEN_OUTPUT)) {
|
||||
@ -1495,7 +1495,7 @@ std::string CWindow::fetchTitle() {
|
||||
return m_xdgSurface->m_toplevel->m_state.title;
|
||||
} else {
|
||||
if (m_xwaylandSurface)
|
||||
return m_xwaylandSurface->state.title;
|
||||
return m_xwaylandSurface->m_state.title;
|
||||
}
|
||||
|
||||
return "";
|
||||
@ -1507,7 +1507,7 @@ std::string CWindow::fetchClass() {
|
||||
return m_xdgSurface->m_toplevel->m_state.appid;
|
||||
} else {
|
||||
if (m_xwaylandSurface)
|
||||
return m_xwaylandSurface->state.appid;
|
||||
return m_xwaylandSurface->m_state.appid;
|
||||
}
|
||||
|
||||
return "";
|
||||
@ -1524,9 +1524,9 @@ void CWindow::onAck(uint32_t serial) {
|
||||
}
|
||||
|
||||
void CWindow::onResourceChangeX11() {
|
||||
if (m_xwaylandSurface->surface && !m_wlSurface->resource())
|
||||
m_wlSurface->assign(m_xwaylandSurface->surface.lock(), m_self.lock());
|
||||
else if (!m_xwaylandSurface->surface && m_wlSurface->resource())
|
||||
if (m_xwaylandSurface->m_surface && !m_wlSurface->resource())
|
||||
m_wlSurface->assign(m_xwaylandSurface->m_surface.lock(), m_self.lock());
|
||||
else if (!m_xwaylandSurface->m_surface && m_wlSurface->resource())
|
||||
m_wlSurface->unassign();
|
||||
|
||||
// update metadata as well,
|
||||
@ -1538,7 +1538,7 @@ void CWindow::onResourceChangeX11() {
|
||||
|
||||
void CWindow::onX11ConfigureRequest(CBox box) {
|
||||
|
||||
if (!m_xwaylandSurface->surface || !m_xwaylandSurface->mapped || !m_isMapped) {
|
||||
if (!m_xwaylandSurface->m_surface || !m_xwaylandSurface->m_mapped || !m_isMapped) {
|
||||
m_xwaylandSurface->configure(box);
|
||||
m_pendingReportedSize = box.size();
|
||||
m_reportedSize = box.size();
|
||||
@ -1668,18 +1668,18 @@ void CWindow::unsetWindowData(eOverridePriority priority) {
|
||||
}
|
||||
|
||||
bool CWindow::isX11OverrideRedirect() {
|
||||
return m_xwaylandSurface && m_xwaylandSurface->overrideRedirect;
|
||||
return m_xwaylandSurface && m_xwaylandSurface->m_overrideRedirect;
|
||||
}
|
||||
|
||||
bool CWindow::isModal() {
|
||||
return (m_xwaylandSurface && m_xwaylandSurface->modal);
|
||||
return (m_xwaylandSurface && m_xwaylandSurface->m_modal);
|
||||
}
|
||||
|
||||
Vector2D CWindow::requestedMinSize() {
|
||||
if ((m_isX11 && !m_xwaylandSurface->sizeHints) || (!m_isX11 && !m_xdgSurface->m_toplevel))
|
||||
if ((m_isX11 && !m_xwaylandSurface->m_sizeHints) || (!m_isX11 && !m_xdgSurface->m_toplevel))
|
||||
return Vector2D(1, 1);
|
||||
|
||||
Vector2D minSize = m_isX11 ? Vector2D(m_xwaylandSurface->sizeHints->min_width, m_xwaylandSurface->sizeHints->min_height) : m_xdgSurface->m_toplevel->layoutMinSize();
|
||||
Vector2D minSize = m_isX11 ? Vector2D(m_xwaylandSurface->m_sizeHints->min_width, m_xwaylandSurface->m_sizeHints->min_height) : m_xdgSurface->m_toplevel->layoutMinSize();
|
||||
|
||||
minSize = minSize.clamp({1, 1});
|
||||
|
||||
@ -1688,10 +1688,10 @@ Vector2D CWindow::requestedMinSize() {
|
||||
|
||||
Vector2D CWindow::requestedMaxSize() {
|
||||
constexpr int NO_MAX_SIZE_LIMIT = 99999;
|
||||
if (((m_isX11 && !m_xwaylandSurface->sizeHints) || (!m_isX11 && (!m_xdgSurface || !m_xdgSurface->m_toplevel)) || m_windowData.noMaxSize.valueOrDefault()))
|
||||
if (((m_isX11 && !m_xwaylandSurface->m_sizeHints) || (!m_isX11 && (!m_xdgSurface || !m_xdgSurface->m_toplevel)) || m_windowData.noMaxSize.valueOrDefault()))
|
||||
return Vector2D(NO_MAX_SIZE_LIMIT, NO_MAX_SIZE_LIMIT);
|
||||
|
||||
Vector2D maxSize = m_isX11 ? Vector2D(m_xwaylandSurface->sizeHints->max_width, m_xwaylandSurface->sizeHints->max_height) : m_xdgSurface->m_toplevel->layoutMaxSize();
|
||||
Vector2D maxSize = m_isX11 ? Vector2D(m_xwaylandSurface->m_sizeHints->max_width, m_xwaylandSurface->m_sizeHints->max_height) : m_xdgSurface->m_toplevel->layoutMaxSize();
|
||||
|
||||
if (maxSize.x < 5)
|
||||
maxSize.x = NO_MAX_SIZE_LIMIT;
|
||||
|
@ -136,7 +136,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
PWINDOW->m_matchedRules = g_pConfigManager->getMatchingRules(PWINDOW, false);
|
||||
std::optional<eFullscreenMode> requestedInternalFSMode, requestedClientFSMode;
|
||||
std::optional<SFullscreenState> requestedFSState;
|
||||
if (PWINDOW->m_wantsInitialFullscreen || (PWINDOW->m_isX11 && PWINDOW->m_xwaylandSurface->fullscreen))
|
||||
if (PWINDOW->m_wantsInitialFullscreen || (PWINDOW->m_isX11 && PWINDOW->m_xwaylandSurface->m_fullscreen))
|
||||
requestedClientFSMode = FSMODE_FULLSCREEN;
|
||||
MONITORID requestedFSMonitor = PWINDOW->m_wantsInitialFullscreenMonitor;
|
||||
|
||||
@ -975,13 +975,13 @@ void Events::listener_activateX11(void* owner, void* data) {
|
||||
void Events::listener_unmanagedSetGeometry(void* owner, void* data) {
|
||||
PHLWINDOW PWINDOW = ((CWindow*)owner)->m_self.lock();
|
||||
|
||||
if (!PWINDOW->m_isMapped || !PWINDOW->m_xwaylandSurface || !PWINDOW->m_xwaylandSurface->overrideRedirect)
|
||||
if (!PWINDOW->m_isMapped || !PWINDOW->m_xwaylandSurface || !PWINDOW->m_xwaylandSurface->m_overrideRedirect)
|
||||
return;
|
||||
|
||||
const auto POS = PWINDOW->m_realPosition->goal();
|
||||
const auto SIZ = PWINDOW->m_realSize->goal();
|
||||
|
||||
if (PWINDOW->m_xwaylandSurface->geometry.size() > Vector2D{1, 1})
|
||||
if (PWINDOW->m_xwaylandSurface->m_geometry.size() > Vector2D{1, 1})
|
||||
PWINDOW->setHidden(false);
|
||||
else
|
||||
PWINDOW->setHidden(true);
|
||||
@ -994,17 +994,17 @@ void Events::listener_unmanagedSetGeometry(void* owner, void* data) {
|
||||
|
||||
static auto PXWLFORCESCALEZERO = CConfigValue<Hyprlang::INT>("xwayland:force_zero_scaling");
|
||||
|
||||
const auto LOGICALPOS = g_pXWaylandManager->xwaylandToWaylandCoords(PWINDOW->m_xwaylandSurface->geometry.pos());
|
||||
const auto LOGICALPOS = g_pXWaylandManager->xwaylandToWaylandCoords(PWINDOW->m_xwaylandSurface->m_geometry.pos());
|
||||
|
||||
if (abs(std::floor(POS.x) - LOGICALPOS.x) > 2 || abs(std::floor(POS.y) - LOGICALPOS.y) > 2 || abs(std::floor(SIZ.x) - PWINDOW->m_xwaylandSurface->geometry.width) > 2 ||
|
||||
abs(std::floor(SIZ.y) - PWINDOW->m_xwaylandSurface->geometry.height) > 2) {
|
||||
Debug::log(LOG, "Unmanaged window {} requests geometry update to {:j} {:j}", PWINDOW, LOGICALPOS, PWINDOW->m_xwaylandSurface->geometry.size());
|
||||
if (abs(std::floor(POS.x) - LOGICALPOS.x) > 2 || abs(std::floor(POS.y) - LOGICALPOS.y) > 2 || abs(std::floor(SIZ.x) - PWINDOW->m_xwaylandSurface->m_geometry.width) > 2 ||
|
||||
abs(std::floor(SIZ.y) - PWINDOW->m_xwaylandSurface->m_geometry.height) > 2) {
|
||||
Debug::log(LOG, "Unmanaged window {} requests geometry update to {:j} {:j}", PWINDOW, LOGICALPOS, PWINDOW->m_xwaylandSurface->m_geometry.size());
|
||||
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
PWINDOW->m_realPosition->setValueAndWarp(Vector2D(LOGICALPOS.x, LOGICALPOS.y));
|
||||
|
||||
if (abs(std::floor(SIZ.x) - PWINDOW->m_xwaylandSurface->geometry.w) > 2 || abs(std::floor(SIZ.y) - PWINDOW->m_xwaylandSurface->geometry.h) > 2)
|
||||
PWINDOW->m_realSize->setValueAndWarp(PWINDOW->m_xwaylandSurface->geometry.size());
|
||||
if (abs(std::floor(SIZ.x) - PWINDOW->m_xwaylandSurface->m_geometry.w) > 2 || abs(std::floor(SIZ.y) - PWINDOW->m_xwaylandSurface->m_geometry.h) > 2)
|
||||
PWINDOW->m_realSize->setValueAndWarp(PWINDOW->m_xwaylandSurface->m_geometry.size());
|
||||
|
||||
if (*PXWLFORCESCALEZERO) {
|
||||
if (const auto PMONITOR = PWINDOW->m_monitor.lock(); PMONITOR) {
|
||||
|
@ -131,8 +131,8 @@ void IHyprLayout::onWindowCreatedFloating(PHLWINDOW pWindow) {
|
||||
|
||||
if (pWindow->m_isX11 && pWindow->isX11OverrideRedirect()) {
|
||||
|
||||
if (pWindow->m_xwaylandSurface->geometry.x != 0 && pWindow->m_xwaylandSurface->geometry.y != 0)
|
||||
*pWindow->m_realPosition = g_pXWaylandManager->xwaylandToWaylandCoords(pWindow->m_xwaylandSurface->geometry.pos());
|
||||
if (pWindow->m_xwaylandSurface->m_geometry.x != 0 && pWindow->m_xwaylandSurface->m_geometry.y != 0)
|
||||
*pWindow->m_realPosition = g_pXWaylandManager->xwaylandToWaylandCoords(pWindow->m_xwaylandSurface->m_geometry.pos());
|
||||
else
|
||||
*pWindow->m_realPosition = Vector2D(PMONITOR->m_position.x + (PMONITOR->m_size.x - pWindow->m_realSize->goal().x) / 2.f,
|
||||
PMONITOR->m_position.y + (PMONITOR->m_size.y - pWindow->m_realSize->goal().y) / 2.f);
|
||||
|
@ -218,7 +218,7 @@ pid_t CANRManager::SANRData::getPid() const {
|
||||
}
|
||||
|
||||
if (xwaylandSurface)
|
||||
return xwaylandSurface->pid;
|
||||
return xwaylandSurface->m_pid;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ CBox CHyprXWaylandManager::getGeometryForWindow(PHLWINDOW pWindow) {
|
||||
CBox box;
|
||||
|
||||
if (pWindow->m_isX11)
|
||||
box = pWindow->m_xwaylandSurface->geometry;
|
||||
box = pWindow->m_xwaylandSurface->m_geometry;
|
||||
else if (pWindow->m_xdgSurface)
|
||||
box = pWindow->m_xdgSurface->m_current.geometry;
|
||||
|
||||
@ -100,7 +100,7 @@ void CHyprXWaylandManager::sendCloseWindow(PHLWINDOW pWindow) {
|
||||
|
||||
bool CHyprXWaylandManager::shouldBeFloated(PHLWINDOW pWindow, bool pending) {
|
||||
if (pWindow->m_isX11) {
|
||||
for (const auto& a : pWindow->m_xwaylandSurface->atoms)
|
||||
for (const auto& a : pWindow->m_xwaylandSurface->m_atoms)
|
||||
if (a == HYPRATOMS["_NET_WM_WINDOW_TYPE_DIALOG"] || a == HYPRATOMS["_NET_WM_WINDOW_TYPE_SPLASH"] || a == HYPRATOMS["_NET_WM_WINDOW_TYPE_TOOLBAR"] ||
|
||||
a == HYPRATOMS["_NET_WM_WINDOW_TYPE_UTILITY"] || a == HYPRATOMS["_NET_WM_WINDOW_TYPE_TOOLTIP"] || a == HYPRATOMS["_NET_WM_WINDOW_TYPE_POPUP_MENU"] ||
|
||||
a == HYPRATOMS["_NET_WM_WINDOW_TYPE_DOCK"] || a == HYPRATOMS["_NET_WM_WINDOW_TYPE_DROPDOWN_MENU"] || a == HYPRATOMS["_NET_WM_WINDOW_TYPE_MENU"] ||
|
||||
@ -115,12 +115,12 @@ bool CHyprXWaylandManager::shouldBeFloated(PHLWINDOW pWindow, bool pending) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pWindow->isModal() || pWindow->m_xwaylandSurface->transient ||
|
||||
(pWindow->m_xwaylandSurface->role.contains("task_dialog") || pWindow->m_xwaylandSurface->role.contains("pop-up")) || pWindow->m_xwaylandSurface->overrideRedirect)
|
||||
if (pWindow->isModal() || pWindow->m_xwaylandSurface->m_transient ||
|
||||
(pWindow->m_xwaylandSurface->m_role.contains("task_dialog") || pWindow->m_xwaylandSurface->m_role.contains("pop-up")) || pWindow->m_xwaylandSurface->m_overrideRedirect)
|
||||
return true;
|
||||
|
||||
const auto SIZEHINTS = pWindow->m_xwaylandSurface->sizeHints.get();
|
||||
if (pWindow->m_xwaylandSurface->transient || pWindow->m_xwaylandSurface->parent ||
|
||||
const auto SIZEHINTS = pWindow->m_xwaylandSurface->m_sizeHints.get();
|
||||
if (pWindow->m_xwaylandSurface->m_transient || pWindow->m_xwaylandSurface->m_parent ||
|
||||
(SIZEHINTS && (SIZEHINTS->min_width == SIZEHINTS->max_width) && (SIZEHINTS->min_height == SIZEHINTS->max_height)))
|
||||
return true;
|
||||
} else {
|
||||
@ -140,7 +140,7 @@ void CHyprXWaylandManager::checkBorders(PHLWINDOW pWindow) {
|
||||
if (!pWindow->m_isX11)
|
||||
return;
|
||||
|
||||
for (auto const& a : pWindow->m_xwaylandSurface->atoms) {
|
||||
for (auto const& a : pWindow->m_xwaylandSurface->m_atoms) {
|
||||
if (a == HYPRATOMS["_NET_WM_WINDOW_TYPE_POPUP_MENU"] || a == HYPRATOMS["_NET_WM_WINDOW_TYPE_NOTIFICATION"] || a == HYPRATOMS["_NET_WM_WINDOW_TYPE_DROPDOWN_MENU"] ||
|
||||
a == HYPRATOMS["_NET_WM_WINDOW_TYPE_COMBO"] || a == HYPRATOMS["_NET_WM_WINDOW_TYPE_MENU"] || a == HYPRATOMS["_NET_WM_WINDOW_TYPE_SPLASH"] ||
|
||||
a == HYPRATOMS["_NET_WM_WINDOW_TYPE_TOOLTIP"]) {
|
||||
|
@ -47,7 +47,7 @@ void CXDGOutputProtocol::onManagerGetXDGOutput(CZxdgOutputManagerV1* mgr, uint32
|
||||
|
||||
CXDGOutput* pXDGOutput = m_xdgOutputs.emplace_back(makeUnique<CXDGOutput>(makeShared<CZxdgOutputV1>(CLIENT, mgr->version(), id), PMONITOR)).get();
|
||||
#ifndef NO_XWAYLAND
|
||||
if (g_pXWayland && g_pXWayland->pServer && g_pXWayland->pServer->xwaylandClient == CLIENT)
|
||||
if (g_pXWayland && g_pXWayland->m_server && g_pXWayland->m_server->m_xwaylandClient == CLIENT)
|
||||
pXDGOutput->m_isXWayland = true;
|
||||
#endif
|
||||
pXDGOutput->m_client = CLIENT;
|
||||
|
@ -420,8 +420,8 @@ void CWLDataDeviceProtocol::destroyResource(CWLDataOfferResource* resource) {
|
||||
|
||||
SP<IDataDevice> CWLDataDeviceProtocol::dataDeviceForClient(wl_client* c) {
|
||||
#ifndef NO_XWAYLAND
|
||||
if (g_pXWayland && g_pXWayland->pServer && c == g_pXWayland->pServer->xwaylandClient)
|
||||
return g_pXWayland->pWM->getDataDevice();
|
||||
if (g_pXWayland && g_pXWayland->m_server && c == g_pXWayland->m_server->m_xwaylandClient)
|
||||
return g_pXWayland->m_wm->getDataDevice();
|
||||
#endif
|
||||
|
||||
auto it = std::find_if(m_devices.begin(), m_devices.end(), [c](const auto& e) { return e->client() == c; });
|
||||
@ -451,7 +451,7 @@ void CWLDataDeviceProtocol::sendSelectionToDevice(SP<IDataDevice> dev, SP<IDataS
|
||||
}
|
||||
#ifndef NO_XWAYLAND
|
||||
else if (const auto X11 = dev->getX11(); X11)
|
||||
offer = g_pXWayland->pWM->createX11DataOffer(g_pSeatManager->m_state.keyboardFocus.lock(), sel);
|
||||
offer = g_pXWayland->m_wm->createX11DataOffer(g_pSeatManager->m_state.keyboardFocus.lock(), sel);
|
||||
#endif
|
||||
|
||||
if UNLIKELY (!offer) {
|
||||
@ -669,7 +669,7 @@ void CWLDataDeviceProtocol::updateDrag() {
|
||||
}
|
||||
#ifndef NO_XWAYLAND
|
||||
else if (const auto X11 = m_dnd.focusedDevice->getX11(); X11)
|
||||
offer = g_pXWayland->pWM->createX11DataOffer(g_pSeatManager->m_state.keyboardFocus.lock(), m_dnd.currentSource.lock());
|
||||
offer = g_pXWayland->m_wm->createX11DataOffer(g_pSeatManager->m_state.keyboardFocus.lock(), m_dnd.currentSource.lock());
|
||||
#endif
|
||||
|
||||
if (!offer) {
|
||||
|
@ -36,15 +36,15 @@ void CX11DataDevice::sendDndEvent(xcb_window_t targetWindow, xcb_atom_t type, xc
|
||||
.data = data,
|
||||
};
|
||||
|
||||
xcb_send_event(g_pXWayland->pWM->connection, 0, targetWindow, XCB_EVENT_MASK_NO_EVENT, (const char*)&event);
|
||||
xcb_flush(g_pXWayland->pWM->connection);
|
||||
xcb_send_event(g_pXWayland->m_wm->m_connection, 0, targetWindow, XCB_EVENT_MASK_NO_EVENT, (const char*)&event);
|
||||
xcb_flush(g_pXWayland->m_wm->m_connection);
|
||||
}
|
||||
|
||||
xcb_window_t CX11DataDevice::getProxyWindow(xcb_window_t window) {
|
||||
xcb_window_t targetWindow = window;
|
||||
xcb_get_property_cookie_t proxyCookie =
|
||||
xcb_get_property(g_pXWayland->pWM->connection, PROPERTY_OFFSET, window, HYPRATOMS["XdndProxy"], XCB_ATOM_WINDOW, PROPERTY_OFFSET, PROPERTY_LENGTH);
|
||||
xcb_get_property_reply_t* proxyReply = xcb_get_property_reply(g_pXWayland->pWM->connection, proxyCookie, nullptr);
|
||||
xcb_get_property(g_pXWayland->m_wm->m_connection, PROPERTY_OFFSET, window, HYPRATOMS["XdndProxy"], XCB_ATOM_WINDOW, PROPERTY_OFFSET, PROPERTY_LENGTH);
|
||||
xcb_get_property_reply_t* proxyReply = xcb_get_property_reply(g_pXWayland->m_wm->m_connection, proxyCookie, nullptr);
|
||||
|
||||
const auto isValidPropertyReply = [](xcb_get_property_reply_t* reply) {
|
||||
return reply && reply->type == XCB_ATOM_WINDOW && reply->format == PROPERTY_FORMAT_32BIT && xcb_get_property_value_length(reply) == sizeof(xcb_window_t);
|
||||
@ -54,8 +54,8 @@ xcb_window_t CX11DataDevice::getProxyWindow(xcb_window_t window) {
|
||||
xcb_window_t proxyWindow = *(xcb_window_t*)xcb_get_property_value(proxyReply);
|
||||
|
||||
xcb_get_property_cookie_t proxyVerifyCookie =
|
||||
xcb_get_property(g_pXWayland->pWM->connection, PROPERTY_OFFSET, proxyWindow, HYPRATOMS["XdndProxy"], XCB_ATOM_WINDOW, PROPERTY_OFFSET, PROPERTY_LENGTH);
|
||||
xcb_get_property_reply_t* proxyVerifyReply = xcb_get_property_reply(g_pXWayland->pWM->connection, proxyVerifyCookie, nullptr);
|
||||
xcb_get_property(g_pXWayland->m_wm->m_connection, PROPERTY_OFFSET, proxyWindow, HYPRATOMS["XdndProxy"], XCB_ATOM_WINDOW, PROPERTY_OFFSET, PROPERTY_LENGTH);
|
||||
xcb_get_property_reply_t* proxyVerifyReply = xcb_get_property_reply(g_pXWayland->m_wm->m_connection, proxyVerifyCookie, nullptr);
|
||||
|
||||
if (isValidPropertyReply(proxyVerifyReply)) {
|
||||
xcb_window_t verifyWindow = *(xcb_window_t*)xcb_get_property_value(proxyVerifyReply);
|
||||
@ -81,16 +81,16 @@ SP<CWLDataOfferResource> CX11DataOffer::getWayland() {
|
||||
}
|
||||
|
||||
SP<CX11DataOffer> CX11DataOffer::getX11() {
|
||||
return self.lock();
|
||||
return m_self.lock();
|
||||
}
|
||||
|
||||
SP<IDataSource> CX11DataOffer::getSource() {
|
||||
return source.lock();
|
||||
return m_source.lock();
|
||||
}
|
||||
|
||||
void CX11DataOffer::markDead() {
|
||||
#ifndef NO_XWAYLAND
|
||||
std::erase(g_pXWayland->pWM->dndDataOffers, self);
|
||||
std::erase(g_pXWayland->m_wm->m_dndDataOffers, m_self);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -100,7 +100,7 @@ void CX11DataDevice::sendDataOffer(SP<IDataOffer> offer) {
|
||||
|
||||
void CX11DataDevice::sendEnter(uint32_t serial, SP<CWLSurfaceResource> surf, const Vector2D& local, SP<IDataOffer> offer) {
|
||||
#ifndef NO_XWAYLAND
|
||||
auto XSURF = g_pXWayland->pWM->windowForWayland(surf);
|
||||
auto XSURF = g_pXWayland->m_wm->windowForWayland(surf);
|
||||
|
||||
if (!XSURF) {
|
||||
Debug::log(ERR, "CX11DataDevice::sendEnter: No xwayland surface for destination");
|
||||
@ -118,54 +118,54 @@ void CX11DataDevice::sendEnter(uint32_t serial, SP<CWLSurfaceResource> surf, con
|
||||
// reserve to avoid reallocations
|
||||
targets.reserve(SOURCE->mimes().size());
|
||||
for (auto const& m : SOURCE->mimes()) {
|
||||
targets.push_back(g_pXWayland->pWM->mimeToAtom(m));
|
||||
targets.push_back(g_pXWayland->m_wm->mimeToAtom(m));
|
||||
}
|
||||
|
||||
xcb_change_property(g_pXWayland->pWM->connection, XCB_PROP_MODE_REPLACE, g_pXWayland->pWM->dndSelection.window, HYPRATOMS["XdndTypeList"], XCB_ATOM_ATOM, 32, targets.size(),
|
||||
targets.data());
|
||||
xcb_change_property(g_pXWayland->m_wm->m_connection, XCB_PROP_MODE_REPLACE, g_pXWayland->m_wm->m_dndSelection.window, HYPRATOMS["XdndTypeList"], XCB_ATOM_ATOM, 32,
|
||||
targets.size(), targets.data());
|
||||
|
||||
xcb_set_selection_owner(g_pXWayland->pWM->connection, g_pXWayland->pWM->dndSelection.window, HYPRATOMS["XdndSelection"], XCB_TIME_CURRENT_TIME);
|
||||
xcb_flush(g_pXWayland->pWM->connection);
|
||||
xcb_set_selection_owner(g_pXWayland->m_wm->m_connection, g_pXWayland->m_wm->m_dndSelection.window, HYPRATOMS["XdndSelection"], XCB_TIME_CURRENT_TIME);
|
||||
xcb_flush(g_pXWayland->m_wm->m_connection);
|
||||
|
||||
xcb_window_t targetWindow = getProxyWindow(XSURF->xID);
|
||||
xcb_window_t targetWindow = getProxyWindow(XSURF->m_xID);
|
||||
|
||||
xcb_client_message_data_t data = {{0}};
|
||||
data.data32[0] = g_pXWayland->pWM->dndSelection.window;
|
||||
data.data32[0] = g_pXWayland->m_wm->m_dndSelection.window;
|
||||
data.data32[1] = XDND_VERSION << 24;
|
||||
data.data32[1] |= 1;
|
||||
|
||||
sendDndEvent(targetWindow, HYPRATOMS["XdndEnter"], data);
|
||||
|
||||
lastSurface = XSURF;
|
||||
lastOffer = offer;
|
||||
m_lastSurface = XSURF;
|
||||
m_lastOffer = offer;
|
||||
|
||||
auto hlSurface = XSURF->surface.lock();
|
||||
auto hlSurface = XSURF->m_surface.lock();
|
||||
if (!hlSurface) {
|
||||
Debug::log(ERR, "CX11DataDevice::sendEnter: Non desktop x surface?!");
|
||||
lastSurfaceCoords = {};
|
||||
m_lastSurfaceCoords = {};
|
||||
return;
|
||||
}
|
||||
|
||||
lastSurfaceCoords = g_pXWaylandManager->xwaylandToWaylandCoords(XSURF->geometry.pos());
|
||||
m_lastSurfaceCoords = g_pXWaylandManager->xwaylandToWaylandCoords(XSURF->m_geometry.pos());
|
||||
#endif
|
||||
}
|
||||
|
||||
void CX11DataDevice::cleanupState() {
|
||||
lastSurface.reset();
|
||||
lastOffer.reset();
|
||||
lastSurfaceCoords = {};
|
||||
lastTime = 0;
|
||||
m_lastSurface.reset();
|
||||
m_lastOffer.reset();
|
||||
m_lastSurfaceCoords = {};
|
||||
m_lastTime = 0;
|
||||
}
|
||||
|
||||
void CX11DataDevice::sendLeave() {
|
||||
#ifndef NO_XWAYLAND
|
||||
if (!lastSurface)
|
||||
if (!m_lastSurface)
|
||||
return;
|
||||
|
||||
xcb_window_t targetWindow = getProxyWindow(lastSurface->xID);
|
||||
xcb_window_t targetWindow = getProxyWindow(m_lastSurface->m_xID);
|
||||
|
||||
xcb_client_message_data_t data = {{0}};
|
||||
data.data32[0] = g_pXWayland->pWM->dndSelection.window;
|
||||
data.data32[0] = g_pXWayland->m_wm->m_dndSelection.window;
|
||||
|
||||
sendDndEvent(targetWindow, HYPRATOMS["XdndLeave"], data);
|
||||
|
||||
@ -175,38 +175,38 @@ void CX11DataDevice::sendLeave() {
|
||||
|
||||
void CX11DataDevice::sendMotion(uint32_t timeMs, const Vector2D& local) {
|
||||
#ifndef NO_XWAYLAND
|
||||
if (!lastSurface || !lastOffer || !lastOffer->getSource())
|
||||
if (!m_lastSurface || !m_lastOffer || !m_lastOffer->getSource())
|
||||
return;
|
||||
|
||||
xcb_window_t targetWindow = getProxyWindow(lastSurface->xID);
|
||||
xcb_window_t targetWindow = getProxyWindow(m_lastSurface->m_xID);
|
||||
|
||||
const auto XCOORDS = g_pXWaylandManager->waylandToXWaylandCoords(lastSurfaceCoords + local);
|
||||
const auto XCOORDS = g_pXWaylandManager->waylandToXWaylandCoords(m_lastSurfaceCoords + local);
|
||||
const uint32_t coords = ((uint32_t)XCOORDS.x << 16) | (uint32_t)XCOORDS.y;
|
||||
|
||||
xcb_client_message_data_t data = {{0}};
|
||||
data.data32[0] = g_pXWayland->pWM->dndSelection.window;
|
||||
data.data32[0] = g_pXWayland->m_wm->m_dndSelection.window;
|
||||
data.data32[2] = coords;
|
||||
data.data32[3] = timeMs;
|
||||
data.data32[4] = dndActionToAtom(lastOffer->getSource()->actions());
|
||||
data.data32[4] = dndActionToAtom(m_lastOffer->getSource()->actions());
|
||||
|
||||
sendDndEvent(targetWindow, HYPRATOMS["XdndPosition"], data);
|
||||
|
||||
lastTime = timeMs;
|
||||
m_lastTime = timeMs;
|
||||
#endif
|
||||
}
|
||||
|
||||
void CX11DataDevice::sendDrop() {
|
||||
#ifndef NO_XWAYLAND
|
||||
if (!lastSurface || !lastOffer) {
|
||||
if (!m_lastSurface || !m_lastOffer) {
|
||||
Debug::log(ERR, "CX11DataDevice::sendDrop: No surface or offer");
|
||||
return;
|
||||
}
|
||||
|
||||
xcb_window_t targetWindow = getProxyWindow(lastSurface->xID);
|
||||
xcb_window_t targetWindow = getProxyWindow(m_lastSurface->m_xID);
|
||||
|
||||
xcb_client_message_data_t data = {{0}};
|
||||
data.data32[0] = g_pXWayland->pWM->dndSelection.window;
|
||||
data.data32[2] = lastTime;
|
||||
data.data32[0] = g_pXWayland->m_wm->m_dndSelection.window;
|
||||
data.data32[2] = m_lastTime;
|
||||
|
||||
sendDndEvent(targetWindow, HYPRATOMS["XdndDrop"], data);
|
||||
|
||||
@ -227,11 +227,11 @@ SP<CWLDataDeviceResource> CX11DataDevice::getWayland() {
|
||||
}
|
||||
|
||||
SP<CX11DataDevice> CX11DataDevice::getX11() {
|
||||
return self.lock();
|
||||
return m_self.lock();
|
||||
}
|
||||
|
||||
std::vector<std::string> CX11DataSource::mimes() {
|
||||
return mimeTypes;
|
||||
return m_mimeTypes;
|
||||
}
|
||||
|
||||
void CX11DataSource::send(const std::string& mime, CFileDescriptor fd) {
|
||||
@ -243,30 +243,30 @@ void CX11DataSource::accepted(const std::string& mime) {
|
||||
}
|
||||
|
||||
void CX11DataSource::cancelled() {
|
||||
dndSuccess = false;
|
||||
dropped = false;
|
||||
m_dndSuccess = false;
|
||||
m_dropped = false;
|
||||
}
|
||||
|
||||
bool CX11DataSource::hasDnd() {
|
||||
return dnd;
|
||||
return m_dnd;
|
||||
}
|
||||
|
||||
bool CX11DataSource::dndDone() {
|
||||
return dropped;
|
||||
return m_dropped;
|
||||
}
|
||||
|
||||
void CX11DataSource::error(uint32_t code, const std::string& msg) {
|
||||
Debug::log(ERR, "CX11DataSource error: code {} msg {}", code, msg);
|
||||
dndSuccess = false;
|
||||
dropped = false;
|
||||
m_dndSuccess = false;
|
||||
m_dropped = false;
|
||||
}
|
||||
|
||||
void CX11DataSource::sendDndFinished() {
|
||||
dndSuccess = true;
|
||||
m_dndSuccess = true;
|
||||
}
|
||||
|
||||
uint32_t CX11DataSource::actions() {
|
||||
return supportedActions;
|
||||
return m_supportedActions;
|
||||
}
|
||||
|
||||
eDataSourceType CX11DataSource::type() {
|
||||
@ -274,7 +274,7 @@ eDataSourceType CX11DataSource::type() {
|
||||
}
|
||||
|
||||
void CX11DataSource::sendDndDropPerformed() {
|
||||
dropped = true;
|
||||
m_dropped = true;
|
||||
}
|
||||
|
||||
void CX11DataSource::sendDndAction(wl_data_device_manager_dnd_action a) {
|
||||
@ -283,16 +283,16 @@ void CX11DataSource::sendDndAction(wl_data_device_manager_dnd_action a) {
|
||||
|
||||
void CX11DataDevice::forceCleanupDnd() {
|
||||
#ifndef NO_XWAYLAND
|
||||
if (lastOffer) {
|
||||
auto source = lastOffer->getSource();
|
||||
if (m_lastOffer) {
|
||||
auto source = m_lastOffer->getSource();
|
||||
if (source) {
|
||||
source->cancelled();
|
||||
source->sendDndFinished();
|
||||
}
|
||||
}
|
||||
|
||||
xcb_set_selection_owner(g_pXWayland->pWM->connection, XCB_ATOM_NONE, HYPRATOMS["XdndSelection"], XCB_TIME_CURRENT_TIME);
|
||||
xcb_flush(g_pXWayland->pWM->connection);
|
||||
xcb_set_selection_owner(g_pXWayland->m_wm->m_connection, XCB_ATOM_NONE, HYPRATOMS["XdndSelection"], XCB_TIME_CURRENT_TIME);
|
||||
xcb_flush(g_pXWayland->m_wm->m_connection);
|
||||
|
||||
cleanupState();
|
||||
|
||||
|
@ -22,15 +22,9 @@ class CX11DataOffer : public IDataOffer {
|
||||
virtual SP<IDataSource> getSource();
|
||||
virtual void markDead();
|
||||
|
||||
WP<IDataSource> source;
|
||||
WP<CX11DataOffer> self;
|
||||
WP<CXWaylandSurface> xwaylandSurface;
|
||||
|
||||
bool dead = false;
|
||||
bool accepted = false;
|
||||
bool recvd = false;
|
||||
|
||||
uint32_t actions = 0;
|
||||
WP<IDataSource> m_source;
|
||||
WP<CX11DataOffer> m_self;
|
||||
WP<CXWaylandSurface> m_xwaylandSurface;
|
||||
};
|
||||
|
||||
class CX11DataSource : public IDataSource {
|
||||
@ -51,15 +45,12 @@ class CX11DataSource : public IDataSource {
|
||||
virtual void sendDndDropPerformed();
|
||||
virtual void sendDndAction(wl_data_device_manager_dnd_action a);
|
||||
|
||||
bool used = false;
|
||||
bool dnd = true;
|
||||
bool dndSuccess = false;
|
||||
bool dropped = false;
|
||||
bool m_dnd = true;
|
||||
bool m_dndSuccess = false;
|
||||
bool m_dropped = false;
|
||||
|
||||
WP<CX11DataSource> self;
|
||||
|
||||
std::vector<std::string> mimeTypes;
|
||||
uint32_t supportedActions = 0;
|
||||
std::vector<std::string> m_mimeTypes;
|
||||
uint32_t m_supportedActions = 0;
|
||||
};
|
||||
|
||||
class CX11DataDevice : public IDataDevice {
|
||||
@ -77,7 +68,7 @@ class CX11DataDevice : public IDataDevice {
|
||||
virtual eDataSourceType type();
|
||||
void forceCleanupDnd();
|
||||
|
||||
WP<CX11DataDevice> self;
|
||||
WP<CX11DataDevice> m_self;
|
||||
|
||||
private:
|
||||
void cleanupState();
|
||||
@ -85,8 +76,8 @@ class CX11DataDevice : public IDataDevice {
|
||||
xcb_window_t getProxyWindow(xcb_window_t window);
|
||||
void sendDndEvent(xcb_window_t targetWindow, xcb_atom_t type, xcb_client_message_data_t& data);
|
||||
#endif
|
||||
WP<CXWaylandSurface> lastSurface;
|
||||
WP<IDataOffer> lastOffer;
|
||||
Vector2D lastSurfaceCoords;
|
||||
uint32_t lastTime = 0;
|
||||
WP<CXWaylandSurface> m_lastSurface;
|
||||
WP<IDataOffer> m_lastOffer;
|
||||
Vector2D m_lastSurfaceCoords;
|
||||
uint32_t m_lastTime = 0;
|
||||
};
|
||||
|
@ -172,12 +172,12 @@ static bool openSockets(std::array<CFileDescriptor, 2>& sockets, int display) {
|
||||
}
|
||||
|
||||
static void startServer(void* data) {
|
||||
if (!g_pXWayland->pServer->start())
|
||||
if (!g_pXWayland->m_server->start())
|
||||
Debug::log(ERR, "The XWayland server could not start! XWayland will not work...");
|
||||
}
|
||||
|
||||
static int xwaylandReady(int fd, uint32_t mask, void* data) {
|
||||
return g_pXWayland->pServer->ready(fd, mask);
|
||||
return g_pXWayland->m_server->ready(fd, mask);
|
||||
}
|
||||
|
||||
static bool safeRemove(const std::string& path) {
|
||||
@ -194,7 +194,7 @@ bool CXWaylandServer::tryOpenSockets() {
|
||||
CFileDescriptor fd{open(lockPath.c_str(), O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, LOCK_FILE_MODE)};
|
||||
if (fd.isValid()) {
|
||||
// we managed to open the lock
|
||||
if (!openSockets(xFDs, i)) {
|
||||
if (!openSockets(m_xFDs, i)) {
|
||||
safeRemove(lockPath);
|
||||
continue;
|
||||
}
|
||||
@ -205,8 +205,8 @@ bool CXWaylandServer::tryOpenSockets() {
|
||||
continue;
|
||||
}
|
||||
|
||||
display = i;
|
||||
displayName = std::format(":{}", display);
|
||||
m_display = i;
|
||||
m_displayName = std::format(":{}", m_display);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -230,12 +230,12 @@ bool CXWaylandServer::tryOpenSockets() {
|
||||
}
|
||||
}
|
||||
|
||||
if (display < 0) {
|
||||
if (m_display < 0) {
|
||||
Debug::log(ERR, "Failed to find a suitable socket for XWayland");
|
||||
return false;
|
||||
}
|
||||
|
||||
Debug::log(LOG, "XWayland found a suitable display socket at DISPLAY: {}", displayName);
|
||||
Debug::log(LOG, "XWayland found a suitable display socket at DISPLAY: {}", m_displayName);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -245,63 +245,63 @@ CXWaylandServer::CXWaylandServer() {
|
||||
|
||||
CXWaylandServer::~CXWaylandServer() {
|
||||
die();
|
||||
if (display < 0)
|
||||
if (m_display < 0)
|
||||
return;
|
||||
|
||||
std::string lockPath = std::format("/tmp/.X{}-lock", display);
|
||||
std::string lockPath = std::format("/tmp/.X{}-lock", m_display);
|
||||
safeRemove(lockPath);
|
||||
|
||||
std::string path;
|
||||
for (bool isLinux : {true, false}) {
|
||||
path = getSocketPath(display, isLinux);
|
||||
path = getSocketPath(m_display, isLinux);
|
||||
safeRemove(path);
|
||||
}
|
||||
}
|
||||
|
||||
void CXWaylandServer::die() {
|
||||
if (display < 0)
|
||||
if (m_display < 0)
|
||||
return;
|
||||
|
||||
if (xFDReadEvents[0]) {
|
||||
wl_event_source_remove(xFDReadEvents[0]);
|
||||
wl_event_source_remove(xFDReadEvents[1]);
|
||||
xFDReadEvents = {nullptr, nullptr};
|
||||
if (m_xFDReadEvents[0]) {
|
||||
wl_event_source_remove(m_xFDReadEvents[0]);
|
||||
wl_event_source_remove(m_xFDReadEvents[1]);
|
||||
m_xFDReadEvents = {nullptr, nullptr};
|
||||
}
|
||||
|
||||
if (pipeSource)
|
||||
wl_event_source_remove(pipeSource);
|
||||
if (m_pipeSource)
|
||||
wl_event_source_remove(m_pipeSource);
|
||||
|
||||
// possible crash. Better to leak a bit.
|
||||
//if (xwaylandClient)
|
||||
// wl_client_destroy(xwaylandClient);
|
||||
|
||||
xwaylandClient = nullptr;
|
||||
m_xwaylandClient = nullptr;
|
||||
}
|
||||
|
||||
bool CXWaylandServer::create() {
|
||||
if (!tryOpenSockets())
|
||||
return false;
|
||||
|
||||
setenv("DISPLAY", displayName.c_str(), true);
|
||||
setenv("DISPLAY", m_displayName.c_str(), true);
|
||||
|
||||
// TODO: lazy mode
|
||||
|
||||
idleSource = wl_event_loop_add_idle(g_pCompositor->m_wlEventLoop, ::startServer, nullptr);
|
||||
m_idleSource = wl_event_loop_add_idle(g_pCompositor->m_wlEventLoop, ::startServer, nullptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CXWaylandServer::runXWayland(CFileDescriptor& notifyFD) {
|
||||
if (!xFDs[0].setFlags(xFDs[0].getFlags() & ~FD_CLOEXEC) || !xFDs[1].setFlags(xFDs[1].getFlags() & ~FD_CLOEXEC) ||
|
||||
!waylandFDs[1].setFlags(waylandFDs[1].getFlags() & ~FD_CLOEXEC) || !xwmFDs[1].setFlags(xwmFDs[1].getFlags() & ~FD_CLOEXEC)) {
|
||||
if (!m_xFDs[0].setFlags(m_xFDs[0].getFlags() & ~FD_CLOEXEC) || !m_xFDs[1].setFlags(m_xFDs[1].getFlags() & ~FD_CLOEXEC) ||
|
||||
!m_waylandFDs[1].setFlags(m_waylandFDs[1].getFlags() & ~FD_CLOEXEC) || !m_xwmFDs[1].setFlags(m_xwmFDs[1].getFlags() & ~FD_CLOEXEC)) {
|
||||
Debug::log(ERR, "Failed to unset cloexec on fds");
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
auto cmd =
|
||||
std::format("Xwayland {} -rootless -core -listenfd {} -listenfd {} -displayfd {} -wm {}", displayName, xFDs[0].get(), xFDs[1].get(), notifyFD.get(), xwmFDs[1].get());
|
||||
auto cmd = std::format("Xwayland {} -rootless -core -listenfd {} -listenfd {} -displayfd {} -wm {}", m_displayName, m_xFDs[0].get(), m_xFDs[1].get(), notifyFD.get(),
|
||||
m_xwmFDs[1].get());
|
||||
|
||||
auto waylandSocket = std::format("{}", waylandFDs[1].get());
|
||||
auto waylandSocket = std::format("{}", m_waylandFDs[1].get());
|
||||
setenv("WAYLAND_SOCKET", waylandSocket.c_str(), true);
|
||||
|
||||
Debug::log(LOG, "Starting XWayland with \"{}\", bon voyage!", cmd);
|
||||
@ -313,17 +313,17 @@ void CXWaylandServer::runXWayland(CFileDescriptor& notifyFD) {
|
||||
}
|
||||
|
||||
bool CXWaylandServer::start() {
|
||||
idleSource = nullptr;
|
||||
m_idleSource = nullptr;
|
||||
int wlPair[2] = {-1, -1};
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, wlPair) != 0) {
|
||||
Debug::log(ERR, "socketpair failed (1)");
|
||||
die();
|
||||
return false;
|
||||
}
|
||||
waylandFDs[0] = CFileDescriptor{wlPair[0]};
|
||||
waylandFDs[1] = CFileDescriptor{wlPair[1]};
|
||||
m_waylandFDs[0] = CFileDescriptor{wlPair[0]};
|
||||
m_waylandFDs[1] = CFileDescriptor{wlPair[1]};
|
||||
|
||||
if (!waylandFDs[0].setFlags(waylandFDs[0].getFlags() | FD_CLOEXEC) || !waylandFDs[1].setFlags(waylandFDs[1].getFlags() | FD_CLOEXEC)) {
|
||||
if (!m_waylandFDs[0].setFlags(m_waylandFDs[0].getFlags() | FD_CLOEXEC) || !m_waylandFDs[1].setFlags(m_waylandFDs[1].getFlags() | FD_CLOEXEC)) {
|
||||
Debug::log(ERR, "set_cloexec failed (1)");
|
||||
die();
|
||||
return false;
|
||||
@ -336,23 +336,23 @@ bool CXWaylandServer::start() {
|
||||
return false;
|
||||
}
|
||||
|
||||
xwmFDs[0] = CFileDescriptor{xwmPair[0]};
|
||||
xwmFDs[1] = CFileDescriptor{xwmPair[1]};
|
||||
m_xwmFDs[0] = CFileDescriptor{xwmPair[0]};
|
||||
m_xwmFDs[1] = CFileDescriptor{xwmPair[1]};
|
||||
|
||||
if (!xwmFDs[0].setFlags(xwmFDs[0].getFlags() | FD_CLOEXEC) || !xwmFDs[1].setFlags(xwmFDs[1].getFlags() | FD_CLOEXEC)) {
|
||||
if (!m_xwmFDs[0].setFlags(m_xwmFDs[0].getFlags() | FD_CLOEXEC) || !m_xwmFDs[1].setFlags(m_xwmFDs[1].getFlags() | FD_CLOEXEC)) {
|
||||
Debug::log(ERR, "set_cloexec failed (2)");
|
||||
die();
|
||||
return false;
|
||||
}
|
||||
|
||||
xwaylandClient = wl_client_create(g_pCompositor->m_wlDisplay, waylandFDs[0].get());
|
||||
if (!xwaylandClient) {
|
||||
m_xwaylandClient = wl_client_create(g_pCompositor->m_wlDisplay, m_waylandFDs[0].get());
|
||||
if (!m_xwaylandClient) {
|
||||
Debug::log(ERR, "wl_client_create failed");
|
||||
die();
|
||||
return false;
|
||||
}
|
||||
|
||||
waylandFDs[0].take(); // wl_client owns this fd now
|
||||
m_waylandFDs[0].take(); // wl_client owns this fd now
|
||||
|
||||
int notify[2] = {-1, -1};
|
||||
if (pipe(notify) < 0) {
|
||||
@ -369,8 +369,8 @@ bool CXWaylandServer::start() {
|
||||
return false;
|
||||
}
|
||||
|
||||
pipeSource = wl_event_loop_add_fd(g_pCompositor->m_wlEventLoop, notifyFds[0].get(), WL_EVENT_READABLE, ::xwaylandReady, nullptr);
|
||||
pipeFd = std::move(notifyFds[0]);
|
||||
m_pipeSource = wl_event_loop_add_fd(g_pCompositor->m_wlEventLoop, notifyFds[0].get(), WL_EVENT_READABLE, ::xwaylandReady, nullptr);
|
||||
m_pipeFd = std::move(notifyFds[0]);
|
||||
|
||||
auto serverPID = fork();
|
||||
if (serverPID < 0) {
|
||||
@ -400,19 +400,19 @@ int CXWaylandServer::ready(int fd, uint32_t mask) {
|
||||
// if we don't have readable here, it failed
|
||||
if (!(mask & WL_EVENT_READABLE)) {
|
||||
Debug::log(ERR, "Xwayland: startup failed, not setting up xwm");
|
||||
g_pXWayland->pServer.reset();
|
||||
g_pXWayland->m_server.reset();
|
||||
return 1;
|
||||
}
|
||||
|
||||
Debug::log(LOG, "XWayland is ready");
|
||||
|
||||
wl_event_source_remove(pipeSource);
|
||||
pipeFd.reset();
|
||||
pipeSource = nullptr;
|
||||
wl_event_source_remove(m_pipeSource);
|
||||
m_pipeFd.reset();
|
||||
m_pipeSource = nullptr;
|
||||
|
||||
// start the wm
|
||||
if (!g_pXWayland->pWM)
|
||||
g_pXWayland->pWM = makeUnique<CXWM>();
|
||||
if (!g_pXWayland->m_wm)
|
||||
g_pXWayland->m_wm = makeUnique<CXWM>();
|
||||
|
||||
g_pCursorManager->setXWaylandCursor();
|
||||
|
||||
|
@ -20,29 +20,25 @@ class CXWaylandServer {
|
||||
bool start();
|
||||
|
||||
// called on ready
|
||||
int ready(int fd, uint32_t mask);
|
||||
int ready(int fd, uint32_t mask);
|
||||
|
||||
void die();
|
||||
void die();
|
||||
|
||||
struct {
|
||||
CSignal ready;
|
||||
} events;
|
||||
|
||||
wl_client* xwaylandClient = nullptr;
|
||||
wl_client* m_xwaylandClient = nullptr;
|
||||
|
||||
private:
|
||||
bool tryOpenSockets();
|
||||
void runXWayland(Hyprutils::OS::CFileDescriptor& notifyFD);
|
||||
|
||||
std::string displayName;
|
||||
int display = -1;
|
||||
std::array<Hyprutils::OS::CFileDescriptor, 2> xFDs;
|
||||
std::array<wl_event_source*, 2> xFDReadEvents = {nullptr, nullptr};
|
||||
wl_event_source* idleSource = nullptr;
|
||||
wl_event_source* pipeSource = nullptr;
|
||||
Hyprutils::OS::CFileDescriptor pipeFd;
|
||||
std::array<Hyprutils::OS::CFileDescriptor, 2> xwmFDs;
|
||||
std::array<Hyprutils::OS::CFileDescriptor, 2> waylandFDs;
|
||||
std::string m_displayName;
|
||||
int m_display = -1;
|
||||
std::array<Hyprutils::OS::CFileDescriptor, 2> m_xFDs;
|
||||
std::array<wl_event_source*, 2> m_xFDReadEvents = {nullptr, nullptr};
|
||||
wl_event_source* m_idleSource = nullptr;
|
||||
wl_event_source* m_pipeSource = nullptr;
|
||||
Hyprutils::OS::CFileDescriptor m_pipeFd;
|
||||
std::array<Hyprutils::OS::CFileDescriptor, 2> m_xwmFDs;
|
||||
std::array<Hyprutils::OS::CFileDescriptor, 2> m_waylandFDs;
|
||||
|
||||
friend class CXWM;
|
||||
};
|
||||
|
@ -7,12 +7,12 @@
|
||||
#include <fcntl.h>
|
||||
using namespace Hyprutils::OS;
|
||||
|
||||
CXDataSource::CXDataSource(SXSelection& sel_) : selection(sel_) {
|
||||
xcb_get_property_cookie_t cookie = xcb_get_property(g_pXWayland->pWM->connection,
|
||||
CXDataSource::CXDataSource(SXSelection& sel_) : m_selection(sel_) {
|
||||
xcb_get_property_cookie_t cookie = xcb_get_property(g_pXWayland->m_wm->m_connection,
|
||||
1, // delete
|
||||
selection.window, HYPRATOMS["_WL_SELECTION"], XCB_GET_PROPERTY_TYPE_ANY, 0, 4096);
|
||||
m_selection.window, HYPRATOMS["_WL_SELECTION"], XCB_GET_PROPERTY_TYPE_ANY, 0, 4096);
|
||||
|
||||
xcb_get_property_reply_t* reply = xcb_get_property_reply(g_pXWayland->pWM->connection, cookie, nullptr);
|
||||
xcb_get_property_reply_t* reply = xcb_get_property_reply(g_pXWayland->m_wm->m_connection, cookie, nullptr);
|
||||
if (!reply)
|
||||
return;
|
||||
|
||||
@ -24,28 +24,28 @@ CXDataSource::CXDataSource(SXSelection& sel_) : selection(sel_) {
|
||||
auto value = (xcb_atom_t*)xcb_get_property_value(reply);
|
||||
for (uint32_t i = 0; i < reply->value_len; i++) {
|
||||
if (value[i] == HYPRATOMS["UTF8_STRING"])
|
||||
mimeTypes.emplace_back("text/plain;charset=utf-8");
|
||||
m_mimeTypes.emplace_back("text/plain;charset=utf-8");
|
||||
else if (value[i] == HYPRATOMS["TEXT"])
|
||||
mimeTypes.emplace_back("text/plain");
|
||||
m_mimeTypes.emplace_back("text/plain");
|
||||
else if (value[i] != HYPRATOMS["TARGETS"] && value[i] != HYPRATOMS["TIMESTAMP"]) {
|
||||
|
||||
auto type = g_pXWayland->pWM->mimeFromAtom(value[i]);
|
||||
auto type = g_pXWayland->m_wm->mimeFromAtom(value[i]);
|
||||
|
||||
if (type == "INVALID")
|
||||
continue;
|
||||
|
||||
mimeTypes.push_back(type);
|
||||
m_mimeTypes.push_back(type);
|
||||
} else
|
||||
continue;
|
||||
|
||||
mimeAtoms.push_back(value[i]);
|
||||
m_mimeAtoms.push_back(value[i]);
|
||||
}
|
||||
|
||||
free(reply);
|
||||
}
|
||||
|
||||
std::vector<std::string> CXDataSource::mimes() {
|
||||
return mimeTypes;
|
||||
return m_mimeTypes;
|
||||
}
|
||||
|
||||
void CXDataSource::send(const std::string& mime, CFileDescriptor fd) {
|
||||
@ -56,9 +56,9 @@ void CXDataSource::send(const std::string& mime, CFileDescriptor fd) {
|
||||
else if (mime == "text/plain;charset=utf-8")
|
||||
mimeAtom = HYPRATOMS["UTF8_STRING"];
|
||||
else {
|
||||
for (size_t i = 0; i < mimeTypes.size(); ++i) {
|
||||
if (mimeTypes[i] == mime) {
|
||||
mimeAtom = mimeAtoms[i];
|
||||
for (size_t i = 0; i < m_mimeTypes.size(); ++i) {
|
||||
if (m_mimeTypes[i] == mime) {
|
||||
mimeAtom = m_mimeAtoms[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -71,26 +71,26 @@ void CXDataSource::send(const std::string& mime, CFileDescriptor fd) {
|
||||
|
||||
Debug::log(LOG, "[XDataSource] send with mime {} to fd {}", mime, fd.get());
|
||||
|
||||
auto transfer = makeUnique<SXTransfer>(selection);
|
||||
transfer->incomingWindow = xcb_generate_id(g_pXWayland->pWM->connection);
|
||||
auto transfer = makeUnique<SXTransfer>(m_selection);
|
||||
transfer->incomingWindow = xcb_generate_id(g_pXWayland->m_wm->m_connection);
|
||||
const uint32_t MASK = XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_PROPERTY_CHANGE;
|
||||
xcb_create_window(g_pXWayland->pWM->connection, XCB_COPY_FROM_PARENT, transfer->incomingWindow, g_pXWayland->pWM->screen->root, 0, 0, 10, 10, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT,
|
||||
g_pXWayland->pWM->screen->root_visual, XCB_CW_EVENT_MASK, &MASK);
|
||||
xcb_create_window(g_pXWayland->m_wm->m_connection, XCB_COPY_FROM_PARENT, transfer->incomingWindow, g_pXWayland->m_wm->m_screen->root, 0, 0, 10, 10, 0,
|
||||
XCB_WINDOW_CLASS_INPUT_OUTPUT, g_pXWayland->m_wm->m_screen->root_visual, XCB_CW_EVENT_MASK, &MASK);
|
||||
|
||||
xcb_atom_t selection_atom = HYPRATOMS["CLIPBOARD"];
|
||||
if (&selection == &g_pXWayland->pWM->primarySelection)
|
||||
if (&m_selection == &g_pXWayland->m_wm->m_primarySelection)
|
||||
selection_atom = HYPRATOMS["PRIMARY"];
|
||||
else if (&selection == &g_pXWayland->pWM->dndSelection)
|
||||
else if (&m_selection == &g_pXWayland->m_wm->m_dndSelection)
|
||||
selection_atom = HYPRATOMS["XdndSelection"];
|
||||
|
||||
xcb_convert_selection(g_pXWayland->pWM->connection, transfer->incomingWindow, selection_atom, mimeAtom, HYPRATOMS["_WL_SELECTION"], XCB_TIME_CURRENT_TIME);
|
||||
xcb_convert_selection(g_pXWayland->m_wm->m_connection, transfer->incomingWindow, selection_atom, mimeAtom, HYPRATOMS["_WL_SELECTION"], XCB_TIME_CURRENT_TIME);
|
||||
|
||||
xcb_flush(g_pXWayland->pWM->connection);
|
||||
xcb_flush(g_pXWayland->m_wm->m_connection);
|
||||
|
||||
//TODO: make CFileDescriptor setflags take SETFL aswell
|
||||
fcntl(fd.get(), F_SETFL, O_WRONLY | O_NONBLOCK);
|
||||
transfer->wlFD = std::move(fd);
|
||||
selection.transfers.emplace_back(std::move(transfer));
|
||||
m_selection.transfers.emplace_back(std::move(transfer));
|
||||
}
|
||||
|
||||
void CXDataSource::accepted(const std::string& mime) {
|
||||
|
@ -17,7 +17,7 @@ class CXDataSource : public IDataSource {
|
||||
virtual eDataSourceType type();
|
||||
|
||||
private:
|
||||
SXSelection& selection;
|
||||
std::vector<std::string> mimeTypes; // these two have shared idx
|
||||
std::vector<uint32_t> mimeAtoms; //
|
||||
SXSelection& m_selection;
|
||||
std::vector<std::string> m_mimeTypes; // these two have shared idx
|
||||
std::vector<uint32_t> m_mimeAtoms; //
|
||||
};
|
||||
|
@ -9,19 +9,19 @@
|
||||
|
||||
#include <ranges>
|
||||
|
||||
CXWaylandSurface::CXWaylandSurface(uint32_t xID_, CBox geometry_, bool OR) : xID(xID_), geometry(geometry_), overrideRedirect(OR) {
|
||||
CXWaylandSurface::CXWaylandSurface(uint32_t xID_, CBox geometry_, bool OR) : m_xID(xID_), m_geometry(geometry_), m_overrideRedirect(OR) {
|
||||
xcb_res_query_client_ids_cookie_t client_id_cookie = {0};
|
||||
if (g_pXWayland->pWM->xres) {
|
||||
xcb_res_client_id_spec_t spec = {.client = xID, .mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID};
|
||||
client_id_cookie = xcb_res_query_client_ids(g_pXWayland->pWM->connection, 1, &spec);
|
||||
if (g_pXWayland->m_wm->m_xres) {
|
||||
xcb_res_client_id_spec_t spec = {.client = m_xID, .mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID};
|
||||
client_id_cookie = xcb_res_query_client_ids(g_pXWayland->m_wm->m_connection, 1, &spec);
|
||||
}
|
||||
|
||||
uint32_t values[1];
|
||||
values[0] = XCB_EVENT_MASK_FOCUS_CHANGE | XCB_EVENT_MASK_PROPERTY_CHANGE;
|
||||
xcb_change_window_attributes(g_pXWayland->pWM->connection, xID, XCB_CW_EVENT_MASK, values);
|
||||
xcb_change_window_attributes(g_pXWayland->m_wm->m_connection, m_xID, XCB_CW_EVENT_MASK, values);
|
||||
|
||||
if (g_pXWayland->pWM->xres) {
|
||||
xcb_res_query_client_ids_reply_t* reply = xcb_res_query_client_ids_reply(g_pXWayland->pWM->connection, client_id_cookie, nullptr);
|
||||
if (g_pXWayland->m_wm->m_xres) {
|
||||
xcb_res_query_client_ids_reply_t* reply = xcb_res_query_client_ids_reply(g_pXWayland->m_wm->m_connection, client_id_cookie, nullptr);
|
||||
if (!reply)
|
||||
return;
|
||||
|
||||
@ -38,101 +38,101 @@ CXWaylandSurface::CXWaylandSurface(uint32_t xID_, CBox geometry_, bool OR) : xID
|
||||
free(reply);
|
||||
return;
|
||||
}
|
||||
pid = *ppid;
|
||||
m_pid = *ppid;
|
||||
free(reply);
|
||||
}
|
||||
|
||||
events.resourceChange.registerStaticListener([this](void* data, std::any d) { ensureListeners(); }, nullptr);
|
||||
m_events.resourceChange.registerStaticListener([this](void* data, std::any d) { ensureListeners(); }, nullptr);
|
||||
}
|
||||
|
||||
void CXWaylandSurface::ensureListeners() {
|
||||
bool connected = listeners.destroySurface;
|
||||
bool connected = m_listeners.destroySurface;
|
||||
|
||||
if (connected && !surface) {
|
||||
listeners.destroySurface.reset();
|
||||
listeners.commitSurface.reset();
|
||||
} else if (!connected && surface) {
|
||||
listeners.destroySurface = surface->m_events.destroy.registerListener([this](std::any d) {
|
||||
if (mapped)
|
||||
if (connected && !m_surface) {
|
||||
m_listeners.destroySurface.reset();
|
||||
m_listeners.commitSurface.reset();
|
||||
} else if (!connected && m_surface) {
|
||||
m_listeners.destroySurface = m_surface->m_events.destroy.registerListener([this](std::any d) {
|
||||
if (m_mapped)
|
||||
unmap();
|
||||
|
||||
surface.reset();
|
||||
listeners.destroySurface.reset();
|
||||
listeners.commitSurface.reset();
|
||||
events.resourceChange.emit();
|
||||
m_surface.reset();
|
||||
m_listeners.destroySurface.reset();
|
||||
m_listeners.commitSurface.reset();
|
||||
m_events.resourceChange.emit();
|
||||
});
|
||||
|
||||
listeners.commitSurface = surface->m_events.commit.registerListener([this](std::any d) {
|
||||
if (surface->m_current.texture && !mapped) {
|
||||
m_listeners.commitSurface = m_surface->m_events.commit.registerListener([this](std::any d) {
|
||||
if (m_surface->m_current.texture && !m_mapped) {
|
||||
map();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!surface->m_current.texture && mapped) {
|
||||
if (!m_surface->m_current.texture && m_mapped) {
|
||||
unmap();
|
||||
return;
|
||||
}
|
||||
|
||||
events.commit.emit();
|
||||
m_events.commit.emit();
|
||||
});
|
||||
}
|
||||
|
||||
if (resource) {
|
||||
listeners.destroyResource = resource->events.destroy.registerListener([this](std::any d) {
|
||||
if (m_resource) {
|
||||
m_listeners.destroyResource = m_resource->events.destroy.registerListener([this](std::any d) {
|
||||
unmap();
|
||||
surface.reset();
|
||||
events.resourceChange.emit();
|
||||
m_surface.reset();
|
||||
m_events.resourceChange.emit();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void CXWaylandSurface::map() {
|
||||
if (mapped)
|
||||
if (m_mapped)
|
||||
return;
|
||||
|
||||
ASSERT(surface);
|
||||
ASSERT(m_surface);
|
||||
|
||||
g_pXWayland->pWM->mappedSurfaces.emplace_back(self);
|
||||
g_pXWayland->pWM->mappedSurfacesStacking.emplace_back(self);
|
||||
g_pXWayland->m_wm->m_mappedSurfaces.emplace_back(m_self);
|
||||
g_pXWayland->m_wm->m_mappedSurfacesStacking.emplace_back(m_self);
|
||||
|
||||
mapped = true;
|
||||
surface->map();
|
||||
m_mapped = true;
|
||||
m_surface->map();
|
||||
|
||||
Debug::log(LOG, "XWayland surface {:x} mapping", (uintptr_t)this);
|
||||
|
||||
events.map.emit();
|
||||
m_events.map.emit();
|
||||
|
||||
g_pXWayland->pWM->updateClientList();
|
||||
g_pXWayland->m_wm->updateClientList();
|
||||
}
|
||||
|
||||
void CXWaylandSurface::unmap() {
|
||||
if (!mapped)
|
||||
if (!m_mapped)
|
||||
return;
|
||||
|
||||
ASSERT(surface);
|
||||
ASSERT(m_surface);
|
||||
|
||||
std::erase(g_pXWayland->pWM->mappedSurfaces, self);
|
||||
std::erase(g_pXWayland->pWM->mappedSurfacesStacking, self);
|
||||
std::erase(g_pXWayland->m_wm->m_mappedSurfaces, m_self);
|
||||
std::erase(g_pXWayland->m_wm->m_mappedSurfacesStacking, m_self);
|
||||
|
||||
mapped = false;
|
||||
events.unmap.emit();
|
||||
surface->unmap();
|
||||
m_mapped = false;
|
||||
m_events.unmap.emit();
|
||||
m_surface->unmap();
|
||||
|
||||
Debug::log(LOG, "XWayland surface {:x} unmapping", (uintptr_t)this);
|
||||
|
||||
g_pXWayland->pWM->updateClientList();
|
||||
g_pXWayland->m_wm->updateClientList();
|
||||
}
|
||||
|
||||
void CXWaylandSurface::considerMap() {
|
||||
if (mapped)
|
||||
if (m_mapped)
|
||||
return;
|
||||
|
||||
if (!surface) {
|
||||
if (!m_surface) {
|
||||
Debug::log(LOG, "XWayland surface: considerMap, nope, no surface");
|
||||
return;
|
||||
}
|
||||
|
||||
if (surface->m_current.texture) {
|
||||
if (m_surface->m_current.texture) {
|
||||
Debug::log(LOG, "XWayland surface: considerMap, sure, we have a buffer");
|
||||
map();
|
||||
return;
|
||||
@ -142,7 +142,7 @@ void CXWaylandSurface::considerMap() {
|
||||
}
|
||||
|
||||
bool CXWaylandSurface::wantsFocus() {
|
||||
if (atoms.empty())
|
||||
if (m_atoms.empty())
|
||||
return true;
|
||||
|
||||
const std::array<uint32_t, 10> search = {
|
||||
@ -153,7 +153,7 @@ bool CXWaylandSurface::wantsFocus() {
|
||||
};
|
||||
|
||||
for (auto const& searched : search) {
|
||||
for (auto const& a : atoms) {
|
||||
for (auto const& a : m_atoms) {
|
||||
if (a == searched)
|
||||
return false;
|
||||
}
|
||||
@ -163,110 +163,110 @@ bool CXWaylandSurface::wantsFocus() {
|
||||
}
|
||||
|
||||
void CXWaylandSurface::configure(const CBox& box) {
|
||||
Vector2D oldSize = geometry.size();
|
||||
Vector2D oldSize = m_geometry.size();
|
||||
|
||||
geometry = box;
|
||||
m_geometry = box;
|
||||
|
||||
uint32_t mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT | XCB_CONFIG_WINDOW_BORDER_WIDTH;
|
||||
uint32_t values[] = {box.x, box.y, box.width, box.height, 0};
|
||||
xcb_configure_window(g_pXWayland->pWM->connection, xID, mask, values);
|
||||
xcb_configure_window(g_pXWayland->m_wm->m_connection, m_xID, mask, values);
|
||||
|
||||
if (geometry.width == box.width && geometry.height == box.height) {
|
||||
if (m_geometry.width == box.width && m_geometry.height == box.height) {
|
||||
// ICCCM requires a synthetic event when window size is not changed
|
||||
xcb_configure_notify_event_t e;
|
||||
e.response_type = XCB_CONFIGURE_NOTIFY;
|
||||
e.event = xID;
|
||||
e.window = xID;
|
||||
e.event = m_xID;
|
||||
e.window = m_xID;
|
||||
e.x = box.x;
|
||||
e.y = box.y;
|
||||
e.width = box.width;
|
||||
e.height = box.height;
|
||||
e.border_width = 0;
|
||||
e.above_sibling = XCB_NONE;
|
||||
e.override_redirect = overrideRedirect;
|
||||
xcb_send_event(g_pXWayland->pWM->connection, false, xID, XCB_EVENT_MASK_STRUCTURE_NOTIFY, (const char*)&e);
|
||||
e.override_redirect = m_overrideRedirect;
|
||||
xcb_send_event(g_pXWayland->m_wm->m_connection, false, m_xID, XCB_EVENT_MASK_STRUCTURE_NOTIFY, (const char*)&e);
|
||||
}
|
||||
|
||||
g_pXWayland->pWM->updateClientList();
|
||||
g_pXWayland->m_wm->updateClientList();
|
||||
|
||||
xcb_flush(g_pXWayland->pWM->connection);
|
||||
xcb_flush(g_pXWayland->m_wm->m_connection);
|
||||
}
|
||||
|
||||
void CXWaylandSurface::activate(bool activate) {
|
||||
if (overrideRedirect && !activate)
|
||||
if (m_overrideRedirect && !activate)
|
||||
return;
|
||||
g_pXWayland->pWM->activateSurface(self.lock(), activate);
|
||||
g_pXWayland->m_wm->activateSurface(m_self.lock(), activate);
|
||||
}
|
||||
|
||||
void CXWaylandSurface::setFullscreen(bool fs) {
|
||||
fullscreen = fs;
|
||||
g_pXWayland->pWM->sendState(self.lock());
|
||||
m_fullscreen = fs;
|
||||
g_pXWayland->m_wm->sendState(m_self.lock());
|
||||
}
|
||||
|
||||
void CXWaylandSurface::setMinimized(bool mz) {
|
||||
minimized = mz;
|
||||
g_pXWayland->pWM->sendState(self.lock());
|
||||
m_minimized = mz;
|
||||
g_pXWayland->m_wm->sendState(m_self.lock());
|
||||
}
|
||||
|
||||
void CXWaylandSurface::restackToTop() {
|
||||
uint32_t values[1] = {XCB_STACK_MODE_ABOVE};
|
||||
|
||||
xcb_configure_window(g_pXWayland->pWM->connection, xID, XCB_CONFIG_WINDOW_STACK_MODE, values);
|
||||
xcb_configure_window(g_pXWayland->m_wm->m_connection, m_xID, XCB_CONFIG_WINDOW_STACK_MODE, values);
|
||||
|
||||
auto& stack = g_pXWayland->pWM->mappedSurfacesStacking;
|
||||
auto it = std::find(stack.begin(), stack.end(), self);
|
||||
auto& stack = g_pXWayland->m_wm->m_mappedSurfacesStacking;
|
||||
auto it = std::find(stack.begin(), stack.end(), m_self);
|
||||
|
||||
if (it != stack.end())
|
||||
std::rotate(it, it + 1, stack.end());
|
||||
|
||||
g_pXWayland->pWM->updateClientList();
|
||||
g_pXWayland->m_wm->updateClientList();
|
||||
|
||||
xcb_flush(g_pXWayland->pWM->connection);
|
||||
xcb_flush(g_pXWayland->m_wm->m_connection);
|
||||
}
|
||||
|
||||
void CXWaylandSurface::close() {
|
||||
xcb_client_message_data_t msg = {};
|
||||
msg.data32[0] = HYPRATOMS["WM_DELETE_WINDOW"];
|
||||
msg.data32[1] = XCB_CURRENT_TIME;
|
||||
g_pXWayland->pWM->sendWMMessage(self.lock(), &msg, XCB_EVENT_MASK_NO_EVENT);
|
||||
g_pXWayland->m_wm->sendWMMessage(m_self.lock(), &msg, XCB_EVENT_MASK_NO_EVENT);
|
||||
}
|
||||
|
||||
void CXWaylandSurface::setWithdrawn(bool withdrawn_) {
|
||||
withdrawn = withdrawn_;
|
||||
m_withdrawn = withdrawn_;
|
||||
std::vector<uint32_t> props = {XCB_ICCCM_WM_STATE_NORMAL, XCB_WINDOW_NONE};
|
||||
|
||||
if (withdrawn)
|
||||
if (m_withdrawn)
|
||||
props[0] = XCB_ICCCM_WM_STATE_WITHDRAWN;
|
||||
else if (minimized)
|
||||
else if (m_minimized)
|
||||
props[0] = XCB_ICCCM_WM_STATE_ICONIC;
|
||||
else
|
||||
props[0] = XCB_ICCCM_WM_STATE_NORMAL;
|
||||
|
||||
xcb_change_property(g_pXWayland->pWM->connection, XCB_PROP_MODE_REPLACE, xID, HYPRATOMS["WM_STATE"], HYPRATOMS["WM_STATE"], 32, props.size(), props.data());
|
||||
xcb_change_property(g_pXWayland->m_wm->m_connection, XCB_PROP_MODE_REPLACE, m_xID, HYPRATOMS["WM_STATE"], HYPRATOMS["WM_STATE"], 32, props.size(), props.data());
|
||||
}
|
||||
|
||||
void CXWaylandSurface::ping() {
|
||||
bool supportsPing = std::ranges::find(protocols, HYPRATOMS["_NET_WM_PING"]) != protocols.end();
|
||||
bool supportsPing = std::ranges::find(m_protocols, HYPRATOMS["_NET_WM_PING"]) != m_protocols.end();
|
||||
|
||||
if (!supportsPing) {
|
||||
Debug::log(TRACE, "CXWaylandSurface: XID {} does not support ping, just sending an instant reply", xID);
|
||||
g_pANRManager->onResponse(self.lock());
|
||||
Debug::log(TRACE, "CXWaylandSurface: XID {} does not support ping, just sending an instant reply", m_xID);
|
||||
g_pANRManager->onResponse(m_self.lock());
|
||||
return;
|
||||
}
|
||||
|
||||
xcb_client_message_data_t msg = {};
|
||||
msg.data32[0] = HYPRATOMS["_NET_WM_PING"];
|
||||
msg.data32[1] = Time::millis(Time::steadyNow());
|
||||
msg.data32[2] = xID;
|
||||
msg.data32[2] = m_xID;
|
||||
|
||||
lastPingSeq = msg.data32[1];
|
||||
m_lastPingSeq = msg.data32[1];
|
||||
|
||||
g_pXWayland->pWM->sendWMMessage(self.lock(), &msg, XCB_EVENT_MASK_PROPERTY_CHANGE);
|
||||
g_pXWayland->m_wm->sendWMMessage(m_self.lock(), &msg, XCB_EVENT_MASK_PROPERTY_CHANGE);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
CXWaylandSurface::CXWaylandSurface(uint32_t xID_, CBox geometry_, bool OR) : xID(xID_), geometry(geometry_), overrideRedirect(OR) {
|
||||
CXWaylandSurface::CXWaylandSurface(uint32_t xID_, CBox geometry_, bool OR) : m_xID(xID_), m_geometry(geometry_), m_overrideRedirect(OR) {
|
||||
;
|
||||
}
|
||||
|
||||
|
@ -39,8 +39,8 @@ typedef struct {
|
||||
|
||||
class CXWaylandSurface {
|
||||
public:
|
||||
WP<CWLSurfaceResource> surface;
|
||||
WP<CXWaylandSurfaceResource> resource;
|
||||
WP<CWLSurfaceResource> m_surface;
|
||||
WP<CXWaylandSurfaceResource> m_resource;
|
||||
|
||||
struct {
|
||||
CSignal stateChanged; // maximized, fs, minimized, etc.
|
||||
@ -57,7 +57,7 @@ class CXWaylandSurface {
|
||||
CSignal commit;
|
||||
|
||||
CSignal activate;
|
||||
} events;
|
||||
} m_events;
|
||||
|
||||
struct {
|
||||
std::string title;
|
||||
@ -67,31 +67,32 @@ class CXWaylandSurface {
|
||||
std::optional<bool> requestsMaximize;
|
||||
std::optional<bool> requestsFullscreen;
|
||||
std::optional<bool> requestsMinimize;
|
||||
} state;
|
||||
} m_state;
|
||||
|
||||
uint32_t xID = 0;
|
||||
uint64_t wlID = 0;
|
||||
uint64_t wlSerial = 0;
|
||||
uint32_t lastPingSeq = 0;
|
||||
pid_t pid = 0;
|
||||
CBox geometry;
|
||||
bool overrideRedirect = false;
|
||||
bool withdrawn = false;
|
||||
bool fullscreen = false;
|
||||
bool maximized = false;
|
||||
bool minimized = false;
|
||||
bool mapped = false;
|
||||
bool modal = false;
|
||||
uint32_t m_xID = 0;
|
||||
uint64_t m_wlID = 0;
|
||||
uint64_t m_wlSerial = 0;
|
||||
uint32_t m_lastPingSeq = 0;
|
||||
pid_t m_pid = 0;
|
||||
CBox m_geometry;
|
||||
bool m_overrideRedirect = false;
|
||||
bool m_withdrawn = false;
|
||||
bool m_fullscreen = false;
|
||||
bool m_maximized = false;
|
||||
bool m_minimized = false;
|
||||
bool m_mapped = false;
|
||||
bool m_modal = false;
|
||||
|
||||
WP<CXWaylandSurface> parent;
|
||||
WP<CXWaylandSurface> self;
|
||||
std::vector<WP<CXWaylandSurface>> children;
|
||||
WP<CXWaylandSurface> m_parent;
|
||||
WP<CXWaylandSurface> m_self;
|
||||
std::vector<WP<CXWaylandSurface>> m_children;
|
||||
|
||||
UP<xcb_icccm_wm_hints_t> hints;
|
||||
UP<xcb_size_hints_t> sizeHints;
|
||||
std::vector<uint32_t> atoms, protocols;
|
||||
std::string role = "";
|
||||
bool transient = false;
|
||||
UP<xcb_icccm_wm_hints_t> m_hints;
|
||||
UP<xcb_size_hints_t> m_sizeHints;
|
||||
std::vector<uint32_t> m_atoms;
|
||||
std::vector<uint32_t> m_protocols;
|
||||
std::string m_role = "";
|
||||
bool m_transient = false;
|
||||
|
||||
bool wantsFocus();
|
||||
void configure(const CBox& box);
|
||||
@ -115,7 +116,7 @@ class CXWaylandSurface {
|
||||
CHyprSignalListener destroyResource;
|
||||
CHyprSignalListener destroySurface;
|
||||
CHyprSignalListener commitSurface;
|
||||
} listeners;
|
||||
} m_listeners;
|
||||
|
||||
friend class CXWM;
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -63,45 +63,45 @@ struct SXSelection {
|
||||
|
||||
class CXCBConnection {
|
||||
public:
|
||||
CXCBConnection(int fd) : connection{xcb_connect_to_fd(fd, nullptr)} {
|
||||
CXCBConnection(int fd) : m_connection{xcb_connect_to_fd(fd, nullptr)} {
|
||||
;
|
||||
}
|
||||
|
||||
~CXCBConnection() {
|
||||
if (connection)
|
||||
xcb_disconnect(connection);
|
||||
if (m_connection)
|
||||
xcb_disconnect(m_connection);
|
||||
}
|
||||
|
||||
bool hasError() const {
|
||||
return xcb_connection_has_error(connection);
|
||||
return xcb_connection_has_error(m_connection);
|
||||
}
|
||||
|
||||
operator xcb_connection_t*() const {
|
||||
return connection;
|
||||
return m_connection;
|
||||
}
|
||||
|
||||
private:
|
||||
xcb_connection_t* connection = nullptr;
|
||||
xcb_connection_t* m_connection = nullptr;
|
||||
};
|
||||
|
||||
class CXCBErrorContext {
|
||||
public:
|
||||
explicit CXCBErrorContext(xcb_connection_t* connection) {
|
||||
if (xcb_errors_context_new(connection, &errors) != 0)
|
||||
errors = nullptr;
|
||||
if (xcb_errors_context_new(connection, &m_errors) != 0)
|
||||
m_errors = nullptr;
|
||||
}
|
||||
|
||||
~CXCBErrorContext() {
|
||||
if (errors)
|
||||
xcb_errors_context_free(errors);
|
||||
if (m_errors)
|
||||
xcb_errors_context_free(m_errors);
|
||||
}
|
||||
|
||||
bool isValid() const {
|
||||
return errors != nullptr;
|
||||
return m_errors != nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
xcb_errors_context_t* errors = nullptr;
|
||||
xcb_errors_context_t* m_errors = nullptr;
|
||||
};
|
||||
|
||||
class CXWM {
|
||||
@ -174,42 +174,42 @@ class CXWM {
|
||||
SXSelection* getSelection(xcb_atom_t atom);
|
||||
|
||||
//
|
||||
CXCBConnection connection;
|
||||
xcb_errors_context_t* errors = nullptr;
|
||||
xcb_screen_t* screen = nullptr;
|
||||
CXCBConnection m_connection;
|
||||
xcb_errors_context_t* m_errors = nullptr;
|
||||
xcb_screen_t* m_screen = nullptr;
|
||||
|
||||
xcb_window_t wmWindow;
|
||||
xcb_window_t m_wmWindow;
|
||||
|
||||
wl_event_source* eventSource = nullptr;
|
||||
wl_event_source* m_eventSource = nullptr;
|
||||
|
||||
const xcb_query_extension_reply_t* xfixes = nullptr;
|
||||
const xcb_query_extension_reply_t* xres = nullptr;
|
||||
int xfixesMajor = 0;
|
||||
const xcb_query_extension_reply_t* m_xfixes = nullptr;
|
||||
const xcb_query_extension_reply_t* m_xres = nullptr;
|
||||
int m_xfixesMajor = 0;
|
||||
|
||||
xcb_visualid_t visual_id;
|
||||
xcb_colormap_t colormap;
|
||||
uint32_t cursorXID = 0;
|
||||
xcb_visualid_t m_visualID;
|
||||
xcb_colormap_t m_colormap;
|
||||
uint32_t m_cursorXID = 0;
|
||||
|
||||
xcb_render_pictformat_t render_format_id;
|
||||
xcb_render_pictformat_t m_renderFormatID;
|
||||
|
||||
std::vector<WP<CXWaylandSurfaceResource>> shellResources;
|
||||
std::vector<SP<CXWaylandSurface>> surfaces;
|
||||
std::vector<WP<CXWaylandSurface>> mappedSurfaces; // ordered by map time
|
||||
std::vector<WP<CXWaylandSurface>> mappedSurfacesStacking; // ordered by stacking
|
||||
std::vector<WP<CXWaylandSurfaceResource>> m_shellResources;
|
||||
std::vector<SP<CXWaylandSurface>> m_surfaces;
|
||||
std::vector<WP<CXWaylandSurface>> m_mappedSurfaces; // ordered by map time
|
||||
std::vector<WP<CXWaylandSurface>> m_mappedSurfacesStacking; // ordered by stacking
|
||||
|
||||
WP<CXWaylandSurface> focusedSurface;
|
||||
uint64_t lastFocusSeq = 0;
|
||||
WP<CXWaylandSurface> m_focusedSurface;
|
||||
uint64_t m_lastFocusSeq = 0;
|
||||
|
||||
SXSelection clipboard;
|
||||
SXSelection primarySelection;
|
||||
SXSelection dndSelection;
|
||||
SP<CX11DataDevice> dndDataDevice = makeShared<CX11DataDevice>();
|
||||
std::vector<SP<CX11DataOffer>> dndDataOffers;
|
||||
SXSelection m_clipboard;
|
||||
SXSelection m_primarySelection;
|
||||
SXSelection m_dndSelection;
|
||||
SP<CX11DataDevice> m_dndDataDevice = makeShared<CX11DataDevice>();
|
||||
std::vector<SP<CX11DataOffer>> m_dndDataOffers;
|
||||
|
||||
struct {
|
||||
CHyprSignalListener newWLSurface;
|
||||
CHyprSignalListener newXShellSurface;
|
||||
} listeners;
|
||||
} m_listeners;
|
||||
|
||||
friend class CXWaylandSurface;
|
||||
friend class CXWayland;
|
||||
|
@ -26,9 +26,9 @@ CXWayland::CXWayland(const bool wantsEnabled) {
|
||||
|
||||
Debug::log(LOG, "Starting up the XWayland server");
|
||||
|
||||
pServer = makeUnique<CXWaylandServer>();
|
||||
m_server = makeUnique<CXWaylandServer>();
|
||||
|
||||
if (!pServer->create()) {
|
||||
if (!m_server->create()) {
|
||||
Debug::log(ERR, "XWayland failed to start: it will not work.");
|
||||
return;
|
||||
}
|
||||
@ -41,12 +41,12 @@ CXWayland::CXWayland(const bool wantsEnabled) {
|
||||
|
||||
void CXWayland::setCursor(unsigned char* pixData, uint32_t stride, const Vector2D& size, const Vector2D& hotspot) {
|
||||
#ifndef NO_XWAYLAND
|
||||
if (!pWM) {
|
||||
if (!m_wm) {
|
||||
Debug::log(ERR, "Couldn't set XCursor: no XWM yet");
|
||||
return;
|
||||
}
|
||||
|
||||
pWM->setCursor(pixData, stride, size, hotspot);
|
||||
m_wm->setCursor(pixData, stride, size, hotspot);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -19,17 +19,13 @@ class CXWayland {
|
||||
CXWayland(const bool wantsEnabled);
|
||||
|
||||
#ifndef NO_XWAYLAND
|
||||
UP<CXWaylandServer> pServer;
|
||||
UP<CXWM> pWM;
|
||||
UP<CXWaylandServer> m_server;
|
||||
UP<CXWM> m_wm;
|
||||
#endif
|
||||
bool enabled();
|
||||
|
||||
void setCursor(unsigned char* pixData, uint32_t stride, const Vector2D& size, const Vector2D& hotspot);
|
||||
|
||||
struct {
|
||||
CSignal newSurface;
|
||||
} events;
|
||||
|
||||
private:
|
||||
bool m_enabled = false;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user