summaryrefslogtreecommitdiff
path: root/indra/newview/llappviewerlinux.cpp
diff options
context:
space:
mode:
authorAndrey Lihatskiy <118752495+marchcat@users.noreply.github.com>2026-08-13 20:18:46 +0300
committerGitHub <noreply@github.com>2026-08-13 20:18:46 +0300
commit039c1b4b027a5f34449a934d9aea0cea8a2c7659 (patch)
treef27a36ca21ab04d7e3ddb0c65ea39ee063252611 /indra/newview/llappviewerlinux.cpp
parentc8730531ee1a030c4e71f2b7ddb7d3394c9af7b7 (diff)
parentf376c52ee2a22b3b58263d86566394e80626fc1a (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.cpp189
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)
{
}