mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-06-13 07:03:54 +00:00
Add notification framework with test and dummy driver
This commit is contained in:
@@ -59,6 +59,8 @@ LOCAL_SRC_FILES := \
|
||||
$(wildcard $(LOCAL_PATH)/src/main/generic/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/misc/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/misc/android/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/notification/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/notification/dummy/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/power/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/power/android/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/process/*.c) \
|
||||
|
||||
@@ -268,6 +268,7 @@ define_sdl_subsystem(Power)
|
||||
define_sdl_subsystem(Sensor)
|
||||
define_sdl_subsystem(Dialog)
|
||||
define_sdl_subsystem(Tray)
|
||||
define_sdl_subsystem(Notification)
|
||||
|
||||
cmake_dependent_option(SDL_FRAMEWORK "Build SDL libraries as Apple Framework" OFF "APPLE" OFF)
|
||||
if(SDL_FRAMEWORK)
|
||||
@@ -460,6 +461,7 @@ if (NGAGE)
|
||||
set(SDL_DUMMYAUDIO OFF)
|
||||
set(SDL_DUMMYCAMERA OFF)
|
||||
set(SDL_DUMMYVIDEO OFF)
|
||||
set(SDL_NOTIFICATION OFF)
|
||||
set(SDL_OFFSCREEN OFF)
|
||||
set(SDL_RENDER_GPU OFF)
|
||||
set(SDL_TRAY OFF)
|
||||
@@ -1327,6 +1329,8 @@ sdl_glob_sources(
|
||||
"${SDL3_SOURCE_DIR}/src/main/*.h"
|
||||
"${SDL3_SOURCE_DIR}/src/misc/*.c"
|
||||
"${SDL3_SOURCE_DIR}/src/misc/*.h"
|
||||
"${SDL3_SOURCE_DIR}/src/notification/*.c"
|
||||
"${SDL3_SOURCE_DIR}/src/notification/*.h"
|
||||
"${SDL3_SOURCE_DIR}/src/power/*.c"
|
||||
"${SDL3_SOURCE_DIR}/src/power/*.h"
|
||||
"${SDL3_SOURCE_DIR}/src/render/*.c"
|
||||
@@ -2055,6 +2059,13 @@ elseif(UNIX AND NOT (APPLE OR RISCOS OR HAIKU OR CYGWIN))
|
||||
"${SDL3_SOURCE_DIR}/src/core/linux/SDL_progressbar.c"
|
||||
"${SDL3_SOURCE_DIR}/src/core/linux/SDL_progressbar.h"
|
||||
)
|
||||
|
||||
if(SDL_NOTIFICATION)
|
||||
sdl_sources(
|
||||
"${SDL3_SOURCE_DIR}/src/notification/unix/SDL_dbusnotification.c"
|
||||
)
|
||||
set(HAVE_SDL_NOTIFICATION TRUE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(SDL_USE_IME)
|
||||
@@ -2316,6 +2327,7 @@ elseif(WINDOWS OR CYGWIN)
|
||||
check_include_file(audioclient.h HAVE_AUDIOCLIENT_H)
|
||||
check_include_file(sensorsapi.h HAVE_SENSORSAPI_H)
|
||||
check_include_file(shellscalingapi.h HAVE_SHELLSCALINGAPI_H)
|
||||
check_include_file(Windows.ui.notifications.h HAVE_WINDOWS_UI_NOTIFICATIONS_H)
|
||||
check_c_source_compiles("
|
||||
#include <windows.h>
|
||||
#include <mfapi.h>
|
||||
@@ -2425,7 +2437,7 @@ elseif(WINDOWS OR CYGWIN)
|
||||
set(HAVE_SDL_STORAGE 1)
|
||||
|
||||
# Libraries for Win32 native and MinGW
|
||||
sdl_link_dependency(base LIBS kernel32 user32 gdi32 winmm imm32 ole32 oleaut32 version uuid advapi32 setupapi shell32 hid)
|
||||
sdl_link_dependency(base LIBS kernel32 user32 gdi32 winmm imm32 ole32 oleaut32 version uuid advapi32 setupapi shell32 hid mincore)
|
||||
|
||||
set(SDL_TIME_WINDOWS 1)
|
||||
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/time/windows/*.c")
|
||||
@@ -2474,6 +2486,11 @@ elseif(WINDOWS OR CYGWIN)
|
||||
set(HAVE_SDL_TRAY TRUE)
|
||||
endif()
|
||||
|
||||
if(SDL_NOTIFICATION AND HAVE_WINDOWS_UI_NOTIFICATIONS_H)
|
||||
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/notification/windows/*.c")
|
||||
set(HAVE_SDL_NOTIFICATION TRUE)
|
||||
endif()
|
||||
|
||||
if(SDL_HIDAPI)
|
||||
CheckHIDAPI()
|
||||
endif()
|
||||
@@ -2650,6 +2667,11 @@ elseif(APPLE)
|
||||
set(HAVE_SDL_HAPTIC TRUE)
|
||||
endif()
|
||||
|
||||
if(SDL_NOTIFICATION)
|
||||
set(SDL_FRAMEWORK_SECURITY 1)
|
||||
set(SDL_FRAMEWORK_USERNOTIFICATIONS 1)
|
||||
endif()
|
||||
|
||||
if(SDL_POWER)
|
||||
if (IOS OR TVOS OR VISIONOS OR WATCHOS)
|
||||
sdl_glob_sources(
|
||||
@@ -2680,6 +2702,10 @@ elseif(APPLE)
|
||||
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/filesystem/cocoa/*.m")
|
||||
set(HAVE_SDL_FILESYSTEM TRUE)
|
||||
|
||||
set(SDL_NOTIFICATION_COCOA 1)
|
||||
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/notification/cocoa/*.m")
|
||||
set(HAVE_SDL_NOTIFICATION TRUE)
|
||||
|
||||
# TODO: SDL_STORAGE_ICLOUD
|
||||
set(SDL_STORAGE_GENERIC 1)
|
||||
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/storage/generic/*.c")
|
||||
@@ -2842,12 +2868,19 @@ elseif(APPLE)
|
||||
if(SDL_FRAMEWORK_METAL)
|
||||
sdl_link_dependency(metal LIBS "$<LINK_LIBRARY:FRAMEWORK,Metal>" PKG_CONFIG_LINK_OPTIONS "-Wl,-framework,Metal")
|
||||
endif()
|
||||
if(SDL_FRAMEWORK_USERNOTIFICATIONS)
|
||||
find_library(USERNOTIFICATIONS UserNotifications)
|
||||
sdl_link_dependency(usernotifications LIBS "$<LINK_LIBRARY:FRAMEWORK,UserNotifications>" PKG_CONFIG_LINK_OPTIONS "-Wl,-framework,UserNotifications")
|
||||
endif()
|
||||
if(SDL_FRAMEWORK_OPENGLES)
|
||||
sdl_link_dependency(opengles LIBS "$<LINK_LIBRARY:FRAMEWORK,OpenGLES>" PKG_CONFIG_LINK_OPTIONS "-Wl,-framework,OpenGLES")
|
||||
endif()
|
||||
if(SDL_FRAMEWORK_QUARTZCORE)
|
||||
sdl_link_dependency(quartz_core LIBS "$<LINK_LIBRARY:FRAMEWORK,QuartzCore>" PKG_CONFIG_LINK_OPTIONS "-Wl,-framework,QuartzCore")
|
||||
endif()
|
||||
if(SDL_FRAMEWORK_SECURITY)
|
||||
sdl_link_dependency(quartz_core LIBS "$<LINK_LIBRARY:FRAMEWORK,Security>" PKG_CONFIG_LINK_OPTIONS "-Wl,-framework,Security")
|
||||
endif()
|
||||
if(SDL_FRAMEWORK_UIKIT)
|
||||
sdl_link_dependency(ui_kit LIBS "$<LINK_LIBRARY:FRAMEWORK,UIKit>" PKG_CONFIG_LINK_OPTIONS "-Wl,-framework,UIKit")
|
||||
endif()
|
||||
@@ -3754,6 +3787,12 @@ if(NOT HAVE_CAMERA)
|
||||
"${SDL3_SOURCE_DIR}/src/camera/dummy/*.h"
|
||||
)
|
||||
endif()
|
||||
if(NOT HAVE_SDL_NOTIFICATION)
|
||||
sdl_glob_sources(
|
||||
"${SDL3_SOURCE_DIR}/src/notification/dummy/*.c"
|
||||
"${SDL3_SOURCE_DIR}/src/notification/dummy/*.h"
|
||||
)
|
||||
endif()
|
||||
|
||||
# We always need to have threads and timers around
|
||||
if(NOT HAVE_SDL_THREADS)
|
||||
|
||||
@@ -452,6 +452,7 @@
|
||||
<ClInclude Include="..\..\src\events\SDL_keyboard_c.h" />
|
||||
<ClInclude Include="..\..\src\events\SDL_keymap_c.h" />
|
||||
<ClInclude Include="..\..\src\events\SDL_mouse_c.h" />
|
||||
<ClInclude Include="..\..\src\events\SDL_notificationevents_c.h" />
|
||||
<ClInclude Include="..\..\src\events\SDL_touch_c.h" />
|
||||
<ClInclude Include="..\..\src\events\SDL_windowevents_c.h" />
|
||||
<ClInclude Include="..\..\src\filesystem\SDL_sysfilesystem.h" />
|
||||
@@ -486,6 +487,7 @@
|
||||
<ClInclude Include="..\..\src\locale\SDL_syslocale.h" />
|
||||
<ClInclude Include="..\..\src\main\SDL_main_callbacks.h" />
|
||||
<ClInclude Include="..\..\src\misc\SDL_sysurl.h" />
|
||||
<ClInclude Include="..\..\src\notification\SDL_notification_c.h" />
|
||||
<ClInclude Include="..\..\src\power\SDL_syspower.h" />
|
||||
<ClInclude Include="..\..\src\render\direct3d11\SDL_shaders_d3d11.h" />
|
||||
<ClInclude Include="..\..\src\render\direct3d12\SDL_render_d3d12_xbox.h" />
|
||||
@@ -544,6 +546,7 @@
|
||||
<ClCompile Include="..\..\src\camera\SDL_camera.c" />
|
||||
<ClCompile Include="..\..\src\dialog\SDL_dialog.c" />
|
||||
<ClCompile Include="..\..\src\dialog\SDL_dialog_utils.c" />
|
||||
<ClCompile Include="..\..\src\events\SDL_notificationevents.c" />
|
||||
<ClCompile Include="..\..\src\filesystem\SDL_filesystem.c" />
|
||||
<ClCompile Include="..\..\src\filesystem\windows\SDL_sysfsops.c" />
|
||||
<ClCompile Include="..\..\src\io\generic\SDL_asyncio_generic.c" />
|
||||
@@ -553,6 +556,8 @@
|
||||
<ClCompile Include="..\..\src\main\generic\SDL_sysmain_callbacks.c" />
|
||||
<ClCompile Include="..\..\src\main\SDL_main_callbacks.c" />
|
||||
<ClCompile Include="..\..\src\main\SDL_runapp.c" />
|
||||
<ClCompile Include="..\..\src\notification\dummy\SDL_dummynotification.c" />
|
||||
<ClCompile Include="..\..\src\notification\SDL_notification.c" />
|
||||
<ClCompile Include="..\..\src\SDL_guid.c" />
|
||||
<ClInclude Include="..\..\src\SDL_hashtable.h" />
|
||||
<ClInclude Include="..\..\src\SDL_hints_c.h" />
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
#include <SDL3/SDL_misc.h>
|
||||
#include <SDL3/SDL_mouse.h>
|
||||
#include <SDL3/SDL_mutex.h>
|
||||
#include <SDL3/SDL_notification.h>
|
||||
#include <SDL3/SDL_pen.h>
|
||||
#include <SDL3/SDL_pixels.h>
|
||||
#include <SDL3/SDL_platform.h>
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
#include <SDL3/SDL_keyboard.h>
|
||||
#include <SDL3/SDL_keycode.h>
|
||||
#include <SDL3/SDL_mouse.h>
|
||||
#include <SDL3/SDL_notification.h>
|
||||
#include <SDL3/SDL_pen.h>
|
||||
#include <SDL3/SDL_power.h>
|
||||
#include <SDL3/SDL_sensor.h>
|
||||
@@ -262,6 +263,9 @@ typedef enum SDL_EventType
|
||||
SDL_EVENT_CAMERA_DEVICE_APPROVED, /**< A camera device has been approved for use by the user. */
|
||||
SDL_EVENT_CAMERA_DEVICE_DENIED, /**< A camera device has been denied for use by the user. */
|
||||
|
||||
/* Notification events */
|
||||
SDL_EVENT_NOTIFICATION_ACTION_INVOKED = 0x1500, /**< A user response to a system notification was received. */
|
||||
|
||||
/* Render events */
|
||||
SDL_EVENT_RENDER_TARGETS_RESET = 0x2000, /**< The render targets have been reset and their contents need to be updated */
|
||||
SDL_EVENT_RENDER_DEVICE_RESET, /**< The device has been reset and all textures need to be recreated */
|
||||
@@ -764,6 +768,23 @@ typedef struct SDL_CameraDeviceEvent
|
||||
SDL_CameraID which; /**< SDL_CameraID for the device being added or removed or changing */
|
||||
} SDL_CameraDeviceEvent;
|
||||
|
||||
/**
|
||||
* Notification dialog event structure (event.notification.*)
|
||||
*
|
||||
* An `action_id` value of 'default' for an SDL_EVENT_NOTIFICATION_ACTION_INVOKED
|
||||
* event indicates that the notification was interacted with without selecting a
|
||||
* specific action (e.g. the body of the notification was clicked on).
|
||||
*
|
||||
* \since This struct is available since SDL 3.6.0.
|
||||
*/
|
||||
typedef struct SDL_NotificationEvent
|
||||
{
|
||||
SDL_EventType type; /**< SDL_EVENT_NOTIFICATION_ACTION_INVOKED */
|
||||
Uint32 reserved;
|
||||
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
|
||||
SDL_NotificationID which; /**< The ID of the notification that generated this event. */
|
||||
const char *action_id; /**< The identifier string of the action invoked in the notification dialog. */
|
||||
} SDL_NotificationEvent;
|
||||
|
||||
/**
|
||||
* Renderer event structure (event.render.*)
|
||||
@@ -1075,6 +1096,7 @@ typedef union SDL_Event
|
||||
SDL_RenderEvent render; /**< Render event data */
|
||||
SDL_DropEvent drop; /**< Drag and drop event data */
|
||||
SDL_ClipboardEvent clipboard; /**< Clipboard event data */
|
||||
SDL_NotificationEvent notification; /**< Notification event data */
|
||||
|
||||
/* This is necessary for ABI compatibility between Visual C++ and GCC.
|
||||
Visual C++ will respect the push pack pragma and use 52 bytes (size of
|
||||
|
||||
254
include/SDL3/SDL_notification.h
Normal file
254
include/SDL3/SDL_notification.h
Normal file
@@ -0,0 +1,254 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
/**
|
||||
* # CategoryNotifications
|
||||
*
|
||||
* Notifications are temporary popup dialogs that passively present
|
||||
* information to the user, or prompt user action. They are managed
|
||||
* and presented by the system, and can present simple options for
|
||||
* user feedback, usually in the form of buttons.
|
||||
*
|
||||
* The capabilities of notifications, and how they are displayed,
|
||||
* vary between systems, but they generally allow for a title,
|
||||
* message body, an associated image, and buttons to allow the user
|
||||
* to provide feedback.
|
||||
*
|
||||
* How notifications are presented and handled are subject to system
|
||||
* policy, and it should not be assumed that showing a notification
|
||||
* means that the user will see it immediately, if at all. The
|
||||
* user may disable notifications for certain applications, they may
|
||||
* be suppressed based on the current activity, and most systems
|
||||
* provide a "do not disturb" mode that universally silences
|
||||
* notifications when activated.
|
||||
*
|
||||
* There is both a customizable function `SDL_ShowNotificationWithProperties()`
|
||||
* that offers many options for what is displayed, and also a much-simplified
|
||||
* version `SDL_ShowSimpleNotification()`, which simply takes a header (required),
|
||||
* body (optional), and image (optional).
|
||||
*/
|
||||
|
||||
#ifndef SDL_notification_h_
|
||||
#define SDL_notification_h_
|
||||
|
||||
#include <SDL3/SDL_properties.h>
|
||||
#include <SDL3/SDL_stdinc.h>
|
||||
#include <SDL3/SDL_surface.h>
|
||||
|
||||
#include <SDL3/SDL_begin_code.h>
|
||||
/* Set up for C function definitions, even when using C++ */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The path to an image to be used as the header icon for system notifications on
|
||||
* some platforms. This is required on:
|
||||
* - Windows
|
||||
* - *nix when not running in a container, and no .desktop entry is available
|
||||
*
|
||||
* Image types supported depend on the platform, but .png generally offers the best
|
||||
* compatability.
|
||||
*
|
||||
* On *nix platforms, this can also be the name of a system icon, as specified by
|
||||
* the Icon Naming Specification.
|
||||
*
|
||||
* Can be set before calling SDL_ShowNotification() or SDL_ShowSimpleNotification()
|
||||
* for the first time.
|
||||
*
|
||||
* \since This macro is available since SDL 3.6.0.
|
||||
*/
|
||||
#define SDL_PROP_GLOBAL_NOTIFICATION_HEADER_ICON_STRING "SDL.notification.header_icon"
|
||||
|
||||
typedef Uint32 SDL_NotificationID; /**< The identifier for a system notification. */
|
||||
|
||||
typedef enum SDL_NotificationPriority
|
||||
{
|
||||
SDL_NOTIFICATION_PRIORITY_LOW = -1, /**< Lowest priority. */
|
||||
SDL_NOTIFICATION_PRIORITY_NORMAL = 0, /**< Normal/medium priority. */
|
||||
SDL_NOTIFICATION_PRIORITY_HIGH = 1, /**< High/important priority. */
|
||||
SDL_NOTIFICATION_PRIORITY_CRITICAL = 2 /**< Highest/critical priority. Note that this may override any "Do Not Disturb" settings and wake the screen. */
|
||||
} SDL_NotificationPriority;
|
||||
|
||||
typedef enum SDL_NotificationActionType
|
||||
{
|
||||
SDL_NOTIFICATION_ACTION_TYPE_BUTTON = 1 /**< Adds a button to the notification that generates feedback when activated. */
|
||||
} SDL_NotificationActionType;
|
||||
|
||||
/**
|
||||
* Notification structure describing actions that can be used to allow users
|
||||
* to interact with notification dialogs. Exactly How they are presented depends
|
||||
* on the platform and implementation.
|
||||
*
|
||||
* User interactions with a notification are reported via events with the type
|
||||
* SDL_EVENT_NOTIFICATION_ACTION_INVOKED.
|
||||
*
|
||||
* Action types:
|
||||
* - button: A button with a localized text label, which generates feedback when activated.
|
||||
*
|
||||
* \sa SDL_NotificationEvent
|
||||
* \sa SDL_NotificationActionType
|
||||
*/
|
||||
typedef union SDL_NotificationAction
|
||||
{
|
||||
SDL_NotificationActionType type;
|
||||
|
||||
struct
|
||||
{
|
||||
SDL_NotificationActionType type; /**< SDL_NOTIFICATION_ACTION_TYPE_BUTTON */
|
||||
const char *action_id; /**< The identifier string for the button. 'default' is a reserved identifier and must not be used. */
|
||||
const char *action_label; /**< The localized label for the button associated with the action, in UTF-8 encoding. */
|
||||
} button;
|
||||
|
||||
Uint8 padding[128];
|
||||
} SDL_NotificationAction;
|
||||
|
||||
#define SDL_PROP_NOTIFICATION_ACTIONS_POINTER "SDL.notification.actions"
|
||||
#define SDL_PROP_NOTIFICATION_ACTION_COUNT_NUMBER "SDL.notification.action_count"
|
||||
#define SDL_PROP_NOTIFICATION_IMAGE_POINTER "SDL.notification.image"
|
||||
#define SDL_PROP_NOTIFICATION_MESSAGE_STRING "SDL.notification.message"
|
||||
#define SDL_PROP_NOTIFICATION_PRIORITY_NUMBER "SDL.notification.priority"
|
||||
#define SDL_PROP_NOTIFICATION_REPLACES_NUMBER "SDL.notification.replaces"
|
||||
#define SDL_PROP_NOTIFICATION_SOUND_STRING "SDL.notification.sound"
|
||||
#define SDL_PROP_NOTIFICATION_TRANSIENT_BOOLEAN "SDL.notification.transient"
|
||||
#define SDL_PROP_NOTIFICATION_TITLE_STRING "SDL.notification.title"
|
||||
|
||||
/**
|
||||
* Requests permission from the system to display notifications. A return value of `true`
|
||||
* only means that the system supports notifications, and that the request for permission
|
||||
* was successfully issued. It does not reflect any user settings to allow or deny
|
||||
* notifications.
|
||||
*
|
||||
* \returns True on success or false on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 3.6.0
|
||||
*
|
||||
* \sa SDL_ShowNotification
|
||||
* \sa SDL_ShowNotificationWithProperties
|
||||
* \sa SDL_NotificationAction
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_RequestNotificationPermission(void);
|
||||
|
||||
/**
|
||||
* Show a system notification.
|
||||
*
|
||||
* System notifications are small, asynchronous popup windows that notify the user
|
||||
* of some information. How they are displayed is system dependent.
|
||||
*
|
||||
* These are the supported properties:
|
||||
*
|
||||
* - `SDL_PROP_NOTIFICATION_TITLE_STRING`: the title of the notification, in
|
||||
* UTF-8 encoding. This property is required.
|
||||
* - `SDL_PROP_NOTIFICATION_ACTIONS_POINTER`: An array of pointers to `SDL_NotificationAction`
|
||||
* structs that will add actions to the notification, usually in the form of buttons or menu
|
||||
* items. Note that systems may have a limit on the maximum number of actions that a
|
||||
* notification can have.
|
||||
* - `SDL_PROP_NOTIFICATIONS_ACTION_COUNT_NUMBER`: the number of actions in the array of actions,
|
||||
* if it exists.
|
||||
* - `SDL_PROP_NOTIFICATION_IMAGE_POINTER`: a pointer to an `SDL_Surface` containing
|
||||
* an image that will be attached to the notification. In most cases, the image is displayed
|
||||
* in the form of a large icon or thumbnail alongside the message body. Notifications on Apple
|
||||
* platforms can be expanded to show a larger format image.
|
||||
* - `SDL_PROP_NOTIFICATION_MESSAGE_STRING`: the message body of the notification,
|
||||
* in UTF-8 encoding.
|
||||
* - `SDL_PROP_NOTIFICATION_PRIORITY_NUMBER`: an `SDL_NotificationPriority` value representing
|
||||
* the notification priority.
|
||||
* - `SDL_PROP_NOTIFICATION_REPLACES_NUMBER`: the `SDL_NotificationID` of a previously
|
||||
* shown notification that this notification should replace.
|
||||
* - `SDL_PROP_NOTIFICATION_SOUND_STRING`: sets a sound to play when the notification is shown.
|
||||
* This can have the value "default", to play the system default notification sound, "silent",
|
||||
* to play no sound, or contain the path to a file with a custom sound. The paths and formats
|
||||
* that can be used for custom sounds are system-specific, and can have some restrictions,
|
||||
* depending on the platform:
|
||||
* - Apple platforms require that the sound file is contained within the app bundle. Supported
|
||||
* formats are: Linear PCM, MA4 (IMA/ADPCM), uLaw, or aLaw, in an .aiff, .wav, or .caf file.
|
||||
* - Windows can only play custom notification sounds when the app is packaged inside an MSIX
|
||||
* installer. Playback from arbitrary file paths is not supported. Supported formats are:
|
||||
* .aac, .flac, .m4a, .mp3, .wav, and .wma.
|
||||
* - Unix platforms can generally load sounds from any arbitrary path, as long as the read
|
||||
* permissions are correct. Supported formats are: ogg/opus, ogg/vorbis, and wav/pcm.
|
||||
* If this property is not set, the system default sound will be used.
|
||||
* - `SDL_PROP_NOTIFICATION_TRANSIENT_BOOLEAN`: true if the notification should not persist
|
||||
* in the system notification center after initially being shown.
|
||||
*
|
||||
* Not all properties are supported by all platforms.
|
||||
*
|
||||
* Notifications are available on:
|
||||
* - Windows 10 or higher
|
||||
* - macOS 10.14 or higher
|
||||
* - iOS 11 or higher
|
||||
* - *nix platforms that support the org.freedesktop.Notifications, or
|
||||
* org.freedesktop.portal.Notification interfaces
|
||||
*
|
||||
* \param props the properties to be used when creating this notification.
|
||||
* \returns A non-zero SDL_NotificationID on success or 0 on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 3.6.0
|
||||
*
|
||||
* \sa SDL_ShowNotification
|
||||
* \sa SDL_NotificationAction
|
||||
* \sa SDL_NotificationPriority
|
||||
* \sa SDL_NotificationEvent
|
||||
*/
|
||||
extern SDL_DECLSPEC SDL_NotificationID SDLCALL SDL_ShowNotificationWithProperties(SDL_PropertiesID props);
|
||||
|
||||
/**
|
||||
* Show a system notification with normal priority.
|
||||
*
|
||||
* \param title UTF-8 title text, required.
|
||||
* \param message UTF-8 message text, may be NULL.
|
||||
* \param image The image associated with this notification, may be NULL.
|
||||
* \param actions An array of actions to attach to the notification, may be NULL.
|
||||
* \param num_actions The number of actions in the actions array.
|
||||
* \returns A non-zero SDL_NotificationID on success or 0 on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 3.6.0
|
||||
*
|
||||
* \sa SDL_ShowNotificationWithProperties
|
||||
* \sa SDL_NotificationAction
|
||||
* \sa SDL_NotificationEvent
|
||||
*/
|
||||
extern SDL_DECLSPEC SDL_NotificationID SDLCALL SDL_ShowNotification(const char *title, const char *message, SDL_Surface *image, SDL_NotificationAction *actions, int num_actions);
|
||||
|
||||
/**
|
||||
* Remove a notification.
|
||||
*
|
||||
* \param notification the ID of the notification to remove.
|
||||
* \returns True on success or false on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 3.6.0
|
||||
*
|
||||
* \sa SDL_ShowNotificationWithProperties
|
||||
* \sa SDL_ShowNotification
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_RemoveNotification(SDL_NotificationID notification);
|
||||
|
||||
// Ends C function definitions when using C++
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#include <SDL3/SDL_close_code.h>
|
||||
|
||||
#endif // SDL_notification_h_
|
||||
@@ -44,9 +44,12 @@
|
||||
#include "camera/SDL_camera_c.h"
|
||||
#include "cpuinfo/SDL_cpuinfo_c.h"
|
||||
#include "events/SDL_events_c.h"
|
||||
#include "filesystem/SDL_filesystem_c.h"
|
||||
#include "haptic/SDL_haptic_c.h"
|
||||
#include "io/SDL_asyncio_c.h"
|
||||
#include "joystick/SDL_gamepad_c.h"
|
||||
#include "joystick/SDL_joystick_c.h"
|
||||
#include "notification/SDL_notification_c.h"
|
||||
#include "render/SDL_sysrender.h"
|
||||
#include "sensor/SDL_sensor_c.h"
|
||||
#include "stdlib/SDL_getenv_c.h"
|
||||
@@ -55,8 +58,6 @@
|
||||
#include "video/SDL_pixels_c.h"
|
||||
#include "video/SDL_surface_c.h"
|
||||
#include "video/SDL_video_c.h"
|
||||
#include "filesystem/SDL_filesystem_c.h"
|
||||
#include "io/SDL_asyncio_c.h"
|
||||
#ifdef SDL_PLATFORM_ANDROID
|
||||
#include "core/android/SDL_android.h"
|
||||
#endif
|
||||
@@ -710,6 +711,7 @@ void SDL_Quit(void)
|
||||
#endif
|
||||
SDL_QuitSubSystem(SDL_ALL_SUBSYSTEM_FLAGS);
|
||||
SDL_CleanupTrays();
|
||||
SDL_CleanupNotifications();
|
||||
|
||||
#ifdef SDL_USE_LIBDBUS
|
||||
SDL_DBus_Quit();
|
||||
|
||||
@@ -1294,3 +1294,7 @@ _SDL_aligned_alloc_zero
|
||||
_SDL_wcstoul
|
||||
_SDL_wcstoll
|
||||
_SDL_wcstoull
|
||||
_SDL_RequestNotificationPermission
|
||||
_SDL_ShowNotificationWithProperties
|
||||
_SDL_ShowNotification
|
||||
_SDL_RemoveNotification
|
||||
|
||||
@@ -1295,6 +1295,10 @@ SDL3_0.0.0 {
|
||||
SDL_wcstoul;
|
||||
SDL_wcstoll;
|
||||
SDL_wcstoull;
|
||||
SDL_RequestNotificationPermission;
|
||||
SDL_ShowNotificationWithProperties;
|
||||
SDL_ShowNotification;
|
||||
SDL_RemoveNotification;
|
||||
# extra symbols go here (don't modify this line)
|
||||
local: *;
|
||||
};
|
||||
|
||||
@@ -1321,3 +1321,7 @@
|
||||
#define SDL_wcstoul SDL_wcstoul_REAL
|
||||
#define SDL_wcstoll SDL_wcstoll_REAL
|
||||
#define SDL_wcstoull SDL_wcstoull_REAL
|
||||
#define SDL_RequestNotificationPermission SDL_RequestNotificationPermission_REAL
|
||||
#define SDL_ShowNotificationWithProperties SDL_ShowNotificationWithProperties_REAL
|
||||
#define SDL_ShowNotification SDL_ShowNotification_REAL
|
||||
#define SDL_RemoveNotification SDL_RemoveNotification_REAL
|
||||
|
||||
@@ -1329,3 +1329,7 @@ SDL_DYNAPI_PROC(void*,SDL_aligned_alloc_zero,(size_t a,size_t b),(a,b),return)
|
||||
SDL_DYNAPI_PROC(unsigned long,SDL_wcstoul,(const wchar_t *a,wchar_t **b,int c),(a,b,c),return)
|
||||
SDL_DYNAPI_PROC(long long,SDL_wcstoll,(const wchar_t *a,wchar_t **b,int c),(a,b,c),return)
|
||||
SDL_DYNAPI_PROC(unsigned long long,SDL_wcstoull,(const wchar_t *a,wchar_t **b,int c),(a,b,c),return)
|
||||
SDL_DYNAPI_PROC(bool,SDL_RequestNotificationPermission,(void),(),return)
|
||||
SDL_DYNAPI_PROC(SDL_NotificationID,SDL_ShowNotificationWithProperties,(SDL_PropertiesID a),(a),return)
|
||||
SDL_DYNAPI_PROC(SDL_NotificationID,SDL_ShowNotification,(const char *a,const char *b,SDL_Surface *c,SDL_NotificationAction *d,int e),(a,b,c,d,e),return)
|
||||
SDL_DYNAPI_PROC(bool,SDL_RemoveNotification,(SDL_NotificationID a),(a),return)
|
||||
|
||||
@@ -185,6 +185,9 @@ SDL_EventCategory SDL_GetEventCategory(Uint32 type)
|
||||
case SDL_EVENT_CAMERA_DEVICE_APPROVED:
|
||||
case SDL_EVENT_CAMERA_DEVICE_DENIED:
|
||||
return SDL_EVENTCATEGORY_CDEVICE;
|
||||
|
||||
case SDL_EVENT_NOTIFICATION_ACTION_INVOKED:
|
||||
return SDL_EVENTCATEGORY_NOTIFICATION;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@ typedef enum SDL_EventCategory
|
||||
SDL_EVENTCATEGORY_DROP,
|
||||
SDL_EVENTCATEGORY_CLIPBOARD,
|
||||
SDL_EVENTCATEGORY_RENDER,
|
||||
SDL_EVENTCATEGORY_NOTIFICATION,
|
||||
} SDL_EventCategory;
|
||||
|
||||
extern SDL_EventCategory SDL_GetEventCategory(Uint32 type);
|
||||
|
||||
@@ -911,6 +911,11 @@ int SDL_GetEventDescription(const SDL_Event *event, char *buf, int buflen)
|
||||
break;
|
||||
#undef PRINT_CAMERADEV_EVENT
|
||||
|
||||
SDL_EVENT_CASE(SDL_EVENT_NOTIFICATION_ACTION_INVOKED)
|
||||
(void)SDL_snprintf(details, sizeof(details), " (timestamp=%" SDL_PRIu64 " which=%d button_id='%s')",
|
||||
event->notification.timestamp, (uint)event->notification.which, event->notification.action_id);
|
||||
break;
|
||||
|
||||
SDL_EVENT_CASE(SDL_EVENT_SENSOR_UPDATE)
|
||||
(void)SDL_snprintf(details, sizeof(details), " (timestamp=%" SDL_PRIu64 " which=%d data[0]=%f data[1]=%f data[2]=%f data[3]=%f data[4]=%f data[5]=%f)",
|
||||
event->sensor.timestamp, (int)event->sensor.which,
|
||||
|
||||
41
src/events/SDL_notificationevents.c
Normal file
41
src/events/SDL_notificationevents.c
Normal file
@@ -0,0 +1,41 @@
|
||||
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#include "SDL_events_c.h"
|
||||
#include "SDL_notificationevents_c.h"
|
||||
|
||||
bool SDL_SendNotificationAction(SDL_NotificationID notification_id, const char *action_id)
|
||||
{
|
||||
if (SDL_EventEnabled(SDL_EVENT_NOTIFICATION_ACTION_INVOKED)) {
|
||||
SDL_Event event;
|
||||
event.type = SDL_EVENT_NOTIFICATION_ACTION_INVOKED;
|
||||
|
||||
SDL_NotificationEvent *nevent = &event.notification;
|
||||
nevent->timestamp = 0;
|
||||
nevent->which = notification_id;
|
||||
nevent->action_id = SDL_CreateTemporaryString(action_id);
|
||||
return SDL_PushEvent(&event);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
30
src/events/SDL_notificationevents_c.h
Normal file
30
src/events/SDL_notificationevents_c.h
Normal file
@@ -0,0 +1,30 @@
|
||||
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifndef SDL_notificationevents_c_h_
|
||||
#define SDL_notificationevents_c_h_
|
||||
|
||||
extern bool SDL_SendNotificationAction(SDL_NotificationID notification_id, const char *action_id);
|
||||
|
||||
#endif // SDL_notificationevents_c_h_
|
||||
|
||||
85
src/notification/SDL_notification.c
Normal file
85
src/notification/SDL_notification.c
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#include "SDL_notification_c.h"
|
||||
#include <SDL3/SDL_properties.h>
|
||||
|
||||
SDL_NotificationID SDL_ShowNotificationWithProperties(SDL_PropertiesID props)
|
||||
{
|
||||
if (!props) {
|
||||
SDL_InvalidParamError("props");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// The title property is required.
|
||||
CHECK_PARAM (true) {
|
||||
const char *title = SDL_GetStringProperty(props, SDL_PROP_NOTIFICATION_TITLE_STRING, NULL);
|
||||
if (!title) {
|
||||
SDL_SetError("Notifications must have a title");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return SDL_SYS_ShowNotification(props);
|
||||
}
|
||||
|
||||
SDL_NotificationID SDL_ShowNotification(const char *title, const char *message, SDL_Surface *image, SDL_NotificationAction *actions, int num_actions)
|
||||
{
|
||||
SDL_NotificationID id = 0;
|
||||
SDL_PropertiesID props = SDL_CreateProperties();
|
||||
if (!props) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (title) {
|
||||
if (!SDL_SetStringProperty(props, SDL_PROP_NOTIFICATION_TITLE_STRING, title)) {
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
SDL_SetError("Notifications must have a title");
|
||||
goto cleanup;
|
||||
}
|
||||
if (message) {
|
||||
if (!SDL_SetStringProperty(props, SDL_PROP_NOTIFICATION_MESSAGE_STRING, message)) {
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
if (image) {
|
||||
if (!SDL_SetPointerProperty(props, SDL_PROP_NOTIFICATION_IMAGE_POINTER, image)) {
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
if (actions && num_actions) {
|
||||
if (!SDL_SetPointerProperty(props, SDL_PROP_NOTIFICATION_ACTIONS_POINTER, actions)) {
|
||||
goto cleanup;
|
||||
}
|
||||
if (!SDL_SetNumberProperty(props, SDL_PROP_NOTIFICATION_ACTION_COUNT_NUMBER, num_actions)) {
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
id = SDL_ShowNotificationWithProperties(props);
|
||||
|
||||
cleanup:
|
||||
SDL_DestroyProperties(props);
|
||||
return id;
|
||||
}
|
||||
34
src/notification/SDL_notification_c.h
Normal file
34
src/notification/SDL_notification_c.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_NOTIFICATION_C_H
|
||||
#define SDL_NOTIFICATION_C_H
|
||||
|
||||
#include <SDL3/SDL_notification.h>
|
||||
|
||||
extern SDL_NotificationID SDL_SYS_ShowNotification(SDL_PropertiesID props);
|
||||
extern void SDL_CleanupNotifications();
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_WAYLAND
|
||||
extern const char *SDL_GetNotificationActivationToken();
|
||||
#endif
|
||||
|
||||
#endif // SDL_NOTIFICATION_C_H
|
||||
51
src/notification/dummy/SDL_dummynotification.c
Normal file
51
src/notification/dummy/SDL_dummynotification.c
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "SDL_internal.h"
|
||||
#include "../SDL_notification_c.h"
|
||||
|
||||
bool SDL_RequestNotificationPermission(void)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
SDL_NotificationID SDL_SYS_ShowNotification(SDL_PropertiesID props)
|
||||
{
|
||||
SDL_Unsupported();
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool SDL_RemoveNotification(SDL_NotificationID notification)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
void SDL_CleanupNotifications()
|
||||
{
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_WAYLAND
|
||||
const char *SDL_GetNotificationActivationToken()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
@@ -2012,6 +2012,10 @@ void SDLTest_PrintEvent(const SDL_Event *event)
|
||||
SDL_Log("SDL EVENT: Camera device %" SDL_PRIu32 " permission denied",
|
||||
event->cdevice.which);
|
||||
break;
|
||||
case SDL_EVENT_NOTIFICATION_ACTION_INVOKED:
|
||||
SDL_Log("SDL EVENT: Notification action for %" SDL_PRIu32 " button_id=%s",
|
||||
event->notification.which, event->notification.action_id);
|
||||
break;
|
||||
case SDL_EVENT_SENSOR_UPDATE:
|
||||
SDL_Log("SDL EVENT: Sensor update for %" SDL_PRIu32,
|
||||
event->sensor.which);
|
||||
|
||||
@@ -441,6 +441,7 @@ add_sdl_test_executable(testlocale NONINTERACTIVE SOURCES testlocale.c NAME83 lo
|
||||
add_sdl_test_executable(testlock SOURCES testlock.c NAME83 lock)
|
||||
add_sdl_test_executable(testrwlock SOURCES testrwlock.c NONINTERACTIVE NONINTERACTIVE_TIMEOUT 20 NAME83 rwlock)
|
||||
add_sdl_test_executable(testmouse SOURCES testmouse.c NAME83 mouse)
|
||||
add_sdl_test_executable(testnotification NEEDS_RESOURCES SOURCES testnotification.c NAME83 notify)
|
||||
|
||||
add_sdl_test_executable(testoverlay NEEDS_RESOURCES TESTUTILS SOURCES testoverlay.c NAME83 overlay)
|
||||
add_sdl_test_executable(testplatform NONINTERACTIVE SOURCES testplatform.c NAME83 platform)
|
||||
|
||||
160
test/testnotification.c
Normal file
160
test/testnotification.c
Normal file
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely.
|
||||
*/
|
||||
|
||||
/* Simple test of the SDL Notification API */
|
||||
#define SDL_MAIN_USE_CALLBACKS 1
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_main.h>
|
||||
#include <SDL3/SDL_test.h>
|
||||
|
||||
/* This enables themed Windows dialogs when building with Visual Studio */
|
||||
#if defined(SDL_PLATFORM_WINDOWS) && defined(_MSC_VER)
|
||||
#pragma comment(linker, "\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
|
||||
#endif
|
||||
|
||||
static SDLTest_CommonState *state;
|
||||
static SDL_Surface *icon;
|
||||
static SDL_NotificationID last_id;
|
||||
static SDL_PropertiesID props;
|
||||
static SDL_NotificationAction actions[] = {
|
||||
{ .button = { SDL_NOTIFICATION_ACTION_TYPE_BUTTON, "action_1", "OK" } },
|
||||
{ .button = { SDL_NOTIFICATION_ACTION_TYPE_BUTTON, "action_2", "Cancel" } }
|
||||
};
|
||||
static SDL_NotificationAction *action_array[SDL_arraysize(actions) + 1];
|
||||
|
||||
static bool transient;
|
||||
static int sound;
|
||||
|
||||
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
|
||||
{
|
||||
SDL_SetAppMetadata("SDL Notification Test", "0.0.1", "org.libsdl.testnotification");
|
||||
|
||||
/* Initialize test framework */
|
||||
state = SDLTest_CommonCreateState(argv, 0);
|
||||
if (!state) {
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
/* Parse commandline */
|
||||
if (!SDLTest_CommonDefaultArgs(state, argc, argv)) {
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
state->flags |= SDL_INIT_VIDEO;
|
||||
if (!SDLTest_CommonInit(state)) {
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
SDL_SetStringProperty(SDL_GetGlobalProperties(), SDL_PROP_GLOBAL_NOTIFICATION_HEADER_ICON_STRING, "sdl-test_round.png");
|
||||
|
||||
props = SDL_CreateProperties();
|
||||
SDL_SetStringProperty(props, SDL_PROP_NOTIFICATION_TITLE_STRING, "Test Notification");
|
||||
SDL_SetStringProperty(props, SDL_PROP_NOTIFICATION_MESSAGE_STRING, "Hey, pay attention to me!");
|
||||
|
||||
icon = SDL_LoadPNG("sdl-test_round.png");
|
||||
SDL_SetPointerProperty(props, SDL_PROP_NOTIFICATION_IMAGE_POINTER, icon);
|
||||
|
||||
SDL_SetPointerProperty(props, SDL_PROP_NOTIFICATION_ACTIONS_POINTER, actions);
|
||||
SDL_SetNumberProperty(props, SDL_PROP_NOTIFICATION_ACTION_COUNT_NUMBER, SDL_arraysize(actions));
|
||||
|
||||
SDL_RequestNotificationPermission();
|
||||
|
||||
return SDL_APP_CONTINUE;
|
||||
}
|
||||
|
||||
static void ShowNotification(bool replace)
|
||||
{
|
||||
if (replace) {
|
||||
SDL_SetNumberProperty(props, SDL_PROP_NOTIFICATION_REPLACES_NUMBER, last_id);
|
||||
} else {
|
||||
SDL_SetNumberProperty(props, SDL_PROP_NOTIFICATION_REPLACES_NUMBER, 0);
|
||||
}
|
||||
SDL_SetBooleanProperty(props, SDL_PROP_NOTIFICATION_TRANSIENT_BOOLEAN, transient);
|
||||
|
||||
// Test showing a system notification message.
|
||||
const SDL_NotificationID new_id = SDL_ShowNotificationWithProperties(props);
|
||||
if (new_id) {
|
||||
SDL_Log("Notification successfully dispatched. ID: %" SDL_PRIu32, new_id);
|
||||
last_id = new_id;
|
||||
} else {
|
||||
SDL_Log("Notification dispatch failed: %s", SDL_GetError());
|
||||
}
|
||||
}
|
||||
|
||||
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
|
||||
{
|
||||
if (event->type == SDL_EVENT_KEY_DOWN) {
|
||||
if (event->key.key == SDLK_SPACE) {
|
||||
ShowNotification((event->key.mod & SDL_KMOD_CTRL) != 0);
|
||||
} else if (event->key.key == SDLK_H) {
|
||||
if (last_id) {
|
||||
SDL_RemoveNotification(last_id);
|
||||
}
|
||||
} else if (event->key.key == SDLK_T) {
|
||||
transient ^= true;
|
||||
} else if (event->key.key == SDLK_S) {
|
||||
sound = (sound + 1) % 3;
|
||||
switch (sound) {
|
||||
default:
|
||||
SDL_SetStringProperty(props, SDL_PROP_NOTIFICATION_SOUND_STRING, "default");
|
||||
break;
|
||||
case 1:
|
||||
SDL_SetStringProperty(props, SDL_PROP_NOTIFICATION_SOUND_STRING, "sword.wav");
|
||||
break;
|
||||
case 2:
|
||||
SDL_SetStringProperty(props, SDL_PROP_NOTIFICATION_SOUND_STRING, "silent");
|
||||
}
|
||||
}
|
||||
} else if (event->type == SDL_EVENT_MOUSE_BUTTON_DOWN) {
|
||||
ShowNotification(false);
|
||||
} else if (event->type == SDL_EVENT_NOTIFICATION_ACTION_INVOKED) {
|
||||
SDL_Log("User responded to notification %" SDL_PRIu32 " with action \"%s\"", event->notification.which, event->notification.action_id);
|
||||
|
||||
// Raise the window of the user clicked "OK".
|
||||
if (SDL_strcmp(event->notification.action_id, "action_1") == 0) {
|
||||
SDL_RaiseWindow(state->windows[0]);
|
||||
} else if (SDL_strcmp(event->notification.action_id, "action_url") == 0) {
|
||||
SDL_OpenURL("https://www.libsdl.org");
|
||||
}
|
||||
}
|
||||
|
||||
return SDLTest_CommonEventMainCallbacks(state, event);
|
||||
}
|
||||
|
||||
SDL_AppResult SDL_AppIterate(void *appstate)
|
||||
{
|
||||
for (int i = 0; i < state->num_windows; ++i) {
|
||||
SDL_Renderer *renderer = state->renderers[i];
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
||||
SDL_RenderClear(renderer);
|
||||
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
|
||||
|
||||
float y = 16.0f;
|
||||
SDL_RenderDebugText(renderer, 8.f, y, "Click or press space to show a notification");
|
||||
y += SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE + 2;
|
||||
SDL_RenderDebugText(renderer, 8.f, y, "Press 'H' to hide the last notification");
|
||||
y += SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE + 2;
|
||||
SDL_RenderDebugTextFormat(renderer, 8.f, y, "Press 'T' to toggle the transient property (%s)", transient ? "ON" : "OFF");
|
||||
y += SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE + 2;
|
||||
SDL_RenderDebugTextFormat(renderer, 8.f, y, "Press 'S' to toggle the sound property (%s)", sound == 0 ? "Default" : sound == 1 ? "Custom"
|
||||
: "Silent");
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
|
||||
return SDL_APP_CONTINUE;
|
||||
}
|
||||
|
||||
void SDL_AppQuit(void *appstate, SDL_AppResult result)
|
||||
{
|
||||
SDL_DestroySurface(icon);
|
||||
SDLTest_CommonQuit(state);
|
||||
}
|
||||
Reference in New Issue
Block a user