More workarounds for the broken underMouse() function in Qt 5 on X11

Fixes buttons on the toolbar remaining raised even after their popup
menus are closed.
This commit is contained in:
Kovid Goyal 2014-07-15 10:35:43 +05:30
parent 81d1a3b922
commit b00781b87a
4 changed files with 41 additions and 7 deletions

View File

@ -1152,3 +1152,14 @@ if _df and os.path.exists(_df):
build_forms(_df) build_forms(_df)
if islinux or isbsd:
def workaround_broken_under_mouse(ch):
import sip
from PyQt5.Qt import QCursor, QToolButton
# See https://bugreports.qt-project.org/browse/QTBUG-40233
if isinstance(ch, QToolButton) and not sip.isdeleted(ch):
ch.setAttribute(Qt.WA_UnderMouse, ch.rect().contains(ch.mapFromGlobal(QCursor.pos())))
ch.update()
else:
workaround_broken_under_mouse = None

View File

@ -7,13 +7,15 @@ __license__ = 'GPL v3'
__copyright__ = '2011, Kovid Goyal <kovid@kovidgoyal.net>' __copyright__ = '2011, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
from functools import partial
import sip import sip
from PyQt5.Qt import (Qt, QAction, QMenu, QMenuBar, QObject, from PyQt5.Qt import (Qt, QAction, QMenu, QMenuBar, QObject,
QToolBar, QToolButton, QSize, pyqtSignal, QTimer) QToolBar, QToolButton, QSize, pyqtSignal, QTimer)
from calibre.constants import isosx from calibre.constants import isosx
from calibre.gui2.throbber import create_donate_widget from calibre.gui2.throbber import create_donate_widget
from calibre.gui2 import gprefs from calibre.gui2 import gprefs, workaround_broken_under_mouse
class ToolBar(QToolBar): # {{{ class ToolBar(QToolBar): # {{{
@ -106,8 +108,12 @@ class ToolBar(QToolBar): # {{{
ch = self.child_bar.widgetForAction(ac) ch = self.child_bar.widgetForAction(ac)
ch.setCursor(Qt.PointingHandCursor) ch.setCursor(Qt.PointingHandCursor)
ch.setAutoRaise(True) ch.setAutoRaise(True)
if ac.menu() is not None and menu_mode is not None: m = ac.menu()
ch.setPopupMode(menu_mode) if m is not None:
if workaround_broken_under_mouse is not None:
m.aboutToHide.connect(partial(workaround_broken_under_mouse, ch))
if menu_mode is not None:
ch.setPopupMode(menu_mode)
return ch return ch
# support drag&drop from/to library, from/to reader/card, enabled plugins # support drag&drop from/to library, from/to reader/card, enabled plugins

View File

@ -16,8 +16,8 @@ from PyQt5.Qt import (
from calibre import prints from calibre import prints
from calibre.constants import DEBUG from calibre.constants import DEBUG
from calibre.ebooks.chardet import replace_encoding_declarations from calibre.ebooks.chardet import replace_encoding_declarations
from calibre.gui2 import error_dialog, open_url
from calibre.gui2.tweak_book import actions, current_container, tprefs, dictionaries, editor_toolbar_actions, editor_name, editors from calibre.gui2.tweak_book import actions, current_container, tprefs, dictionaries, editor_toolbar_actions, editor_name, editors
from calibre.gui2 import error_dialog, open_url, workaround_broken_under_mouse
from calibre.gui2.tweak_book.editor import SPELL_PROPERTY, LINK_PROPERTY, TAG_NAME_PROPERTY, CSS_PROPERTY from calibre.gui2.tweak_book.editor import SPELL_PROPERTY, LINK_PROPERTY, TAG_NAME_PROPERTY, CSS_PROPERTY
from calibre.gui2.tweak_book.editor.help import help_url from calibre.gui2.tweak_book.editor.help import help_url
from calibre.gui2.tweak_book.editor.text import TextEdit from calibre.gui2.tweak_book.editor.text import TextEdit
@ -310,10 +310,19 @@ class Editor(QMainWindow):
w.setContextMenuPolicy(Qt.CustomContextMenu) w.setContextMenuPolicy(Qt.CustomContextMenu)
w.customContextMenuRequested.connect(w.showMenu) w.customContextMenuRequested.connect(w.showMenu)
self._build_insert_tag_button_menu() self._build_insert_tag_button_menu()
if workaround_broken_under_mouse is not None:
try:
self.insert_tag_menu.aboutToHide.disconnect()
except TypeError:
pass
self.insert_tag_menu.aboutToHide.connect(partial(workaround_broken_under_mouse, w))
elif name == 'change-paragraph': elif name == 'change-paragraph':
m = ac.m = QMenu() m = ac.m = QMenu()
ac.setMenu(m) ac.setMenu(m)
bar.widgetForAction(ac).setPopupMode(QToolButton.InstantPopup) ch = bar.widgetForAction(ac)
ch.setPopupMode(QToolButton.InstantPopup)
if workaround_broken_under_mouse is not None:
m.aboutToHide.connect(partial(workaround_broken_under_mouse, ch))
for name in tuple('h%d' % d for d in range(1, 7)) + ('p',): for name in tuple('h%d' % d for d in range(1, 7)) + ('p',):
m.addAction(actions['rename-block-tag-%s' % name]) m.addAction(actions['rename-block-tag-%s' % name])

View File

@ -13,8 +13,10 @@ from calibre.gui2.viewer.ui import Main as MainWindow
from calibre.gui2.viewer.printing import Printing from calibre.gui2.viewer.printing import Printing
from calibre.gui2.viewer.toc import TOC from calibre.gui2.viewer.toc import TOC
from calibre.gui2.widgets import ProgressIndicator from calibre.gui2.widgets import ProgressIndicator
from calibre.gui2 import (Application, ORG_NAME, APP_UID, choose_files, from calibre.gui2 import (
info_dialog, error_dialog, open_url, setup_gui_option_parser, detach_gui) Application, ORG_NAME, APP_UID, choose_files, info_dialog, error_dialog,
open_url, setup_gui_option_parser, detach_gui,
workaround_broken_under_mouse)
from calibre.ebooks.oeb.iterator.book import EbookIterator from calibre.ebooks.oeb.iterator.book import EbookIterator
from calibre.ebooks import DRMError from calibre.ebooks import DRMError
from calibre.constants import islinux, filesystem_encoding from calibre.constants import islinux, filesystem_encoding
@ -154,6 +156,12 @@ class EbookViewer(MainWindow):
self.action_toggle_paged_mode.toggled[bool].connect(self.toggle_paged_mode) self.action_toggle_paged_mode.toggled[bool].connect(self.toggle_paged_mode)
if (start_in_fullscreen or self.view.document.start_in_fullscreen): if (start_in_fullscreen or self.view.document.start_in_fullscreen):
self.action_full_screen.trigger() self.action_full_screen.trigger()
if workaround_broken_under_mouse is not None:
for bar in (self.tool_bar, self.tool_bar2):
for ac in bar.actions():
m = ac.menu()
if m is not None:
m.aboutToHide.connect(partial(workaround_broken_under_mouse, bar.widgetForAction(ac)))
def toggle_paged_mode(self, checked, at_start=False): def toggle_paged_mode(self, checked, at_start=False):
in_paged_mode = not self.action_toggle_paged_mode.isChecked() in_paged_mode = not self.action_toggle_paged_mode.isChecked()