Generalize statusbar-attached website overlays
We already had some duplicated logic for completion/keyhint/messageview, and plan to add prompt overlays too now - so here we refactor related code to have a list of overlays instead, which are all resized/positioned by the mainwindow when needed. This also changes the size management, which gets moved into the sizeHint of the respective overlay widgets.
This commit is contained in:
parent
57d896e989
commit
750dfd98af
@ -24,12 +24,12 @@ subclasses to provide completions.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from PyQt5.QtWidgets import QStyle, QTreeView, QSizePolicy
|
from PyQt5.QtWidgets import QStyle, QTreeView, QSizePolicy
|
||||||
from PyQt5.QtCore import pyqtSlot, pyqtSignal, Qt, QItemSelectionModel
|
from PyQt5.QtCore import pyqtSlot, pyqtSignal, Qt, QItemSelectionModel, QSize
|
||||||
|
|
||||||
from qutebrowser.config import config, style
|
from qutebrowser.config import config, style
|
||||||
from qutebrowser.completion import completiondelegate
|
from qutebrowser.completion import completiondelegate
|
||||||
from qutebrowser.completion.models import base
|
from qutebrowser.completion.models import base
|
||||||
from qutebrowser.utils import utils, usertypes
|
from qutebrowser.utils import utils, usertypes, objreg
|
||||||
from qutebrowser.commands import cmdexc, cmdutils
|
from qutebrowser.commands import cmdexc, cmdutils
|
||||||
|
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ class CompletionView(QTreeView):
|
|||||||
_active: Whether a selection is active.
|
_active: Whether a selection is active.
|
||||||
|
|
||||||
Signals:
|
Signals:
|
||||||
resize_completion: Emitted when the completion should be resized.
|
update_geometry: Emitted when the completion should be resized.
|
||||||
selection_changed: Emitted when the completion item selection changes.
|
selection_changed: Emitted when the completion item selection changes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -102,7 +102,7 @@ class CompletionView(QTreeView):
|
|||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
resize_completion = pyqtSignal()
|
update_geometry = pyqtSignal()
|
||||||
selection_changed = pyqtSignal(str)
|
selection_changed = pyqtSignal(str)
|
||||||
|
|
||||||
def __init__(self, win_id, parent=None):
|
def __init__(self, win_id, parent=None):
|
||||||
@ -110,6 +110,7 @@ class CompletionView(QTreeView):
|
|||||||
self._win_id = win_id
|
self._win_id = win_id
|
||||||
# FIXME handle new aliases.
|
# FIXME handle new aliases.
|
||||||
# objreg.get('config').changed.connect(self.init_command_completion)
|
# objreg.get('config').changed.connect(self.init_command_completion)
|
||||||
|
objreg.get('config').changed.connect(self._on_config_changed)
|
||||||
|
|
||||||
self._column_widths = base.BaseCompletionModel.COLUMN_WIDTHS
|
self._column_widths = base.BaseCompletionModel.COLUMN_WIDTHS
|
||||||
self._active = False
|
self._active = False
|
||||||
@ -117,7 +118,7 @@ class CompletionView(QTreeView):
|
|||||||
self._delegate = completiondelegate.CompletionItemDelegate(self)
|
self._delegate = completiondelegate.CompletionItemDelegate(self)
|
||||||
self.setItemDelegate(self._delegate)
|
self.setItemDelegate(self._delegate)
|
||||||
style.set_register_stylesheet(self)
|
style.set_register_stylesheet(self)
|
||||||
self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Minimum)
|
self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
||||||
self.setHeaderHidden(True)
|
self.setHeaderHidden(True)
|
||||||
self.setAlternatingRowColors(True)
|
self.setAlternatingRowColors(True)
|
||||||
self.setIndentation(0)
|
self.setIndentation(0)
|
||||||
@ -138,6 +139,13 @@ class CompletionView(QTreeView):
|
|||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return utils.get_repr(self)
|
return utils.get_repr(self)
|
||||||
|
|
||||||
|
@pyqtSlot(str, str)
|
||||||
|
def _on_config_changed(self, section, option):
|
||||||
|
if section != 'completion':
|
||||||
|
return
|
||||||
|
if option in ['height', 'shrink']:
|
||||||
|
self.update_geometry.emit()
|
||||||
|
|
||||||
def _resize_columns(self):
|
def _resize_columns(self):
|
||||||
"""Resize the completion columns based on column_widths."""
|
"""Resize the completion columns based on column_widths."""
|
||||||
width = self.size().width()
|
width = self.size().width()
|
||||||
@ -287,13 +295,12 @@ class CompletionView(QTreeView):
|
|||||||
|
|
||||||
self._column_widths = model.srcmodel.COLUMN_WIDTHS
|
self._column_widths = model.srcmodel.COLUMN_WIDTHS
|
||||||
self._resize_columns()
|
self._resize_columns()
|
||||||
self.maybe_resize_completion()
|
self._maybe_update_geometry()
|
||||||
|
|
||||||
@pyqtSlot()
|
def _maybe_update_geometry(self):
|
||||||
def maybe_resize_completion(self):
|
"""Emit the update_geometry signal if the config says so."""
|
||||||
"""Emit the resize_completion signal if the config says so."""
|
|
||||||
if config.get('completion', 'shrink'):
|
if config.get('completion', 'shrink'):
|
||||||
self.resize_completion.emit()
|
self.update_geometry.emit()
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def on_clear_completion_selection(self):
|
def on_clear_completion_selection(self):
|
||||||
@ -304,6 +311,27 @@ class CompletionView(QTreeView):
|
|||||||
selmod.clearSelection()
|
selmod.clearSelection()
|
||||||
selmod.clearCurrentIndex()
|
selmod.clearCurrentIndex()
|
||||||
|
|
||||||
|
def sizeHint(self):
|
||||||
|
"""Get the completion size according to the config."""
|
||||||
|
# Get the configured height/percentage.
|
||||||
|
confheight = str(config.get('completion', 'height'))
|
||||||
|
if confheight.endswith('%'):
|
||||||
|
perc = int(confheight.rstrip('%'))
|
||||||
|
height = self.window().height() * perc / 100
|
||||||
|
else:
|
||||||
|
height = int(confheight)
|
||||||
|
# Shrink to content size if needed and shrinking is enabled
|
||||||
|
if config.get('completion', 'shrink'):
|
||||||
|
contents_height = (
|
||||||
|
self.viewportSizeHint().height() +
|
||||||
|
self.horizontalScrollBar().sizeHint().height())
|
||||||
|
if contents_height <= height:
|
||||||
|
height = contents_height
|
||||||
|
else:
|
||||||
|
contents_height = -1
|
||||||
|
# The width isn't really relevant as we're expanding anyways.
|
||||||
|
return QSize(-1, height)
|
||||||
|
|
||||||
def selectionChanged(self, selected, deselected):
|
def selectionChanged(self, selected, deselected):
|
||||||
"""Extend selectionChanged to call completers selection_changed."""
|
"""Extend selectionChanged to call completers selection_changed."""
|
||||||
if not self._active:
|
if not self._active:
|
||||||
@ -322,7 +350,7 @@ class CompletionView(QTreeView):
|
|||||||
|
|
||||||
def showEvent(self, e):
|
def showEvent(self, e):
|
||||||
"""Adjust the completion size and scroll when it's freshly shown."""
|
"""Adjust the completion size and scroll when it's freshly shown."""
|
||||||
self.resize_completion.emit()
|
self.update_geometry.emit()
|
||||||
scrollbar = self.verticalScrollBar()
|
scrollbar = self.verticalScrollBar()
|
||||||
if scrollbar is not None:
|
if scrollbar is not None:
|
||||||
scrollbar.setValue(scrollbar.minimum())
|
scrollbar.setValue(scrollbar.minimum())
|
||||||
|
@ -25,7 +25,7 @@ import itertools
|
|||||||
import functools
|
import functools
|
||||||
|
|
||||||
from PyQt5.QtCore import pyqtSlot, QRect, QPoint, QTimer, Qt
|
from PyQt5.QtCore import pyqtSlot, QRect, QPoint, QTimer, Qt
|
||||||
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QApplication
|
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QApplication, QSizePolicy
|
||||||
|
|
||||||
from qutebrowser.commands import runners, cmdutils
|
from qutebrowser.commands import runners, cmdutils
|
||||||
from qutebrowser.config import config
|
from qutebrowser.config import config
|
||||||
@ -125,6 +125,7 @@ class MainWindow(QWidget):
|
|||||||
_downloadview: The DownloadView widget.
|
_downloadview: The DownloadView widget.
|
||||||
_vbox: The main QVBoxLayout.
|
_vbox: The main QVBoxLayout.
|
||||||
_commandrunner: The main CommandRunner instance.
|
_commandrunner: The main CommandRunner instance.
|
||||||
|
_overlays: Widgets shown as overlay for the current webpage.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, geometry=None, parent=None):
|
def __init__(self, geometry=None, parent=None):
|
||||||
@ -137,6 +138,7 @@ class MainWindow(QWidget):
|
|||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self.setAttribute(Qt.WA_DeleteOnClose)
|
self.setAttribute(Qt.WA_DeleteOnClose)
|
||||||
self._commandrunner = None
|
self._commandrunner = None
|
||||||
|
self._overlays = []
|
||||||
self.win_id = next(win_id_gen)
|
self.win_id = next(win_id_gen)
|
||||||
self.registry = objreg.ObjectRegistry()
|
self.registry = objreg.ObjectRegistry()
|
||||||
objreg.window_registry[self.win_id] = self
|
objreg.window_registry[self.win_id] = self
|
||||||
@ -177,7 +179,10 @@ class MainWindow(QWidget):
|
|||||||
partial_match=True)
|
partial_match=True)
|
||||||
|
|
||||||
self._keyhint = keyhintwidget.KeyHintView(self.win_id, self)
|
self._keyhint = keyhintwidget.KeyHintView(self.win_id, self)
|
||||||
|
self._overlays.append((self._keyhint, self._keyhint.update_geometry))
|
||||||
self._messageview = messageview.MessageView(parent=self)
|
self._messageview = messageview.MessageView(parent=self)
|
||||||
|
self._overlays.append((self._messageview,
|
||||||
|
self._messageview.update_geometry))
|
||||||
|
|
||||||
log.init.debug("Initializing modes...")
|
log.init.debug("Initializing modes...")
|
||||||
modeman.init(self.win_id, self)
|
modeman.init(self.win_id, self)
|
||||||
@ -196,11 +201,49 @@ class MainWindow(QWidget):
|
|||||||
# When we're here the statusbar might not even really exist yet, so
|
# When we're here the statusbar might not even really exist yet, so
|
||||||
# resizing will fail. Therefore, we use singleShot QTimers to make sure
|
# resizing will fail. Therefore, we use singleShot QTimers to make sure
|
||||||
# we defer this until everything else is initialized.
|
# we defer this until everything else is initialized.
|
||||||
QTimer.singleShot(0, self._connect_resize_signals)
|
QTimer.singleShot(0, self._connect_overlay_signals)
|
||||||
objreg.get('config').changed.connect(self.on_config_changed)
|
objreg.get('config').changed.connect(self.on_config_changed)
|
||||||
|
|
||||||
objreg.get("app").new_window.emit(self)
|
objreg.get("app").new_window.emit(self)
|
||||||
|
|
||||||
|
def _update_overlay_geometry(self, widget=None):
|
||||||
|
"""Reposition/resize the given overlay.
|
||||||
|
|
||||||
|
If no widget is given, reposition/resize all overlays.
|
||||||
|
"""
|
||||||
|
if widget is None:
|
||||||
|
for w, _signal in self._overlays:
|
||||||
|
self._update_overlay_geometry(w)
|
||||||
|
return
|
||||||
|
|
||||||
|
if not widget.isVisible():
|
||||||
|
return
|
||||||
|
|
||||||
|
size_hint = widget.sizeHint()
|
||||||
|
if widget.sizePolicy().horizontalPolicy() == QSizePolicy.Expanding:
|
||||||
|
width = self.width()
|
||||||
|
else:
|
||||||
|
width = size_hint.width()
|
||||||
|
|
||||||
|
status_position = config.get('ui', 'status-position')
|
||||||
|
if status_position == 'bottom':
|
||||||
|
top = self.height() - self.status.height() - size_hint.height()
|
||||||
|
top = qtutils.check_overflow(top, 'int', fatal=False)
|
||||||
|
topleft = QPoint(0, top)
|
||||||
|
bottomright = QPoint(width, self.status.geometry().top())
|
||||||
|
elif status_position == 'top':
|
||||||
|
topleft = self.status.geometry().bottomLeft()
|
||||||
|
bottom = self.status.height() + widget.height()
|
||||||
|
bottom = qtutils.check_overflow(bottom, 'int', fatal=False)
|
||||||
|
bottomright = QPoint(size_hint.width(), bottom)
|
||||||
|
else:
|
||||||
|
raise ValueError("Invalid position {}!".format(status_position))
|
||||||
|
|
||||||
|
rect = QRect(topleft, bottomright)
|
||||||
|
log.misc.debug('new geometry for {!r}: {}'.format(widget, rect))
|
||||||
|
if rect.isValid():
|
||||||
|
widget.setGeometry(rect)
|
||||||
|
|
||||||
def _init_downloadmanager(self):
|
def _init_downloadmanager(self):
|
||||||
log.init.debug("Initializing downloads...")
|
log.init.debug("Initializing downloads...")
|
||||||
download_manager = downloads.DownloadManager(self.win_id, self)
|
download_manager = downloads.DownloadManager(self.win_id, self)
|
||||||
@ -218,6 +261,8 @@ class MainWindow(QWidget):
|
|||||||
completer_obj.on_selection_changed)
|
completer_obj.on_selection_changed)
|
||||||
objreg.register('completion', self._completion, scope='window',
|
objreg.register('completion', self._completion, scope='window',
|
||||||
window=self.win_id)
|
window=self.win_id)
|
||||||
|
self._overlays.append((self._completion,
|
||||||
|
self._completion.update_geometry))
|
||||||
|
|
||||||
def _init_command_dispatcher(self):
|
def _init_command_dispatcher(self):
|
||||||
dispatcher = commands.CommandDispatcher(self.win_id,
|
dispatcher = commands.CommandDispatcher(self.win_id,
|
||||||
@ -234,15 +279,15 @@ class MainWindow(QWidget):
|
|||||||
@pyqtSlot(str, str)
|
@pyqtSlot(str, str)
|
||||||
def on_config_changed(self, section, option):
|
def on_config_changed(self, section, option):
|
||||||
"""Resize the completion if related config options changed."""
|
"""Resize the completion if related config options changed."""
|
||||||
if section == 'completion' and option in ['height', 'shrink']:
|
if section != 'ui':
|
||||||
self.resize_completion()
|
return
|
||||||
elif section == 'ui' and option == 'statusbar-padding':
|
if option == 'statusbar-padding':
|
||||||
self.resize_completion()
|
self._update_overlay_geometry()
|
||||||
elif section == 'ui' and option == 'downloads-position':
|
elif option == 'downloads-position':
|
||||||
self._add_widgets()
|
self._add_widgets()
|
||||||
elif section == 'ui' and option == 'status-position':
|
elif option == 'status-position':
|
||||||
self._add_widgets()
|
self._add_widgets()
|
||||||
self.resize_completion()
|
self._update_overlay_geometry()
|
||||||
|
|
||||||
def _add_widgets(self):
|
def _add_widgets(self):
|
||||||
"""Add or readd all widgets to the VBox."""
|
"""Add or readd all widgets to the VBox."""
|
||||||
@ -303,14 +348,12 @@ class MainWindow(QWidget):
|
|||||||
log.init.warning("Error while loading geometry.")
|
log.init.warning("Error while loading geometry.")
|
||||||
self._set_default_geometry()
|
self._set_default_geometry()
|
||||||
|
|
||||||
def _connect_resize_signals(self):
|
def _connect_overlay_signals(self):
|
||||||
"""Connect the resize signal and resize everything once."""
|
"""Connect the resize signal and resize everything once."""
|
||||||
self._completion.resize_completion.connect(self.resize_completion)
|
for widget, signal in self._overlays:
|
||||||
self._keyhint.reposition_keyhint.connect(self.reposition_keyhint)
|
signal.connect(
|
||||||
self._messageview.reposition.connect(self._reposition_messageview)
|
functools.partial(self._update_overlay_geometry, widget))
|
||||||
self.resize_completion()
|
self._update_overlay_geometry(widget)
|
||||||
self.reposition_keyhint()
|
|
||||||
self._reposition_messageview()
|
|
||||||
|
|
||||||
def _set_default_geometry(self):
|
def _set_default_geometry(self):
|
||||||
"""Set some sensible default geometry."""
|
"""Set some sensible default geometry."""
|
||||||
@ -407,63 +450,6 @@ class MainWindow(QWidget):
|
|||||||
raise ValueError("Invalid position {}!".format(status_position))
|
raise ValueError("Invalid position {}!".format(status_position))
|
||||||
return QRect(topleft, bottomright)
|
return QRect(topleft, bottomright)
|
||||||
|
|
||||||
@pyqtSlot()
|
|
||||||
def resize_completion(self):
|
|
||||||
"""Adjust completion according to config."""
|
|
||||||
if not self._completion.isVisible():
|
|
||||||
# It doesn't make sense to resize the completion as long as it's
|
|
||||||
# not shown anyways.
|
|
||||||
return
|
|
||||||
# Get the configured height/percentage.
|
|
||||||
confheight = str(config.get('completion', 'height'))
|
|
||||||
if confheight.endswith('%'):
|
|
||||||
perc = int(confheight.rstrip('%'))
|
|
||||||
height = self.height() * perc / 100
|
|
||||||
else:
|
|
||||||
height = int(confheight)
|
|
||||||
# Shrink to content size if needed and shrinking is enabled
|
|
||||||
if config.get('completion', 'shrink'):
|
|
||||||
contents_height = (
|
|
||||||
self._completion.viewportSizeHint().height() +
|
|
||||||
self._completion.horizontalScrollBar().sizeHint().height())
|
|
||||||
if contents_height <= height:
|
|
||||||
height = contents_height
|
|
||||||
else:
|
|
||||||
contents_height = -1
|
|
||||||
rect = self._get_overlay_position(height)
|
|
||||||
log.misc.debug('completion rect: {}'.format(rect))
|
|
||||||
if rect.isValid():
|
|
||||||
self._completion.setGeometry(rect)
|
|
||||||
|
|
||||||
@pyqtSlot()
|
|
||||||
def reposition_keyhint(self):
|
|
||||||
"""Adjust keyhint according to config."""
|
|
||||||
if not self._keyhint.isVisible():
|
|
||||||
return
|
|
||||||
# Shrink the window to the shown text and place it at the bottom left
|
|
||||||
width = self._keyhint.width()
|
|
||||||
height = self._keyhint.height()
|
|
||||||
topleft_y = self.height() - self.status.height() - height
|
|
||||||
topleft_y = qtutils.check_overflow(topleft_y, 'int', fatal=False)
|
|
||||||
topleft = QPoint(0, topleft_y)
|
|
||||||
bottomright = (self.status.geometry().topLeft() +
|
|
||||||
QPoint(width, 0))
|
|
||||||
rect = QRect(topleft, bottomright)
|
|
||||||
log.misc.debug('keyhint rect: {}'.format(rect))
|
|
||||||
if rect.isValid():
|
|
||||||
self._keyhint.setGeometry(rect)
|
|
||||||
|
|
||||||
@pyqtSlot()
|
|
||||||
def _reposition_messageview(self):
|
|
||||||
"""Position the message view correctly."""
|
|
||||||
if not self._messageview.isVisible():
|
|
||||||
return
|
|
||||||
height = self._messageview.message_height()
|
|
||||||
rect = self._get_overlay_position(height)
|
|
||||||
log.misc.debug('messageview rect: {}'.format(rect))
|
|
||||||
if rect.isValid():
|
|
||||||
self._messageview.setGeometry(rect)
|
|
||||||
|
|
||||||
@cmdutils.register(instance='main-window', scope='window')
|
@cmdutils.register(instance='main-window', scope='window')
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def close(self):
|
def close(self):
|
||||||
@ -490,8 +476,7 @@ class MainWindow(QWidget):
|
|||||||
e: The QResizeEvent
|
e: The QResizeEvent
|
||||||
"""
|
"""
|
||||||
super().resizeEvent(e)
|
super().resizeEvent(e)
|
||||||
self.resize_completion()
|
self._update_overlay_geometry()
|
||||||
self.reposition_keyhint()
|
|
||||||
self._downloadview.updateGeometry()
|
self._downloadview.updateGeometry()
|
||||||
self.tabbed_browser.tabBar().refresh()
|
self.tabbed_browser.tabBar().refresh()
|
||||||
|
|
||||||
|
@ -20,8 +20,8 @@
|
|||||||
"""Showing messages above the statusbar."""
|
"""Showing messages above the statusbar."""
|
||||||
|
|
||||||
|
|
||||||
from PyQt5.QtCore import pyqtSlot, pyqtSignal, QTimer, Qt
|
from PyQt5.QtCore import pyqtSlot, pyqtSignal, QTimer, Qt, QSize
|
||||||
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel
|
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QSizePolicy
|
||||||
|
|
||||||
from qutebrowser.config import config, style
|
from qutebrowser.config import config, style
|
||||||
from qutebrowser.utils import usertypes, objreg
|
from qutebrowser.utils import usertypes, objreg
|
||||||
@ -71,13 +71,14 @@ class MessageView(QWidget):
|
|||||||
|
|
||||||
"""Widget which stacks error/warning/info messages."""
|
"""Widget which stacks error/warning/info messages."""
|
||||||
|
|
||||||
reposition = pyqtSignal()
|
update_geometry = pyqtSignal()
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self._vbox = QVBoxLayout(self)
|
self._vbox = QVBoxLayout(self)
|
||||||
self._vbox.setContentsMargins(0, 0, 0, 0)
|
self._vbox.setContentsMargins(0, 0, 0, 0)
|
||||||
self._vbox.setSpacing(0)
|
self._vbox.setSpacing(0)
|
||||||
|
self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
||||||
|
|
||||||
self._clear_timer = QTimer()
|
self._clear_timer = QTimer()
|
||||||
self._clear_timer.timeout.connect(self._clear_messages)
|
self._clear_timer.timeout.connect(self._clear_messages)
|
||||||
@ -87,15 +88,17 @@ class MessageView(QWidget):
|
|||||||
self._last_text = None
|
self._last_text = None
|
||||||
self._messages = []
|
self._messages = []
|
||||||
|
|
||||||
|
def sizeHint(self):
|
||||||
|
"""Get the proposed height for the view."""
|
||||||
|
height = sum(label.sizeHint().height() for label in self._messages)
|
||||||
|
# The width isn't really relevant as we're expanding anyways.
|
||||||
|
return QSize(-1, height)
|
||||||
|
|
||||||
@config.change_filter('ui', 'message-timeout')
|
@config.change_filter('ui', 'message-timeout')
|
||||||
def _set_clear_timer_interval(self):
|
def _set_clear_timer_interval(self):
|
||||||
"""Configure self._clear_timer according to the config."""
|
"""Configure self._clear_timer according to the config."""
|
||||||
self._clear_timer.setInterval(config.get('ui', 'message-timeout'))
|
self._clear_timer.setInterval(config.get('ui', 'message-timeout'))
|
||||||
|
|
||||||
def message_height(self):
|
|
||||||
"""Get the total height of all messages."""
|
|
||||||
return sum(label.sizeHint().height() for label in self._messages)
|
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def _clear_messages(self):
|
def _clear_messages(self):
|
||||||
"""Hide and delete all messages."""
|
"""Hide and delete all messages."""
|
||||||
@ -121,4 +124,4 @@ class MessageView(QWidget):
|
|||||||
self._messages.append(widget)
|
self._messages.append(widget)
|
||||||
self._last_text = text
|
self._last_text = text
|
||||||
self.show()
|
self.show()
|
||||||
self.reposition.emit()
|
self.update_geometry.emit()
|
||||||
|
@ -42,7 +42,7 @@ class KeyHintView(QLabel):
|
|||||||
_win_id: Window ID of parent.
|
_win_id: Window ID of parent.
|
||||||
|
|
||||||
Signals:
|
Signals:
|
||||||
reposition_keyhint: Emitted when this widget should be resized.
|
update_geometry: Emitted when this widget should be resized/positioned.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
STYLESHEET = """
|
STYLESHEET = """
|
||||||
@ -55,7 +55,7 @@ class KeyHintView(QLabel):
|
|||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
reposition_keyhint = pyqtSignal()
|
update_geometry = pyqtSignal()
|
||||||
|
|
||||||
def __init__(self, win_id, parent=None):
|
def __init__(self, win_id, parent=None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
@ -73,7 +73,7 @@ class KeyHintView(QLabel):
|
|||||||
|
|
||||||
def showEvent(self, e):
|
def showEvent(self, e):
|
||||||
"""Adjust the keyhint size when it's freshly shown."""
|
"""Adjust the keyhint size when it's freshly shown."""
|
||||||
self.reposition_keyhint.emit()
|
self.update_geometry.emit()
|
||||||
super().showEvent(e)
|
super().showEvent(e)
|
||||||
|
|
||||||
@pyqtSlot(str)
|
@pyqtSlot(str)
|
||||||
@ -126,4 +126,4 @@ class KeyHintView(QLabel):
|
|||||||
|
|
||||||
self.setText(text)
|
self.setText(text)
|
||||||
self.adjustSize()
|
self.adjustSize()
|
||||||
self.reposition_keyhint.emit()
|
self.update_geometry.emit()
|
||||||
|
@ -39,6 +39,7 @@ def completionview(qtbot, status_command_stub, config_stub, win_registry,
|
|||||||
'scrollbar-padding': 2,
|
'scrollbar-padding': 2,
|
||||||
'shrink': False,
|
'shrink': False,
|
||||||
'quick-complete': False,
|
'quick-complete': False,
|
||||||
|
'height': '50%',
|
||||||
},
|
},
|
||||||
'colors': {
|
'colors': {
|
||||||
'completion.fg': QColor(),
|
'completion.fg': QColor(),
|
||||||
@ -87,13 +88,13 @@ def test_set_pattern(completionview):
|
|||||||
model.set_pattern.assert_called_with('foo')
|
model.set_pattern.assert_called_with('foo')
|
||||||
|
|
||||||
|
|
||||||
def test_maybe_resize_completion(completionview, config_stub, qtbot):
|
def test_maybe_update_geometry(completionview, config_stub, qtbot):
|
||||||
"""Ensure completion is resized only if shrink is True."""
|
"""Ensure completion is resized only if shrink is True."""
|
||||||
with qtbot.assertNotEmitted(completionview.resize_completion):
|
with qtbot.assertNotEmitted(completionview.update_geometry):
|
||||||
completionview.maybe_resize_completion()
|
completionview._maybe_update_geometry()
|
||||||
config_stub.data = {'completion': {'shrink': True}}
|
config_stub.data['completion']['shrink'] = True
|
||||||
with qtbot.waitSignal(completionview.resize_completion):
|
with qtbot.waitSignal(completionview.update_geometry):
|
||||||
completionview.maybe_resize_completion()
|
completionview._maybe_update_geometry()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('which, tree, expected', [
|
@pytest.mark.parametrize('which, tree, expected', [
|
||||||
|
@ -67,13 +67,13 @@ def test_message_hiding(qtbot, view):
|
|||||||
assert not view._messages
|
assert not view._messages
|
||||||
|
|
||||||
|
|
||||||
def test_message_height(view):
|
def test_size_hint(view):
|
||||||
"""The message height should increase with more messages."""
|
"""The message height should increase with more messages."""
|
||||||
view.show_message(usertypes.MessageLevel.info, 'test1')
|
view.show_message(usertypes.MessageLevel.info, 'test1')
|
||||||
height1 = view.message_height()
|
height1 = view.sizeHint().height()
|
||||||
assert height1 > 0
|
assert height1 > 0
|
||||||
view.show_message(usertypes.MessageLevel.info, 'test2')
|
view.show_message(usertypes.MessageLevel.info, 'test2')
|
||||||
height2 = view.message_height()
|
height2 = view.sizeHint().height()
|
||||||
assert height2 == height1 * 2
|
assert height2 == height1 * 2
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user