Cleanup DBUS send notification API
This commit is contained in:
parent
2c90baf0b6
commit
c18098d872
10 changed files with 43 additions and 29 deletions
|
|
@ -325,8 +325,7 @@ def generate_wrappers(glfw_header: str) -> None:
|
||||||
void glfwWaylandRedrawCSDWindowTitle(GLFWwindow *handle)
|
void glfwWaylandRedrawCSDWindowTitle(GLFWwindow *handle)
|
||||||
void glfwWaylandSetupLayerShellForNextWindow(const GLFWLayerShellConfig *c)
|
void glfwWaylandSetupLayerShellForNextWindow(const GLFWLayerShellConfig *c)
|
||||||
pid_t glfwWaylandCompositorPID(void)
|
pid_t glfwWaylandCompositorPID(void)
|
||||||
unsigned long long glfwDBusUserNotify(const char *app_name, const char* icon, const char *summary, const char *body, \
|
unsigned long long glfwDBusUserNotify(const GLFWDBUSNotificationData *n, GLFWDBusnotificationcreatedfun callback, void *data)
|
||||||
const char *action_text, int32_t timeout, int urgency, GLFWDBusnotificationcreatedfun callback, void *data)
|
|
||||||
void glfwDBusSetUserNotificationHandler(GLFWDBusnotificationactivatedfun handler)
|
void glfwDBusSetUserNotificationHandler(GLFWDBusnotificationactivatedfun handler)
|
||||||
int glfwSetX11LaunchCommand(GLFWwindow *handle, char **argv, int argc)
|
int glfwSetX11LaunchCommand(GLFWwindow *handle, char **argv, int argc)
|
||||||
void glfwSetX11WindowAsDock(int32_t x11_window_id)
|
void glfwSetX11WindowAsDock(int32_t x11_window_id)
|
||||||
|
|
|
||||||
5
glfw/glfw3.h
vendored
5
glfw/glfw3.h
vendored
|
|
@ -1315,6 +1315,11 @@ typedef struct GLFWLayerShellConfig {
|
||||||
void (*size_callback)(GLFWwindow *window, const struct GLFWLayerShellConfig *config, unsigned monitor_width, unsigned monitor_height, uint32_t *width, uint32_t *height);
|
void (*size_callback)(GLFWwindow *window, const struct GLFWLayerShellConfig *config, unsigned monitor_width, unsigned monitor_height, uint32_t *width, uint32_t *height);
|
||||||
} GLFWLayerShellConfig;
|
} GLFWLayerShellConfig;
|
||||||
|
|
||||||
|
typedef struct GLFWDBUSNotificationData {
|
||||||
|
const char *app_name, *icon, *summary, *body, *action_name;
|
||||||
|
int32_t timeout; uint8_t urgency;
|
||||||
|
} GLFWDBUSNotificationData;
|
||||||
|
|
||||||
/*! @brief The function pointer type for error callbacks.
|
/*! @brief The function pointer type for error callbacks.
|
||||||
*
|
*
|
||||||
* This is the function pointer type for error callbacks. An error callback
|
* This is the function pointer type for error callbacks. An error callback
|
||||||
|
|
|
||||||
21
glfw/linux_notify.c
vendored
21
glfw/linux_notify.c
vendored
|
|
@ -93,10 +93,10 @@ cancel_user_notification(DBusConnection *session_bus, uint32_t *id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
notification_id_type
|
notification_id_type
|
||||||
glfw_dbus_send_user_notification(const char *app_name, const char* icon, const char *summary, const char *body, const char* action_name, int32_t timeout, int urgency, GLFWDBusnotificationcreatedfun callback, void *user_data) {
|
glfw_dbus_send_user_notification(const GLFWDBUSNotificationData *n, GLFWDBusnotificationcreatedfun callback, void *user_data) {
|
||||||
DBusConnection *session_bus = glfw_dbus_session_bus();
|
DBusConnection *session_bus = glfw_dbus_session_bus();
|
||||||
if (!session_bus) return 0;
|
if (!session_bus) return 0;
|
||||||
if (timeout == -9999 && urgency == -9999) return cancel_user_notification(session_bus, user_data) ? 1 : 0;
|
if (n->timeout == -9999 && n->urgency == 255) return cancel_user_notification(session_bus, user_data) ? 1 : 0;
|
||||||
static DBusConnection *added_signal_match = NULL;
|
static DBusConnection *added_signal_match = NULL;
|
||||||
if (added_signal_match != session_bus) {
|
if (added_signal_match != session_bus) {
|
||||||
dbus_bus_add_match(session_bus, "type='signal',interface='" NOTIFICATIONS_IFACE "',member='ActionInvoked'", NULL);
|
dbus_bus_add_match(session_bus, "type='signal',interface='" NOTIFICATIONS_IFACE "',member='ActionInvoked'", NULL);
|
||||||
|
|
@ -119,16 +119,16 @@ glfw_dbus_send_user_notification(const char *app_name, const char* icon, const c
|
||||||
dbus_message_iter_init_append(msg, &args);
|
dbus_message_iter_init_append(msg, &args);
|
||||||
#define check_call(func, ...) if (!func(__VA_ARGS__)) { _glfwInputError(GLFW_PLATFORM_ERROR, "%s", "Out of memory allocating DBUS message for notification\n"); return 0; }
|
#define check_call(func, ...) if (!func(__VA_ARGS__)) { _glfwInputError(GLFW_PLATFORM_ERROR, "%s", "Out of memory allocating DBUS message for notification\n"); return 0; }
|
||||||
#define APPEND(to, type, val) check_call(dbus_message_iter_append_basic, &to, type, &val);
|
#define APPEND(to, type, val) check_call(dbus_message_iter_append_basic, &to, type, &val);
|
||||||
APPEND(args, DBUS_TYPE_STRING, app_name)
|
APPEND(args, DBUS_TYPE_STRING, n->app_name)
|
||||||
APPEND(args, DBUS_TYPE_UINT32, replaces_id)
|
APPEND(args, DBUS_TYPE_UINT32, replaces_id)
|
||||||
APPEND(args, DBUS_TYPE_STRING, icon)
|
APPEND(args, DBUS_TYPE_STRING, n->icon)
|
||||||
APPEND(args, DBUS_TYPE_STRING, summary)
|
APPEND(args, DBUS_TYPE_STRING, n->summary)
|
||||||
APPEND(args, DBUS_TYPE_STRING, body)
|
APPEND(args, DBUS_TYPE_STRING, n->body)
|
||||||
check_call(dbus_message_iter_open_container, &args, DBUS_TYPE_ARRAY, "s", &array);
|
check_call(dbus_message_iter_open_container, &args, DBUS_TYPE_ARRAY, "s", &array);
|
||||||
if (action_name) {
|
if (n->action_name) {
|
||||||
static const char* default_action = "default";
|
static const char* default_action = "default";
|
||||||
APPEND(array, DBUS_TYPE_STRING, default_action);
|
APPEND(array, DBUS_TYPE_STRING, default_action);
|
||||||
APPEND(array, DBUS_TYPE_STRING, action_name);
|
APPEND(array, DBUS_TYPE_STRING, n->action_name);
|
||||||
}
|
}
|
||||||
check_call(dbus_message_iter_close_container, &args, &array);
|
check_call(dbus_message_iter_close_container, &args, &array);
|
||||||
check_call(dbus_message_iter_open_container, &args, DBUS_TYPE_ARRAY, "{sv}", &array);
|
check_call(dbus_message_iter_open_container, &args, DBUS_TYPE_ARRAY, "{sv}", &array);
|
||||||
|
|
@ -142,11 +142,10 @@ glfw_dbus_send_user_notification(const char *app_name, const char* icon, const c
|
||||||
check_call(dbus_message_iter_close_container, &dict, &variant); \
|
check_call(dbus_message_iter_close_container, &dict, &variant); \
|
||||||
check_call(dbus_message_iter_close_container, &array, &dict); \
|
check_call(dbus_message_iter_close_container, &array, &dict); \
|
||||||
}
|
}
|
||||||
uint8_t urgencyb = urgency & 3;
|
append_sv_dictionary_entry("urgency", DBUS_TYPE_BYTE, n->urgency);
|
||||||
append_sv_dictionary_entry("urgency", DBUS_TYPE_BYTE, urgencyb);
|
|
||||||
|
|
||||||
check_call(dbus_message_iter_close_container, &args, &array);
|
check_call(dbus_message_iter_close_container, &args, &array);
|
||||||
APPEND(args, DBUS_TYPE_INT32, timeout)
|
APPEND(args, DBUS_TYPE_INT32, n->timeout)
|
||||||
#undef check_call
|
#undef check_call
|
||||||
#undef APPEND
|
#undef APPEND
|
||||||
if (!call_method_with_msg(session_bus, msg, 5000, notification_created, data)) return 0;
|
if (!call_method_with_msg(session_bus, msg, 5000, notification_created, data)) return 0;
|
||||||
|
|
|
||||||
2
glfw/linux_notify.h
vendored
2
glfw/linux_notify.h
vendored
|
|
@ -14,6 +14,6 @@ typedef unsigned long long notification_id_type;
|
||||||
typedef void (*GLFWDBusnotificationcreatedfun)(notification_id_type, uint32_t, void*);
|
typedef void (*GLFWDBusnotificationcreatedfun)(notification_id_type, uint32_t, void*);
|
||||||
typedef void (*GLFWDBusnotificationactivatedfun)(uint32_t, int, const char*);
|
typedef void (*GLFWDBusnotificationactivatedfun)(uint32_t, int, const char*);
|
||||||
notification_id_type
|
notification_id_type
|
||||||
glfw_dbus_send_user_notification(const char *app_name, const char* icon, const char *summary, const char *body, const char *action_name, int32_t timeout, int urgency, GLFWDBusnotificationcreatedfun, void*);
|
glfw_dbus_send_user_notification(const GLFWDBUSNotificationData *n, GLFWDBusnotificationcreatedfun, void*);
|
||||||
void
|
void
|
||||||
glfw_dbus_set_user_notification_activated_handler(GLFWDBusnotificationactivatedfun handler);
|
glfw_dbus_set_user_notification_activated_handler(GLFWDBusnotificationactivatedfun handler);
|
||||||
|
|
|
||||||
4
glfw/wl_window.c
vendored
4
glfw/wl_window.c
vendored
|
|
@ -2720,8 +2720,8 @@ GLFWAPI void glfwRequestWaylandFrameEvent(GLFWwindow *handle, unsigned long long
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GLFWAPI unsigned long long glfwDBusUserNotify(const char *app_name, const char* icon, const char *summary, const char *body, const char *action_name, int32_t timeout, int urgency, GLFWDBusnotificationcreatedfun callback, void *data) {
|
GLFWAPI unsigned long long glfwDBusUserNotify(const GLFWDBUSNotificationData *n, GLFWDBusnotificationcreatedfun callback, void *data) {
|
||||||
return glfw_dbus_send_user_notification(app_name, icon, summary, body, action_name, timeout, urgency, callback, data);
|
return glfw_dbus_send_user_notification(n, callback, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLFWAPI void glfwDBusSetUserNotificationHandler(GLFWDBusnotificationactivatedfun handler) {
|
GLFWAPI void glfwDBusSetUserNotificationHandler(GLFWDBusnotificationactivatedfun handler) {
|
||||||
|
|
|
||||||
4
glfw/x11_window.c
vendored
4
glfw/x11_window.c
vendored
|
|
@ -3253,8 +3253,8 @@ GLFWAPI int glfwGetNativeKeyForName(const char* keyName, bool caseSensitive) {
|
||||||
return glfw_xkb_keysym_from_name(keyName, caseSensitive);
|
return glfw_xkb_keysym_from_name(keyName, caseSensitive);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLFWAPI unsigned long long glfwDBusUserNotify(const char *app_name, const char* icon, const char *summary, const char *body, const char *action_name, int32_t timeout, int urgency,GLFWDBusnotificationcreatedfun callback, void *data) {
|
GLFWAPI unsigned long long glfwDBusUserNotify(const GLFWDBUSNotificationData *n, GLFWDBusnotificationcreatedfun callback, void *data) {
|
||||||
return glfw_dbus_send_user_notification(app_name, icon, summary, body, action_name, timeout, urgency, callback, data);
|
return glfw_dbus_send_user_notification(n, callback, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLFWAPI void glfwDBusSetUserNotificationHandler(GLFWDBusnotificationactivatedfun handler) {
|
GLFWAPI void glfwDBusSetUserNotificationHandler(GLFWDBusnotificationactivatedfun handler) {
|
||||||
|
|
|
||||||
|
|
@ -550,10 +550,10 @@ def dbus_set_notification_callback(c: Optional[Callable[[str, int, Union[str, in
|
||||||
|
|
||||||
def dbus_send_notification(
|
def dbus_send_notification(
|
||||||
app_name: str,
|
app_name: str,
|
||||||
icon: str,
|
app_icon: str,
|
||||||
summary: str,
|
title: str,
|
||||||
body: str,
|
body: str,
|
||||||
action_name: str,
|
action_text: str = '',
|
||||||
timeout: int = -1,
|
timeout: int = -1,
|
||||||
urgency: int = 1,
|
urgency: int = 1,
|
||||||
) -> int:
|
) -> int:
|
||||||
|
|
|
||||||
8
kitty/glfw-wrapper.h
generated
8
kitty/glfw-wrapper.h
generated
|
|
@ -1053,6 +1053,11 @@ typedef struct GLFWLayerShellConfig {
|
||||||
void (*size_callback)(GLFWwindow *window, const struct GLFWLayerShellConfig *config, unsigned monitor_width, unsigned monitor_height, uint32_t *width, uint32_t *height);
|
void (*size_callback)(GLFWwindow *window, const struct GLFWLayerShellConfig *config, unsigned monitor_width, unsigned monitor_height, uint32_t *width, uint32_t *height);
|
||||||
} GLFWLayerShellConfig;
|
} GLFWLayerShellConfig;
|
||||||
|
|
||||||
|
typedef struct GLFWDBUSNotificationData {
|
||||||
|
const char *app_name, *icon, *summary, *body, *action_name;
|
||||||
|
int32_t timeout; uint8_t urgency;
|
||||||
|
} GLFWDBUSNotificationData;
|
||||||
|
|
||||||
/*! @brief The function pointer type for error callbacks.
|
/*! @brief The function pointer type for error callbacks.
|
||||||
*
|
*
|
||||||
* This is the function pointer type for error callbacks. An error callback
|
* This is the function pointer type for error callbacks. An error callback
|
||||||
|
|
@ -1700,6 +1705,7 @@ typedef void (* GLFWcocoarenderframefun)(GLFWwindow*);
|
||||||
typedef void (*GLFWwaylandframecallbackfunc)(unsigned long long id);
|
typedef void (*GLFWwaylandframecallbackfunc)(unsigned long long id);
|
||||||
typedef void (*GLFWDBusnotificationcreatedfun)(unsigned long long, uint32_t, void*);
|
typedef void (*GLFWDBusnotificationcreatedfun)(unsigned long long, uint32_t, void*);
|
||||||
typedef void (*GLFWDBusnotificationactivatedfun)(uint32_t, int, const char*);
|
typedef void (*GLFWDBusnotificationactivatedfun)(uint32_t, int, const char*);
|
||||||
|
|
||||||
typedef int (*glfwInit_func)(monotonic_t);
|
typedef int (*glfwInit_func)(monotonic_t);
|
||||||
GFW_EXTERN glfwInit_func glfwInit_impl;
|
GFW_EXTERN glfwInit_func glfwInit_impl;
|
||||||
#define glfwInit glfwInit_impl
|
#define glfwInit glfwInit_impl
|
||||||
|
|
@ -2328,7 +2334,7 @@ typedef pid_t (*glfwWaylandCompositorPID_func)(void);
|
||||||
GFW_EXTERN glfwWaylandCompositorPID_func glfwWaylandCompositorPID_impl;
|
GFW_EXTERN glfwWaylandCompositorPID_func glfwWaylandCompositorPID_impl;
|
||||||
#define glfwWaylandCompositorPID glfwWaylandCompositorPID_impl
|
#define glfwWaylandCompositorPID glfwWaylandCompositorPID_impl
|
||||||
|
|
||||||
typedef unsigned long long (*glfwDBusUserNotify_func)(const char*, const char*, const char*, const char*, const char*, int32_t, int, GLFWDBusnotificationcreatedfun, void*);
|
typedef unsigned long long (*glfwDBusUserNotify_func)(const GLFWDBUSNotificationData*, GLFWDBusnotificationcreatedfun, void*);
|
||||||
GFW_EXTERN glfwDBusUserNotify_func glfwDBusUserNotify_impl;
|
GFW_EXTERN glfwDBusUserNotify_func glfwDBusUserNotify_impl;
|
||||||
#define glfwDBusUserNotify glfwDBusUserNotify_impl
|
#define glfwDBusUserNotify glfwDBusUserNotify_impl
|
||||||
|
|
||||||
|
|
|
||||||
17
kitty/glfw.c
17
kitty/glfw.c
|
|
@ -2092,15 +2092,19 @@ dbus_notification_created_callback(unsigned long long notification_id, uint32_t
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
dbus_send_notification(PyObject *self UNUSED, PyObject *args) {
|
dbus_send_notification(PyObject *self UNUSED, PyObject *args, PyObject *kw) {
|
||||||
char *app_name, *icon, *summary, *body, *action_name;
|
|
||||||
int timeout = -1, urgency = 1;
|
int timeout = -1, urgency = 1;
|
||||||
if (!PyArg_ParseTuple(args, "sssss|ii", &app_name, &icon, &summary, &body, &action_name, &timeout, &urgency)) return NULL;
|
GLFWDBUSNotificationData d = {.action_name=""};
|
||||||
|
static const char* kwlist[] = {"app_name", "app_icon", "title", "body", "action_text", "timeout", "urgency", NULL};
|
||||||
|
if (!PyArg_ParseTupleAndKeywords(args, kw, "ssss|sii", (char**)kwlist,
|
||||||
|
&d.app_name, &d.icon, &d.summary, &d.body, &d.action_name, &timeout, &urgency)) return NULL;
|
||||||
if (!glfwDBusUserNotify) {
|
if (!glfwDBusUserNotify) {
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to load glfwDBusUserNotify, did you call glfw_init?");
|
PyErr_SetString(PyExc_RuntimeError, "Failed to load glfwDBusUserNotify, did you call glfw_init?");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
unsigned long long notification_id = glfwDBusUserNotify(app_name, icon, summary, body, action_name, timeout, urgency, dbus_notification_created_callback, NULL);
|
d.timeout = timeout;
|
||||||
|
d.urgency = urgency & 3;
|
||||||
|
unsigned long long notification_id = glfwDBusUserNotify(&d, dbus_notification_created_callback, NULL);
|
||||||
return PyLong_FromUnsignedLongLong(notification_id);
|
return PyLong_FromUnsignedLongLong(notification_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2108,11 +2112,12 @@ static PyObject*
|
||||||
dbus_close_notification(PyObject *self UNUSED, PyObject *args) {
|
dbus_close_notification(PyObject *self UNUSED, PyObject *args) {
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
if (!PyArg_ParseTuple(args, "I", &id)) return NULL;
|
if (!PyArg_ParseTuple(args, "I", &id)) return NULL;
|
||||||
|
GLFWDBUSNotificationData d = {.timeout=-9999, .urgency=255};
|
||||||
if (!glfwDBusUserNotify) {
|
if (!glfwDBusUserNotify) {
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Failed to load glfwDBusUserNotify, did you call glfw_init?");
|
PyErr_SetString(PyExc_RuntimeError, "Failed to load glfwDBusUserNotify, did you call glfw_init?");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (glfwDBusUserNotify("", "", "", "", "", -9999, -9999, NULL, &id)) Py_RETURN_TRUE;
|
if (glfwDBusUserNotify(&d, NULL, &id)) Py_RETURN_TRUE;
|
||||||
Py_RETURN_FALSE;
|
Py_RETURN_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2280,9 +2285,9 @@ static PyMethodDef module_methods[] = {
|
||||||
METHODB(make_x11_window_a_dock_window, METH_VARARGS),
|
METHODB(make_x11_window_a_dock_window, METH_VARARGS),
|
||||||
METHODB(strip_csi, METH_O),
|
METHODB(strip_csi, METH_O),
|
||||||
#ifndef __APPLE__
|
#ifndef __APPLE__
|
||||||
METHODB(dbus_send_notification, METH_VARARGS),
|
|
||||||
METHODB(dbus_close_notification, METH_VARARGS),
|
METHODB(dbus_close_notification, METH_VARARGS),
|
||||||
METHODB(dbus_set_notification_callback, METH_O),
|
METHODB(dbus_set_notification_callback, METH_O),
|
||||||
|
{"dbus_send_notification", (PyCFunction)(void (*) (void))(dbus_send_notification), METH_KEYWORDS | METH_VARARGS, NULL},
|
||||||
#else
|
#else
|
||||||
{"cocoa_recreate_global_menu", (PyCFunction)py_recreate_global_menu, METH_NOARGS, ""},
|
{"cocoa_recreate_global_menu", (PyCFunction)py_recreate_global_menu, METH_NOARGS, ""},
|
||||||
{"cocoa_clear_global_shortcuts", (PyCFunction)py_clear_global_shortcuts, METH_NOARGS, ""},
|
{"cocoa_clear_global_shortcuts", (PyCFunction)py_clear_global_shortcuts, METH_NOARGS, ""},
|
||||||
|
|
|
||||||
|
|
@ -497,7 +497,7 @@ def notify(self,
|
||||||
from .fast_data_types import dbus_send_notification
|
from .fast_data_types import dbus_send_notification
|
||||||
app_icon = icon_name or icon_path or get_custom_window_icon()[1] or logo_png_file
|
app_icon = icon_name or icon_path or get_custom_window_icon()[1] or logo_png_file
|
||||||
desktop_notification_id = dbus_send_notification(
|
desktop_notification_id = dbus_send_notification(
|
||||||
application, app_icon, title, body, 'Click to see changes', timeout, urgency.value)
|
app_name=application, app_icon=app_icon, title=title, body=body, timeout=timeout, urgency=urgency.value)
|
||||||
if debug_desktop_integration:
|
if debug_desktop_integration:
|
||||||
log_error(f'Created notification with {desktop_notification_id=}')
|
log_error(f'Created notification with {desktop_notification_id=}')
|
||||||
return desktop_notification_id
|
return desktop_notification_id
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue