mirror of
https://github.com/moparisthebest/FireTray
synced 2024-11-15 05:15:01 -05:00
* complete per-window registration and show/hide handeling
* fix storage of Gdk-/GtkWindows pointers (ctypesMap.jsm)
This commit is contained in:
parent
6b4fd546d2
commit
aadf727816
@ -24,7 +24,10 @@ var firetrayChrome = {
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG("Handler initialized: "+firetray.Handler.initialized);
|
||||
let init = firetray.Handler.initialized || firetray.Handler.init();
|
||||
|
||||
LOG("ONLOAD"); firetray.Handler.dumpWindows();
|
||||
firetray.Handler.registerWindow(win);
|
||||
|
||||
// update unread messages count
|
||||
@ -55,15 +58,19 @@ var firetrayChrome = {
|
||||
// TODO: prevent preceding warning about closing multiple tabs (browser.tabs.warnOnClose)
|
||||
onClose: function(event) {
|
||||
LOG('Firetray CLOSE');
|
||||
let win = event.originalTarget;
|
||||
if (!win instanceof ChromeWindow)
|
||||
throw new TypeError('originalTarget not a ChromeWindow');
|
||||
|
||||
let hides_on_close = firetray.Utils.prefService.getBoolPref('hides_on_close');
|
||||
let hides_single_window = firetray.Utils.prefService.getBoolPref('hides_single_window');
|
||||
LOG('hides_on_close: '+hides_on_close+', hides_single_window='+hides_single_window);
|
||||
LOG('event.originalTarget: '+event.originalTarget);
|
||||
if (hides_on_close) {
|
||||
if (hides_single_window)
|
||||
firetray.Window.hideWindow(window);
|
||||
else
|
||||
firetray.Handler.hideAllWindows(window);
|
||||
if (hides_single_window) {
|
||||
let winId = firetray.Handler.getWindowIdFromChromeWindow(win);
|
||||
firetray.Handler.hideSingleWindow(winId);
|
||||
} else
|
||||
firetray.Handler.hideAllWindows();
|
||||
event && event.preventDefault(); // no event when called directly (xul)
|
||||
}
|
||||
},
|
||||
|
@ -5,7 +5,7 @@
|
||||
<em:unpack>true</em:unpack> <!-- needed for embedded icons -->
|
||||
<em:type>2</em:type>
|
||||
<em:name>FireTray</em:name>
|
||||
<em:version>0.4.0a5</em:version>
|
||||
<em:version>0.4.0a6</em:version>
|
||||
<em:creator>Hua Luo, Francesco Solero, Foudil BRÉTEL</em:creator>
|
||||
<em:contributor>Hua Luo, Francesco Solero (Firetray original authors)</em:contributor>
|
||||
<em:homepageURL>https://github.com/foudfou/firetray</em:homepageURL>
|
||||
|
@ -20,7 +20,7 @@ if ("undefined" == typeof(firetray)) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Singleton object and abstraction for tray icon management.
|
||||
* Singleton object and abstraction for windows and tray icon management.
|
||||
*/
|
||||
// NOTE: modules work outside of the window scope. Unlike scripts in the
|
||||
// chrome, modules don't have access to objects such as window, document, or
|
||||
@ -35,7 +35,9 @@ firetray.Handler = {
|
||||
FILENAME_NEWMAIL: null,
|
||||
runtimeOS: null,
|
||||
inMailApp: false,
|
||||
windows: [],
|
||||
windows: {},
|
||||
windowsCount: 0,
|
||||
visibleWindowsCount: 0,
|
||||
|
||||
init: function() { // does creates icon
|
||||
this.appName = Services.appinfo.name.toLowerCase();
|
||||
@ -58,17 +60,16 @@ firetray.Handler = {
|
||||
LOG('FiretrayStatusIcon imported');
|
||||
Cu.import("resource://firetray/gtk2/FiretrayWindow.jsm");
|
||||
LOG('FiretrayWindow imported');
|
||||
|
||||
// instanciate tray icon
|
||||
firetray.StatusIcon.init();
|
||||
LOG('StatusIcon initialized');
|
||||
|
||||
break;
|
||||
default:
|
||||
ERROR("FIRETRAY: only Linux platform supported at this time. Firetray not loaded");
|
||||
return false;
|
||||
}
|
||||
|
||||
// instanciate tray icon
|
||||
firetray.StatusIcon.init();
|
||||
LOG('StatusIcon initialized');
|
||||
|
||||
// check if in mail app
|
||||
var mozAppId = Services.appinfo.ID;
|
||||
if (mozAppId === THUNDERBIRD_ID || mozAppId === SEAMONKEY_ID) {
|
||||
@ -107,15 +108,30 @@ firetray.Handler = {
|
||||
return true;
|
||||
},
|
||||
|
||||
// these get overridden in OS-specific Icon handlers
|
||||
// these get overridden in OS-specific Window handlers
|
||||
setImage: function(filename) {},
|
||||
setImageDefault: function() {},
|
||||
setText: function(text, color) {},
|
||||
setTooltip: function(localizedMessage) {},
|
||||
setTooltipDefault: function() {},
|
||||
showHideAllWindows: function() {},
|
||||
registerWindow: function(win) {},
|
||||
unregisterWindow: function(win) {},
|
||||
getWindowIdFromChromeWindow: function(win) {},
|
||||
hideSingleWindow: function(winId) {},
|
||||
showSingleWindow: function(winId) {},
|
||||
showHideAllWindows: function() {},
|
||||
|
||||
showAllWindows: function() {
|
||||
for (let winId in firetray.Handler.windows)
|
||||
if (!firetray.Handler.windows[winId].visibility)
|
||||
firetray.Handler.showSingleWindow(winId);
|
||||
},
|
||||
hideAllWindows: function() {
|
||||
for (let winId in firetray.Handler.windows) {
|
||||
if (firetray.Handler.windows[winId].visibility)
|
||||
firetray.Handler.hideSingleWindow(winId);
|
||||
}
|
||||
},
|
||||
|
||||
_getBaseOrXULWindowFromDOMWindow: function(win, winType) {
|
||||
let winInterface, winOut;
|
||||
|
@ -198,3 +198,11 @@ function isEmpty(obj) {
|
||||
function strEquals(obj1, obj2) {
|
||||
return obj1.toString() === obj2.toString();
|
||||
}
|
||||
|
||||
// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Custom_Error_Types
|
||||
function DeleteError(message) {
|
||||
this.name = "DeleteError";
|
||||
this.message = message || "Could not delete object memeber";
|
||||
}
|
||||
DeleteError.prototype = new Error();
|
||||
DeleteError.prototype.constructor = DeleteError;
|
||||
|
68
src/modules/ctypesMap.jsm
Normal file
68
src/modules/ctypesMap.jsm
Normal file
@ -0,0 +1,68 @@
|
||||
/* -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
|
||||
var EXPORTED_SYMBOLS = [ "ctypesMap", "CTYPES_ARRAY_MAX_SIZE" ];
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/ctypes.jsm");
|
||||
Cu.import("resource://firetray/logging.jsm");
|
||||
Cu.import("resource://firetray/commons.js");
|
||||
|
||||
const FIRETRAY_WINDOW_COUNT_MAX = 64;
|
||||
|
||||
/**
|
||||
* basic Hash mapping a key (of any type) to a cell in a ctypes array
|
||||
*/
|
||||
function ctypesMap(t) {
|
||||
this.array = ctypes.ArrayType(t)(FIRETRAY_WINDOW_COUNT_MAX);
|
||||
this.indexLast = -1;
|
||||
this.freedCells = []; // indices of freed cells
|
||||
this.count = 0; // count of actually stored things
|
||||
this.map = {}; // map key -> index
|
||||
};
|
||||
|
||||
ctypesMap.prototype.get = function(key) {
|
||||
if (!this.map.hasOwnProperty(key))
|
||||
throw new RangeError('Unknown key: '+key);
|
||||
|
||||
return this.array[this.map[key]];
|
||||
};
|
||||
|
||||
ctypesMap.prototype.insert = function(key, item) {
|
||||
if (this.map.hasOwnProperty(key)) { // replace
|
||||
LOG("REPLACE");
|
||||
this.array[this.map[key]] = item;
|
||||
|
||||
} else if (this.freedCells.length) {
|
||||
LOG("USE FREE CELL");
|
||||
let idx = this.freedCells.shift();
|
||||
this.array[idx] = item;
|
||||
this.map[key] = idx;
|
||||
this.count += 1;
|
||||
|
||||
} else {
|
||||
let indexNext = this.indexLast + 1;
|
||||
if (indexNext >= FIRETRAY_WINDOW_COUNT_MAX)
|
||||
throw new RangeError('Array overflow');
|
||||
|
||||
this.indexLast = indexNext;
|
||||
this.array[this.indexLast] = item;
|
||||
this.map[key] = this.indexLast;
|
||||
this.count += 1;
|
||||
}
|
||||
};
|
||||
|
||||
ctypesMap.prototype.remove = function(key) {
|
||||
if (!this.map.hasOwnProperty(key))
|
||||
throw new RangeError('Unknown key: '+key);
|
||||
LOG("FREE CELL");
|
||||
|
||||
let idx = this.map[key];
|
||||
if (!delete this.map[key])
|
||||
throw new DeleteError();
|
||||
this.freedCells.unshift(idx);
|
||||
this.count -= 1;
|
||||
};
|
||||
|
@ -112,6 +112,7 @@ firetray.StatusIcon = {
|
||||
|
||||
}; // firetray.StatusIcon
|
||||
|
||||
|
||||
firetray.Handler.setImage = function(filename) {
|
||||
if (!firetray.StatusIcon.trayIcon)
|
||||
return false;
|
||||
|
@ -16,6 +16,7 @@ const Cu = Components.utils;
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/ctypes.jsm");
|
||||
Cu.import("resource://firetray/ctypesMap.jsm");
|
||||
Cu.import("resource://firetray/gobject.jsm");
|
||||
Cu.import("resource://firetray/gdk.jsm");
|
||||
Cu.import("resource://firetray/gtk.jsm");
|
||||
@ -42,95 +43,6 @@ var _find_data_t = ctypes.StructType("_find_data_t", [
|
||||
]);
|
||||
|
||||
|
||||
firetray.Handler.registerWindow = function(win) {
|
||||
LOG("register window");
|
||||
let that = this;
|
||||
|
||||
// register
|
||||
let [gtkWin, gdkWin, xid] = firetray.Window.getWindowsFromChromeWindow(win);
|
||||
this.windows[xid] = {};
|
||||
this.windows[xid].win = win;
|
||||
this.windows[xid].gtkWin = gtkWin;
|
||||
this.windows[xid].gdkWin = gdkWin;
|
||||
LOG("window "+xid+" registered");
|
||||
/* NOTE: it should not be necessary to gtk_widget_add_events(gtkWin,
|
||||
gdk.GDK_ALL_EVENTS_MASK); */
|
||||
|
||||
try {
|
||||
/* NOTE: we could try to catch the "delete-event" here and block
|
||||
delete_event_cb (in gtk2/nsWindow.cpp), but we prefer to use the
|
||||
provided "close" JS event */
|
||||
|
||||
/* we'll catch minimize events with Gtk:
|
||||
http://stackoverflow.com/questions/8018328/what-is-the-gtk-event-called-when-a-window-minimizes */
|
||||
this.windows[xid].windowStateCb = gtk.GCallbackWindowStateEvent_t(firetray.Window.windowState);
|
||||
this.windows[xid].windowStateCbId = gobject.g_signal_connect(gtkWin, "window-state-event", this.windows[xid].windowStateCb, null);
|
||||
LOG("g_connect window-state-event="+this.windows[xid].windowStateCbId);
|
||||
|
||||
} catch (x) {
|
||||
this._unregisterWindowByXID(xid);
|
||||
ERROR(x);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
firetray.Handler.unregisterWindow = function(win) {
|
||||
LOG("unregister window");
|
||||
|
||||
try {
|
||||
let xid = firetray.Window.getXIDFromChromeWindow(win);
|
||||
return this._unregisterWindowByXID(xid);
|
||||
} catch (x) {
|
||||
ERROR(x);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
firetray.Handler._unregisterWindowByXID = function(xid) {
|
||||
try {
|
||||
if (this.windows.hasOwnProperty(xid))
|
||||
delete this.windows[xid];
|
||||
else {
|
||||
ERROR("can't unregister unknown window "+xid);
|
||||
return false;
|
||||
}
|
||||
} catch (x) {
|
||||
ERROR(x);
|
||||
return false;
|
||||
}
|
||||
LOG("window "+xid+" unregistered");
|
||||
return true;
|
||||
};
|
||||
|
||||
firetray.Handler.showSingleWindow = function(xid) {
|
||||
try {
|
||||
// keep z-order - and try to restore previous state
|
||||
LOG("gdkWin="+firetray.Handler.windows[xid].gdkWin);
|
||||
gdk.gdk_window_show_unraised(firetray.Handler.windows[xid].gdkWin);
|
||||
// need to restore *after* showing for correction
|
||||
// firetray.Window._restoreWindowPositionSizeState(xid);
|
||||
} catch (x) {
|
||||
ERROR(x);
|
||||
}
|
||||
};
|
||||
|
||||
firetray.Handler.showHideAllWindows = function(gtkStatusIcon, userData) {
|
||||
LOG("showHideAllWindows: "+userData);
|
||||
|
||||
// NOTE: showHideAllWindows being a callback, we need to use 'firetray.Handler'
|
||||
// explicitely instead of 'this'
|
||||
for (let xid in firetray.Handler.windows) {
|
||||
LOG("show xid="+xid);
|
||||
firetray.Handler.showSingleWindow(xid);
|
||||
}
|
||||
|
||||
let stopPropagation = true;
|
||||
return stopPropagation;
|
||||
};
|
||||
|
||||
|
||||
firetray.Window = {
|
||||
|
||||
/**
|
||||
@ -143,9 +55,9 @@ firetray.Window = {
|
||||
*/
|
||||
getGtkWindowHandle: function(window) {
|
||||
let baseWindow = window
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIBaseWindow);
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIBaseWindow);
|
||||
|
||||
// Tag the base window
|
||||
let oldTitle = baseWindow.title;
|
||||
@ -194,14 +106,10 @@ firetray.Window = {
|
||||
let gtkWin = ctypes.cast(gtkWidget, gtk.GtkWindow.ptr);
|
||||
let winTitle = gtk.gtk_window_get_title(gtkWin);
|
||||
|
||||
try {
|
||||
if (!winTitle.isNull()) {
|
||||
LOG(inTitle+" = "+winTitle);
|
||||
if (libc.strcmp(inTitle, winTitle) == 0)
|
||||
data.contents.outWindow = gtkWin;
|
||||
}
|
||||
} catch (x) {
|
||||
ERROR(x);
|
||||
if (!winTitle.isNull()) {
|
||||
LOG(inTitle+" = "+winTitle);
|
||||
if (libc.strcmp(inTitle, winTitle) == 0)
|
||||
data.contents.outWindow = gtkWin;
|
||||
}
|
||||
},
|
||||
|
||||
@ -232,9 +140,7 @@ firetray.Window = {
|
||||
/** consider using getXIDFromChromeWindow() if you only need the XID */
|
||||
getWindowsFromChromeWindow: function(win) {
|
||||
let gtkWin = firetray.Window.getGtkWindowHandle(win);
|
||||
LOG("gtkWin="+gtkWin);
|
||||
let gdkWin = firetray.Window.getGdkWindowFromGtkWindow(gtkWin);
|
||||
LOG("gdkWin="+gdkWin);
|
||||
let xid = firetray.Window.getXIDFromGdkWindow(gdkWin);
|
||||
LOG("XID="+xid);
|
||||
return [gtkWin, gdkWin, xid];
|
||||
@ -248,33 +154,17 @@ firetray.Window = {
|
||||
return null;
|
||||
},
|
||||
|
||||
hideWindow: function(win) {
|
||||
LOG("hideWindow");
|
||||
let xid = this.getXIDFromChromeWindow(win);
|
||||
LOG("found xid="+xid);
|
||||
try {
|
||||
firetray.Window._saveWindowPositionSizeState(xid);
|
||||
|
||||
// hide window - NOTE: we don't use BaseWindow.visibility to have full
|
||||
// control
|
||||
gdk.gdk_window_hide(firetray.Handler.windows[xid].gdkWin);
|
||||
} catch (x) {
|
||||
ERROR(x);
|
||||
}
|
||||
},
|
||||
|
||||
_saveWindowPositionSizeState: function(xid) {
|
||||
let gdkWin = firetray.Handler.windows[xid].gdkWin;
|
||||
saveWindowPositionSizeState: function(xid) {
|
||||
let gtkWin = firetray.Handler.gtkWindows.get(xid);
|
||||
let gdkWin = firetray.Handler.gdkWindows.get(xid);
|
||||
|
||||
try {
|
||||
let gx = new gobject.gint; let gy = new gobject.gint;
|
||||
// gtk.gtk_window_get_position(gtkWin, gx.address(), gy.address());
|
||||
gdk.gdk_window_get_position(gdkWin, gx.address(), gy.address());
|
||||
gtk.gtk_window_get_position(gtkWin, gx.address(), gy.address());
|
||||
let gwidth = new gobject.gint; let gheight = new gobject.gint;
|
||||
// gtk.gtk_window_get_size(gtkWin, gwidth.address(), gheight.address());
|
||||
gdk.gdk_drawable_get_size(ctypes.cast(gdkWin, gdk.GdkDrawable.ptr), gwidth.address(), gheight.address());
|
||||
let windowState = gdk.gdk_window_get_state(firetray.Handler.windows[xid].gdkWin);
|
||||
LOG("gx="+gx+", gy="+gy+", gwidth="+gwidth+", gheight="+gheight+", windowState="+windowState);
|
||||
gtk.gtk_window_get_size(gtkWin, gwidth.address(), gheight.address());
|
||||
let windowState = gdk.gdk_window_get_state(gdkWin);
|
||||
LOG("save: gx="+gx+", gy="+gy+", gwidth="+gwidth+", gheight="+gheight+", windowState="+windowState);
|
||||
firetray.Handler.windows[xid].savedX = gx;
|
||||
firetray.Handler.windows[xid].savedY = gy;
|
||||
firetray.Handler.windows[xid].savedWidth = gwidth;
|
||||
@ -286,25 +176,29 @@ firetray.Window = {
|
||||
|
||||
},
|
||||
|
||||
_restoreWindowPositionSizeState: function(xid) {
|
||||
let gdkWin = firetray.Handler.windows[xid].gdkWin;
|
||||
restoreWindowPositionSizeState: function(xid) {
|
||||
if (!firetray.Handler.windows[xid].savedX)
|
||||
return; // windows[xid].saved* may not be initialized
|
||||
|
||||
LOG("restore gdkWin: "+gdkWin+", x="+firetray.Handler.windows[xid].savedX+", y="+firetray.Handler.windows[xid].savedY+", w="+firetray.Handler.windows[xid].savedWidth+", h="+firetray.Handler.windows[xid].savedHeight);
|
||||
let gtkWin = firetray.Handler.gtkWindows.get(xid);
|
||||
let gdkWin = firetray.Handler.gdkWindows.get(xid);
|
||||
|
||||
LOG("restore: x="+firetray.Handler.windows[xid].savedX+", y="+firetray.Handler.windows[xid].savedY+", w="+firetray.Handler.windows[xid].savedWidth+", h="+firetray.Handler.windows[xid].savedHeight);
|
||||
// NOTE: unfortunately, this is the best way I found *inside GTK* to
|
||||
// restore position and size: gdk.gdk_window_move_resize doesn't work
|
||||
// well. And unfortunately, we need to show the window before restoring
|
||||
// position and size :-( TODO: Might be worth trying with x11 or
|
||||
// BaseWindow.visibility ?
|
||||
try {
|
||||
gdk.gdk_window_move_resize(gdkWin,
|
||||
firetray.Handler.windows[xid].savedX,
|
||||
firetray.Handler.windows[xid].savedY,
|
||||
firetray.Handler.windows[xid].savedWidth,
|
||||
firetray.Handler.windows[xid].savedHeight);
|
||||
gtk.gtk_window_move(gtkWin, firetray.Handler.windows[xid].savedX, firetray.Handler.windows[xid].savedY);
|
||||
gtk.gtk_window_resize(gtkWin, firetray.Handler.windows[xid].savedWidth, firetray.Handler.windows[xid].savedHeight);
|
||||
// firetray.Handler.windows[xid].savedState
|
||||
} catch (x) {
|
||||
ERROR(x);
|
||||
}
|
||||
},
|
||||
|
||||
windowState: function(gtkWidget, gdkEventState, userData){
|
||||
onWindowState: function(gtkWidget, gdkEventState, userData){
|
||||
// LOG("window-state-event");
|
||||
// if(event->new_window_state & GDK_WINDOW_STATE_ICONIFIED){
|
||||
let stopPropagation = true;
|
||||
@ -312,3 +206,132 @@ firetray.Window = {
|
||||
}
|
||||
|
||||
}; // firetray.Window
|
||||
|
||||
|
||||
///////////////////////// firetray.Handler overriding /////////////////////////
|
||||
|
||||
// NOTE: storing ctypes pointers into a JS object doesn't work: pointers are
|
||||
// "evolving" after a while (maybe due to back and forth conversion). So we
|
||||
// need to store them into a real ctypes array !
|
||||
firetray.Handler.gtkWindows = new ctypesMap(gtk.GtkWindow.ptr),
|
||||
firetray.Handler.gdkWindows = new ctypesMap(gdk.GdkWindow.ptr),
|
||||
|
||||
/** debug facility */
|
||||
firetray.Handler.dumpWindows = function() {
|
||||
LOG(firetray.Handler.windowsCount);
|
||||
for (let winId in firetray.Handler.windows)
|
||||
LOG(winId+"="+firetray.Handler.gtkWindows.get(winId));
|
||||
};
|
||||
|
||||
firetray.Handler.registerWindow = function(win) {
|
||||
LOG("register window");
|
||||
|
||||
// register
|
||||
let [gtkWin, gdkWin, xid] = firetray.Window.getWindowsFromChromeWindow(win);
|
||||
this.windows[xid] = {};
|
||||
this.windows[xid].win = win;
|
||||
this.gtkWindows.insert(xid, gtkWin);
|
||||
this.gdkWindows.insert(xid, gdkWin);
|
||||
this.windowsCount += 1;
|
||||
this.visibleWindowsCount += 1;
|
||||
this.windows[xid].visibility = true;
|
||||
LOG("window "+xid+" registered");
|
||||
/* NOTE: it should not be necessary to gtk_widget_add_events(gtkWin,
|
||||
gdk.GDK_ALL_EVENTS_MASK); */
|
||||
|
||||
try {
|
||||
/* NOTE: we could try to catch the "delete-event" here and block
|
||||
delete_event_cb (in gtk2/nsWindow.cpp), but we prefer to use the
|
||||
provided 'close' JS event */
|
||||
|
||||
/* we'll catch minimize events with Gtk:
|
||||
http://stackoverflow.com/questions/8018328/what-is-the-gtk-event-called-when-a-window-minimizes */
|
||||
this.windows[xid].onWindowStateCb = gtk.GCallbackWindowStateEvent_t(firetray.Window.onWindowState);
|
||||
this.windows[xid].onWindowStateCbId = gobject.g_signal_connect(gtkWin, "window-state-event", this.windows[xid].onWindowStateCb, null);
|
||||
LOG("g_connect window-state-event="+this.windows[xid].onWindowStateCbId);
|
||||
|
||||
} catch (x) {
|
||||
this._unregisterWindowByXID(xid);
|
||||
ERROR(x);
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG("AFTER"); firetray.Handler.dumpWindows();
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
firetray.Handler._unregisterWindowByXID = function(xid) {
|
||||
this.windowsCount -= 1;
|
||||
if (this.windows[xid].visibility) this.visibleWindowsCount -= 1;
|
||||
if (this.windows.hasOwnProperty(xid)) {
|
||||
if (!delete this.windows[xid])
|
||||
throw new DeleteError();
|
||||
this.gtkWindows.remove(xid);
|
||||
this.gdkWindows.remove(xid);
|
||||
} else {
|
||||
ERROR("can't unregister unknown window "+xid);
|
||||
return false;
|
||||
}
|
||||
LOG("window "+xid+" unregistered");
|
||||
return true;
|
||||
};
|
||||
|
||||
firetray.Handler.unregisterWindow = function(win) {
|
||||
LOG("unregister window");
|
||||
|
||||
try {
|
||||
let xid = firetray.Window.getXIDFromChromeWindow(win);
|
||||
return this._unregisterWindowByXID(xid);
|
||||
} catch (x) {
|
||||
ERROR(x);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
firetray.Handler.getWindowIdFromChromeWindow = firetray.Window.getXIDFromChromeWindow;
|
||||
|
||||
firetray.Handler.showSingleWindow = function(xid) {
|
||||
LOG("show xid="+xid);
|
||||
try {
|
||||
// try to restore previous state. TODO: z-order respected ?
|
||||
gdk.gdk_window_show_unraised(firetray.Handler.gdkWindows.get(xid));
|
||||
// need to restore *after* showing for correctness
|
||||
firetray.Window.restoreWindowPositionSizeState(xid);
|
||||
} catch (x) {
|
||||
ERROR(x);
|
||||
}
|
||||
firetray.Handler.windows[xid].visibility = true;
|
||||
firetray.Handler.visibleWindowsCount += 1;
|
||||
};
|
||||
|
||||
firetray.Handler.hideSingleWindow = function(xid) {
|
||||
LOG("hideSingleWindow");
|
||||
try {
|
||||
firetray.Window.saveWindowPositionSizeState(xid);
|
||||
// NOTE: we don't use BaseWindow.visibility to have full control
|
||||
gdk.gdk_window_hide(firetray.Handler.gdkWindows.get(xid));
|
||||
} catch (x) {
|
||||
ERROR(x);
|
||||
}
|
||||
firetray.Handler.windows[xid].visibility = false;
|
||||
firetray.Handler.visibleWindowsCount -= 1;
|
||||
};
|
||||
|
||||
firetray.Handler.showHideAllWindows = function(gtkStatusIcon, userData) {
|
||||
LOG("showHideAllWindows: "+userData);
|
||||
// NOTE: showHideAllWindows being a callback, we need to use
|
||||
// 'firetray.Handler' explicitely instead of 'this'
|
||||
|
||||
LOG("visibleWindowsCount="+firetray.Handler.visibleWindowsCount);
|
||||
LOG("windowsCount="+firetray.Handler.windowsCount);
|
||||
let visibilityRate = firetray.Handler.visibleWindowsCount/firetray.Handler.windowsCount;
|
||||
LOG("visibilityRate="+visibilityRate);
|
||||
if (visibilityRate > 0.5) // TODO: should be configurable
|
||||
firetray.Handler.hideAllWindows();
|
||||
else
|
||||
firetray.Handler.showAllWindows();
|
||||
|
||||
let stopPropagation = true;
|
||||
return stopPropagation;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user