2022-03-16 20:50:55 +01:00
|
|
|
#include "defines.hpp"
|
|
|
|
#include "debug/Log.hpp"
|
2022-03-16 21:37:21 +01:00
|
|
|
#include "Compositor.hpp"
|
2022-03-17 15:53:45 +01:00
|
|
|
#include "config/ConfigManager.hpp"
|
2022-05-19 19:28:15 +02:00
|
|
|
#include "init/initHelpers.hpp"
|
2024-09-25 11:36:43 +02:00
|
|
|
#include "debug/HyprCtl.hpp"
|
2023-04-07 16:03:26 +02:00
|
|
|
|
2024-10-13 14:24:10 +02:00
|
|
|
#include <cstdio>
|
2024-09-19 12:25:58 +02:00
|
|
|
#include <hyprutils/string/String.hpp>
|
2024-10-13 14:24:10 +02:00
|
|
|
#include <print>
|
2024-09-19 12:25:58 +02:00
|
|
|
using namespace Hyprutils::String;
|
|
|
|
|
2024-07-20 00:37:20 +02:00
|
|
|
#include <fcntl.h>
|
2022-06-03 17:48:07 +02:00
|
|
|
#include <iostream>
|
2023-04-07 16:03:26 +02:00
|
|
|
#include <iterator>
|
|
|
|
#include <vector>
|
|
|
|
#include <stdexcept>
|
|
|
|
#include <string>
|
|
|
|
#include <filesystem>
|
|
|
|
|
|
|
|
void help() {
|
2024-10-13 14:24:10 +02:00
|
|
|
std::println("usage: Hyprland [arg [...]].\n");
|
|
|
|
std::println(R"(Arguments:
|
|
|
|
--help -h - Show this message again
|
|
|
|
--config FILE -c FILE - Specify config file to use
|
|
|
|
--socket NAME - Sets the Wayland socket name (for Wayland socket handover)
|
|
|
|
--wayland-fd FD - Sets the Wayland socket fd (for Wayland socket handover)
|
|
|
|
--systeminfo - Prints system infos
|
|
|
|
--i-am-really-stupid - Omits root user privileges check (why would you do that?)
|
|
|
|
--version -v - Print this binary's version)");
|
2023-04-07 16:03:26 +02:00
|
|
|
}
|
|
|
|
|
2022-03-16 20:50:55 +01:00
|
|
|
int main(int argc, char** argv) {
|
|
|
|
|
|
|
|
if (!getenv("XDG_RUNTIME_DIR"))
|
2023-08-20 13:58:46 +02:00
|
|
|
throwError("XDG_RUNTIME_DIR is not set!");
|
2022-03-16 20:50:55 +01:00
|
|
|
|
2022-09-19 22:06:44 +02:00
|
|
|
// export HYPRLAND_CMD
|
2024-10-11 13:19:16 +02:00
|
|
|
std::string cmd = argv[0];
|
|
|
|
for (int i = 1; i < argc; ++i)
|
|
|
|
cmd += std::string(" ") + argv[i];
|
2023-04-07 16:03:26 +02:00
|
|
|
|
2022-09-19 22:06:44 +02:00
|
|
|
setenv("HYPRLAND_CMD", cmd.c_str(), 1);
|
2022-11-19 20:37:16 +01:00
|
|
|
setenv("XDG_BACKEND", "wayland", 1);
|
2023-01-09 21:26:19 +01:00
|
|
|
setenv("_JAVA_AWT_WM_NONREPARENTING", "1", 1);
|
2023-03-05 14:37:21 +01:00
|
|
|
setenv("MOZ_ENABLE_WAYLAND", "1", 1);
|
2022-09-19 22:06:44 +02:00
|
|
|
|
2022-05-19 19:28:15 +02:00
|
|
|
// parse some args
|
2023-04-07 16:03:26 +02:00
|
|
|
std::string configPath;
|
2024-07-20 00:37:20 +02:00
|
|
|
std::string socketName;
|
|
|
|
int socketFd = -1;
|
2023-04-07 16:03:26 +02:00
|
|
|
bool ignoreSudo = false;
|
|
|
|
|
|
|
|
std::vector<std::string> args{argv + 1, argv + argc};
|
|
|
|
|
|
|
|
for (auto it = args.begin(); it != args.end(); it++) {
|
2024-12-07 18:51:18 +01:00
|
|
|
if (*it == "--i-am-really-stupid" && !ignoreSudo) {
|
2024-10-13 14:24:10 +02:00
|
|
|
std::println("[ WARNING ] Running Hyprland with superuser privileges might damage your system");
|
2023-04-07 16:03:26 +02:00
|
|
|
|
2022-05-19 19:28:15 +02:00
|
|
|
ignoreSudo = true;
|
2024-12-07 18:51:18 +01:00
|
|
|
} else if (*it == "--socket") {
|
2024-07-20 00:37:20 +02:00
|
|
|
if (std::next(it) == args.end()) {
|
|
|
|
help();
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
socketName = *std::next(it);
|
|
|
|
it++;
|
2024-12-07 18:51:18 +01:00
|
|
|
} else if (*it == "--wayland-fd") {
|
2024-07-20 00:37:20 +02:00
|
|
|
if (std::next(it) == args.end()) {
|
|
|
|
help();
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
2024-12-07 18:51:18 +01:00
|
|
|
socketFd = std::stoi(*std::next(it));
|
2024-07-20 00:37:20 +02:00
|
|
|
|
|
|
|
// check if socketFd is a valid file descriptor
|
|
|
|
if (fcntl(socketFd, F_GETFD) == -1)
|
|
|
|
throw std::exception();
|
|
|
|
} catch (...) {
|
2024-10-13 14:24:10 +02:00
|
|
|
std::println(stderr, "[ ERROR ] Invalid Wayland FD!");
|
2024-07-20 00:37:20 +02:00
|
|
|
help();
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
it++;
|
2024-12-07 18:51:18 +01:00
|
|
|
} else if (*it == "-c" || *it == "--config") {
|
2023-06-09 12:15:18 +02:00
|
|
|
if (std::next(it) == args.end()) {
|
2023-04-07 16:03:26 +02:00
|
|
|
help();
|
2023-07-18 21:00:08 +02:00
|
|
|
|
2023-04-07 16:03:26 +02:00
|
|
|
return 1;
|
|
|
|
}
|
2024-12-07 18:51:18 +01:00
|
|
|
configPath = *std::next(it);
|
2023-04-07 16:03:26 +02:00
|
|
|
|
2023-12-12 17:43:38 +01:00
|
|
|
try {
|
|
|
|
configPath = std::filesystem::canonical(configPath);
|
2023-12-04 02:35:24 +01:00
|
|
|
|
2023-12-12 17:43:38 +01:00
|
|
|
if (!std::filesystem::is_regular_file(configPath)) {
|
|
|
|
throw std::exception();
|
|
|
|
}
|
|
|
|
} catch (...) {
|
2024-10-13 14:24:10 +02:00
|
|
|
std::println(stderr, "[ ERROR ] Config file '{}' doesn't exist!", configPath);
|
2023-04-07 16:03:26 +02:00
|
|
|
help();
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2023-09-06 21:45:37 +02:00
|
|
|
Debug::log(LOG, "User-specified config location: '{}'", configPath);
|
2023-04-10 19:26:36 +02:00
|
|
|
|
|
|
|
it++;
|
|
|
|
|
2023-04-07 16:03:26 +02:00
|
|
|
continue;
|
2024-12-07 18:51:18 +01:00
|
|
|
} else if (*it == "-h" || *it == "--help") {
|
2023-04-10 19:26:36 +02:00
|
|
|
help();
|
2023-07-18 21:00:08 +02:00
|
|
|
|
2024-09-19 12:25:58 +02:00
|
|
|
return 0;
|
2024-12-07 18:51:18 +01:00
|
|
|
} else if (*it == "-v" || *it == "--version") {
|
2024-10-13 14:24:10 +02:00
|
|
|
std::println("{}", versionRequest(eHyprCtlOutputFormat::FORMAT_NORMAL, ""));
|
2023-04-10 19:26:36 +02:00
|
|
|
return 0;
|
2024-12-07 18:51:18 +01:00
|
|
|
} else if (*it == "--systeminfo") {
|
2024-10-13 14:24:10 +02:00
|
|
|
std::println("{}", systemInfoRequest(eHyprCtlOutputFormat::FORMAT_NORMAL, ""));
|
2024-09-25 11:36:43 +02:00
|
|
|
return 0;
|
2023-07-18 21:00:08 +02:00
|
|
|
} else {
|
2024-12-07 18:51:18 +01:00
|
|
|
std::println(stderr, "[ ERROR ] Unknown option '{}' !", *it);
|
2023-07-18 21:00:08 +02:00
|
|
|
help();
|
|
|
|
|
|
|
|
return 1;
|
2022-12-16 18:17:31 +01:00
|
|
|
}
|
2023-04-07 16:03:26 +02:00
|
|
|
}
|
|
|
|
|
2024-12-07 18:51:18 +01:00
|
|
|
if (!ignoreSudo && NInit::isSudo()) {
|
2024-10-13 14:24:10 +02:00
|
|
|
std::println(stderr,
|
|
|
|
"[ ERROR ] Hyprland was launched with superuser privileges, but the privileges check is not omitted.\n"
|
|
|
|
" Hint: Use the --i-am-really-stupid flag to omit that check.");
|
2023-04-07 16:03:26 +02:00
|
|
|
|
|
|
|
return 1;
|
2024-12-07 18:51:18 +01:00
|
|
|
} else if (ignoreSudo && NInit::isSudo()) {
|
2024-10-13 14:24:10 +02:00
|
|
|
std::println("Superuser privileges check is omitted. I hope you know what you're doing.");
|
2022-05-19 19:28:15 +02:00
|
|
|
}
|
|
|
|
|
2024-07-20 00:37:20 +02:00
|
|
|
if (socketName.empty() ^ (socketFd == -1)) {
|
2024-10-13 14:24:10 +02:00
|
|
|
std::println(stderr,
|
|
|
|
"[ ERROR ] Hyprland was launched with only one of --socket and --wayland-fd.\n"
|
|
|
|
" Hint: Pass both --socket and --wayland-fd to perform Wayland socket handover.");
|
2024-07-20 00:37:20 +02:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2024-10-13 14:24:10 +02:00
|
|
|
std::println("Welcome to Hyprland!");
|
2022-03-16 21:37:21 +01:00
|
|
|
|
|
|
|
// let's init the compositor.
|
|
|
|
// it initializes basic Wayland stuff in the constructor.
|
2024-04-28 23:25:24 +02:00
|
|
|
try {
|
|
|
|
g_pCompositor = std::make_unique<CCompositor>();
|
|
|
|
g_pCompositor->explicitConfigPath = configPath;
|
2024-10-13 14:24:10 +02:00
|
|
|
} catch (const std::exception& e) {
|
|
|
|
std::println(stderr, "Hyprland threw in ctor: {}\nCannot continue.", e.what());
|
2024-04-28 23:25:24 +02:00
|
|
|
return 1;
|
|
|
|
}
|
2022-03-16 21:37:21 +01:00
|
|
|
|
2024-07-22 13:16:25 +02:00
|
|
|
g_pCompositor->initServer(socketName, socketFd);
|
2023-03-05 14:37:21 +01:00
|
|
|
|
2023-12-21 22:27:12 +01:00
|
|
|
if (!envEnabled("HYPRLAND_NO_RT"))
|
2024-12-07 18:51:18 +01:00
|
|
|
NInit::gainRealTime();
|
2023-07-24 18:26:24 +02:00
|
|
|
|
2022-03-16 21:37:21 +01:00
|
|
|
Debug::log(LOG, "Hyprland init finished.");
|
|
|
|
|
|
|
|
// If all's good to go, start.
|
2024-07-22 13:16:25 +02:00
|
|
|
g_pCompositor->startCompositor();
|
2022-03-16 20:50:55 +01:00
|
|
|
|
2024-07-24 19:07:36 +02:00
|
|
|
g_pCompositor->cleanup();
|
2023-11-07 15:53:56 +01:00
|
|
|
|
2024-07-24 19:07:36 +02:00
|
|
|
Debug::log(LOG, "Hyprland has reached the end.");
|
2022-03-16 20:50:55 +01:00
|
|
|
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
}
|