示例#1
0
    def _on_load_finished(self, ok: bool) -> None:
        assert self._widget is not None
        if sip.isdeleted(self._widget):
            # https://github.com/qutebrowser/qutebrowser/issues/3498
            return

        try:
            sess_manager = objreg.get('session-manager')
        except KeyError:
            # https://github.com/qutebrowser/qutebrowser/issues/4311
            return

        sess_manager.save_autosave()

        if ok and not self._has_ssl_errors:
            if self.url().scheme() == 'https':
                self._set_load_status(usertypes.LoadStatus.success_https)
            else:
                self._set_load_status(usertypes.LoadStatus.success)
        elif ok:
            self._set_load_status(usertypes.LoadStatus.warn)
        else:
            self._set_load_status(usertypes.LoadStatus.error)

        self.load_finished.emit(ok)

        if not self.title():
            self.title_changed.emit(self.url().toDisplayString())

        self.zoom.reapply()
示例#2
0
    def _inject_userjs(self, frame):
        """Inject user JavaScripts into the page.

        Args:
            frame: The QWebFrame to inject the user scripts into.
        """
        if sip.isdeleted(frame):
            log.greasemonkey.debug("_inject_userjs called for deleted frame!")
            return

        url = frame.url()
        if url.isEmpty():
            url = frame.requestedUrl()

        log.greasemonkey.debug("_inject_userjs called for {} ({})"
                               .format(frame, url.toDisplayString()))

        scripts = greasemonkey.gm_manager.scripts_for(url)
        # QtWebKit has trouble providing us with signals representing
        # page load progress at reasonable times, so we just load all
        # scripts on the same event.
        toload = scripts.start + scripts.end + scripts.idle

        if url.isEmpty():
            # This happens during normal usage like with view source but may
            # also indicate a bug.
            log.greasemonkey.debug("Not running scripts for frame with no "
                                   "url: {}".format(frame))
            assert not toload, toload

        for script in toload:
            if frame is self.mainFrame() or script.runs_on_sub_frames:
                log.webview.debug(f'Running GM script: {script}')
                frame.evaluateJavaScript(script.code())
示例#3
0
    def _on_load_finished(self, ok):
        if sip.isdeleted(self._widget):
            # https://github.com/qutebrowser/qutebrowser/issues/3498
            return

        try:
            sess_manager = objreg.get('session-manager')
        except KeyError:
            # https://github.com/qutebrowser/qutebrowser/issues/4311
            return

        sess_manager.save_autosave()

        if ok and not self._has_ssl_errors:
            if self.url().scheme() == 'https':
                self._set_load_status(usertypes.LoadStatus.success_https)
            else:
                self._set_load_status(usertypes.LoadStatus.success)
        elif ok:
            self._set_load_status(usertypes.LoadStatus.warn)
        else:
            self._set_load_status(usertypes.LoadStatus.error)

        self.load_finished.emit(ok)

        if not self.title():
            self.title_changed.emit(self.url().toDisplayString())

        self.zoom.set_current()
示例#4
0
    def on_ready_read(self):
        """Read json data from the client."""
        if self._socket is None:  # pragma: no cover
            # This happens when doing a connection while another one is already
            # active for some reason.
            if self._old_socket is None:
                log.ipc.warning("In on_ready_read with None socket and "
                                "old_socket!")
                return
            log.ipc.debug("In on_ready_read with None socket!")
            socket = self._old_socket
        else:
            socket = self._socket

        if sip.isdeleted(socket):  # pragma: no cover
            log.ipc.warning("Ignoring deleted IPC socket")
            return

        self._timer.stop()
        while socket is not None and socket.canReadLine():
            data = bytes(socket.readLine())
            self.got_raw.emit(data)
            log.ipc.debug("Read from socket 0x{:x}: {!r}".format(
                id(socket), data))
            self._handle_data(data)

        if self._socket is not None:
            self._timer.start()
示例#5
0
    def _save_all(self, *, only_window=None, with_private=False):
        """Get a dict with data for all windows/tabs."""
        data = {'windows': []}
        if only_window is not None:
            winlist = [only_window]
        else:
            winlist = objreg.window_registry

        for win_id in sorted(winlist):
            tabbed_browser = objreg.get('tabbed-browser', scope='window',
                                        window=win_id)
            main_window = objreg.get('main-window', scope='window',
                                     window=win_id)

            # We could be in the middle of destroying a window here
            if sip.isdeleted(main_window):
                continue

            if tabbed_browser.is_private and not with_private:
                continue

            win_data = {}
            active_window = QApplication.instance().activeWindow()
            if getattr(active_window, 'win_id', None) == win_id:
                win_data['active'] = True
            win_data['geometry'] = bytes(main_window.saveGeometry())
            win_data['tabs'] = []
            if tabbed_browser.is_private:
                win_data['private'] = True
            for i, tab in enumerate(tabbed_browser.widgets()):
                active = i == tabbed_browser.widget.currentIndex()
                win_data['tabs'].append(self._save_tab(tab, active))
            data['windows'].append(win_data)
        return data
示例#6
0
    def _save_all(self, *, only_window=None, with_private=False, with_history=True):
        """Get a dict with data for all windows/tabs."""
        data: _JsonType = {'windows': []}
        if only_window is not None:
            winlist: Iterable[int] = [only_window]
        else:
            winlist = objreg.window_registry

        for win_id in sorted(winlist):
            tabbed_browser = objreg.get('tabbed-browser', scope='window',
                                        window=win_id)
            main_window = objreg.get('main-window', scope='window',
                                     window=win_id)

            # We could be in the middle of destroying a window here
            if sip.isdeleted(main_window):
                continue

            if tabbed_browser.is_private and not with_private:
                continue

            win_data: _JsonType = {}
            active_window = objects.qapp.activeWindow()
            if getattr(active_window, 'win_id', None) == win_id:
                win_data['active'] = True
            win_data['geometry'] = bytes(main_window.saveGeometry())
            win_data['tabs'] = []
            if tabbed_browser.is_private:
                win_data['private'] = True
            for i, tab in enumerate(tabbed_browser.widgets()):
                active = i == tabbed_browser.widget.currentIndex()
                win_data['tabs'].append(self._save_tab(tab, active,
                                                       with_history=with_history))
            data['windows'].append(win_data)
        return data
示例#7
0
    def _inject_userjs(self, frame):
        """Inject user JavaScripts into the page.

        Args:
            frame: The QWebFrame to inject the user scripts into.
        """
        if sip.isdeleted(frame):
            log.greasemonkey.debug("_inject_userjs called for deleted frame!")
            return

        url = frame.url()
        if url.isEmpty():
            url = frame.requestedUrl()

        log.greasemonkey.debug("_inject_userjs called for {} ({})"
                               .format(frame, url.toDisplayString()))

        greasemonkey = objreg.get('greasemonkey')
        scripts = greasemonkey.scripts_for(url)
        # QtWebKit has trouble providing us with signals representing
        # page load progress at reasonable times, so we just load all
        # scripts on the same event.
        toload = scripts.start + scripts.end + scripts.idle

        if url.isEmpty():
            # This happens during normal usage like with view source but may
            # also indicate a bug.
            log.greasemonkey.debug("Not running scripts for frame with no "
                                   "url: {}".format(frame))
            assert not toload, toload

        for script in toload:
            if frame is self.mainFrame() or script.runs_on_sub_frames:
                log.webview.debug('Running GM script: {}'.format(script.name))
                frame.evaluateJavaScript(script.code())
示例#8
0
    def _cleanup(self, *, successful):
        """Clean up temporary files after the editor closed.

        Args:
            successful: Whether the editor exited successfully, i.e. the file can be
                        deleted.
        """
        assert self._remove_file is not None
        if (self._watcher is not None and not sip.isdeleted(self._watcher)
                and self._watcher.files()):
            failed = self._watcher.removePaths(self._watcher.files())
            if failed:
                log.procs.error("Failed to unwatch paths: {}".format(failed))

        if self._filename is None or not self._remove_file:
            # Could not create initial file.
            return

        assert self._proc is not None

        if successful:
            try:
                os.remove(self._filename)
            except OSError as e:
                # NOTE: Do not replace this with "raise CommandError" as it's
                # executed async.
                message.error("Failed to delete tempfile... ({})".format(e))
        else:
            message.info(
                f"Keeping file {self._filename} as the editor process exited "
                "abnormally")
示例#9
0
def debug_keytester() -> None:
    """Show a keytester widget."""
    global _keytester_widget
    if (_keytester_widget and not sip.isdeleted(_keytester_widget)
            and _keytester_widget.isVisible()):
        _keytester_widget.close()
    else:
        _keytester_widget = miscwidgets.KeyTesterWidget()
        _keytester_widget.show()
示例#10
0
 def _pop(self):
     """Pop a question from the queue and ask it, if there are any."""
     log.prompt.debug("Popping from queue {}".format(self._queue))
     if self._queue:
         question = self._queue.popleft()
         if not sip.isdeleted(question):
             # the question could already be deleted, e.g. by a cancelled
             # download. See
             # https://github.com/qutebrowser/qutebrowser/issues/415
             self.ask_question(question, blocking=False)
示例#11
0
def window_only(current_win_id):
    """Close all windows except for the current one."""
    for win_id, window in objreg.window_registry.items():

        # We could be in the middle of destroying a window here
        if sip.isdeleted(window):
            continue

        if win_id != current_win_id:
            window.close()
示例#12
0
def window_only(current_win_id):
    """Close all windows except for the current one."""
    for win_id, window in objreg.window_registry.items():

        # We could be in the middle of destroying a window here
        if sip.isdeleted(window):
            continue

        if win_id != current_win_id:
            window.close()
示例#13
0
 def _pop(self):
     """Pop a question from the queue and ask it, if there are any."""
     log.prompt.debug("Popping from queue {}".format(self._queue))
     if self._queue:
         question = self._queue.popleft()
         if not sip.isdeleted(question):
             # the question could already be deleted, e.g. by a cancelled
             # download. See
             # https://github.com/qutebrowser/qutebrowser/issues/415
             self.ask_question(question, blocking=False)
示例#14
0
def proc(qtbot, caplog):
    """A fixture providing a GUIProcess and cleaning it up after the test."""
    p = guiprocess.GUIProcess('testprocess')
    yield p
    if not sip.isdeleted(p._proc) and p._proc.state() != QProcess.NotRunning:
        with caplog.at_level(logging.ERROR):
            with qtbot.wait_signal(p.finished, timeout=10000,
                                   raising=False) as blocker:
                p._proc.terminate()
            if not blocker.signal_triggered:
                p._proc.kill()
            p._proc.waitForFinished()
示例#15
0
    def _save_all(self, *, only_window=None, with_private=False):
        """Get a dict with data for all windows/tabs."""
        data = {'windows': []}
        if only_window is not None:
            winlist = [only_window]
        else:
            winlist = objreg.window_registry

        for win_id in sorted(winlist):
            tabbed_browser = objreg.get('tabbed-browser',
                                        scope='window',
                                        window=win_id)
            main_window = objreg.get('main-window',
                                     scope='window',
                                     window=win_id)

            # We could be in the middle of destroying a window here
            if sip.isdeleted(main_window):
                continue

            if tabbed_browser.is_private and not with_private:
                continue

            win_data = {}
            active_window = QApplication.instance().activeWindow()
            if getattr(active_window, 'win_id', None) == win_id:
                win_data['active'] = True
            win_data['geometry'] = bytes(main_window.saveGeometry())
            if tabbed_browser.is_private:
                win_data['private'] = True

            if tabbed_browser.is_treetabbedbrowser:
                # a dict where keys are node UIDs, and values are dicts
                # with tab data (the resul of _save_tab) and a list of
                # children UIDs
                tree_data = {}
                root_node = tabbed_browser.widget.tree_root
                for i, node in enumerate(root_node.traverse()):
                    node_data = {}
                    active = i == tabbed_browser.widget.currentIndex()
                    node_data['tab'] = self._save_tab(node.value, active)
                    node_data['children'] = [c.uid for c in node.children]
                    node_data['collapsed'] = node.collapsed
                    tree_data[node.uid] = node_data
                win_data['tree'] = tree_data
            else:
                win_data['tabs'] = []
                for i, tab in enumerate(tabbed_browser.widgets()):
                    active = i == tabbed_browser.widget.currentIndex()
                    win_data['tabs'].append(self._save_tab(tab, active))
            data['windows'].append(win_data)
        return data
示例#16
0
def raise_window(window, alert=True):
    """Raise the given MainWindow object."""
    window.setWindowState(window.windowState() & ~Qt.WindowMinimized)
    window.setWindowState(window.windowState() | Qt.WindowActive)
    window.raise_()
    # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-69568
    QCoreApplication.processEvents(  # type: ignore[call-overload]
        QEventLoop.ExcludeUserInputEvents | QEventLoop.ExcludeSocketNotifiers)

    if not sip.isdeleted(window):
        # Could be deleted by the events run above
        window.activateWindow()

    if alert:
        objects.qapp.alert(window)
