1
0
mirror of https://github.com/moparisthebest/FireTray synced 2025-01-06 11:08:04 -05:00

* Linux: fix return value according to return type definitions for some

ctypes callbacks, thus avoiding "expected type int, got (void 0)".
* Cleaning.
This commit is contained in:
foudfou 2014-10-08 23:19:19 +02:00
parent e2448d4ae8
commit 0cfe58e410
4 changed files with 86 additions and 39 deletions

View File

@ -16,7 +16,8 @@ var EXPORTED_SYMBOLS =
"FIRETRAY_DELAY_NOWAIT_MILLISECONDS", "FIRETRAY_MESSAGE_COUNT_TYPE_UNREAD",
"FIRETRAY_MESSAGE_COUNT_TYPE_NEW", "FIRETRAY_CHAT_ICON_BLINK_STYLE_NORMAL",
"FIRETRAY_CHAT_ICON_BLINK_STYLE_FADE", "FIRETRAY_APP_DB",
"FIRETRAY_XUL_ATTRIBUTE_COMMAND", "FIRETRAY_XUL_ATTRIBUTE_ONCOMMAND" ];
"FIRETRAY_XUL_ATTRIBUTE_COMMAND", "FIRETRAY_XUL_ATTRIBUTE_ONCOMMAND",
"FIRETRAY_CB_SENTINEL" ];
const Cc = Components.classes;
const Ci = Components.interfaces;
@ -91,6 +92,28 @@ const FIRETRAY_APP_DB = {
};
/*
* Debugging purpose: if a callback fails (like "expected type int, got (void
* 0)"), there is no easy way to find out which (for ex. when called through
* g_signal_connect()). A possible way is to remove the sentinel definition on
* each callback definition one-by-one. For ex:
*
* let callback = gtk.GCallbackWidgetFocusEvent_t(
* firetray.Window.onFocusIn, null, FIRETRAY_CB_SENTINEL);
*
* becomes
*
* let callback = gtk.GCallbackWidgetFocusEvent_t(
* firetray.Window.onFocusIn);
*
* and see if the the message "JavaScript callback failed, and an error
* sentinel was not specified" appears in the console.
*
* Note: it's not possible to define a sentinel when the return type is void.
* Note: almost all return types end up as int's (even gboolean).
*/
const FIRETRAY_CB_SENTINEL = -1;
/**
* firetray namespace.
*/

View File

