forked from enlightenment/efl
parent
10cb9bcf73
commit
27c6def19d
|
@ -752,6 +752,7 @@
|
|||
|
||||
* Add elm_app_name_set/get(): Formal application name string.
|
||||
* Add elm_app_destkop_entry_set/get(): Path to '.desktop' file.
|
||||
* Add elm_sys_notify to expose System Notifications (D-Bus atm).
|
||||
|
||||
2012-12-04 Gwanglim Lee
|
||||
|
||||
|
|
|
@ -121,6 +121,7 @@ test_slider.c \
|
|||
test_slideshow.c \
|
||||
test_spinner.c \
|
||||
test_store.c \
|
||||
test_sys_notify.c \
|
||||
test_table.c \
|
||||
test_thumb.c \
|
||||
test_toolbar.c \
|
||||
|
|
|
@ -177,6 +177,7 @@ void test_ctxpopup(void *data, Evas_Object *obj, void *event_info);
|
|||
void test_bubble(void *data, Evas_Object *obj, void *event_info);
|
||||
void test_segment_control(void *data, Evas_Object *obj, void *event_info);
|
||||
void test_store(void *data, Evas_Object *obj, void *event_info);
|
||||
void test_sys_notify(void *data, Evas_Object *obj, void *event_info);
|
||||
void test_win_inline(void *data, Evas_Object *obj, void *event_info);
|
||||
void test_win_socket(void *data, Evas_Object *obj, void *event_info);
|
||||
void test_win_plug(void *data, Evas_Object *obj, void *event_info);
|
||||
|
@ -723,6 +724,9 @@ add_tests:
|
|||
ADD_TEST(NULL, "Helpers", "Store", test_store);
|
||||
// ADD_TEST(NULL, "Helpers", "Factory", test_factory);
|
||||
|
||||
//------------------------------//
|
||||
ADD_TEST(NULL, "System", "Notification", test_sys_notify);
|
||||
|
||||
//------------------------------//
|
||||
ADD_TEST(NULL, "Micellaneous", "Copy And Paste", test_cnp);
|
||||
ADD_TEST(NULL, "Micellaneous", "Weather", test_weather);
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include "elementary_config.h"
|
||||
#endif
|
||||
#include <Elementary.h>
|
||||
#ifndef ELM_LIB_QUICKLAUNCH
|
||||
|
||||
#define WIDTH 320
|
||||
#define HEIGHT 160
|
||||
|
||||
static Evas_Object *s = NULL;
|
||||
static Evas_Object *b = NULL;
|
||||
|
||||
static void
|
||||
_bt_clicked(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
|
||||
{
|
||||
elm_sys_notify_simple_send("", elm_entry_entry_get(s), elm_entry_entry_get(b));
|
||||
}
|
||||
|
||||
void
|
||||
test_sys_notify(void *data __UNUSED__,
|
||||
Evas_Object *obj __UNUSED__,
|
||||
void *event_info __UNUSED__)
|
||||
{
|
||||
Evas_Object *win, *bx, *it;
|
||||
|
||||
elm_need_sys_notify();
|
||||
|
||||
win = elm_win_add(NULL, "Sys Notify", ELM_WIN_BASIC);
|
||||
elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
|
||||
elm_win_title_set(win, "System Notification");
|
||||
elm_win_autodel_set(win, EINA_TRUE);
|
||||
|
||||
it = elm_bg_add(win);
|
||||
elm_win_resize_object_add(win, it);
|
||||
evas_object_size_hint_min_set(it, WIDTH, HEIGHT);
|
||||
evas_object_size_hint_max_set(it, WIDTH, HEIGHT);
|
||||
evas_object_show(it);
|
||||
|
||||
bx = elm_box_add(win);
|
||||
evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
||||
elm_win_resize_object_add(win, bx);
|
||||
evas_object_show(bx);
|
||||
|
||||
s = elm_entry_add(win);
|
||||
elm_entry_single_line_set(s, EINA_TRUE);
|
||||
elm_entry_scrollable_set(s, EINA_TRUE);
|
||||
elm_entry_entry_set(s, "Summary");
|
||||
evas_object_size_hint_align_set(s, EVAS_HINT_FILL, EVAS_HINT_FILL);
|
||||
elm_box_pack_end(bx, s);
|
||||
evas_object_show(s);
|
||||
|
||||
b = elm_entry_add(win);
|
||||
elm_entry_single_line_set(b, EINA_TRUE);
|
||||
elm_entry_scrollable_set(b, EINA_TRUE);
|
||||
elm_entry_entry_set(b, "Body long description.");
|
||||
evas_object_size_hint_align_set(b, EVAS_HINT_FILL, EVAS_HINT_FILL);
|
||||
elm_box_pack_end(bx, b);
|
||||
evas_object_show(b);
|
||||
|
||||
it = elm_button_add(win);
|
||||
elm_object_text_set(it, "Send Notification");
|
||||
evas_object_smart_callback_add(it, "clicked", _bt_clicked, NULL);
|
||||
elm_box_pack_end(bx, it);
|
||||
evas_object_show(it);
|
||||
|
||||
evas_object_resize(win, WIDTH, HEIGHT);
|
||||
evas_object_show(win);
|
||||
}
|
||||
#endif
|
|
@ -158,6 +158,7 @@ EAPI extern Elm_Version *elm_version;
|
|||
|
||||
#include <elm_prefs_data.h>
|
||||
#include <elm_prefs.h>
|
||||
#include <elm_sys_notify.h>
|
||||
|
||||
/* special widgets - types used elsewhere */
|
||||
#include <elm_icon.h>
|
||||
|
|
|
@ -193,6 +193,7 @@ elm_slider.h \
|
|||
elm_slideshow.h \
|
||||
elm_spinner.h \
|
||||
elm_store.h \
|
||||
elm_sys_notify.h \
|
||||
elm_table.h \
|
||||
elm_theme.h \
|
||||
elm_thumb.h \
|
||||
|
@ -279,6 +280,7 @@ elm_slider.c \
|
|||
elm_slideshow.c \
|
||||
elm_spinner.c \
|
||||
elm_store.c \
|
||||
elm_sys_notify.c \
|
||||
elm_table.c \
|
||||
elm_theme.c \
|
||||
elm_thumb.c \
|
||||
|
|
|
@ -623,6 +623,7 @@ elm_quicklaunch_shutdown(void)
|
|||
_elm_exit_handler = NULL;
|
||||
|
||||
_elm_theme_shutdown();
|
||||
_elm_unneed_sys_notify();
|
||||
_elm_unneed_efreet();
|
||||
_elm_unneed_e_dbus();
|
||||
_elm_unneed_edbus();
|
||||
|
|
|
@ -11,6 +11,20 @@
|
|||
*/
|
||||
EAPI Eina_Bool elm_need_efreet(void);
|
||||
|
||||
/**
|
||||
* Request that your elementary application needs Elm_Sys_Notify
|
||||
*
|
||||
* This initializes the Elm_Sys_Notify when called and if support exists
|
||||
* it returns EINA_TRUE, otherwise returns EINA_FALSE. This must be called
|
||||
* before any elm_sys_notify calls.
|
||||
*
|
||||
* @return EINA_TRUE if support exists and initialization succeeded.
|
||||
*
|
||||
* @ingroup Elm_Sys_Notify
|
||||
* @since 1.8
|
||||
*/
|
||||
EAPI Eina_Bool elm_need_sys_notify(void);
|
||||
|
||||
/**
|
||||
* Request that your elementary application needs e_dbus
|
||||
*
|
||||
|
|
|
@ -327,6 +327,7 @@ void _elm_widget_top_win_focused_set(Evas_Object *obj,
|
|||
Eina_Bool top_win_focused);
|
||||
Eina_Bool _elm_widget_top_win_focused_get(const Evas_Object *obj);
|
||||
|
||||
void _elm_unneed_sys_notify(void);
|
||||
void _elm_unneed_ethumb(void);
|
||||
void _elm_unneed_web(void);
|
||||
|
||||
|
|
|
@ -0,0 +1,303 @@
|
|||
#include <Elementary.h>
|
||||
#include "elm_priv.h"
|
||||
|
||||
#define OBJ "/org/freedesktop/Notifications"
|
||||
#define BUS "org.freedesktop.Notifications"
|
||||
#define INTERFACE "org.freedesktop.Notifications"
|
||||
|
||||
#ifdef ELM_EDBUS2
|
||||
static Eina_Bool _elm_need_sys_notify = EINA_FALSE;
|
||||
|
||||
static EDBus_Connection *_elm_sysnotif_conn = NULL;
|
||||
static EDBus_Object *_elm_sysnotif_obj = NULL;
|
||||
static EDBus_Proxy *_elm_sysnotif_proxy = NULL;
|
||||
|
||||
static Eina_Bool _has_markup = EINA_FALSE;
|
||||
|
||||
typedef struct _Elm_Sys_Notify_Send_Data
|
||||
{
|
||||
Elm_Sys_Notify_Send_Cb cb;
|
||||
const void *data;
|
||||
} Elm_Sys_Notify_Send_Data;
|
||||
|
||||
static void
|
||||
_elm_sys_notify_marshal_dict_byte(EDBus_Message_Iter *array,
|
||||
const char *key,
|
||||
const char value)
|
||||
{
|
||||
EDBus_Message_Iter *var, *entry;
|
||||
|
||||
edbus_message_iter_arguments_set(array, "{sv}", &entry);
|
||||
edbus_message_iter_basic_append(entry, 's', key);
|
||||
|
||||
var = edbus_message_iter_container_new(entry, 'v', "y");
|
||||
edbus_message_iter_basic_append(var, 'y', value);
|
||||
edbus_message_iter_container_close(entry, var);
|
||||
edbus_message_iter_container_close(array, entry);
|
||||
}
|
||||
|
||||
static void
|
||||
_elm_sys_notify_marshal_dict_string(EDBus_Message_Iter *array,
|
||||
const char *key,
|
||||
const char *value)
|
||||
{
|
||||
EDBus_Message_Iter *var, *entry;
|
||||
|
||||
edbus_message_iter_arguments_set(array, "{sv}", &entry);
|
||||
edbus_message_iter_basic_append(entry, 's', key);
|
||||
|
||||
var = edbus_message_iter_container_new(entry, 'v', "s");
|
||||
edbus_message_iter_basic_append(var, 's', value);
|
||||
edbus_message_iter_container_close(entry, var);
|
||||
edbus_message_iter_container_close(array, entry);
|
||||
}
|
||||
|
||||
static void
|
||||
_get_capabilities_cb(void *data EINA_UNUSED,
|
||||
const EDBus_Message *msg,
|
||||
EDBus_Pending *pending EINA_UNUSED)
|
||||
{
|
||||
char *val;
|
||||
EDBus_Message_Iter *arr;
|
||||
|
||||
if (edbus_message_error_get(msg, NULL, NULL) ||
|
||||
!edbus_message_arguments_get(msg, "as", &arr)) goto end;
|
||||
|
||||
while(edbus_message_iter_get_and_next(arr, 's', &val))
|
||||
if (!strcmp(val, "body-markup"))
|
||||
{
|
||||
_has_markup = EINA_TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
end:
|
||||
_has_markup = EINA_FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
_elm_sys_notify_capabilities_get(void)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN(_elm_sysnotif_proxy);
|
||||
|
||||
if (!edbus_proxy_call(_elm_sysnotif_proxy, "GetCapabilities",
|
||||
_get_capabilities_cb, NULL, -1, ""))
|
||||
ERR("Error sending message: "INTERFACE".GetCapabilities.");
|
||||
}
|
||||
|
||||
static void
|
||||
_close_notification_cb(void *data EINA_UNUSED,
|
||||
const EDBus_Message *msg,
|
||||
EDBus_Pending *pending EINA_UNUSED)
|
||||
{
|
||||
const char *errname, *errmsg;
|
||||
|
||||
if (edbus_message_error_get(msg, &errname, &errmsg))
|
||||
{
|
||||
if (errmsg && errmsg[0] == '\0')
|
||||
INF("Notification no longer exists.");
|
||||
else
|
||||
ERR("Edbus Error: %s %s", errname, errmsg);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
EAPI void
|
||||
elm_sys_notify_close(unsigned int id)
|
||||
{
|
||||
#ifdef ELM_EDBUS2
|
||||
EINA_SAFETY_ON_FALSE_RETURN(_elm_need_sys_notify);
|
||||
EINA_SAFETY_ON_NULL_RETURN(_elm_sysnotif_proxy);
|
||||
|
||||
if (!edbus_proxy_call(_elm_sysnotif_proxy, "CloseNotification",
|
||||
_close_notification_cb, NULL, -1, "u", id))
|
||||
ERR("Error sending message: "INTERFACE".CloseNotification.");
|
||||
#else
|
||||
(void) id;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ELM_EDBUS2
|
||||
static void
|
||||
_notify_cb(void *data,
|
||||
const EDBus_Message *msg,
|
||||
EDBus_Pending *pending EINA_UNUSED)
|
||||
{
|
||||
const char *errname, *errmsg;
|
||||
Elm_Sys_Notify_Send_Data *d = data;
|
||||
unsigned int id = 0;
|
||||
|
||||
if (edbus_message_error_get(msg, &errname, &errmsg))
|
||||
ERR("Error: %s %s", errname, errmsg);
|
||||
else if (!edbus_message_arguments_get(msg, "u", &id))
|
||||
{
|
||||
ERR("Error getting return values of "INTERFACE".Notify.");
|
||||
id = 0;
|
||||
}
|
||||
|
||||
if (d->cb) d->cb((void *)d->data, id);
|
||||
free(d);
|
||||
}
|
||||
#endif
|
||||
|
||||
EAPI void
|
||||
elm_sys_notify_send(unsigned int replaces_id, const char *icon,
|
||||
const char *summary, const char *body,
|
||||
Elm_Sys_Notify_Urgency urgency, int timeout,
|
||||
Elm_Sys_Notify_Send_Cb cb, const void *cb_data)
|
||||
{
|
||||
#ifdef ELM_EDBUS2
|
||||
EDBus_Message *msg;
|
||||
EDBus_Message_Iter *iter, *actions, *hints;
|
||||
Elm_Sys_Notify_Send_Data *data;
|
||||
char *body_free = NULL;
|
||||
char *desk_free = NULL;
|
||||
const char *deskentry = elm_app_desktop_entry_get();
|
||||
const char *appname = elm_app_name_get();
|
||||
|
||||
EINA_SAFETY_ON_FALSE_RETURN(_elm_need_sys_notify);
|
||||
EINA_SAFETY_ON_NULL_RETURN(_elm_sysnotif_proxy);
|
||||
|
||||
data = malloc(sizeof(Elm_Sys_Notify_Send_Data));
|
||||
EINA_SAFETY_ON_NULL_GOTO(data, error);
|
||||
data->cb = cb;
|
||||
data->data = cb_data;
|
||||
|
||||
if (!icon) icon = "";
|
||||
if (!summary) summary = "";
|
||||
if (!body)
|
||||
body = "";
|
||||
else if (!_has_markup)
|
||||
body = body_free = elm_entry_markup_to_utf8(body);
|
||||
|
||||
msg = edbus_proxy_method_call_new(_elm_sysnotif_proxy, "Notify");
|
||||
|
||||
iter = edbus_message_iter_get(msg);
|
||||
edbus_message_iter_arguments_set(iter, "susssas", appname, replaces_id, icon,
|
||||
summary, body, &actions);
|
||||
/* actions */
|
||||
edbus_message_iter_container_close(iter, actions);
|
||||
|
||||
/* hints */
|
||||
edbus_message_iter_arguments_set(iter, "a{sv}", &hints);
|
||||
_elm_sys_notify_marshal_dict_byte(hints, "urgency", (char) urgency);
|
||||
|
||||
if (strcmp(deskentry, ""))
|
||||
{
|
||||
deskentry = ecore_file_file_get(deskentry);
|
||||
deskentry = desk_free = ecore_file_strip_ext(deskentry);
|
||||
_elm_sys_notify_marshal_dict_string(hints, "desktop_entry", deskentry);
|
||||
}
|
||||
edbus_message_iter_container_close(iter, hints);
|
||||
|
||||
/* timeout */
|
||||
edbus_message_iter_arguments_set(iter, "i", timeout);
|
||||
|
||||
edbus_proxy_send(_elm_sysnotif_proxy, msg, _notify_cb, data, -1);
|
||||
|
||||
edbus_message_unref(msg);
|
||||
free(desk_free);
|
||||
free(body_free);
|
||||
return;
|
||||
|
||||
error:
|
||||
#else
|
||||
(void) replaces_id;
|
||||
(void) icon;
|
||||
(void) summary;
|
||||
(void) body;
|
||||
(void) urgency;
|
||||
(void) timeout;
|
||||
#endif
|
||||
if (cb) cb((void *)cb_data, 0);
|
||||
}
|
||||
|
||||
#ifdef ELM_EDBUS2
|
||||
static void
|
||||
_release(void)
|
||||
{
|
||||
if (_elm_sysnotif_proxy)
|
||||
{
|
||||
edbus_proxy_unref(_elm_sysnotif_proxy);
|
||||
_elm_sysnotif_proxy = NULL;
|
||||
}
|
||||
|
||||
if (_elm_sysnotif_obj)
|
||||
{
|
||||
edbus_object_unref(_elm_sysnotif_obj);
|
||||
_elm_sysnotif_obj = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_update(void)
|
||||
{
|
||||
_release();
|
||||
_elm_sysnotif_obj = edbus_object_get(_elm_sysnotif_conn, BUS, OBJ);
|
||||
_elm_sysnotif_proxy = edbus_proxy_get(_elm_sysnotif_obj, INTERFACE);
|
||||
_elm_sys_notify_capabilities_get();
|
||||
}
|
||||
|
||||
static void
|
||||
_name_owner_get_cb(void *data EINA_UNUSED,
|
||||
const EDBus_Message *msg,
|
||||
EDBus_Pending *pending EINA_UNUSED)
|
||||
{
|
||||
const char *errname, *errmsg;
|
||||
|
||||
if (edbus_message_error_get(msg, &errname, &errmsg))
|
||||
ERR("Edbus Error: %s %s", errname, errmsg);
|
||||
else
|
||||
_update();
|
||||
}
|
||||
|
||||
static void
|
||||
_name_owner_changed_cb(void *data EINA_UNUSED,
|
||||
const char *bus EINA_UNUSED,
|
||||
const char *old_id EINA_UNUSED,
|
||||
const char *new_id)
|
||||
{
|
||||
if ((!new_id) || (*new_id == '\0'))
|
||||
_release();
|
||||
else
|
||||
_update();
|
||||
}
|
||||
#endif
|
||||
|
||||
EAPI Eina_Bool
|
||||
elm_need_sys_notify(void)
|
||||
{
|
||||
#ifdef ELM_EDBUS2
|
||||
if (_elm_need_sys_notify) return EINA_TRUE;
|
||||
|
||||
if (!elm_need_edbus()) return EINA_FALSE;
|
||||
|
||||
_elm_sysnotif_conn = edbus_connection_get(EDBUS_CONNECTION_TYPE_SESSION);
|
||||
|
||||
edbus_name_owner_changed_callback_add(_elm_sysnotif_conn, BUS,
|
||||
_name_owner_changed_cb, NULL,
|
||||
EINA_FALSE);
|
||||
|
||||
edbus_name_owner_get(_elm_sysnotif_conn, BUS, _name_owner_get_cb, NULL);
|
||||
|
||||
_elm_need_sys_notify = EINA_TRUE;
|
||||
|
||||
return EINA_TRUE;
|
||||
#else
|
||||
return EINA_FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
_elm_unneed_sys_notify(void)
|
||||
{
|
||||
#ifdef ELM_EDBUS2
|
||||
if (!_elm_need_sys_notify) return;
|
||||
|
||||
_elm_need_sys_notify = EINA_FALSE;
|
||||
|
||||
_release();
|
||||
|
||||
edbus_connection_unref(_elm_sysnotif_conn);
|
||||
_elm_sysnotif_conn = NULL;
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
#ifndef ELM_SYS_NOTIFY_H
|
||||
#define ELM_SYS_NOTIFY_H
|
||||
|
||||
/**
|
||||
* Urgency levels of a notification
|
||||
*
|
||||
* @see elm_sys_notify_send()
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
typedef enum _Elm_Sys_Notify_Urgency
|
||||
{
|
||||
ELM_SYS_NOTIFY_URGENCY_LOW,
|
||||
ELM_SYS_NOTIFY_URGENCY_NORMAL,
|
||||
ELM_SYS_NOTIFY_URGENCY_CRITICAL
|
||||
} Elm_Sys_Notify_Urgency;
|
||||
|
||||
typedef void (*Elm_Sys_Notify_Send_Cb)(void *data, unsigned int id);
|
||||
|
||||
/**
|
||||
* @def elm_sys_notify_simple_send
|
||||
*
|
||||
* Create a new notification just with Icon, Body and Summary.
|
||||
*
|
||||
* @param[in] icon
|
||||
* @param[in] summary
|
||||
* @param[in] body
|
||||
*
|
||||
* @see elm_sys_notify_send()
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
#define elm_sys_notify_simple_send(icon, summary, body) \
|
||||
elm_sys_notify_send(0, icon, summary, body, \
|
||||
ELM_SYS_NOTIFY_URGENCY_NORMAL, \
|
||||
-1, NULL, NULL)
|
||||
|
||||
/**
|
||||
* Causes a notification to be forcefully closed and removed from the user's
|
||||
* view. It can be used, for example, in the event that what the notification
|
||||
* pertains to is no longer relevant, or to cancel a notification * with no
|
||||
* expiration time.
|
||||
*
|
||||
* @param id Notification id
|
||||
*
|
||||
* @note If the notification no longer exists,
|
||||
* an empty D-BUS Error message is sent back.
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
EAPI void elm_sys_notify_close(unsigned int id);
|
||||
|
||||
/**
|
||||
* Sends a notification to the notification server.
|
||||
*
|
||||
* @param replaces_id Notification ID that this notification replaces.
|
||||
* The value 0 means a new notification.
|
||||
* @param icon The optional program icon of the calling application.
|
||||
* @param summary The summary text briefly describing the notification.
|
||||
* @param body The optional detailed body text. Can be empty.
|
||||
* @param urgency The urgency level.
|
||||
* @param timeout Timeout display in milliseconds.
|
||||
* @param cb Callback used to retrieve the notification id
|
||||
* return by the Notification Server.
|
||||
* @param cb_data Optional context data
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
EAPI void elm_sys_notify_send(unsigned int replaces_id,
|
||||
const char *icon,
|
||||
const char *summary,
|
||||
const char *body,
|
||||
Elm_Sys_Notify_Urgency urgency,
|
||||
int timeout,
|
||||
Elm_Sys_Notify_Send_Cb cb,
|
||||
const void *cb_data);
|
||||
#endif
|
Loading…
Reference in New Issue