示例#1
0
def first_opened_window() -> 'mainwindow.MainWindow':
    """Get the first opened window object."""
    for idx in range(0, len(window_registry)+1):
        window = _window_by_index(idx)
        if not window.tabbed_browser.is_shutting_down:
            return window
    raise utils.Unreachable()
示例#2
0
文件: bar.py 项目: mkonig/qutebrowser
 def _get_widget_from_config(self, key):
     """Return the widget that fits with config string key."""
     if key == 'url':
         return self.url
     elif key == 'scroll':
         return self.percentage
     elif key == 'scroll_raw':
         return self.percentage
     elif key == 'history':
         return self.backforward
     elif key == 'tabs':
         return self.tabindex
     elif key == 'keypress':
         return self.keystring
     elif key == 'progress':
         return self.prog
     elif key == 'search_match':
         return self.search_match
     elif key.startswith('text:'):
         new_text_widget = textbase.TextBase()
         self._text_widgets.append(new_text_widget)
         return new_text_widget
     elif key.startswith('clock:') or key == 'clock':
         return self.clock
     else:
         raise utils.Unreachable(key)
def _variant(versions: version.WebEngineVersions) -> Variant:
    """Get the dark mode variant based on the underlying Qt version."""
    env_var = os.environ.get('QUTE_DARKMODE_VARIANT')
    if env_var is not None:
        try:
            return Variant[env_var]
        except KeyError:
            log.init.warning(
                f"Ignoring invalid QUTE_DARKMODE_VARIANT={env_var}")

    if (versions.webengine == utils.VersionNumber(5, 15, 2)
            and versions.chromium_major == 87):
        # WORKAROUND for Gentoo packaging something newer as 5.15.2...
        return Variant.qt_515_3
    elif versions.webengine >= utils.VersionNumber(5, 15, 3):
        return Variant.qt_515_3
    elif versions.webengine >= utils.VersionNumber(5, 15, 2):
        return Variant.qt_515_2
    elif versions.webengine == utils.VersionNumber(5, 15, 1):
        return Variant.qt_515_1
    elif versions.webengine == utils.VersionNumber(5, 15):
        return Variant.qt_515_0
    elif versions.webengine >= utils.VersionNumber(5, 14):
        return Variant.qt_514
    elif versions.webengine >= utils.VersionNumber(5, 11):
        return Variant.qt_511_to_513
    raise utils.Unreachable(versions.webengine)
示例#4
0
def create(*,
           splitter: 'miscwidgets.InspectorSplitter',
           win_id: int,
           parent: QWidget = None) -> 'AbstractWebInspector':
    """Get a WebKitInspector/WebEngineInspector.

    Args:
        splitter: InspectorSplitter where the inspector can be placed.
        win_id: The window ID this inspector is associated with.
        parent: The Qt parent to set.
    """
    # Importing modules here so we don't depend on QtWebEngine without the
    # argument and to avoid circular imports.
    if objects.backend == usertypes.Backend.QtWebEngine:
        from qutebrowser.browser.webengine import webengineinspector
        if webengineinspector.supports_new():
            return webengineinspector.WebEngineInspector(
                splitter, win_id, parent)
        else:
            return webengineinspector.LegacyWebEngineInspector(
                splitter, win_id, parent)
    elif objects.backend == usertypes.Backend.QtWebKit:
        from qutebrowser.browser.webkit import webkitinspector
        return webkitinspector.WebKitInspector(splitter, win_id, parent)
    raise utils.Unreachable(objects.backend)
示例#5
0
    def matches(self, other):
        """Check whether the given KeySequence matches with this one.

        We store multiple QKeySequences with <= 4 keys each, so we need to
        match those pair-wise, and account for an unequal amount of sequences
        as well.
        """
        # pylint: disable=protected-access

        if len(self._sequences) > len(other._sequences):
            # If we entered more sequences than there are in the config,
            # there's no way there can be a match.
            return QKeySequence.NoMatch

        for entered, configured in zip(self._sequences, other._sequences):
            # If we get NoMatch/PartialMatch in a sequence, we can abort there.
            match = entered.matches(configured)
            if match != QKeySequence.ExactMatch:
                return match

        # We checked all common sequences and they had an ExactMatch.
        #
        # If there's still more sequences configured than entered, that's a
        # PartialMatch, as more keypresses can still follow and new sequences
        # will appear which we didn't check above.
        #
        # If there's the same amount of sequences configured and entered,
        # that's an EqualMatch.
        if len(self._sequences) == len(other._sequences):
            return QKeySequence.ExactMatch
        elif len(self._sequences) < len(other._sequences):
            return QKeySequence.PartialMatch
        else:
            raise utils.Unreachable("self={!r} other={!r}".format(self, other))