@ -33,33 +33,41 @@ firetray.PopupMenu = {
var addMenuSeparator = false;
if (firetray.Handler.inMailApp) {
this.addItem("ResetIcon", "gtk-apply", "activate", firetray.Handler.setIconImageDefault);
this.addItem("NewMessage", "gtk-edit", "activate", firetray.Handler.openMailMessage);
this.addItem("ResetIcon", "gtk-apply", "activate",
firetray.Handler.setIconImageDefault);
this.addItem("NewMessage", "gtk-edit", "activate",
firetray.Handler.openMailMessage);
addMenuSeparator = true;
}
if (firetray.Handler.inBrowserApp) {
this.addItem("NewWindow", "gtk-new", "activate", firetray.Handler.openBrowserWindow);
this.addItem("NewWindow", "gtk-new", "activate",
firetray.Handler.openBrowserWindow);
addMenuSeparator = true;
}
var menuSeparator;
if (addMenuSeparator) {
menuSeparator = gtk.gtk_separator_menu_item_new();
gtk.gtk_menu_shell_append(this.menuShell, ctypes.cast(menuSeparator, gtk.GtkWidget.ptr));
gtk.gtk_menu_shell_append(this.menuShell, ctypes.cast(menuSeparator,
gtk.GtkWidget.ptr));
}
this.addItem("Preferences", "gtk-preferences", "activate", firetray.Handler.openPrefWindow);
this.addItem("Preferences", "gtk-preferences", "activate",
firetray.Handler.openPrefWindow);
menuSeparator = gtk.gtk_separator_menu_item_new();
gtk.gtk_menu_shell_append(this.menuShell, ctypes.cast(menuSeparator, gtk.GtkWidget.ptr));
gtk.gtk_menu_shell_append(this.menuShell, ctypes.cast(menuSeparator,
gtk.GtkWidget.ptr));
this.addItem("Quit", "gtk-quit", "activate", firetray.Handler.quitApplication);
this.addItem("Quit", "gtk-quit", "activate",
firetray.Handler.quitApplication);
var menuWidget = ctypes.cast(this.menu, gtk.GtkWidget.ptr);
gtk.gtk_widget_show_all(menuWidget);
var menuSeparatorWindows = gtk.gtk_separator_menu_item_new();
gtk.gtk_menu_shell_prepend(this.menuShell, ctypes.cast(menuSeparatorWindows, gtk.GtkWidget.ptr));
gtk.gtk_menu_shell_prepend(this.menuShell, ctypes.cast(menuSeparatorWindows,
gtk.GtkWidget.ptr));
this.menuSeparatorWindows = menuSeparatorWindows;
this.initialized = true;
@ -84,7 +92,7 @@ firetray.PopupMenu = {
let cbName = "menuItem"+capitalizeFirst(itemName)+capitalizeFirst(action);
log.debug("cbName="+cbName);
this.callbacks[cbName] = gobject.GCallback_t(callback);
this.callbacks[cbName] = gobject.GCallback_t(callback); // void return, no sentinel
gobject.g_signal_connect(menuItem, action,
firetray.PopupMenu.callbacks[cbName], null);
},
@ -93,34 +101,37 @@ firetray.PopupMenu = {
log.debug("menu-popup");
log.debug("ARGS="+icon+", "+button+", "+activateTime+", "+menu);
try {
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.error(x); }
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);
let stopPropagation = false;
return stopPropagation;
},
// we'll be creating menuItems for windows (and not showing them) even if
// hides_single_window is false, because if hides_single_window becomes true,
// we'll just have to show the menuItems
addWindowItem: function(xid) { // on registerWindow
log.warn("addWindowItem");
var menuItemWindow = this.createAndAddItemToMenu();
firetray.Handler.gtkPopupMenuWindowItems.insert(xid, menuItemWindow);
this.setWindowItemLabel(menuItemWindow, xid.toString()); // default to xid
this.callbacks.menuItemWindowActivate[xid] = gobject.GCallback_t(
function(){firetray.Handler.showWindow(xid);});
gobject.g_signal_connect(menuItemWindow, "activate",
firetray.PopupMenu.callbacks.menuItemWindowActivate[xid], null);
let callback = gobject.GCallback_t(
function(){firetray.Handler.showWindow(xid);}, null, FIRETRAY_CB_SENTINEL); // void return, no sentinel
this.callbacks.menuItemWindowActivate[xid] = callback,
gobject.g_signal_connect(menuItemWindow, "activate", callback, null);
log.debug("added gtkPopupMenuWindowItems: "+firetray.Handler.gtkPopupMenuWindowItems.count);
},
createAndAddItemToMenu: function() {
var menuItem = gtk.gtk_image_menu_item_new();
gtk.gtk_menu_shell_prepend(this.menuShell, ctypes.cast(menuItem, gtk.GtkWidget.ptr));
gtk.gtk_menu_shell_prepend(this.menuShell, ctypes.cast(menuItem,
gtk.GtkWidget.ptr));
return menuItem;
},

View File

