From d2ea177052b20b31a1a8aad64d3708d780050bc1 Mon Sep 17 00:00:00 2001 From: Trianta <56975502+Trimutex@users.noreply.github.com> Date: Sun, 1 Sep 2024 17:22:53 -0500 Subject: [PATCH 1/9] config: add xwayland enabled option to config --- src/config/ConfigDescriptions.hpp | 6 ++++++ src/config/ConfigManager.cpp | 15 +++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/config/ConfigDescriptions.hpp b/src/config/ConfigDescriptions.hpp index 73f3c9a321b..ac466d9a9b7 100644 --- a/src/config/ConfigDescriptions.hpp +++ b/src/config/ConfigDescriptions.hpp @@ -1115,6 +1115,12 @@ inline static const std::vector CONFIG_OPTIONS = { * xwayland: */ + SConfigOptionDescription{ + .value = "xwayland:enabled", + .description = "enables xwayland applications to exist", + .type = CONFIG_OPTION_BOOL, + .data = SConfigOptionDescription::SBoolData{true}, + }, SConfigOptionDescription{ .value = "xwayland:use_nearest_neighbor", .description = "uses the nearest neighbor filtering for xwayland apps, making them pixelated rather than blurry", diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 5940a6fe3ba..e00f8aaa595 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -6,6 +6,7 @@ #include "config/ConfigValue.hpp" #include "helpers/varlist/VarList.hpp" #include "../protocols/LayerShell.hpp" +#include "../xwayland/XWayland.hpp" #include #include @@ -523,6 +524,7 @@ CConfigManager::CConfigManager() { m_pConfig->addConfigValue("gestures:workspace_swipe_touch", Hyprlang::INT{0}); m_pConfig->addConfigValue("gestures:workspace_swipe_touch_invert", Hyprlang::INT{0}); + m_pConfig->addConfigValue("xwayland:enabled", Hyprlang::INT{1}); m_pConfig->addConfigValue("xwayland:use_nearest_neighbor", Hyprlang::INT{1}); m_pConfig->addConfigValue("xwayland:force_zero_scaling", Hyprlang::INT{0}); @@ -813,6 +815,8 @@ std::optional CConfigManager::resetHLConfig() { void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) { static const auto PENABLEEXPLICIT = CConfigValue("render:explicit_sync"); static int prevEnabledExplicit = *PENABLEEXPLICIT; + static const auto PENABLEXWAYLAND = CConfigValue("xwayland:enabled"); + static int prevEnabledXwayland = *PENABLEXWAYLAND; for (auto const& w : g_pCompositor->m_vWindows) { w->uncacheWindowDecos(); @@ -860,6 +864,17 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) { ensureVRR(); } + // Clean up XWayland if config changes + if (!(*PENABLEXWAYLAND) && prevEnabledXwayland) { + for (auto const& w : g_pCompositor->m_vWindows) { + if (w->m_bIsX11) + g_pCompositor->closeWindow(w); + } + } + + g_pXWayland->m_bEnabled = *PENABLEXWAYLAND; + + if (!isFirstLaunch && !g_pCompositor->m_bUnsafeState) refreshGroupBarGradients(); From bcf0d202ccf4846eacf712daefb2b8924f782309 Mon Sep 17 00:00:00 2001 From: Trianta <56975502+Trimutex@users.noreply.github.com> Date: Mon, 2 Sep 2024 20:27:46 -0500 Subject: [PATCH 2/9] xwayland: use DISPLAY env variable for enable/disable of new launches --- src/Compositor.hpp | 1 + src/config/ConfigManager.cpp | 27 ++++++++++++++++----------- src/xwayland/Server.cpp | 9 ++++++++- src/xwayland/Server.hpp | 2 ++ 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/Compositor.hpp b/src/Compositor.hpp index bb986f5e2bd..f17d86e5441 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -92,6 +92,7 @@ class CCompositor { CMonitor* m_pUnsafeOutput = nullptr; // fallback output for the unsafe state bool m_bIsShuttingDown = false; bool m_bDesktopEnvSet = false; + bool m_bEnableXwayland = true; // ------------------------------------------------- // diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index e00f8aaa595..b803530f46c 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -815,8 +815,6 @@ std::optional CConfigManager::resetHLConfig() { void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) { static const auto PENABLEEXPLICIT = CConfigValue("render:explicit_sync"); static int prevEnabledExplicit = *PENABLEEXPLICIT; - static const auto PENABLEXWAYLAND = CConfigValue("xwayland:enabled"); - static int prevEnabledXwayland = *PENABLEXWAYLAND; for (auto const& w : g_pCompositor->m_vWindows) { w->uncacheWindowDecos(); @@ -864,16 +862,23 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) { ensureVRR(); } - // Clean up XWayland if config changes - if (!(*PENABLEXWAYLAND) && prevEnabledXwayland) { - for (auto const& w : g_pCompositor->m_vWindows) { - if (w->m_bIsX11) - g_pCompositor->closeWindow(w); +#ifndef NO_XWAYLAND + const auto PENABLEXWAYLAND = std::any_cast(m_pConfig->getConfigValue("xwayland:enabled")); + // enable/disable xwayland usage + // TODO: Clean up xwayland when changing to false + if (!isFirstLaunch) { + bool prevEnabledXwayland = g_pCompositor->m_bEnableXwayland; + if (PENABLEXWAYLAND != prevEnabledXwayland) { + if (PENABLEXWAYLAND) + Debug::log(LOG, "xwayland has been enabled"); + else + Debug::log(LOG, "xwayland has been disabled"); + g_pCompositor->m_bEnableXwayland = PENABLEXWAYLAND; + g_pXWayland->pServer->setDisplayEnv(); } - } - - g_pXWayland->m_bEnabled = *PENABLEXWAYLAND; - + } else + g_pCompositor->m_bEnableXwayland = PENABLEXWAYLAND; +#endif if (!isFirstLaunch && !g_pCompositor->m_bUnsafeState) refreshGroupBarGradients(); diff --git a/src/xwayland/Server.cpp b/src/xwayland/Server.cpp index 200bec70b4a..0fb7def9718 100644 --- a/src/xwayland/Server.cpp +++ b/src/xwayland/Server.cpp @@ -288,7 +288,7 @@ bool CXWaylandServer::create() { if (!tryOpenSockets()) return false; - setenv("DISPLAY", displayName.c_str(), true); + setDisplayEnv(); // TODO: lazy mode @@ -297,6 +297,13 @@ bool CXWaylandServer::create() { return true; } +void CXWaylandServer::setDisplayEnv(void) { + if (g_pCompositor->m_bEnableXwayland) + setenv("DISPLAY", displayName.c_str(), true); + else + unsetenv("DISPLAY"); +} + void CXWaylandServer::runXWayland(int notifyFD) { if (!set_cloexec(xFDs[0], false) || !set_cloexec(xFDs[1], false) || !set_cloexec(waylandFDs[1], false) || !set_cloexec(xwmFDs[1], false)) { Debug::log(ERR, "Failed to unset cloexec on fds"); diff --git a/src/xwayland/Server.hpp b/src/xwayland/Server.hpp index 7a36a965f9c..cff59d3353c 100644 --- a/src/xwayland/Server.hpp +++ b/src/xwayland/Server.hpp @@ -15,6 +15,8 @@ class CXWaylandServer { // create the server. bool create(); + void setDisplayEnv(void); + // starts the server, meant to be called by CXWaylandServer. bool start(); From d32640fae89c09c50bd34276e907d0182320351a Mon Sep 17 00:00:00 2001 From: Trianta <56975502+Trimutex@users.noreply.github.com> Date: Mon, 2 Sep 2024 20:39:44 -0500 Subject: [PATCH 3/9] xwayland: close X11 windows when turning of XWayland --- src/config/ConfigManager.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index b803530f46c..2aa945fa7e6 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -865,14 +865,18 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) { #ifndef NO_XWAYLAND const auto PENABLEXWAYLAND = std::any_cast(m_pConfig->getConfigValue("xwayland:enabled")); // enable/disable xwayland usage - // TODO: Clean up xwayland when changing to false if (!isFirstLaunch) { bool prevEnabledXwayland = g_pCompositor->m_bEnableXwayland; if (PENABLEXWAYLAND != prevEnabledXwayland) { if (PENABLEXWAYLAND) Debug::log(LOG, "xwayland has been enabled"); - else - Debug::log(LOG, "xwayland has been disabled"); + else { + Debug::log(LOG, "xwayland has been disabled, cleaning up..."); + for (const auto& w : g_pCompositor->m_vWindows) { + if (w->m_bIsX11) + g_pCompositor->closeWindow(w); + } + } g_pCompositor->m_bEnableXwayland = PENABLEXWAYLAND; g_pXWayland->pServer->setDisplayEnv(); } From 6c6386931864293eef2f53708af5ce8197cc82ab Mon Sep 17 00:00:00 2001 From: Trianta <56975502+Trimutex@users.noreply.github.com> Date: Mon, 2 Sep 2024 20:55:07 -0500 Subject: [PATCH 4/9] clang: format fix --- src/xwayland/Server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xwayland/Server.cpp b/src/xwayland/Server.cpp index 0fb7def9718..d3b121a2150 100644 --- a/src/xwayland/Server.cpp +++ b/src/xwayland/Server.cpp @@ -300,7 +300,7 @@ bool CXWaylandServer::create() { void CXWaylandServer::setDisplayEnv(void) { if (g_pCompositor->m_bEnableXwayland) setenv("DISPLAY", displayName.c_str(), true); - else + else unsetenv("DISPLAY"); } From 47d146e5a38d196bce00fe7316fbea3359194ebc Mon Sep 17 00:00:00 2001 From: Trianta <56975502+Trimutex@users.noreply.github.com> Date: Mon, 2 Sep 2024 21:46:22 -0500 Subject: [PATCH 5/9] config: add better description for xwayland:enabled --- src/config/ConfigDescriptions.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config/ConfigDescriptions.hpp b/src/config/ConfigDescriptions.hpp index ac466d9a9b7..00ebde6adfe 100644 --- a/src/config/ConfigDescriptions.hpp +++ b/src/config/ConfigDescriptions.hpp @@ -1117,7 +1117,7 @@ inline static const std::vector CONFIG_OPTIONS = { SConfigOptionDescription{ .value = "xwayland:enabled", - .description = "enables xwayland applications to exist", + .description = "allow running applications using X11", .type = CONFIG_OPTION_BOOL, .data = SConfigOptionDescription::SBoolData{true}, }, From b87d8b9a0ebd8f9d4b54963ead93931143fdf8eb Mon Sep 17 00:00:00 2001 From: Trianta <56975502+Trimutex@users.noreply.github.com> Date: Tue, 3 Sep 2024 22:30:19 -0500 Subject: [PATCH 6/9] xwayland: close X11 windows on disable without crashes --- src/config/ConfigManager.cpp | 18 +++++++++++------- src/xwayland/Server.cpp | 5 +++-- src/xwayland/XWM.cpp | 3 +++ src/xwayland/XWayland.cpp | 7 ++++++- 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 2aa945fa7e6..737df661cfd 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -868,17 +868,21 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) { if (!isFirstLaunch) { bool prevEnabledXwayland = g_pCompositor->m_bEnableXwayland; if (PENABLEXWAYLAND != prevEnabledXwayland) { - if (PENABLEXWAYLAND) + g_pCompositor->m_bEnableXwayland = PENABLEXWAYLAND; + if (PENABLEXWAYLAND) { Debug::log(LOG, "xwayland has been enabled"); - else { + g_pXWayland = std::make_unique(); + } else { Debug::log(LOG, "xwayland has been disabled, cleaning up..."); - for (const auto& w : g_pCompositor->m_vWindows) { - if (w->m_bIsX11) - g_pCompositor->closeWindow(w); + for (auto& w : g_pCompositor->m_vWindows) { + if (!w->m_bIsX11) + continue; + g_pCompositor->closeWindow(w); } + g_pXWayland->pServer = std::make_unique(); + g_pXWayland->pWM = std::make_unique(); + g_pXWayland->pServer->setDisplayEnv(); } - g_pCompositor->m_bEnableXwayland = PENABLEXWAYLAND; - g_pXWayland->pServer->setDisplayEnv(); } } else g_pCompositor->m_bEnableXwayland = PENABLEXWAYLAND; diff --git a/src/xwayland/Server.cpp b/src/xwayland/Server.cpp index d3b121a2150..a845156d1a0 100644 --- a/src/xwayland/Server.cpp +++ b/src/xwayland/Server.cpp @@ -297,7 +297,7 @@ bool CXWaylandServer::create() { return true; } -void CXWaylandServer::setDisplayEnv(void) { +void CXWaylandServer::setDisplayEnv() { if (g_pCompositor->m_bEnableXwayland) setenv("DISPLAY", displayName.c_str(), true); else @@ -439,7 +439,8 @@ int CXWaylandServer::ready(int fd, uint32_t mask) { pipeSource = nullptr; // start the wm - g_pXWayland->pWM = std::make_unique(); + if (!g_pXWayland->pWM) + g_pXWayland->pWM = std::make_unique(); g_pCursorManager->setXWaylandCursor(); diff --git a/src/xwayland/XWM.cpp b/src/xwayland/XWM.cpp index cb4d8f4dfcb..886a3505b0e 100644 --- a/src/xwayland/XWM.cpp +++ b/src/xwayland/XWM.cpp @@ -890,6 +890,9 @@ CXWM::~CXWM() { if (eventSource) wl_event_source_remove(eventSource); + + for (auto const& sr : surfaces) + sr->events.destroy.emit(); } void CXWM::setActiveWindow(xcb_window_t window) { diff --git a/src/xwayland/XWayland.cpp b/src/xwayland/XWayland.cpp index 8d45fa63a39..c2136dc1b83 100644 --- a/src/xwayland/XWayland.cpp +++ b/src/xwayland/XWayland.cpp @@ -7,6 +7,11 @@ CXWayland::CXWayland() { pServer = std::make_unique(); + if (!g_pCompositor->m_bEnableXwayland) { + pServer->setDisplayEnv(); + return; + } + if (!pServer->create()) { Debug::log(ERR, "XWayland failed to start: it will not work."); return; @@ -25,4 +30,4 @@ void CXWayland::setCursor(unsigned char* pixData, uint32_t stride, const Vector2 pWM->setCursor(pixData, stride, size, hotspot); #endif -} \ No newline at end of file +} From b0ea997184a05717354368913c9060129e23515a Mon Sep 17 00:00:00 2001 From: Trianta <56975502+Trimutex@users.noreply.github.com> Date: Wed, 4 Sep 2024 09:54:22 -0500 Subject: [PATCH 7/9] xwayland: better method of informing CXWayland if xwayland enabled --- src/Compositor.cpp | 2 +- src/config/ConfigManager.cpp | 5 +---- src/xwayland/Server.cpp | 9 +-------- src/xwayland/Server.hpp | 2 -- src/xwayland/XWayland.cpp | 6 +++--- src/xwayland/XWayland.hpp | 4 ++-- 6 files changed, 8 insertions(+), 20 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index eac75bd4d45..34e5bf78eef 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -615,7 +615,7 @@ void CCompositor::initManagers(eManagersInitStage stage) { g_pCursorManager = std::make_unique(); Debug::log(LOG, "Starting XWayland"); - g_pXWayland = std::make_unique(); + g_pXWayland = std::make_unique(g_pCompositor->m_bEnableXwayland); } break; default: UNREACHABLE(); } diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 737df661cfd..d6c0e8e4b4d 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -871,7 +871,6 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) { g_pCompositor->m_bEnableXwayland = PENABLEXWAYLAND; if (PENABLEXWAYLAND) { Debug::log(LOG, "xwayland has been enabled"); - g_pXWayland = std::make_unique(); } else { Debug::log(LOG, "xwayland has been disabled, cleaning up..."); for (auto& w : g_pCompositor->m_vWindows) { @@ -879,10 +878,8 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) { continue; g_pCompositor->closeWindow(w); } - g_pXWayland->pServer = std::make_unique(); - g_pXWayland->pWM = std::make_unique(); - g_pXWayland->pServer->setDisplayEnv(); } + g_pXWayland = std::make_unique(g_pCompositor->m_bEnableXwayland); } } else g_pCompositor->m_bEnableXwayland = PENABLEXWAYLAND; diff --git a/src/xwayland/Server.cpp b/src/xwayland/Server.cpp index a845156d1a0..f3bf576881a 100644 --- a/src/xwayland/Server.cpp +++ b/src/xwayland/Server.cpp @@ -288,7 +288,7 @@ bool CXWaylandServer::create() { if (!tryOpenSockets()) return false; - setDisplayEnv(); + setenv("DISPLAY", displayName.c_str(), true); // TODO: lazy mode @@ -297,13 +297,6 @@ bool CXWaylandServer::create() { return true; } -void CXWaylandServer::setDisplayEnv() { - if (g_pCompositor->m_bEnableXwayland) - setenv("DISPLAY", displayName.c_str(), true); - else - unsetenv("DISPLAY"); -} - void CXWaylandServer::runXWayland(int notifyFD) { if (!set_cloexec(xFDs[0], false) || !set_cloexec(xFDs[1], false) || !set_cloexec(waylandFDs[1], false) || !set_cloexec(xwmFDs[1], false)) { Debug::log(ERR, "Failed to unset cloexec on fds"); diff --git a/src/xwayland/Server.hpp b/src/xwayland/Server.hpp index cff59d3353c..7a36a965f9c 100644 --- a/src/xwayland/Server.hpp +++ b/src/xwayland/Server.hpp @@ -15,8 +15,6 @@ class CXWaylandServer { // create the server. bool create(); - void setDisplayEnv(void); - // starts the server, meant to be called by CXWaylandServer. bool start(); diff --git a/src/xwayland/XWayland.cpp b/src/xwayland/XWayland.cpp index c2136dc1b83..8cdb1fca319 100644 --- a/src/xwayland/XWayland.cpp +++ b/src/xwayland/XWayland.cpp @@ -1,14 +1,14 @@ #include "XWayland.hpp" #include "../debug/Log.hpp" -CXWayland::CXWayland() { +CXWayland::CXWayland(const bool enabled) { #ifndef NO_XWAYLAND Debug::log(LOG, "Starting up the XWayland server"); pServer = std::make_unique(); - if (!g_pCompositor->m_bEnableXwayland) { - pServer->setDisplayEnv(); + if (!enabled) { + unsetenv("DISPLAY"); return; } diff --git a/src/xwayland/XWayland.hpp b/src/xwayland/XWayland.hpp index 40c0ba656cd..96253d193c0 100644 --- a/src/xwayland/XWayland.hpp +++ b/src/xwayland/XWayland.hpp @@ -17,7 +17,7 @@ class CXWM; class CXWayland { public: - CXWayland(); + CXWayland(const bool enabled); #ifndef NO_XWAYLAND std::unique_ptr pServer; @@ -126,4 +126,4 @@ inline std::unordered_map HYPRATOMS = { HYPRATOM("DELETE"), HYPRATOM("TEXT"), HYPRATOM("INCR"), -}; \ No newline at end of file +}; From 02b2972a71c2b2d27434e1ea5861808ddea2bff6 Mon Sep 17 00:00:00 2001 From: Trianta <56975502+Trimutex@users.noreply.github.com> Date: Wed, 4 Sep 2024 15:29:55 -0500 Subject: [PATCH 8/9] xwayland: prevent closing non-xwayland windows on disable --- src/config/ConfigManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index d6c0e8e4b4d..740dbbdf88e 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -874,7 +874,7 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) { } else { Debug::log(LOG, "xwayland has been disabled, cleaning up..."); for (auto& w : g_pCompositor->m_vWindows) { - if (!w->m_bIsX11) + if (w->m_pXDGSurface || !w->m_bIsX11) continue; g_pCompositor->closeWindow(w); } From 14d47ade78c6bc4407b008b1ca8bb3cd07b529eb Mon Sep 17 00:00:00 2001 From: Trianta <56975502+Trimutex@users.noreply.github.com> Date: Wed, 4 Sep 2024 19:54:14 -0500 Subject: [PATCH 9/9] misc: loop formatting --- src/xwayland/XWM.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/xwayland/XWM.cpp b/src/xwayland/XWM.cpp index 886a3505b0e..e8e2258a119 100644 --- a/src/xwayland/XWM.cpp +++ b/src/xwayland/XWM.cpp @@ -891,8 +891,9 @@ CXWM::~CXWM() { if (eventSource) wl_event_source_remove(eventSource); - for (auto const& sr : surfaces) + for (auto const& sr : surfaces) { sr->events.destroy.emit(); + } } void CXWM::setActiveWindow(xcb_window_t window) {