示例#6
0
    def test_config_source(self, tmp_path, commands, config_stub,
                           config_tmpdir, location, clear):
        assert config_stub.val.content.javascript.enabled
        config_stub.val.search.ignore_case = 'always'

        if location == 'default':
            pyfile = config_tmpdir / 'config.py'
            arg = None
        elif location == 'absolute':
            pyfile = tmp_path / 'sourced.py'
            arg = str(pyfile)
        elif location == 'relative':
            pyfile = config_tmpdir / 'sourced.py'
            arg = 'sourced.py'
        else:
            raise utils.Unreachable(location)

        pyfile.write_text('\n'.join([
            'config.load_autoconfig(False)',
            'c.content.javascript.enabled = False'
        ]),
                          encoding='utf-8')

        commands.config_source(arg, clear=clear)

        assert not config_stub.val.content.javascript.enabled
        ignore_case = config_stub.val.search.ignore_case
        assert ignore_case == (usertypes.IgnoreCase.smart
                               if clear else usertypes.IgnoreCase.always)
示例#7
0
def process(tab: apitypes.Tab, pid: int = None, action: str = 'show') -> None:
    """Manage processes spawned by qutebrowser.

    Note that processes with a successful exit get cleaned up after 1h.

    Args:
        pid: The process ID of the process to manage.
        action: What to do with the given process:

            - show: Show information about the process.
            - terminate: Try to gracefully terminate the process (SIGTERM).
            - kill: Kill the process forcefully (SIGKILL).
    """
    if pid is None:
        if last_pid is None:
            raise cmdutils.CommandError("No process executed yet!")
        pid = last_pid

    try:
        proc = all_processes[pid]
    except KeyError:
        raise cmdutils.CommandError(f"No process found with pid {pid}")

    if proc is None:
        raise cmdutils.CommandError(f"Data for process {pid} got cleaned up")

    if action == 'show':
        tab.load_url(QUrl(f'qute://process/{pid}'))
    elif action == 'terminate':
        proc.terminate()
    elif action == 'kill':
        proc.terminate(kill=True)
    else:
        raise utils.Unreachable(action)
示例#8
0
def _variant() -> Variant:
    """Get the dark mode variant based on the underlying Qt version."""
    if PYQT_WEBENGINE_VERSION is not None:
        # Available with Qt >= 5.13
        if PYQT_WEBENGINE_VERSION >= 0x050f02:
            return Variant.qt_515_2
        elif PYQT_WEBENGINE_VERSION == 0x050f01:
            return Variant.qt_515_1
        elif PYQT_WEBENGINE_VERSION == 0x050f00:
            return Variant.qt_515_0
        elif PYQT_WEBENGINE_VERSION >= 0x050e00:
            return Variant.qt_514
        elif PYQT_WEBENGINE_VERSION >= 0x050d00:
            return Variant.qt_511_to_513
        raise utils.Unreachable(hex(PYQT_WEBENGINE_VERSION))

    # If we don't have PYQT_WEBENGINE_VERSION, we'll need to assume based on the Qt
    # version.
    assert not qtutils.version_check(  # type: ignore[unreachable]
        '5.13', compiled=False)

    if qtutils.version_check('5.11', compiled=False):
        return Variant.qt_511_to_513
    elif qtutils.version_check('5.10', compiled=False):
        return Variant.qt_510

    return Variant.unavailable