@ -128,22 +128,23 @@ firetray.StatusIcon = {
/* NOTE: here we do use a function handler (instead of a function
definition) because we need the args passed to it ! As a consequence, we
need to abandon 'this' in PopupMenu.popup() */
this.callbacks.menuPopup = gtk.GCallbackMenuPopup_t(firetray.PopupMenu.popup);
this.callbacks.menuPopup = gtk.GCallbackMenuPopup_t(firetray.PopupMenu.popup); // void return, no sentinel
gobject.g_signal_connect(this.trayIcon, "popup-menu",
firetray.StatusIcon.callbacks.menuPopup, firetray.PopupMenu.menu);
this.callbacks.onScroll = gtk.GCallbackOnScroll_t(firetray.StatusIcon.onScroll);
this.callbacks.onScroll = gtk.GCallbackOnScroll_t(
firetray.StatusIcon.onScroll, null, FIRETRAY_CB_SENTINEL);
gobject.g_signal_connect(this.trayIcon, "scroll-event",
firetray.StatusIcon.callbacks.onScroll, null);
log.debug("showHideAllWindows: "+firetray.Handler.hasOwnProperty("showHideAllWindows"));
this.callbacks.iconActivate = gtk.GCallbackStatusIconActivate_t(
firetray.StatusIcon.onClick);
firetray.StatusIcon.onClick, null, FIRETRAY_CB_SENTINEL);
let handlerId = gobject.g_signal_connect(firetray.StatusIcon.trayIcon,
"activate", firetray.StatusIcon.callbacks.iconActivate, null);
log.debug("g_connect activate="+handlerId);
this.callbacks.iconMiddleClick = gtk.GCallbackStatusIconMiddleClick_t(
firetray.Handler.activateLastWindowCb);
firetray.Handler.activateLastWindowCb, null, FIRETRAY_CB_SENTINEL);
handlerId = gobject.g_signal_connect(firetray.StatusIcon.trayIcon,
"button-press-event", firetray.StatusIcon.callbacks.iconMiddleClick, null);
log.debug("g_connect middleClick="+handlerId);
@ -151,7 +152,7 @@ firetray.StatusIcon = {
onScroll: function(icon, event, data) {
if (!firetray.Utils.prefService.getBoolPref("scroll_hides"))
return;
return false;
let iconGpointer = ctypes.cast(icon, gobject.gpointer);
let gdkEventScroll = ctypes.cast(event, gdk.GdkEventScroll.ptr);
@ -176,6 +177,9 @@ firetray.StatusIcon = {
default:
log.error("SCROLL UNKNOWN");
}
let stopPropagation = false;
return stopPropagation;
},
onClick: function(gtkStatusIcon, userData) {

View File

@ -86,7 +86,7 @@ firetray.Window.shutdown = function() {
* Iterate over all Gtk toplevel windows to find a window. We rely on
* Service.wm to watch windows correctly: we should find only one window.
*
* @author Nils Maier (stolen from MiniTrayR)
* @author Nils Maier (stolen from MiniTrayR), himself inspired by Windows docs
* @param window nsIDOMWindow from Services.wm
* @return a gtk.GtkWindow.ptr
*/
@ -105,7 +105,7 @@ firetray.Window.getGtkWindowFromChromeWindow = function(window) {
// Search the window by the *temporary* title
let widgets = gtk.gtk_window_list_toplevels();
let that = this;
let findGtkWindowByTitleCb = gobject.GFunc_t(that._findGtkWindowByTitle);
let findGtkWindowByTitleCb = gobject.GFunc_t(that._findGtkWindowByTitle); // void return, no sentinel
var userData = new _find_data_t(
ctypes.char.array()(baseWindow.title),
null
@ -590,18 +590,22 @@ firetray.Window.showAllWindowsAndActivate = function() {
firetray.Window.attachOnFocusInCallback = function(xid) {
log.debug("attachOnFocusInCallback xid="+xid);
this.signals['focus-in'].callback[xid] =
gtk.GCallbackWidgetFocusEvent_t(firetray.Window.onFocusIn);
this.signals['focus-in'].handler[xid] = gobject.g_signal_connect(
firetray.Handler.gtkWindows.get(xid), "focus-in-event",
firetray.Window.signals['focus-in'].callback[xid], null);
log.debug("focus-in handler="+this.signals['focus-in'].handler[xid]);
let callback = gtk.GCallbackWidgetFocusEvent_t(
firetray.Window.onFocusIn, null, FIRETRAY_CB_SENTINEL);
this.signals['focus-in'].callback[xid] = callback;
let rv = gobject.g_signal_connect(
firetray.Handler.gtkWindows.get(xid), "focus-in-event", callback, null);
log.debug("focus-in handler="+rv);
this.signals['focus-in'].handler[xid] = rv;
};
firetray.Window.detachOnFocusInCallback = function(xid) {
log.debug("detachOnFocusInCallback xid="+xid);
let gtkWin = firetray.Handler.gtkWindows.get(xid);
gobject.g_signal_handler_disconnect(gtkWin, this.signals['focus-in'].handler[xid]);
gobject.g_signal_handler_disconnect(
gtkWin,
gobject.gulong(this.signals['focus-in'].handler[xid])
);
delete this.signals['focus-in'].callback[xid];
delete this.signals['focus-in'].handler[xid];
};
@ -619,6 +623,9 @@ firetray.Window.onFocusIn = function(widget, event, data) {
if (firetray.Handler.isChatEnabled() && firetray.Chat.initialized) {
firetray.Chat.stopGetAttentionMaybe(xid);
}
let stopPropagation = false;
return stopPropagation;
};
@ -660,10 +667,12 @@ firetray.Handler.registerWindow = function(win) {
// delete_event_cb (in gtk2/nsWindow.cpp), but we prefer to use the
// provided 'close' JS event
this.windows[xid].filterWindowCb = gdk.GdkFilterFunc_t(firetray.Window.filterWindow);
this.windows[xid].filterWindowCb = gdk.GdkFilterFunc_t(
firetray.Window.filterWindow, null, FIRETRAY_CB_SENTINEL);
gdk.gdk_window_add_filter(gdkWin, this.windows[xid].filterWindowCb, null);
if (!firetray.Handler.appStarted) {
this.windows[xid].startupFilterCb = gdk.GdkFilterFunc_t(firetray.Window.startupFilter);
this.windows[xid].startupFilterCb = gdk.GdkFilterFunc_t(
firetray.Window.startupFilter, null, FIRETRAY_CB_SENTINEL);
gdk.gdk_window_add_filter(gdkWin, this.windows[xid].startupFilterCb, null);
}
@ -673,8 +682,8 @@ firetray.Handler.registerWindow = function(win) {
}
} catch (x) {
firetray.Window.unregisterWindowByXID(xid);
log.error(x);
firetray.Window.unregisterWindowByXID(xid);
return null;
}