-
-
Notifications
You must be signed in to change notification settings - Fork 99
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix extra tab #737
Fix extra tab #737
Conversation
Probably needs splitting into two PRs. |
cd50a2d
to
6de245a
Compare
Now only fixes the linked issue. A separate PR dealing with option handling will be prepared later. |
src/Application.vala
Outdated
@@ -201,7 +201,11 @@ public class Terminal.Application : Gtk.Application { | |||
); | |||
|
|||
var new_window_action = new SimpleAction ("new-window", null); | |||
new_window_action.activate.connect (new_window); | |||
new_window_action.activate.connect (() => { | |||
var win = new MainWindow (this, false); // Do not restore tabs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this will break having the first window be created by the action when we enable DBus activation (the only thing that was stopping us of doing that was the duplicate tab). so the active_window == null
is necessary here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure what this means 😞 as I am not sure how DBus activation works. Could you give more details or suggested code?
The idea with the rewrite is that working directory isn't a "real" option, so it shouldn't cause different behaviour by itself.
the behaviour of opening a new tab when invoked in a directory without a tab already open is also intentional. the rationale is that any command line invocation is done with the intention of open a tab or window, so it act as a "weakened" (it won't create a tab, if one in the current directory already exists) version of if we are going to change the behaviour here, i would prefer that it's to drop the weakened |
src/Application.vala
Outdated
// Only if no other tabs, add default tab | ||
add_default_tab (window, false); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this won't respect the current working directory as the others.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whether or not it respects the current working directory depends on the "follow-last-tab" setting (that is what the default tab does) since it uses the action-new-tab. This is for consistency with other situations where there is no specified tab.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This also replaces functionality removed from MainWindow so I want to keep the behaviour the same.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is already being inconsistent with the others command line options handling, where the current working directory is always respected. the code in the action-new-tab won't respect it either, it will either use the last tab directory or the current working directory of the first invocation.
} else { | ||
new_tab (Environment.get_current_dir ()); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's better to keep any "current directory" concept exclusive to the application class. because of the local/primary instance logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So what do you suggest?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: Environment.get_current_dir () is already in use in TerminalWidget
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So what do you suggest?
Only the Application class known the real working directory for the current invocation, so either action-new-tab is updated to take a path, or we don't try to use the action in the command line context, where is the only place that a concept of working directory exists.
Note: Environment.get_current_dir () is already in use in TerminalWidget
It actually isn't, the only place that we call activate_shell() without a location is in the case that we call new_tab() with a empty location, what isn't possible.
src/tests/Application.vala
Outdated
@@ -145,7 +145,7 @@ namespace Terminal.Test.Application { | |||
unowned var window = (MainWindow) application.active_window; | |||
assert_nonnull (window); | |||
var n_tabs = (int) window.terminals.length (); | |||
assert_cmpint (n_tabs, CompareOperator.EQ, 2); | |||
assert_cmpint (n_tabs, CompareOperator.EQ, 1); // No default tab added as well in this case |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this test was made to assert that we always create a new tab when requested, so this change is wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is necessary for the test to pass. If the original test is correct then the app is wrong
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you run io.elementary.terminal -t
manually without a Terminal window open you get one tab (as expected). If you run the same command with the primary window open (but no restored tabs) then you get 2 tabs - the original default one and the requested additional one.
I am not exactly sure what happens in the test environment - does a window get created before the options are processed or not?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After some investigation it seems like before processing the commandline in option ()
there is 1 window with 1 tab. So I would have expected -t
true to create a new tab like when used manually. But it doesn't in the test environment for some reason.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, so it is race - the callback is executed before the window terminal list is updated in the on_tab_added
signal handler. Need to get a more immediate count of true number of tabs in the notebook. I'll review whether the terminals list is needed or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so, what's happening here is that add_tab_with_working_directory()
is matching the already existent tab (from the first launch), and add_default_tab()
is not creating one because window.terminals.length () == 1
.
src/tests/Application.vala
Outdated
|
||
// valid | ||
option ("{'execute':<[b'%s']>}".printf (string.joinv ("',b'", execute)), "@a{sv} {}", () => { | ||
unowned var window = (MainWindow) application.active_window; | ||
assert_nonnull (window); | ||
var n_tabs = (int) window.terminals.length (); | ||
assert_cmpint (n_tabs, CompareOperator.EQ, 5); // include the guaranted extra tab | ||
assert_cmpint (n_tabs, CompareOperator.EQ, 5); // Includes initial default tab added when no tabs restored. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
now that we aren't creating the extra tab, this should be 4.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm then it should be failing - will investigate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So what I think is happening is that the test environment opens a window without restoring tabs before processing the option. So there is already a default tab in the window and the execute option creates 4 more, one for each command, giving a total of 5. However this does not seem to be the case for the -t
option test so tbh I am not on what exactly happening in the test environment.
If you manually execute multiple commands before any window is opened e.g. with a commandline io.elementary.terminal -e "true" -e "echo Hi"
then no extra default tab appears.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Further investigation indicates that 5 tabs are added during this test including one due to a restore-saved-tabs attempt that should not be happening.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
simillary as the new-tab test, there's 1 tab from first launch, and 4 from the commands, the sixty one seems strange.
Not sure what this means. The |
Again, I do not understand this. The change (and the whole PR) is about not opening two tabs when the user would expect only one. The change from |
There is a case for reconsidering whether we need both |
Elementary Terminal is currently different from other terminals in that it has a "follow-last-tab" setting (unexposed) that is by default |
This would make commandline invocation different from invocation from the dock or App Menu which both just focus an existing primary window, so I disagree. Interestingly |
@Marukesu I'm going to have to ask you to look at that race issue in the testing of adding tabs I am afraid. I tried a few things but I do not fully understand the code 😞 Even getting the UPDATE: Wait a minute I think I have been misinterpreting the logs - there are two calls to |
Not sure why we're getting the expected tab count in the |
So it seems that for each call to |
yes it does, that is the only way to test the options and actions without having interference of the command line. the first invocation override the default handler, so for the tests, the second invocation appears as if it was the first one. to be a little more clear: var app = new Terminal.Application ();
ulong signal_id = app.command_line.connect (() => { // this override the command_line () implementation of Terminal.Application
app.disconnect (signal_id); // make the next command_line() call go to the default handler
// ... EDIT: oh, sorry, now i see, you say the second line in the overriden launching, it's needed because some of the test can only be properly tested in a secondary launching (like the new-window test), so it tries to act if the command_line was called with a already existent instance. |
I have found a fix for the tests by allowing the test to choose whether or not |
I'll have another look tomorrow - I've been down enough rabbit holes and followed enough red herrings today 😝 |
Closing as this has become too complicated/contentious. I'll try and find a simpler, if more limited, solution to the immediate issue of unwanted tabs being added every time the terminal is launched from the dock. |
Fixes #736
-w
option) when an instance is already running in order to allow different behaviour for-t
option It is an open question whether the-t
option should behave the same as the new-tab action (honor "follow-last-tab" setting). It also fixes a small issue in master where if Terminal is launched withio.elementary.terminal
when an instance is already added then a new unrequested tab is added to the first window.To clarify what is going on, MainWindow does not automatically add a default tab.
TESTING
Where is the path to a folder that is not amongst the saved tabs.
With History/restore-tabs ON:
Open first instance of Terminal from command line with
io.elementary.terminal -nw <folder-path>
Terminal opens containing one tab at the requested path plus restored tabs
Close Terminal and reopen with
io.elementary.terminal
Terminal opens with restored tabs including the requested path
Now open second instance of Terminal from the command line with
io.elementary.terminal -nw <folder-path>
A new window opens containing only the requested tab (difference from master - fixes issue)
Close the first window then close the second window
Reopen Terminal
Terminal opens with only the tab from the second (last closed) window
Open second instance with `io.elementary.terminal -w
The first window is focused with the tab selected (already exists)
Open second instance with `io.elementary.terminal -w
The first window is focused with an additional tab at the new path - the new tab is selected
Open second instance with
io.elementary.terminal -t
The first window is focused with an additional tab at the current working directory.
Open second instance with
io.elementary.terminal -nt
A new window is opened with a single tab at the current working directory.
Open a second instance
io.elementary.terminal
The first window is focused and no extra tab added (difference from
master
)With History/restore-tabs OFF
Open first instance of Terminal from command line with
io.elementary.terminal -nw <folder-path>
Terminal opens containing one tab at the requested path.
Close Terminal and reopen with
io.elementary.terminal
Terminal opens with the default tab
Now open second instance of Terminal from the command line with
io.elementary.terminal -nw <folder-path>
A new window opens containing only the requested tab (difference from master - fixes issue)
Close the first window then close the second window
Reopen Terminal
Terminal opens with the default tab
Running Commands
The
-e
and-x
options behave similarly. If they create the first window then tabs are restored (if settings permit) and then an additional tab at the current working directory is created for each command to run in. If used with the-n
option to create an additional window then only tabs running the commands are created.