Merge branch 'master' of ssh://the-compiler.org:2323/qutebrowser
This commit is contained in:
commit
4661f2c30b
2
THANKS
2
THANKS
@ -24,6 +24,7 @@ valuable ones:
|
|||||||
- andrean
|
- andrean
|
||||||
- chelmuth
|
- chelmuth
|
||||||
- quark
|
- quark
|
||||||
|
- Bleeding Fingers
|
||||||
|
|
||||||
Thanks to these people for helpful bits and pieces in the Qt bugtracker and IRC
|
Thanks to these people for helpful bits and pieces in the Qt bugtracker and IRC
|
||||||
channel:
|
channel:
|
||||||
@ -51,6 +52,7 @@ channel:
|
|||||||
- AlexWMF
|
- AlexWMF
|
||||||
- scummos
|
- scummos
|
||||||
- svuorela
|
- svuorela
|
||||||
|
- kpj
|
||||||
|
|
||||||
Thanks to these projects which were essential while developing qutebrowser:
|
Thanks to these projects which were essential while developing qutebrowser:
|
||||||
- Python
|
- Python
|
||||||
|
21
TODO
21
TODO
@ -11,6 +11,7 @@ Style
|
|||||||
=====
|
=====
|
||||||
|
|
||||||
Refactor completion widget mess (initializing / changing completions)
|
Refactor completion widget mess (initializing / changing completions)
|
||||||
|
keypress-signal-foo is a bit of a chaos and might be done better
|
||||||
|
|
||||||
Major features
|
Major features
|
||||||
==============
|
==============
|
||||||
@ -25,7 +26,6 @@ Plugin architecture
|
|||||||
NoScript
|
NoScript
|
||||||
Certificate Patrol
|
Certificate Patrol
|
||||||
https://chrome.google.com/webstore/detail/remove-google-redirects/ccenmflbeofaceccfhhggbagkblihpoh
|
https://chrome.google.com/webstore/detail/remove-google-redirects/ccenmflbeofaceccfhhggbagkblihpoh
|
||||||
Insert mode
|
|
||||||
Extern editor
|
Extern editor
|
||||||
Downloads
|
Downloads
|
||||||
webinterface for settings/colors/bindings
|
webinterface for settings/colors/bindings
|
||||||
@ -37,6 +37,12 @@ Before Blink
|
|||||||
session handling / saving
|
session handling / saving
|
||||||
IPC, like dwb -x
|
IPC, like dwb -x
|
||||||
Mode handling?
|
Mode handling?
|
||||||
|
- Problem: how to detect we're going to insert mode:
|
||||||
|
-> Detect mouse clicks and use QWebFrame::hitTestContent (only mouse)
|
||||||
|
-> Use javascript: http://stackoverflow.com/a/2848120/2085149
|
||||||
|
-> Use microFocusChanged and check active element via:
|
||||||
|
frame = page.currentFrame()
|
||||||
|
elem = frame.findFirstElement('*:focus')
|
||||||
Bookmarks
|
Bookmarks
|
||||||
Internationalization
|
Internationalization
|
||||||
Marks
|
Marks
|
||||||
@ -59,7 +65,18 @@ handle completion for aliases
|
|||||||
keybind should have completion for commands/arguments
|
keybind should have completion for commands/arguments
|
||||||
Hiding scrollbars
|
Hiding scrollbars
|
||||||
Ctrl+A/X to increase/decrease last number in URL
|
Ctrl+A/X to increase/decrease last number in URL
|
||||||
keypress-signal-foo is a bit of a chaos and might be done better
|
command completion gets hidden when doing a new ValueList value
|
||||||
|
logging contexts
|
||||||
|
catch import errors for PyQt and QtWebKit
|
||||||
|
|
||||||
|
Qt Bugs
|
||||||
|
========
|
||||||
|
|
||||||
|
- Printing under windows produced blank pages
|
||||||
|
https://bugreports.qt-project.org/browse/QTBUG-19571
|
||||||
|
If this isn't fixed in Qt 5.3, bug should be reopened.
|
||||||
|
|
||||||
|
- Web inspector is blank unless .hide()/.show() is called.
|
||||||
|
|
||||||
Other stuff
|
Other stuff
|
||||||
===========
|
===========
|
||||||
|
@ -164,7 +164,7 @@ class CurCommandDispatcher(QObject):
|
|||||||
if self._tabs.currentWidget().page_.history().canGoBack():
|
if self._tabs.currentWidget().page_.history().canGoBack():
|
||||||
self._tabs.currentWidget().back()
|
self._tabs.currentWidget().back()
|
||||||
else:
|
else:
|
||||||
message.info("At beginning of history.")
|
message.error("At beginning of history.")
|
||||||
break
|
break
|
||||||
|
|
||||||
@cmdutils.register(instance='mainwindow.tabs.cur')
|
@cmdutils.register(instance='mainwindow.tabs.cur')
|
||||||
@ -180,7 +180,7 @@ class CurCommandDispatcher(QObject):
|
|||||||
if self._tabs.currentWidget().page_.history().canGoForward():
|
if self._tabs.currentWidget().page_.history().canGoForward():
|
||||||
self._tabs.currentWidget().forward()
|
self._tabs.currentWidget().forward()
|
||||||
else:
|
else:
|
||||||
message.info("At end of history.")
|
message.error("At end of history.")
|
||||||
break
|
break
|
||||||
|
|
||||||
@cmdutils.register(instance='mainwindow.tabs.cur')
|
@cmdutils.register(instance='mainwindow.tabs.cur')
|
||||||
|
@ -88,7 +88,10 @@ class register: # pylint: disable=invalid-name
|
|||||||
mainname = name[0]
|
mainname = name[0]
|
||||||
names += name
|
names += name
|
||||||
count, nargs = self._get_nargs_count(func)
|
count, nargs = self._get_nargs_count(func)
|
||||||
|
if func.__doc__ is not None:
|
||||||
desc = func.__doc__.splitlines()[0].strip().rstrip('.')
|
desc = func.__doc__.splitlines()[0].strip().rstrip('.')
|
||||||
|
else:
|
||||||
|
desc = ""
|
||||||
cmd = Command(name=mainname, maxsplit=self.maxsplit,
|
cmd = Command(name=mainname, maxsplit=self.maxsplit,
|
||||||
hide=self.hide, nargs=nargs, count=count, desc=desc,
|
hide=self.hide, nargs=nargs, count=count, desc=desc,
|
||||||
instance=self.instance, handler=func,
|
instance=self.instance, handler=func,
|
||||||
|
@ -497,18 +497,22 @@ DATA = OrderedDict([
|
|||||||
|
|
||||||
('tab.fg',
|
('tab.fg',
|
||||||
SettingValue(types.Color(), "white"),
|
SettingValue(types.Color(), "white"),
|
||||||
"Foreground color of the tabbar."),
|
"Foreground color of tabs."),
|
||||||
|
|
||||||
('tab.bg',
|
('tab.bg',
|
||||||
SettingValue(types.Color(), "grey"),
|
SettingValue(types.Color(), "grey"),
|
||||||
"Background color of the tabbar."),
|
"Background color of unselected tabs."),
|
||||||
|
|
||||||
('tab.bg.selected',
|
('tab.bg.selected',
|
||||||
SettingValue(types.Color(), "black"),
|
SettingValue(types.Color(), "black"),
|
||||||
"Background color of the tabbar for the selected tab."),
|
"Background color of selected tabs."),
|
||||||
|
|
||||||
|
('tab.bg.bar',
|
||||||
|
SettingValue(types.Color(), "#555555"),
|
||||||
|
"Background color of the tabbar."),
|
||||||
|
|
||||||
('tab.seperator',
|
('tab.seperator',
|
||||||
SettingValue(types.Color(), "white"),
|
SettingValue(types.Color(), "#555555"),
|
||||||
"Color for the tab seperator."),
|
"Color for the tab seperator."),
|
||||||
|
|
||||||
('hints.fg',
|
('hints.fg',
|
||||||
|
@ -263,11 +263,12 @@ class CompletionModel(QAbstractItemModel):
|
|||||||
"""
|
"""
|
||||||
if not index.isValid():
|
if not index.isValid():
|
||||||
return Qt.NoItemFlags
|
return Qt.NoItemFlags
|
||||||
flags = Qt.ItemIsEnabled
|
if index.parent().isValid():
|
||||||
if len(self._id_map[index.internalId()].children) > 0:
|
# item
|
||||||
return flags
|
return Qt.ItemIsEnabled | Qt.ItemIsSelectable
|
||||||
else:
|
else:
|
||||||
return flags | Qt.ItemIsSelectable
|
# category
|
||||||
|
return Qt.NoItemFlags
|
||||||
|
|
||||||
def index(self, row, column, parent=QModelIndex()):
|
def index(self, row, column, parent=QModelIndex()):
|
||||||
"""Return the QModelIndex for row/column/parent.
|
"""Return the QModelIndex for row/column/parent.
|
||||||
|
@ -18,8 +18,10 @@
|
|||||||
"""Utilities used for debugging."""
|
"""Utilities used for debugging."""
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
import logging
|
||||||
|
from functools import wraps
|
||||||
|
|
||||||
from PyQt5.QtCore import pyqtRemoveInputHook
|
from PyQt5.QtCore import pyqtRemoveInputHook, QEvent
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# pylint: disable=import-error
|
# pylint: disable=import-error
|
||||||
@ -29,6 +31,24 @@ except ImportError:
|
|||||||
|
|
||||||
import qutebrowser.commands.utils as cmdutils
|
import qutebrowser.commands.utils as cmdutils
|
||||||
|
|
||||||
|
EVENTS = {n: x for x, n in vars(QEvent).items()
|
||||||
|
if isinstance(n, QEvent.Type)}
|
||||||
|
|
||||||
|
|
||||||
|
def log_events(klass):
|
||||||
|
"""Class decorator to log Qt events."""
|
||||||
|
old_event = klass.event
|
||||||
|
|
||||||
|
@wraps(old_event)
|
||||||
|
def new_event(self, e, *args, **kwargs):
|
||||||
|
"""Wrapper for event() which logs events."""
|
||||||
|
logging.debug("Event in {}: {}".format(klass.__name__,
|
||||||
|
EVENTS[e.type()]))
|
||||||
|
return old_event(self, e, *args, **kwargs)
|
||||||
|
|
||||||
|
klass.event = new_event
|
||||||
|
return klass
|
||||||
|
|
||||||
|
|
||||||
@cmdutils.register(name='settrace', hide=True)
|
@cmdutils.register(name='settrace', hide=True)
|
||||||
def set_trace():
|
def set_trace():
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
import logging
|
import logging
|
||||||
import functools
|
import functools
|
||||||
|
|
||||||
from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QEvent
|
from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt
|
||||||
from PyQt5.QtWidgets import QApplication
|
from PyQt5.QtWidgets import QApplication
|
||||||
from PyQt5.QtWebKit import QWebSettings
|
from PyQt5.QtWebKit import QWebSettings
|
||||||
from PyQt5.QtWebKitWidgets import QWebView, QWebPage
|
from PyQt5.QtWebKitWidgets import QWebView, QWebPage
|
||||||
@ -248,10 +248,10 @@ class BrowserTab(QWebView):
|
|||||||
# Let superclass handle the event
|
# Let superclass handle the event
|
||||||
return super().paintEvent(e)
|
return super().paintEvent(e)
|
||||||
|
|
||||||
def event(self, e):
|
def mousePressEvent(self, e):
|
||||||
"""Check if a link was clicked with the middle button or Ctrl.
|
"""Check if a link was clicked with the middle button or Ctrl.
|
||||||
|
|
||||||
Extend the superclass event().
|
Extend the superclass mousePressEvent().
|
||||||
|
|
||||||
This also is a bit of a hack, but it seems it's the only possible way.
|
This also is a bit of a hack, but it seems it's the only possible way.
|
||||||
Set the _open_target attribute accordingly.
|
Set the _open_target attribute accordingly.
|
||||||
@ -260,9 +260,8 @@ class BrowserTab(QWebView):
|
|||||||
e: The arrived event.
|
e: The arrived event.
|
||||||
|
|
||||||
Return:
|
Return:
|
||||||
The superclass event return value.
|
The superclass return value.
|
||||||
"""
|
"""
|
||||||
if e.type() in [QEvent.MouseButtonPress, QEvent.MouseButtonDblClick]:
|
|
||||||
if self._force_open_target is not None:
|
if self._force_open_target is not None:
|
||||||
self._open_target = self._force_open_target
|
self._open_target = self._force_open_target
|
||||||
self._force_open_target = None
|
self._force_open_target = None
|
||||||
@ -277,4 +276,4 @@ class BrowserTab(QWebView):
|
|||||||
logging.debug("Setting target: {}".format(self._open_target))
|
logging.debug("Setting target: {}".format(self._open_target))
|
||||||
else:
|
else:
|
||||||
self._open_target = "normal"
|
self._open_target = "normal"
|
||||||
return super().event(e)
|
return super().mousePressEvent(e)
|
||||||
|
@ -79,17 +79,20 @@ class CompletionView(QTreeView):
|
|||||||
{color[completion.bg]}
|
{color[completion.bg]}
|
||||||
outline: 0;
|
outline: 0;
|
||||||
}}
|
}}
|
||||||
QTreeView::item {{
|
|
||||||
|
QTreeView::item:enabled {{
|
||||||
{color[completion.item.fg]}
|
{color[completion.item.fg]}
|
||||||
{color[completion.item.bg]}
|
{color[completion.item.bg]}
|
||||||
}}
|
}}
|
||||||
QTreeView::item:has-children {{
|
|
||||||
|
QTreeView::item:disabled {{
|
||||||
{color[completion.category.fg]}
|
{color[completion.category.fg]}
|
||||||
{color[completion.category.bg]}
|
{color[completion.category.bg]}
|
||||||
border-top: 1px solid {color[completion.category.border.top]};
|
border-top: 1px solid {color[completion.category.border.top]};
|
||||||
border-bottom: 1px solid
|
border-bottom: 1px solid
|
||||||
{color[completion.category.border.bottom]};
|
{color[completion.category.border.bottom]};
|
||||||
}}
|
}}
|
||||||
|
|
||||||
QTreeView::item:selected {{
|
QTreeView::item:selected {{
|
||||||
border-top: 1px solid {color[completion.item.selected.border.top]};
|
border-top: 1px solid {color[completion.item.selected.border.top]};
|
||||||
border-bottom: 1px solid
|
border-bottom: 1px solid
|
||||||
@ -98,8 +101,7 @@ class CompletionView(QTreeView):
|
|||||||
{color[completion.item.selected.fg]}
|
{color[completion.item.selected.fg]}
|
||||||
}}
|
}}
|
||||||
"""
|
"""
|
||||||
# FIXME because we use :has-children, if a category is empty, it won't look
|
|
||||||
# like one anymore
|
|
||||||
change_completed_part = pyqtSignal(str)
|
change_completed_part = pyqtSignal(str)
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
|
@ -268,6 +268,8 @@ class TabbedBrowser(TabWidget):
|
|||||||
"""
|
"""
|
||||||
if self._url_stack:
|
if self._url_stack:
|
||||||
self.tabopen(self._url_stack.pop())
|
self.tabopen(self._url_stack.pop())
|
||||||
|
else:
|
||||||
|
message.error("Nothing to undo!")
|
||||||
|
|
||||||
@cmdutils.register(instance='mainwindow.tabs', name='tabprev')
|
@cmdutils.register(instance='mainwindow.tabs', name='tabprev')
|
||||||
def switch_prev(self, count=1):
|
def switch_prev(self, count=1):
|
||||||
@ -284,7 +286,7 @@ class TabbedBrowser(TabWidget):
|
|||||||
elif config.get('tabbar', 'wrap'):
|
elif config.get('tabbar', 'wrap'):
|
||||||
self.setCurrentIndex(newidx % self.count())
|
self.setCurrentIndex(newidx % self.count())
|
||||||
else:
|
else:
|
||||||
message.info("First tab")
|
message.error("First tab")
|
||||||
|
|
||||||
@cmdutils.register(instance='mainwindow.tabs', name='tabnext')
|
@cmdutils.register(instance='mainwindow.tabs', name='tabnext')
|
||||||
def switch_next(self, count=1):
|
def switch_next(self, count=1):
|
||||||
@ -301,7 +303,7 @@ class TabbedBrowser(TabWidget):
|
|||||||
elif config.get('tabbar', 'wrap'):
|
elif config.get('tabbar', 'wrap'):
|
||||||
self.setCurrentIndex(newidx % self.count())
|
self.setCurrentIndex(newidx % self.count())
|
||||||
else:
|
else:
|
||||||
message.info("Last tab")
|
message.error("Last tab")
|
||||||
|
|
||||||
@cmdutils.register(instance='mainwindow.tabs', nargs=(0, 1))
|
@cmdutils.register(instance='mainwindow.tabs', nargs=(0, 1))
|
||||||
def paste(self, sel=False, tab=False):
|
def paste(self, sel=False, tab=False):
|
||||||
|
@ -33,9 +33,6 @@ class TabWidget(QTabWidget):
|
|||||||
STYLESHEET: The stylesheet template to be used.
|
STYLESHEET: The stylesheet template to be used.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# FIXME there is still some ugly 1px white stripe from somewhere if we do
|
|
||||||
# background-color: grey for QTabBar...
|
|
||||||
|
|
||||||
STYLESHEET = """
|
STYLESHEET = """
|
||||||
QTabWidget::pane {{
|
QTabWidget::pane {{
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -44,18 +41,13 @@ class TabWidget(QTabWidget):
|
|||||||
|
|
||||||
QTabBar {{
|
QTabBar {{
|
||||||
{font[tabbar]}
|
{font[tabbar]}
|
||||||
|
{color[tab.bg.bar]}
|
||||||
}}
|
}}
|
||||||
|
|
||||||
QTabBar::tab {{
|
QTabBar::tab {{
|
||||||
{color[tab.bg]}
|
{color[tab.bg]}
|
||||||
{color[tab.fg]}
|
{color[tab.fg]}
|
||||||
padding-left: 5px;
|
padding: 0px 5px 0px 5px;
|
||||||
padding-right: 5px;
|
|
||||||
padding-top: 0px;
|
|
||||||
padding-bottom: 0px;
|
|
||||||
}}
|
|
||||||
|
|
||||||
QTabBar::tab:first, QTabBar::tab:middle {{
|
|
||||||
border-right: 1px solid {color[tab.seperator]};
|
border-right: 1px solid {color[tab.seperator]};
|
||||||
}}
|
}}
|
||||||
|
|
||||||
@ -71,6 +63,7 @@ class TabWidget(QTabWidget):
|
|||||||
set_register_stylesheet(self)
|
set_register_stylesheet(self)
|
||||||
self.setDocumentMode(True)
|
self.setDocumentMode(True)
|
||||||
self.setElideMode(Qt.ElideRight)
|
self.setElideMode(Qt.ElideRight)
|
||||||
|
self.tabBar().setDrawBase(False)
|
||||||
self._init_config()
|
self._init_config()
|
||||||
|
|
||||||
def _init_config(self):
|
def _init_config(self):
|
||||||
|
Loading…
Reference in New Issue
Block a user