mirror of
https://github.com/abraunegg/onedrive
synced 2024-06-28 10:20:22 +02:00
3d249b8d10
* fix libnotify * Add notification error handling
324 lines
8.7 KiB
D
324 lines
8.7 KiB
D
module dnotify;
|
|
|
|
private {
|
|
import std.string : toStringz;
|
|
import std.conv : to;
|
|
import std.traits : isPointer, isArray;
|
|
import std.variant : Variant;
|
|
import std.array : appender;
|
|
|
|
import deimos.notify.notify;
|
|
}
|
|
|
|
public import deimos.notify.notify : NOTIFY_EXPIRES_DEFAULT, NOTIFY_EXPIRES_NEVER,
|
|
NotifyUrgency;
|
|
|
|
|
|
version(NoPragma) {
|
|
} else {
|
|
pragma(lib, "notify");
|
|
pragma(lib, "gmodule");
|
|
pragma(lib, "glib-2.0");
|
|
}
|
|
|
|
extern (C) {
|
|
private void g_free(void* mem);
|
|
private void g_list_free(GList* glist);
|
|
}
|
|
|
|
version(NoGdk) {
|
|
} else {
|
|
version(NoPragma) {
|
|
} else {
|
|
pragma(lib, "gdk_pixbuf");
|
|
}
|
|
|
|
private:
|
|
extern (C) {
|
|
GdkPixbuf* gdk_pixbuf_new_from_file(const(char)* filename, GError **error);
|
|
}
|
|
}
|
|
|
|
class NotificationError : Exception {
|
|
string message;
|
|
GError* gerror;
|
|
|
|
this(GError* gerror) {
|
|
this.message = to!(string)(gerror.message);
|
|
this.gerror = gerror;
|
|
|
|
super(this.message);
|
|
}
|
|
|
|
this(string message) {
|
|
this.message = message;
|
|
|
|
super(message);
|
|
}
|
|
}
|
|
|
|
bool check_availability() {
|
|
// notify_init might return without dbus server actually started
|
|
// try to check for running dbus server
|
|
char **ret_name;
|
|
char **ret_vendor;
|
|
char **ret_version;
|
|
char **ret_spec_version;
|
|
bool ret;
|
|
try {
|
|
return notify_get_server_info(ret_name, ret_vendor, ret_version, ret_spec_version);
|
|
} catch (NotificationError e) {
|
|
throw new NotificationError("Cannot find dbus server!");
|
|
}
|
|
}
|
|
|
|
void init(in char[] name) {
|
|
notify_init(name.toStringz());
|
|
}
|
|
|
|
alias notify_is_initted is_initted;
|
|
alias notify_uninit uninit;
|
|
|
|
shared static this() {
|
|
init(__FILE__);
|
|
}
|
|
|
|
shared static ~this() {
|
|
uninit();
|
|
}
|
|
|
|
string get_app_name() {
|
|
return to!(string)(notify_get_app_name());
|
|
}
|
|
|
|
void set_app_name(in char[] app_name) {
|
|
notify_set_app_name(app_name.toStringz());
|
|
}
|
|
|
|
string[] get_server_caps() {
|
|
auto result = appender!(string[])();
|
|
|
|
GList* list = notify_get_server_caps();
|
|
if(list !is null) {
|
|
for(GList* c = list; c !is null; c = c.next) {
|
|
result.put(to!(string)(cast(char*)c.data));
|
|
g_free(c.data);
|
|
}
|
|
|
|
g_list_free(list);
|
|
}
|
|
|
|
return result.data;
|
|
}
|
|
|
|
struct ServerInfo {
|
|
string name;
|
|
string vendor;
|
|
string version_;
|
|
string spec_version;
|
|
}
|
|
|
|
ServerInfo get_server_info() {
|
|
char* name;
|
|
char* vendor;
|
|
char* version_;
|
|
char* spec_version;
|
|
notify_get_server_info(&name, &vendor, &version_, &spec_version);
|
|
|
|
scope(exit) {
|
|
g_free(name);
|
|
g_free(vendor);
|
|
g_free(version_);
|
|
g_free(spec_version);
|
|
}
|
|
|
|
return ServerInfo(to!string(name), to!string(vendor), to!string(version_), to!string(spec_version));
|
|
}
|
|
|
|
|
|
struct Action {
|
|
const(char[]) id;
|
|
const(char[]) label;
|
|
NotifyActionCallback callback;
|
|
void* user_ptr;
|
|
}
|
|
|
|
|
|
class Notification {
|
|
NotifyNotification* notify_notification;
|
|
|
|
const(char)[] summary;
|
|
const(char)[] body_;
|
|
const(char)[] icon;
|
|
|
|
bool closed = true;
|
|
|
|
private int _timeout = NOTIFY_EXPIRES_DEFAULT;
|
|
const(char)[] _category;
|
|
NotifyUrgency _urgency;
|
|
GdkPixbuf* _image;
|
|
Variant[const(char)[]] _hints;
|
|
const(char)[] _app_name;
|
|
Action[] _actions;
|
|
|
|
this(in char[] summary, in char[] body_, in char[] icon="")
|
|
in { assert(is_initted(), "call dnotify.init() before using Notification"); }
|
|
do {
|
|
this.summary = summary;
|
|
this.body_ = body_;
|
|
this.icon = icon;
|
|
notify_notification = notify_notification_new(summary.toStringz(), body_.toStringz(), icon.toStringz());
|
|
}
|
|
|
|
bool update(in char[] summary, in char[] body_, in char[] icon="") {
|
|
this.summary = summary;
|
|
this.body_ = body_;
|
|
this.icon = icon;
|
|
return notify_notification_update(notify_notification, summary.toStringz(), body_.toStringz(), icon.toStringz());
|
|
}
|
|
|
|
void show() {
|
|
GError* ge;
|
|
|
|
if(!notify_notification_show(notify_notification, &ge)) {
|
|
throw new NotificationError(ge);
|
|
}
|
|
}
|
|
|
|
@property int timeout() { return _timeout; }
|
|
@property void timeout(int timeout) {
|
|
this._timeout = timeout;
|
|
notify_notification_set_timeout(notify_notification, timeout);
|
|
}
|
|
|
|
@property const(char[]) category() { return _category; }
|
|
@property void category(in char[] category) {
|
|
this._category = category;
|
|
notify_notification_set_category(notify_notification, category.toStringz());
|
|
}
|
|
|
|
@property NotifyUrgency urgency() { return _urgency; }
|
|
@property void urgency(NotifyUrgency urgency) {
|
|
this._urgency = urgency;
|
|
notify_notification_set_urgency(notify_notification, urgency);
|
|
}
|
|
|
|
|
|
void set_image(GdkPixbuf* pixbuf) {
|
|
notify_notification_set_image_from_pixbuf(notify_notification, pixbuf);
|
|
//_image = pixbuf;
|
|
}
|
|
|
|
version(NoGdk) {
|
|
} else {
|
|
void set_image(in char[] filename) {
|
|
GError* ge;
|
|
// TODO: free pixbuf
|
|
GdkPixbuf* pixbuf = gdk_pixbuf_new_from_file(filename.toStringz(), &ge);
|
|
|
|
if(pixbuf is null) {
|
|
if(ge is null) {
|
|
throw new NotificationError("Unable to load file: " ~ filename.idup);
|
|
} else {
|
|
throw new NotificationError(ge);
|
|
}
|
|
}
|
|
assert(notify_notification !is null);
|
|
notify_notification_set_image_from_pixbuf(notify_notification, pixbuf); // TODO: fix segfault
|
|
//_image = pixbuf;
|
|
}
|
|
}
|
|
|
|
@property GdkPixbuf* image() { return _image; }
|
|
|
|
// using deprecated set_hint_* functions (GVariant is an opaque structure, which needs the glib)
|
|
void set_hint(T)(in char[] key, T value) {
|
|
static if(is(T == int)) {
|
|
notify_notification_set_hint_int32(notify_notification, key, value);
|
|
} else static if(is(T == uint)) {
|
|
notify_notification_set_hint_uint32(notify_notification, key, value);
|
|
} else static if(is(T == double)) {
|
|
notify_notification_set_hint_double(notify_notification, key, value);
|
|
} else static if(is(T : const(char)[])) {
|
|
notify_notification_set_hint_string(notify_notification, key, value.toStringz());
|
|
} else static if(is(T == ubyte)) {
|
|
notify_notification_set_hint_byte(notify_notification, key, value);
|
|
} else static if(is(T == ubyte[])) {
|
|
notify_notification_set_hint_byte_array(notify_notification, key, value.ptr, value.length);
|
|
} else {
|
|
static assert(false, "unsupported value for Notification.set_hint");
|
|
}
|
|
|
|
_hints[key] = Variant(value);
|
|
}
|
|
|
|
// unset hint?
|
|
|
|
Variant get_hint(in char[] key) {
|
|
return _hints[key];
|
|
}
|
|
|
|
@property const(char)[] app_name() { return _app_name; }
|
|
@property void app_name(in char[] name) {
|
|
this._app_name = app_name;
|
|
notify_notification_set_app_name(notify_notification, app_name.toStringz());
|
|
}
|
|
|
|
void add_action(T)(in char[] action, in char[] label, NotifyActionCallback callback, T user_data) {
|
|
static if(isPointer!T) {
|
|
void* user_ptr = cast(void*)user_data;
|
|
} else static if(isArray!T) {
|
|
void* user_ptr = cast(void*)user_data.ptr;
|
|
} else {
|
|
void* user_ptr = cast(void*)&user_data;
|
|
}
|
|
|
|
notify_notification_add_action(notify_notification, action.toStringz(), label.toStringz(),
|
|
callback, user_ptr, null);
|
|
|
|
_actions ~= Action(action, label, callback, user_ptr);
|
|
}
|
|
|
|
void add_action()(Action action) {
|
|
notify_notification_add_action(notify_notification, action.id.toStringz(), action.label.toStringz(),
|
|
action.callback, action.user_ptr, null);
|
|
|
|
_actions ~= action;
|
|
}
|
|
|
|
@property Action[] actions() { return _actions; }
|
|
|
|
void clear_actions() {
|
|
notify_notification_clear_actions(notify_notification);
|
|
}
|
|
|
|
void close() {
|
|
GError* ge;
|
|
|
|
if(!notify_notification_close(notify_notification, &ge)) {
|
|
throw new NotificationError(ge);
|
|
}
|
|
}
|
|
|
|
@property int closed_reason() {
|
|
return notify_notification_get_closed_reason(notify_notification);
|
|
}
|
|
}
|
|
|
|
|
|
version(TestMain) {
|
|
import std.stdio;
|
|
|
|
void main() {
|
|
writeln(get_app_name());
|
|
set_app_name("bla");
|
|
writeln(get_app_name());
|
|
writeln(get_server_caps());
|
|
writeln(get_server_info());
|
|
|
|
auto n = new Notification("foo", "bar", "notification-message-im");
|
|
n.timeout = 3;
|
|
n.show();
|
|
}
|
|
}
|