diff options
| author | Andrey Lihatskiy <118752495+marchcat@users.noreply.github.com> | 2026-08-13 20:18:46 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-08-13 20:18:46 +0300 |
| commit | 039c1b4b027a5f34449a934d9aea0cea8a2c7659 (patch) | |
| tree | f27a36ca21ab04d7e3ddb0c65ea39ee063252611 /indra/newview/llappviewerlinux.cpp | |
| parent | c8730531ee1a030c4e71f2b7ddb7d3394c9af7b7 (diff) | |
| parent | f376c52ee2a22b3b58263d86566394e80626fc1a (diff) | |
Merge pull request #6133 from secondlife/marchcat/lua-linux-develop
geenz/linux-to-develop to lua_editor
Diffstat (limited to 'indra/newview/llappviewerlinux.cpp')
| -rw-r--r-- | indra/newview/llappviewerlinux.cpp | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp index c924771816..2fd0eebd44 100644 --- a/indra/newview/llappviewerlinux.cpp +++ b/indra/newview/llappviewerlinux.cpp @@ -79,6 +79,10 @@ namespace void (*gOldTerminateHandler)() = NULL; } +// Initialize static members +guint32 LLAppViewerLinux::sPowerInhibitCookie = 0; +bool LLAppViewerLinux::sPowerInhibitActive = false; + void check_vm_bloat() { #if LL_LINUX @@ -276,6 +280,19 @@ void SDL_AppQuit(void *appstate, SDL_AppResult result) gViewerAppPtr = nullptr; } +LLAppViewerLinux::LLAppViewerLinux() +{ +} + +LLAppViewerLinux::~LLAppViewerLinux() +{ + // Clean up any power management inhibition on exit + if (sPowerInhibitActive) + { + uninhibitPowerManagement(); + } +} + bool LLAppViewerLinux::init() { bool success = LLAppViewer::init(); @@ -449,6 +466,178 @@ bool LLAppViewerLinux::sendURLToOtherInstance(const std::string& url) } #endif // LL_GLIB + +#if LL_GLIB + +namespace +{ + // Session-bus sleep inhibitors, tried in order; both hand back a uint cookie. + struct PowerInhibitor + { + const char* service; + const char* path; + const char* iface; + const char* uninhibit; + bool gnome_args; + }; + + const PowerInhibitor POWER_INHIBITORS[] = + { + { "org.freedesktop.PowerManagement", "/org/freedesktop/PowerManagement/Inhibit", + "org.freedesktop.PowerManagement.Inhibit", "UnInhibit", false }, + { "org.gnome.SessionManager", "/org/gnome/SessionManager", + "org.gnome.SessionManager", "Uninhibit", true } + }; + + const PowerInhibitor* sActiveInhibitor = nullptr; + + // Returns the reply, or null on failure. Takes ownership of args. + GVariant* call_power_manager(const PowerInhibitor& inhibitor, const char* method, GVariant* args, + const GVariantType* reply_type) + { + g_variant_ref_sink(args); + + GDBusConnection* bus = g_bus_get_sync(G_BUS_TYPE_SESSION, nullptr, nullptr); + if (!bus) + { + LL_WARNS("OS") << "Getting dbus failed." << LL_ENDL; + g_variant_unref(args); + return nullptr; + } + + GError* error = nullptr; + GVariant* result = g_dbus_connection_call_sync(bus, inhibitor.service, inhibitor.path, + inhibitor.iface, method, args, reply_type, + G_DBUS_CALL_FLAGS_NONE, -1, nullptr, &error); + if (!result) + { + LL_DEBUGS("OS") << inhibitor.service << "." << method << " failed: " + << (error ? error->message : "unknown error") << LL_ENDL; + } + if (error) + { + g_error_free(error); + } + + g_variant_unref(args); + g_object_unref(bus); + return result; + } +} + +#endif // LL_GLIB + +void LLAppViewerLinux::setOSHibernationMode(eHibernationMode mode) +{ + if (mode == LL_HIBERNATE_MODE_DEFAULT) + { + // Allow OS to sleep/hibernate - remove any inhibition + if (sPowerInhibitActive) + { + uninhibitPowerManagement(); + LL_INFOS("OS") << "Permitted OS hibernation/sleep" << LL_ENDL; + } + } + else if (mode == LL_HIBERNATE_MODE_PREVENT) + { + // Prevent system sleep, but allow display to turn off + // Release any existing inhibition first to allow mode switching + if (sPowerInhibitActive) + { + uninhibitPowerManagement(); + } + + if (inhibitPowerManagement(false)) + { + LL_INFOS("OS") << "Prevented OS hibernation/sleep, display sleep allowed" << LL_ENDL; + } + else + { + LL_WARNS("OS") << "Failed to prevent OS hibernation/sleep" << LL_ENDL; + } + } + else if (mode == LL_HIBERNATE_MODE_PREVENT_SCREEN) + { + // Prevent both system and display sleep + // Release any existing inhibition first to allow mode switching + if (sPowerInhibitActive) + { + uninhibitPowerManagement(); + } + + if (inhibitPowerManagement(true)) + { + LL_INFOS("OS") << "Prevented OS hibernation/sleep and display sleep" << LL_ENDL; + } + else + { + LL_WARNS("OS") << "Failed to prevent OS hibernation/sleep and display sleep" << LL_ENDL; + } + } +} + +// TODO: This is AI Generated!!!, needs review and testing. +bool LLAppViewerLinux::inhibitPowerManagement(bool inhibit_display) +{ +#if LL_GLIB + const char* reason = inhibit_display ? + "Viewer active - preventing system and display sleep" : + "Viewer active - preventing system sleep"; + + for (const PowerInhibitor& inhibitor : POWER_INHIBITORS) + { + // Inhibit(app: s, reason: s) -> u, or GNOME's Inhibit(app: s, xid: u, reason: s, flags: u) -> u + // GNOME flags: 4 = suspend, 8 = idle (display), 12 = both + GVariant* args = inhibitor.gnome_args ? + g_variant_new("(susu)", "SecondLifeViewer", (guint32)0, reason, + (guint32)(inhibit_display ? 12 : 4)) : + g_variant_new("(ss)", "Second Life Viewer", reason); + + GVariant* result = call_power_manager(inhibitor, "Inhibit", args, G_VARIANT_TYPE("(u)")); + if (!result) + { + continue; + } + + guint32 cookie = 0; + g_variant_get(result, "(u)", &cookie); + g_variant_unref(result); + + sPowerInhibitCookie = cookie; + sPowerInhibitActive = true; + sActiveInhibitor = &inhibitor; + LL_INFOS("OS") << "Successfully inhibited power management using " + << inhibitor.service << LL_ENDL; + return true; + } +#endif // LL_GLIB + + return false; +} + +void LLAppViewerLinux::uninhibitPowerManagement() +{ +#if LL_GLIB + if (sPowerInhibitActive && sActiveInhibitor) + { + GVariant* result = call_power_manager(*sActiveInhibitor, sActiveInhibitor->uninhibit, + g_variant_new("(u)", (guint32)sPowerInhibitCookie), + nullptr); + if (result) + { + g_variant_unref(result); + LL_INFOS("OS") << "Successfully uninhibited power management using " + << sActiveInhibitor->service << LL_ENDL; + } + + sActiveInhibitor = nullptr; + } +#endif // LL_GLIB + + sPowerInhibitCookie = 0; + sPowerInhibitActive = false; +} + void LLAppViewerLinux::initCrashReporting(bool reportFreeze) { } |
