Start implementing message-timeout

This commit is contained in:
Florian Bruhin 2014-05-16 15:33:36 +02:00
parent 1bfbdd79e4
commit 7eb19e2a1e
6 changed files with 73 additions and 64 deletions

1
TODO
View File

@ -57,7 +57,6 @@ Improvements / minor features
=============================
- configurable warning when closing window with multiple tabs open
- Hide statusbar messages after timeout, not on keypress
- Reimplement tabbar to paint it by ourselves to look like dwb
- Save cookies in Netscape format so it can be used by wget.
http://www.cookiecentral.com/faq/#3.5

View File

@ -368,7 +368,6 @@ class QuteBrowser(QApplication):
self.modeman.entered.connect(status.on_mode_entered)
self.modeman.left.connect(status.on_mode_left)
self.modeman.left.connect(status.cmd.on_mode_left)
self.modeman.key_pressed.connect(status.on_key_pressed)
# commands
cmd.got_cmd.connect(self.commandmanager.run_safely)
@ -386,14 +385,14 @@ class QuteBrowser(QApplication):
# messages
self.messagebridge.error.connect(status.disp_error)
self.messagebridge.info.connect(status.txt.set_temptext)
self.messagebridge.text.connect(status.txt.set_normaltext)
self.messagebridge.info.connect(status.disp_temp_text)
self.messagebridge.text.connect(status.set_text)
self.messagebridge.set_cmd_text.connect(cmd.set_cmd_text)
# config
self.config.style_changed.connect(style.invalidate_caches)
for obj in [tabs, completion, self.mainwindow, self.cmd_history,
websettings, kp['normal'], self.modeman]:
websettings, kp['normal'], self.modeman, status]:
self.config.changed.connect(obj.on_config_changed)
# statusbar
@ -405,7 +404,7 @@ class QuteBrowser(QApplication):
tabs.currentChanged.connect(status.percentage.on_tab_changed)
tabs.cur_scroll_perc_changed.connect(status.percentage.set_perc)
tabs.cur_statusbar_message.connect(status.txt.on_statusbar_message)
tabs.cur_statusbar_message.connect(status.on_statusbar_message)
tabs.currentChanged.connect(status.url.on_tab_changed)
tabs.cur_url_text_changed.connect(status.url.set_url)

View File

