mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-05 06:25:59 +01:00
config: add exec-shutdown for running commands on shutdown (#7683)
* config: add exec-shutdown for running commands on shutdown * compositor: delay stopping until after exec-shutdown
This commit is contained in:
parent
5ca4823128
commit
70add904c4
4 changed files with 51 additions and 0 deletions
|
@ -91,6 +91,7 @@ class CCompositor {
|
|||
bool m_bNextIsUnsafe = false;
|
||||
CMonitor* m_pUnsafeOutput = nullptr; // fallback output for the unsafe state
|
||||
bool m_bIsShuttingDown = false;
|
||||
bool m_bFinalRequests = false;
|
||||
bool m_bDesktopEnvSet = false;
|
||||
bool m_bEnableXwayland = true;
|
||||
|
||||
|
|
|
@ -141,6 +141,18 @@ static Hyprlang::CParseResult handleExecOnce(const char* c, const char* v) {
|
|||
return result;
|
||||
}
|
||||
|
||||
static Hyprlang::CParseResult handleExecShutdown(const char* c, const char* v) {
|
||||
const std::string VALUE = v;
|
||||
const std::string COMMAND = c;
|
||||
|
||||
const auto RESULT = g_pConfigManager->handleExecShutdown(COMMAND, VALUE);
|
||||
|
||||
Hyprlang::CParseResult result;
|
||||
if (RESULT.has_value())
|
||||
result.setError(RESULT.value().c_str());
|
||||
return result;
|
||||
}
|
||||
|
||||
static Hyprlang::CParseResult handleMonitor(const char* c, const char* v) {
|
||||
const std::string VALUE = v;
|
||||
const std::string COMMAND = c;
|
||||
|
@ -609,6 +621,7 @@ CConfigManager::CConfigManager() {
|
|||
// keywords
|
||||
m_pConfig->registerHandler(&::handleRawExec, "exec", {false});
|
||||
m_pConfig->registerHandler(&::handleExecOnce, "exec-once", {false});
|
||||
m_pConfig->registerHandler(&::handleExecShutdown, "exec-shutdown", {false});
|
||||
m_pConfig->registerHandler(&::handleMonitor, "monitor", {false});
|
||||
m_pConfig->registerHandler(&::handleBind, "bind", {true});
|
||||
m_pConfig->registerHandler(&::handleUnbind, "unbind", {false});
|
||||
|
@ -801,6 +814,7 @@ std::optional<std::string> CConfigManager::resetHLConfig() {
|
|||
m_vDeclaredPlugins.clear();
|
||||
m_dLayerRules.clear();
|
||||
m_vFailedPluginConfigValues.clear();
|
||||
finalExecRequests.clear();
|
||||
|
||||
// paths
|
||||
configPaths.clear();
|
||||
|
@ -1398,6 +1412,24 @@ void CConfigManager::dispatchExecOnce() {
|
|||
g_pCompositor->performUserChecks();
|
||||
}
|
||||
|
||||
void CConfigManager::dispatchExecShutdown() {
|
||||
if (finalExecRequests.empty()) {
|
||||
g_pCompositor->m_bFinalRequests = false;
|
||||
return;
|
||||
}
|
||||
|
||||
g_pCompositor->m_bFinalRequests = true;
|
||||
|
||||
for (auto const& c : finalExecRequests) {
|
||||
handleExecShutdown("", c);
|
||||
}
|
||||
|
||||
finalExecRequests.clear();
|
||||
|
||||
// Actually exit now
|
||||
handleExecShutdown("", "hyprctl dispatch exit");
|
||||
}
|
||||
|
||||
void CConfigManager::appendMonitorRule(const SMonitorRule& r) {
|
||||
m_dMonitorRules.emplace_back(r);
|
||||
}
|
||||
|
@ -1700,6 +1732,16 @@ std::optional<std::string> CConfigManager::handleExecOnce(const std::string& com
|
|||
return {};
|
||||
}
|
||||
|
||||
std::optional<std::string> CConfigManager::handleExecShutdown(const std::string& command, const std::string& args) {
|
||||
if (g_pCompositor->m_bFinalRequests) {
|
||||
g_pKeybindManager->spawn(args);
|
||||
return {};
|
||||
}
|
||||
|
||||
finalExecRequests.push_back(args);
|
||||
return {};
|
||||
}
|
||||
|
||||
static bool parseModeLine(const std::string& modeline, drmModeModeInfo& mode) {
|
||||
auto args = CVarList(modeline, 0, 's');
|
||||
|
||||
|
|
|
@ -192,6 +192,7 @@ class CConfigManager {
|
|||
|
||||
// no-op when done.
|
||||
void dispatchExecOnce();
|
||||
void dispatchExecShutdown();
|
||||
|
||||
void performMonitorReload();
|
||||
void appendMonitorRule(const SMonitorRule&);
|
||||
|
@ -213,6 +214,7 @@ class CConfigManager {
|
|||
// keywords
|
||||
std::optional<std::string> handleRawExec(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleExecOnce(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleExecShutdown(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleMonitor(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleBind(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleUnbind(const std::string&, const std::string&);
|
||||
|
@ -289,6 +291,7 @@ class CConfigManager {
|
|||
bool firstExecDispatched = false;
|
||||
bool m_bManualCrashInitiated = false;
|
||||
std::deque<std::string> firstExecRequests;
|
||||
std::deque<std::string> finalExecRequests;
|
||||
|
||||
std::vector<std::pair<std::string, std::string>> m_vFailedPluginConfigValues; // for plugin values of unloaded plugins
|
||||
std::string m_szConfigErrors = "";
|
||||
|
|
|
@ -1781,6 +1781,11 @@ SDispatchResult CKeybindManager::renameWorkspace(std::string args) {
|
|||
}
|
||||
|
||||
SDispatchResult CKeybindManager::exitHyprland(std::string argz) {
|
||||
g_pConfigManager->dispatchExecShutdown();
|
||||
|
||||
if (g_pCompositor->m_bFinalRequests)
|
||||
return {}; // Exiting deferred until requests complete
|
||||
|
||||
g_pCompositor->stopCompositor();
|
||||
return {};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue