From 6fb8a15f2291bf7630a1381ddf815341b5d5c14b Mon Sep 17 00:00:00 2001 From: foudfou Date: Sun, 10 Mar 2013 20:51:33 +0100 Subject: [PATCH] * more accurate startup event detection * when start_hidden, hide window on first x11.MapNotify instead of hiding all windows short after the "startup event". This prevents having visibility falsely corrected for windows that are displayed after the "startup event", and thus having to click twice on the tray icon to actually restore windows. --- src/modules/FiretrayHandler.jsm | 58 ++++++++++++++++++---------- src/modules/commons.js | 44 ++++++++++++++++----- src/modules/ctypes/linux/gdk.jsm | 1 + src/modules/linux/FiretrayWindow.jsm | 28 ++++++++++++-- 4 files changed, 98 insertions(+), 33 deletions(-) diff --git a/src/modules/FiretrayHandler.jsm b/src/modules/FiretrayHandler.jsm index dd36bb9..210ee6c 100644 --- a/src/modules/FiretrayHandler.jsm +++ b/src/modules/FiretrayHandler.jsm @@ -74,13 +74,17 @@ firetray.Handler = { return false; } - if (this.appId === FIRETRAY_THUNDERBIRD_ID || this.appId === FIRETRAY_SEAMONKEY_ID) + if (this.appId === FIRETRAY_APP_DB['thunderbird']['id'] || + this.appId === FIRETRAY_APP_DB['seamonkey']['id']) this.inMailApp = true; - if (this.appId === FIRETRAY_FIREFOX_ID || this.appId === FIRETRAY_SEAMONKEY_ID) + if (this.appId === FIRETRAY_APP_DB['firefox']['id'] || + this.appId === FIRETRAY_APP_DB['seamonkey']['id']) this.inBrowserApp = true; - if (this.appId === FIRETRAY_THUNDERBIRD_ID && Services.vc.compare(this.xulVer,"15.0")>=0) + if (this.appId === FIRETRAY_APP_DB['thunderbird']['id'] && + Services.vc.compare(this.xulVer,"15.0")>=0) this.appHasChat = true; - log.info('inMailApp='+this.inMailApp+', inBrowserApp='+this.inBrowserApp+', appHasChat='+this.appHasChat); + log.info('inMailApp='+this.inMailApp+', inBrowserApp='+this.inBrowserApp+ + ', appHasChat='+this.appHasChat); VersionChange.init(FIRETRAY_ID, FIRETRAY_VERSION, FIRETRAY_PREF_BRANCH); VersionChange.addHook(["install", "upgrade", "reinstall"], firetray.VersionChangeHandler.showReleaseNotes); @@ -119,7 +123,13 @@ firetray.Handler = { } firetray.Utils.addObservers(firetray.Handler, - [ "before-first-paint", "xpcom-will-shutdown", "profile-change-teardown" ]); + [ "xpcom-will-shutdown", "profile-change-teardown" ]); + if (this.appId === FIRETRAY_APP_DB['thunderbird']['id'] || + this.appId === FIRETRAY_APP_DB['firefox']['id']) { + firetray.Utils.addObservers(firetray.Handler, [ "before-first-paint" ]); + } else { + firetray.Utils.addObservers(firetray.Handler, [ "xul-window-visible" ]); + } this.preventWarnOnClose(); @@ -187,23 +197,29 @@ firetray.Handler = { return false; }, + startupDone: function() { + firetray.Handler.timers['startup-done'] = + firetray.Utils.timer(FIRETRAY_DELAY_BROWSER_STARTUP_MILLISECONDS, + Ci.nsITimer.TYPE_ONE_SHOT, function() { + firetray.Handler.appStarted = true; + log.debug("*** appStarted ***"); + }); + }, + observe: function(subject, topic, data) { switch (topic) { case "before-first-paint": + if (FIRETRAY_APP_DB[this.appName.toLowerCase()]['mainXUL'] !== subject.baseURI) return; + log.debug("before-first-paint: "+subject.baseURI); firetray.Utils.removeObservers(firetray.Handler, [ "before-first-paint" ]); - firetray.Handler.timers['before-first-paint'] = - firetray.Utils.timer(FIRETRAY_DELAY_BROWSER_STARTUP_MILLISECONDS, - Ci.nsITimer.TYPE_ONE_SHOT, function() { - if (firetray.Utils.prefService.getBoolPref('start_hidden')) { - log.debug("start_hidden"); - firetray.Handler.hideAllWindows(); - } - - firetray.Handler.appStarted = true; - log.debug("*** appStarted ***"); - }); + firetray.Handler.startupDone(); + break; + case "xul-window-visible": + log.debug("xul-window-visible: "+subject+","+data); + firetray.Utils.removeObservers(firetray.Handler, [ "xul-window-visible" ]); + firetray.Handler.startupDone(); break; case "xpcom-will-shutdown": @@ -297,9 +313,9 @@ firetray.Handler = { }, _getBrowserProperties: function() { - if (firetray.Handler.appId === FIRETRAY_FIREFOX_ID) + if (firetray.Handler.appId === FIRETRAY_APP_DB['firefox']['id']) return "chrome://branding/locale/browserconfig.properties"; - else if (firetray.Handler.appId === FIRETRAY_SEAMONKEY_ID) + else if (firetray.Handler.appId === FIRETRAY_APP_DB['seamonkey']['id']) return "chrome://navigator-region/locale/region.properties"; else return null; }, @@ -454,10 +470,10 @@ firetray.VersionChangeHandler = { openTab: function(url) { log.info("appId="+firetray.Handler.appId); - if (firetray.Handler.appId === FIRETRAY_THUNDERBIRD_ID) + if (firetray.Handler.appId === FIRETRAY_APP_DB['thunderbird']['id']) this.openMailTab(url); - else if (firetray.Handler.appId === FIRETRAY_FIREFOX_ID || - firetray.Handler.appId === FIRETRAY_SEAMONKEY_ID) + else if (firetray.Handler.appId === FIRETRAY_APP_DB['firefox']['id'] || + firetray.Handler.appId === FIRETRAY_APP_DB['seamonkey']['id']) this.openBrowserTab(url); else log.error("unsupported application"); diff --git a/src/modules/commons.js b/src/modules/commons.js index 07b939a..b5bc865 100644 --- a/src/modules/commons.js +++ b/src/modules/commons.js @@ -15,8 +15,7 @@ var EXPORTED_SYMBOLS = "FIRETRAY_DELAY_NOWAIT_MILLISECONDS", "FIRETRAY_DELAY_PREF_CLEANING_MILLISECONDS", "FIRETRAY_MESSAGE_COUNT_TYPE_UNREAD", "FIRETRAY_MESSAGE_COUNT_TYPE_NEW", - "FIRETRAY_FIREFOX_ID", "FIRETRAY_THUNDERBIRD_ID", "FIRETRAY_SONGBIRD_ID", - "FIRETRAY_SUNBIRD_ID", "FIRETRAY_SEAMONKEY_ID", "FIRETRAY_CHATZILLA_ID" ]; + "FIRETRAY_APP_DB" ]; const Cc = Components.classes; const Ci = Components.interfaces; @@ -26,8 +25,8 @@ Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://firetray/logging.jsm"); const FIRETRAY_VERSION = "0.4.5"; // needed for sync call of onVersionChange() :( -const FIRETRAY_PREF_BRANCH = "extensions.firetray."; const FIRETRAY_ID = "{9533f794-00b4-4354-aa15-c2bbda6989f8}"; +const FIRETRAY_PREF_BRANCH = "extensions.firetray."; const FIRETRAY_SPLASH_PAGE = "http://foudfou.github.com/FireTray/"; const FIRETRAY_APPLICATION_ICON_TYPE_THEMED = 0; @@ -51,12 +50,39 @@ const FIRETRAY_DELAY_BROWSER_STARTUP_MILLISECONDS = 500; const FIRETRAY_DELAY_NOWAIT_MILLISECONDS = 0; const FIRETRAY_DELAY_PREF_CLEANING_MILLISECONDS = 15*60*1000; -const FIRETRAY_FIREFOX_ID = "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}"; -const FIRETRAY_THUNDERBIRD_ID = "{3550f703-e582-4d05-9a08-453d09bdfdc6}"; -const FIRETRAY_SONGBIRD_ID = "songbird@songbirdnest.com"; -const FIRETRAY_SUNBIRD_ID = "{718e30fb-e89b-41dd-9da7-e25a45638b28}"; -const FIRETRAY_SEAMONKEY_ID = "{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}"; -const FIRETRAY_CHATZILLA_ID = "{59c81df5-4b7a-477b-912d-4e0fdf64e5f2}"; +const FIRETRAY_APP_DB = { + + firefox: { + id: "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}", + mainXUL: "chrome://browser/content/browser.xul" + }, + + thunderbird: { + id: "{3550f703-e582-4d05-9a08-453d09bdfdc6}", + mainXUL: "chrome://messenger/content/msgAccountCentral.xul" + }, + + seamonkey: { + id: "{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}", + mainXUL: null + }, + + songbird: { + id: "songbird@songbirdnest.com", + mainXUL: null + }, + + sunbird: { + id: "718e30fb-e89b-41dd-9da7-e25a45638b28}", + mainXUL: null + }, + + chatzilla: { + id: "{59c81df5-4b7a-477b-912d-4e0fdf64e5f2}", + mainXUL: null + } + +}; /** * firetray namespace. diff --git a/src/modules/ctypes/linux/gdk.jsm b/src/modules/ctypes/linux/gdk.jsm index 95febfb..16d71a0 100644 --- a/src/modules/ctypes/linux/gdk.jsm +++ b/src/modules/ctypes/linux/gdk.jsm @@ -292,6 +292,7 @@ function gdk_defines(lib) { lib.lazy_bind("gdk_window_get_events", this.GdkEventMask, this.GdkWindow.ptr); lib.lazy_bind("gdk_window_set_events", ctypes.void_t, this.GdkWindow.ptr, this.GdkEventMask); lib.lazy_bind("gdk_window_add_filter", ctypes.void_t, this.GdkWindow.ptr, this.GdkFilterFunc, gobject.gpointer); + lib.lazy_bind("gdk_window_remove_filter", ctypes.void_t, this.GdkWindow.ptr, this.GdkFilterFunc, gobject.gpointer); lib.lazy_bind("gdk_display_get_default", this.GdkDisplay.ptr); lib.lazy_bind("gdk_x11_display_get_xdisplay", x11.Display.ptr, this.GdkDisplay.ptr); lib.lazy_bind("gdk_window_get_state", this.GdkWindowState, this.GdkWindow.ptr); diff --git a/src/modules/linux/FiretrayWindow.jsm b/src/modules/linux/FiretrayWindow.jsm index 09f435f..b5694ee 100644 --- a/src/modules/linux/FiretrayWindow.jsm +++ b/src/modules/linux/FiretrayWindow.jsm @@ -243,7 +243,8 @@ firetray.Window = { firetray.Handler.showHideIcon(); }, - /* FIXME: hiding windows should also hide child windows */ + /* FIXME: hiding windows should also hide child windows, like message windows + in Thunderbird */ hide: function(xid) { log.debug("hide"); @@ -488,7 +489,7 @@ firetray.Window = { let title = firetray.Handler.windows[xid].baseWin.title; log.debug("|baseWin.title="+title+"|"); let tailIndex; - if (firetray.Handler.appId === FIRETRAY_SEAMONKEY_ID) + if (firetray.Handler.appId === FIRETRAY_APP_DB['seamonkey']['id']) tailIndex = title.indexOf(" - "+firetray.Handler.appName); else tailIndex = title.indexOf(" - Mozilla "+firetray.Handler.appName); @@ -513,6 +514,25 @@ firetray.Window = { } }, + startupFilter: function(xev, gdkEv, data) { + if (!xev) + return gdk.GDK_FILTER_CONTINUE; + + let xany = ctypes.cast(xev, x11.XAnyEvent.ptr); + let xid = xany.contents.window; + + if (xany.contents.type === x11.MapNotify) { + if (firetray.Utils.prefService.getBoolPref('start_hidden')) { + log.debug("start_hidden"); + firetray.Window.hide(xid); + } + gdk.gdk_window_remove_filter(firetray.Handler.gdkWindows.get(xid), + firetray.Handler.windows[xid].startupFilterCb, null); + } + + return gdk.GDK_FILTER_CONTINUE; + }, + filterWindow: function(xev, gdkEv, data) { if (!xev) return gdk.GDK_FILTER_CONTINUE; @@ -527,7 +547,7 @@ firetray.Window = { let gdkWinStateOnMap = gdk.gdk_window_get_state(firetray.Handler.gdkWindows.get(xid)); log.debug("gdkWinState="+gdkWinStateOnMap+" for xid="+xid); let win = firetray.Handler.windows[xid]; - if (!win.visible && firetray.Handler.appStarted) { // happens when hidden app called from command line + if (firetray.Handler.appStarted && !win.visible) { // happens when hidden app called from command line log.warn("window not visible, correcting visibility"); firetray.Window.updateVisibility(xid, true); log.debug("visibleWindowsCount="+firetray.Handler.visibleWindowsCount); @@ -617,6 +637,8 @@ firetray.Handler.registerWindow = function(win) { this.windows[xid].filterWindowCb = gdk.GdkFilterFunc_t(firetray.Window.filterWindow); gdk.gdk_window_add_filter(gdkWin, this.windows[xid].filterWindowCb, null); + this.windows[xid].startupFilterCb = gdk.GdkFilterFunc_t(firetray.Window.startupFilter); + gdk.gdk_window_add_filter(gdkWin, this.windows[xid].startupFilterCb, null); if (firetray.Handler.isChatEnabled() && firetray.Chat.initialized) { // missing import ok Cu.import("resource://firetray/linux/FiretrayChatStatusIcon.jsm");