[fix] restore Linux connections and reflect actual autostart state

This commit is contained in:
dijunkun
2026-11-09 16:18:01 +08:00
parent 4f37422317
commit d3fd9d0209
5 changed files with 49 additions and 10 deletions
@@ -618,6 +618,10 @@ bool ConfigCenter::IsSelfHosted() const { return enable_self_hosted_; }
bool ConfigCenter::IsEnableAutostart() const { bool ConfigCenter::IsEnableAutostart() const {
#ifdef _WIN32 #ifdef _WIN32
return IsServiceAutostartEnabled(); return IsServiceAutostartEnabled();
#elif defined(__linux__) && !defined(__OHOS__)
// Uninstalling or desktop startup settings can remove the registration while
// leaving config.ini intact. Report the actual entry, not the saved intent.
return IsAutostartEnabled("CrossDesk");
#else #else
return enable_autostart_; return enable_autostart_;
#endif #endif
@@ -4,9 +4,6 @@
* Copyright (c) 2026 by DI JUNKUN, All Rights Reserved. * Copyright (c) 2026 by DI JUNKUN, All Rights Reserved.
*/ */
#ifndef _PEER_TRANSPORT_H_
#define _PEER_TRANSPORT_H_
#include "runtime/peer_transport.h" #include "runtime/peer_transport.h"
#ifdef _WIN32 #ifdef _WIN32
@@ -100,5 +97,3 @@ int PeerUpdateConnectionSettings(MiniRtcPeerPtr* peer, bool hardware, bool av1,
return MiniRtcUpdateConnectionSettings(peer, hardware, av1, turn); return MiniRtcUpdateConnectionSettings(peer, hardware, av1, turn);
} }
} // namespace crossdesk } // namespace crossdesk
#endif
@@ -16,6 +16,7 @@
#include <unistd.h> #include <unistd.h>
#ifdef CROSSDESK_HAS_ATSPI #ifdef CROSSDESK_HAS_ATSPI
#include <atspi/atspi.h> #include <atspi/atspi.h>
#include <dlfcn.h>
#endif #endif
extern char** environ; extern char** environ;
@@ -102,18 +103,44 @@ struct XConnection {
} }
}; };
#ifdef CROSSDESK_HAS_ATSPI #ifdef CROSSDESK_HAS_ATSPI
template <class T> std::shared_ptr<T> Own(T* object) { return {object, [](T* value) { if (value) g_object_unref(value); }}; } // AT-SPI objects and its event loop belong to the system GLib, not MiniRTC's
// private static copy. Keep the handle for the lifetime of these objects.
struct AtspiGlib {
decltype(&g_object_unref) object_unref;
decltype(&g_free) free;
decltype(&g_main_context_pending) context_pending;
decltype(&g_main_context_iteration) context_iteration;
AtspiGlib() {
void* library = dlopen("libatspi.so.0", RTLD_NOW | RTLD_LOCAL);
if (!library) throw std::runtime_error("ACCESSIBILITY_UNAVAILABLE");
object_unref = reinterpret_cast<decltype(object_unref)>(dlsym(library, "g_object_unref"));
free = reinterpret_cast<decltype(free)>(dlsym(library, "g_free"));
context_pending = reinterpret_cast<decltype(context_pending)>(dlsym(library, "g_main_context_pending"));
context_iteration = reinterpret_cast<decltype(context_iteration)>(dlsym(library, "g_main_context_iteration"));
if (!object_unref || !free || !context_pending || !context_iteration) {
dlclose(library);
throw std::runtime_error("ACCESSIBILITY_UNAVAILABLE");
}
}
};
AtspiGlib& SystemGlib() {
static AtspiGlib api;
return api;
}
template <class T> std::shared_ptr<T> Own(T* object) { return {object, [](T* value) { if (value) SystemGlib().object_unref(value); }}; }
using Accessible = std::shared_ptr<AtspiAccessible>; using Accessible = std::shared_ptr<AtspiAccessible>;
std::string Text(char* value) { std::string Text(char* value) {
auto text = DesktopText(value ? value : ""); auto text = DesktopText(value ? value : "");
g_free(value); SystemGlib().free(value);
return text; return text;
} }
Accessible Desktop() { Accessible Desktop() {
auto& glib = SystemGlib();
static const int initialized = atspi_init(); static const int initialized = atspi_init();
if (initialized > 1) throw std::runtime_error("ACCESSIBILITY_UNAVAILABLE"); if (initialized > 1) throw std::runtime_error("ACCESSIBILITY_UNAVAILABLE");
atspi_set_timeout(120, 120); atspi_set_timeout(120, 120);
for (int count = 0; count < 32 && g_main_context_pending(nullptr); ++count) g_main_context_iteration(nullptr, false); for (int count = 0; count < 32 && glib.context_pending(nullptr); ++count) glib.context_iteration(nullptr, false);
auto desktop = Own(atspi_get_desktop(0)); auto desktop = Own(atspi_get_desktop(0));
if (!desktop) throw std::runtime_error("ACCESSIBILITY_UNAVAILABLE"); if (!desktop) throw std::runtime_error("ACCESSIBILITY_UNAVAILABLE");
return desktop; return desktop;
@@ -173,7 +200,7 @@ DesktopSnapshot Tree(Accessible root, int limit, int depth) {
const auto rect = atspi_component_get_extents(component.get(), ATSPI_COORD_TYPE_SCREEN, nullptr); const auto rect = atspi_component_get_extents(component.get(), ATSPI_COORD_TYPE_SCREEN, nullptr);
if (rect) { if (rect) {
data["bounds"] = {{"x", rect->x}, {"y", rect->y}, {"width", rect->width}, {"height", rect->height}}; data["bounds"] = {{"x", rect->x}, {"y", rect->y}, {"width", rect->width}, {"height", rect->height}};
g_free(rect); SystemGlib().free(rect);
} }
} }
if (!secure) { if (!secure) {
@@ -86,7 +86,14 @@ struct DesktopIndicatorApi {
template <typename T> template <typename T>
bool LoadDesktopIndicatorSymbol(void* library, T* function, bool LoadDesktopIndicatorSymbol(void* library, T* function,
const char* symbol_name) { const char* symbol_name) {
*function = reinterpret_cast<T>(dlsym(library, symbol_name)); // MiniRTC can export a statically linked GLib/GObject. GTK's own calls then
// bind to those process-wide symbols, while a lookup through the indicator
// handle can select the system GObject's separate type registry instead.
// Match GTK's symbol resolution so menu signals and unrefs use its registry.
*function = reinterpret_cast<T>(dlsym(RTLD_DEFAULT, symbol_name));
if (!*function) {
*function = reinterpret_cast<T>(dlsym(library, symbol_name));
}
return *function != nullptr; return *function != nullptr;
} }
+6
View File
@@ -47,6 +47,12 @@ function setup_platform_settings()
add_cxflags("/WX") add_cxflags("/WX")
set_runtimes("MT") set_runtimes("MT")
elseif is_os("linux") then elseif is_os("linux") then
-- MiniRTC carries its own static GLib/GIO. System GTK and AT-SPI must
-- keep using the system runtime, including its separate GType registry.
-- Partial ELF interposition otherwise registers GCancellable twice and
-- leaves ICE stream initialization stuck in g_once_init_enter().
add_ldflags("-Wl,--exclude-libs,libgio-2.0.a:libgobject-2.0.a:libgthread-2.0.a:libgmodule-2.0.a:libglib-2.0.a:libffi.a",
{force = true})
add_requires("pkgconfig::atspi-2", {alias = "atspi", system = true, optional = true}) add_requires("pkgconfig::atspi-2", {alias = "atspi", system = true, optional = true})
add_links("pulse-simple", "pulse") add_links("pulse-simple", "pulse")
add_requires("libyuv") add_requires("libyuv")