Skip to content

Commit

Permalink
xwayland: move to hyprland impl
Browse files Browse the repository at this point in the history
  • Loading branch information
vaxerski committed May 24, 2024
1 parent 93fea89 commit bd0b348
Show file tree
Hide file tree
Showing 36 changed files with 2,918 additions and 706 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ protocolNew("stable/tablet/tablet-v2.xml" "tablet-v2" false)
protocolNew("stable/presentation-time/presentation-time.xml" "presentation-time" false)
protocolNew("stable/xdg-shell/xdg-shell.xml" "xdg-shell" false)
protocolNew("unstable/primary-selection/primary-selection-unstable-v1.xml" "primary-selection-unstable-v1" false)
protocolNew("staging/xwayland-shell/xwayland-shell-v1.xml" "xwayland-shell-v1" false)

protocolWayland()

Expand Down
1 change: 1 addition & 0 deletions protocols/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ new_protocols = [
[wl_protocol_dir, 'stable/presentation-time/presentation-time.xml'],
[wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'],
[wl_protocol_dir, 'unstable/primary-selection/primary-selection-unstable-v1.xml'],
[wl_protocol_dir, 'staging/xwayland-shell/xwayland-shell-v1.xml'],
]

wl_protos_src = []
Expand Down
21 changes: 11 additions & 10 deletions src/Compositor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "protocols/LayerShell.hpp"
#include "protocols/XDGShell.hpp"
#include "desktop/LayerSurface.hpp"
#include "xwayland/XWayland.hpp"

#include <sys/types.h>
#include <sys/stat.h>
Expand Down Expand Up @@ -332,12 +333,9 @@ void CCompositor::cleanup() {
m->state.commit();
}

m_vMonitors.clear();
g_pXWayland.reset();

if (g_pXWaylandManager->m_sWLRXWayland) {
wlr_xwayland_destroy(g_pXWaylandManager->m_sWLRXWayland);
g_pXWaylandManager->m_sWLRXWayland = nullptr;
}
m_vMonitors.clear();

wl_display_destroy_clients(g_pCompositor->m_sWLDisplay);
removeAllSignals();
Expand Down Expand Up @@ -462,6 +460,9 @@ void CCompositor::initManagers(eManagersInitStage stage) {

Debug::log(LOG, "Creating the CursorManager!");
g_pCursorManager = std::make_unique<CCursorManager>();

Debug::log(LOG, "Starting XWayland");
g_pXWayland = std::make_unique<CXWayland>();
} break;
default: UNREACHABLE();
}
Expand Down Expand Up @@ -669,7 +670,7 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper
if (properties & ALLOW_FLOATING) {
for (auto& w : m_vWindows | std::views::reverse) {
const auto BB = w->getWindowBoxUnified(properties);
CBox box = {BB.x - BORDER_GRAB_AREA, BB.y - BORDER_GRAB_AREA, BB.width + 2 * BORDER_GRAB_AREA, BB.height + 2 * BORDER_GRAB_AREA};
CBox box = BB.copy().expand(w->m_iX11Type == 2 ? BORDER_GRAB_AREA : 0);
if (w->m_bIsFloating && w->m_bIsMapped && !w->isHidden() && !w->m_bX11ShouldntFocus && w->m_bPinned && !w->m_sAdditionalConfigData.noFocus && w != pIgnoreWindow) {
if (box.containsPoint(g_pPointerManager->position()))
return w;
Expand Down Expand Up @@ -698,7 +699,7 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper
BB.x + BB.width <= PWINDOWMONITOR->vecPosition.x + PWINDOWMONITOR->vecSize.x && BB.y + BB.height <= PWINDOWMONITOR->vecPosition.y + PWINDOWMONITOR->vecSize.y)
continue;

CBox box = {BB.x - BORDER_GRAB_AREA, BB.y - BORDER_GRAB_AREA, BB.width + 2 * BORDER_GRAB_AREA, BB.height + 2 * BORDER_GRAB_AREA};
CBox box = BB.copy().expand(w->m_iX11Type == 2 ? BORDER_GRAB_AREA : 0);
if (w->m_bIsFloating && w->m_bIsMapped && isWorkspaceVisible(w->m_pWorkspace) && !w->isHidden() && !w->m_bPinned && !w->m_sAdditionalConfigData.noFocus &&
w != pIgnoreWindow && (!aboveFullscreen || w->m_bCreatedOverFullscreen)) {
// OR windows should add focus to parent
Expand All @@ -707,7 +708,7 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper

if (box.containsPoint(g_pPointerManager->position())) {

if (w->m_bIsX11 && w->m_iX11Type == 2 && !wlr_xwayland_or_surface_wants_focus(w->m_uSurface.xwayland)) {
if (w->m_bIsX11 && w->m_iX11Type == 2 && !w->m_pXWaylandSurface->wantsFocus()) {
// Override Redirect
return g_pCompositor->m_pLastWindow.lock(); // we kinda trick everything here.
// TODO: this is wrong, we should focus the parent, but idk how to get it considering it's nullptr in most cases.
Expand Down Expand Up @@ -892,7 +893,7 @@ void CCompositor::focusWindow(PHLWINDOW pWindow, wlr_surface* pSurface) {
return;
}

if (pWindow && pWindow->m_bIsX11 && pWindow->m_iX11Type == 2 && !wlr_xwayland_or_surface_wants_focus(pWindow->m_uSurface.xwayland))
if (pWindow && pWindow->m_bIsX11 && pWindow->m_iX11Type == 2 && !pWindow->m_pXWaylandSurface->wantsFocus())
return;

g_pLayoutManager->getCurrentLayout()->bringWindowToTop(pWindow);
Expand Down Expand Up @@ -2219,7 +2220,7 @@ PHLWINDOW CCompositor::getX11Parent(PHLWINDOW pWindow) {
if (!w->m_bIsX11)
continue;

if (w->m_uSurface.xwayland == pWindow->m_uSurface.xwayland->parent)
if (w->m_pXWaylandSurface == pWindow->m_pXWaylandSurface->parent)
return w;
}

Expand Down
18 changes: 0 additions & 18 deletions src/Compositor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,21 +189,3 @@ class CCompositor {
};

inline std::unique_ptr<CCompositor> g_pCompositor;

// For XWayland
inline std::map<std::string, xcb_atom_t> HYPRATOMS = {HYPRATOM("_NET_WM_WINDOW_TYPE"),
HYPRATOM("_NET_WM_WINDOW_TYPE_NORMAL"),
HYPRATOM("_NET_WM_WINDOW_TYPE_DOCK"),
HYPRATOM("_NET_WM_WINDOW_TYPE_DIALOG"),
HYPRATOM("_NET_WM_WINDOW_TYPE_UTILITY"),
HYPRATOM("_NET_WM_WINDOW_TYPE_TOOLBAR"),
HYPRATOM("_NET_WM_WINDOW_TYPE_SPLASH"),
HYPRATOM("_NET_WM_WINDOW_TYPE_MENU"),
HYPRATOM("_NET_WM_WINDOW_TYPE_DROPDOWN_MENU"),
HYPRATOM("_NET_WM_WINDOW_TYPE_POPUP_MENU"),
HYPRATOM("_NET_WM_WINDOW_TYPE_TOOLTIP"),
HYPRATOM("_NET_WM_WINDOW_TYPE_NOTIFICATION"),
HYPRATOM("_KDE_NET_WM_WINDOW_TYPE_OVERRIDE"),
HYPRATOM("_NET_SUPPORTING_WM_CHECK"),
HYPRATOM("_NET_WM_NAME"),
HYPRATOM("UTF8_STRING")};
158 changes: 114 additions & 44 deletions src/desktop/Window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -426,22 +440,7 @@ void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) {
}

PHLWINDOW CWindow::X11TransientFor() {
if (!m_bIsX11)
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);
}

if (!validMapped(PPARENT))
return nullptr;

return PPARENT;
return nullptr;
}

void CWindow::removeDecorationByType(eDecorationType type) {
Expand Down Expand Up @@ -494,8 +493,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)
Expand Down Expand Up @@ -548,9 +545,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;

Expand Down Expand Up @@ -1119,9 +1113,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);
Expand Down Expand Up @@ -1334,23 +1328,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);
}
}
Expand Down Expand Up @@ -1399,8 +1393,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 "";
Expand All @@ -1411,8 +1405,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 "";
Expand All @@ -1426,4 +1420,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());
}
Loading

0 comments on commit bd0b348

Please sign in to comment.