示例#9
0
def create(win_id: int,
           private: bool,
           parent: QWidget = None) -> 'AbstractTab':
    """Get a QtWebKit/QtWebEngine tab object.

    Args:
        win_id: The window ID where the tab will be shown.
        private: Whether the tab is a private/off the record tab.
        parent: The Qt parent to set.
    """
    # Importing modules here so we don't depend on QtWebEngine without the
    # argument and to avoid circular imports.
    mode_manager = modeman.instance(win_id)
    if objects.backend == usertypes.Backend.QtWebEngine:
        from qutebrowser.browser.webengine import webenginetab
        tab_class: Type[AbstractTab] = webenginetab.WebEngineTab
    elif objects.backend == usertypes.Backend.QtWebKit:
        from qutebrowser.browser.webkit import webkittab
        tab_class = webkittab.WebKitTab
    else:
        raise utils.Unreachable(objects.backend)
    return tab_class(win_id=win_id,
                     mode_manager=mode_manager,
                     private=private,
                     parent=parent)
示例#10
0
def _show_dialog(*args, **kwargs):
    """Show a dialog for a backend problem."""
    cmd_args = objreg.get('args')
    if cmd_args.no_err_windows:
        text = _error_text(*args, **kwargs)
        print(text, file=sys.stderr)
        sys.exit(usertypes.Exit.err_init)

    dialog = _Dialog(*args, **kwargs)

    status = dialog.exec_()
    quitter = objreg.get('quitter')

    if status in [_Result.quit, QDialog.Rejected]:
        pass
    elif status == _Result.restart_webkit:
        quitter.restart(override_args={'backend': 'webkit'})
    elif status == _Result.restart_webengine:
        quitter.restart(override_args={'backend': 'webengine'})
    elif status == _Result.restart:
        quitter.restart()
    else:
        raise utils.Unreachable(status)

    sys.exit(usertypes.Exit.err_init)
示例#11
0
def _select_backend(config):
    """Select the backend for running tests.

    The backend is auto-selected in the following manner:
    1. Use QtWebKit if available
    2. Otherwise use QtWebEngine as a fallback

    Auto-selection is overridden by either passing a backend via
    `--qute-backend=<backend>` or setting the environment variable
    `QUTE_TESTS_BACKEND=<backend>`.

    Args:
        config: pytest config

    Raises:
        ImportError if the selected backend is not available.

    Returns:
        The selected backend as a string (e.g. 'webkit').
    """
    backend_arg = config.getoption('--qute-backend')
    backend_env = os.environ.get('QUTE_TESTS_BACKEND')

    backend = backend_arg or backend_env or _auto_select_backend()

    # Fail early if selected backend is not available
    if backend == 'webkit':
        import PyQt5.QtWebKitWidgets
    elif backend == 'webengine':
        import PyQt5.QtWebEngineWidgets
    else:
        raise utils.Unreachable(backend)

    return backend
示例#12
0
def _variant() -> Variant:
    """Get the dark mode variant based on the underlying Qt version."""
    env_var = os.environ.get('QUTE_DARKMODE_VARIANT')
    if env_var is not None:
        try:
            return Variant[env_var]
        except KeyError:
            log.init.warning(
                f"Ignoring invalid QUTE_DARKMODE_VARIANT={env_var}")

    if PYQT_WEBENGINE_VERSION is not None:
        # Available with Qt >= 5.13
        if PYQT_WEBENGINE_VERSION >= 0x050f02:
            return Variant.qt_515_2
        elif PYQT_WEBENGINE_VERSION == 0x050f01:
            return Variant.qt_515_1
        elif PYQT_WEBENGINE_VERSION == 0x050f00:
            return Variant.qt_515_0
        elif PYQT_WEBENGINE_VERSION >= 0x050e00:
            return Variant.qt_514
        elif PYQT_WEBENGINE_VERSION >= 0x050d00:
            return Variant.qt_511_to_513
        raise utils.Unreachable(hex(PYQT_WEBENGINE_VERSION))

    # If we don't have PYQT_WEBENGINE_VERSION, we're on 5.12 (or older, but 5.12 is the
    # oldest supported version).
    assert not qtutils.version_check(  # type: ignore[unreachable]
        '5.13', compiled=False)

    return Variant.qt_511_to_513
示例#13
0
    def queryProxy(self, query):
        """Get the QNetworkProxies for a query.

        Args:
            query: The QNetworkProxyQuery to get a proxy for.

        Return:
            A list of QNetworkProxy objects in order of preference.
        """
        proxy = config.val.content.proxy
        if proxy is configtypes.SYSTEM_PROXY:
            # On Linux, use "export http_proxy=socks5://host:port" to manually
            # set system proxy.
            # ref. https://doc.qt.io/qt-5/qnetworkproxyfactory.html#systemProxyForQuery
            proxies = QNetworkProxyFactory.systemProxyForQuery(query)
        elif isinstance(proxy, pac.PACFetcher):
            if objects.backend == usertypes.Backend.QtWebEngine:
                # Looks like query.url() is always invalid on QtWebEngine...
                proxy = urlutils.proxy_from_url(QUrl('direct://'))
                assert not isinstance(proxy, pac.PACFetcher)
                proxies = [proxy]
            elif objects.backend == usertypes.Backend.QtWebKit:
                proxies = proxy.resolve(query)
            else:
                raise utils.Unreachable(objects.backend)
        else:
            proxies = [proxy]
        for proxy in proxies:
            self._set_capabilities(proxy)
        return proxies
示例#14
0
    def _process_text(self, data: QByteArray, attr: str) -> None:
        """Process new stdout/stderr text.

        Arguments:
            data: The new process data.
            attr: Either 'stdout' or 'stderr'.
        """
        text = self._decode_data(data)

        if '\r' in text and not utils.is_windows:
            # Crude handling of CR for e.g. progress output.
            # Discard everything before the last \r in the new input, then discard
            # everything after the last \n in self.stdout/self.stderr.
            text = text.rsplit('\r', maxsplit=1)[-1]
            existing = getattr(self, attr)
            if '\n' in existing:
                new = existing.rsplit('\n', maxsplit=1)[0] + '\n'
            else:
                new = ''
            setattr(self, attr, new)

        if attr == 'stdout':
            self.stdout += text
        elif attr == 'stderr':
            self.stderr += text
        else:
            raise utils.Unreachable(attr)
示例#15
0
    def _partition(self):
        """Divide the commandline text into chunks around the cursor position.

        Return:
            ([parts_before_cursor], 'part_under_cursor', [parts_after_cursor])
        """
        text = self._cmd.text()[len(self._cmd.prefix()):]
        if not text or not text.strip():
            # Only ":", empty part under the cursor with nothing before/after
            return [], '', []
        parser = runners.CommandParser()
        result = parser.parse(text, fallback=True, keep=True)
        parts = [x for x in result.cmdline if x]
        pos = self._cmd.cursorPosition() - len(self._cmd.prefix())
        pos = min(pos, len(text))  # Qt treats 2-byte UTF-16 chars as 2 chars
        log.completion.debug('partitioning {} around position {}'.format(parts,
                                                                         pos))
        for i, part in enumerate(parts):
            pos -= len(part)
            if pos <= 0:
                if part[pos-1:pos+1].isspace():
                    # cursor is in a space between two existing words
                    parts.insert(i, '')
                prefix = [x.strip() for x in parts[:i]]
                center = parts[i].strip()
                # strip trailing whitespace included as a separate token
                postfix = [x.strip() for x in parts[i+1:] if not x.isspace()]
                log.completion.debug(
                    "partitioned: {} '{}' {}".format(prefix, center, postfix))
                return prefix, center, postfix

        raise utils.Unreachable("Not all parts consumed: {}".format(parts))
示例#16
0
    def _handle_special_call_arg(self, *, pos, param, win_id, args, kwargs):
        """Check whether the argument is special, and if so, fill it in.

        Args:
            pos: The position of the argument.
            param: The argparse.Parameter.
            win_id: The window ID the command is run in.
            args/kwargs: The args/kwargs to fill.

        Return:
            True if it was a special arg, False otherwise.
        """
        arg_info = self.get_arg_info(param)
        if pos == 0 and self._instance is not None:
            assert param.kind == inspect.Parameter.POSITIONAL_OR_KEYWORD
            self_value = self._get_objreg(win_id=win_id,
                                          name=self._instance,
                                          scope=self._scope)
            self._add_special_arg(value=self_value,
                                  param=param,
                                  args=args,
                                  kwargs=kwargs)
            return True
        elif arg_info.value == usertypes.CommandValue.count:
            if self._count is None:
                assert param.default is not inspect.Parameter.empty
                value = param.default
            else:
                value = self._count
            self._add_special_arg(value=value,
                                  param=param,
                                  args=args,
                                  kwargs=kwargs)
            return True
        elif arg_info.value == usertypes.CommandValue.win_id:
            self._add_special_arg(value=win_id,
                                  param=param,
                                  args=args,
                                  kwargs=kwargs)
            return True
        elif arg_info.value == usertypes.CommandValue.cur_tab:
            tab = self._get_objreg(win_id=win_id, name='tab', scope='tab')
            self._add_special_arg(value=tab,
                                  param=param,
                                  args=args,
                                  kwargs=kwargs)
            return True
        elif arg_info.value == usertypes.CommandValue.count_tab:
            self._add_count_tab(win_id=win_id,
                                param=param,
                                args=args,
                                kwargs=kwargs)
            return True
        elif arg_info.value is None:
            pass
        else:
            raise utils.Unreachable(arg_info)

        return False
