Skip to content

Commit b865715

Browse files
committed
Update the SDL notification patch from #1932
1 parent 3951cae commit b865715

File tree

10 files changed

+201
-0
lines changed

10 files changed

+201
-0
lines changed

include/SDL3/SDL.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
#include <SDL3/SDL_misc.h>
5959
#include <SDL3/SDL_mouse.h>
6060
#include <SDL3/SDL_mutex.h>
61+
#include <SDL3/SDL_notification.h>
6162
#include <SDL3/SDL_pixels.h>
6263
#include <SDL3/SDL_platform.h>
6364
#include <SDL3/SDL_power.h>

include/SDL3/SDL_notification.h

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
Simple DirectMedia Layer
3+
Copyright (C) 1997-2023 Sam Lantinga <[email protected]>
4+
5+
This software is provided 'as-is', without any express or implied
6+
warranty. In no event will the authors be held liable for any damages
7+
arising from the use of this software.
8+
9+
Permission is granted to anyone to use this software for any purpose,
10+
including commercial applications, and to alter it and redistribute it
11+
freely, subject to the following restrictions:
12+
13+
1. The origin of this software must not be misrepresented; you must not
14+
claim that you wrote the original software. If you use this software
15+
in a product, an acknowledgment in the product documentation would be
16+
appreciated but is not required.
17+
2. Altered source versions must be plainly marked as such, and must not be
18+
misrepresented as being the original software.
19+
3. This notice may not be removed or altered from any source distribution.
20+
*/
21+
22+
/**
23+
* \file SDL_notification.h
24+
*
25+
* \brief Header file for notification API
26+
*/
27+
28+
#ifndef SDL_notification_h_
29+
#define SDL_notification_h_
30+
31+
#include <SDL3/SDL_stdinc.h>
32+
33+
#include <SDL3/SDL_begin_code.h>
34+
/* Set up for C function definitions, even when using C++ */
35+
#ifdef __cplusplus
36+
extern "C" {
37+
#endif
38+
39+
/**
40+
* \brief SDL_Notification flags.
41+
*/
42+
typedef enum
43+
{
44+
SDL_NOTIFICATION_PRIORITY_LOW = 0x00000010, /**< lowest */
45+
SDL_NOTIFICATION_PRIORITY_NORMAL = 0x00000020, /**< normal/medium */
46+
SDL_NOTIFICATION_PRIORITY_HIGH = 0x00000040 /**< high/important/critical */
47+
} SDL_NotificationFlags;
48+
49+
/**
50+
* \brief SDL_Icon flags.
51+
*/
52+
typedef enum
53+
{
54+
SDL_ICON_TYPE_SINGLE_FILE = 0x00000010, /**< A single icon file. */
55+
SDL_ICON_TYPE_ICON_DIRECTORY = 0x00000020, /**< A directory containing icons in "heightxwidth.bmp" format. */
56+
SDL_ICON_TYPE_SURFACE = 0x00000040 /**< Icon inside an SDL surface. */
57+
} SDL_IconFlags;
58+
59+
typedef struct
60+
{
61+
Uint32 flags;
62+
union {
63+
const char *path;
64+
SDL_Surface *surface;
65+
} icon;
66+
} SDL_Icon;
67+
68+
/**
69+
* \brief Create a simple system notification.
70+
*
71+
* If a window is specified it's icon will be used for the notification,
72+
* and the notifcation will open that window when clicked on supported
73+
* platforms. Alternatively if an icon is specified for the icon this will,
74+
* be used instead.
75+
*
76+
* \param flags Notification/Priority Flags
77+
* \param title UTF-8 title text
78+
* \param message UTF-8 message text
79+
* \param window Window to associate to the notfication.
80+
* \param icon Icon (if different to window icon).
81+
*
82+
* \return 0 on success, -1 on error
83+
*
84+
* \sa SDL_ShowSimpleNotification
85+
*/
86+
extern DECLSPEC int SDLCALL SDL_ShowSimpleNotification(Uint32 flags, const char *title, const char *message,
87+
SDL_Window *window, SDL_Icon *icon);
88+
89+
/* Ends C function definitions when using C++ */
90+
#ifdef __cplusplus
91+
}
92+
#endif
93+
#include <SDL3/SDL_close_code.h>
94+
95+
96+
#endif /* SDL_notification_h_ */
97+

src/core/linux/SDL_dbus.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,4 +498,54 @@ SDL_DBus_ScreensaverInhibit(SDL_bool inhibit)
498498

499499
return SDL_TRUE;
500500
}
501+
502+
SDL_bool SDL_DBus_SendNotification(const char *app, const char *title, const char *body)
503+
{
504+
dbus_bool_t status = 0;
505+
DBusConnection *conn = dbus.session_conn;
506+
DBusMessage *msg = NULL;
507+
Uint32 replace_id = 0;
508+
Sint32 timeout = -1;
509+
const char *icon = "";
510+
DBusMessageIter iter;
511+
DBusMessageIter sub;
512+
513+
if (conn == NULL) {
514+
return SDL_FALSE;
515+
}
516+
517+
msg = dbus.message_new_method_call("org.freedesktop.Notifications",
518+
"/org/freedesktop/Notifications",
519+
"org.freedesktop.Notifications",
520+
"Notify");
521+
if (msg != NULL) {
522+
dbus.message_iter_init_append(msg, &iter);
523+
status = dbus.message_iter_append_basic(&iter, DBUS_TYPE_STRING, &app);
524+
status = dbus.message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &replace_id);
525+
status = dbus.message_iter_append_basic(&iter, DBUS_TYPE_STRING, &icon);
526+
status = dbus.message_iter_append_basic(&iter, DBUS_TYPE_STRING, &title);
527+
status = dbus.message_iter_append_basic(&iter, DBUS_TYPE_STRING, &body);
528+
status = dbus.message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &sub);
529+
status = dbus.message_iter_close_container(&iter, &sub);
530+
status = dbus.message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &sub);
531+
status = dbus.message_iter_close_container(&iter, &sub);
532+
status = dbus.message_iter_append_basic(&iter, DBUS_TYPE_INT32, &timeout);
533+
if (!status) {
534+
SDL_SetError("Error appending to dbus parameters (notification)");
535+
} else {
536+
status = dbus.connection_send(conn, msg, NULL);
537+
if (!status) {
538+
SDL_SetError("Error sending to dbus (notification)");
539+
} else {
540+
dbus.connection_flush(conn);
541+
}
542+
}
543+
544+
dbus.message_unref(msg);
545+
}
546+
547+
return (status) ? SDL_TRUE : SDL_FALSE;
548+
}
549+
550+
501551
#endif

