Skip to content

Commit

Permalink
config: add exec-shutdown for running commands on shutdown (#7683)
Browse files Browse the repository at this point in the history
* config: add exec-shutdown for running commands on shutdown

* compositor: delay stopping until after exec-shutdown
  • Loading branch information
Trimutex authored Sep 7, 2024
1 parent 5ca4823 commit 70add90
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/Compositor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
42 changes: 42 additions & 0 deletions src/config/ConfigManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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});
Expand Down Expand Up @@ -801,6 +814,7 @@ std::optional<std::string> CConfigManager::resetHLConfig() {
m_vDeclaredPlugins.clear();
m_dLayerRules.clear();
m_vFailedPluginConfigValues.clear();
finalExecRequests.clear();

// paths
configPaths.clear();
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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');

Expand Down
3 changes: 3 additions & 0 deletions src/config/ConfigManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ class CConfigManager {

// no-op when done.
void dispatchExecOnce();
void dispatchExecShutdown();

void performMonitorReload();
void appendMonitorRule(const SMonitorRule&);
Expand All @@ -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&);
Expand Down Expand Up @@ -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 = "";
Expand Down
5 changes: 5 additions & 0 deletions src/managers/KeybindManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {};
}
Expand Down

0 comments on commit 70add90

Please sign in to comment.