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
Get rid of objreg? #640
Comments
The CompletionView is the parent of the Completer, so there's no need to use objreg to get it. See qutebrowser#640.
The CompletionView is the parent of the Completer, so there's no need to use objreg to get it. See qutebrowser#640.
I had some ideas on how to handle this for commands inside classes, which will
This also means it's much easier to have some commands in a class when we need class RepeatCommand:
def __init__(self):
self._timers = []
@cmdutils.register()
def repeat(self, times=None, command=None, stop=False):
if stop:
for timer in self._timers:
timer.stop()
else:
# ...
def init():
cmdutils.register_instance(RepeatCommand()) This could also be a quite nice way to register commands inside classes for Compared to now: class RepeatCommand:
# ...
@cmdutils.register(instance='repeat-command')
def repeat(self, times=None, command=None, stop=False):
# ...
def init():
objreg.register('repeat-command', RepeatCommand()) This is slightly more verbose, but most importantly, it leaves an object in the |
That won't work in this way, as the class is not yet created when the class methods are defined, and the decorator won't have access to the class. We can only add some attribute to the function itself, and later iterate over all class members, taking the ones we want. |
Oh, indeed - that still sounds like a good plan though. |
@jberglinds asked for something refactoring-related to work on as a group in the KTH Sweden, I'm currently writing a mail proposing this issue. @rcorre, I noticed you started some work back in December in the byeobjreg branch but that seems abandoned - is this okay to take over, or do you plan to continue? |
Oh, I completely forgot about that. Go ahead, refactor away!
- Ryan
…On February 14, 2018 11:02:27 AM EST, Florian Bruhin ***@***.***> wrote:
@jberglinds asked for something refactoring-related to work on as a
group in the KTH Sweden, I'm currently writing a mail proposing this
issue. @rcorre, I noticed you started some work back in December in the
[byeobjreg
branch](master...rcorre:byeobjreg)
but that seems abandoned - is this okay to take over, or do you plan to
continue?
|
I started working on #640 (comment) but this is going to be a bigger thing than I thought it'd be. For global objects this is fine, but for per-window/per-tab objects, we basically end up building another objreg-like thing, which is what I wanted to avoid 😆 Going to stop here for now, need to think some more about it first. Patch so far: diff --git a/qutebrowser/api/cmdutils.py b/qutebrowser/api/cmdutils.py
index f95e984ca..3c9540f02 100644
--- a/qutebrowser/api/cmdutils.py
+++ b/qutebrowser/api/cmdutils.py
@@ -78,15 +78,11 @@ class register: # noqa: N801,N806 pylint: disable=invalid-name
"""Decorator to register a new command handler.
Attributes:
- _instance: The object from the object registry to be used as "self".
_name: The name (as string) or names (as list) of the command.
_kwargs: The arguments to pass to Command.
"""
- def __init__(self, *,
- instance: str = None,
- name: str = None,
- **kwargs: typing.Any) -> None:
+ def __init__(self, *, name: str = None, **kwargs: typing.Any) -> None:
"""Save decorator arguments.
Gets called on parse-time with the decorator arguments.
@@ -94,7 +90,6 @@ class register: # noqa: N801,N806 pylint: disable=invalid-name
Args:
See class attributes.
"""
- self._instance = instance
self._name = name
self._kwargs = kwargs
@@ -118,8 +113,7 @@ class register: # noqa: N801,N806 pylint: disable=invalid-name
assert isinstance(self._name, str), self._name
name = self._name
- cmd = command.Command(name=name, instance=self._instance,
- handler=func, **self._kwargs)
+ cmd = command.Command(name=name, handler=func, **self._kwargs)
cmd.register()
return func
diff --git a/qutebrowser/app.py b/qutebrowser/app.py
index 27848c4c1..29178335c 100644
--- a/qutebrowser/app.py
+++ b/qutebrowser/app.py
@@ -116,6 +116,7 @@ def run(args):
app=qApp, quitter=quitter, args=args, parent=qApp)
crash_handler.activate()
objreg.register('crash-handler', crash_handler)
+ cmdutils.register_instance(crash_handler)
signal_handler = crashsignal.SignalHandler(app=qApp, quitter=quitter,
parent=qApp)
@@ -424,6 +425,7 @@ def _init_modules(args, crash_handler):
log.init.debug("Initializing save manager...")
save_manager = savemanager.SaveManager(qApp)
objreg.register('save-manager', save_manager)
+ cmdutils.register_instance(save_manager)
configinit.late_init(save_manager)
log.init.debug("Checking backend requirements...")
@@ -440,7 +442,7 @@ def _init_modules(args, crash_handler):
log.init.debug("Initializing readline-bridge...")
readline_bridge = readline.ReadlineBridge()
- objreg.register('readline-bridge', readline_bridge)
+ cmdutils.register_instance(readline_bridge)
try:
log.init.debug("Initializing sql...")
diff --git a/qutebrowser/commands/command.py b/qutebrowser/commands/command.py
index 5422a9984..709fae1f7 100644
--- a/qutebrowser/commands/command.py
+++ b/qutebrowser/commands/command.py
@@ -69,16 +69,15 @@ class Command:
both)
no_replace_variables: Don't replace variables like {url}
modes: The modes the command can be executed in.
+ instance: The object to bind 'self' to.
_qute_args: The saved data from @cmdutils.argument
_count: The count set for the command.
- _instance: The object to bind 'self' to.
- _scope: The scope to get _instance for in the object registry.
"""
def __init__(self, *, handler, name, instance=None, maxsplit=None,
modes=None, not_modes=None, debug=False, deprecated=False,
- no_cmd_split=False, star_args_optional=False, scope='global',
- backend=None, no_replace_variables=False):
+ no_cmd_split=False, star_args_optional=False, backend=None,
+ no_replace_variables=False):
if modes is not None and not_modes is not None:
raise ValueError("Only modes or not_modes can be given!")
if modes is not None:
@@ -93,15 +92,11 @@ class Command:
self.modes = set(usertypes.KeyMode).difference(not_modes)
else:
self.modes = set(usertypes.KeyMode)
- if scope != 'global' and instance is None:
- raise ValueError("Setting scope without setting instance makes "
- "no sense!")
self.name = name
self.maxsplit = maxsplit
self.deprecated = deprecated
- self._instance = instance
- self._scope = scope
+ self.instance = None
self._star_args_optional = star_args_optional
self.debug = debug
self.handler = handler
@@ -154,14 +149,8 @@ class Command:
def _check_func(self):
"""Make sure the function parameters don't violate any rules."""
signature = inspect.signature(self.handler)
- if 'self' in signature.parameters and self._instance is None:
- raise TypeError("{} is a class method, but instance was not "
- "given!".format(self.name[0]))
- elif 'self' not in signature.parameters and self._instance is not None:
- raise TypeError("{} is not a class method, but instance was "
- "given!".format(self.name[0]))
- elif any(param.kind == inspect.Parameter.VAR_KEYWORD
- for param in signature.parameters.values()):
+ if any(param.kind == inspect.Parameter.VAR_KEYWORD
+ for param in signature.parameters.values()):
raise TypeError("{}: functions with varkw arguments are not "
"supported!".format(self.name[0]))
@@ -341,18 +330,7 @@ class Command:
args: The positional argument list. Gets modified directly.
"""
assert param.kind == inspect.Parameter.POSITIONAL_OR_KEYWORD
- if self._scope == 'global':
- tab_id = None
- win_id = None
- elif self._scope == 'tab':
- tab_id = 'current'
- elif self._scope == 'window':
- tab_id = None
- else:
- raise ValueError("Invalid scope {}!".format(self._scope))
- obj = objreg.get(self._instance, scope=self._scope, window=win_id,
- tab=tab_id)
- args.append(obj)
+ args.append(self._instance)
def _get_count_arg(self, param, args, kwargs):
"""Add the count argument to a function call.
@@ -428,6 +406,15 @@ class Command:
return value
+ def _check_instance(self, signature):
+ """Make sure we have an instance set if we need one."""
+ if 'self' in signature.parameters and self.instance is None:
+ raise TypeError("{} is a class method, but instance was not "
+ "given!".format(self.name[0]))
+ elif 'self' not in signature.parameters and self.instance is not None:
+ raise TypeError("{} is not a class method, but instance was "
+ "given!".format(self.name[0]))
+
def _get_call_args(self, win_id):
"""Get arguments for a function call.
@@ -440,10 +427,11 @@ class Command:
args = []
kwargs = {}
signature = inspect.signature(self.handler)
+ self._check_instance(signature)
for i, param in enumerate(signature.parameters.values()):
arg_info = self.get_arg_info(param)
- if i == 0 and self._instance is not None:
+ if i == 0 and self.instance is not None:
# Special case for 'self'.
self._get_self_arg(win_id, param, args)
continue
diff --git a/qutebrowser/keyinput/macros.py b/qutebrowser/keyinput/macros.py
index bd17f5664..03bdef1d9 100644
--- a/qutebrowser/keyinput/macros.py
+++ b/qutebrowser/keyinput/macros.py
@@ -44,7 +44,7 @@ class MacroRecorder:
self._macro_count = {}
self._last_register = None
- @cmdutils.register(instance='macro-recorder', name='record-macro')
+ @cmdutils.register(name='record-macro')
@cmdutils.argument('win_id', win_id=True)
def record_macro_command(self, win_id, register=None):
"""Start or stop recording a macro.
@@ -69,7 +69,7 @@ class MacroRecorder:
self._macros[register] = []
self._recording_macro = register
- @cmdutils.register(instance='macro-recorder', name='run-macro')
+ @cmdutils.register(name='run-macro')
@cmdutils.argument('win_id', win_id=True)
@cmdutils.argument('count', count=True)
def run_macro_command(self, win_id, count=1, register=None):
@@ -113,3 +113,4 @@ def init():
"""Initialize the MacroRecorder."""
macro_recorder = MacroRecorder()
objreg.register('macro-recorder', macro_recorder)
+ cmdutils.register_instance(macro_recorder)
diff --git a/qutebrowser/keyinput/modeman.py b/qutebrowser/keyinput/modeman.py
index c06700b6c..f77ba2999 100644
--- a/qutebrowser/keyinput/modeman.py
+++ b/qutebrowser/keyinput/modeman.py
@@ -67,6 +67,7 @@ def init(win_id, parent):
KM = usertypes.KeyMode # noqa: N801,N806 pylint: disable=invalid-name
modeman = ModeManager(win_id, parent)
objreg.register('mode-manager', modeman, scope='window', window=win_id)
+ cmdutils.register_instance(modeman, scope='window')
keyparsers = {
KM.normal:
modeparsers.NormalKeyParser(win_id, modeman),
@@ -272,7 +273,7 @@ class ModeManager(QObject):
self.mode = mode
self.entered.emit(mode, self._win_id)
- @cmdutils.register(instance='mode-manager', scope='window')
+ @cmdutils.register()
def enter_mode(self, mode):
"""Enter a key mode.
@@ -320,8 +321,7 @@ class ModeManager(QObject):
self.enter(self._prev_mode,
reason='restore mode before {}'.format(mode.name))
- @cmdutils.register(instance='mode-manager', name='leave-mode',
- not_modes=[usertypes.KeyMode.normal], scope='window')
+ @cmdutils.register(name='leave-mode', not_modes=[usertypes.KeyMode.normal])
def leave_current_mode(self):
"""Leave the mode we're currently in."""
if self.mode == usertypes.KeyMode.normal:
@@ -352,7 +352,7 @@ class ModeManager(QObject):
handler = handlers[event.type()]
return handler(event)
- @cmdutils.register(instance='mode-manager', scope='window')
+ @cmdutils.register()
def clear_keychain(self):
"""Clear the currently entered key chain."""
self._parsers[self.mode].clear_keystring()
diff --git a/qutebrowser/mainwindow/statusbar/bar.py b/qutebrowser/mainwindow/statusbar/bar.py
index 13a368f05..f3b2c8b3a 100644
--- a/qutebrowser/mainwindow/statusbar/bar.py
+++ b/qutebrowser/mainwindow/statusbar/bar.py
@@ -24,6 +24,7 @@ import attr
from PyQt5.QtCore import pyqtSignal, pyqtSlot, pyqtProperty, Qt, QSize, QTimer
from PyQt5.QtWidgets import QWidget, QHBoxLayout, QStackedLayout, QSizePolicy
+from qutebrowser.api import cmdutils
from qutebrowser.browser import browsertab
from qutebrowser.config import config
from qutebrowser.utils import usertypes, log, objreg, utils
@@ -174,6 +175,7 @@ class StatusBar(QWidget):
self._stack.addWidget(self.cmd)
objreg.register('status-command', self.cmd, scope='window',
window=win_id)
+ cmdutils.register_instance(self.cmd, scope='window')
self.txt = textwidget.Text()
self._stack.addWidget(self.txt)
diff --git a/qutebrowser/mainwindow/statusbar/command.py b/qutebrowser/mainwindow/statusbar/command.py
index de42cda4e..39af23cab 100644
--- a/qutebrowser/mainwindow/statusbar/command.py
+++ b/qutebrowser/mainwindow/statusbar/command.py
@@ -113,8 +113,7 @@ class Command(misc.MinimalLineEditMixin, misc.CommandLineEdit):
self.setFocus()
self.show_cmd.emit()
- @cmdutils.register(instance='status-command', name='set-cmd-text',
- scope='window', maxsplit=0)
+ @cmdutils.register(name='set-cmd-text', maxsplit=0)
@cmdutils.argument('count', count=True)
def set_cmd_text_command(self, text, count=None, space=False, append=False,
run_on_count=False):
@@ -148,8 +147,7 @@ class Command(misc.MinimalLineEditMixin, misc.CommandLineEdit):
else:
self.set_cmd_text(text)
- @cmdutils.register(instance='status-command',
- modes=[usertypes.KeyMode.command], scope='window')
+ @cmdutils.register(modes=[usertypes.KeyMode.command])
def command_history_prev(self):
"""Go back in the commandline history."""
try:
@@ -163,8 +161,7 @@ class Command(misc.MinimalLineEditMixin, misc.CommandLineEdit):
if item:
self.set_cmd_text(item)
- @cmdutils.register(instance='status-command',
- modes=[usertypes.KeyMode.command], scope='window')
+ @cmdutils.register(modes=[usertypes.KeyMode.command])
def command_history_next(self):
"""Go forward in the commandline history."""
if not self.history.is_browsing():
@@ -176,8 +173,7 @@ class Command(misc.MinimalLineEditMixin, misc.CommandLineEdit):
if item:
self.set_cmd_text(item)
- @cmdutils.register(instance='status-command',
- modes=[usertypes.KeyMode.command], scope='window')
+ @cmdutils.register(modes=[usertypes.KeyMode.command])
def command_accept(self, rapid=False):
"""Execute the command currently in the commandline.
@@ -196,7 +192,7 @@ class Command(misc.MinimalLineEditMixin, misc.CommandLineEdit):
if not was_search:
self.got_cmd[str].emit(text[1:])
- @cmdutils.register(instance='status-command', scope='window')
+ @cmdutils.register()
def edit_command(self, run=False):
"""Open an editor to modify the current command.
diff --git a/qutebrowser/misc/crashsignal.py b/qutebrowser/misc/crashsignal.py
index 7890380e8..4ed3a54dd 100644
--- a/qutebrowser/misc/crashsignal.py
+++ b/qutebrowser/misc/crashsignal.py
@@ -146,7 +146,7 @@ class CrashHandler(QObject):
else:
earlyinit.init_faulthandler(self._crash_log_file)
- @cmdutils.register(instance='crash-handler')
+ @cmdutils.register()
def report(self):
"""Report a bug in qutebrowser."""
pages = self._recover_pages()
diff --git a/qutebrowser/misc/readline.py b/qutebrowser/misc/readline.py
index 14c25cd6d..bdd4a20f6 100644
--- a/qutebrowser/misc/readline.py
+++ b/qutebrowser/misc/readline.py
@@ -48,8 +48,7 @@ class ReadlineBridge:
else:
return None
- @cmdutils.register(instance='readline-bridge',
- modes=[typ.KeyMode.command, typ.KeyMode.prompt])
+ @cmdutils.register(modes=[typ.KeyMode.command, typ.KeyMode.prompt])
def rl_backward_char(self):
"""Move back a character.
@@ -60,8 +59,7 @@ class ReadlineBridge:
return
widget.cursorBackward(False)
- @cmdutils.register(instance='readline-bridge',
- modes=[typ.KeyMode.command, typ.KeyMode.prompt])
+ @cmdutils.register(modes=[typ.KeyMode.command, typ.KeyMode.prompt])
def rl_forward_char(self):
"""Move forward a character.
@@ -72,8 +70,7 @@ class ReadlineBridge:
return
widget.cursorForward(False)
- @cmdutils.register(instance='readline-bridge',
- modes=[typ.KeyMode.command, typ.KeyMode.prompt])
+ @cmdutils.register(modes=[typ.KeyMode.command, typ.KeyMode.prompt])
def rl_backward_word(self):
"""Move back to the start of the current or previous word.
@@ -84,8 +81,7 @@ class ReadlineBridge:
return
widget.cursorWordBackward(False)
- @cmdutils.register(instance='readline-bridge',
- modes=[typ.KeyMode.command, typ.KeyMode.prompt])
+ @cmdutils.register(modes=[typ.KeyMode.command, typ.KeyMode.prompt])
def rl_forward_word(self):
"""Move forward to the end of the next word.
@@ -96,8 +92,7 @@ class ReadlineBridge:
return
widget.cursorWordForward(False)
- @cmdutils.register(instance='readline-bridge',
- modes=[typ.KeyMode.command, typ.KeyMode.prompt])
+ @cmdutils.register(modes=[typ.KeyMode.command, typ.KeyMode.prompt])
def rl_beginning_of_line(self):
"""Move to the start of the line.
@@ -108,8 +103,7 @@ class ReadlineBridge:
return
widget.home(False)
- @cmdutils.register(instance='readline-bridge',
- modes=[typ.KeyMode.command, typ.KeyMode.prompt])
+ @cmdutils.register(modes=[typ.KeyMode.command, typ.KeyMode.prompt])
def rl_end_of_line(self):
"""Move to the end of the line.
@@ -120,8 +114,7 @@ class ReadlineBridge:
return
widget.end(False)
- @cmdutils.register(instance='readline-bridge',
- modes=[typ.KeyMode.command, typ.KeyMode.prompt])
+ @cmdutils.register(modes=[typ.KeyMode.command, typ.KeyMode.prompt])
def rl_unix_line_discard(self):
"""Remove chars backward from the cursor to the beginning of the line.
@@ -134,8 +127,7 @@ class ReadlineBridge:
self._deleted[widget] = widget.selectedText()
widget.del_()
- @cmdutils.register(instance='readline-bridge',
- modes=[typ.KeyMode.command, typ.KeyMode.prompt])
+ @cmdutils.register(modes=[typ.KeyMode.command, typ.KeyMode.prompt])
def rl_kill_line(self):
"""Remove chars from the cursor to the end of the line.
@@ -173,8 +165,7 @@ class ReadlineBridge:
self._deleted[widget] = widget.selectedText()
widget.del_()
- @cmdutils.register(instance='readline-bridge',
- modes=[typ.KeyMode.command, typ.KeyMode.prompt])
+ @cmdutils.register(modes=[typ.KeyMode.command, typ.KeyMode.prompt])
def rl_unix_word_rubout(self):
"""Remove chars from the cursor to the beginning of the word.
@@ -183,8 +174,7 @@ class ReadlineBridge:
"""
self._rubout([' '])
- @cmdutils.register(instance='readline-bridge',
- modes=[typ.KeyMode.command, typ.KeyMode.prompt])
+ @cmdutils.register(modes=[typ.KeyMode.command, typ.KeyMode.prompt])
def rl_unix_filename_rubout(self):
"""Remove chars from the cursor to the previous path separator.
@@ -192,8 +182,7 @@ class ReadlineBridge:
"""
self._rubout([' ', '/'])
- @cmdutils.register(instance='readline-bridge',
- modes=[typ.KeyMode.command, typ.KeyMode.prompt])
+ @cmdutils.register(modes=[typ.KeyMode.command, typ.KeyMode.prompt])
def rl_backward_kill_word(self):
"""Remove chars from the cursor to the beginning of the word.
@@ -207,8 +196,7 @@ class ReadlineBridge:
self._deleted[widget] = widget.selectedText()
widget.del_()
- @cmdutils.register(instance='readline-bridge',
- modes=[typ.KeyMode.command, typ.KeyMode.prompt])
+ @cmdutils.register(modes=[typ.KeyMode.command, typ.KeyMode.prompt])
def rl_kill_word(self):
"""Remove chars from the cursor to the end of the current word.
@@ -221,8 +209,7 @@ class ReadlineBridge:
self._deleted[widget] = widget.selectedText()
widget.del_()
- @cmdutils.register(instance='readline-bridge',
- modes=[typ.KeyMode.command, typ.KeyMode.prompt])
+ @cmdutils.register(modes=[typ.KeyMode.command, typ.KeyMode.prompt])
def rl_yank(self):
"""Paste the most recently deleted text.
@@ -233,8 +220,7 @@ class ReadlineBridge:
return
widget.insert(self._deleted[widget])
- @cmdutils.register(instance='readline-bridge',
- modes=[typ.KeyMode.command, typ.KeyMode.prompt])
+ @cmdutils.register(modes=[typ.KeyMode.command, typ.KeyMode.prompt])
def rl_delete_char(self):
"""Delete the character after the cursor.
@@ -245,8 +231,7 @@ class ReadlineBridge:
return
widget.del_()
- @cmdutils.register(instance='readline-bridge',
- modes=[typ.KeyMode.command, typ.KeyMode.prompt])
+ @cmdutils.register(modes=[typ.KeyMode.command, typ.KeyMode.prompt])
def rl_backward_delete_char(self):
"""Delete the character before the cursor.
diff --git a/qutebrowser/misc/savemanager.py b/qutebrowser/misc/savemanager.py
index 9985c5191..ab647a34b 100644
--- a/qutebrowser/misc/savemanager.py
+++ b/qutebrowser/misc/savemanager.py
@@ -178,8 +178,7 @@ class SaveManager(QObject):
except OSError as e:
message.error("Failed to auto-save {}: {}".format(key, e))
- @cmdutils.register(instance='save-manager', name='save',
- star_args_optional=True)
+ @cmdutils.register(name='save', star_args_optional=True)
def save_command(self, *what):
"""Save configs and state.
diff --git a/qutebrowser/misc/sessions.py b/qutebrowser/misc/sessions.py
index 357d5be64..ef93b9a36 100644
--- a/qutebrowser/misc/sessions.py
+++ b/qutebrowser/misc/sessions.py
@@ -60,6 +60,7 @@ def init(parent=None):
session_manager = SessionManager(base_path, parent)
objreg.register('session-manager', session_manager)
+ cmdutils.register_instance(session_manager)
class SessionError(Exception):
@@ -465,7 +466,7 @@ class SessionManager(QObject):
sessions.append(base)
return sorted(sessions)
- @cmdutils.register(instance='session-manager')
+ @cmdutils.register()
@cmdutils.argument('name', completion=miscmodels.session)
def session_load(self, name, clear=False, temp=False, force=False,
delete=False):
@@ -506,7 +507,7 @@ class SessionManager(QObject):
log.sessions.debug(
"Loaded & deleted session {}.".format(name))
- @cmdutils.register(instance='session-manager')
+ @cmdutils.register()
@cmdutils.argument('name', completion=miscmodels.session)
@cmdutils.argument('win_id', win_id=True)
@cmdutils.argument('with_private', flag='p')
@@ -554,7 +555,7 @@ class SessionManager(QObject):
else:
message.info("Saved session {}.".format(name))
- @cmdutils.register(instance='session-manager')
+ @cmdutils.register()
@cmdutils.argument('name', completion=miscmodels.session)
def session_delete(self, name, force=False):
"""Delete a session.
diff --git a/tests/unit/api/test_cmdutils.py b/tests/unit/api/test_cmdutils.py
index f2318ab46..3aa40b135 100644
--- a/tests/unit/api/test_cmdutils.py
+++ b/tests/unit/api/test_cmdutils.py
@@ -130,7 +130,8 @@ class TestRegister:
def test_instance(self):
"""Make sure the instance gets passed to Command."""
- @cmdutils.register(instance='foobar')
+ # FIXME update
+ @cmdutils.register()
def fun(self):
"""Blah."""
assert objects.commands['fun']._instance == 'foobar'
@@ -416,7 +417,8 @@ class TestRun:
sure the backend checking happens before resolving the instance, so we
display an error instead of crashing.
"""
- @cmdutils.register(instance='doesnotexist',
+ # FIXME update
+ @cmdutils.register()
backend=usertypes.Backend.QtWebEngine)
def fun(self):
"""Blah.""" |
This means we can set command_only=True for command-dispatcher See #640
Pushed a first bunch of refactorings. Before:
after:
Next step: Cleaning up |
Instead of checking |
I don't think it matters much, unless we want to get rid of win_id/tab_id completely (which I don't think is feasible). |
This also removes it from objreg, see #640.
With Qt 6.4, QtWebEngine closes/reopens the main window to switch the RHI rendering mode when a QWebEngineView gets added: https://github.com/qt/qtbase/blob/v6.4.1/src/widgets/kernel/qwidget.cpp#L10706-L10709 To avoid this, we need to make sure we only call .show() *after* adding a tab, similarly to what Qt did too: https://code.qt.io/cgit/qt/qtwebengine.git/commit/?id=d7e0fd5304ebdb12c6f809cdbcf8193b49b9ecd2 See #7504 ---- This commit handles changes around app.py/mainwindow.py, which was probably the most complex one of the whole set (and also involving the oldest code I bet...). This changes a couple of intertwined things: - app._process_args() now needs to take track of the window it opened (if any), so that it can call .show() on it *after* opening pages. * If a session was loaded instead, sessions.py takes care of showing it. * The setActiveWindow call was also moved for simplicitly. Before, it was called even with --nowindow given, but that doesn't really make much sense. * I'm not actually sure why the .setActiveWindow() call is there. Qt docs say "Warning: This function does not set the keyboard focus to the active widget. Call QWidget::activateWindow() instead.". It was added back in 2014: ae44aa0 ("Set initial focused window correctly."). It's possible it's not needed anymore, but that's for a separate commit. - app.process_pos_args() now gets a MainWindow (rather than win_id) from mainwindow.get_window(), and is responsible for calling .show() and .maybe_raise() on it when nothing else does (like open_url called from it). * To preserve existing behavior (and not fail tests), it also still calls .maybe_raise() when a command was given. Maybe we should get rid of this to fix #5094, but that's for a separate commit. * Note it does *not* call .show(). That's taken care of later in _process_args() already. - app.open_url() can directly show the window, because it already opens a URL. It now still returns the MainWindow object for consistency. Also gets rid of some questionable objreg usage just to access a tabbed browser, as a tiny step towards #640. - Similarly, app._open_startpage() could have stayed, but now also takes a MainWindow and uses objreg a bit less. - open_desktopservices_url also takes care of the show/raise (as this gets called isolated from Qt), and also avoids objreg stuff where an attribute access would have sufficed... - mainwindow.get_window() now doesn't show the window anymore, and returns the mainwindow object instead of a window ID. * However, this means it can't actually raise the window anymore (it needs to be shown first). - To keep the decision about whether to raise the window in a central place, MainWindow now has a new should_raise attribute and maybe_raise() method. mainwindow.get_window() sets should_raise accordingly, and the caller is responsible to call .maybe_raise() after showing.
qutebrowser currently has a global object registry, where objects are registered and retrieved using a string as name - see the contributing documentation for some details about it. This is a stringly typed API and got us into various problems (like #1638, #1652, and bad testability).
This should be phased out and replaced by global objects where appropriate (like
modeman.instance
,config.instance
) and objects passed as arguments elsewhere.There seem to be various uses of the object registry right now:
Commands
We somehow need to get the proper instance to registered commands. Currently this is done via
instance='some-string'[, scope={'tab','window'}]
passed to@cmdutils.register
, andCommand
then uses that and gets the instance via the object registry.I'm still not 100% sure if this will work or not, but we probably could change that to something like this:
got_command
signal is emitted.CommandDispatcher
(?) which gets thegot_command
signal and calls all command handlers with the correct instances.Global objects
These are the current global objects:
app, args, cache, command-history, config, cookie-jar, debug-console, host-blocker, ipc-server, js-bridge, key-config, quickmark-manager, save-manager, session-manager, state-config, web-history
Alternatives:
config.get
, etc.).Application
(e.g. args) and useQApplication.instance()
(or a convenience function for that).Getting other objects
Many of those probably could be replaced by instance variables or signals/slots.
The text was updated successfully, but these errors were encountered: