When many tabs were open in temporary containers on exit of Firefox and the session is reopened on the next start of Firefox, the tabs stay inactive at first. When activating a tab, Firefox then reloads it. When that tab existed already in its own temporary container, TC nevertheless closes that tab and reopens it in a new temporary container.
This does not seem to be a big issue on its own, but causes a big problem with Tree Style Tab.
TST is an extension which is very useful when many tabs are open, as it arranges them in a collapsable tree view, showing a tab B as a child of tab A when B had been opened by clicking on a link in A. (It also allows to change the parent-child relationships manually.)
When a tab is replaced by TC on the first activation after restarting Firefox, it is removed and so loses its parent-child relationship in TST. The new tab created by TC seems to be at the correct tab index, but does not get its original parent which may cause its tab position to be changed by TST. Things get really bad when a parent tab is activated, because its replacement by TC causes all children to lose their parent. After a few tab activations, the whole tab tree is totally puzzeled.
The problem is related to the TC preference "Isolation/Global/Navigating in Tabs should open new Temporary Containers" as it only exist when that setting is different from "Never".
When "Isolation/Global/Navigating in Tabs should open new Temporary Containers" is used, existing tabs in temporary containers should not be replaced on their first activation after a restart of Firefox.
Would it be possible to distinguish the initial reload from opening a new URL typed into the tab's address bar by the user (tab navigation)?
The underlying problem here is that Firefox recreates tabs after a restart, but doesn't keep the openerTabIds intact, which essentially clears their relationship. The index is still correctly set. I'm not sure how TST is able retain the correct nesting of tabs - you say it does? I'd have to dive into their code to find out how they do it.
TST indeed retains the former nesting of tabs after restarting Firefox. It seems to be stored in the Firefox session (I was able to recreate a destroyed TST tree structure from the backup of a Firefox sessionstore file).
The problem I described is gone when I deactivate isolation on navigating. Firefox then does not seem to recreate tabs after restart but just reloads a discarded tab at its first activation. Are you saying that (with isolation on navigating activated) a reload of a discarded tab at its first activation after startup of Firefox cannot be distinguished from navigation to a different URL when entering one in the address bar?
The problem that caused me to open this issue no longer exists as TST (version 3.1.2) has fixed the parent-child relationship when tabs are being replaced by navigation isolation. So if you are not addressing the question "Why is the first tab activation after Firefox restart considered a navigation" (causing a replacement with a new temporary tab when the _Navigating in tabs_ isolation has been enabled) for some other reason, you can just close this issue.
I'm unfortunately unable to reproduce the reopening of tabs at Firefox startup.
v1.0beta7 includes a lot of request-handling refactoring - could you try and see if that maybe solves that bug? Otherwise it would be very helpful if you could provide your exported preferences (maybe want to to strip your per domain isolation configuration from the JSON file) and steps to reproduce, that would be very helpful, thanks!
For reproducing with version 0.103: Note that I also have _automatic mode_ enabled. The strange thing is, it depends on the web page what happens when activating a discarded tab that is already in a temporary container after Firefox startup: https://heise.de reloads in a _new_ temporary container, https://freefilesync.org/ reloads in the _original_ temporary container.
With v1.0beta7, the problem is gone.
Note, with v1.0beta7, the _Per domain_ configuration tab is empty. So I reverted back to 0.103.
With v1.0beta7, the problem is gone.
Nice, thanks for checking!
Note, with v1.0beta7, the Per domain configuration tab is empty.
That's bad. Is it completely blank or "just" the isolated domain list saying "No isolated domains added yet "? That might be a problem with migrating preferences from 0.103 to 1.0beta7. Could you by chance provide your exported preferences from 0.103 so that I can try to reproduce? That'd be great. If you don't want to post it here, maybe consider mailing it to [email protected] - I'll delete after testing. Thanks!
It was completely blank. The domain added with 0.103 was back when I reverted from 1.0beta7 to 0.103.
Thanks for letting me know. That means migration wasn't executed for you. I'm refactoring how migration of preferences is done to avoid that in the future (this already happened in the past - going to track progress in #112).
To make sure that migration works until that's fixed, you can export your 0.103 preferences, upgrade to 1.0beta7 and import the preferences there. Would you mind doing that and checking whether the tab replacement bug still doesn't occur in 1.0beta7 with your per domain isolation preferences in place?
After installing 1.0beta7, the per-domain setting was actually present. I did not have to import the settings exported with 0.103. The migration did include everything. But after a minute or so, the tab became empty again:

Nevertheless, my per-domain settings are still active.
I saw a few tab replacements after installing 1.0beta7 but before restarting Firefox. After the restart, I did not see another tab replacement.
I was able to reproduce the blank tab issues with the preferences you provided - looking into it, thanks!
Correction of my last comment: I just thought the per-domain settings that weakened some global isolation was properly migrated to 1.0beta7. However, isolation did not take place anymore at all. So I reverted back to 0.103 again.
Ok, so, v1.0beta13 fixes the blank per domain tab issue. Thank you very much for reporting and please let me know if you encounter another issue in the beta!
I still can't reproduce the tab replacement issue. Tried with your preferences and these steps:
heise.de in a tabThe beta now has a way of getting a debug log even when Firefox starts. To get it the same steps as described in debug log are required, but instead of log.DEBUG=true it needs localStorage.setItem('debug', true) (and setting to false when done accordingly). If you could provide that, it'd be very helpful. Thanks!
Reproduction of the issue seems to depend on the exact URL. Use these steps:
I sent you a log where I caught a tab replacement with v0.103. After starting Firefox and enabling the debug log, I selected two pages, faz.net (no tab replacement, reloaded in temporary container 636) and heise.de (tab replacement, started as temporary container 3, reloaded in temporary container 4).
I tried again with v1.0beta15 and sent you a log for this as well. Again here is a tab/container replacement. I selected the same pages, faz.net (no tab replacement, reloaded in temporary container 636) and heise.de (tab replacement, started as temporary container 7, reloaded in temporary container 8).
Thanks for providing the logs. What happens here is that for some reason the "Opener Tab" for the navigation to heise.de is Tree Style Tab with the url moz-extension://<tree-style-tab-id/resources/group-tab.html?title=Test&temporary=true. Do you maybe have an idea how this happens? Do you use Tree Style Tab somehow to open tabs?
I might be able to fix anyhow by checking that the opener tab url starts with http.
Should be fixed in v1.0beta16, please let me know if not.
The problem still exists with v1.0beta16.
Some explanations: Normally TST just creates parent-child relationships between tabs, but there is one case where TST creates a new tab: With several tabs or tab trees selected at the same time, you can group them from the context menu. This means, TST creates a new group tab as the parent of those selected tabs and tab trees and moves them all underneath that group tab. The content of the group tab itself, when activated, is a hierarchical view of the grouped tab's and tab trees' titles. These titles look like normal links, however do not open a new page when clicked but activate (switch to) the corresponding tab.
The TST tab you saw (named Test) was a group tab created some weeks ago and just happened to be selected when I then restarted Firefox (I hope I remember correctly). The tab activations for which I sent my last log, were both child tabs of that Test tab.
I sent you a new log with two tab activations. Both tabs have exact the same heise.de URL mentioned in one of my comments above. The first tab loaded in its original temporary container (631), the second tab started in temporary container 18 but then created a new temporary container 19 when it was loaded.
Both tabs were in the Test TST group tab, but I moved the first one manually to it recently, while the second one was there all the time so I think the group tab was created from it (and some other tabs).
I understand that navigation from an opener tab to a different tab causes isolation, but once this has taken place, why is the original opener tab still considered the current opener tab, even after Firefox has been restarted? Is this a problem caused by TST or can you do something that isolation is not executed twice?
Thanks for the log and explanation. Here's what I found:
TST group-tab id 305 in firefox-default container opens tab with id 308 in firefox-container-637 and heise.de as url.
TC detects container firefox-container-637 as permanent and ignores the request (id 147) because the opener is the TST tab which is in the firefox-default container. This scenario usually only happens if someone explicitly selects "Open Link in New Container Tab" in the link context menu (opener tab container different from loading container). I'm not sure why this request even happens. Do you by chance have another tab with heise.de in a permanent container?
Next comes in a request (id 169) in tab id 306 and firefox-container-660, also loading heise.de and opener is also the TST group-tab id 305. The container is not detected as permanent, so this is probably the "old TC tab" where heise.de should actually load in. TC now checks the opener domain against the request url (moz-extension:// vs heise.de) and decides to isolate because they're different, finally creating tab id 421 in firefox-container-661.
So my "fix" can't actually work - because isolation should behave exactly like that.
A possible fix here might be to detect TST and check for moz-extension://<internal-TST-id>/resources/group-tab.html and don't isolate in this case. TC has the management permission and can get information about installed Add-ons, unfortunately the <internal-TST-id> is something you can't get from the API - however, I guess a) the management API doesn't know about the correct TST path/file and b) it's unlikely that another extension opens tabs from that path/file - and I'm already doing something similar for MAC. However, this breaks if TST, or MAC for that matter, ever change the path/file.
Another way might be to provide a Exclude from Isolation if Originating from Domain option in TC and configure that with the appropriate file/path Exclusion/Domain Pattern. This however also can break, since the internal ID is regenerated if the Add-on or Firefox is reinstalled.
I guess having both wouldn't be too bad.
A "clean" and not breaking in the long run solution might be if TST implements an API which provides a list of full moz-extension:// urls which can open tabs, so TC can ignore them.
I'm wondering how TST works anyway - does it actually close tabs and create new ones with the original url on demand? If that's the case, old TCs might get removed because there's no tab in them anymore. I guess TST opens tabs whose container doesn't exist anymore in the firefox-default container, which would also result in reopening and new TC ids.
You said above that "TC detects container firefox-container-637 as permanent", but the tab I activated was _not_ permanent. It was just a normal numbered temporary container in the color I chose for temporary containers. So for this tab, the wrong detection as permanent container seems to cover the problem seen for the other tab. (Note that I actually do have heise.de open in a third tab in a permanent container, but there is nothing special, it works as expected.)
When I understand the concept of opener tab correctly, a tab navigating to a different domain that should be isolated due to the TC configuration becomes an opener tab for that domain, which is opened in a new tab in a temporary container.
From my user's perspective, there is no navigation after restart of Firefox. I just activated existing tabs, so there should not be an opener tab at all. However from your observations, TST seems to use an opener tab and navigation under the hood, causing the problem discussed here.
I suppose TST hooks into the tab activation, uses the activated tab as an opener tab so that it is fixed in the tree, and navigates to the former URL which is then either opened in the same tab or, when isolation takes place, in a new tab in a new/different container. In the latter case, the new tab can be at any tab position where Firefox created it, but TST then can move it to the position of the opener tab in the tree and remove the opener tab itself. So it can keep the activated tab visibly in place even when isolation causes a replacement with a new tab.
Note when Firefox is restarted after disabling TST, the problem is gone, and when Firefox is again restarted after re-enabling TST, the problem comes back.
I am speculating here and trying to understand and explain, but I am really not sure about my ideas. I would suggest you contact @piroor directly or ask at piroor/treestyletab for a TST API TC can use (or vice versa).
What can/should TST do for this compatibility issue?
By the way, if you are OK to do it asynchronously, you can detect a tab is/isn't group tab with an API call like:
let isTSTGroupTab = false;
try {
let treeItem = await browser.runtime.sendMessage('[email protected]', { type: 'get-tree', tab: tab.id });
isTSTGroupTab = treeItem && treeItem.states.includes('group-tab');
}
catch(e) {
}
if (isTSTGroupTab) { ... }
Oh, wow, TST already has an extensive and well documented API, that's great news!
I'm totally fine with using the message async as described. That makes it an easy and reliable fix, thanks @piroor!
Should be fixed in v1.0beta20.
Most helpful comment
Should be fixed in v1.0beta20.