示例#17
0
 def resource_root(self, request):
     """Resource files packaged either directly or via a zip."""
     if request.param == 'pathlib':
         request.getfixturevalue('html_path')
         return request.getfixturevalue('package_path')
     elif request.param == 'zipfile':
         return request.getfixturevalue('html_zip')
     raise utils.Unreachable(request.param)
示例#18
0
def _backend() -> str:
    """Get the backend line with relevant information."""
    if objects.backend == usertypes.Backend.QtWebKit:
        return 'new QtWebKit (WebKit {})'.format(qWebKitVersion())
    elif objects.backend == usertypes.Backend.QtWebEngine:
        webengine = usertypes.Backend.QtWebEngine
        assert objects.backend == webengine, objects.backend
        return 'QtWebEngine (Chromium {})'.format(_chromium_version())
    raise utils.Unreachable(objects.backend)
示例#19
0
def _backend() -> str:
    """Get the backend line with relevant information."""
    if objects.backend == usertypes.Backend.QtWebKit:
        return 'new QtWebKit (WebKit {})'.format(qWebKitVersion())
    elif objects.backend == usertypes.Backend.QtWebEngine:
        return str(
            qtwebengine_versions(
                avoid_init='avoid-chromium-init' in objects.debug_flags))
    raise utils.Unreachable(objects.backend)
示例#20
0
 def setText(self, text: str) -> None:
     """Extend setText to set prefix and make sure the prompt is ok."""
     if not text:
         pass
     elif text[0] in modeparsers.STARTCHARS:
         super().set_prompt(text[0])
     else:
         raise utils.Unreachable("setText got called with invalid text "
                                 "'{}'!".format(text))
     super().setText(text)
示例#21
0
def shutdown() -> None:
    """Shut down QWeb(Engine)Settings."""
    if objects.backend == usertypes.Backend.QtWebEngine:
        from qutebrowser.browser.webengine import webenginesettings
        webenginesettings.shutdown()
    elif objects.backend == usertypes.Backend.QtWebKit:
        from qutebrowser.browser.webkit import webkitsettings
        webkitsettings.shutdown()
    else:
        raise utils.Unreachable(objects.backend)
示例#22
0
    def _handle_single_key(self, e):
        """Handle a new keypress with a single key (no modifiers).

        Separate the keypress into count/command, then check if it matches
        any possible command, and either run the command, ignore it, or
        display an error.

        Args:
            e: the KeyPressEvent from Qt.

        Return:
            A self.Match member.
        """
        txt = e.text()
        key = e.key()
        self._debug_log("Got key: 0x{:x} / text: '{}'".format(key, txt))

        if len(txt) == 1:
            category = unicodedata.category(txt)
            is_control_char = (category == 'Cc')
        else:
            is_control_char = False

        if (not txt) or is_control_char:
            self._debug_log("Ignoring, no text char")
            return self.Match.none

        count, cmd_input = self._split_count(self._keystring + txt)
        match, binding = self._match_key(cmd_input)
        if match == self.Match.none:
            mappings = config.val.bindings.key_mappings
            mapped = mappings.get(txt, None)
            if mapped is not None:
                txt = mapped
                count, cmd_input = self._split_count(self._keystring + txt)
                match, binding = self._match_key(cmd_input)

        self._keystring += txt
        if match == self.Match.definitive:
            self._debug_log("Definitive match for '{}'.".format(
                self._keystring))
            self.clear_keystring()
            self.execute(binding, self.Type.chain, count)
        elif match == self.Match.partial:
            self._debug_log("No match for '{}' (added {})".format(
                self._keystring, txt))
        elif match == self.Match.none:
            self._debug_log("Giving up with '{}', no matches".format(
                self._keystring))
            self.clear_keystring()
        elif match == self.Match.other:
            pass
        else:
            raise utils.Unreachable("Invalid match value {!r}".format(match))
        return match