@ -205,6 +205,10 @@ DATA = OrderedDict([
('show-scroll-bar-vertical',
SettingValue(types.ScrollBarPolicy(), 'never'),
"Whether to show vertical scrollbar for web content."),
('message-timeout',
SettingValue(types.Int(), '3000'),
"Time (in ms) to show messages in the statusbar for."),
)),
('network', sect.KeyValue(

View File

@ -76,12 +76,10 @@ class ModeManager(QObject):
arg: Name of the entered mode.
left: Emitted when a mode is left.
arg: Name of the left mode.
key_pressed: A key was pressed.
"""
entered = pyqtSignal(str)
left = pyqtSignal(str)
key_pressed = pyqtSignal('QKeyEvent')
def __init__(self, parent=None):
super().__init__(parent)
@ -123,7 +121,6 @@ class ModeManager(QObject):
"""
handler = self._handlers[self.mode]
logging.debug("calling handler {}".format(handler.__qualname__))
self.key_pressed.emit(event)
handled = handler(event) if handler is not None else False
if handled:
@ -242,9 +239,6 @@ class ModeManager(QObject):
Return:
True if event should be filtered, False otherwise.
Emit:
key_pressed: When a key was actually pressed.
"""
if self.mode is None:
# We got events before mode is set, so just pass them through.

View File

@ -17,8 +17,6 @@
"""Text displayed in the statusbar."""
from PyQt5.QtCore import pyqtSlot
from qutebrowser.widgets.statusbar._textbase import TextBase
@ -28,15 +26,12 @@ class Text(TextBase):
Attributes:
normaltext: The "permanent" text. Never automatically cleared.
temptext: The temporary text. Cleared on a keystroke.
errortext: The error text. Cleared on a keystroke.
temptext: The temporary text to display.
_initializing: True if we're currently in __init__ and no text should
be updated yet.
The errortext has the highest priority, i.e. it will always be shown
when it is set. The temptext is shown when there is no error, and the
(permanent) text is shown when there is neither a temporary text nor an
error.
The temptext is shown from StatusBar when a temporary text or error is
available. If not, the permanent text is shown.
"""
def __init__(self, parent=None):
@ -44,7 +39,6 @@ class Text(TextBase):
self._initializing = True
self.normaltext = ''
self.temptext = ''
self.errortext = ''
self._initializing = False
def __setattr__(self, name, val):
@ -58,30 +52,9 @@ class Text(TextBase):
Called from __setattr__ if a text property changed.
"""
for text in [self.errortext, self.temptext, self.normaltext]:
for text in [self.temptext, self.normaltext]:
if text:
self.setText(text)
break
else:
self.setText('')
@pyqtSlot(str)
def set_normaltext(self, val):
"""Setter for normaltext, to be used as Qt slot."""
self.normaltext = val
@pyqtSlot(str)
def on_statusbar_message(self, val):
"""Called when javascript tries to set a statusbar message.
For some reason, this is emitted a lot with an empty string during page
load, so we currently ignore these and thus don't support clearing the
message, which is a bit unfortunate...
"""
if val:
self.temptext = val
@pyqtSlot(str)
def set_temptext(self, val):
"""Setter for temptext, to be used as Qt slot."""
self.temptext = val

View File

@ -17,10 +17,14 @@
"""The main statusbar widget."""
from PyQt5.QtCore import pyqtSignal, pyqtSlot, pyqtProperty, Qt
import logging
from collections import deque
from PyQt5.QtCore import pyqtSignal, pyqtSlot, pyqtProperty, Qt, QTimer
from PyQt5.QtWidgets import QWidget, QHBoxLayout, QStackedLayout, QSizePolicy
import qutebrowser.keyinput.modeman as modeman
import qutebrowser.config.config as config
from qutebrowser.widgets.statusbar._command import Command
from qutebrowser.widgets.statusbar._progress import Progress
from qutebrowser.widgets.statusbar._text import Text
@ -46,6 +50,9 @@ class StatusBar(QWidget):
prog: The Progress widget in the statusbar.
_hbox: The main QHBoxLayout.
_stack: The QStackedLayout with cmd/txt widgets.
_text_queue: A deque of (error, text) tuples to be displayed.
error: True if message is an error, False otherwise
_text_pop_timer: A QTimer displaying the error messages.
Class attributes:
_error: If there currently is an error, accessed through the error
@ -104,6 +111,11 @@ class StatusBar(QWidget):
self.txt = Text(self)
self._stack.addWidget(self.txt)
self._text_queue = deque()
self._text_pop_timer = QTimer()
self._text_pop_timer.setInterval(
config.get('general', 'message-timeout'))
self._text_pop_timer.timeout.connect(self._pop_text)
self.cmd.show_cmd.connect(self._show_cmd_widget)
self.cmd.hide_cmd.connect(self._hide_cmd_widget)
@ -139,39 +151,49 @@ class StatusBar(QWidget):
self._error = val
self.setStyleSheet(get_stylesheet(self.STYLESHEET))
def _pop_text(self):
"""Display a text in the statusbar and pop it from _text_queue."""
try:
error, text = self._text_queue.popleft()
except IndexError:
self.error = False
self.txt.temptext = ''
self._text_pop_timer.stop()
return
logging.debug("Displaying {} message: {}".format(
'error' if error else 'text', text))
logging.debug("Remaining: {}".format(self._text_queue))
self.error = error
self.txt.temptext = text
def _show_cmd_widget(self):
"""Show command widget instead of temporary text."""
self._text_pop_timer.stop()
self._stack.setCurrentWidget(self.cmd)
self.clear_error()
def _hide_cmd_widget(self):
"""Show temporary text instead of command widget."""
if self._text_queue and not self._text_pop_timer.isActive():
self._pop_text()
self._text_pop_timer.start()
self._stack.setCurrentWidget(self.txt)
@pyqtSlot(str)
def disp_error(self, text):
"""Display an error in the statusbar."""
self.error = True
self.txt.errortext = text
self._text_queue.append((True, text))
self._text_pop_timer.start()
@pyqtSlot()
def clear_error(self):
"""Clear a displayed error from the status bar."""
self.error = False
self.txt.errortext = ''
@pyqtSlot(str)
def disp_temp_text(self, text):
"""Add a temporary text to the queue."""
self._text_queue.append((False, text))
self._text_pop_timer.start()
@pyqtSlot('QKeyEvent')
def on_key_pressed(self, e):
"""Hide temporary error message if a key was pressed.
Args:
e: The original QKeyEvent.
"""
if e.key() in [Qt.Key_Control, Qt.Key_Alt, Qt.Key_Shift, Qt.Key_Meta]:
# Only modifier pressed, don't hide yet.
return
self.txt.set_temptext('')
self.clear_error()
@pyqtSlot(str)
def set_text(self, val):
"""Set a normal (persistent) text in the status bar."""
self.txt.normaltext = val
@pyqtSlot(str)
def on_mode_entered(self, mode):
@ -185,6 +207,24 @@ class StatusBar(QWidget):
if mode in modeman.instance().passthrough:
self.txt.normaltext = ""
@pyqtSlot(str)
def on_statusbar_message(self, val):
"""Called when javascript tries to set a statusbar message.
For some reason, this is emitted a lot with an empty string during page
load, so we currently ignore these and thus don't support clearing the
message, which is a bit unfortunate...
"""
if val:
self.txt.temptext = val
@pyqtSlot(str, str)
def on_config_changed(self, section, option):
"""Update message timeout when config changed."""
if section == 'general' and option == 'message-timeout':
self._text_pop_timer.setInterval(
config.get('general', 'message-timeout'))
def resizeEvent(self, e):
"""Extend resizeEvent of QWidget to emit a resized signal afterwards.