diff options
| author | Berke Güzel <wenekar1@gmail.com> | 2026-10-13 17:05:59 +0300 |
|---|---|---|
| committer | Berke Güzel <wenekar1@gmail.com> | 2026-10-13 17:05:59 +0300 |
| commit | d4d13e616cb15ef22479d9cb97922af93317a01a (patch) | |
| tree | 17f812ae15c239ce7d6c2a50a292ebd91375db8e /include/yasl | |
| parent | 305a341022c8119b89b32420445bb38154073fc4 (diff) | |
Add desktop services: open URI, notify, appearance, bell, and paths
wsap_term keeps per-platform code for opening links, notifications, the
bell, high-contrast detection, the executable and bundle paths, and the
default locale. These now live behind <yasl/desktop.h>.
On Linux, src/platform/freedesktop serves both backends. Opening a URI
runs xdg-open from PATH through a double fork, so the opener gets default
signal dispositions, an empty mask, a new session, and none of the
application's descriptors. Notifications and the Settings portal use the
session bus through libdbus-1, an optional dependency behind -Ddbus.
Appearance falls back to GTK_THEME without a portal. The bell uses
xdg-system-bell on Wayland and the XKB bell on X11.
Cocoa implements the same calls with NSWorkspace, UserNotifications, the
effective appearance, NSBeep, the bundle, and CFLocale. That code is not
built or run here; it needs a macOS check.
The desktop test runs under dbus-run-session against a fake notification
server and portal, and uses a fake xdg-open to check argument passing,
signal state, and descriptor inheritance.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'include/yasl')
| -rw-r--r-- | include/yasl/desktop.h | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/include/yasl/desktop.h b/include/yasl/desktop.h new file mode 100644 index 0000000..3e72a50 --- /dev/null +++ b/include/yasl/desktop.h @@ -0,0 +1,113 @@ +/** + * @file + * Desktop services next to windowing: opening URIs, notifications, the bell, + * appearance preferences, and process paths. + * + * Display and surface functions use the display's opening thread (the main + * thread on Cocoa). Path and locale functions may be called from any thread. + * On Linux, notifications and appearance use the D-Bus session bus when YASL + * is built with libdbus-1; without it they report unsupported. + * + * Functions that fill a buffer return the full string length in bytes, + * excluding the NUL, or zero on failure. A result less than cap means out + * holds the NUL-terminated string. Otherwise out is unchanged; call again with + * a buffer of at least the result plus one. + */ +#ifndef YASL_DESKTOP_H +#define YASL_DESKTOP_H + +#include "yasl/yasl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Appearance preference flags returned by yasl_display_appearance(). */ +enum yasl_appearance : uint32_t { + YASL_APPEARANCE_DARK = 1 << 0, /**< The user prefers dark colors. */ + YASL_APPEARANCE_LIGHT = 1 << 1, /**< The user prefers light colors. */ + YASL_APPEARANCE_HIGH_CONTRAST = 1 << 2, /**< The user asks for higher contrast. */ +}; + +/** + * Open a URI with the user's default handler. + * @param d Display, or NULL. + * @param uri NUL-terminated absolute URI with a scheme, such as https: or file:. + * @return true if the request was handed to the system; false for NULL + * arguments, a missing scheme, or a failed launch. + * YASL checks only the URI syntax. The application decides which schemes and + * hosts it trusts. Success does not confirm that a handler opened the URI. + * Linux runs xdg-open from PATH in a new session, with default signal + * dispositions, an empty signal mask, stdin on /dev/null, and no descriptors + * above stderr. It forks a short-lived helper first, which raises SIGCHLD; + * YASL reaps it unless the application's reaper does. Cocoa uses NSWorkspace. + */ +YASL_API bool yasl_display_open_uri(struct yasl_display *d, const char *uri); +/** + * Show a desktop notification. + * @param d Display, or NULL. + * @param title NUL-terminated UTF-8 summary. + * @param body NUL-terminated UTF-8 body, or NULL for none. + * @return true if the request was sent; false for NULL arguments or when no + * notification service is available. + * Linux sends org.freedesktop.Notifications.Notify with the display's app_id + * as the application name and desktop-entry hint. Cocoa uses the user + * notification center, which needs an app bundle with a bundle identifier, + * and asks for permission on first use. Success does not confirm that the + * notification was shown. + */ +YASL_API bool yasl_display_notify(struct yasl_display *d, const char *title, const char *body); +/** + * Read the user's appearance preferences. + * @param d Display, or NULL. + * @return A yasl_appearance bitmask, or zero for NULL, no preference, or no + * way to read it. + * Linux reads color-scheme and contrast from the XDG Settings portal, which + * waits briefly for a reply, then falls back to the GTK_THEME variable. Cocoa + * reads the effective appearance and the increase-contrast setting. The + * result is not cached and no change notification is sent; query again when + * the window is focused. + */ +YASL_API uint32_t yasl_display_appearance(struct yasl_display *d); +/** + * Ring the system bell for a surface. + * @param s Surface, or NULL. + * @return true if the request was sent; false for NULL or when unsupported. + * The system decides whether the bell is audible, visual, or muted. Wayland + * needs the xdg-system-bell protocol; X11 uses the XKB bell for the window + * and Cocoa uses NSBeep. + */ +YASL_API bool yasl_surface_bell(struct yasl_surface *s); +/** + * Get the absolute path of the running executable, with symbolic links resolved. + * @param out Output buffer, or NULL when cap is zero. + * @param cap Size of out in bytes. + * @return Path length, or zero on failure. See the buffer rule in this file. + */ +YASL_API size_t yasl_executable_path(char *out, size_t cap); +/** + * Get the resource directory of the app bundle that contains the executable. + * @param out Output buffer, or NULL when cap is zero. + * @param cap Size of out in bytes. + * @return Path length, or zero when the executable is not in an app bundle. + * Only Cocoa has app bundles; other platforms return zero. + */ +YASL_API size_t yasl_resource_dir(char *out, size_t cap); +/** + * Get the user's preferred locale as a POSIX locale name, such as "en_US.UTF-8". + * @param out Output buffer, or NULL when cap is zero. + * @param cap Size of out in bytes. + * @return Name length, or zero on failure. + * Linux returns the first nonempty LC_ALL, LC_CTYPE, or LANG, and "C.UTF-8" + * when none is set. Cocoa builds the name from the current locale's language + * and region with a ".UTF-8" codeset, because apps started from Finder have no + * locale variables. Use the result to set LANG for child processes; YASL does + * not change the process locale. + */ +YASL_API size_t yasl_default_locale(char *out, size_t cap); + +#ifdef __cplusplus +} +#endif + +#endif /* YASL_DESKTOP_H */ |
