caller's environment.
-.. function:: register(name, constructor, instance=None)
+.. function:: register(name, constructor, instance=None, *, preferred=False)
Register the browser type *name*. Once a browser type is registered, the
:func:`get` function can return a controller for that browser type. If
parameters to create an instance when needed. If *instance* is provided,
*constructor* will never be called, and may be ``None``.
- This entry point is only useful if you plan to either set the :envvar:`BROWSER`
- variable or call :func:`get` with a nonempty argument matching the name of a
- handler you declare.
+ Setting *preferred* to ``True`` makes this browser a preferred result for
+ a :func:`get` call with no argument. Otherwise, this entry point is only
+ useful if you plan to either set the :envvar:`BROWSER` variable or call
+ :func:`get` with a nonempty argument matching the name of a handler you
+ declare.
A number of browser types are predefined. This table gives the type names that
may be passed to the :func:`get` function and the corresponding instantiations
class Error(Exception):
pass
-_browsers = {} # Dictionary of available browser controllers
-_tryorder = [] # Preference order of available browsers
+_browsers = {} # Dictionary of available browser controllers
+_tryorder = [] # Preference order of available browsers
+_os_preferred_browser = None # The preferred browser
-def register(name, klass, instance=None, update_tryorder=1):
- """Register a browser connector and, optionally, connection."""
+def register(name, klass, instance=None, *, preferred=False):
+ """Register a browser connector."""
_browsers[name.lower()] = [klass, instance]
- if update_tryorder > 0:
- _tryorder.append(name)
- elif update_tryorder < 0:
+
+ # Preferred browsers go to the front of the list.
+ # Need to match to the default browser returned by xdg-settings, which
+ # may be of the form e.g. "firefox.desktop".
+ if preferred or (_os_preferred_browser and name in _os_preferred_browser):
_tryorder.insert(0, name)
+ else:
+ _tryorder.append(name)
def get(using=None):
"""Return a browser launcher instance appropriate for the environment."""
# Prefer X browsers if present
if os.environ.get("DISPLAY"):
+ try:
+ cmd = "xdg-settings get default-web-browser".split()
+ result = subprocess.check_output(cmd).decode().strip()
+ except (FileNotFoundError, subprocess.CalledProcessError):
+ pass
+ else:
+ _os_preferred_browser = result
+
register_X_browsers()
# Also try console browsers
# Don't clear _tryorder or _browsers since OS X can use above Unix support
# (but we prefer using the OS X specific stuff)
- register("safari", None, MacOSXOSAScript('safari'), -1)
- register("firefox", None, MacOSXOSAScript('firefox'), -1)
- register("chrome", None, MacOSXOSAScript('chrome'), -1)
- register("MacOSX", None, MacOSXOSAScript('default'), -1)
+ register("safari", None, MacOSXOSAScript('safari'), preferred=True)
+ register("firefox", None, MacOSXOSAScript('firefox'), preferred=True)
+ register("chrome", None, MacOSXOSAScript('chrome'), preferred=True)
+ register("MacOSX", None, MacOSXOSAScript('default'), preferred=True)
# OK, now that we know what the default preference orders for each
if cmdline != '':
cmd = _synthesize(cmdline, -1)
if cmd[1] is None:
- register(cmdline, None, GenericBrowser(cmdline), -1)
+ register(cmdline, None, GenericBrowser(cmdline), preferred=True)
cmdline = None # to make del work if _userchoices was empty
del cmdline
del _userchoices
- Issue #23262: The webbrowser module now supports Firefox 36+ and derived
browsers. Based on patch by Oleg Broytman.
+- Issue #24241: The webbrowser in an X environment now prefers using the
+ default browser directly. Also, the webbrowser register() function now has
+ a documented 'preferred' argument, to specify browsers to be returned by
+ get() with no arguments. Patch by David Steele
+
- Issue #27939: Fixed bugs in tkinter.ttk.LabeledScale and tkinter.Scale caused
by representing the scale as float value internally in Tk. tkinter.IntVar
now works if float value is set to underlying Tk variable.