Skip to content

Commit

Permalink
compositor: implement wayland socket handover
Browse files Browse the repository at this point in the history
This commit implements the compositor side of the Wayland socket
handover protocol as described in the [KDE Wiki]. The CLI options are
chosen so that they are compatible with Kwin.

[KDE Wiki]: https://invent.kde.org/plasma/kwin/-/wikis/Restarting
  • Loading branch information
Ferdi265 committed Jul 19, 2024
1 parent 300228b commit 94d994c
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 11 deletions.
30 changes: 21 additions & 9 deletions src/Compositor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <hyprutils/string/String.hpp>
using namespace Hyprutils::String;

#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/resource.h>
Expand Down Expand Up @@ -533,19 +534,30 @@ void CCompositor::prepareFallbackOutput() {
wlr_headless_add_output(headless, 1920, 1080);
}

void CCompositor::startCompositor() {
void CCompositor::startCompositor(std::string socketName, int socketFd) {
initAllSignals();

// get socket, avoid using 0
for (int candidate = 1; candidate <= 32; candidate++) {
const auto CANDIDATESTR = ("wayland-" + std::to_string(candidate));
const auto RETVAL = wl_display_add_socket(m_sWLDisplay, CANDIDATESTR.c_str());
if (!socketName.empty() && socketFd != -1) {
fcntl(socketFd, F_SETFD, FD_CLOEXEC);
const auto RETVAL = wl_display_add_socket_fd(m_sWLDisplay, socketFd);
if (RETVAL >= 0) {
m_szWLDisplaySocket = CANDIDATESTR;
Debug::log(LOG, "wl_display_add_socket for {} succeeded with {}", CANDIDATESTR, RETVAL);
break;
m_szWLDisplaySocket = socketName;
Debug::log(LOG, "wl_display_add_socket_fd for {} succeeded with {}", socketName, RETVAL);
} else {
Debug::log(WARN, "wl_display_add_socket for {} returned {}: skipping candidate {}", CANDIDATESTR, RETVAL, candidate);
Debug::log(WARN, "wl_display_add_socket_fd for {} returned {}: skipping", socketName, RETVAL);
}
} else {
// get socket, avoid using 0
for (int candidate = 1; candidate <= 32; candidate++) {
const auto CANDIDATESTR = ("wayland-" + std::to_string(candidate));
const auto RETVAL = wl_display_add_socket(m_sWLDisplay, CANDIDATESTR.c_str());
if (RETVAL >= 0) {
m_szWLDisplaySocket = CANDIDATESTR;
Debug::log(LOG, "wl_display_add_socket for {} succeeded with {}", CANDIDATESTR, RETVAL);
break;
} else {
Debug::log(WARN, "wl_display_add_socket for {} returned {}: skipping candidate {}", CANDIDATESTR, RETVAL, candidate);
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/Compositor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class CCompositor {
std::unordered_map<std::string, uint64_t> m_mMonitorIDMap;

void initServer();
void startCompositor();
void startCompositor(std::string socketName, int socketFd);
void cleanup();
void createLockFile();
void removeLockFile();
Expand Down
24 changes: 23 additions & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ void help() {
std::cout << "\nArguments:\n";
std::cout << " --help -h - Show this message again\n";
std::cout << " --config FILE -c FILE - Specify config file to use\n";
std::cout << " --socket NAME - Sets the Wayland socket name (for crash-recovery)\n";
std::cout << " --wayland-fd FD - Sets the Wayland socket fd (for crash-recovery)\n";
std::cout << " --i-am-really-stupid - Omits root user privileges check (why would you do that?)\n";
}

Expand All @@ -37,6 +39,8 @@ int main(int argc, char** argv) {

// parse some args
std::string configPath;
std::string socketName;
int socketFd = -1;
bool ignoreSudo = false;

std::vector<std::string> args{argv + 1, argv + argc};
Expand All @@ -46,6 +50,24 @@ int main(int argc, char** argv) {
std::cout << "[ WARNING ] Running Hyprland with superuser privileges might damage your system\n";

ignoreSudo = true;
} else if (it->compare("--socket") == 0) {
if (std::next(it) == args.end()) {
help();

return 1;
}

socketName = *std::next(it);
it++;
} else if (it->compare("--wayland-fd") == 0) {
if (std::next(it) == args.end()) {
help();

return 1;
}

socketFd = std::atoi(std::next(it)->c_str());
it++;
} else if (it->compare("-c") == 0 || it->compare("--config") == 0) {
if (std::next(it) == args.end()) {
help();
Expand Down Expand Up @@ -113,7 +135,7 @@ int main(int argc, char** argv) {
Debug::log(LOG, "Hyprland init finished.");

// If all's good to go, start.
g_pCompositor->startCompositor();
g_pCompositor->startCompositor(socketName, socketFd);

g_pCompositor->m_bIsShuttingDown = true;

Expand Down

0 comments on commit 94d994c

Please sign in to comment.