|
15 | 15 | #include <thread> |
16 | 16 |
|
17 | 17 | void CIPCSocket::initialize() { |
18 | | - std::thread([&]() { |
19 | | - const auto SOCKET = socket(AF_UNIX, SOCK_STREAM, 0); |
| 18 | + fd = socket(AF_UNIX, SOCK_STREAM, 0); |
20 | 19 |
|
21 | | - if (SOCKET < 0) { |
22 | | - Debug::log(ERR, "Couldn't start the hyprpaper Socket. (1) IPC will not work."); |
23 | | - return; |
24 | | - } |
25 | | - |
26 | | - sockaddr_un SERVERADDRESS = {.sun_family = AF_UNIX}; |
27 | | - |
28 | | - const auto HISenv = getenv("HYPRLAND_INSTANCE_SIGNATURE"); |
29 | | - const auto RUNTIMEdir = getenv("XDG_RUNTIME_DIR"); |
30 | | - const std::string USERID = std::to_string(getpwuid(getuid())->pw_uid); |
| 20 | + if (fd < 0) { |
| 21 | + Debug::log(ERR, "Couldn't start the hyprpaper Socket. (1) IPC will not work."); |
| 22 | + return; |
| 23 | + } |
31 | 24 |
|
32 | | - const auto USERDIR = RUNTIMEdir ? RUNTIMEdir + std::string{"/hypr/"} : "/run/user/" + USERID + "/hypr/"; |
| 25 | + sockaddr_un SERVERADDRESS = {.sun_family = AF_UNIX}; |
33 | 26 |
|
34 | | - std::string socketPath = HISenv ? USERDIR + std::string(HISenv) + "/.hyprpaper.sock" : USERDIR + ".hyprpaper.sock"; |
| 27 | + const auto HISenv = getenv("HYPRLAND_INSTANCE_SIGNATURE"); |
| 28 | + const auto RUNTIMEdir = getenv("XDG_RUNTIME_DIR"); |
| 29 | + const std::string USERID = std::to_string(getpwuid(getuid())->pw_uid); |
35 | 30 |
|
36 | | - if (!HISenv) |
37 | | - mkdir(USERDIR.c_str(), S_IRWXU); |
| 31 | + const auto USERDIR = RUNTIMEdir ? RUNTIMEdir + std::string{"/hypr/"} : "/run/user/" + USERID + "/hypr/"; |
38 | 32 |
|
39 | | - unlink(socketPath.c_str()); |
| 33 | + std::string socketPath = HISenv ? USERDIR + std::string(HISenv) + "/.hyprpaper.sock" : USERDIR + ".hyprpaper.sock"; |
40 | 34 |
|
41 | | - strcpy(SERVERADDRESS.sun_path, socketPath.c_str()); |
| 35 | + if (!HISenv) |
| 36 | + mkdir(USERDIR.c_str(), S_IRWXU); |
42 | 37 |
|
43 | | - bind(SOCKET, (sockaddr*)&SERVERADDRESS, SUN_LEN(&SERVERADDRESS)); |
| 38 | + unlink(socketPath.c_str()); |
44 | 39 |
|
45 | | - // 10 max queued. |
46 | | - listen(SOCKET, 10); |
| 40 | + strcpy(SERVERADDRESS.sun_path, socketPath.c_str()); |
47 | 41 |
|
48 | | - sockaddr_in clientAddress = {}; |
49 | | - socklen_t clientSize = sizeof(clientAddress); |
| 42 | + if (bind(fd, (sockaddr*)&SERVERADDRESS, SUN_LEN(&SERVERADDRESS)) < 0) { |
| 43 | + Debug::log(ERR, "Couldn't bind the hyprpaper Socket. IPC will not work."); |
| 44 | + fd = -1; |
| 45 | + return; |
| 46 | + } |
50 | 47 |
|
51 | | - char readBuffer[1024] = {0}; |
| 48 | + // 10 max queued. |
| 49 | + listen(fd, 10); |
52 | 50 |
|
53 | | - Debug::log(LOG, "hyprpaper socket started at %s (fd: %i)", socketPath.c_str(), SOCKET); |
54 | | - while (1) { |
55 | | - const auto ACCEPTEDCONNECTION = accept(SOCKET, (sockaddr*)&clientAddress, &clientSize); |
56 | | - if (ACCEPTEDCONNECTION < 0) { |
57 | | - Debug::log(ERR, "Couldn't listen on the hyprpaper Socket. (3) IPC will not work."); |
58 | | - break; |
59 | | - } else { |
60 | | - do { |
61 | | - Debug::log(LOG, "Accepted incoming socket connection request on fd %i", ACCEPTEDCONNECTION); |
62 | | - std::lock_guard<std::mutex> lg(g_pHyprpaper->m_mtTickMutex); |
63 | | - |
64 | | - auto messageSize = read(ACCEPTEDCONNECTION, readBuffer, 1024); |
65 | | - readBuffer[messageSize == 1024 ? 1023 : messageSize] = '\0'; |
66 | | - if (messageSize == 0) |
67 | | - break; |
68 | | - std::string request(readBuffer); |
69 | | - |
70 | | - m_szRequest = request; |
71 | | - m_bRequestReady = true; |
72 | | - |
73 | | - g_pHyprpaper->tick(true); |
74 | | - while (!m_bReplyReady) { // wait for Hyprpaper to finish processing the request |
75 | | - std::this_thread::sleep_for(std::chrono::milliseconds(1)); |
76 | | - } |
77 | | - write(ACCEPTEDCONNECTION, m_szReply.c_str(), m_szReply.length()); |
78 | | - m_bReplyReady = false; |
79 | | - m_szReply = ""; |
80 | | - |
81 | | - } while (1); |
82 | | - Debug::log(LOG, "Closing Accepted Connection"); |
83 | | - close(ACCEPTEDCONNECTION); |
84 | | - } |
85 | | - } |
| 51 | + Debug::log(LOG, "hyprpaper socket started at %s (fd: %i)", socketPath.c_str(), fd); |
| 52 | +} |
86 | 53 |
|
87 | | - close(SOCKET); |
88 | | - }).detach(); |
| 54 | +CIPCSocket::~CIPCSocket() { |
| 55 | + if (fd >= 0) |
| 56 | + close(fd); |
89 | 57 | } |
90 | 58 |
|
91 | | -bool CIPCSocket::mainThreadParseRequest() { |
| 59 | +bool CIPCSocket::parseRequest() { |
| 60 | + sockaddr_in clientAddress = {}; |
| 61 | + socklen_t clientSize = sizeof(clientAddress); |
| 62 | + |
| 63 | + char readBuffer[1024] = {0}; |
92 | 64 |
|
93 | | - if (!m_bRequestReady) |
| 65 | + const auto ACCEPTEDCONNECTION = accept(fd, (sockaddr*)&clientAddress, &clientSize); |
| 66 | + if (ACCEPTEDCONNECTION < 0) { |
| 67 | + Debug::log(ERR, "Couldn't listen on the hyprpaper Socket. (3)"); |
94 | 68 | return false; |
| 69 | + } else { |
| 70 | + |
| 71 | + Debug::log(LOG, "Accepted incoming socket connection request on fd %i", ACCEPTEDCONNECTION); |
| 72 | + std::string body = ""; |
| 73 | + do { |
| 74 | + auto messageSize = read(ACCEPTEDCONNECTION, readBuffer, 1024); |
| 75 | + body += std::string{readBuffer, messageSize}; |
| 76 | + if (messageSize < 1024) |
| 77 | + break; |
| 78 | + } while (1); |
95 | 79 |
|
96 | | - std::string copy = m_szRequest; |
| 80 | + auto reply = processRequest(body); |
| 81 | + write(ACCEPTEDCONNECTION, reply.c_str(), reply.length()); |
97 | 82 |
|
98 | | - if (copy == "") |
99 | | - return false; |
| 83 | + Debug::log(LOG, "Closing Accepted Connection"); |
| 84 | + close(ACCEPTEDCONNECTION); |
| 85 | + } |
| 86 | + |
| 87 | + return true; |
| 88 | +} |
100 | 89 |
|
101 | | - // now we can work on the copy |
| 90 | +std::string CIPCSocket::processRequest(const std::string& body) { |
102 | 91 |
|
103 | | - Debug::log(LOG, "Received a request: %s", copy.c_str()); |
| 92 | + std::string reply = "ok"; |
104 | 93 |
|
105 | | - // set default reply |
106 | | - m_szReply = "ok"; |
107 | | - m_bReplyReady = true; |
108 | | - m_bRequestReady = false; |
| 94 | + Debug::log(LOG, "Received a request: %s", body.c_str()); |
109 | 95 |
|
110 | 96 | // config commands |
111 | | - if (copy.find("wallpaper") == 0 || copy.find("preload") == 0 || copy.find("unload") == 0 || copy.find("reload") == 0) { |
| 97 | + if (body.find("wallpaper") == 0 || body.find("preload") == 0 || body.find("unload") == 0 || body.find("reload") == 0) { |
112 | 98 |
|
113 | | - const auto RESULT = g_pConfigManager->config->parseDynamic(copy.substr(0, copy.find_first_of(' ')).c_str(), copy.substr(copy.find_first_of(' ') + 1).c_str()); |
| 99 | + const auto RESULT = g_pConfigManager->config->parseDynamic(body.substr(0, body.find_first_of(' ')).c_str(), body.substr(body.find_first_of(' ') + 1).c_str()); |
114 | 100 |
|
115 | | - if (RESULT.error) { |
116 | | - m_szReply = RESULT.getError(); |
117 | | - return false; |
118 | | - } |
| 101 | + if (RESULT.error) |
| 102 | + reply = RESULT.getError(); |
119 | 103 |
|
120 | | - return true; |
| 104 | + return reply; |
121 | 105 | } |
122 | 106 |
|
123 | | - if (copy.find("listloaded") == 0) { |
| 107 | + if (body.find("listloaded") == 0) { |
124 | 108 |
|
125 | 109 | const auto numWallpapersLoaded = g_pHyprpaper->m_mWallpaperTargets.size(); |
126 | 110 | Debug::log(LOG, "numWallpapersLoaded: %d", numWallpapersLoaded); |
127 | 111 |
|
128 | | - if (numWallpapersLoaded == 0) { |
129 | | - m_szReply = "no wallpapers loaded"; |
130 | | - return false; |
131 | | - } |
| 112 | + if (numWallpapersLoaded == 0) |
| 113 | + return "no wallpapers loaded"; |
132 | 114 |
|
133 | | - m_szReply = ""; |
| 115 | + reply = ""; |
134 | 116 | long unsigned int i = 0; |
135 | 117 | for (auto& [name, target] : g_pHyprpaper->m_mWallpaperTargets) { |
136 | | - m_szReply += name; |
| 118 | + reply += name; |
137 | 119 | i++; |
138 | 120 | if (i < numWallpapersLoaded) |
139 | | - m_szReply += '\n'; // dont add newline on last entry |
| 121 | + reply += '\n'; // dont add newline on last entry |
140 | 122 | } |
141 | 123 |
|
142 | | - return true; |
| 124 | + return reply; |
143 | 125 | } |
144 | 126 |
|
145 | | - if (copy.find("listactive") == 0) { |
| 127 | + if (body.find("listactive") == 0) { |
146 | 128 |
|
147 | 129 | const auto numWallpapersActive = g_pHyprpaper->m_mMonitorActiveWallpapers.size(); |
148 | 130 | Debug::log(LOG, "numWallpapersActive: %d", numWallpapersActive); |
149 | 131 |
|
150 | | - if (numWallpapersActive == 0) { |
151 | | - m_szReply = "no wallpapers active"; |
152 | | - return false; |
153 | | - } |
| 132 | + if (numWallpapersActive == 0) |
| 133 | + return "no wallpapers active"; |
154 | 134 |
|
155 | | - m_szReply = ""; |
| 135 | + reply = ""; |
156 | 136 | long unsigned int i = 0; |
157 | 137 | for (auto& [mon, path1] : g_pHyprpaper->m_mMonitorActiveWallpapers) { |
158 | | - m_szReply += mon + " = " + path1; |
| 138 | + reply += mon + " = " + path1; |
159 | 139 | i++; |
160 | 140 | if (i < numWallpapersActive) |
161 | | - m_szReply += '\n'; // dont add newline on last entry |
| 141 | + reply += '\n'; // dont add newline on last entry |
162 | 142 | } |
163 | 143 |
|
164 | | - return true; |
| 144 | + return reply; |
165 | 145 | } |
166 | 146 |
|
167 | | - m_szReply = "invalid command"; |
168 | | - return false; |
| 147 | + return "invalid command"; |
169 | 148 | } |
0 commit comments