示例#23
0
            def _fake_version(name):
                if name == 'PyQtWebEngine-Qt':
                    outcome = qt
                elif name == 'PyQtWebEngine-Qt5':
                    outcome = qt5
                else:
                    raise utils.Unreachable(outcome)

                if outcome is None:
                    raise importlib_metadata.PackageNotFoundError(name)
                return outcome
示例#24
0
def clear_private_data() -> None:
    """Clear cookies, cache and related data for private browsing sessions."""
    if objects.backend == usertypes.Backend.QtWebEngine:
        from qutebrowser.browser.webengine import webenginesettings
        webenginesettings.init_private_profile()
    elif objects.backend == usertypes.Backend.QtWebKit:
        from qutebrowser.browser.webkit import cookies
        assert cookies.ram_cookie_jar is not None
        cookies.ram_cookie_jar.setAllCookies([])
    else:
        raise utils.Unreachable(objects.backend)
示例#25
0
    def _init_adapter(self) -> None:
        """Initialize the adapter to use based on the config."""
        setting = config.val.content.notifications.presenter
        log.misc.debug(f"Setting up notification adapter ({setting})...")

        if setting == "qt":
            message.error(
                "Can't switch to qt notification presenter at runtime.")
            setting = "auto"

        if setting in ["auto", "libnotify"]:
            candidates = [
                DBusNotificationAdapter,
                SystrayNotificationAdapter,
                MessagesNotificationAdapter,
            ]
        elif setting == "systray":
            candidates = [
                SystrayNotificationAdapter,
                DBusNotificationAdapter,
                MessagesNotificationAdapter,
            ]
        elif setting == "herbe":
            candidates = [
                HerbeNotificationAdapter,
                DBusNotificationAdapter,
                SystrayNotificationAdapter,
                MessagesNotificationAdapter,
            ]
        elif setting == "messages":
            candidates = [MessagesNotificationAdapter]  # always succeeds
        else:
            raise utils.Unreachable(setting)

        for candidate in candidates:
            try:
                self._adapter = candidate()
            except Error as e:
                msg = f"Failed to initialize {candidate.NAME} notification adapter: {e}"
                if candidate.NAME == setting:  # We picked this one explicitly
                    message.error(msg)
                else:  # automatic fallback
                    log.misc.debug(msg)
            else:
                log.misc.debug(
                    f"Initialized {self._adapter.NAME} notification adapter")
                break

        assert self._adapter is not None
        self._adapter.click_id.connect(self._on_adapter_clicked)
        self._adapter.close_id.connect(self._on_adapter_closed)
        self._adapter.error.connect(self._on_adapter_error)
        self._adapter.clear_all.connect(self._on_adapter_clear_all)
示例#26
0
def _get_version_tag(tag):
    """Handle tags like pyqt>=5.3.1 for BDD tests.

    This transforms e.g. pyqt>=5.3.1 into an appropriate @pytest.mark.skip
    marker, and falls back to pytest-bdd's implementation for all other
    casesinto an appropriate @pytest.mark.skip marker, and falls back to
    """
    version_re = re.compile(
        r"""
        (?P<package>qt|pyqt|pyqtwebengine)
        (?P<operator>==|>=|!=|<)
        (?P<version>\d+\.\d+(\.\d+)?)
    """, re.VERBOSE)

    match = version_re.fullmatch(tag)
    if not match:
        return None

    package = match.group('package')
    version = match.group('version')

    if package == 'qt':
        op = match.group('operator')
        do_skip = {
            '==':
            not qtutils.version_check(version, exact=True, compiled=False),
            '>=': not qtutils.version_check(version, compiled=False),
            '<': qtutils.version_check(version, compiled=False),
            '!=': qtutils.version_check(version, exact=True, compiled=False),
        }
        return pytest.mark.skipif(do_skip[op], reason='Needs ' + tag)
    elif package == 'pyqt':
        return pytest.mark.skipif(
            not _check_hex_version(op_str=match.group('operator'),
                                   running_version=PYQT_VERSION,
                                   version=version),
            reason='Needs ' + tag,
        )
    elif package == 'pyqtwebengine':
        try:
            from PyQt5.QtWebEngine import PYQT_WEBENGINE_VERSION
        except ImportError:
            running_version = PYQT_VERSION
        else:
            running_version = PYQT_WEBENGINE_VERSION
        return pytest.mark.skipif(
            not _check_hex_version(op_str=match.group('operator'),
                                   running_version=running_version,
                                   version=version),
            reason='Needs ' + tag,
        )
    else:
        raise utils.Unreachable(package)
