@@ -887,6 +887,28 @@ def _default_allow_remote(self):
887
887
"""
888
888
)
889
889
890
+ # The name of the app that started this server (if not started directly).
891
+ # It is sometimes important to know if + which another app (say a server extension)
892
+ # started the serverapp to properly configure some traits.
893
+ # This trait should not be configured by users. It will likely be set by ExtensionApp.
894
+ _starter_app_name = Unicode (None , allow_none = True )
895
+
896
+ @validate ('_starter_app_name' )
897
+ def _validate_starter_app (self , proposal ):
898
+ # Check that a previous server extension isn't named yet
899
+ value = proposal ["value" ]
900
+ if self ._starter_app_name != None :
901
+ raise TraitError ("Another extension was already named as the starter_server_extension." )
902
+ return value
903
+
904
+ @property
905
+ def starter_app (self ):
906
+ """Get the Extension that started this server."""
907
+ name = self ._starter_app_name
908
+ if name is None :
909
+ return
910
+ return self .extension_manager .extension_points .get (name , None ).app
911
+
890
912
open_browser = Bool (False , config = True ,
891
913
help = """Whether to open in a browser after starting.
892
914
The specific browser used is platform dependent and
@@ -895,6 +917,31 @@ def _default_allow_remote(self):
895
917
(ServerApp.browser) configuration option.
896
918
""" )
897
919
920
+
921
+ def _handle_browser_opening (self ):
922
+ """This method handles whether a browser should be opened.
923
+ By default, Jupyter Server doesn't try to open an browser. However,
924
+ it's many server extensions might want to open the browser by default.
925
+ This essentially toggles the default value for open_browser.
926
+
927
+ From a UX perspective, this needs to be surfaced to the user. The default
928
+ behavior of Jupyter Server switches, which can be confusing.
929
+ """
930
+ # If the server was started by another application, use that applications
931
+ # trait for the open_browser trait. If that trait is not given, ignore
932
+ if self .starter_app :
933
+ try :
934
+ if self .starter_app .open_browser :
935
+ self .launch_browser ()
936
+ # If the starter_app doesn't have an open_browser trait, ignore
937
+ # move on and don't start a browser.
938
+ except AttributeError :
939
+ pass
940
+ else :
941
+ if self .open_browser :
942
+ self .launch_browser ()
943
+
944
+
898
945
browser = Unicode (u'' , config = True ,
899
946
help = """Specify what command to use to invoke a web
900
947
browser when starting the server. If not specified, the
@@ -1807,8 +1854,8 @@ def start_app(self):
1807
1854
self .write_server_info_file ()
1808
1855
self .write_browser_open_file ()
1809
1856
1810
- if self . open_browser :
1811
- self .launch_browser ()
1857
+ # Handle the browser opening.
1858
+ self ._handle_browser_opening ()
1812
1859
1813
1860
if self .token and self ._token_generated :
1814
1861
# log full URL with generated token, so there's a copy/pasteable link
0 commit comments