From 23cf34ea9f0068e2bc9679d3d8e126e3707de50d Mon Sep 17 00:00:00 2001 From: foudfou Date: Mon, 13 Feb 2012 23:55:01 +0100 Subject: [PATCH 1/3] fix start_hidden: do not save+restore unrealized position and size. NEEDS REFACTORING --- src/chrome/content/overlay.js | 4 +- src/modules/FiretrayHandler.jsm | 13 ++- src/modules/linux/FiretrayWindow.jsm | 125 +++++++++++++++++---------- 3 files changed, 91 insertions(+), 51 deletions(-) diff --git a/src/chrome/content/overlay.js b/src/chrome/content/overlay.js index e975b6c..8673c41 100644 --- a/src/chrome/content/overlay.js +++ b/src/chrome/content/overlay.js @@ -19,11 +19,9 @@ var firetrayChrome = { // each new window gets a new firetrayChrome ! LOG("ONLOAD"); firetray.Handler.dumpWindows(); firetray.Handler.registerWindow(win); - // update unread messages count if (firetray.Handler.inMailApp && firetray.Messaging.initialized) firetray.Messaging.updateMsgCount(); - // prevent window closing. win.addEventListener('close', firetrayChrome.onClose, true); if (!firetray.Handler.appStarted @@ -63,7 +61,7 @@ var firetrayChrome = { // each new window gets a new firetrayChrome ! firetray.Handler.hideSingleWindow(winId); } else firetray.Handler.hideAllWindows(); - event && event.preventDefault(); // no event when called directly (xul) + event && event.preventDefault(); } } }; diff --git a/src/modules/FiretrayHandler.jsm b/src/modules/FiretrayHandler.jsm index 8a29618..54472ab 100644 --- a/src/modules/FiretrayHandler.jsm +++ b/src/modules/FiretrayHandler.jsm @@ -109,6 +109,14 @@ firetray.Handler = { VersionChange.setReinstallHook(welcome); VersionChange.watch(); + if (firetray.Utils.prefService.getBoolPref('start_hidden')) { + firetray.Handler.showSingleWindow = firetray.Window.showSingleStatelessOnce; + firetray.Handler.hideSingleWindow = firetray.Window.hideSingleStatelessOnce; + } else { + firetray.Handler.showSingleWindow = firetray.Window.showSingleStateful; + firetray.Handler.hideSingleWindow = firetray.Window.hideSingleStateful; + } + this.initialized = true; return true; }, @@ -139,11 +147,10 @@ firetray.Handler = { LOG("RECEIVED: "+topic+", launching timer"); // sessionstore-windows-restored does not come after the realization of // all windows... so we wait a little - var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - timer.initWithCallback({ notify: function() { + firetray.Utils.timer(function() { firetray.Handler.appStarted = true; LOG("*** appStarted ***"); - }}, FIRETRAY_DELAY_BROWSER_STARTUP_MILLISECONDS, Ci.nsITimer.TYPE_ONE_SHOT); + }, FIRETRAY_DELAY_BROWSER_STARTUP_MILLISECONDS, Ci.nsITimer.TYPE_ONE_SHOT); break; case "xpcom-will-shutdown": LOG("xpcom-will-shutdown"); diff --git a/src/modules/linux/FiretrayWindow.jsm b/src/modules/linux/FiretrayWindow.jsm index a20cb9c..eca6608 100644 --- a/src/modules/linux/FiretrayWindow.jsm +++ b/src/modules/linux/FiretrayWindow.jsm @@ -188,7 +188,80 @@ firetray.Window = { return true; }, - saveWindowPositionAndSize: function(xid) { + showSingleStateful: function(xid) { + LOG("show xid="+xid); + + // try to restore previous state. TODO: z-order respected ? + firetray.Window.restorePositionAndSize(xid); + firetray.Window.restoreStates(xid); + firetray.Handler.windows[xid].baseWin.visibility = true; // show + firetray.Window.restoreDesktop(xid); // after show + firetray.Window.activate(xid); + + firetray.Handler.windows[xid].visibility = true; + firetray.Handler.visibleWindowsCount += 1; + + if (firetray.Handler.popupMenuWindowItemsHandled()) + firetray.PopupMenu.hideSingleWindowItemAndSeparatorMaybe(xid); + firetray.Handler.showHideIcon(); + }, + + showSingleStatelessOnce: function(xid) { + LOG("showSingleStateless"); + + firetray.Handler.windows[xid].baseWin.visibility = true; // show + + firetray.Handler.windows[xid].visibility = true; + firetray.Handler.visibleWindowsCount += 1; + + if (firetray.Handler.popupMenuWindowItemsHandled()) + firetray.PopupMenu.hideSingleWindowItemAndSeparatorMaybe(xid); + firetray.Handler.showHideIcon(); + + firetray.Handler.showSingleWindow = firetray.Window.showSingleStateful; + }, + + // NOTE: we keep using high-level cross-plat BaseWindow.visibility (instead of + // gdk_window_show_unraised) + /* FIXME: hiding windows should also hide child windows */ + hideSingleStateful: function(xid) { + LOG("hideSingleStateful"); + + firetray.Window.savePositionAndSize(xid); + firetray.Window.saveStates(xid); + firetray.Window.saveDesktop(xid); + + firetray.Handler.windows[xid].baseWin.visibility = false; // hide + + firetray.Handler.windows[xid].visibility = false; + firetray.Handler.visibleWindowsCount -= 1; + + if (firetray.Handler.popupMenuWindowItemsHandled()) + firetray.PopupMenu.showSingleWindowItem(xid); + firetray.Handler.showHideIcon(); + }, + + /** + * hides without saving window states (position, size, ...) This is needed when + * application starts hidden: as windows are not realized, their state is not + * accurate. + */ + hideSingleStatelessOnce: function(xid) { + LOG("hideSingleStateless"); + + firetray.Handler.windows[xid].baseWin.visibility = false; // hide + + firetray.Handler.windows[xid].visibility = false; + firetray.Handler.visibleWindowsCount -= 1; + + if (firetray.Handler.popupMenuWindowItemsHandled()) + firetray.PopupMenu.showSingleWindowItem(xid); + firetray.Handler.showHideIcon(); + + firetray.Handler.hideSingleWindow = firetray.Window.hideSingleStateful; + }, + + savePositionAndSize: function(xid) { let gx = {}, gy = {}, gwidth = {}, gheight = {}; firetray.Handler.windows[xid].baseWin.getPositionAndSize(gx, gy, gwidth, gheight); firetray.Handler.windows[xid].savedX = gx.value; @@ -198,7 +271,7 @@ firetray.Window = { LOG("save: gx="+gx.value+", gy="+gy.value+", gwidth="+gwidth.value+", gheight="+gheight.value); }, - restoreWindowPositionAndSize: function(xid) { + restorePositionAndSize: function(xid) { if ("undefined" === typeof(firetray.Handler.windows[xid].savedX)) return; // windows[xid].saved* may not be initialized @@ -215,13 +288,13 @@ firetray.Window = { }); }, - saveWindowStates: function(xid) { + saveStates: function(xid) { let winStates = firetray.Window.getXWindowStates(x11.Window(xid)); firetray.Handler.windows[xid].savedStates = winStates; LOG("save: windowStates="+winStates); }, - restoreWindowStates: function(xid) { + restoreStates: function(xid) { let winStates = firetray.Handler.windows[xid].savedStates; LOG("restored WindowStates: " + winStates); if (winStates & FIRETRAY_XWINDOW_MAXIMIZED) { @@ -235,15 +308,15 @@ firetray.Window = { delete firetray.Handler.windows[xid].savedStates; }, - saveWindowDesktop: function(xid) { + saveDesktop: function(xid) { let winDesktop = firetray.Window.getXWindowDesktop(x11.Window(xid)); firetray.Handler.windows[xid].savedDesktop = winDesktop; LOG("save: windowDesktop="+winDesktop); }, - restoreWindowDesktop: function(xid) { + restoreDesktop: function(xid) { let desktopDest = firetray.Handler.windows[xid].savedDesktop; - if (desktopDest === null) return; + if (desktopDest === null || "undefined" === typeof(desktopDest)) return; let dataSize = 1; let data = ctypes.long(dataSize); @@ -498,44 +571,6 @@ firetray.Handler.unregisterWindow = function(win) { return firetray.Window.unregisterWindowByXID(xid); }; -firetray.Handler.showSingleWindow = function(xid) { - LOG("show xid="+xid); - - // try to restore previous state. TODO: z-order respected ? - firetray.Window.restoreWindowPositionAndSize(xid); - firetray.Window.restoreWindowStates(xid); - firetray.Handler.windows[xid].baseWin.visibility = true; // show - firetray.Window.restoreWindowDesktop(xid); // after show - firetray.Window.activate(xid); - // TODO: we need want to restore to the original monitor (screen) - - firetray.Handler.windows[xid].visibility = true; - firetray.Handler.visibleWindowsCount += 1; - - if (firetray.Handler.popupMenuWindowItemsHandled()) - firetray.PopupMenu.hideSingleWindowItemAndSeparatorMaybe(xid); - firetray.Handler.showHideIcon(); -}; - -// NOTE: we keep using high-level cross-plat BaseWindow.visibility (instead of -// gdk_window_show_unraised) -/* FIXME: hiding windows should also hide child windows */ -firetray.Handler.hideSingleWindow = function(xid) { - LOG("hideSingleWindow"); - - firetray.Window.saveWindowPositionAndSize(xid); - firetray.Window.saveWindowStates(xid); - firetray.Window.saveWindowDesktop(xid); - firetray.Handler.windows[xid].baseWin.visibility = false; // hide - - firetray.Handler.windows[xid].visibility = false; - firetray.Handler.visibleWindowsCount -= 1; - - if (firetray.Handler.popupMenuWindowItemsHandled()) - firetray.PopupMenu.showSingleWindowItem(xid); - firetray.Handler.showHideIcon(); -}; - firetray.Handler.showHideAllWindows = function(gtkStatusIcon, userData) { LOG("showHideAllWindows: "+userData); // NOTE: showHideAllWindows being a callback, we need to use From 2789844b069e55125b93f82ab9651ab52dd77717 Mon Sep 17 00:00:00 2001 From: foudfou Date: Sun, 19 Feb 2012 15:36:16 +0100 Subject: [PATCH 2/3] minor refactoring: firetray.Window.setVisibility() --- src/modules/linux/FiretrayWindow.jsm | 35 +++++++++++++--------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/src/modules/linux/FiretrayWindow.jsm b/src/modules/linux/FiretrayWindow.jsm index eca6608..07d29a9 100644 --- a/src/modules/linux/FiretrayWindow.jsm +++ b/src/modules/linux/FiretrayWindow.jsm @@ -194,25 +194,21 @@ firetray.Window = { // try to restore previous state. TODO: z-order respected ? firetray.Window.restorePositionAndSize(xid); firetray.Window.restoreStates(xid); + // better visual effect if visibility set here instead of before firetray.Handler.windows[xid].baseWin.visibility = true; // show firetray.Window.restoreDesktop(xid); // after show firetray.Window.activate(xid); - firetray.Handler.windows[xid].visibility = true; - firetray.Handler.visibleWindowsCount += 1; + firetray.Window.setVisibility(xid, true); if (firetray.Handler.popupMenuWindowItemsHandled()) firetray.PopupMenu.hideSingleWindowItemAndSeparatorMaybe(xid); firetray.Handler.showHideIcon(); }, - showSingleStatelessOnce: function(xid) { LOG("showSingleStateless"); - firetray.Handler.windows[xid].baseWin.visibility = true; // show - - firetray.Handler.windows[xid].visibility = true; - firetray.Handler.visibleWindowsCount += 1; + firetray.Window.setVisibility(xid, true); if (firetray.Handler.popupMenuWindowItemsHandled()) firetray.PopupMenu.hideSingleWindowItemAndSeparatorMaybe(xid); @@ -231,28 +227,21 @@ firetray.Window = { firetray.Window.saveStates(xid); firetray.Window.saveDesktop(xid); - firetray.Handler.windows[xid].baseWin.visibility = false; // hide - - firetray.Handler.windows[xid].visibility = false; - firetray.Handler.visibleWindowsCount -= 1; + firetray.Window.setVisibility(xid, false); if (firetray.Handler.popupMenuWindowItemsHandled()) firetray.PopupMenu.showSingleWindowItem(xid); firetray.Handler.showHideIcon(); }, - /** - * hides without saving window states (position, size, ...) This is needed when - * application starts hidden: as windows are not realized, their state is not - * accurate. + * hides without saving window states (position, size, ...) This is needed + * when application starts hidden: as windows are not realized, their state + * is not accurate. */ hideSingleStatelessOnce: function(xid) { LOG("hideSingleStateless"); - firetray.Handler.windows[xid].baseWin.visibility = false; // hide - - firetray.Handler.windows[xid].visibility = false; - firetray.Handler.visibleWindowsCount -= 1; + firetray.Window.setVisibility(xid, false); if (firetray.Handler.popupMenuWindowItemsHandled()) firetray.PopupMenu.showSingleWindowItem(xid); @@ -327,6 +316,14 @@ firetray.Window = { delete firetray.Handler.windows[xid].savedDesktop; }, + setVisibility: function(xid, visibility) { + firetray.Handler.windows[xid].baseWin.visibility = visibility; + firetray.Handler.windows[xid].visibility = visibility; + firetray.Handler.visibleWindowsCount = visibility ? + firetray.Handler.visibleWindowsCount + 1 : + firetray.Handler.visibleWindowsCount - 1 ; + }, + xSendClientMessgeEvent: function(xid, atom, data, dataSize) { let xev = new x11.XClientMessageEvent; xev.type = x11.ClientMessage; From 7efe604b9ca4fc054a0b113f38e6031106e8ff8c Mon Sep 17 00:00:00 2001 From: foudfou Date: Mon, 20 Feb 2012 15:34:51 +0100 Subject: [PATCH 3/3] showSingleWindow() and hideSingleWindow() now defined per window (needed for start_hidden) --- src/chrome/content/overlay.js | 7 +--- src/modules/FiretrayHandler.jsm | 10 +---- src/modules/linux/FiretrayPopupMenu.jsm | 32 ++++++++------ src/modules/linux/FiretrayWindow.jsm | 55 +++++++++++++++++-------- 4 files changed, 59 insertions(+), 45 deletions(-) diff --git a/src/chrome/content/overlay.js b/src/chrome/content/overlay.js index 8673c41..f75b370 100644 --- a/src/chrome/content/overlay.js +++ b/src/chrome/content/overlay.js @@ -17,18 +17,15 @@ var firetrayChrome = { // each new window gets a new firetrayChrome ! let init = firetray.Handler.initialized || firetray.Handler.init(); LOG("ONLOAD"); firetray.Handler.dumpWindows(); - firetray.Handler.registerWindow(win); + let winId = firetray.Handler.registerWindow(win); if (firetray.Handler.inMailApp && firetray.Messaging.initialized) firetray.Messaging.updateMsgCount(); win.addEventListener('close', firetrayChrome.onClose, true); - if (!firetray.Handler.appStarted - && firetray.Utils.prefService.getBoolPref('start_hidden')) { + if (firetray.Handler.windows[winId].startHidden) { LOG('start_hidden'); - let winId = firetray.Handler.getWindowIdFromChromeWindow(win); - LOG('winId='+winId); firetray.Handler.hideSingleWindow(winId); } diff --git a/src/modules/FiretrayHandler.jsm b/src/modules/FiretrayHandler.jsm index 54472ab..9a64e5c 100644 --- a/src/modules/FiretrayHandler.jsm +++ b/src/modules/FiretrayHandler.jsm @@ -109,14 +109,6 @@ firetray.Handler = { VersionChange.setReinstallHook(welcome); VersionChange.watch(); - if (firetray.Utils.prefService.getBoolPref('start_hidden')) { - firetray.Handler.showSingleWindow = firetray.Window.showSingleStatelessOnce; - firetray.Handler.hideSingleWindow = firetray.Window.hideSingleStatelessOnce; - } else { - firetray.Handler.showSingleWindow = firetray.Window.showSingleStateful; - firetray.Handler.hideSingleWindow = firetray.Window.hideSingleStateful; - } - this.initialized = true; return true; }, @@ -358,7 +350,7 @@ firetray.PrefListener = new PrefListener( LOG('Pref changed: '+name); switch (name) { case 'hides_single_window': - firetray.Handler.updatePopupMenu(); + firetray.Handler.showHidePopupMenuItems(); break; case 'show_icon_on_hide': firetray.Handler.showHideIcon(); diff --git a/src/modules/linux/FiretrayPopupMenu.jsm b/src/modules/linux/FiretrayPopupMenu.jsm index 829c03a..4b958db 100644 --- a/src/modules/linux/FiretrayPopupMenu.jsm +++ b/src/modules/linux/FiretrayPopupMenu.jsm @@ -151,6 +151,9 @@ firetray.PopupMenu = { }, showSingleWindowItem: function(xid) { + if (!this.windowItemsHandled()) + return; + LOG("showSingleWindowItem"); let menuItemWindow = firetray.Handler.gtkPopupMenuWindowItems.get(xid); this.showItem(menuItemWindow); @@ -173,13 +176,15 @@ firetray.PopupMenu = { this.hideSingleWindowItemAndSeparator(xid); }, - // PopupMenu.hideItem(firetray.Handler.gtkPopupMenuWindowItems.get(xid)) hideSingleWindowItemAndSeparator: function(xid) { this.hideSingleWindowItem(xid); this.hideWindowSeparator(); }, hideSingleWindowItemAndSeparatorMaybe: function(xid) { + if (!this.windowItemsHandled()) + return; + this.hideSingleWindowItem(xid); if (firetray.Handler.visibleWindowsCount === firetray.Handler.windowsCount) this.hideWindowSeparator(); @@ -202,19 +207,20 @@ firetray.PopupMenu = { hideWindowSeparator: function() { LOG("hiding menuSeparatorWindows"); gtk.gtk_widget_hide(ctypes.cast(this.menuSeparatorWindows, gtk.GtkWidget.ptr)); + }, + + showHideWindowItems: function() { + if (this.windowItemsHandled()) + this.showAllWindowItemsOnlyVisibleWindows(); + else + this.hideAllWindowItems(); + }, + + windowItemsHandled: function() { + return (firetray.Handler.inBrowserApp && + firetray.Utils.prefService.getBoolPref('hides_single_window')); } }; // firetray.PopupMenu - -firetray.Handler.popupMenuWindowItemsHandled = function() { - return (firetray.Handler.inBrowserApp && - firetray.Utils.prefService.getBoolPref('hides_single_window')); -}; - -firetray.Handler.updatePopupMenu = function() { - if (firetray.Handler.popupMenuWindowItemsHandled()) - firetray.PopupMenu.showAllWindowItemsOnlyVisibleWindows(); - else - firetray.PopupMenu.hideAllWindowItems(); -}; +firetray.Handler.showHidePopupMenuItems = firetray.PopupMenu.showHideWindowItems; diff --git a/src/modules/linux/FiretrayWindow.jsm b/src/modules/linux/FiretrayWindow.jsm index 07d29a9..61d676a 100644 --- a/src/modules/linux/FiretrayWindow.jsm +++ b/src/modules/linux/FiretrayWindow.jsm @@ -189,20 +189,19 @@ firetray.Window = { }, showSingleStateful: function(xid) { - LOG("show xid="+xid); + LOG("showSingleStateful xid="+xid); // try to restore previous state. TODO: z-order respected ? firetray.Window.restorePositionAndSize(xid); firetray.Window.restoreStates(xid); + // better visual effect if visibility set here instead of before - firetray.Handler.windows[xid].baseWin.visibility = true; // show + firetray.Window.setVisibility(xid, true); + firetray.Window.restoreDesktop(xid); // after show firetray.Window.activate(xid); - firetray.Window.setVisibility(xid, true); - - if (firetray.Handler.popupMenuWindowItemsHandled()) - firetray.PopupMenu.hideSingleWindowItemAndSeparatorMaybe(xid); + firetray.PopupMenu.hideSingleWindowItemAndSeparatorMaybe(xid); firetray.Handler.showHideIcon(); }, showSingleStatelessOnce: function(xid) { @@ -210,11 +209,10 @@ firetray.Window = { firetray.Window.setVisibility(xid, true); - if (firetray.Handler.popupMenuWindowItemsHandled()) - firetray.PopupMenu.hideSingleWindowItemAndSeparatorMaybe(xid); + firetray.PopupMenu.hideSingleWindowItemAndSeparatorMaybe(xid); firetray.Handler.showHideIcon(); - firetray.Handler.showSingleWindow = firetray.Window.showSingleStateful; + firetray.Handler.windows[xid].show = firetray.Window.showSingleStateful; // reset }, // NOTE: we keep using high-level cross-plat BaseWindow.visibility (instead of @@ -229,8 +227,7 @@ firetray.Window = { firetray.Window.setVisibility(xid, false); - if (firetray.Handler.popupMenuWindowItemsHandled()) - firetray.PopupMenu.showSingleWindowItem(xid); + firetray.PopupMenu.showSingleWindowItem(xid); firetray.Handler.showHideIcon(); }, /** @@ -243,11 +240,10 @@ firetray.Window = { firetray.Window.setVisibility(xid, false); - if (firetray.Handler.popupMenuWindowItemsHandled()) - firetray.PopupMenu.showSingleWindowItem(xid); + firetray.PopupMenu.showSingleWindowItem(xid); firetray.Handler.showHideIcon(); - firetray.Handler.hideSingleWindow = firetray.Window.hideSingleStateful; + firetray.Handler.windows[xid].hide = firetray.Window.hideSingleStateful; // reset }, savePositionAndSize: function(xid) { @@ -459,9 +455,12 @@ firetray.Window = { getWindowTitle: function(xid) { let title = firetray.Handler.windows[xid].baseWin.title; + LOG("baseWin.title="+title); let tailIndex = title.indexOf(" - Mozilla "+firetray.Handler.appNameOriginal); if (tailIndex !== -1) - return title.substring(0, tailIndex) + return title.substring(0, tailIndex); + else if (title === "Mozilla "+firetray.Handler.appNameOriginal) + return title; else return null; }, @@ -554,12 +553,22 @@ firetray.Handler.registerWindow = function(win) { } catch (x) { firetray.Window.unregisterWindowByXID(xid); ERROR(x); - return false; + return null; + } + + if (!firetray.Handler.appStarted && + firetray.Utils.prefService.getBoolPref('start_hidden')) { + this.windows[xid].startHidden = true; + this.windows[xid].hide = firetray.Window.hideSingleStatelessOnce; + this.windows[xid].show = firetray.Window.showSingleStatelessOnce; + } else { + this.windows[xid].startHidden = false; + this.windows[xid].hide = firetray.Window.hideSingleStateful; + this.windows[xid].show = firetray.Window.showSingleStateful; } LOG("AFTER"); firetray.Handler.dumpWindows(); - - return true; + return xid; }; firetray.Handler.unregisterWindow = function(win) { @@ -568,6 +577,16 @@ firetray.Handler.unregisterWindow = function(win) { return firetray.Window.unregisterWindowByXID(xid); }; +firetray.Handler.showSingleWindow = function(xid) { + LOG("showSingleWindow xid="+xid); + this.windows[xid].show(xid); +}; + +firetray.Handler.hideSingleWindow = function(xid) { + LOG("hideSingleWindow xid="+xid); + this.windows[xid].hide(xid); +}; + firetray.Handler.showHideAllWindows = function(gtkStatusIcon, userData) { LOG("showHideAllWindows: "+userData); // NOTE: showHideAllWindows being a callback, we need to use