示例#27
0
    def send_event(self, evt):
        """Send the given event to the underlying widget.

        The event will be sent via QApplication.postEvent.
        Note that a posted event may not be re-used in any way!
        """
        # This only gives us some mild protection against re-using events, but
        # it's certainly better than a segfault.
        if getattr(evt, 'posted', False):
            raise utils.Unreachable("Can't re-use an event which was already "
                                    "posted!")
        recipient = self.event_target()
        evt.posted = True
        QApplication.postEvent(recipient, evt)
示例#28
0
def init(args: argparse.Namespace) -> None:
    """Initialize all QWeb(Engine)Settings."""
    if objects.backend == usertypes.Backend.QtWebEngine:
        from qutebrowser.browser.webengine import webenginesettings
        webenginesettings.init()
    elif objects.backend == usertypes.Backend.QtWebKit:
        from qutebrowser.browser.webkit import webkitsettings
        webkitsettings.init()
    else:
        raise utils.Unreachable(objects.backend)

    # Make sure special URLs always get JS support
    for pattern in ['chrome://*/*', 'qute://*/*']:
        config.instance.set_obj('content.javascript.enabled', True,
                                pattern=urlmatch.UrlPattern(pattern),
                                hide_userconfig=True)
示例#29
0
    def _draw_widgets(self):
        """Draw statusbar widgets."""
        self._clear_widgets()

        tab = self._current_tab()

        # Read the list and set widgets accordingly
        for segment in config.val.statusbar.widgets:
            if segment == 'url':
                self._hbox.addWidget(self.url)
                self.url.show()
            elif segment == 'scroll':
                self._hbox.addWidget(self.percentage)
                self.percentage.show()
            elif segment == 'scroll_raw':
                self._hbox.addWidget(self.percentage)
                self.percentage.set_raw()
                self.percentage.show()
            elif segment == 'history':
                self._hbox.addWidget(self.backforward)
                self.backforward.enabled = True
                if tab:
                    self.backforward.on_tab_changed(tab)
            elif segment == 'tabs':
                self._hbox.addWidget(self.tabindex)
                self.tabindex.show()
            elif segment == 'keypress':
                self._hbox.addWidget(self.keystring)
                self.keystring.show()
            elif segment == 'progress':
                self._hbox.addWidget(self.prog)
                self.prog.enabled = True
                if tab:
                    self.prog.on_tab_changed(tab)
            elif segment.startswith('text:'):
                cur_widget = textbase.TextBase()
                self._text_widgets.append(cur_widget)
                cur_widget.setText(segment.split(':', maxsplit=1)[1])
                self._hbox.addWidget(cur_widget)
                cur_widget.show()
            else:
                raise utils.Unreachable(segment)
示例#30
0
    def send_event(self, evt: QEvent) -> None:
        """Send the given event to the underlying widget.

        The event will be sent via QApplication.postEvent.
        Note that a posted event must not be re-used in any way!
        """
        # This only gives us some mild protection against re-using events, but
        # it's certainly better than a segfault.
        if getattr(evt, 'posted', False):
            raise utils.Unreachable("Can't re-use an event which was already "
                                    "posted!")

        recipient = self.private_api.event_target()
        if recipient is None:
            # https://github.com/qutebrowser/qutebrowser/issues/3888
            log.webview.warning("Unable to find event target!")
            return

        evt.posted = True  # type: ignore[attr-defined]
        QApplication.postEvent(recipient, evt)