示例#17
0
    def _on_load_finished(self, ok: bool) -> None:
        assert self._widget is not None
        if sip.isdeleted(self._widget):
            # https://github.com/qutebrowser/qutebrowser/issues/3498
            return

        if sessions.session_manager is not None:
            sessions.session_manager.save_autosave()

        self.load_finished.emit(ok)

        if not self.title():
            self.title_changed.emit(self.url().toDisplayString())

        self.zoom.reapply()
示例#18
0
def qute_tabs(_url):
    """Handler for qute://tabs. Display information about all open tabs."""
    tabs = collections.defaultdict(list)
    for win_id, window in objreg.window_registry.items():
        if sip.isdeleted(window):
            continue
        tabbed_browser = objreg.get('tabbed-browser',
                                    scope='window',
                                    window=win_id)
        for tab in tabbed_browser.widgets():
            if tab.url() not in [QUrl("qute://tabs/"), QUrl("qute://tabs")]:
                urlstr = tab.url().toDisplayString()
                tabs[str(win_id)].append((tab.title(), urlstr))

    src = jinja.render('tabs.html', title='Tabs', tab_list_by_window=tabs)
    return 'text/html', src
示例#19
0
 def _remove_item(self, download):
     """Remove a given download."""
     if sip.isdeleted(self):
         # https://github.com/qutebrowser/qutebrowser/issues/1242
         return
     try:
         idx = self.downloads.index(download)
     except ValueError:
         # already removed
         return
     self.begin_remove_row.emit(idx)
     del self.downloads[idx]
     self.end_remove_row.emit()
     download.deleteLater()
     self._update_indexes()
     if not self.downloads:
         self._update_timer.stop()
     log.downloads.debug("Removed download {}".format(download))
示例#20
0
 def _remove_item(self, download):
     """Remove a given download."""
     if sip.isdeleted(self):
         # https://github.com/qutebrowser/qutebrowser/issues/1242
         return
     try:
         idx = self.downloads.index(download)
     except ValueError:
         # already removed
         return
     self.begin_remove_row.emit(idx)
     del self.downloads[idx]
     self.end_remove_row.emit()
     download.deleteLater()
     self._update_indexes()
     if not self.downloads:
         self._update_timer.stop()
     log.downloads.debug("Removed download {}".format(download))
示例#21
0
    def _on_proc_closed(self, _exitcode, exitstatus):
        """Write the editor text into the form field and clean up tempfile.

        Callback for QProcess when the editor was closed.
        """
        if sip.isdeleted(self):  # pragma: no cover
            log.procs.debug("Ignoring _on_proc_closed for deleted editor")
            return

        log.procs.debug("Editor closed")
        if exitstatus != QProcess.NormalExit:
            # No error/cleanup here, since we already handle this in
            # on_proc_error.
            return
        # do a final read to make sure we don't miss the last signal
        self._on_file_changed(self._filename)
        self.editing_finished.emit()
        self._cleanup()
示例#22
0
def qute_tabs(_url):
    """Handler for qute://tabs. Display information about all open tabs."""
    tabs = collections.defaultdict(list)
    for win_id, window in objreg.window_registry.items():
        if sip.isdeleted(window):
            continue
        tabbed_browser = objreg.get('tabbed-browser',
                                    scope='window',
                                    window=win_id)
        for tab in tabbed_browser.widgets():
            if tab.url() not in [QUrl("qute://tabs/"), QUrl("qute://tabs")]:
                urlstr = tab.url().toDisplayString()
                tabs[str(win_id)].append((tab.title(), urlstr))

    src = jinja.render('tabs.html',
                       title='Tabs',
                       tab_list_by_window=tabs)
    return 'text/html', src
示例#23
0
    def _on_load_finished(self, ok: bool) -> None:
        assert self._widget is not None
        if sip.isdeleted(self._widget):
            # https://github.com/qutebrowser/qutebrowser/issues/3498
            return

        try:
            sess_manager = objreg.get('session-manager')
        except KeyError:
            # https://github.com/qutebrowser/qutebrowser/issues/4311
            return

        sess_manager.save_autosave()
        self.load_finished.emit(ok)

        if not self.title():
            self.title_changed.emit(self.url().toDisplayString())

        self.zoom.reapply()