src/core/linux/SDL_dbus.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ extern SDL_bool SDL_DBus_QueryPropertyOnConnection(DBusConnection *conn, const c
9393

9494
extern void SDL_DBus_ScreensaverTickle(void);
9595
extern SDL_bool SDL_DBus_ScreensaverInhibit(SDL_bool inhibit);
96+
extern SDL_bool SDL_DBus_SendNotification(const char *app, const char *title, const char *body);
9697

9798
#endif /* HAVE_DBUS_DBUS_H */
9899

src/dynapi/SDL_dynapi.sym

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -841,6 +841,7 @@ SDL3_0.0.0 {
841841
SDL_GetSystemTheme;
842842
SDL_CreatePopupWindow;
843843
SDL_GetWindowParent;
844+
SDL_ShowSimpleNotification;
844845
# extra symbols go here (don't modify this line)
845846
local: *;
846847
};

src/dynapi/SDL_dynapi_overrides.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -868,3 +868,4 @@
868868
#define SDL_GetSystemTheme SDL_GetSystemTheme_REAL
869869
#define SDL_CreatePopupWindow SDL_CreatePopupWindow_REAL
870870
#define SDL_GetWindowParent SDL_GetWindowParent_REAL
871+
#define SDL_ShowSimpleNotification SDL_ShowSimpleNotification_REAL

src/dynapi/SDL_dynapi_procs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -913,3 +913,4 @@ SDL_DYNAPI_PROC(int,SDL_GetRenderWindowSize,(SDL_Renderer *a, int *b, int *c),(a
913913
SDL_DYNAPI_PROC(SDL_SystemTheme,SDL_GetSystemTheme,(void),(),return)
914914
SDL_DYNAPI_PROC(SDL_Window*,SDL_CreatePopupWindow,(SDL_Window *a, int b, int c, int d, int e, Uint32 f),(a,b,c,d,e,f),return)
915915
SDL_DYNAPI_PROC(SDL_Window*,SDL_GetWindowParent,(SDL_Window *a),(a),return)
916+
SDL_DYNAPI_PROC(int,SDL_ShowSimpleNotification,(Uint32 a, const char *b, const char *c, SDL_Window *d, SDL_Icon *e),(a,b,c,d,e),return)

src/video/SDL_sysvideo.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,9 @@ struct SDL_VideoDevice
344344
/* Hit-testing */
345345
int (*SetWindowHitTest)(SDL_Window *window, SDL_bool enabled);
346346

347+
/* Notification */
348+
int (*ShowNotification)(_THIS, const SDL_MessageBoxData *messageboxdata, int *buttonid);
349+
347350
/* Tell window that app enabled drag'n'drop events */
348351
void (*AcceptDragAndDrop)(SDL_Window *window, SDL_bool accept);
349352

src/video/SDL_video.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5043,3 +5043,35 @@ void *SDL_Metal_GetLayer(SDL_MetalView view)
50435043
return NULL;
50445044
}
50455045
}
5046+
5047+
5048+
#if defined(__LINUX__)
5049+
#include "../core/linux/SDL_dbus.h"
5050+
#endif
5051+
5052+
static int SDL_PrivateShowNotification(Uint32 flags, const char *title, const char *message, SDL_Window *window, SDL_Icon *icon)
5053+
{
5054+
int retval = -1;
5055+
5056+
#if SDL_USE_LIBDBUS
5057+
/* Currently DBUS is initialized in X11 Video Init and needs to moved out */
5058+
if (retval == -1 &&
5059+
SDL_DBus_SendNotification(title, title, message) == SDL_TRUE) {
5060+
retval = 0;
5061+
}
5062+
#endif
5063+
5064+
if (retval == -1) {
5065+
retval = SDL_ShowSimpleMessageBox(0, title, message, window);
5066+
}
5067+
5068+
return retval;
5069+
}
5070+
5071+
int SDL_ShowSimpleNotification(Uint32 flags, const char *title, const char *message, SDL_Window *window, SDL_Icon *icon)
5072+
{
5073+
/* This is to allow expansion of the API later on.
5074+
Assuming you would create a notification which could then be updated later via a pointer.
5075+
This would be useful for progress notifications etc. */
5076+
return SDL_PrivateShowNotification(flags, title, message, window, icon);
5077+
}

test/testmessage.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,11 +200,25 @@ int main(int argc, char *argv[])
200200
quit(1);
201201
}
202202

203+
204+
/* Test showing a system notification message with a parent window */
205+
success = SDL_ShowSimpleNotification(SDL_NOTIFICATION_PRIORITY_NORMAL,
206+
"Simple Notification",
207+
"Hey this window needs attention!",
208+
window, NULL);
209+
if (success == -1) {
210+
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error Presenting Notification: %s\n", SDL_GetError());
211+
quit(1);
212+
}
213+
203214
while (SDL_WaitEvent(&event)) {
204215
if (event.type == SDL_EVENT_QUIT || event.type == SDL_EVENT_KEY_UP) {
205216
break;
206217
}
207218
}
219+
220+
221+
SDL_DestroyWindow(window);
208222
}
209223

210224
SDL_Quit();

0 commit comments

Comments
 (0)