This commit is contained in:
foudfou 2011-09-20 10:43:02 +02:00
parent 835f4055aa
commit a02129828c
2 changed files with 159 additions and 137 deletions

View File

@ -138,22 +138,6 @@ mozt.Handler = {
}, // showHideToTray
popupMenu: function(icon, button, activateTime, menu) {
LOG("MENU POPUP");
LOG("ARGS="+icon+", "+button+", "+activateTime+", "+menu);
try {
// TODO: move to MoztIconLinux
var gtkMenuPtr = ctypes.cast(menu, gtk.GtkMenu.ptr);
var iconGpointer = ctypes.cast(icon, gobject.gpointer);
gtk.gtk_menu_popup(
gtkMenuPtr, null, null, gtk.gtk_status_icon_position_menu,
iconGpointer, button, activateTime);
} catch (x) {
LOG(x);
}
},
quitApplication: function() {
try {
let appStartup = Cc['@mozilla.org/toolkit/app-startup;1']

View File

@ -34,9 +34,7 @@ mozt.IconLinux = {
MIN_FONT_SIZE: 4,
init: function() {
try {
// init tray icon, some variables
this.trayIcon = gtk.gtk_status_icon_new();
this.appName = Services.appinfo.name.toLowerCase();
@ -44,45 +42,25 @@ mozt.IconLinux = {
"chrome://moztray/skin/" + this.appName + this.FILENAME_SUFFIX);
this.FILENAME_NEWMAIL = mozt.Utils.chromeToPath(
"chrome://moztray/skin/newmail.png");
} catch (x) {
ERROR(x);
return false;
}
this.setImageDefault();
this.setImageDefault();
// build icon popup menu
this.menu = gtk.gtk_menu_new();
// shouldn't need to convert to utf8 thank to js-ctypes
var menuItemQuitLabel = mozt.Utils.strings.GetStringFromName("popupMenu.itemLabel.Quit");
var menuItemQuit = gtk.gtk_image_menu_item_new_with_label(
menuItemQuitLabel);
var menuItemQuitIcon = gtk.gtk_image_new_from_stock(
"gtk-quit", gtk.GTK_ICON_SIZE_MENU);
gtk.gtk_image_menu_item_set_image(menuItemQuit, menuItemQuitIcon);
var menuShell = ctypes.cast(this.menu, gtk.GtkMenuShell.ptr);
gtk.gtk_menu_shell_append(menuShell, menuItemQuit);
this._buildPopupMenu();
mozt_menuItemQuitActivateCb = gobject.GCallback_t(
function(){mozt.Handler.quitApplication();});
gobject.g_signal_connect(menuItemQuit, "activate",
mozt_menuItemQuitActivateCb, null);
var menuWidget = ctypes.cast(this.menu, gtk.GtkWidget.ptr);
gtk.gtk_widget_show_all(menuWidget);
// here we do use a function handler because we need the args passed to
// it ! But we need to abandon 'this' in popupMenu()
mozt_popupMenuCb =
gtk.GCallbackMenuPopup_t(mozt.Handler.popupMenu);
gobject.g_signal_connect(this.trayIcon, "popup-menu",
mozt_popupMenuCb, this.menu);
this.setTooltipDefault();
this.setTooltipDefault();
// attach popupMenu to trayIcon
try {
// watch out for binding problems ! here we prefer to keep 'this' in
// showHideToTray() and abandon the args.
mozt_iconActivateCb = gobject.GCallback_t(
function(){mozt.Handler.showHideToTray();});
gobject.g_signal_connect(this.trayIcon, "activate",
mozt_iconActivateCb, null);
mozt_iconActivateCb, null);
} catch (x) {
ERROR(x);
return false;
@ -92,10 +70,58 @@ mozt.IconLinux = {
},
shutdown: function() {
cairo.close();
// glib.close();
gobject.close();
gdk.close();
gtk.close();
// glib.close();
pango.close();
},
_buildPopupMenu: function() {
this.menu = gtk.gtk_menu_new();
// shouldn't need to convert to utf8 thank to js-ctypes
var menuItemQuitLabel = mozt.Utils.strings.GetStringFromName("popupMenu.itemLabel.Quit");
var menuItemQuit = gtk.gtk_image_menu_item_new_with_label(
menuItemQuitLabel);
var menuItemQuitIcon = gtk.gtk_image_new_from_stock(
"gtk-quit", gtk.GTK_ICON_SIZE_MENU);
gtk.gtk_image_menu_item_set_image(menuItemQuit, menuItemQuitIcon);
var menuShell = ctypes.cast(this.menu, gtk.GtkMenuShell.ptr);
gtk.gtk_menu_shell_append(menuShell, menuItemQuit);
mozt_menuItemQuitActivateCb = gobject.GCallback_t(
function(){mozt.Handler.quitApplication();});
gobject.g_signal_connect(menuItemQuit, "activate",
mozt_menuItemQuitActivateCb, null);
var menuWidget = ctypes.cast(this.menu, gtk.GtkWidget.ptr);
gtk.gtk_widget_show_all(menuWidget);
/* NOTE: here we do use a function handler (instead of a function
* definition) because we need the args passed to it ! On the other hand
* we need to abandon 'this' in popupMenu() */
let that = this;
mozt_popupMenuCb =
gtk.GCallbackMenuPopup_t(that.popupMenu);
gobject.g_signal_connect(this.trayIcon, "popup-menu",
mozt_popupMenuCb, this.menu);
},
popupMenu: function(icon, button, activateTime, menu) {
LOG("MENU POPUP");
LOG("ARGS="+icon+", "+button+", "+activateTime+", "+menu);
try {
// TODO: move to MoztIconLinux
var gtkMenuPtr = ctypes.cast(menu, gtk.GtkMenu.ptr);
var iconGpointer = ctypes.cast(icon, gobject.gpointer);
gtk.gtk_menu_popup(
gtkMenuPtr, null, null, gtk.gtk_status_icon_position_menu,
iconGpointer, button, activateTime);
} catch (x) {
LOG(x);
}
},
setImage: function(filename) {
@ -123,8 +149,14 @@ mozt.IconLinux = {
setTooltip: function(toolTipStr) {
if (!this.trayIcon)
return false;
gtk.gtk_status_icon_set_tooltip_text(this.trayIcon,
toolTipStr);
try {
gtk.gtk_status_icon_set_tooltip_text(this.trayIcon,
toolTipStr);
} catch (x) {
ERROR(x);
return false;
}
return true;
},
@ -141,98 +173,104 @@ mozt.IconLinux = {
return false;
}
// build background from image
let specialIcon = gdk.gdk_pixbuf_new_from_file(this.FILENAME_NEWMAIL, null); // GError **error);
let dest = gdk.gdk_pixbuf_copy(specialIcon);
let w = gdk.gdk_pixbuf_get_width(specialIcon);
let h = gdk.gdk_pixbuf_get_height(specialIcon);
try {
// build background from image
let specialIcon = gdk.gdk_pixbuf_new_from_file(this.FILENAME_NEWMAIL, null); // GError **error);
let dest = gdk.gdk_pixbuf_copy(specialIcon);
let w = gdk.gdk_pixbuf_get_width(specialIcon);
let h = gdk.gdk_pixbuf_get_height(specialIcon);
// prepare colors/alpha
let colorMap = gdk.gdk_screen_get_system_colormap(gdk.gdk_screen_get_default());
let visual = gdk.gdk_colormap_get_visual(colorMap);
let visualDepth = gdk.gdk_visual_get_depth(visual);
LOG("colorMap="+colorMap+" visual="+visual+" visualDepth="+visualDepth);
let fore = new gdk.GdkColor;
fore.pixel = fore.red = fore.green = fore.blue = 0;
let alpha = new gdk.GdkColor;
alpha.pixel = alpha.red = alpha.green = alpha.blue = 0xFFFF;
if (!fore || !alpha)
WARN("Undefined GdkColor fore or alpha");
gdk.gdk_color_parse(color, fore.address());
if(fore.red == alpha.red && fore.green == alpha.green && fore.blue == alpha.blue) {
alpha.red=0; // make sure alpha is different from fore
}
gdk.gdk_colormap_alloc_color(colorMap, fore.address(), true, true);
gdk.gdk_colormap_alloc_color(colorMap, alpha.address(), true, true);
// build pixmap with rectangle
let pm = gdk.gdk_pixmap_new(null, w, h, visualDepth);
let pmDrawable = ctypes.cast(pm, gdk.GdkDrawable.ptr);
let cr = gdk.gdk_cairo_create(pmDrawable);
gdk.gdk_cairo_set_source_color(cr, alpha.address());
cairo.cairo_rectangle(cr, 0, 0, w, h);
cairo.cairo_set_source_rgb(cr, 1, 1, 1);
cairo.cairo_fill(cr);
// build text
let scratch = gtk.gtk_window_new(gtk.GTK_WINDOW_TOPLEVEL);
let layout = gtk.gtk_widget_create_pango_layout(scratch, null);
gtk.gtk_widget_destroy(scratch);
let fnt = pango.pango_font_description_from_string("Sans 18");
pango.pango_font_description_set_weight(fnt,pango.PANGO_WEIGHT_SEMIBOLD);
pango.pango_layout_set_spacing(layout,0);
pango.pango_layout_set_font_description(layout, fnt);
LOG("layout="+layout);
LOG("text="+text);
pango.pango_layout_set_text(layout, text,-1);
let tw = new ctypes.int;
let th = new ctypes.int;
let sz;
let border = 4;
pango.pango_layout_get_pixel_size(layout, tw.address(), th.address());
LOG("tw="+tw.value+" th="+th.value);
// fit text to the icon by decreasing font size
while ( tw.value > (w - border) || th.value > (h - border) ) {
sz = pango.pango_font_description_get_size(fnt);
if(sz < this.MIN_FONT_SIZE) {
sz = this.MIN_FONT_SIZE;
break;
// prepare colors/alpha
let colorMap = gdk.gdk_screen_get_system_colormap(gdk.gdk_screen_get_default());
let visual = gdk.gdk_colormap_get_visual(colorMap);
let visualDepth = gdk.gdk_visual_get_depth(visual);
LOG("colorMap="+colorMap+" visual="+visual+" visualDepth="+visualDepth);
let fore = new gdk.GdkColor;
fore.pixel = fore.red = fore.green = fore.blue = 0;
let alpha = new gdk.GdkColor;
alpha.pixel = alpha.red = alpha.green = alpha.blue = 0xFFFF;
if (!fore || !alpha)
WARN("Undefined GdkColor fore or alpha");
gdk.gdk_color_parse(color, fore.address());
if(fore.red == alpha.red && fore.green == alpha.green && fore.blue == alpha.blue) {
alpha.red=0; // make sure alpha is different from fore
}
sz -= pango.PANGO_SCALE;
pango.pango_font_description_set_size(fnt,sz);
gdk.gdk_colormap_alloc_color(colorMap, fore.address(), true, true);
gdk.gdk_colormap_alloc_color(colorMap, alpha.address(), true, true);
// build pixmap with rectangle
let pm = gdk.gdk_pixmap_new(null, w, h, visualDepth);
let pmDrawable = ctypes.cast(pm, gdk.GdkDrawable.ptr);
let cr = gdk.gdk_cairo_create(pmDrawable);
gdk.gdk_cairo_set_source_color(cr, alpha.address());
cairo.cairo_rectangle(cr, 0, 0, w, h);
cairo.cairo_set_source_rgb(cr, 1, 1, 1);
cairo.cairo_fill(cr);
// build text
let scratch = gtk.gtk_window_new(gtk.GTK_WINDOW_TOPLEVEL);
let layout = gtk.gtk_widget_create_pango_layout(scratch, null);
gtk.gtk_widget_destroy(scratch);
let fnt = pango.pango_font_description_from_string("Sans 18");
pango.pango_font_description_set_weight(fnt,pango.PANGO_WEIGHT_SEMIBOLD);
pango.pango_layout_set_spacing(layout,0);
pango.pango_layout_set_font_description(layout, fnt);
LOG("layout="+layout);
LOG("text="+text);
pango.pango_layout_set_text(layout, text,-1);
let tw = new ctypes.int;
let th = new ctypes.int;
let sz;
let border = 4;
pango.pango_layout_get_pixel_size(layout, tw.address(), th.address());
LOG("tw="+tw.value+" th="+th.value);
// fit text to the icon by decreasing font size
while ( tw.value > (w - border) || th.value > (h - border) ) {
sz = pango.pango_font_description_get_size(fnt);
if(sz < this.MIN_FONT_SIZE) {
sz = this.MIN_FONT_SIZE;
break;
}
sz -= pango.PANGO_SCALE;
pango.pango_font_description_set_size(fnt,sz);
pango.pango_layout_set_font_description(layout, fnt);
pango.pango_layout_get_pixel_size(layout, tw.address(), th.address());
}
LOG("tw="+tw.value+" th="+th.value);
pango.pango_font_description_free(fnt);
// center text
let px = (w-tw.value)/2;
let py = (h-th.value)/2;
// draw text on pixmap
gdk.gdk_cairo_set_source_color(cr, fore.address());
cairo.cairo_move_to(cr, px, py);
pangocairo.pango_cairo_show_layout(cr, layout);
cairo.cairo_destroy(cr);
gobject.g_object_unref(layout);
let buf = gdk.gdk_pixbuf_get_from_drawable(null, pmDrawable, null, 0, 0, 0, 0, w, h);
gobject.g_object_unref(pm);
LOG("alpha="+alpha);
let alphaRed = gobject.guint16(alpha.red);
let alphaRed_guchar = ctypes.cast(alphaRed, gobject.guchar);
let alphaGreen = gobject.guint16(alpha.green);
let alphaGreen_guchar = ctypes.cast(alphaGreen, gobject.guchar);
let alphaBlue = gobject.guint16(alpha.blue);
let alphaBlue_guchar = ctypes.cast(alphaBlue, gobject.guchar);
let bufAlpha = gdk.gdk_pixbuf_add_alpha(buf, true, alphaRed_guchar, alphaGreen_guchar, alphaBlue_guchar);
gobject.g_object_unref(buf);
// merge the rendered text on top
gdk.gdk_pixbuf_composite(bufAlpha,dest,0,0,w,h,0,0,1,1,gdk.GDK_INTERP_NEAREST,255);
gobject.g_object_unref(bufAlpha);
gtk.gtk_status_icon_set_from_pixbuf(this.trayIcon, dest);
} catch (x) {
ERROR(x);
return false;
}
LOG("tw="+tw.value+" th="+th.value);
pango.pango_font_description_free(fnt);
// center text
let px = (w-tw.value)/2;
let py = (h-th.value)/2;
// draw text on pixmap
gdk.gdk_cairo_set_source_color(cr, fore.address());
cairo.cairo_move_to(cr, px, py);
pangocairo.pango_cairo_show_layout(cr, layout);
cairo.cairo_destroy(cr);
gobject.g_object_unref(layout);
let buf = gdk.gdk_pixbuf_get_from_drawable(null, pmDrawable, null, 0, 0, 0, 0, w, h);
gobject.g_object_unref(pm);
LOG("alpha="+alpha);
let alphaRed = gobject.guint16(alpha.red);
let alphaRed_guchar = ctypes.cast(alphaRed, gobject.guchar);
let alphaGreen = gobject.guint16(alpha.green);
let alphaGreen_guchar = ctypes.cast(alphaGreen, gobject.guchar);
let alphaBlue = gobject.guint16(alpha.blue);
let alphaBlue_guchar = ctypes.cast(alphaBlue, gobject.guchar);
let bufAlpha = gdk.gdk_pixbuf_add_alpha(buf, true, alphaRed_guchar, alphaGreen_guchar, alphaBlue_guchar);
gobject.g_object_unref(buf);
// merge the rendered text on top
gdk.gdk_pixbuf_composite(bufAlpha,dest,0,0,w,h,0,0,1,1,gdk.GDK_INTERP_NEAREST,255);
gobject.g_object_unref(bufAlpha);
gtk.gtk_status_icon_set_from_pixbuf(this.trayIcon, dest);
}
}; // mozt.IconLinux