示例#24
0
    def _on_load_finished(self, ok: bool) -> None:
        assert self._widget is not None
        if sip.isdeleted(self._widget):
            # https://github.com/qutebrowser/qutebrowser/issues/3498
            return

        try:
            sess_manager = objreg.get('session-manager')
        except KeyError:
            # https://github.com/qutebrowser/qutebrowser/issues/4311
            return

        sess_manager.save_autosave()
        self.load_finished.emit(ok)

        if not self.title():
            self.title_changed.emit(self.url().toDisplayString())

        self.zoom.reapply()
示例#25
0
    def _cleanup(self):
        """Clean up temporary files after the editor closed."""
        assert self._remove_file is not None
        if (self._watcher is not None and not sip.isdeleted(self._watcher)
                and self._watcher.files()):
            failed = self._watcher.removePaths(self._watcher.files())
            if failed:
                log.procs.error("Failed to unwatch paths: {}".format(failed))

        if self._filename is None or not self._remove_file:
            # Could not create initial file.
            return

        assert self._proc is not None

        try:
            if self._proc.exit_status() != QProcess.CrashExit:
                os.remove(self._filename)
        except OSError as e:
            # NOTE: Do not replace this with "raise CommandError" as it's
            # executed async.
            message.error("Failed to delete tempfile... ({})".format(e))
示例#26
0
    def _get_socket(self, warn=True):
        """Get the current socket for on_ready_read.

        Arguments:
            warn: Whether to warn if no socket was found.
        """
        if self._socket is None:  # pragma: no cover
            # This happens when doing a connection while another one is already
            # active for some reason.
            if self._old_socket is None:
                if warn:
                    log.ipc.warning("In _get_socket with None socket and old_socket!")
                return None
            log.ipc.debug("In _get_socket with None socket!")
            socket = self._old_socket
        else:
            socket = self._socket

        if sip.isdeleted(socket):  # pragma: no cover
            log.ipc.warning("Ignoring deleted IPC socket")
            return None

        return socket
示例#27
0
def raise_window(window, alert=True):
    """Raise the given MainWindow object."""
    window.setWindowState(window.windowState() & ~Qt.WindowMinimized)
    window.setWindowState(window.windowState() | Qt.WindowActive)
    window.raise_()
    # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-69568
    QCoreApplication.processEvents(  # type: ignore[call-overload]
        QEventLoop.ExcludeUserInputEvents | QEventLoop.ExcludeSocketNotifiers)

    window.activateWindow()

    global i3ipc_used
    if i3ipc_used and window.wm_variant == 'sway':
        curfoc = window.wm_connection.get_tree().find_focused().app_id
        if curfoc != 'org.qutebrowser.qutebrowser':
            window.wm_connection.command(
                '[app_id="org.qutebrowser.qutebrowser"] focus')

    if not sip.isdeleted(window):
        # Could be deleted by the events run above
        window.activateWindow()

    if alert:
        objects.qapp.alert(window)
示例#28
0
 def is_deleted(self):
     return sip.isdeleted(self._widget)
示例#29
0
 def is_deleted(self) -> bool:
     if self._widget is None:
         raise AssertionError
     return sip.isdeleted(self._widget)
示例#30
0
 def _on_webkit_icon_changed(self):
     """Emit iconChanged with a QIcon like QWebEngineView does."""
     if sip.isdeleted(self._widget):
         log.webview.debug("Got _on_webkit_icon_changed for deleted view!")
         return
     self.icon_changed.emit(self._widget.icon())
示例#31
0
 def is_deleted(self):
     return sip.isdeleted(self._widget)
示例#32
0
 def _on_webkit_icon_changed(self):
     """Emit iconChanged with a QIcon like QWebEngineView does."""
     if sip.isdeleted(self._widget):
         log.webview.debug("Got _on_webkit_icon_changed for deleted view!")
         return
     self.icon_changed.emit(self._widget.icon())
示例#33
0
 def is_deleted(self) -> bool:
     assert self._widget is not None
     return sip.isdeleted(self._widget)
示例#34
0
 def on_web_closed(self, notification_id: int) -> None:
     assert notification_id == self.NOTIFICATION_ID, notification_id
     if not sip.isdeleted(self._systray):
         # This can get called during shutdown
         self._systray.hide()
示例#35
0
 def _update_geometry():
     """Actually update the geometry if the object still exists."""
     if sip.isdeleted(obj):
         return
     obj.updateGeometry()
示例#36
0
 def _update_geometry():
     """Actually update the geometry if the object still exists."""
     if sip.isdeleted(obj):
         return
     obj.updateGeometry()
示例#37
0
 def is_deleted(self) -> bool:
     assert self._widget is not None
     return sip.isdeleted(self._widget)