Track HTML fullscreen per-tab
We now automatically get out of fullscreen when switching away from a fullscreened tab. This also means we can't get into a situation where we can't leave fullscreen anymore. Fixes #2379.
This commit is contained in:
parent
a18ebd52a9
commit
06e754a632
@ -97,6 +97,7 @@ class TabData:
|
|||||||
override_target: Override for open_target for fake clicks (like hints).
|
override_target: Override for open_target for fake clicks (like hints).
|
||||||
Only used for QtWebKit.
|
Only used for QtWebKit.
|
||||||
pinned: Flag to pin the tab.
|
pinned: Flag to pin the tab.
|
||||||
|
fullscreen: Whether the tab has a video shown fullscreen currently.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -105,6 +106,7 @@ class TabData:
|
|||||||
self.inspector = None
|
self.inspector = None
|
||||||
self.override_target = None
|
self.override_target = None
|
||||||
self.pinned = False
|
self.pinned = False
|
||||||
|
self.fullscreen = False
|
||||||
|
|
||||||
|
|
||||||
class AbstractAction:
|
class AbstractAction:
|
||||||
|
@ -694,6 +694,8 @@ class WebEngineTab(browsertab.AbstractTab):
|
|||||||
def _on_fullscreen_requested(self, request):
|
def _on_fullscreen_requested(self, request):
|
||||||
request.accept()
|
request.accept()
|
||||||
on = request.toggleOn()
|
on = request.toggleOn()
|
||||||
|
|
||||||
|
self.data.fullscreen = on
|
||||||
self.fullscreen_requested.emit(on)
|
self.fullscreen_requested.emit(on)
|
||||||
if on:
|
if on:
|
||||||
notification = miscwidgets.FullscreenNotification(self)
|
notification = miscwidgets.FullscreenNotification(self)
|
||||||
|
@ -471,10 +471,8 @@ class MainWindow(QWidget):
|
|||||||
tabs.cur_url_changed.connect(status.url.set_url)
|
tabs.cur_url_changed.connect(status.url.set_url)
|
||||||
tabs.cur_link_hovered.connect(status.url.set_hover_url)
|
tabs.cur_link_hovered.connect(status.url.set_hover_url)
|
||||||
tabs.cur_load_status_changed.connect(status.url.on_load_status_changed)
|
tabs.cur_load_status_changed.connect(status.url.on_load_status_changed)
|
||||||
tabs.page_fullscreen_requested.connect(
|
tabs.cur_fullscreen_requested.connect(self._on_fullscreen_requested)
|
||||||
self._on_page_fullscreen_requested)
|
tabs.cur_fullscreen_requested.connect(status.maybe_hide)
|
||||||
tabs.page_fullscreen_requested.connect(
|
|
||||||
status.on_page_fullscreen_requested)
|
|
||||||
|
|
||||||
# command input / completion
|
# command input / completion
|
||||||
mode_manager.left.connect(tabs.on_mode_left)
|
mode_manager.left.connect(tabs.on_mode_left)
|
||||||
@ -483,7 +481,7 @@ class MainWindow(QWidget):
|
|||||||
cmd.hide_completion.connect(completion_obj.hide)
|
cmd.hide_completion.connect(completion_obj.hide)
|
||||||
|
|
||||||
@pyqtSlot(bool)
|
@pyqtSlot(bool)
|
||||||
def _on_page_fullscreen_requested(self, on):
|
def _on_fullscreen_requested(self, on):
|
||||||
if on:
|
if on:
|
||||||
self.showFullScreen()
|
self.showFullScreen()
|
||||||
else:
|
else:
|
||||||
|
@ -125,8 +125,6 @@ class StatusBar(QWidget):
|
|||||||
_hbox: The main QHBoxLayout.
|
_hbox: The main QHBoxLayout.
|
||||||
_stack: The QStackedLayout with cmd/txt widgets.
|
_stack: The QStackedLayout with cmd/txt widgets.
|
||||||
_win_id: The window ID the statusbar is associated with.
|
_win_id: The window ID the statusbar is associated with.
|
||||||
_page_fullscreen: Whether the webpage (e.g. a video) is shown
|
|
||||||
fullscreen.
|
|
||||||
|
|
||||||
Signals:
|
Signals:
|
||||||
resized: Emitted when the statusbar has resized, so the completion
|
resized: Emitted when the statusbar has resized, so the completion
|
||||||
@ -155,13 +153,11 @@ class StatusBar(QWidget):
|
|||||||
|
|
||||||
self._win_id = win_id
|
self._win_id = win_id
|
||||||
self._option = None
|
self._option = None
|
||||||
self._page_fullscreen = False
|
|
||||||
self._color_flags = ColorFlags()
|
self._color_flags = ColorFlags()
|
||||||
self._color_flags.private = private
|
self._color_flags.private = private
|
||||||
|
|
||||||
self._hbox = QHBoxLayout(self)
|
self._hbox = QHBoxLayout(self)
|
||||||
self.set_hbox_padding()
|
self._set_hbox_padding()
|
||||||
objreg.get('config').changed.connect(self.set_hbox_padding)
|
|
||||||
self._hbox.setSpacing(5)
|
self._hbox.setSpacing(5)
|
||||||
|
|
||||||
self._stack = QStackedLayout()
|
self._stack = QStackedLayout()
|
||||||
@ -198,23 +194,32 @@ class StatusBar(QWidget):
|
|||||||
self.prog = progress.Progress(self)
|
self.prog = progress.Progress(self)
|
||||||
self._hbox.addWidget(self.prog)
|
self._hbox.addWidget(self.prog)
|
||||||
|
|
||||||
objreg.get('config').changed.connect(self.maybe_hide)
|
objreg.get('config').changed.connect(self._on_config_changed)
|
||||||
QTimer.singleShot(0, self.maybe_hide)
|
QTimer.singleShot(0, self.maybe_hide)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return utils.get_repr(self)
|
return utils.get_repr(self)
|
||||||
|
|
||||||
@config.change_filter('ui', 'hide-statusbar')
|
@pyqtSlot(str, str)
|
||||||
|
def _on_config_changed(self, section, option):
|
||||||
|
if section != 'ui':
|
||||||
|
return
|
||||||
|
if option == 'hide-statusbar':
|
||||||
|
self.maybe_hide()
|
||||||
|
elif option == 'statusbar-pdading':
|
||||||
|
self._set_hbox_padding()
|
||||||
|
|
||||||
|
@pyqtSlot()
|
||||||
def maybe_hide(self):
|
def maybe_hide(self):
|
||||||
"""Hide the statusbar if it's configured to do so."""
|
"""Hide the statusbar if it's configured to do so."""
|
||||||
hide = config.get('ui', 'hide-statusbar')
|
hide = config.get('ui', 'hide-statusbar')
|
||||||
if hide or self._page_fullscreen:
|
tab = self._current_tab()
|
||||||
|
if hide or (tab is not None and tab.data.fullscreen):
|
||||||
self.hide()
|
self.hide()
|
||||||
else:
|
else:
|
||||||
self.show()
|
self.show()
|
||||||
|
|
||||||
@config.change_filter('ui', 'statusbar-padding')
|
def _set_hbox_padding(self):
|
||||||
def set_hbox_padding(self):
|
|
||||||
padding = config.get('ui', 'statusbar-padding')
|
padding = config.get('ui', 'statusbar-padding')
|
||||||
self._hbox.setContentsMargins(padding.left, 0, padding.right, 0)
|
self._hbox.setContentsMargins(padding.left, 0, padding.right, 0)
|
||||||
|
|
||||||
@ -223,6 +228,12 @@ class StatusBar(QWidget):
|
|||||||
"""Getter for self.color_flags, so it can be used as Qt property."""
|
"""Getter for self.color_flags, so it can be used as Qt property."""
|
||||||
return self._color_flags.to_stringlist()
|
return self._color_flags.to_stringlist()
|
||||||
|
|
||||||
|
def _current_tab(self):
|
||||||
|
"""Get the currently displayed tab."""
|
||||||
|
window = objreg.get('tabbed-browser', scope='window',
|
||||||
|
window=self._win_id)
|
||||||
|
return window.currentWidget()
|
||||||
|
|
||||||
def set_mode_active(self, mode, val):
|
def set_mode_active(self, mode, val):
|
||||||
"""Setter for self.{insert,command,caret}_active.
|
"""Setter for self.{insert,command,caret}_active.
|
||||||
|
|
||||||
@ -239,8 +250,7 @@ class StatusBar(QWidget):
|
|||||||
log.statusbar.debug("Setting prompt flag to {}".format(val))
|
log.statusbar.debug("Setting prompt flag to {}".format(val))
|
||||||
self._color_flags.prompt = val
|
self._color_flags.prompt = val
|
||||||
elif mode == usertypes.KeyMode.caret:
|
elif mode == usertypes.KeyMode.caret:
|
||||||
tab = objreg.get('tabbed-browser', scope='window',
|
tab = self._current_tab()
|
||||||
window=self._win_id).currentWidget()
|
|
||||||
log.statusbar.debug("Setting caret flag - val {}, selection "
|
log.statusbar.debug("Setting caret flag - val {}, selection "
|
||||||
"{}".format(val, tab.caret.selection_enabled))
|
"{}".format(val, tab.caret.selection_enabled))
|
||||||
if val:
|
if val:
|
||||||
@ -306,17 +316,13 @@ class StatusBar(QWidget):
|
|||||||
usertypes.KeyMode.yesno]:
|
usertypes.KeyMode.yesno]:
|
||||||
self.set_mode_active(old_mode, False)
|
self.set_mode_active(old_mode, False)
|
||||||
|
|
||||||
@pyqtSlot(bool)
|
|
||||||
def on_page_fullscreen_requested(self, on):
|
|
||||||
self._page_fullscreen = on
|
|
||||||
self.maybe_hide()
|
|
||||||
|
|
||||||
@pyqtSlot(browsertab.AbstractTab)
|
@pyqtSlot(browsertab.AbstractTab)
|
||||||
def on_tab_changed(self, tab):
|
def on_tab_changed(self, tab):
|
||||||
"""Notify sub-widgets when the tab has been changed."""
|
"""Notify sub-widgets when the tab has been changed."""
|
||||||
self.url.on_tab_changed(tab)
|
self.url.on_tab_changed(tab)
|
||||||
self.prog.on_tab_changed(tab)
|
self.prog.on_tab_changed(tab)
|
||||||
self.percentage.on_tab_changed(tab)
|
self.percentage.on_tab_changed(tab)
|
||||||
|
self.maybe_hide()
|
||||||
assert tab.private == self._color_flags.private
|
assert tab.private == self._color_flags.private
|
||||||
|
|
||||||
def resizeEvent(self, e):
|
def resizeEvent(self, e):
|
||||||
|
@ -96,11 +96,11 @@ class TabbedBrowser(tabwidget.TabWidget):
|
|||||||
cur_link_hovered = pyqtSignal(str)
|
cur_link_hovered = pyqtSignal(str)
|
||||||
cur_scroll_perc_changed = pyqtSignal(int, int)
|
cur_scroll_perc_changed = pyqtSignal(int, int)
|
||||||
cur_load_status_changed = pyqtSignal(str)
|
cur_load_status_changed = pyqtSignal(str)
|
||||||
|
cur_fullscreen_requested = pyqtSignal(bool)
|
||||||
close_window = pyqtSignal()
|
close_window = pyqtSignal()
|
||||||
resized = pyqtSignal('QRect')
|
resized = pyqtSignal('QRect')
|
||||||
current_tab_changed = pyqtSignal(browsertab.AbstractTab)
|
current_tab_changed = pyqtSignal(browsertab.AbstractTab)
|
||||||
new_tab = pyqtSignal(browsertab.AbstractTab, int)
|
new_tab = pyqtSignal(browsertab.AbstractTab, int)
|
||||||
page_fullscreen_requested = pyqtSignal(bool)
|
|
||||||
|
|
||||||
def __init__(self, *, win_id, private, parent=None):
|
def __init__(self, *, win_id, private, parent=None):
|
||||||
super().__init__(win_id, parent)
|
super().__init__(win_id, parent)
|
||||||
@ -111,6 +111,7 @@ class TabbedBrowser(tabwidget.TabWidget):
|
|||||||
self.tabCloseRequested.connect(self.on_tab_close_requested)
|
self.tabCloseRequested.connect(self.on_tab_close_requested)
|
||||||
self.currentChanged.connect(self.on_current_changed)
|
self.currentChanged.connect(self.on_current_changed)
|
||||||
self.cur_load_started.connect(self.on_cur_load_started)
|
self.cur_load_started.connect(self.on_cur_load_started)
|
||||||
|
self.cur_fullscreen_requested.connect(self.tabBar().maybe_hide)
|
||||||
self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
||||||
self._undo_stack = []
|
self._undo_stack = []
|
||||||
self._filter = signalfilter.SignalFilter(win_id, self)
|
self._filter = signalfilter.SignalFilter(win_id, self)
|
||||||
@ -190,6 +191,8 @@ class TabbedBrowser(tabwidget.TabWidget):
|
|||||||
self._filter.create(self.cur_url_changed, tab))
|
self._filter.create(self.cur_url_changed, tab))
|
||||||
tab.load_status_changed.connect(
|
tab.load_status_changed.connect(
|
||||||
self._filter.create(self.cur_load_status_changed, tab))
|
self._filter.create(self.cur_load_status_changed, tab))
|
||||||
|
tab.fullscreen_requested.connect(
|
||||||
|
self._filter.create(self.cur_fullscreen_requested, tab))
|
||||||
tab.url_changed.connect(
|
tab.url_changed.connect(
|
||||||
functools.partial(self.on_url_changed, tab))
|
functools.partial(self.on_url_changed, tab))
|
||||||
# misc
|
# misc
|
||||||
@ -211,9 +214,6 @@ class TabbedBrowser(tabwidget.TabWidget):
|
|||||||
if not self.private:
|
if not self.private:
|
||||||
web_history = objreg.get('web-history')
|
web_history = objreg.get('web-history')
|
||||||
tab.add_history_item.connect(web_history.add_from_tab)
|
tab.add_history_item.connect(web_history.add_from_tab)
|
||||||
tab.fullscreen_requested.connect(self.page_fullscreen_requested)
|
|
||||||
tab.fullscreen_requested.connect(
|
|
||||||
self.tabBar().on_page_fullscreen_requested)
|
|
||||||
|
|
||||||
def current_url(self):
|
def current_url(self):
|
||||||
"""Get the URL of the current tab.
|
"""Get the URL of the current tab.
|
||||||
|
@ -52,7 +52,7 @@ class TabWidget(QTabWidget):
|
|||||||
|
|
||||||
def __init__(self, win_id, parent=None):
|
def __init__(self, win_id, parent=None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
bar = TabBar(win_id)
|
bar = TabBar(win_id, self)
|
||||||
self.setStyle(TabBarStyle())
|
self.setStyle(TabBarStyle())
|
||||||
self.setTabBar(bar)
|
self.setTabBar(bar)
|
||||||
bar.tabCloseRequested.connect(self.tabCloseRequested)
|
bar.tabCloseRequested.connect(self.tabCloseRequested)
|
||||||
@ -298,8 +298,6 @@ class TabBar(QTabBar):
|
|||||||
Attributes:
|
Attributes:
|
||||||
vertical: When the tab bar is currently vertical.
|
vertical: When the tab bar is currently vertical.
|
||||||
win_id: The window ID this TabBar belongs to.
|
win_id: The window ID this TabBar belongs to.
|
||||||
_page_fullscreen: Whether the webpage (e.g. a video) is shown
|
|
||||||
fullscreen.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, win_id, parent=None):
|
def __init__(self, win_id, parent=None):
|
||||||
@ -311,17 +309,16 @@ class TabBar(QTabBar):
|
|||||||
config_obj.changed.connect(self.set_font)
|
config_obj.changed.connect(self.set_font)
|
||||||
config_obj.changed.connect(self.set_icon_size)
|
config_obj.changed.connect(self.set_icon_size)
|
||||||
self.vertical = False
|
self.vertical = False
|
||||||
self._page_fullscreen = False
|
|
||||||
self._auto_hide_timer = QTimer()
|
self._auto_hide_timer = QTimer()
|
||||||
self._auto_hide_timer.setSingleShot(True)
|
self._auto_hide_timer.setSingleShot(True)
|
||||||
self._auto_hide_timer.setInterval(
|
self._auto_hide_timer.setInterval(
|
||||||
config.get('tabs', 'show-switching-delay'))
|
config.get('tabs', 'show-switching-delay'))
|
||||||
self._auto_hide_timer.timeout.connect(self._tabhide)
|
self._auto_hide_timer.timeout.connect(self.maybe_hide)
|
||||||
self.setAutoFillBackground(True)
|
self.setAutoFillBackground(True)
|
||||||
self.set_colors()
|
self.set_colors()
|
||||||
self.pinned_count = 0
|
self.pinned_count = 0
|
||||||
config_obj.changed.connect(self.set_colors)
|
config_obj.changed.connect(self.set_colors)
|
||||||
QTimer.singleShot(0, self._tabhide)
|
QTimer.singleShot(0, self.maybe_hide)
|
||||||
config_obj.changed.connect(self.on_tab_colors_changed)
|
config_obj.changed.connect(self.on_tab_colors_changed)
|
||||||
config_obj.changed.connect(self.on_show_switching_delay_changed)
|
config_obj.changed.connect(self.on_show_switching_delay_changed)
|
||||||
config_obj.changed.connect(self.tabs_show)
|
config_obj.changed.connect(self.tabs_show)
|
||||||
@ -329,10 +326,14 @@ class TabBar(QTabBar):
|
|||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return utils.get_repr(self, count=self.count())
|
return utils.get_repr(self, count=self.count())
|
||||||
|
|
||||||
|
def _current_tab(self):
|
||||||
|
"""Get the current tab object."""
|
||||||
|
return self.parent().currentWidget()
|
||||||
|
|
||||||
@config.change_filter('tabs', 'show')
|
@config.change_filter('tabs', 'show')
|
||||||
def tabs_show(self):
|
def tabs_show(self):
|
||||||
"""Hide or show tab bar if needed when tabs->show got changed."""
|
"""Hide or show tab bar if needed when tabs->show got changed."""
|
||||||
self._tabhide()
|
self.maybe_hide()
|
||||||
|
|
||||||
@config.change_filter('tabs', 'show-switching-delay')
|
@config.change_filter('tabs', 'show-switching-delay')
|
||||||
def on_show_switching_delay_changed(self):
|
def on_show_switching_delay_changed(self):
|
||||||
@ -340,24 +341,22 @@ class TabBar(QTabBar):
|
|||||||
self._auto_hide_timer.setInterval(
|
self._auto_hide_timer.setInterval(
|
||||||
config.get('tabs', 'show-switching-delay'))
|
config.get('tabs', 'show-switching-delay'))
|
||||||
|
|
||||||
@pyqtSlot(bool)
|
|
||||||
def on_page_fullscreen_requested(self, on):
|
|
||||||
self._page_fullscreen = on
|
|
||||||
self._tabhide()
|
|
||||||
|
|
||||||
def on_current_changed(self):
|
def on_current_changed(self):
|
||||||
"""Show tab bar when current tab got changed."""
|
"""Show tab bar when current tab got changed."""
|
||||||
|
self.maybe_hide() # for fullscreen tabs
|
||||||
show = config.get('tabs', 'show')
|
show = config.get('tabs', 'show')
|
||||||
if show == 'switching' or self._page_fullscreen:
|
if show == 'switching':
|
||||||
self.show()
|
self.show()
|
||||||
self._auto_hide_timer.start()
|
self._auto_hide_timer.start()
|
||||||
|
|
||||||
def _tabhide(self):
|
@pyqtSlot()
|
||||||
|
def maybe_hide(self):
|
||||||
"""Hide the tab bar if needed."""
|
"""Hide the tab bar if needed."""
|
||||||
show = config.get('tabs', 'show')
|
show = config.get('tabs', 'show')
|
||||||
|
tab = self._current_tab()
|
||||||
if (show in ['never', 'switching'] or
|
if (show in ['never', 'switching'] or
|
||||||
(show == 'multiple' and self.count() == 1) or
|
(show == 'multiple' and self.count() == 1) or
|
||||||
self._page_fullscreen):
|
(tab and tab.data.fullscreen)):
|
||||||
self.hide()
|
self.hide()
|
||||||
else:
|
else:
|
||||||
self.show()
|
self.show()
|
||||||
@ -579,12 +578,12 @@ class TabBar(QTabBar):
|
|||||||
def tabInserted(self, idx):
|
def tabInserted(self, idx):
|
||||||
"""Update visibility when a tab was inserted."""
|
"""Update visibility when a tab was inserted."""
|
||||||
super().tabInserted(idx)
|
super().tabInserted(idx)
|
||||||
self._tabhide()
|
self.maybe_hide()
|
||||||
|
|
||||||
def tabRemoved(self, idx):
|
def tabRemoved(self, idx):
|
||||||
"""Update visibility when a tab was removed."""
|
"""Update visibility when a tab was removed."""
|
||||||
super().tabRemoved(idx)
|
super().tabRemoved(idx)
|
||||||
self._tabhide()
|
self.maybe_hide()
|
||||||
|
|
||||||
def wheelEvent(self, e):
|
def wheelEvent(self, e):
|
||||||
"""Override wheelEvent to make the action configurable.
|
"""Override wheelEvent to make the action configurable.
|
||||||
|
Loading…
Reference in New Issue
Block a user