Skip to content

Commit

Permalink
weaponize #363 - systray
Browse files Browse the repository at this point in the history
* type check the args
* add some Ruby garbage collection thinking.
* update the manual
* needs osx
  • Loading branch information
Cecil committed Aug 5, 2017
1 parent f44fe03 commit 1ec0106
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 15 deletions.
8 changes: 7 additions & 1 deletion Tests/systray/note.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@
ctr = 0;
button "Notify" do
ctr += 1
systray title: "Notify Test", message: "message ##{ctr}", icon: "#{DIR}/static/shoes-icon.png"
icp = ''
if ctr % 3 != 0
icp = "#{DIR}/static/shoes-icon.png"
else
icp = "#{DIR}/static/shoes-icon-red.png"
end
systray title: "Notify Test", message: "message ##{ctr}", icon: icp
end
end
end
8 changes: 4 additions & 4 deletions shoes/native/gtk.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ GtkApplication *shoes_GtkApp;
void
shoes_gtk_app_activate (GApplication *app, gpointer user_data) {
shoes_GApp = app;
fprintf(stderr, "shoes_gtk_app_activate called\n");
//fprintf(stderr, "shoes_gtk_app_activate called\n");
//GtkWidget *widget;
//widget = gtk_application_window_new (GTK_APPLICATION (app));
//gtk_widget_show (widget);
Expand All @@ -100,16 +100,16 @@ void shoes_native_init() {
curl_global_init(CURL_GLOBAL_ALL);
#endif
#ifndef SHOES_GTK_WIN32
/* try using gtk_application_new() instead of gtk_init
/* try using linux gtk_application_new() instead of gtk_init
*/
int status;
char *empty = NULL;
shoes_GtkApp = gtk_application_new ("org.gnome.example", G_APPLICATION_FLAGS_NONE);
shoes_GtkApp = gtk_application_new ("com.mvmanila.shoes", G_APPLICATION_FLAGS_NONE);
shoes_GApp = (G_APPLICATION (shoes_GtkApp));
g_signal_connect (shoes_GtkApp, "activate", G_CALLBACK (shoes_gtk_app_activate), NULL);
status = g_application_run (G_APPLICATION (shoes_GtkApp), 0, &empty);
//gtk_init(NULL, NULL);
#else
// windows Shoes <= 3.3.3
gtk_init(NULL, NULL);
#endif
}
Expand Down
7 changes: 7 additions & 0 deletions shoes/native/gtk/gtksystray.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,16 @@ void shoes_native_systray(char *title, char *message, char *path) {
#else
// try older gtk_status_icon for Windows to see what happens
static GtkStatusIcon *stsicon = NULL;
static char *stspath = NULL;
void shoes_native_systray(char *title, char *message, char *path) {
if (stsicon == NULL) {
stsicon = gtk_status_icon_new_from_file(path);
stspath = path;
}
// detect change of icon
if (strcmp(path, stspath)) {
stspath = path;
gtk_status_icon_set_from_file (stsicon, stspath);
}
gtk_status_icon_set_title(stsicon, title);
gtk_status_icon_set_tooltip_text(stsicon, message);
Expand Down
39 changes: 29 additions & 10 deletions shoes/types/systray.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* systray
* Is not really a widget with things you can modifiy
*/
#include "shoes/types/native.h"
#include "shoes/types/systray.h"
Expand All @@ -11,8 +12,7 @@ FUNC_M("+systray", systray, -1);
shoes_systray_init() {
cSystray = rb_define_class_under(cTypes, "Systray", cNative);
rb_define_alloc_func(cSystray, shoes_systray_alloc);
//rb_define_method(cSystray, "width", CASTHOOK(shoes_svghandle_get_width), 0);
//rb_define_method(cSystray, "height", CASTHOOK(shoes_svghandle_get_height), 0);
// no methods
RUBY_M("+systray", systray, -1);
}

Expand Down Expand Up @@ -48,24 +48,43 @@ VALUE shoes_systray_alloc(VALUE klass) {
VALUE shoes_systray_new(int argc, VALUE *argv, VALUE parent) {
// Get Ruby args.
VALUE rbtitle, rbmessage, rbpath;
rbtitle = shoes_hash_get(argv[0], rb_intern("title"));
rbmessage = shoes_hash_get(argv[0], rb_intern("message"));
rbpath = shoes_hash_get(argv[0], rb_intern("icon"));
if (argc == 1) {
rbtitle = shoes_hash_get(argv[0], rb_intern("title"));
rbmessage = shoes_hash_get(argv[0], rb_intern("message"));
rbpath = shoes_hash_get(argv[0], rb_intern("icon"));
} else if (argc == 3) {
rbtitle = argv[0];
rbmessage = argv[1];
rbpath = argv[2];
} else {
rb_raise(rb_eArgError, "Missing an argument to systray");
}
char *title = NULL, *message = NULL, *path = NULL;

// Alloc the object and init
/* Alloc the object and init. We do keep a copy of the strings
* which will be garbage collected in at some point by Ruby
* Assumes the strings and pixbugs in the native are copied
* out of our process memory into the Desktop's space.
*/
VALUE obj = shoes_systray_alloc(cSystray);
shoes_systray *self_t;
Data_Get_Struct(obj, shoes_systray, self_t);
Check_Type(rbtitle, T_STRING);
if ((!NIL_P(rbtitle)) && (RSTRING_LEN(rbtitle) > 0)) {
title = strdup(RSTRING_PTR(rbtitle));
title = self_t->title = strdup(RSTRING_PTR(rbtitle));
}
Check_Type(rbmessage, T_STRING);
if ((!NIL_P(rbmessage)) && (RSTRING_LEN(rbmessage) > 0)) {
message = strdup(RSTRING_PTR(rbmessage));
message = self_t->message = strdup(RSTRING_PTR(rbmessage));
}
Check_Type(rbpath, T_STRING);
if ((!NIL_P(rbpath)) && (RSTRING_LEN(rbpath) > 0)) {
path = strdup(RSTRING_PTR(rbpath));
path = self_t->icon_path =strdup(RSTRING_PTR(rbpath));
}
if (path == NULL || message == NULL || title == NULL) {
rb_raise(rb_eArgError, "Bad arguments to systray");
}
// call the native widget
shoes_native_systray(title, message, path); // temporary
shoes_native_systray(title, message, path);
return Qnil;
}
49 changes: 49 additions & 0 deletions static/manual-en.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4423,6 +4423,55 @@ end
note that the method returns the drawing code (text) of the snapshot, so
you might take further control about details of your svg image for example.

== Systray ==

Systray allows you to send an icon and a text message to the desktop manager
which will be shown where the platform decides it should be (systray for Windows),
Notification area for Linux and OSX. Typically, you would call it for some
long running process, like a email client that got a new message and you the desktop
to know about it.

This is not a widget you can modify. There are no methods other than creating it
and that will return nil (even when it works). There is no guarantee it will work,
particularly if you call it too often and expect everything to show up. That's up to
the OS and Desktop manager, not Shoes.

You can call it in two ways, with positional arguments or with a hash of arguments.


=== systray <string>, <string>, <string> » nil ===

The first string is the title, the second is the message to display and the
third string is a file path to the icon. The example below describes the preferred
way

=== systray title: <string>, message: <string>, icon: <file path> » nil ===

You can also use a hash of arguments. The example below is worth some study.
{{{
#!ruby
Shoes.app do
stack do
para "Press button and look in your systems notication area"
ctr = 0;
button "Notify" do
ctr += 1
icp = ''
if ctr % 3 != 0
icp = "#{DIR}/static/shoes-icon.png"
else
icp = "#{DIR}/static/shoes-icon-red.png"
end
systray title: "Shoes Notify", message: "message ##{ctr}", icon: icp
end
end
end
}}}

Notice how we change the message: and every third click, the icon changes.
Changes to the title: may not appear, depending on your platform so you
not change change it. All three arguments must be included.

== TextBlock ==

The TextBlock object represents a group of text organized as a single element.
Expand Down

0 comments on commit 1ec0106

Please sign in to comment.