Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

config: add exec-shutdown for running commands on shutdown #7683

Merged
merged 2 commits into from
Sep 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading